46 #define M_PI_2 1.5707963267948966192E0
60 typedef unsigned char byte;
63 int main(
int argc,
char **argv)
66 size_t depth, height, width;
70 bool mark_free =
false;
72 bool show_help =
false;
73 string output_filename;
80 bool applyBBX =
false;
81 bool applyOffset =
false;
85 if(argc == 1) show_help =
true;
86 for(
int i = 1; i < argc && !show_help; i++) {
87 if(strcmp(argv[i],
"--help") == 0 || strcmp(argv[i],
"-help") == 0 ||
88 strcmp(argv[i],
"--usage") == 0 || strcmp(argv[i],
"-usage") == 0 ||
89 strcmp(argv[i],
"-h") == 0
95 cout <<
"Usage: "<<argv[0]<<
" [OPTIONS] <binvox filenames>" << endl;
96 cout <<
"\tOPTIONS:" << endl;
97 cout <<
"\t -o <file> Output filename (default: first input filename + .bt)\n";
98 cout <<
"\t --mark-free Mark not occupied cells as 'free' (default: unknown)\n";
99 cout <<
"\t --rotate Rotate left by 90 deg. to fix the coordinate system when exported from Webots\n";
100 cout <<
"\t --bb <minx> <miny> <minz> <maxx> <maxy> <maxz>: force bounding box for OcTree\n";
101 cout <<
"\t --offset <x> <y> <z>: add an offset to the final coordinates\n";
102 cout <<
"If more than one binvox file is given, the models are composed to a single bonsai tree->\n";
103 cout <<
"All options apply to the subsequent input files.\n\n";
107 for(
int i = 1; i < argc; i++) {
109 if(strcmp(argv[i],
"--mark-free") == 0) {
112 }
else if(strcmp(argv[i],
"--no-mark-free") == 0) {
115 }
else if(strcmp(argv[i],
"--rotate") == 0) {
118 }
else if(strcmp(argv[i],
"-o") == 0 && i < argc - 1) {
120 output_filename = argv[i];
123 }
else if (strcmp(argv[i],
"--bb") == 0 && i < argc - 7) {
125 minX = atof(argv[i]);
127 minY = atof(argv[i]);
129 minZ = atof(argv[i]);
131 maxX = atof(argv[i]);
133 maxY = atof(argv[i]);
135 maxZ = atof(argv[i]);
140 }
else if (strcmp(argv[i],
"--offset") == 0 && i < argc - 4) {
142 offset(0) = (float) atof(argv[i]);
144 offset(1) = (float) atof(argv[i]);
146 offset(2) = (float) atof(argv[i]);
155 ifstream *input =
new ifstream(argv[i], ios::in | ios::binary);
157 cerr <<
"Error: Could not open input file " << argv[i] <<
"!" << endl;
160 cout <<
"Reading binvox file " << argv[i] <<
"." << endl;
161 if(output_filename.empty()) {
162 output_filename = string(argv[i]).append(
".bt");
169 if (line.compare(
"#binvox") != 0) {
170 cout <<
"Error: first line reads [" << line <<
"] instead of [#binvox]" << endl;
175 cout <<
"reading binvox version " << version << endl;
179 while(input->good() && !done) {
181 if (line.compare(
"data") == 0) done = 1;
182 else if (line.compare(
"dim") == 0) {
183 *input >> depth >> height >> width;
185 else if (line.compare(
"translate") == 0) {
186 *input >> tx >> ty >> tz;
188 else if (line.compare(
"scale") == 0) {
192 cout <<
" unrecognized keyword [" << line <<
"], skipping" << endl;
196 }
while(input->good() && (c !=
'\n'));
201 cout <<
" error reading header" << endl;
205 cout <<
" missing dimensions in header" << endl;
209 size = width * height * depth;
210 int maxSide = std::max(std::max(width, height), depth);
211 double res = double(scale)/double(maxSide);
214 cout <<
"Generating octree with leaf size " << res << endl << endl;
219 cout <<
"Bounding box for Octree: [" << minX <<
","<< minY <<
"," << minZ <<
" - "
220 << maxX <<
","<< maxY <<
"," << maxZ <<
"]\n";
224 std::cout <<
"Offset on final map: "<< offset << std::endl;
228 cout <<
"Read data: ";
235 size_t end_index = 0;
236 size_t nr_voxels = 0;
237 size_t nr_voxels_out = 0;
239 input->unsetf(ios::skipws);
242 while((end_index < size) && input->good()) {
243 *input >> value >> count;
246 end_index = index + count;
247 if (end_index > size)
return 0;
248 for(
size_t j=index; j < end_index; j++) {
250 if(j % (size / 20) == 0) {
255 size_t y = j % width;
256 size_t z = (j / width) % height;
257 size_t x = j / (width * height);
260 point3d endpoint((
float) ((
double) x*res + tx + 0.000001),
261 (
float) ((
double) y*res + ty + 0.000001),
262 (
float) ((
double) z*res + tz + 0.000001));
270 if (!applyBBX || (endpoint(0) <= maxX && endpoint(0) >= minX
271 && endpoint(1) <= maxY && endpoint(1) >= minY
272 && endpoint(2) <= maxZ && endpoint(2) >= minZ)){
275 if(mark_free || value == 1) {
283 if (value) nr_voxels += count;
289 cout << endl << endl;
292 cout <<
" read " << nr_voxels <<
" voxels, skipped "<<nr_voxels_out <<
" (out of bounding box)\n\n";
296 cout <<
"Pruning octree" << endl << endl;
301 if(output_filename.empty()) {
302 cerr <<
"Error: No input files found." << endl << endl;
306 cout <<
"Writing octree to " << output_filename << endl << endl;
310 cout <<
"done" << endl << endl;