DGtalTools  1.3.beta
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 #include "CLI11.hpp"
47 
48 
49 
50 using namespace std;
51 using namespace DGtal;
52 using namespace Z3i;
53 
55 
141 // call back function to display voxel coordinates
142 int
143 displayCoordsCallBack( void* viewer, int name, void* data )
144 {
145  vector<Z3i::RealPoint> *vectVoxels = (vector<Z3i::RealPoint> *) data;
146  std::stringstream ss;
147  ss << "Selected voxel: (" << (*vectVoxels)[name][0] << ", ";
148  ss << (*vectVoxels)[name][1] << ", ";
149  ss << (*vectVoxels)[name][2] << ") ";
150  ((Viewer *) viewer)->displayMessage(QString(ss.str().c_str()), 100000);
151 
152  return 0;
153 }
154 
155 
156 int main( int argc, char** argv )
157 {
158  // parse command line using CLI ----------------------------------------------
159  CLI::App app;
160  std::string inputFileName;
161  std::vector<unsigned int > vectIndexSDP {0,1,2};
162  Color lineColor(100, 100, 250);
163  Color pointColor(250, 250, 250);
164  std::vector<int> vectColorPt;
165  std::vector<int> vectColorLine;
166  std::string meshName;
167  std::string typePrimitive {"voxel"};
168  std::string vectorsFileName;
169  std::vector<double> vectSphereRadius;
170  std::vector<unsigned int> vectColMesh;
171  std::vector<unsigned int> vectIndexColorImport {3,4,5};
172  bool importColorLabels {false};
173  bool noPointDisplay {false};
174  bool drawLines {false};
175  bool sphereRadiusFromInput {true};
176  bool importColors {false};
177  bool interactiveDisplayVoxCoords {false};
178  float sx {1.0};
179  float sy {1.0};
180  float sz {1.0};
181  unsigned int sphereResolution {30};
182  double sphereRadius {0.2};
183  double lineSize {0.2};
184  double filterValue {100.0};
185  double constantNorm {0.0};
186  double percentageFilterVect {100.0};
187 
188  unsigned int colorLabelIndex = 3;
189 
190  app.description("Display sequence of 3d discrete points by using QGLviewer.");
191  app.add_option("-i,--input,1", inputFileName, "input file: sdp (sequence of discrete points)." )
192  ->required()
193  ->check(CLI::ExistingFile);
194  app.add_option("--SDPindex",vectIndexSDP, "specify the sdp index (by default 0,1,2).")
195  ->expected(3);
196  app.add_option("--pointColor,-c",vectColorPt, "set the color of points: r g b a.")
197  ->expected(4);
198  app.add_option("--lineColor,-l",vectColorLine, "set the color of line: r g b a.")
199  ->expected(4);
200  app.add_option("--addMesh,-m",meshName, "append a mesh (off/obj) to the point set visualization.");
201  auto optMesh = app.add_option("--customColorMesh",vectColMesh, "set the R, G, B, A components of the colors of the mesh faces (mesh added with option --addMesh).")
202  ->expected(4);
203  auto importColOpt = app.add_flag("--importColors",importColors, "import point colors from the input file (R G B colors should be by default at index 3, 4, 5).");
204  app.add_option("--setColorsIndex", vectIndexColorImport,"customize the index of the imported colors in the source file (used by --importColor). By default the initial indexes are 3, 4, 5.")
205  ->expected(3)
206  ->needs(importColOpt);
207 
208  app.add_flag("--importColorLabels", importColorLabels,"import color labels from the input file (label index should be by default at index 3)." );
209  app.add_option("--setColorLabelIndex", colorLabelIndex, "customize the index of the imported color labels in the source file (used by -importColorLabels).", true);
210  app.add_option("--filter,-f", filterValue, "filter input file in order to display only the [arg] percent of the input 3D points (uniformly selected).", true);
211  app.add_flag("--noPointDisplay",noPointDisplay, "usefull for instance to only display the lines between points." );
212  app.add_flag("--drawLines", drawLines, "draw the line between discrete points." );
213  app.add_option("--scaleX,-x", sx, "set the scale value in the X direction", true );
214  app.add_option("--scaleY,-y", sy, "set the scale value in the Y direction", true );
215  app.add_option("--scaleZ,-z", sy, "set the scale value in the Z direction", true );
216  app.add_option("--sphereResolution",sphereResolution, "defines the sphere resolution (used when the primitive is set to the sphere).", true );
217  app.add_option("-s,--sphereRadius", sphereRadius, "defines the sphere radius (used when the primitive is set to the sphere).", true);
218  app.add_flag("--sphereRadiusFromInput", sphereRadiusFromInput, "takes, as sphere radius, the 4th field of the sdp input file.");
219  app.add_option("--lineSize", lineSize, "defines the line size (used when the --drawLines or --drawVectors option is selected).", true);
220  app.add_option("--primitive,-p",typePrimitive, "set the primitive to display the set of points.", true )
221  -> check(CLI::IsMember({"voxel", "glPoints", "sphere"}));
222  app.add_option("--drawVectors,-v",vectorsFileName, "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.");
223 
224  app.add_option("--unitVector,-u", constantNorm, "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]).", true );
225 
226  app.add_option("--filterVectors", percentageFilterVect, "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). ", true );
227  app.add_flag("--interactiveDisplayVoxCoords", interactiveDisplayVoxCoords, " by using this option the coordinates can be displayed after selection (shift+left click on voxel).");
228 
229 
230  app.get_formatter()->column_width(40);
231  CLI11_PARSE(app, argc, argv);
232  // END parse command line using CLI ----------------------------------------------
233 
234 
235  if (vectColorLine.size() == 4){
236  lineColor.setRGBi(vectColorLine[0], vectColorLine[1], vectColorLine[2], vectColorLine[3]);
237  }
238  if (vectColorPt.size() == 4){
239  pointColor.setRGBi(vectColorPt[0], vectColorPt[1], vectColorPt[2], vectColorPt[3]);
240  }
241 
242 
243  QApplication application(argc,argv);
244 
245 
246  bool useUnitVector = constantNorm != 0.0;
247 
249  Z3i::KSpace K;
250  Viewer viewer( K );
251  viewer.setWindowTitle("3dSPD Viewer");
252  viewer.show();
253  viewer.setGLScale(sx, sy, sz);
254  viewer.myGLLineMinWidth = lineSize;
255  viewer << CustomColors3D(pointColor, pointColor);
256 
257 
258  // Get vector of colors if imported.
259  std::vector<Color> vectColors;
260  if(importColors)
261  {
262  std::vector<unsigned int> r = TableReader<unsigned int>::getColumnElementsFromFile(inputFileName,vectIndexColorImport[0]);
263  std::vector<unsigned int> g = TableReader<unsigned int>::getColumnElementsFromFile(inputFileName,vectIndexColorImport[1]);
264  std::vector<unsigned int> b = TableReader<unsigned int>::getColumnElementsFromFile(inputFileName,vectIndexColorImport[2]);
265  for (unsigned int i = 0; i<r.size(); i++){
266  vectColors.push_back(Color(r[i], g[i], b[i]));
267  }
268  }
269 
270  // Get vector of colors if imported.
271  std::vector< int> vectColorLabels;
272  unsigned int maxLabel = 1;
273  if(importColorLabels)
274  {
275  vectColorLabels = TableReader< int>::getColumnElementsFromFile(inputFileName, colorLabelIndex);
276  maxLabel = *(std::max_element(vectColorLabels.begin(), vectColorLabels.end()));
277  }
278  HueShadeColorMap<unsigned int> aColorMap(0, maxLabel);
279 
280 
281  if(sphereRadiusFromInput)
282  {
283  vectSphereRadius = TableReader<double>::getColumnElementsFromFile(inputFileName,3);
284  }
285 
286  vector<Z3i::RealPoint> vectVoxels;
287  vectVoxels = PointListReader<Z3i::RealPoint>::getPointsFromFile(inputFileName, vectIndexSDP);
288 
289  int name = 0;
290  if(!noPointDisplay){
291  if (typePrimitive == "glPoints")
292  {
293  viewer.setUseGLPointForBalls(true);
294  }
295 
296  int step = max(1, (int) (100/filterValue));
297  for(unsigned int i=0;i< vectVoxels.size(); i=i+step){
298  if(importColors)
299  {
300  Color col = vectColors[i];
301  viewer.setFillColor(col);
302  }
303  else if(importColorLabels)
304  {
305  unsigned int index = vectColorLabels[i];
306  Color col = aColorMap(index);
307  viewer.setFillColor(col);
308  }
309 
310  if(typePrimitive=="voxel" ){
311  if (interactiveDisplayVoxCoords)
312  {
313  viewer << SetName3D( name++ ) ;
314  }
315  viewer << Z3i::Point((int)vectVoxels.at(i)[0],
316  (int)vectVoxels.at(i)[1],
317  (int)vectVoxels.at(i)[2]);
318  }
319  else
320  {
321  viewer.addBall(vectVoxels.at(i), sphereRadius, sphereResolution);
322  }
323  }
324 
325  viewer << CustomColors3D(lineColor, lineColor);
326  if(drawLines)
327  {
328  for(unsigned int i=1;i< vectVoxels.size(); i++)
329  {
330  viewer.addLine(vectVoxels.at(i-1), vectVoxels.at(i), lineSize);
331  }
332  }
333 
334  if(vectorsFileName != "")
335  {
336  std::vector<Z3i::RealPoint> vectorsPt = PointListReader<Z3i::RealPoint>::getPointsFromFile(vectorsFileName);
337  if (vectorsPt.size()%2==1)
338  {
339  trace.info()<<"Warning the two set of points doesn't contains the same number of points, some vectors will be skipped." << std::endl;
340  }
341 
342  double percentage = percentageFilterVect;
343  int step = max(1, (int) (100/percentage));
344 
345  if(useUnitVector)
346  {
347  for(unsigned int i =0; i< std::min(vectVoxels.size(), vectorsPt.size()); i=i+2*step)
348  {
349  viewer.addLine(vectVoxels.at(i), vectVoxels.at(i)+vectorsPt.at(i)*constantNorm, lineSize);
350  }
351  }
352  else
353  {
354  for(unsigned int i =0; i<vectorsPt.size()-1; i=i+2*step)
355  {
356  viewer.addLine(vectorsPt.at(i),vectorsPt.at(i+1), lineSize);
357  }
358  }
359  }
360  if(meshName != "")
361  {
362  bool customColorMesh = vectColMesh.size() == 4;
363  if(customColorMesh)
364  {
365  viewer.setFillColor(DGtal::Color(vectColMesh[0], vectColMesh[1], vectColMesh[2], vectColMesh[3]));
366  }
367  Mesh<Z3i::RealPoint> mesh(!customColorMesh);
368  mesh << meshName ;
369  viewer << mesh;
370  }
371  if (interactiveDisplayVoxCoords)
372  {
373  viewer << SetSelectCallback3D( displayCoordsCallBack, &vectVoxels, 0, vectVoxels.size()-1 );
374  }
375 
376  viewer << Viewer3D<>::updateDisplay;
377  return application.exec();
378  }
379 }
380 
STL namespace.
int main(int argc, char **argv)
Trace trace(traceWriterTerm)
std::ostream & info()