DGtalTools  1.5.beta
mesh2vol.cpp
1 
28 #include <iostream>
29 #include <fstream>
30 #include <chrono>
31 #include "DGtal/helpers/StdDefs.h"
32 #include "DGtal/shapes/MeshVoxelizer.h"
33 #include "DGtal/kernel/sets/CDigitalSet.h"
34 #include "DGtal/kernel/domains/HyperRectDomain.h"
35 #include "DGtal/io/readers/MeshReader.h"
36 #include "DGtal/io/Display3D.h"
37 #include "DGtal/io/writers/GenericWriter.h"
38 #include "DGtal/images/ImageContainerBySTLVector.h"
39 
40 #include "CLI11.hpp"
41 
42 
43 using namespace std;
44 using namespace DGtal;
45 
46 
80 template< unsigned int SEP >
81 void voxelizeAndExport(const std::string& inputFilename,
82  const std::string& outputFilename,
83  const unsigned int resolution,
84  const unsigned int margin,
85  const unsigned char fillVal)
86 {
87  using Domain = Z3i::Domain;
88  using PointR3 = Z3i::RealPoint;
89  using PointZ3 = Z3i::Point;
90 
91  trace.beginBlock("Preparing the mesh");
92  trace.info() << "Reading input file: " << inputFilename;
93  Mesh<PointR3> inputMesh;
94  inputMesh << inputFilename.c_str();
95  trace.info() << " [done]" << std::endl;
96  const std::pair<PointR3, PointR3> bbox = inputMesh.getBoundingBox();
97  trace.info()<< "Mesh bounding box: "<<bbox.first <<" "<<bbox.second<<std::endl;
98 
99  const double smax = (bbox.second - bbox.first).max();
100  if (resolution != 0)
101  {
102  const double factor = resolution / smax;
103  const PointR3 translate = -bbox.first;
104  trace.info() << "Scale = "<<factor<<" translate = "<<translate<<std::endl;
105  for(auto it = inputMesh.vertexBegin(), itend = inputMesh.vertexEnd();
106  it != itend; ++it)
107  {
108  //scale + translation
109  *it += translate;
110  *it *= factor;
111  }
112  trace.endBlock();
113  }
114  trace.beginBlock("Voxelization");
115  trace.info() << "Voxelization " << SEP << "-separated ; " << resolution << "^3 ";
116  Domain aDomain(PointZ3().diagonal(-margin), PointZ3().diagonal(resolution+margin));
117  if (resolution == 0)
118  {
119  aDomain = Domain(bbox.first, bbox.second);
120  }
121 
122  //Digitization step
123  Z3i::DigitalSet mySet(aDomain);
124  MeshVoxelizer<Z3i::DigitalSet, SEP> aVoxelizer;
125  aVoxelizer.voxelize(mySet, inputMesh, 1.0);
126  trace.info() << " [done] " << std::endl;
127  trace.endBlock();
128 
129  trace.beginBlock("Exporting");
130  // Export the digital set to a vol file
131  trace.info()<<aDomain<<std::endl;
133  for(auto p: mySet)
134  image.setValue(p, fillVal);
135  image >> outputFilename.c_str();
136  trace.endBlock();
137 }
138 
139 int main( int argc, char** argv )
140 {
141 
142 // parse command line using CLI ----------------------------------------------
143  CLI::App app;
144  std::string inputFileName;
145  std::string outputFileName {"result.vol"};
146  unsigned int margin {0};
147  unsigned int separation {6};
148  unsigned int resolution {128};
149  unsigned char fillValue {128};
150  bool unitScale {false};
151 
152  app.description("Convert a mesh file into a 26-separated or 6-separated volumetric voxelization in a given resolution grid. \n Example:\n mesh2vol ${DGtal}/examples/samples/tref.off output.vol --separation 26 --resolution 256 ");
153 
154  app.add_option("-i,--input,1", inputFileName, "mesh file (.off)." )
155  ->required()
156  ->check(CLI::ExistingFile);
157  app.add_option("-o,--output,2", outputFileName, "filename of ouput volumetric file (vol, pgm3d, ...).",true);
158  app.add_option("-m,--margin", margin, "add volume margin around the mesh bounding box.");
159  app.add_flag("-d,--objectDomainBB", unitScale, "use the digitization space defined from bounding box of input mesh. If seleted, the option --resolution will have no effect.");
160  app.add_option("-f,--fillValue", fillValue, "change the default output volumetric image value in [1...255].")
161  ->expected(0, 255);
162  app.add_option("-s,--separation", separation, "voxelization 6-separated or 26-separated.", true)
163  -> check(CLI::IsMember({6, 26}));
164  app.add_option("-r,--resolution", resolution,"digitization domain size (e.g. 128). The mesh will be scaled such that its bounding box maps to [0,resolution)^3.", true);
165 
166 
167  app.get_formatter()->column_width(40);
168  CLI11_PARSE(app, argc, argv);
169  // END parse command line using CLI ----------------------------------------------
170 
171  if (separation==6)
172  voxelizeAndExport<6>(inputFileName, outputFileName, unitScale ? 0 : resolution, margin, fillValue);
173  else
174  voxelizeAndExport<26>(inputFileName, outputFileName, unitScale ? 0 : resolution, margin, fillValue);
175  return EXIT_SUCCESS;
176 }
177 
int main(int argc, char **argv)
typename Self::Domain Domain
std::pair< TPoint, TPoint > getBoundingBox() const
ConstIterator vertexBegin() const
ConstIterator vertexEnd() const
void beginBlock(const std::string &keyword="")
std::ostream & info()
double endBlock()
DGtal::LinearOperator< Calculus, dim, duality, dim, duality > diagonal(const DGtal::KForm< Calculus, dim, duality > &kform)
Trace trace(traceWriterTerm)