DGtalTools  1.3.beta
mesh2vol.cpp
1 
27 #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 
78 template< unsigned int SEP >
79 void voxelizeAndExport(const std::string& inputFilename,
80  const std::string& outputFilename,
81  const unsigned int resolution,
82  const unsigned int margin)
83 {
84  using Domain = Z3i::Domain;
85  using PointR3 = Z3i::RealPoint;
86  using PointZ3 = Z3i::Point;
87 
88  trace.beginBlock("Preparing the mesh");
89  trace.info() << "Reading input file: " << inputFilename;
90  Mesh<PointR3> inputMesh;
91  MeshReader<PointR3>::importOFFFile(inputFilename.c_str(), inputMesh);
92  trace.info() << " [done]" << std::endl;
93  const std::pair<PointR3, PointR3> bbox = inputMesh.getBoundingBox();
94  trace.info()<< "Mesh bounding box: "<<bbox.first <<" "<<bbox.second<<std::endl;
95 
96  const double smax = (bbox.second - bbox.first).max();
97  const double factor = resolution / smax;
98  const PointR3 translate = -bbox.first;
99  trace.info() << "Scale = "<<factor<<" translate = "<<translate<<std::endl;
100  for(auto it = inputMesh.vertexBegin(), itend = inputMesh.vertexEnd();
101  it != itend; ++it)
102  {
103  //scale + translation
104  *it += translate;
105  *it *= factor;
106  }
107  trace.endBlock();
108 
109  trace.beginBlock("Voxelization");
110  trace.info() << "Voxelization " << SEP << "-separated ; " << resolution << "^3 ";
111  Domain aDomain(PointZ3().diagonal(-margin), PointZ3().diagonal(resolution+margin));
112 
113  //Digitization step
114  Z3i::DigitalSet mySet(aDomain);
115  MeshVoxelizer<Z3i::DigitalSet, SEP> aVoxelizer;
116  aVoxelizer.voxelize(mySet, inputMesh, 1.0);
117  trace.info() << " [done] " << std::endl;
118  trace.endBlock();
119 
120  trace.beginBlock("Exporting");
121  // Export the digital set to a vol file
122  trace.info()<<aDomain<<std::endl;
124  for(auto p: mySet)
125  image.setValue(p, 128);
126  image >> outputFilename.c_str();
127  trace.endBlock();
128 }
129 
130 int main( int argc, char** argv )
131 {
132 
133 // parse command line using CLI ----------------------------------------------
134  CLI::App app;
135  std::string inputFileName;
136  std::string outputFileName {"result.vol"};
137  unsigned int margin {0};
138  unsigned int separation {6};
139  unsigned int resolution {128};
140 
141  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 ");
142 
143  app.add_option("-i,--input,1", inputFileName, "mesh file (.off)." )
144  ->required()
145  ->check(CLI::ExistingFile);
146  app.add_option("-o,--output,2", outputFileName, "filename of ouput volumetric file (vol, pgm3d, ...).",true);
147  app.add_option("-m,--margin", margin, "add volume margin around the mesh bounding box.");
148  app.add_option("-s,--separation", separation, "voxelization 6-separated or 26-separated.", true)
149  -> check(CLI::IsMember({6, 26}));
150  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);
151 
152 
153  app.get_formatter()->column_width(40);
154  CLI11_PARSE(app, argc, argv);
155  // END parse command line using CLI ----------------------------------------------
156 
157  if (separation==6)
158  voxelizeAndExport<6>(inputFileName, outputFileName, resolution, margin);
159  else
160  voxelizeAndExport<26>(inputFileName, outputFileName, resolution, margin);
161  return EXIT_SUCCESS;
162 }
163 
void beginBlock(const std::string &keyword="")
ConstIterator vertexEnd() const
DGtal::LinearOperator< Calculus, dim, duality, dim, duality > diagonal(const DGtal::KForm< Calculus, dim, duality > &kform)
STL namespace.
double endBlock()
int main(int argc, char **argv)
ConstIterator vertexBegin() const
Trace trace(traceWriterTerm)
std::ostream & info()
std::pair< TPoint, TPoint > getBoundingBox() const
typename Self::Domain Domain