DGtalTools 2.0.0
Loading...
Searching...
No Matches
vol2obj.cpp
1
28#include <iostream>
29#include "DGtal/base/Common.h"
30#include "DGtal/helpers/StdDefs.h"
31#include "DGtal/io/readers/GenericReader.h"
32#include "DGtal/io/readers/PointListReader.h"
33
34#include "DGtal/images/ImageSelector.h"
35
36#include "CLI11.hpp"
37
38
39using namespace std;
40using namespace DGtal;
41using namespace Z3i;
42
76
77using Vertices = std::vector<std::array<double, 3>>;
78using Faces = std::vector<std::array<size_t, 3>>;
79
80template<typename T>
81void pushCube(const T& center, Vertices& vertices, Faces& faces) {
82 constexpr static double size = 0.5;
83 constexpr static std::array<std::array<double, 3>, 8> coords {{
84 {-size, -size, -size},
85 { size, -size, -size},
86 { size, size, -size},
87 {-size, size, -size},
88 {-size, -size, size},
89 { size, -size, size},
90 { size, size, size},
91 {-size, size, size}
92 }};
93 constexpr static std::array<std::array<size_t, 3>, 12> indices {{
94 {0, 1, 3}, {1, 2, 3},
95 {0, 1, 4}, {1, 5, 4},
96 {1, 2, 5}, {2, 6, 5},
97 {3, 7, 2}, {7, 6, 2},
98 {4, 5, 7}, {5, 6, 7},
99 {0, 4, 3}, {4, 7, 3}
100 }};
101
102 const double x = center[0];
103 const double y = center[1];
104 const double z = center[2];
105
106 const size_t startIndex = vertices.size() + 1;
107 for (size_t i = 0; i < coords.size(); ++i) {
108 vertices.push_back({x + coords[i][0],
109 y + coords[i][1],
110 z + coords[i][2]});
111 }
112 for (size_t i = 0; i < indices.size(); ++i) {
113 faces.push_back({startIndex + indices[i][0],
114 startIndex + indices[i][1],
115 startIndex + indices[i][2]});
116 }
117}
118
119int main( int argc, char** argv )
120{
121
122 // parse command line using CLI ----------------------------------------------
123 CLI::App app;
124 std::string inputFileName;
125 std::string outputFileName {"result.obj"};
126 int thresholdMin {128};
127 int thresholdMax {255};
128 DGtal::int64_t rescaleInputMin {0};
129 DGtal::int64_t rescaleInputMax {255};
130
131
132 app.description(" Converts any volumetric file (or .sdp file) to an OBJ one. Each grid point with value between [thresholdMin, thresholdMax] is exported as a unit cube.");
133 app.add_option("-i,--input,1", inputFileName, "vol file (.vol, .longvol .p3d, .pgm3d or .sdp and if DGTAL_WITH_ITK is selected: dicom, dcm, mha, mhd). For longvol, dicom, dcm, mha or mhd formats, the input values are linearly scaled between 0 and 255." )
134 ->required()
135 ->check(CLI::ExistingFile);
136 app.add_option("--output,-o,2",outputFileName ,"output file (.obj or .off).");
137 app.add_option("--thresholdMin,-m", thresholdMin, "threshold min (excluded) to define binary shape.");
138 app.add_option("--thresholdMax,-M", thresholdMax, "threshold max (included) to define binary shape.");
139 app.add_option("--rescaleInputMin", rescaleInputMin, "min value used to rescale the input intensity (to avoid basic cast into 8 bits image).");
140 app.add_option("--rescaleInputMax", rescaleInputMax, "max value used to rescale the input intensity (to avoid basic cast into 8 bits image).");
141
142
143 app.get_formatter()->column_width(40);
144 CLI11_PARSE(app, argc, argv);
145 // END parse command line using CLI ----------------------------------------------
146
147 Vertices vertices;
148 Faces faces;
149
150 typedef ImageSelector<Domain, unsigned char>::Type Image;
151 string extension = inputFileName.substr(inputFileName.find_last_of(".") + 1);
152
153 if(extension!="sdp")
154 {
155 typedef DGtal::functors::Rescaling<DGtal::int64_t ,unsigned char > RescalFCT;
156 Image image = GenericReader< Image >::importWithValueFunctor( inputFileName,RescalFCT(rescaleInputMin,
157 rescaleInputMax,
158 0, 255) );
159 trace.info() << "Image loaded: "<<image<< std::endl;
160 Domain domain = image.domain();
161 for(Domain::ConstIterator it = domain.begin(), itend=domain.end(); it!=itend; ++it){
162 unsigned char val= image( (*it) );
163 if(val<=thresholdMax && val >=thresholdMin){
164 pushCube(*it, vertices, faces);
165 }
166 }
167 }
168 else
169 if(extension=="sdp")
170 {
171 vector<Z3i::Point> vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(inputFileName);
172 for(unsigned int i=0;i< vectVoxels.size(); i++){
173 pushCube(vectVoxels.at(i), vertices, faces);
174 }
175 }
176
177 // Export file
178 std::ofstream outFile(outputFileName);
179 if (!outFile) {
180 trace.error() << "Can not open file: '" << outputFileName << "'\n";
181 return EXIT_FAILURE;
182 }
183
184 outFile << "#This file was created by DGtalTools vol2obj object\n";
185 for (size_t i = 0; i < vertices.size(); ++i) {
186 outFile << "v " << vertices[i][0] << ' ' << vertices[i][1] << ' ' << vertices[i][2] << '\n';
187 }
188 for (size_t i = 0; i < faces.size(); ++i) {
189 outFile << "f " << faces[i][0] << ' ' << faces[i][1] << ' ' << faces[i][2] << '\n';
190 }
191
192 return EXIT_SUCCESS;
193}
Definition ATu0v1.h:57