FaceGen 3 SDKs Reference
Loading...
Searching...
No Matches
Fg3CmdControls.cpp
1//
2// Copyright (c) Singular Inversions Inc. 2012
3//
4// Authors: Andrew Beatty
5// Created: Feb 16, 2012
6//
7
8#include "stdafx.h"
9
10#include "Fg3Face.hpp"
11#include "Fg3Controls.hpp"
12#include "FgCommand.hpp"
13
14#include "FgSerial.hpp"
15#include "FgFileSystem.hpp"
16#include "FgTestUtils.hpp"
17
18using namespace std;
19
20namespace Fg {
21
22namespace {
23
24void tween(CLArgs const & args)
25{
26 Syntax syn(args,
27 "<in0>.fg <in1>.fg <val> <out>.fg \n"
28 " <val> = interpolation value: 0 gives <in0>.fg, 1 gives <in1>.fg"
29 );
30
31 if (args.size() == 1)
32 syn.error();
33 Face3 in0(syn.next()),
34 in1(syn.next());
35 float iv = syn.nextAs<float>();
36 Face3 out = in0;
37 out.coord = in0.coord * (1.0f - iv) + in1.coord * iv;
38 out.save(syn.next());
39}
40
41void linearList(CLArgs const &)
42{
43 Sam3Controls ctls(dataDir()+"main/si.ctl");
44 for (uint tt=0; tt<2; ++tt) {
45 PushIndent optt(fg3ModeTypeStrs.at(tt) + ":");
46 for (uint ss=0; ss<2; ++ss) {
47 PushIndent opss(fg3ModeSymmStrs.at(ss) + ":");
48 size_t numCtls = ctls.getSliderNum(FanTypeE(tt),FanSymmE(ss));
49 for (size_t ii=0; ii<numCtls; ++ii)
50 fgout << fgnl << toStrDigits(ii,2) << " " << ctls.getSliderName(FanTypeE(tt),FanSymmE(ss),ii);
51 }
52 }
53}
54
55void linearEdit(CLArgs const & args)
56{
57 Syntax syn(args,
58 "<faceIn>.fg [<type> <symm> <index> [<value> <faceOut>.fg] ]\n"
59 " <type> - ( shape | color )\n"
60 " <symm> - ( symm | asym ) // Note that there are no 'asym' 'color' modes\n"
61 " <index> - Index of desired control to view / modify:\n"
62 "NOTES:\n"
63 " * If no <type> is given, all controls will be listed by index, value, name.\n"
64 " * If no <value> is given, the selected control's value and name will be output.\n"
65 " * Otherwise, the specified control will be set to <value> and stored in <faceOut>.fg"
66 );
67 Sam3Controls ctls(dataDir()+"main/si.ctl");
68 Face3 face(syn.next());
69 if (!syn.more()) {
70 for (uint tt=0; tt<2; ++tt) {
71 PushIndent optt(fg3ModeTypeStrs.at(tt) + ":");
72 for (uint ss=0; ss<2; ++ss) {
73 PushIndent opss(fg3ModeSymmStrs.at(ss) + ":");
74 size_t numCtls = ctls.getSliderNum(FanTypeE(tt),FanSymmE(ss));
75 for (size_t ii=0; ii<numCtls; ++ii) {
76 fgout << fgnl << toStrDigits(ii,2) << " "
77 << ctls.getSliderVal(face.coord,FanTypeE(tt),FanSymmE(ss),ii) << " "
78 << ctls.getSliderName(FanTypeE(tt),FanSymmE(ss),ii);
79 }
80 }
81 }
82 return;
83 }
84 FanTypeE type = FanTypeE(syn.nextSelectionIndex(fg3ModeTypeStrs,"<type>"));
85 FanSymmE symm = FanSymmE(syn.nextSelectionIndex(fg3ModeSymmStrs,"<symm>"));
86 size_t index = syn.nextAs<size_t>();
87 float valInitial = ctls.getSliderVal(face.coord,type,symm,index);
88 if (!syn.more()) {
89 fgout << fgnl << toStrDigits(index,2) << " " << valInitial << " " << ctls.getSliderName(type,symm,index);
90 return;
91 }
92 float value = syn.nextAs<float>();
93 ctls.setSliderVal_(face.coord,type,symm,index,value);
94 face.save(syn.next());
95 fgout << fgnl << toStrDigits(index,2) << " " << ctls.getSliderName(type,symm,index)
96 << fgnl << "Value changed from " << valInitial << " to " << ctls.getSliderVal(face.coord,type,symm,index);
97}
98
99void linearExport(CLArgs const & args)
100{
101 Syntax syn(args,"<face>.fg <base>\n"
102 "NOTES:\n"
103 " The following text files will be created, each listing the index, value and name of the\n"
104 " respective linear controls:\n"
105 " <base>_shape_symm.txt\n"
106 " <base>_shape_asym.txt\n"
107 " <base>_color_symm.txt"
108 );
109 Sam3Controls ctls(dataDir()+"main/si.ctl");
110 Face3 face(syn.next());
111 string base(syn.next());
112 for (uint tt=0; tt<2; ++tt) {
113 string base_type = base + "_" + fg3ModeTypeStrs.at(tt);
114 for (uint ss=0; ss<2; ++ss) {
115 string base_type_symm = base_type + "_" + fg3ModeSymmStrs.at(ss) + ".txt";
116 Ofstream ofs(base_type_symm);
117 size_t numCtls = ctls.getSliderNum(FanTypeE(tt),FanSymmE(ss));
118 for (size_t ii=0; ii<numCtls; ++ii) {
119 ofs << toStrDigits(ii,2) << " "
120 << ctls.getSliderVal(face.coord,FanTypeE(tt),FanSymmE(ss),ii) << " "
121 << ctls.getSliderName(FanTypeE(tt),FanSymmE(ss),ii) << "\n";
122 }
123 }
124 }
125}
126
127void linear(CLArgs const & args)
128{
129 Cmds cmds;
130 cmds.push_back(Cmd(linearList,"list","List all linear controls by index and name"));
131 cmds.push_back(Cmd(linearEdit,"edit","View or set control values from the 'Shape' and 'Color' tabs"));
132 cmds.push_back(Cmd(linearExport,"export","Export linear control values of a face to text files"));
133 doMenu(args,cmds);
134}
135
136string getDemogVals(Sam3Controls const & ctls,Sam3Coord const & coord,FanTypeE type)
137{
138 ostringstream os;
139 os << "Age " << ctls.getAge(coord,type) << "\n"
140 "Gender " << ctls.getGender(coord,type) << "\n"
141 "CaricatureShape " << ctls.getCaricature(coord,FANRACE_ALL,FANTYPE_GEO) << "\n"
142 "CaricatureColor " << ctls.getCaricature(coord,FANRACE_ALL,FANTYPE_TEX) << "\n"
143 "Asymmetry " << ctls.getAsymmetry(coord) << "\n"
144 "African " << ctls.getRace(coord,FANRACE_ALL,FANRACE_AFRO,type) << "\n"
145 "EastAsian " << ctls.getRace(coord,FANRACE_ALL,FANRACE_EASIA,type) << "\n"
146 "SouthAsian " << ctls.getRace(coord,FANRACE_ALL,FANRACE_SASIA,type) << "\n"
147 "European " << ctls.getRace(coord,FANRACE_ALL,FANRACE_EURO,type) << "\n";
148 return os.str();
149}
150
151void cmdDemogEdit(CLArgs const & args)
152{
153 Syntax syn {args,R"([-s | -c] <in>.fg [<control> <value> <out>.fg]
154 -s - only view or edit the shape subspace of this control (age, gender & racial groups only)
155 -c - only view or edit the color subspace of this control (age, gender & racial groups only)
156 <in>.fg - face coordinate to view or edit
157 <control> - ( age | gender | caricatureshape | caricaturecolor |
158 asymmetry | african | eastasian | southasian | european)
159 <value> - The new value to set the control to:
160 age (years)
161 gender (-1 average male, 1 average female)
162 caricatureshape (1 is average. Must be > 0)
163 caricaturecolor (1 is average. Must be > 0)
164 asymmetry (1 is average. Must be > 0)
165 african | eastasian | southasian | european (1 is similar)
166NOTES:
167 * If only <in>.fg is specified, the values of all controls will be printed.)"
168 };
169 Sam3Controls ctls {dataDir()+"main/si.ctl"};
170 FanTypeE type = FANTYPE_SIZE; // view/edit combined shape & color
171 if (syn.peekNext() == "-s") {
172 type = FANTYPE_GEO;
173 syn.next();
174 }
175 else if (syn.peekNext() == "-c") {
176 type = FANTYPE_TEX;
177 syn.next();
178 }
179 Face3 face {syn.next()};
180 if (!syn.more()) {
181 fgout << '\n' << getDemogVals(ctls,face.coord,type);
182 return;
183 }
184 String control = syn.next();
185 float valInitial,
186 value = syn.nextAs<float>();
187 if (control == "age") {
188 valInitial = ctls.getAge(face.coord,type);
189 ctls.setAge_(face.coord,type,value);
190 }
191 else if (control == "gender") {
192 valInitial = ctls.getGender(face.coord);
193 ctls.setGender_(face.coord,type,value);
194 }
195 else if (control == "caricatureshape") {
196 valInitial = ctls.getCaricature(face.coord,FANRACE_ALL,FANTYPE_GEO);
197 ctls.setCaricature_(face.coord,FANRACE_ALL,FANTYPE_GEO,value);
198 }
199 else if (control == "caricaturecolor") {
200 valInitial = ctls.getCaricature(face.coord,FANRACE_ALL,FANTYPE_TEX);
201 ctls.setCaricature_(face.coord,FANRACE_ALL,FANTYPE_TEX,value);
202 }
203 else if (control == "asymmetry") {
204 valInitial = ctls.getAsymmetry(face.coord);
205 ctls.setAsymmetry_(face.coord,value);
206 }
207 else if (control == "african") {
208 valInitial = ctls.getRace(face.coord,FANRACE_ALL,FANRACE_AFRO,type);
209 ctls.setRace_(face.coord,FANRACE_ALL,FANRACE_AFRO,value,type);
210 }
211 else if (control == "eastasian") {
212 valInitial = ctls.getRace(face.coord,FANRACE_ALL,FANRACE_EASIA,type);
213 ctls.setRace_(face.coord,FANRACE_ALL,FANRACE_EASIA,value,type);
214 }
215 else if (control == "southasian") {
216 valInitial = ctls.getRace(face.coord,FANRACE_ALL,FANRACE_SASIA,type);
217 ctls.setRace_(face.coord,FANRACE_ALL,FANRACE_SASIA,value,type);
218 }
219 else if (control == "european") {
220 valInitial = ctls.getRace(face.coord,FANRACE_ALL,FANRACE_EURO,type);
221 ctls.setRace_(face.coord,FANRACE_ALL,FANRACE_EURO,value,type);
222 }
223 else {
224 valInitial = 0.0f; // Avoid gcc warning - below statement throws anyway.
225 syn.error("Invalid value for <control>",control);
226 }
227 face.save(syn.next());
228 fgout << fgnl << control << " value changed from " << valInitial << " to " << value;
229}
230
231void cmdDemogExport(CLArgs const & args)
232{
233 Syntax syn {args,"<face>.fg <out>.txt\n"
234 " Creates a <out>.txt containing the demographic control values of <face>.fg"
235 };
236 Sam3Controls ctls {dataDir()+"main/si.ctl"};
237 Face3 face {syn.next()};
238 Ofstream ofs {syn.next()};
239 ofs << getDemogVals(ctls,face.coord,FANTYPE_SIZE);
240}
241
242void cmdDemog(CLArgs const & args)
243{
244 Cmds cmds {
245 {cmdDemogEdit,"edit","View or set demographics control values"},
246 {cmdDemogExport,"export","Export linear control values of a face to text files"},
247 };
248 doMenu(args,cmds);
249}
250
251void genetic(CLArgs const & args)
252{
253 Syntax syn(args,"<faceIn>.fg <randomness> <faceOut>.fg\n"
254 " <randomness> - Amount of perturbation in per-dimension standard deviations in the range (0,1]."
255 );
256 Sam3Controls ctls(dataDir()+"main/si.ctl");
257 Face3 face(syn.next());
258 float randomness = strTo<float>(syn.next());
259 if ((randomness <= 0.0f) || (randomness > 1.0f))
260 fgThrow("Randomness must be in the range (0,1]",syn.curr());
262 face.coord = ctls.genCtrls.geneticRandom(randomness,face.coord);
263 face.save(syn.next());
264}
265
266}
267
272void cmd3Controls(CLArgs const & args)
273{
274 Cmds cmds {
275 {tween,"tween","Interpolate between two face coordinates"},
276 {linear,"linear","Controls from the 'Shape' and 'Color' tabs in our GUI products"},
277 {cmdDemog,"demographic","Controls from the 'Demographics' tab in our GUI products"},
278 {genetic,"genetic","Randomly perturb face coordinates for a genetic interface"},
279 };
280 doMenu(args,cmds);
281}
282
283}
FanTypeE
Enumerate the statistical model types.
Definition Fg3Face.hpp:25
FanSymmE
Enumerate symmetry types.
Definition Fg3Face.hpp:37
@ FANTYPE_TEX
Texture (color)
Definition Fg3Face.hpp:29
@ FANTYPE_GEO
Geometry (shape)
Definition Fg3Face.hpp:27
void cmd3Controls(CLArgs const &)