32 #include "DGtal/base/Common.h"
34 #include "DGtal/io/Display3D.h"
35 #include "DGtal/io/viewers/Viewer3D.h"
36 #include "DGtal/io/readers/MeshReader.h"
37 #include "DGtal/helpers/StdDefs.h"
38 #include "DGtal/io/readers/PointListReader.h"
43 using namespace DGtal;
104 class CustomViewer3D :
public Viewer3D<>
114 virtual void keyPressEvent(QKeyEvent *e)
116 bool handled =
false;
117 if (e->key() == Qt::Key_I)
120 myIsDisplayingInfoMode = !myIsDisplayingInfoMode;
122 qglviewer::Vec camPos = camera()->position();
124 ss << myInfoDisplay <<
" distance to camera: " << (c - centerMesh).norm();
139 myDefaultBackgroundColor = col;
143 std::string myInfoDisplay =
"No information loaded...";
144 bool myIsDisplayingInfoMode =
false;
148 int main(
int argc,
char **argv)
154 unsigned int meshColorR{240};
155 unsigned int meshColorG{240};
156 unsigned int meshColorB{240};
157 unsigned int meshColorA{255};
159 unsigned int meshColorRLine{0};
160 unsigned int meshColorGLine{0};
161 unsigned int meshColorBLine{0};
162 unsigned int meshColorALine{255};
164 unsigned int sdpColorR{240};
165 unsigned int sdpColorG{240};
166 unsigned int sdpColorB{240};
167 unsigned int sdpColorA{255};
169 float lineWidth{1.5};
171 std::vector<unsigned int> customColorMesh;
172 std::vector<unsigned int> customColorSDP;
173 std::vector<unsigned int> customLineColor;
174 std::vector<unsigned int> customBGColor;
175 std::vector<unsigned int> customAlphaMesh;
176 std::vector<unsigned int> vectFieldIndices = {0, 1, 2, 3, 4, 5};
177 std::string displayVectorField;
179 std::string snapshotFile;
180 std::string filenameSDP;
181 double ballRadius{0.5};
182 bool invertNormal{
false};
183 bool drawVertex{
false};
184 bool useLastCamSet{
false};
185 bool fixLightToScene{
false};
186 float ambiantLight{0.0};
190 std::vector<std::string> inputFileNames;
191 std::string outputFileName{
"result.raw"};
192 app.description(
"Display OFF mesh file by using QGLviewer");
193 app.add_option(
"-i,--input,1", inputFileNames,
"inputFileNames.off files (.off), or OFS file (.ofs)")
194 ->check(CLI::ExistingFile)
196 app.add_option(
"-x,--scaleX", sx,
"set the scale value in the X direction (default 1.0)");
197 app.add_option(
"-y,--scaleY", sy,
"set the scale value in the y direction (default 1.0)");
198 app.add_option(
"-z,--scaleZ", sz,
"set the scale value in the z direction (default 1.0)");
199 app.add_option(
"--minLineWidth", lineWidth,
"set the min line width of the mesh faces (default 1.5)",
true);
200 app.add_option(
"--customColorMesh", customColorMesh,
"set the R, G, B, A components of the colors of the mesh faces and eventually the color R, G, B, A of the mesh edge lines (set by default to black).");
201 app.add_option(
"--customAlphaMesh", customAlphaMesh,
"set the alpha(A) components of the colors of the mesh faces (can be applied for each mesh).");
202 app.add_option(
"--customColorSDP", customColorSDP,
"set the R, G, B, A components of the colors of the sdp view")
204 app.add_option(
"--displayVectorField,-f", displayVectorField,
"display a vector field from a simple sdp file (two points per line)");
205 app.add_option(
"--vectorFieldIndex", vectFieldIndices,
"specify special indices for the two point coordinates (instead usinf the default indices: 0 1, 2, 3, 4, 5)")
207 app.add_option(
"--customLineColor", customLineColor,
"set the R, G, B components of the colors of the lines displayed from the --displayVectorField option (red by default).")
209 app.add_option(
"--SDPradius", ballRadius,
"change the ball radius to display a set of discrete points (used with displaySDP option)",
true);
210 app.add_option(
"--displaySDP,-s", filenameSDP,
"add the display of a set of discrete points as ball of radius 0.5.");
211 app.add_option(
"--addAmbientLight,-A", ambiantLight,
"add an ambient light for better display (between 0 and 1).");
212 app.add_option(
"--customBGColor,-b", customBGColor,
"set the R, G, B components of the colors of the background color.")
214 app.add_option(
"--doSnapShotAndExit,-d", snapshotFile,
"save display snapshot into file. Notes that the camera setting is set by default according the last saved configuration (use SHIFT+Key_M to save current camera setting in the Viewer3D). If the camera setting was not saved it will use the default camera setting.");
215 app.add_flag(
"--useLastCameraSetting,-c", useLastCamSet,
"use the last camera setting of the user (i.e if a .qglviewer.xml file is present in the current directory)");
216 app.add_flag(
"--fixLightToScene,-l", fixLightToScene,
"Fix light source to scence instead to camera");
217 app.add_flag(
"--invertNormal,-n", invertNormal,
"invert face normal vectors.");
218 app.add_flag(
"--drawVertex,-v", drawVertex,
"draw the vertex of the mesh");
220 app.get_formatter()->column_width(40);
221 CLI11_PARSE(app, argc, argv);
225 if (customLineColor.size() == 4)
227 vFieldLineColor.
setRGBi(customLineColor[0], customLineColor[1], customLineColor[2], 255);
230 if (customColorMesh.size() != 0)
232 if (customColorMesh.size() < 4)
234 trace.
error() <<
"colors specification should contain R,G,B and Alpha values" << std::endl;
238 if (customColorSDP.size() == 4)
240 sdpColorR = customColorSDP[0];
241 sdpColorG = customColorSDP[1];
242 sdpColorB = customColorSDP[2];
243 sdpColorA = customColorSDP[3];
246 QApplication application(argc, argv);
247 CustomViewer3D viewer;
248 if (snapshotFile !=
"")
250 viewer.setSnapshotFileName(QString(snapshotFile.c_str()));
253 std::stringstream title;
254 title <<
"Simple Mesh Viewer: " << inputFileNames[0];
255 viewer.setWindowTitle(title.str().c_str());
257 viewer.myGLLineMinWidth = lineWidth;
258 viewer.setGLScale(sx, sy, sz);
259 if (customBGColor.size() == 3)
261 viewer.changeDefaultBGColor(
DGtal::Color(customBGColor[0],
263 customBGColor[2], 255));
265 if (ambiantLight != 0.0)
267 GLfloat lightAmbientCoeffs[4] = {ambiantLight, ambiantLight, ambiantLight, 1.0f};
268 viewer.setGLLightAmbientCoefficients(lightAmbientCoeffs);
273 std::vector<Mesh<DGtal::Z3i::RealPoint>> vectMesh;
274 for (
unsigned int i = 0; i < inputFileNames.size(); i++)
277 aMesh << inputFileNames[i];
279 if (aMesh.isStoringFaceColors() && customColorMesh.size() >= 4)
281 if (i * 8 < customColorMesh.size())
283 meshColorR = customColorMesh[i * 8];
285 if (i * 8 + 1 < customColorMesh.size())
287 meshColorG = customColorMesh[i * 8 + 1];
289 if (i * 8 + 2 < customColorMesh.size())
291 meshColorB = customColorMesh[i * 8 + 2];
293 if (i * 8 + 3 < customColorMesh.size())
295 meshColorA = customColorMesh[i * 8 + 3];
297 for (
unsigned int j = 0; j < aMesh.nbFaces(); j++)
299 aMesh.setFaceColor(j,
Color(meshColorR, meshColorG, meshColorB, meshColorA));
302 else if (customAlphaMesh.size() > 0)
304 for (
unsigned int j = 0; j < aMesh.nbFaces(); j++)
306 auto c = aMesh.getFaceColor(j);
307 aMesh.setFaceColor(j,
Color(c.red(), c.green(), c.blue(), customAlphaMesh.at(i < customAlphaMesh.size() ? i : 0)));
311 vectMesh.push_back(aMesh);
314 unsigned int tot = 0;
315 for (
const auto &m : vectMesh)
317 for (
auto p = m.vertexBegin(); p != m.vertexEnd(); ++p)
322 viewer.centerMesh = centerMeshes;
323 bool import = vectMesh.
size() == inputFileNames.size();
326 trace.
info() <<
"File import failed. " << std::endl;
331 if (filenameSDP !=
"")
333 if (customAlphaMesh.size() > 0)
335 trace.
info() <<
"New meshViewer" << std::endl;
338 Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA));
339 for (
auto l : vOrigins)
343 viewer.setFillColor(cl);
344 viewer.addBall(pt, ballRadius);
349 vector<Z3i::RealPoint> vectPoints;
352 Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA));
353 for (
unsigned int i = 0; i < vectPoints.size(); i++)
355 viewer.addBall(vectPoints.at(i), ballRadius);
361 for (
unsigned int i = 0; i < vectMesh.size(); i++)
363 vectMesh[i].invertVertexFaceOrder();
367 for (
unsigned int i = 0; i < vectMesh.size(); i++)
369 if (i * 8 < customColorMesh.size())
371 meshColorR = customColorMesh[i * 8];
373 if (i * 8 + 1 < customColorMesh.size())
375 meshColorG = customColorMesh[i * 8 + 1];
377 if (i * 8 + 2 < customColorMesh.size())
379 meshColorB = customColorMesh[i * 8 + 2];
381 if (i * 8 + 3 < customColorMesh.size())
383 meshColorA = customColorMesh[i * 8 + 3];
385 if (i * 8 + 4 < customColorMesh.size())
387 meshColorALine = customColorMesh[i * 8 + 4];
389 if (i * 8 + 5 < customColorMesh.size())
391 meshColorBLine = customColorMesh[i * 8 + 5];
393 if (i * 8 + 6 < customColorMesh.size())
395 meshColorRLine = customColorMesh[i * 8 + 6];
397 if (i * 8 + 7 < customColorMesh.size())
399 meshColorALine = customColorMesh[i * 8 + 7];
404 Color(meshColorR, meshColorG, meshColorB, meshColorA));
406 viewer << vectMesh[i];
411 for (
unsigned int i = 0; i < vectMesh.size(); i++)
425 if (displayVectorField !=
"")
427 std::vector<unsigned int> vectFieldIndices1 = {vectFieldIndices[0], vectFieldIndices[1], vectFieldIndices[2]};
428 std::vector<unsigned int> vectFieldIndices2 = {vectFieldIndices[3], vectFieldIndices[4], vectFieldIndices[5]};
431 viewer.createNewLineList();
432 for (
unsigned int i = 0; i < vectPt1.size(); i++)
434 viewer.setLineColor(vFieldLineColor);
435 viewer.addLine(vectPt1[i], vectPt2[i]);
438 unsigned int nbVertex = 0;
439 unsigned int nbFaces = 0;
440 for (
auto const &m : vectMesh)
442 nbVertex += m.nbVertex();
443 nbFaces += m.nbFaces();
446 ss <<
"# faces: " << std::fixed << nbFaces <<
" #vertex: " << nbVertex;
447 viewer.myInfoDisplay = ss.str();
451 viewer.setLightModeFixToCamera(
false,
false);
456 viewer.restoreStateFromFile();
461 viewer.saveStateToFile();
464 viewer.sortTriangleFromCamera();
465 viewer.sortQuadFromCamera();
466 viewer.sortSurfelFromCamera();
467 viewer.sortPolygonFromCamera();
470 if (snapshotFile !=
"")
473 viewer.restoreStateFromFile();
474 viewer.saveSnapshot(QString(snapshotFile.c_str()),
true);
477 trace.
info() <<
"[display ready]" << std::endl;
479 return application.exec();
int main(int argc, char **argv)
Color & setRGBi(const unsigned char aRedValue, const unsigned char aGreenValue, const unsigned char aBlueValue, const unsigned char aAlphaValue)
ConstIterator vertexEnd() const
Trace trace(traceWriterTerm)