DGtalTools  1.2.0
meshViewer.cpp
1 
30 #include <iostream>
31 #include <sstream>
32 #include "DGtal/base/Common.h"
33 
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"
39 
40 
41 #include "CLI11.hpp"
42 
43 
44 using namespace std;
45 using namespace DGtal;
46 
47 
104 class CustomViewer3D: public Viewer3D<>
105 {
106 protected:
107 
108  virtual void init()
109  {
110  Viewer3D<>::init();
111  Viewer3D<>::setKeyDescription ( Qt::Key_I, "Display mesh informations about #faces, #vertices" );
112  Viewer3D<>::setGLDoubleRenderingMode(false);
113  if(mySaveSnap){
114  QObject::connect(this, SIGNAL(drawFinished(bool)), this, SLOT(saveSnapshot(bool)));
115  }
116  }
117  virtual void keyPressEvent(QKeyEvent *e){
118  bool handled = false;
119  if( e->key() == Qt::Key_I)
120  {
121  handled=true;
122  myIsDisplayingInfoMode = !myIsDisplayingInfoMode;
123  stringstream ss;
124  qglviewer::Vec camPos = camera()->position();
125  DGtal::Z3i::RealPoint c (camPos[0], camPos[1], camPos[2]);
126  ss << myInfoDisplay << " distance to camera: " << (c-centerMesh).norm();
127  Viewer3D<>::displayMessage(QString(myIsDisplayingInfoMode ?
128  ss.str().c_str() : " "), 1000000);
129 
130  Viewer3D<>::update();
131  }
132 
133  if(!handled)
134  {
135  Viewer3D<>::keyPressEvent(e);
136  }
137  };
138 
139 public:
140  std::string myInfoDisplay = "No information loaded...";
141  bool myIsDisplayingInfoMode = false;
142  bool mySaveSnap = false;
143  DGtal::Z3i::RealPoint centerMesh;
144 };
145 
146 
147 int main( int argc, char** argv )
148 {
149  float sx {1.0};
150  float sy {1.0};
151  float sz {1.0};
152 
153  unsigned int meshColorR {240};
154  unsigned int meshColorG {240};
155  unsigned int meshColorB {240};
156  unsigned int meshColorA {255};
157 
158  unsigned int meshColorRLine {0};
159  unsigned int meshColorGLine {0};
160  unsigned int meshColorBLine {0};
161  unsigned int meshColorALine {255};
162 
163  unsigned int sdpColorR {240};
164  unsigned int sdpColorG {240};
165  unsigned int sdpColorB {240};
166  unsigned int sdpColorA {255};
167 
168  float lineWidth {1.5};
169 
170  std::vector<unsigned int > customColorMesh;
171  std::vector<unsigned int > customColorSDP;
172  std::vector<unsigned int > customLineColor;
173  std::vector<unsigned int > vectFieldIndices = {0,1,2,3,4,5};
174  std::string displayVectorField;
175 
176  std::string snapshotFile;
177  std::string filenameSDP;
178  double ballRadius {0.5};
179  bool invertNormal {false};
180  bool drawVertex {false};
181  float ambiantLight {0.0};
182 
183 
184  // parse command line using CLI ----------------------------------------------
185  CLI::App app;
186  std::vector<std::string> inputFileNames;
187  std::string outputFileName {"result.raw"};
188  app.description("Display OFF mesh file by using QGLviewer");
189  app.add_option("-i,--input,1", inputFileNames, "inputFileNames.off files (.off), or OFS file (.ofs)" )
190  ->check(CLI::ExistingFile)
191  ->required();
192  app.add_option("-x,--scaleX", sx, "set the scale value in the X direction (default 1.0)");
193  app.add_option("-y,--scaleY", sy, "set the scale value in the y direction (default 1.0)");
194  app.add_option("-z,--scaleZ", sz, "set the scale value in the z direction (default 1.0)");
195  app.add_option("--minLineWidth", lineWidth, "set the min line width of the mesh faces (default 1.5)", true);
196  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).");
197 
198  app.add_option("--customColorSDP", customColorSDP, "set the R, G, B, A components of the colors of the sdp view")
199  ->expected(4);
200  app.add_option("--displayVectorField,-f", displayVectorField, "display a vector field from a simple sdp file (two points per line)");
201  app.add_option("--vectorFieldIndex", vectFieldIndices, "specify special indices for the two point coordinates (instead usinf the default indices: 0 1, 2, 3, 4, 5)" )
202  ->expected(6);
203  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).")
204  ->expected(4);
205  app.add_option("--SDPradius", ballRadius, "change the ball radius to display a set of discrete points (used with displaySDP option)", true);
206  app.add_option("--displaySDP,-s", filenameSDP, "add the display of a set of discrete points as ball of radius 0.5.");
207  app.add_option("--addAmbientLight,-A", ambiantLight, "add an ambient light for better display (between 0 and 1)." );
208  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.");
209  app.add_flag("--invertNormal,-n", invertNormal, "invert face normal vectors.");
210  app.add_flag("--drawVertex,-v", drawVertex, "draw the vertex of the mesh");
211 
212 
213  app.get_formatter()->column_width(40);
214  CLI11_PARSE(app, argc, argv);
215  // END parse command line using CLI ----------------------------------------------
216 
217 
218 
219  DGtal::Color vFieldLineColor = DGtal::Color::Red;
220  if( customLineColor.size() == 4)
221  {
222  vFieldLineColor.setRGBi(customLineColor[0], customLineColor[1], customLineColor[2], 255);
223  }
224 
225  if( customColorMesh.size() != 0 )
226  {
227  if(customColorMesh.size()!=4 && customColorMesh.size()!=8 )
228  {
229  trace.error() << "colors specification should contain R,G,B and Alpha values"<< std::endl;
230  }
231  if( customColorMesh.size() >= 4)
232  {
233  meshColorR = customColorMesh[0];
234  meshColorG = customColorMesh[1];
235  meshColorB = customColorMesh[2];
236  meshColorA = customColorMesh[3];
237  }
238  if(customColorMesh.size() == 8)
239  {
240  meshColorRLine = customColorMesh[4];
241  meshColorGLine = customColorMesh[5];
242  meshColorBLine = customColorMesh[6];
243  meshColorALine = customColorMesh[7];
244  }
245  }
246 
247  if(customColorSDP.size() == 4)
248  {
249  sdpColorR = customColorSDP[0];
250  sdpColorG = customColorSDP[1];
251  sdpColorB = customColorSDP[2];
252  sdpColorA = customColorSDP[3];
253  }
254 
255  QApplication application(argc,argv);
256  CustomViewer3D viewer;
257  viewer.mySaveSnap = snapshotFile != "";
258  if(snapshotFile != "")
259  {
260  viewer.setSnapshotFileName(QString(snapshotFile.c_str()));
261  }
262 
263  std::stringstream title;
264  title << "Simple Mesh Viewer: " << inputFileNames[0];
265  viewer.setWindowTitle(title.str().c_str());
266  viewer.show();
267  viewer.myGLLineMinWidth = lineWidth;
268  viewer.setGLScale(sx, sy, sz);
269 
270  if(ambiantLight != 0.0)
271  {
272  GLfloat lightAmbientCoeffs [4] = {ambiantLight,ambiantLight, ambiantLight, 1.0f};
273  viewer.setGLLightAmbientCoefficients(lightAmbientCoeffs);
274  }
275 
276  trace.info() << "Importing mesh... ";
277 
278  std::vector<Mesh<DGtal::Z3i::RealPoint> > vectMesh;
279  for(unsigned int i = 0; i< inputFileNames.size(); i++)
280  {
281  Mesh<DGtal::Z3i::RealPoint> aMesh(customColorMesh.size() != 4 && customColorMesh.size() != 8);
282  aMesh << inputFileNames[i];
283  vectMesh.push_back(aMesh);
284  }
285  DGtal::Z3i::RealPoint centerMeshes;
286  unsigned int tot=0;
287  for(const auto & m: vectMesh)
288  {
289  for( auto p = m.vertexBegin(); p!=m.vertexEnd(); ++p)
290  centerMeshes += *p;
291  tot+=m.nbVertex();
292  }
293  centerMeshes /= tot;
294  viewer.centerMesh = centerMeshes;
295  bool import = vectMesh.size()==inputFileNames.size();
296  if(!import)
297  {
298  trace.info() << "File import failed. " << std::endl;
299  return 0;
300  }
301 
302  trace.info() << "[done]. "<< std::endl;
303  if(filenameSDP != "")
304  {
305  vector<Z3i::RealPoint> vectPoints;
306  vectPoints = PointListReader<Z3i::RealPoint>::getPointsFromFile(filenameSDP);
307  viewer << CustomColors3D(Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA),
308  Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA));
309  for(unsigned int i=0;i< vectPoints.size(); i++){
310  viewer.addBall(vectPoints.at(i), ballRadius);
311  }
312  }
313  if(invertNormal)
314  {
315  for(unsigned int i=0; i<vectMesh.size(); i++){
316  vectMesh[i].invertVertexFaceOrder();
317  }
318  }
319 
320  viewer << CustomColors3D(Color(meshColorRLine, meshColorGLine, meshColorBLine, meshColorALine),
321  Color(meshColorR, meshColorG, meshColorB, meshColorA));
322  for(unsigned int i=0; i<vectMesh.size(); i++){
323  viewer << vectMesh[i];
324  }
325 
326  if(drawVertex){
327  for(unsigned int i=0; i<vectMesh.size(); i++){
328  for( Mesh<DGtal::Z3i::RealPoint>::VertexStorage::const_iterator it = vectMesh[i].vertexBegin();
329  it!=vectMesh[i].vertexEnd(); ++it){
330  DGtal::Z3i::Point pt;
331  pt[0]=(*it)[0]; pt[1]=(*it)[1]; pt[2]=(*it)[2];
332  viewer << pt;
333  }
334  }
335  }
336 
337  if (displayVectorField != "")
338  {
339  std::vector<unsigned int > vectFieldIndices1 = {vectFieldIndices[0],vectFieldIndices[1], vectFieldIndices[2]};
340  std::vector<unsigned int > vectFieldIndices2 = {vectFieldIndices[3],vectFieldIndices[4], vectFieldIndices[5]};
341  std::vector<DGtal::Z3i::RealPoint> vectPt1 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(displayVectorField, vectFieldIndices1);
342  std::vector<DGtal::Z3i::RealPoint> vectPt2 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(displayVectorField, vectFieldIndices2);
343  viewer.createNewLineList();
344  for (unsigned int i = 0; i < vectPt1.size(); i++)
345  {
346  viewer.setLineColor(vFieldLineColor);
347  viewer.addLine(vectPt1[i], vectPt2[i]);
348  }
349  }
350  unsigned int nbVertex = 0;
351  unsigned int nbFaces = 0;
352  for(auto const &m: vectMesh)
353  {
354  nbVertex += m.nbVertex();
355  nbFaces +=m.nbFaces();
356  }
357  stringstream ss;
358  ss << "# faces: " << std::fixed << nbFaces << " #vertex: " << nbVertex ;
359  viewer.myInfoDisplay = ss.str();
360  viewer << CustomViewer3D::updateDisplay;
361  if(snapshotFile != "" )
362  {
363  // Appy cleaning just save the last snap
364  if(!viewer.restoreStateFromFile())
365  {
366  viewer.update();
367  }
368  std::string extension = snapshotFile.substr(snapshotFile.find_last_of(".") + 1);
369  std::string basename = snapshotFile.substr(0, snapshotFile.find_last_of("."));
370  for(int i=0; i< viewer.snapshotCounter()-1; i++){
371  std::stringstream s;
372  s << basename << "-"<< setfill('0') << setw(4)<< i << "." << extension;
373  trace.info() << "erase temp file: " << s.str() << std::endl;
374  remove(s.str().c_str());
375  }
376 
377  std::stringstream s;
378  s << basename << "-"<< setfill('0') << setw(4)<< viewer.snapshotCounter()-1 << "." << extension;
379  rename(s.str().c_str(), snapshotFile.c_str());
380  return 0;
381  }
382 
383  return application.exec();
384 }
Definition: ATu0v1.h:57