FaceGen 3 SDKs Reference
Loading...
Searching...
No Matches
Fg3Cmd.cpp
1//
2// Copyright (c) Singular Inversions Inc. 2014
3//
4// Authors: Andrew Beatty
5// Created: Jan 2, 2014
6//
7
8#include "stdafx.h"
9
10#include "FgCommand.hpp"
11
12#include "FgMain.hpp"
13#include "FgTestUtils.hpp"
14#include "FgBuild.hpp"
15#include "Fg3Face.hpp"
16#include "Fg3dMeshIo.hpp"
17#include "Fg3Sam.hpp"
18#include "Fg3Freeform.hpp"
19#include "FgParse.hpp"
20#include "FgApply.hpp"
21
22using namespace std;
23
24namespace Fg {
25
30void cmd3DetailExtract(CLArgs const & args)
31{
32 Syntax syn {args,
33 R"(<face>.fg <modulationImage>.<ext>
34 <ext> - )" + clOptionsStr(getImgExts()) + R"(
35OUTPUT:
36 <modulationImage>
37NOTES:
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.)"
44 };
45 Face3 face {syn.next()};
46 ImgRgba8 img;
47 face.getDetail(img);
48 saveImage(img,syn.next());
49}
50
51void cmd3DetailInsert(CLArgs const & args)
52{
53 Syntax syn {args,
54 R"( <modulationImage>.<ext> <face>.fg
55 <ext> - )" + clOptionsStr(getImgExts()) + R"(
56OUTPUT:
57 modifies <face>.fg
58NOTES:
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.)"
65 };
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);
75 face.save(faceFname);
76}
77
78void cmd3DetailRemove(CLArgs const & args)
79{
80 Syntax syn{args,R"(<in>.fg <out>.fg
81OUTPUT:
82 <out>.fg is <in>.fg without the detail modulation map)"
83 };
84 Face3 face {syn.next()};
85 if (face.detail.empty())
86 fgout << "WARNING: " << syn.curr() << "has no detail map";
87 face.detail.clear();
88 face.save(syn.next());
89}
90
91void cmd3Detail(CLArgs const & args)
92{
93 Cmds tests {
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"},
97 };
98 doMenu(args,tests,true,false);
99}
100
105void cmd3Interactive(CLArgs const & args)
106{
107 Syntax syn {args,
108 R"((symm | asym) <ssm> <vertexIndex> <vertexDelta> <in>.fg <out>.fg
109 <vertexDelta> - <deltaX> <deltaY> <deltaZ>
110OUTPUT:
111 <out>.fg Face with modified shape
112NOTES:
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.
115)"
116 };
117 if (args.size() != 9)
118 syn.errorNumArgs();
119 string symmStr(syn.next());
120 string ssmStr(syn.next());
121 uint vertexIndex = syn.nextAs<uint>();
122 Vec3F vertexDelta;
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");
130 FanSymmE symmetry = (symmStr == "symm") ? FANSYMM_SYMM : FANSYMM_ASYM;
131 Mesh mesh = loadTri(ssmStr+".tri");
132 Ssm3 ssm(mesh.verts,ssmStr+".egm");
133 Face3 face(inFgStr);
135 fg3Interactive(face.coord,symmetry,ssm,vertexIndex,vertexDelta);
136 face.save(outFgStr);
137}
138
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 &);
146
147void test3Main(CLArgs const & args)
148{
149 Cmds tests {
150 {testCmdApply,"apply","test 'fg3 apply' command"},
151 {test3Controls,"controls"},
152 {test3FaceCoord,"coord"},
153 {test3GetDetail,"getDetail"},
154 {testScm3,"scm"},
155 };
156 doMenu(args,tests,true,false);
157}
158
159void cmdEgmImport(CLArgs const & args)
160{
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
167NOTES
168 All modes are interpreted as symmetric shape modes.)"
169 };
170 Mesh base = loadMesh(syn.next());
171 Strings modeFiles = splitWhitespace(loadRawString(syn.next()));
172 Vec3Fss modes;
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);
178 }
179 saveEgm(syn.next(),modes,{});
180}
181
182void cmd3Basis3dmm(CLArgs const &);
183void cmd3BasisEgm(CLArgs const &);
184void cmd3BasisEgt(CLArgs const &);
185void cmdEgmVariances(CLArgs const &);
186
187void cmd3Basis(CLArgs const & args)
188{
189 Cmds cmds {
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"},
195 };
196 doMenu(args,cmds);
197}
198
199void cmdApply(CLArgs const &);
200void cmd3Controls(CLArgs const &);
201void cmd3Coord(CLArgs const &);
202void cmd3Create(CLArgs const &);
203void cmd3Random(CLArgs const &);
204void cmd3Util(CLArgs const &);
205void cmd3View(CLArgs const &);
206
207Cmds getFg3Cmds()
208{
209 return {
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)"},
221 };
222}
223
228void cmdFg3(CLArgs const & args)
229{
230 if (args.size() == 1)
231 fgout << fgnl << "FaceGen Main SDK CLI " << getSdkVersion(".") << " (" << getCurrentBuildDescription() << ")";
232 doMenu(args,getFg3Cmds(),false,true);
233}
234
235}
void getDetail(ImgRgba8 &img) const
Decode the JPEG detail texture into FG image format:
FanSymmE
Enumerate symmetry types.
Definition Fg3Face.hpp:37
void fg3Interactive(Sam3Coord &coord, FanSymmE symmetry, const Ssm3 &ssm, uint vertexIndex, Vec3F vertexDelta)
@ FANSYMM_SYMM
Symmetric.
Definition Fg3Face.hpp:39
@ FANSYMM_ASYM
Asymmetric.
Definition Fg3Face.hpp:41
void cmd3Coord(CLArgs const &)
void cmd3Create(CLArgs const &)
void cmd3DetailExtract(CLArgs const &args)
Definition Fg3Cmd.cpp:30
void cmd3View(CLArgs const &)
void cmd3Random(CLArgs const &)
void cmd3Util(CLArgs const &)
void cmd3Interactive(CLArgs const &args)
Definition Fg3Cmd.cpp:103
void cmd3Controls(CLArgs const &)