FaceGen 3 SDKs Reference
Loading...
Searching...
No Matches
Fg3CmdView.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#include "Fg3SamGui.hpp"
12#include "Fg3dMeshIo.hpp"
13#include "Fg3dDisplay.hpp"
14#include "FgGuiApi.hpp"
15#include "bootPoints.hpp"
16#include "FgImgDisplay.hpp"
17#include "FgImageDraw.hpp"
18#include "FgApply.hpp"
19#include "FgFileSystem.hpp"
20
21using namespace std;
22
23namespace Fg {
24
25namespace {
26
27void cmdViewDna(CLArgs const & args)
28{
29 Syntax syn {args,R"(<face>.dna)"};
30 Meshes meshes = dnaImport(loadRaw(syn.next()));
31 viewMesh(meshes);
32}
33
34void viewFg3(Face3s const & faces)
35{
36 FGASSERT(!faces.empty());
37 Sam3 sam {dataDir()+"tools/internal/InternalBaseFace"};
38 Face3 face = faces[0];
39 String8 store = getDirUserAppDataLocalFaceGen({"SDK","viewFg3"});
40 Sam3Controls ctrls(dataDir() + "main/si.ctl");
41 IPT<Sam3Coord> coordN(face.coord);
42 IPT<Bytes> detailN(face.detail);
43 IPT<double> texModStrengthN {1.0};
44 Ssm3Ns ssmNs;
45 GuiMorphMeshes gpms;
46 Mat32F bounds = cBounds(sam.ssm.meanVerts);
47 Mesh const & mesh = sam.mesh;
48 bounds = cBoundsUnion(bounds,cBounds(sam.ssm.meanVerts));
49 ssmNs.push_back(makeIPT(sam.ssm));
50 IPT<Mesh> meshN(mesh);
51 Ssm3 const & ssm = sam.ssm;
52 auto applySsm = [=](Sam3Coord const & coord)
53 {
54 return ssm.applyCoord(coord); // Handles empty ssm
55 };
56 OPT<Vec3Fs> identVertsN = link1(coordN,applySsm);
57 Svec<IPT<Scm3>> scmNs;
58 Svec<NPT<ImgRgba8>> smoothNs;
59 Svec<NPT<ImgRgba8>> detailMapNs;
60 for (Scm3 const & scm : sam.scms) {
61 scmNs.emplace_back(scm);
62 smoothNs.push_back(linkApplyScmNoDetail(scmNs.back(),coordN));
63 detailMapNs.push_back(linkXformDetail(scmNs.back(),detailN));
64 }
65 while (scmNs.size() < mesh.surfaces.size()) {
66 scmNs.push_back(IPT<Scm3>{});
67 smoothNs.emplace_back(IPT<ImgRgba8>{});
68 detailMapNs.emplace_back(IPT<ImgRgba8>{});
69 }
70 gpms.addMesh(meshN,identVertsN,smoothNs,{},detailMapNs);
71 IPT<Mat32D> viewBoundsN {Mat32D(bounds)};
72 Gui3d gui3d {makeIPT(gpms.rendMeshes)};
73 gui3d.texModStrengthN = texModStrengthN;
74 gui3d.ctlDragAction = makeInteractiveDeformation(coordN,ssmNs);
75 gui3d.fileDragDrop = cLoadFgFileFunc(coordN,detailN);
76 SamGuiUndo sgu = sam3GuiUndo(coordN,detailN,store+"Undo");
77 GuiTabDefs tabs = {
78 {"Modify",sam3GuiModify(ctrls,coordN,detailN,texModStrengthN,gui3d.capture,store+"Modify",true)},
79 {"Basis",sam3GuiBasis(coordN)},
80 {"View",makeViewCtrls(gui3d,viewBoundsN,store+"View")},
81 {"Undo",sgu.win,true}
82 };
83 if (faces.size() > 1) {
84 GuiPtrs sels;
85 for (size_t ii=0; ii<faces.size(); ++ii) {
86 auto fn = [faces,coordN,detailN,ii]()
87 {
88 Face3 const & face = faces[ii];
89 coordN.set(face.coord);
90 detailN.set(face.detail);
91 };
92 sels.push_back(guiButton("Face "+toStr(ii),fn));
93 }
94 tabs.emplace_back("Select",guiSplitV(sels));
95 }
96 GuiOptions opts;
97 opts.onUpdate = sgu.onUpdate;
98 guiStartImpl(
99 makeIPT<String8>("FaceGen SDK viewFg3"),
100 guiSplitAdj(true,make_shared<Gui3d>(gui3d),guiTabs(tabs)),
101 store,
102 opts);
103}
104
105void cmdViewFg(CLArgs const & args)
106{
107 Syntax syn {args,R"((<face>.fg)+
108NOTES:
109 If viewing more than one face, use the 'Select' tab to toggle between them.)"
110 };
111 Face3s faces;
112 while (syn.more()) {
113 Face3 face;
114 face.load(syn.next());
115 fgout << fgnl << "Face " << faces.size() << fgpush << face << fgpop;
116 if (!faces.empty()) {
117 Floats f1 = face.coord.getVector(),
118 f0 = faces.back().coord.getVector();
119 if (f1.size() == f0.size())
120 fgout << fgnl << "Coordinate RMS delta from previous: " << cRms(f0-f1);
121 }
122 faces.push_back(face);
123 }
124 viewFg3(faces);
125}
126
127void cmdViewFim(CLArgs const & args)
128{
129 Syntax syn {args,"<in>.fim"};
130 Img2F fim = loadFim(syn.next());
131 ImgRgba8 img {fim.dims()};
132 Vec2F const invalid {-1,-1};
133 Rgba8 const blue {0,0,255,255};
134 for (Iter2UI it {img.dims()}; it.valid(); it.next()) {
135 Vec2F in = fim[it()];
136 if (in == invalid)
137 img[it()] = blue;
138 else {
139 uchar r = scast<uchar>(in[0]*255.9f),
140 g = scast<uchar>(in[1]*255.9f);
141 img[it()] = {r,g,0,255};
142 }
143 }
144 fgout
145 << fgnl << "Transform (x/col,y/row) mapped to (red,green), invalid areas to blue."
146 << fgnl << "Resampling bounds:" << cBounds(fim.m_data);
147 viewImage(img);
148}
149
150void cmdViewSam(CLArgs const & args)
151{
152 Syntax syn {args,
153 R"([<face>.fg] (<sam> | -s <ssm> [-c <scm>]+ )+
154 <sam> - loads both <ssm> and <scm> files described below using <sam>
155 <ssm> - loads <ssm>.(fgmesh|tri) (required), and <ssm>.egm (optional)
156 <scm> - loads <scm>.(jpg,png,tga,bmp) (required), and <scm>.egt , <scm>.fim (optional)
157NOTES:
158 * The <sam> argument is for SAMs with one color map and all files stored with the same base name.
159 * In the case of more than one color map, or different names for the SSM/SCM, use the second option.)"
160 };
161 Face3 face;
162 if (pathToExt(syn.peekNext()) == "fg")
163 face.load(syn.next());
164 Sam3s sams;
165 do {
166 if (syn.next() == "-s") {
167 Mesh mesh = loadMeshAnyFormat(syn.next());
168 Ssm3 ssm {syn.curr()};
169 Scm3s scms;
170 while (syn.more() && syn.peekNext() == "-c") {
171 syn.next();
172 scms.emplace_back(syn.next());
173 }
174 sams.emplace_back(mesh,ssm,scms);
175 }
176 else
177 sams.emplace_back(syn.curr());
178 }
179 while (syn.more());
180 viewSam3(face,sams);
181}
182
183}
184
189void cmd3View(CLArgs const & args)
190{
191 Cmds cmds {
192 {cmdViewDna,"dna","view Metahuman .dna file meshes"},
193 {cmdViewFg,"fg","View an FG file with the internal model set"},
194 {cmdViewFim,"fim","Image transform map (.FIM) from an SCM"},
195 {cmdViewSam,"sam","View a SAM"},
196 };
197 doMenu(args,cmds);
198}
199
200}
void cmd3View(CLArgs const &)