DGtalTools  0.9.4
3dSDPViewer.cpp
1 
28 #include <iostream>
30 
31 #include "DGtal/base/Common.h"
32 #include "DGtal/helpers/StdDefs.h"
33 #include "DGtal/io/viewers/Viewer3D.h"
34 #include "DGtal/io/DrawWithDisplay3DModifier.h"
35 #include "DGtal/io/readers/TableReader.h"
36 #include "DGtal/io/readers/PointListReader.h"
37 #include "DGtal/io/readers/MeshReader.h"
38 #include "DGtal/topology/helpers/Surfaces.h"
39 #include "DGtal/topology/SurfelAdjacency.h"
40 #include "DGtal/shapes/Mesh.h"
41 #include "DGtal/io/Color.h"
42 #include "DGtal/io/colormaps/HueShadeColorMap.h"
43 #include "DGtal/io/readers/GenericReader.h"
44 #include "DGtal/io/DrawWithDisplay3DModifier.h"
45 
46 
47 #include <boost/program_options/options_description.hpp>
48 #include <boost/program_options/parsers.hpp>
49 #include <boost/program_options/variables_map.hpp>
50 
51 
52 using namespace std;
53 using namespace DGtal;
54 using namespace Z3i;
55 
57 namespace po = boost::program_options;
59 
60 
181 // call back function to display voxel coordinates
182 int
183 displayCoordsCallBack( void* viewer, int name, void* data )
184 {
185  vector<Z3i::RealPoint> *vectVoxels = (vector<Z3i::RealPoint> *) data;
186  std::stringstream ss;
187  ss << "Selected voxel: (" << (*vectVoxels)[name][0] << ", ";
188  ss << (*vectVoxels)[name][1] << ", ";
189  ss << (*vectVoxels)[name][2] << ") ";
190  ((Viewer *) viewer)->displayMessage(QString(ss.str().c_str()), 100000);
191 
192  return 0;
193 }
194 
195 
196 int main( int argc, char** argv )
197 {
198 
199 
200  // parse command line ----------------------------------------------
201  po::options_description general_opt(" Allowed options are");
202  general_opt.add_options()
203  ("help,h", "display this message")
204  ("input,i", po::value<std::string>(), "input file: sdp (sequence of discrete points)" )
205  ("SDPindex", po::value<std::vector <unsigned int> >()->multitoken(), "specify the sdp index (by default 0,1,2).")
206  ("pointColor,c", po::value<std::vector <int> >()->multitoken(), "set the color of points: r g b a " )
207  ("lineColor,l",po::value<std::vector <int> >()->multitoken(), "set the color of line: r g b a " )
208  ("addMesh,m", po::value<std::string>(), "append a mesh (off/obj) to the point set visualization.")
209  ("customColorMesh",po::value<std::vector<unsigned int> >()->multitoken(), "set the R, G, B, A components of the colors of the mesh faces (mesh added with option --addMesh). " )
210  ("importColors", "import point colors from the input file (R G B colors should be by default at index 3, 4, 5).")
211  ("importColorLabels", "import color labels from the input file (label index should be by default at index 3).")
212  ("setColorsIndex", po::value<std::vector<unsigned int> >()->multitoken(), "customize the index of the imported colors in the source file (used by -importColor).")
213  ("setColorLabelIndex", po::value<unsigned int >()->default_value(3), "customize the index of the imported color labels in the source file (used by -importColorLabels).")
214  ("filter,f",po::value<double>()->default_value(100.0), "filter input file in order to display only the [arg] percent of the input 3D points (uniformly selected)." )
215  ("noPointDisplay", "usefull for instance to only display the lines between points.")
216  ("drawLines", "draw the line between discrete points." )
217  ("scaleX,x", po::value<float>()->default_value(1.0), "set the scale value in the X direction (default 1.0)" )
218  ("scaleY,y", po::value<float>()->default_value(1.0), "set the scale value in the Y direction (default 1.0)" )
219  ("scaleZ,z", po::value<float>()->default_value(1.0), "set the scale value in the Z direction (default 1.0)")
220  ("sphereResolution", po::value<unsigned int>()->default_value(30), "defines the sphere resolution (used when the primitive is set to the sphere). (default resolution: 30)")
221  ("sphereRadius,s", po::value<double>()->default_value(0.2), "defines the sphere radius (used when the primitive is set to the sphere). (default value 0.2)")
222  ("sphereRadiusFromInput", "takes, as sphere radius, the 4th field of the sdp input file.")
223  ("lineSize", po::value<double>()->default_value(0.2), "defines the line size (used when the --drawLines or --drawVectors option is selected). (default value 0.2))")
224  ("primitive,p", po::value<std::string>()->default_value("voxel"), "set the primitive to display the set of points (can be sphere, voxel (default), or glPoints (opengl points).")
225  ("drawVectors,v", po::value<std::string>(), "SDP vector file: draw a set of vectors from the given file (each vector are determined by two consecutive point given, each point represented by its coordinates on a single line.")
226  ("unitVector,u", po::value<double>()->default_value(1.0), "specifies that the SDP vector file format (of --drawVectors option) should be interpreted as unit vectors (each vector position is be defined from the input point (with input order) with a constant norm defined by [arg]).")
227 
228  ("filterVectors",po::value<double>()->default_value(100.0), "filters vector input file in order to display only the [arg] percent of the input vectors (uniformly selected, to be used with option --drawVectors else no effect). " )
229 
230  ("interactiveDisplayVoxCoords", "by using this option the pixel coordinates can be displayed after selection (shift+left click on voxel)." );
231 
232 
233  bool parseOK=true;
234  bool cannotStart= false;
235 
236 
237 
238  po::variables_map vm;
239  try{
240  po::store(po::parse_command_line(argc, argv, general_opt), vm);
241  }catch(const std::exception& ex){
242  parseOK=false;
243  trace.error()<< "Error checking program options: "<< ex.what()<< endl;
244  }
245  po::notify(vm);
246  std::string typePrimitive;
247  double sphereRadius = 0.2;
248  std::vector<double> vectSphereRadius;
249  unsigned int sphereResolution = vm["sphereResolution"].as<unsigned int>();
250  double lineSize =0.2;
251  bool useMultiRad = vm.count("sphereRadiusFromInput");
252 
253  Color lineColor(100, 100, 250);
254  Color pointColor(250, 250, 250);
255  if(parseOK)
256  {
257  typePrimitive = vm["primitive"].as<std::string>();
258  sphereRadius = vm["sphereRadius"].as<double>();
259  lineSize = vm["lineSize"].as<double>();
260  }
261 
262  if (parseOK && typePrimitive !="voxel"
263  && typePrimitive !="glPoints"
264  && typePrimitive != "sphere" )
265  {
266  trace.error() << " The primitive should be sphere or voxel (primitive: "
267  << typePrimitive << " not implemented)" << std::endl;
268  cannotStart = true;
269  }
270 
271  if(parseOK && vm.count("lineColor"))
272  {
273  std::vector<int> vcol= vm["lineColor"].as<std::vector<int > >();
274  if(vcol.size()<4)
275  {
276  trace.error() << " Not enough parameter: color specification should contains four elements: red, green, blue and alpha values "
277  << "(Option --lineColor ignored). " << std::endl;
278  }
279  lineColor.setRGBi(vcol[0], vcol[1], vcol[2], vcol[3]);
280  }
281  if(parseOK && vm.count("pointColor"))
282  {
283  std::vector<int> vcol= vm["pointColor"].as<std::vector<int > >();
284  if(vcol.size()<4)
285  {
286  trace.error() << " Not enough parameter: color specification should contains four elements: red, green, blue and alpha values "
287  << "(Option --pointColor ignored)." << std::endl;
288  }
289  pointColor.setRGBi(vcol[0], vcol[1], vcol[2], vcol[3]);
290  }
291 
292  if( !parseOK || cannotStart || vm.count("help")||argc<=1)
293  {
294  trace.info() << "Usage: " << argv[0] << " [input]\n"
295  << "Display sequence of 3d discrete points by using QGLviewer."
296  << general_opt << "\n";
297  return 0;
298  }
299 
300  string inputFilename = vm["input"].as<std::string>();
301 
302 
303  QApplication application(argc,argv);
304 
305  float sx = vm["scaleX"].as<float>();
306  float sy = vm["scaleY"].as<float>();
307  float sz = vm["scaleZ"].as<float>();
308 
309  bool importColorLabels = vm.count("importColorLabels");
310  bool importColors = vm.count("importColors");
311  bool interactiveDisplayVoxCoords = vm.count("interactiveDisplayVoxCoords");
312  bool useUnitVector = vm.count("unitVector");
313  double constantNorm = vm["unitVector"].as<double>();
314 
316  Z3i::KSpace K;
317  Viewer viewer( K );
318  viewer.setWindowTitle("3dSPD Viewer");
319  viewer.show();
320  viewer.setGLScale(sx, sy, sz);
321  viewer.myGLLineMinWidth = lineSize;
322  viewer << CustomColors3D(pointColor, pointColor);
323 
324 
325  // Get vector of colors if imported.
326  std::vector<Color> vectColors;
327  if(vm.count("importColors"))
328  {
329  std::vector<unsigned int > vectIndex;
330  if(vm.count("setColorsIndex"))
331  {
332  vectIndex = vm["setColorsIndex"].as<std::vector<unsigned int > >();
333  if(vectIndex.size()!=3)
334  {
335  trace.error() << "you need to specify the three indexes of color." << std::endl;
336  return 0;
337  }
338  }
339  else
340  {
341  vectIndex.push_back(3);
342  vectIndex.push_back(4);
343  vectIndex.push_back(5);
344  }
345 
346 
347  std::vector<unsigned int> r = TableReader<unsigned int>::getColumnElementsFromFile(inputFilename,vectIndex[0]);
348  std::vector<unsigned int> g = TableReader<unsigned int>::getColumnElementsFromFile(inputFilename,vectIndex[1]);
349  std::vector<unsigned int> b = TableReader<unsigned int>::getColumnElementsFromFile(inputFilename,vectIndex[2]);
350  for (unsigned int i = 0; i<r.size(); i++){
351  vectColors.push_back(Color(r[i], g[i], b[i]));
352  }
353  }
354 
355  // Get vector of colors if imported.
356  std::vector< int> vectColorLabels;
357  unsigned int maxLabel = 1;
358  if(vm.count("importColorLabels"))
359  {
360  unsigned int index = vm["setColorLabelIndex"].as<unsigned int >();
361  vectColorLabels = TableReader< int>::getColumnElementsFromFile(inputFilename,index);
362  maxLabel = *(std::max_element(vectColorLabels.begin(), vectColorLabels.end()));
363  }
364  HueShadeColorMap<unsigned int> aColorMap(0, maxLabel);
365 
366 
367  if(useMultiRad)
368  {
369  vectSphereRadius = TableReader<double>::getColumnElementsFromFile(inputFilename,3);
370  }
371 
372  vector<Z3i::RealPoint> vectVoxels;
373  if(vm.count("SDPindex"))
374  {
375  std::vector<unsigned int > vectIndex = vm["SDPindex"].as<std::vector<unsigned int > >();
376  if(vectIndex.size()!=3)
377  {
378  trace.error() << "you need to specify the three indexes of vertex." << std::endl;
379  return 0;
380  }
381  vectVoxels = PointListReader<Z3i::RealPoint>::getPointsFromFile(inputFilename, vectIndex);
382 
383  }else{
384  vectVoxels = PointListReader<Z3i::RealPoint>::getPointsFromFile(inputFilename);
385  }
386  int name = 0;
387  if(!vm.count("noPointDisplay")){
388  if (typePrimitive == "glPoints")
389  {
390  viewer.setUseGLPointForBalls(true);
391  }
392 
393  double percent = vm["filter"].as<double>();
394  int step = max(1, (int) (100/percent));
395  for(unsigned int i=0;i< vectVoxels.size(); i=i+step){
396  if(importColors)
397  {
398  Color col = vectColors[i];
399  viewer.setFillColor(col);
400  }
401  else if(importColorLabels)
402  {
403  unsigned int index = vectColorLabels[i];
404  Color col = aColorMap(index);
405  viewer.setFillColor(col);
406  }
407 
408  if(typePrimitive=="voxel" ){
409  if (interactiveDisplayVoxCoords)
410  {
411  viewer << SetName3D( name++ ) ;
412  }
413  viewer << Z3i::Point((int)vectVoxels.at(i)[0],
414  (int)vectVoxels.at(i)[1],
415  (int)vectVoxels.at(i)[2]);
416  }
417  else
418  {
419  viewer.addBall(vectVoxels.at(i), sphereRadius, sphereResolution);
420  }
421  }
422 
423  viewer << CustomColors3D(lineColor, lineColor);
424  if(vm.count("drawLines"))
425  {
426  for(unsigned int i=1;i< vectVoxels.size(); i++)
427  {
428  viewer.addLine(vectVoxels.at(i-1), vectVoxels.at(i), lineSize);
429  }
430  }
431 
432 
433  if(vm.count("drawVectors"))
434  {
435  std::string vectorsFileName = vm["drawVectors"].as<std::string>();
436  std::vector<Z3i::RealPoint> vectorsPt = PointListReader<Z3i::RealPoint>::getPointsFromFile(vectorsFileName);
437  if (vectorsPt.size()%2==1)
438  {
439  trace.info()<<"Warning the two set of points doesn't contains the same number of points, some vectors will be skipped." << std::endl;
440  }
441  int step=1;
442  if(vm.count("filterVectors"))
443  {
444  double percentage = vm["filterVectors"].as<double>();
445  step = max(1, (int) (100/percentage));
446  }
447  if(useUnitVector)
448  {
449  for(unsigned int i =0; i< std::min(vectVoxels.size(), vectorsPt.size()); i=i+2*step)
450  {
451  viewer.addLine(vectVoxels.at(i), vectVoxels.at(i)+vectorsPt.at(i)*constantNorm, lineSize);
452  }
453  }
454  else
455  {
456  for(unsigned int i =0; i<vectorsPt.size()-1; i=i+2*step)
457  {
458  viewer.addLine(vectorsPt.at(i),vectorsPt.at(i+1), lineSize);
459  }
460  }
461 
462  }
463  if(vm.count("addMesh"))
464  {
465  bool customColorMesh = vm.count("customColorMesh");
466  if(customColorMesh)
467  {
468  std::vector<unsigned int > vectCol = vm["customColorMesh"].as<std::vector<unsigned int> >();
469  if(vectCol.size()!=4)
470  {
471  trace.error() << "colors specification should contain R,G,B and Alpha values"<< std::endl;
472  }
473  viewer.setFillColor(DGtal::Color(vectCol[0], vectCol[1], vectCol[2], vectCol[3]));
474  }
475  std::string meshName = vm["addMesh"].as<std::string>();
476  Mesh<Z3i::RealPoint> mesh(!customColorMesh);
477  mesh << meshName ;
478  viewer << mesh;
479  }
480  if (interactiveDisplayVoxCoords)
481  {
482  viewer << SetSelectCallback3D( displayCoordsCallBack, &vectVoxels, 0, vectVoxels.size()-1 );
483  }
484 
485 
486  viewer << Viewer3D<>::updateDisplay;
487  return application.exec();
488  }
489 }
490 
STL namespace.
Trace trace(traceWriterTerm)
std::ostream & info()
std::ostream & error()