10#include "FgCommand.hpp"
13#include "FgTestUtils.hpp"
16#include "Fg3dMeshIo.hpp"
18#include "Fg3Freeform.hpp"
33 R
"(<face>.fg <modulationImage>.<ext>
34 <ext> - )" + clOptionsStr(getImgExts()) + R"(
38 * The modulation images are multiplicative (not additive) modifiers which add detail to the
39 smooth maps created by FaceGen SCMs.
40 * The modulation images are encoded as greyscale images, 8 bits/channel, with the multiplicative
41 value given as X / 64.0
42 * The UV layout of the modulation images is the FaceGen internal cylindrical layout. An SCM
43 .fim file contains the transform from this layout into the UV layout of the SCM.)"
45 Face3 face {syn.next()};
48 saveImage(img,syn.next());
51void cmd3DetailInsert(CLArgs
const & args)
54 R
"( <modulationImage>.<ext> <face>.fg
55 <ext> - )" + clOptionsStr(getImgExts()) + R"(
59 * The modulation images are multiplicative (not additive) modifiers which add detail to the
60 smooth maps created by FaceGen SCMs.
61 * The modulation images are encoded as greyscale images, 8 bits/channel, with the multiplicative
62 value given as X / 64.0
63 * The UV layout of the modulation images is the FaceGen internal cylindrical layout. An SCM
64 .fim file contains the transform from this layout into the UV layout of the SCM.)"
66 String8 imgFname = syn.next(),
67 faceFname = syn.next();
68 ImgRgba8 img = loadImage(imgFname);
69 Face3 face {faceFname};
70 if (img.width() != img.height())
71 fgThrow(
"The detail texture image must be square",imgFname);
72 if (!isPow2(img.width()))
73 fgThrow(
"The detail texture image dimension must be a power of 2");
74 face.detail = encodeJpeg(img,100);
78void cmd3DetailRemove(CLArgs
const & args)
80 Syntax syn{args,R
"(<in>.fg <out>.fg
82 <out>.fg is <in>.fg without the detail modulation map)"
84 Face3 face {syn.next()};
85 if (face.detail.empty())
86 fgout <<
"WARNING: " << syn.curr() <<
"has no detail map";
88 face.save(syn.next());
91void cmd3Detail(CLArgs
const & args)
94 {
cmd3DetailExtract,
"extract",
"extract the detail modulation map from a .FG file"},
95 {cmd3DetailInsert,
"insert",
"insert a detail modulation map into a .FG file"},
96 {cmd3DetailRemove,
"remove",
"remove a detail modulation map from a .FG file"},
98 doMenu(args,tests,
true,
false);
108 R
"((symm | asym) <ssm> <vertexIndex> <vertexDelta> <in>.fg <out>.fg
109 <vertexDelta> - <deltaX> <deltaY> <deltaZ>
111 <out>.fg Face with modified shape
113 * Actual vertex deformation values will always be smaller than the length of <vertexDelta>,
114 depending on the correlation between the given vertex motion and the shape basis.
117 if (args.size() != 9)
119 string symmStr(syn.next());
120 string ssmStr(syn.next());
121 uint vertexIndex = syn.nextAs<uint>();
123 vertexDelta[0] = syn.nextAs<
float>();
124 vertexDelta[1] = syn.nextAs<
float>();
125 vertexDelta[2] = syn.nextAs<
float>();
126 string inFgStr(syn.next());
127 string outFgStr(syn.next());
128 if ((symmStr !=
"symm") && (symmStr !=
"asym"))
129 syn.error(
"Invalid symmetry specification");
131 Mesh mesh = loadTri(ssmStr+
".tri");
132 Ssm3 ssm(mesh.verts,ssmStr+
".egm");
139void test3Controls(CLArgs
const &);
140void testCmd3ConstructScm(CLArgs
const &);
141void testCmd3ConstructSsm(CLArgs
const &);
142void test3FaceCoord(CLArgs
const &);
143void testCmdApply(CLArgs
const &);
144void test3GetDetail(CLArgs
const &);
145void testScm3(CLArgs
const &);
147void test3Main(CLArgs
const & args)
150 {testCmdApply,
"apply",
"test 'fg3 apply' command"},
151 {test3Controls,
"controls"},
152 {test3FaceCoord,
"coord"},
153 {test3GetDetail,
"getDetail"},
156 doMenu(args,tests,
true,
false);
159void cmdEgmImport(CLArgs
const & args)
161 Syntax syn {args,R
"(<mean>.<ext> <modes>.txt <out>.egm
162 <mean> - the base mesh in the mean shape
163 <ext> - )" + getMeshLoadExtsCLDescription() + R"(
164 <modes>.txt - list of the filenames for each mode represented as a mesh with shape given by base + mode.
165 the filenames must have one of the recognized mesh extensions listed above.
166 <out>.egm - the modes are converted to the FaceGen 3 internal format
168 All modes are interpreted as symmetric shape modes.)"
170 Mesh base = loadMesh(syn.next());
171 Strings modeFiles = splitWhitespace(loadRawString(syn.next()));
173 for (String
const & mf : modeFiles) {
174 Vec3Fs verts = loadMesh(mf).verts;
175 if (verts.size() != base.verts.size())
176 syn.error(
"base and mode meshes must have identical size vertex lists");
177 modes.push_back(verts-base.verts);
179 saveEgm(syn.next(),modes,{});
182void cmd3Basis3dmm(CLArgs
const &);
183void cmd3BasisEgm(CLArgs
const &);
184void cmd3BasisEgt(CLArgs
const &);
185void cmdEgmVariances(CLArgs
const &);
187void cmd3Basis(CLArgs
const & args)
190 {cmd3Basis3dmm,
"3dmm",
"Export from an .EGM file to a 3DMM .MatV3F file"},
191 {cmd3BasisEgm,
"egm",
"Export from an .EGM file to .TXT files"},
192 {cmd3BasisEgt,
"egt",
"Export from an .EGT file to .TXT files"},
193 {cmdEgmImport,
"import",
"Import linear shape modes from a base mesh and meshes representing each mode"},
194 {cmdEgmVariances,
"var",
"Print out the squared magnitude of each mode in an .EGM file"},
199void cmdApply(CLArgs
const &);
210 {cmdApply,
"apply",
"Apply a face (.fg) to SAMs to create meshes and color maps"},
211 {cmd3Basis,
"basis",
"Import / export SAM basis modes"},
212 {
cmd3Controls,
"controls",
"Parametric controls on face coordinates (.fg)"},
213 {
cmd3Coord,
"coord",
"list / set face coordinates (.fg)"},
214 {
cmd3Create,
"create",
"Create random or average faces (.fg)"},
215 {cmd3Detail,
"detail",
"Extract/insert a detail texure from/to an .FG file"},
216 {
cmd3Interactive,
"interactive",
"Apply interactive deformations to an SSM and face coordinate"},
217 {
cmd3Random,
"random",
"Batch create random face images"},
218 {test3Main,
"test",
"Automated tests"},
219 {
cmd3Util,
"util",
"Utility functions"},
220 {
cmd3View,
"view",
"interactive GUI view of SAMs, FG files, FIM files (Windows only)"},
228void cmdFg3(CLArgs
const & args)
230 if (args.size() == 1)
231 fgout << fgnl <<
"FaceGen Main SDK CLI " << getSdkVersion(
".") <<
" (" << getCurrentBuildDescription() <<
")";
232 doMenu(args,getFg3Cmds(),
false,
true);
void getDetail(ImgRgba8 &img) const
Decode the JPEG detail texture into FG image format:
FanSymmE
Enumerate symmetry types.
void fg3Interactive(Sam3Coord &coord, FanSymmE symmetry, const Ssm3 &ssm, uint vertexIndex, Vec3F vertexDelta)
@ FANSYMM_ASYM
Asymmetric.
void cmd3Coord(CLArgs const &)
void cmd3Create(CLArgs const &)
void cmd3DetailExtract(CLArgs const &args)
void cmd3View(CLArgs const &)
void cmd3Random(CLArgs const &)
void cmd3Util(CLArgs const &)
void cmd3Interactive(CLArgs const &args)
void cmd3Controls(CLArgs const &)