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