DGtalTools  1.5.beta
volscope.cpp
1 
30 #include <vector>
31 #include <array>
32 
33 #include <DGtal/base/Common.h>
34 #include <DGtal/helpers/StdDefs.h>
35 #include <DGtal/helpers/Shortcuts.h>
36 
37 #include <polyscope/polyscope.h>
38 #include "polyscope/surface_mesh.h"
39 #include "polyscope/volume_mesh.h"
40 #include "polyscope/point_cloud.h"
41 
42 #include "CLI11.hpp"
43 
44 // Using standard 3D digital space.
45 using namespace DGtal;
46 using namespace Z3i;
47 typedef Shortcuts<Z3i::KSpace> SH3;
48 
49 
84 int main(int argc, char**argv)
85 {
86  // parse command line using CLI ----------------------------------------------
87  CLI::App app;
88  app.description("Vol file vizualization using polyscope");
89 
90  std::string inputFileName;
91  app.add_option("-i,--input,1", inputFileName, "Input vol file.")->required()->check(CLI::ExistingFile);
92 
93  bool volumetricMode = false;
94  app.add_flag("--volumetricMode",volumetricMode, "Activate the volumetric mode instead of the isosurface visualization.");
95 
96  bool pclOnly = false;
97  app.add_flag("--point-cloud-only",pclOnly, "In the volumetric mode, visualize the vol file as a point cloud instead of an hex mesh (default: false)");
98 
99  int thresholdMin=0;
100  app.add_option("--min,--thresholdMin,-m", thresholdMin, "For isosurface visualization and voxel filtering, specifies the threshold min (excluded) (default: 0).");
101  int thresholdMax=255;
102  app.add_option("--max, --thresholdMax,-M", thresholdMax, "For isosurface visualization and voxel filtering, specifies the threshold max (included) (default: 255).");
103 
104 
105  app.get_formatter()->column_width(40);
106  CLI11_PARSE(app, argc, argv);
107 
108  polyscope::options::programName = "volscope " + inputFileName + " - (DGtalTools)";
109  polyscope::init();
110 
111  if(!volumetricMode)
112  {
113  trace.beginBlock("Loading vol");
114  auto params = SH3::defaultParameters();
115  params("thresholdMin",thresholdMin)("thresholdMax",thresholdMax);
116  auto volimage = SH3::makeBinaryImage(inputFileName, params );
117  auto K = SH3::getKSpace( volimage );
118  auto surface = SH3::makeLightDigitalSurface( volimage, K, params );
119  auto primalSurface = SH3::makePrimalSurfaceMesh(surface);
120  trace.endBlock();
121 
122  trace.beginBlock("Creating polyscope surface");
123  std::vector<std::vector<SH3::SurfaceMesh::Vertex>> faces;
124  for(auto face= 0 ; face < primalSurface->nbFaces(); ++face)
125  faces.push_back(primalSurface->incidentVertices( face ));
126  polyscope::registerSurfaceMesh("Vol file", primalSurface->positions(), faces);
127  trace.endBlock();
128  }
129  else
130  {
131  std::vector<RealPoint> vertexPos;
132  std::vector<Point> pclPos;
133  std::vector<int> pclData;
134  std::vector<std::array<size_t,8>> hexIndices;
135  std::vector<int> hexData;
136 
137  trace.beginBlock("Loading vol");
138  auto volimage = SH3::makeGrayScaleImage(inputFileName);
139  trace.endBlock();
140  trace.beginBlock("Creating polyscope HexMesh/Point Cloud");
141  auto dom = volimage->domain();
142  auto W = dom.upperBound() - dom.lowerBound() + Point::diagonal(1);
143  auto WW = W + Point::diagonal(1); //for dual grid
144  trace.info()<<W<<std::endl;
145  trace.info()<<dom<<std::endl;
146 
147  size_t cpt=0;
148  unsigned char val;
149  Point p;
150  std::array<size_t,8> hex;
151  for(auto k=0; k <= W[2]; ++k)
152  for(auto j=0; j <= W[1]; ++j)
153  for(auto i=0; i <= W[0]; ++i)
154  {
155  p=Point(i,j,k);
156  if ((i<W[0]) && (j < W[1]) &&(k<W[2]))
157  val = (*volimage)(p);
158 
159  if (pclOnly)
160  {
161  if ((p < W) && (val>thresholdMin) && (val <=thresholdMax))
162  {
163  pclPos.push_back(p);
164  pclData.push_back(val);
165  }
166  }
167  else
168  {
169  vertexPos.push_back(p+dom.lowerBound() -RealPoint::diagonal(0.5) );
170  hex = { cpt, cpt +1 , cpt + 1 + WW[0] , cpt +WW[0] , cpt + WW[0]*WW[1], cpt +1 + WW[0]*WW[1], cpt + 1 + WW[0]*WW[1]+WW[0] , cpt + WW[0]*WW[1]+WW[0]};
171 
172  if (((i+1)< WW[0]) && ((j+1)< WW[1]) && ((k+1)< WW[2])&& (val>thresholdMin) && (val <=thresholdMax))
173  {
174  hexData.push_back(val);
175  hexIndices.push_back(hex);
176  }
177  ++cpt;
178  }
179  }
180 
181  if (pclOnly)
182  {
183  auto ps = polyscope::registerPointCloud("Vol file", pclPos);
184  ps->addScalarQuantity("values", pclData);
185  trace.info()<<"Nb vertices ="<<vertexPos.size()<<std::endl;
186  trace.info()<<"Nb hexes ="<<hexIndices.size()<<std::endl;
187  }
188  else
189  {
190  auto ps = polyscope::registerHexMesh("Vol file", vertexPos, hexIndices);
191  ps->addCellScalarQuantity("values", hexData);
192  trace.info()<<"Nb points ="<<pclPos.size()<<std::endl;
193  }
194  trace.endBlock();
195  }
196  polyscope::show();
197  return 0;
198 }
int main(int argc, char **argv)
typename Self::Point Point
static Self diagonal(Component val=1)
void beginBlock(const std::string &keyword="")
std::ostream & info()
double endBlock()
Space::Point Point
Trace trace(traceWriterTerm)