DGtalTools  0.9.4
meshViewer.cpp
1 
29 #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 #include <boost/program_options/options_description.hpp>
41 #include <boost/program_options/parsers.hpp>
42 #include <boost/program_options/variables_map.hpp>
43 
44 
45 using namespace std;
46 using namespace DGtal;
47 
48 
122 class CustomViewer3D: public Viewer3D<>
123 {
124 protected:
125 
126  virtual void init()
127  {
129  Viewer3D<>::setKeyDescription ( Qt::Key_I, "Display mesh informations about #faces, #vertices" );
131  if(mySaveSnap){
132  QObject::connect(this, SIGNAL(drawFinished(bool)), this, SLOT(saveSnapshot(bool)));
133  }
134  }
135  virtual void keyPressEvent(QKeyEvent *e){
136  bool handled = false;
137  if( e->key() == Qt::Key_I)
138  {
139  handled=true;
140  myIsDisplayingInfoMode = !myIsDisplayingInfoMode;
141  stringstream ss;
142  qglviewer::Vec camPos = camera()->position();
143  DGtal::Z3i::RealPoint c (camPos[0], camPos[1], camPos[2]);
144  ss << myInfoDisplay << " distance to camera: " << (c-centerMesh).norm();
145  Viewer3D<>::displayMessage(QString(myIsDisplayingInfoMode ?
146  ss.str().c_str() : " "), 1000000);
147 
149  }
150 
151  if(!handled)
152  {
154  }
155  };
156 
157 public:
158  std::string myInfoDisplay = "No information loaded...";
159  bool myIsDisplayingInfoMode = false;
160  bool mySaveSnap = false;
161  DGtal::Z3i::RealPoint centerMesh;
162 };
163 
164 
165 
166 
168 namespace po = boost::program_options;
169 
170 int main( int argc, char** argv )
171 {
172 
173  // parse command line ----------------------------------------------
174  po::options_description general_opt("Allowed options are: ");
175  general_opt.add_options()
176  ("help,h", "display this message")
177  ("input,i", po::value<std::vector<string> >()->multitoken(), "off files (.off), or OFS file (.ofs) " )
178  ("scaleX,x", po::value<float>()->default_value(1.0), "set the scale value in the X direction (default 1.0)" )
179  ("scaleY,y", po::value<float>()->default_value(1.0), "set the scale value in the Y direction (default 1.0)" )
180  ("scaleZ,z", po:: value<float>()->default_value(1.0), "set the scale value in the Z direction (default 1.0)")
181  ("minLineWidth,w", po:: value<float>()->default_value(1.5), "set the min line width of the mesh faces (default 1.5)")
182  ("customColorMesh",po::value<std::vector<unsigned int> >()->multitoken(), "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). " )
183  ("customColorSDP",po::value<std::vector<unsigned int> >()->multitoken(), "set the R, G, B, A components of the colors of the sdp view" )
184  ("displayVectorField,f",po::value<std::string>(), "display a vector field from a simple sdp file (two points per line)" )
185  ("vectorFieldIndex",po::value<std::vector<unsigned int> >()->multitoken(), "specify special indices for the two point coordinates (instead usinf the default indices: 0 1, 2, 3, 4, 5)" )
186  ("customLineColor",po::value<std::vector<unsigned int> >()->multitoken(), "set the R, G, B components of the colors of the lines displayed from the --displayVectorField option (red by default). " )
187  ("displaySDP,s", po::value<std::string>(), "add the display of a set of discrete points as ball of radius 0.5.")
188  ("SDPradius", po::value<double>()->default_value(0.5), "change the ball radius to display a set of discrete points (used with displaySDP option)")
189  ("invertNormal,n", "invert face normal vectors." )
190  ("addAmbientLight,A",po:: value<float>()->default_value(0.0), "add an ambient light for better display (between 0 and 1)." )
191  ("drawVertex,v", "draw the vertex of the mesh" )
192  ("doSnapShotAndExit,d", po::value<std::string>(), "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." );
193 
194  bool parseOK=true;
195  po::variables_map vm;
196  try{
197  po::store(po::parse_command_line(argc, argv, general_opt), vm);
198  }catch(const std::exception& ex){
199  parseOK=false;
200  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
201  }
202  po::notify(vm);
203  if( !parseOK || vm.count("help")||argc<=1)
204  {
205  std::cout << "Usage: " << argv[0] << " [input]\n"
206  << "Display OFF mesh file by using QGLviewer"
207  << general_opt << "\n";
208  return 0;
209  }
210 
211  if(! vm.count("input"))
212  {
213  trace.error() << " The file name was defined" << endl;
214  return 0;
215  }
216 
217 
218 
219  std::vector<std::string> inputFilenameVect = vm["input"].as<std::vector<std::string > >();
220  float sx = vm["scaleX"].as<float>();
221  float sy = vm["scaleY"].as<float>();
222  float sz = vm["scaleZ"].as<float>();
223 
224  unsigned int meshColorR = 240;
225  unsigned int meshColorG = 240;
226  unsigned int meshColorB = 240;
227  unsigned int meshColorA = 255;
228 
229  unsigned int meshColorRLine = 0;
230  unsigned int meshColorGLine = 0;
231  unsigned int meshColorBLine = 0;
232  unsigned int meshColorALine = 255;
233 
234 
235  unsigned int sdpColorR = 240;
236  unsigned int sdpColorG = 240;
237  unsigned int sdpColorB = 240;
238  unsigned int sdpColorA = 255;
239 
240 
241  bool displayVectorField = vm.count("displayVectorField");
242  std::vector<unsigned int> vectFieldIndices = {0,1,2,3,4,5};
243 
244  if (displayVectorField) {
245  if(vm.count("vectorFieldIndex")){
246  vectFieldIndices = vm["vectorFieldIndex"].as<std::vector<unsigned int> >();
247  if (vectFieldIndices.size() != 6) {
248  trace.warning() << "you should specify indices for each of the 6 fields of the two coordinates." << std::endl;
249  vectFieldIndices = {0,1,2,3,4,5};
250  }
251  }
252  }
253 
254  float lineWidth = vm["minLineWidth"].as<float>();
255 
256  DGtal::Color vFieldLineColor = DGtal::Color::Red;
257  if(vm.count("customLineColor")){
258  std::vector<unsigned int > vectCol = vm["customLineColor"].as<std::vector<unsigned int> >();
259  if(vectCol.size()!=3 ){
260  trace.error() << "colors specification should contain R,G,B values (using default red)."<< std::endl;
261  }
262  vFieldLineColor.setRGBi(vectCol[0], vectCol[1], vectCol[2], 255);
263  }
264 
265  if(vm.count("customColorMesh")){
266  std::vector<unsigned int > vectCol = vm["customColorMesh"].as<std::vector<unsigned int> >();
267  if(vectCol.size()!=4 && vectCol.size()!=8 ){
268  trace.error() << "colors specification should contain R,G,B and Alpha values"<< std::endl;
269  }
270  meshColorR = vectCol[0];
271  meshColorG = vectCol[1];
272  meshColorB = vectCol[2];
273  meshColorA = vectCol[3];
274  if(vectCol.size() == 8){
275  meshColorRLine = vectCol[4];
276  meshColorGLine = vectCol[5];
277  meshColorBLine = vectCol[6];
278  meshColorALine = vectCol[7];
279 
280  }
281 
282  }
283  if(vm.count("customColorSDP")){
284  std::vector<unsigned int > vectCol = vm["customColorSDP"].as<std::vector<unsigned int> >();
285  if(vectCol.size()!=4){
286  trace.error() << "colors specification should contain R,G,B and Alpha values"<< std::endl;
287  }
288  sdpColorR = vectCol[0];
289  sdpColorG = vectCol[1];
290  sdpColorB = vectCol[2];
291  sdpColorA = vectCol[3];
292  }
293 
294 
295 
296  QApplication application(argc,argv);
297  CustomViewer3D viewer;
298  viewer.mySaveSnap = vm.count("doSnapShotAndExit");
299  if(vm.count("doSnapShotAndExit")){
300  viewer.setSnapshotFileName(QString(vm["doSnapShotAndExit"].as<std::string>().c_str()));
301  }
302 
303  std::stringstream title;
304  title << "Simple Mesh Viewer: " << inputFilenameVect[0];
305  viewer.setWindowTitle(title.str().c_str());
306  viewer.show();
307  viewer.myGLLineMinWidth = lineWidth;
308  viewer.setGLScale(sx, sy, sz);
309  bool invertNormal= vm.count("invertNormal");
310  double ballRadius = vm["SDPradius"].as<double>();
311  if(vm.count("addAmbientLight"))
312  {
313  float val = vm["addAmbientLight"].as<float>();
314  GLfloat lightAmbientCoeffs [4] = {val,val, val, 1.0f};
315  viewer.setGLLightAmbientCoefficients(lightAmbientCoeffs);
316  }
317 
318  trace.info() << "Importing mesh... ";
319 
320  std::vector<Mesh<DGtal::Z3i::RealPoint> > vectMesh;
321  for(unsigned int i = 0; i< inputFilenameVect.size(); i++){
322  Mesh<DGtal::Z3i::RealPoint> aMesh(!vm.count("customColorMesh"));
323  aMesh << inputFilenameVect[i];
324  vectMesh.push_back(aMesh);
325  }
326  DGtal::Z3i::RealPoint centerMeshes;
327  unsigned int tot=0;
328  for(const auto & m: vectMesh)
329  {
330  for( auto p = m.vertexBegin(); p!=m.vertexEnd(); ++p)
331  centerMeshes += *p;
332  tot+=m.nbVertex();
333  }
334  centerMeshes /= tot;
335  viewer.centerMesh = centerMeshes;
336  bool import = vectMesh.size()==inputFilenameVect.size();
337  if(!import){
338  trace.info() << "File import failed. " << std::endl;
339  return 0;
340  }
341 
342  trace.info() << "[done]. "<< std::endl;
343  if(vm.count("displaySDP")){
344  std::string filenameSDP = vm["displaySDP"].as<std::string>();
345  vector<Z3i::RealPoint> vectPoints;
346  vectPoints = PointListReader<Z3i::RealPoint>::getPointsFromFile(filenameSDP);
347  viewer << CustomColors3D(Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA),
348  Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA));
349  for(unsigned int i=0;i< vectPoints.size(); i++){
350  viewer.addBall(vectPoints.at(i), ballRadius);
351  }
352  }
353  if(invertNormal){
354  for(unsigned int i=0; i<vectMesh.size(); i++){
355  vectMesh[i].invertVertexFaceOrder();
356  }
357  }
358 
359  viewer << CustomColors3D(Color(meshColorRLine, meshColorGLine, meshColorBLine, meshColorALine),
360  Color(meshColorR, meshColorG, meshColorB, meshColorA));
361  for(unsigned int i=0; i<vectMesh.size(); i++){
362  viewer << vectMesh[i];
363  }
364 
365  if(vm.count("drawVertex")){
366  for(unsigned int i=0; i<vectMesh.size(); i++){
367  for( Mesh<DGtal::Z3i::RealPoint>::VertexStorage::const_iterator it = vectMesh[i].vertexBegin();
368  it!=vectMesh[i].vertexEnd(); ++it){
370  pt[0]=(*it)[0]; pt[1]=(*it)[1]; pt[2]=(*it)[2];
371  viewer << pt;
372  }
373  }
374  }
375 
376 
377  if (displayVectorField) {
378  std::vector<unsigned int > vectFieldIndices1 = {vectFieldIndices[0],vectFieldIndices[1], vectFieldIndices[2]};
379  std::vector<unsigned int > vectFieldIndices2 = {vectFieldIndices[3],vectFieldIndices[4], vectFieldIndices[5]};
380 
381  std::vector<DGtal::Z3i::RealPoint> vectPt1 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(vm["displayVectorField"].as<std::string>(), vectFieldIndices1);
382  std::vector<DGtal::Z3i::RealPoint> vectPt2 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(vm["displayVectorField"].as<std::string>(), vectFieldIndices2);
383  viewer.createNewLineList();
384  for (unsigned int i = 0; i < vectPt1.size(); i++) {
385 
386  viewer.setLineColor(vFieldLineColor);
387  viewer.addLine(vectPt1[i], vectPt2[i]);
388  }
389  }
390  unsigned int nbVertex = 0;
391  unsigned int nbFaces = 0;
392  for(auto const &m: vectMesh)
393  {
394  nbVertex += m.nbVertex();
395  nbFaces +=m.nbFaces();
396  }
397  stringstream ss;
398  ss << "# faces: " << std::fixed << nbFaces << " #vertex: " << nbVertex ;
399  viewer.myInfoDisplay = ss.str();
401  if(vm.count("doSnapShotAndExit")){
402  // Appy cleaning just save the last snap
403  if(!viewer.restoreStateFromFile())
404  {
405  viewer.update();
406  }
407  std::string name = vm["doSnapShotAndExit"].as<std::string>();
408  std::string extension = name.substr(name.find_last_of(".") + 1);
409  std::string basename = name.substr(0, name.find_last_of("."));
410  for(int i=0; i< viewer.snapshotCounter()-1; i++){
411  std::stringstream s;
412  s << basename << "-"<< setfill('0') << setw(4)<< i << "." << extension;
413  trace.info() << "erase temp file: " << s.str() << std::endl;
414  remove(s.str().c_str());
415  }
416 
417  std::stringstream s;
418  s << basename << "-"<< setfill('0') << setw(4)<< viewer.snapshotCounter()-1 << "." << extension;
419  rename(s.str().c_str(), name.c_str());
420  return 0;
421  }
422 
423  return application.exec();
424 }
ConstIterator vertexEnd() const
STL namespace.
static Dimension size()
Trace trace(traceWriterTerm)
std::ostream & warning()
std::ostream & info()
static const Color Red
std::ostream & error()