15 #if !defined( _MSC_VER ) && !defined( __MINGW32__ )
37 static void usage(
bool err =
true )
39 std::ostream& s = err ? std::cerr : std::cout;
40 s <<
"kd_tree_tool [-d <int>] [-2|-3] [-n <int>] [-u|-p|-m|-v] [-N <int>] [-s|-S] <input file> "
43 <<
"kd_tree_tool [-d <int>] -G <dims> [-s|-S] <output file>" << std::endl
44 <<
"kd_tree_tool [-h]" << std::endl;
47 s <<
"Tool to build adaptive kd-Tree" << std::endl;
48 s <<
" -d <int> Specify maximum depth for tree. Default: 30" << std::endl
49 <<
" -n <int> Specify maximum entities per leaf. Default: 6" << std::endl
50 <<
" -2 Build tree from surface elements. Default: yes" << std::endl
51 <<
" -3 Build tree from volume elements. Default: yes" << std::endl
52 <<
" -u Use 'SUBDIVISION' scheme for tree construction" << std::endl
53 <<
" -p Use 'SUBDIVISION_SNAP' tree construction algorithm." << std::endl
54 <<
" -m Use 'VERTEX_MEDIAN' tree construction algorithm." << std::endl
55 <<
" -v Use 'VERTEX_SAMPLE' tree construction algorithm." << std::endl
56 <<
" -N <int> Specify candidate split planes per axis. Default: 3" << std::endl
57 <<
" -t Tag elements will tree cell number." << std::endl
58 <<
" -T Write tree boxes to file." << std::endl
59 <<
" -G <dims> Generate grid - no input elements. Dims must be " << std::endl
60 <<
" HxWxD or H." << std::endl
61 <<
" -s Use range-based sets for tree nodes" << std::endl
62 <<
" -S Use vector-based sets for tree nodes" << std::endl
96 static int parseint(
int& i,
int argc,
char* argv[] )
102 std::cerr <<
"Expected value following '" << argv[i - 1] <<
"'" << std::endl;
106 int result = strtol( argv[i], &end, 0 );
107 if( result < 0 || *end )
109 std::cerr <<
"Expected positive integer following '" << argv[i - 1] <<
"'" << std::endl;
116 static void parsedims(
int& i,
int argc,
char* argv[],
double dims[3] )
122 std::cerr <<
"Expected value following '" << argv[i - 1] <<
"'" << std::endl;
126 dims[0] = strtod( argv[i], &end );
129 dims[2] = dims[1] = dims[0];
132 else if( *end !=
'x' && *end !=
'X' )
136 dims[1] = strtod( end, &end );
142 else if( *end !=
'x' && *end !=
'X' )
146 dims[2] = strtod( end, &end );
147 if( *end !=
'\0' )
goto error;
151 std::cerr <<
"Invaild dimension specification." << std::endl;
155 int main(
int argc,
char* argv[] )
157 bool surf_elems =
false, vol_elems =
false;
159 const char* output_file = 0;
160 const char* tree_file = 0;
161 std::ostringstream options;
162 bool tag_elems =
false;
164 bool make_grid =
false;
167 for(
int i = 1; i < argc; ++i )
169 if( argv[i][0] !=
'-' )
173 else if( !output_file )
174 output_file = argv[i];
180 if( !argv[i][1] || argv[i][2] )
usage();
191 options <<
"MESHSET_FLAGS=" << MESHSET_ORDERED <<
";";
196 options <<
"MAX_DEPTH=" <<
parseint( i, argc, argv ) <<
";";
199 options <<
"MAX_PER_LEAF=" <<
parseint( i, argc, argv ) <<
";";
214 options <<
"SPLITS_PER_DIR=" <<
parseint( i, argc, argv ) <<
";";
220 tree_file = argv[++i];
235 options <<
"CLEAN_UP=false;";
237 if( make_grid != !output_file )
usage();
240 if( !surf_elems && !vol_elems ) surf_elems = vol_elems =
true;
262 std::cerr <<
"Error reading file: " <<
input_file << std::endl;
269 std::cout <<
"Building tree..." << std::endl;
274 interface->get_entities_by_dimension( 0, 3, elems );
278 interface->get_entities_by_dimension( 0, 2, elems );
282 interface->get_entities_by_dimension( 0, 3, tmp );
291 std::cout <<
"Calculating stats..." << std::endl;
295 if( range.
size() != 1 )
298 std::cerr <<
"Internal error: Failed to retreive tree." << std::endl;
300 std::cerr <<
"Internal error: Multiple tree roots." << std::endl;
309 std::cout <<
"Tagging tree..." << std::endl;
315 std::cout <<
"Writing file... ";
317 rval = interface->write_mesh( output_file );
320 std::cerr <<
"Error writing file: " << output_file << std::endl;
324 std::cout <<
"Wrote " << output_file << std::endl;
328 std::cout <<
"Writing tree block rep...";
331 std::cout <<
"Wrote " << tree_file << std::endl;
333 block_time = clock() - write_time;
335 std::cout <<
"Times: "
340 if( tag_elems ) std::cout <<
"Tag Sets";
341 if( tree_file ) std::cout <<
"Block ";
342 std::cout << std::endl;
348 if( tree_file ) std::cout << std::setw( 8 ) <<
clock_to_string( block_time );
349 std::cout << std::endl;
360 if( !trees.
empty() ) std::cout <<
"Destroying existing tree(s) contained in file" << std::endl;
368 std::cerr <<
"Failed to destroy existing trees. Aborting" << std::endl;
379 std::cerr <<
"No elements from which to build tree." << std::endl;
394 double min[3] = { -0.5 * dims[0], -0.5 * dims[1], -0.5 * dims[2] };
395 double max[3] = { 0.5 * dims[0], 0.5 * dims[1], 0.5 * dims[2] };
399 std::cerr <<
"Failed to create tree root." << std::endl;
406 std::cerr <<
"Failed to get tree iterator." << std::endl;
418 std::cerr <<
"Failed to split tree leaf at depth " << iter.
depth() << std::endl;
426 std::cerr <<
"Error stepping KDTree iterator." << std::endl;
435 double dt =
t / (double)CLOCKS_PER_SEC;
465 if( range.
size() != 1 )
468 std::cerr <<
"Internal error: Failed to retreive tree." << std::endl;
470 std::cerr <<
"Internal error: Multiple tree roots." << std::endl;
474 root = *range.
begin();
484 std::vector< int > tag_vals;
488 moab->get_entities_by_handle( iter.
handle(), range );
491 moab->tag_set_data( tag, range, &tag_vals[0] );
502 if( range.
size() != 1 )
505 std::cerr <<
"Internal error: Failed to retreive tree." << std::endl;
507 std::cerr <<
"Internal error: Multiple tree roots." << std::endl;
511 root = *range.
begin();
524 moab->get_entities_by_handle( iter.
handle(), range );
532 moab->get_coords( &*i, 1, coords.
array() );
534 moab->tag_set_data( tag, &*i, 1, &tag_val );
546 if( range.
size() != 1 )
549 std::cerr <<
"Internal error: Failed to retreive tree." << std::endl;
551 std::cerr <<
"Internal error: Multiple tree roots." << std::endl;
555 root = *range.
begin();
574 double coords[24] = { x1, y1, z1, x2, y1, z1, x2, y2, z1, x1, y2, z1,
575 x1, y1, z2, x2, y1, z2, x2, y2, z2, x1, y2, z2 };
577 for(
int i = 0; i < 8; ++i )