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