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