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;