13 #include "../TestUtil.hpp"
31 static const char*
NAME =
"obb_test";
34 typedef std::map< std::string, std::vector< RayTest > >::iterator
ray_test_itr;
39 std::vector< RayTest > tests;
40 std::string file =
STRINGIFY( MESHDIR )
"/3k-tri-sphere.vtk";
42 {
"triangle edge ", 2,
CartVect( 0, 0, 0 ),
CartVect( 4.99167, 0, 99.7502 ) },
45 num_tests =
sizeof( set1 ) /
sizeof( set1[0] );
46 tests.insert( tests.begin(), &set1[0], &set1[
num_tests] );
51 file =
STRINGIFY( MESHDIR )
"/3k-tri-cube.h5m";
53 file =
STRINGIFY( MESHDIR )
"/3k-tri-cube.vtk";
57 {
"interior triangle edge ", 2,
CartVect( 0, 0, 0 ),
CartVect( -0.25, -0.05, 5 ) },
58 {
"interior triangle node ", 5,
CartVect( 0, 0, 0 ),
CartVect( -0.3, -0.3, 5 ) },
59 {
"edge triangle interior ", 1,
CartVect( 0, 0, 0 ),
CartVect( 5, 2.9, 2.9 ) },
62 {
"corner triangle interior ", 1,
CartVect( 0, 0, 0 ),
CartVect( 5, 4.9, 4.9 ) },
66 num_tests =
sizeof( set2 ) /
sizeof( set2[0] );
67 tests.insert( tests.begin(), &set2[0], &set2[
num_tests] );
77 const char* default_message =
"Invalid option";
80 std::ostream& str =
error ? std::cerr : std::cout;
84 if( opt ) str <<
": " << opt;
88 str <<
"Usage: " <<
NAME <<
" [output opts.] [settings] [file ...]" << std::endl;
89 str <<
" " <<
NAME <<
" -h" << std::endl;
91 str <<
" If no file is specified the defautl test files will be used" << std::endl
92 <<
" -h print help text. " << std::endl
93 <<
" -v verbose output (may be specified multiple times) " << std::endl
94 <<
" -q quiet (minimal output) " << std::endl
95 <<
" -f <x>:<y>:<z>:<i>:<j>:<k> Do ray fire" << std::endl
96 <<
" -c write box geometry to Cubit journal file." << std::endl
97 <<
" -k write leaf contents to vtk files." << std::endl
98 <<
" -K write contents of leaf boxes intersected by rays to vtk file." << std::endl
99 <<
" -o <name> Save file containing tree and triangles. Mesh tag \"OBB_ROOT\"." << std::endl
100 <<
" -t <real> specify tolerance" << std::endl
101 <<
" -n <int> specify max entities per leaf node " << std::endl
102 <<
" -l <int> specify max tree levels" << std::endl
103 <<
" -r <real> specify worst cell split ratio" << std::endl
104 <<
" -R <real> specify best cell split ratio" << std::endl
105 <<
" -s force construction of surface tree" << std::endl
106 <<
" -S do not build surface tree." << std::endl
107 <<
" (Default: surface tree if file contains multiple surfaces" << std::endl
108 <<
" -u use unordered (Range) meshsets for tree nodes" << std::endl
109 <<
" -U use ordered (vector) meshsets for tree nodes" << std::endl
110 <<
" Verbosity (-q sets to 0, each -v increments, default is 1):" << std::endl
111 <<
" 0 - no output" << std::endl
112 <<
" 1 - status messages and error summary" << std::endl
113 <<
" 2 - print tree statistics " << std::endl
114 <<
" 3 - output errors for each node" << std::endl
115 <<
" 4 - print tree" << std::endl
116 <<
" 5 - print tree w/ contents of each node" << std::endl
117 <<
" See documentation for OrientedBoxTreeTool::Settings for " << std::endl
118 <<
" a description of tree generation settings." << std::endl;
122 static const char*
get_option(
int& i,
int argc,
char* argv[] )
125 if( i == argc )
usage(
"Expected argument following option", argv[i - 1] );
131 const char* str =
get_option( i, argc, argv );
133 long val = strtol( str, &end_ptr, 0 );
134 if( !*str || *end_ptr )
usage(
"Expected integer following option", argv[i - 1] );
140 const char* str =
get_option( i, argc, argv );
142 double val = strtod( str, &end_ptr );
143 if( !*str || *end_ptr )
usage(
"Expected real number following option", argv[i - 1] );
162 static std::vector< CartVect >
rays;
166 static void parse_ray(
int& i,
int argc,
char* argv[] );
168 int main(
int argc,
char* argv[] )
171 int fail = MPI_Init( &argc, &argv );
177 std::vector< const char* > file_names;
179 for(
int i = 1; i < argc; ++i )
181 if( flags && argv[i][0] ==
'-' )
183 if( !argv[i][1] || argv[i][2] )
usage( 0, argv[i] );
247 file_names.push_back( argv[i] );
256 std::cout << version << std::endl;
262 <<
"tolerance: " <<
tolerance << std::endl
270 std::cerr <<
"Invalid settings specified." << std::endl;
274 if( file_names.empty() )
276 std::cerr <<
"No file(s) specified." << std::endl;
279 std::cerr <<
"Using default file \"" << file->first <<
'"' << std::endl;
280 file_names.push_back( file->first.c_str() );
286 std::cout <<
"Only one input file allowed if \"-o\" option is specified." << std::endl;
287 std::cout <<
"Only testing with single file " << file_names[0] << std::endl;
288 file_names.erase( ++file_names.begin(), file_names.end() );
292 for(
unsigned j = 0; j < file_names.size(); ++j )
293 if( !
do_file( file_names[j] ) ) ++exit_val;
296 fail = MPI_Finalize();
300 return exit_val ? exit_val + 2 : 0;
306 if( 6 != sscanf(
get_option( i, argc, argv ),
"%lf:%lf:%lf:%lf:%lf:%lf", &point[0], &point[1], &point[2],
307 &direction[0], &direction[1], &direction[2] ) )
308 usage(
"Expected ray specified as <x>:<y>:<z>:<i>:<j>:<k>", 0 );
310 rays.push_back( point );
311 rays.push_back( direction );
327 if( printing ) stream << instance->
id_from_handle( handle ) <<
": " <<
string << std::endl;
333 print( handle,
string );
366 : instance( instance_ptr ), tool( tool_ptr ), printing( print_errors ), epsilon( tol ), surfaces( surfs ),
367 stream( str ),
settings( s ), entity_count( 0 ), loose_box_count( 0 ), child_outside_count( 0 ),
368 entity_outside_count( 0 ), num_entities_outside( 0 ), non_ortho_count( 0 ),
error_count( 0 ),
369 empty_leaf_count( 0 ), non_empty_non_leaf_count( 0 ), entity_invalid_count( 0 ), unsorted_axis_count( 0 ),
370 non_unit_count( 0 ), duplicate_entity_count( 0 ), bad_outer_radius_count( 0 ), missing_surface_count( 0 ),
371 multiple_surface_count( 0 ), surface_depth( -1 ), surface_handle( 0 )
377 return 0 == loose_box_count + child_outside_count + entity_outside_count + num_entities_outside +
378 non_ortho_count +
error_count + empty_leaf_count + non_empty_non_leaf_count +
379 entity_invalid_count + unsorted_axis_count + non_unit_count + duplicate_entity_count +
380 bad_outer_radius_count + missing_surface_count + multiple_surface_count;
397 rval = instance->get_entities_by_handle( node, contents );
398 if(
MB_SUCCESS != rval )
return error( node,
"Error getting contents of tree node. Corrupt tree?" );
399 entity_count += contents.
size();
404 if( depth <= surface_depth ) surface_depth = -1;
408 if( surf_iter != contents.
end() )
410 surface = *surf_iter;
411 contents.
erase( surf_iter );
416 if( surface_depth >= 0 )
418 ++multiple_surface_count;
419 print( node,
"Multiple surfaces in encountered in same subtree." );
423 surface_depth = depth;
424 surface_handle = surface;
429 std::vector< EntityHandle >
children;
430 rval = tool->get_moab_instance()->get_child_meshsets( node,
children );
432 return error( node,
"Error getting children. Corrupt tree?" );
435 rval = tool->box( node,
box );
436 if(
MB_SUCCESS != rval )
return error( node,
"Error getting oriented box from tree node. Corrupt tree?" );
441 print( node,
"Empty leaf node.\n" );
445 ++non_empty_non_leaf_count;
446 print( node,
"Non-leaf node is not empty." );
449 if( surfaces &&
children.empty() && surface_depth < 0 )
451 ++missing_surface_count;
452 print( node,
"Reached leaf node w/out encountering any surface set." );
455 double dot_epsilon = epsilon * (
box.axis( 0 ) +
box.axis( 1 ) +
box.axis( 2 ) ).
length();
456 if(
box.axis( 0 ) %
box.axis( 1 ) > dot_epsilon ||
box.axis( 0 ) %
box.axis( 2 ) > dot_epsilon ||
457 box.axis( 1 ) %
box.axis( 2 ) > dot_epsilon )
460 print( node,
"Box axes are not orthogonal" );
465 for(
int i = 0; i < 2; ++i )
468 rval = tool->box(
children[i], other_box );
470 return error(
children[i],
" Error getting oriented box from tree node. Corrupt tree?" );
480 double vol_ratio = other_box.
volume() /
box.volume();
481 if( vol_ratio > 2.0 )
484 sprintf(
string,
"child/parent volume ratio is %f", vol_ratio );
486 sprintf(
string,
" child/parent area ratio is %f", other_box.
area() /
box.area() );
493 bool bad_element =
false;
494 bool bad_element_handle =
false;
495 bool bad_element_conn =
false;
496 bool duplicate_element =
false;
498 bool boundary[6] = {
false,
false,
false,
false,
false,
false };
501 EntityType type = instance->type_from_handle( *it );
511 rval = instance->get_connectivity( *it, conn, conn_len );
514 bad_element_handle =
true;
518 std::vector< CartVect > coords( conn_len );
519 rval = instance->get_coords( conn, conn_len, coords[0].array() );
522 bad_element_conn =
true;
526 bool outside =
false;
527 for( std::vector< CartVect >::iterator j = coords.begin(); j != coords.end(); ++j )
529 if( !
box.contained( *j, epsilon ) )
532 for(
int d = 0; d < 3; ++d )
534 #if MB_ORIENTED_BOX_UNIT_VECTORS
535 double n =
box.axis( d ) % ( *j -
box.center );
536 if( fabs( n -
box.length[d] ) <= epsilon ) boundary[2 * d] =
true;
537 if( fabs( n +
box.length[d] ) <= epsilon ) boundary[2 * d + 1] =
true;
539 double ln =
box.axis( d ).length();
542 if( fabs( v1 %
box.axis[d] ) <= ln * epsilon ) boundary[2 * d] =
true;
543 if( fabs( v2 %
box.axis[d] ) <= ln * epsilon ) boundary[2 * d + 1] =
true;
547 if( outside ) ++num_outside;
549 if( !seen.insert( *it ).second )
551 duplicate_element =
true;
552 ++duplicate_entity_count;
556 CartVect alength(
box.axis( 0 ).length(),
box.axis( 1 ).length(),
box.axis( 2 ).length() );
557 #if MB_ORIENTED_BOX_UNIT_VECTORS
565 ++unsorted_axis_count;
566 print( node,
"Box axes are not ordered from shortest to longest." );
569 #if MB_ORIENTED_BOX_UNIT_VECTORS
570 if( fabs( alength[0] - 1.0 ) > epsilon || fabs( alength[1] - 1.0 ) > epsilon || fabs( alength[2] - 1.0 ) > epsilon )
573 print( node,
"Box axes are not unit vectors." );
577 #if MB_ORIENTED_BOX_OUTER_RADIUS
580 ++bad_outer_radius_count;
581 print( node,
"Box has incorrect outer radius." );
588 sprintf(
string,
"leaf at depth %d with %u entities", depth, (
unsigned)contents.
size() );
589 print( node,
string );
592 bool all_boundaries =
true;
593 for(
int f = 0; f < 6; ++f )
594 all_boundaries = all_boundaries && boundary[f];
598 ++entity_invalid_count;
599 print( node,
"Set contained an entity with an inappropriate dimension." );
601 if( bad_element_handle )
604 print( node,
"Error querying face contained in set." );
606 if( bad_element_conn )
609 print( node,
"Error querying connectivity of element." );
611 if( duplicate_element )
613 print( node,
"Elements occur in multiple leaves of tree." );
615 if( num_outside > 0 )
617 ++entity_outside_count;
618 num_entities_outside += num_outside;
620 stream << instance->id_from_handle( node ) <<
": " << num_outside <<
" elements outside box." << std::endl;
622 else if( !all_boundaries && !contents.
empty() )
625 print( node,
"Box does not fit contained elements tightly." );
654 double sign[] = { -1, 1 };
655 for(
int i = 0; i < 2; ++i )
656 for(
int j = 0; j < 2; ++j )
657 for(
int k = 0; k < 2; ++k )
659 #if MB_ORIENTED_BOX_UNIT_VECTORS
661 box.length[1] * sign[j] *
box.axis( 1 ) +
box.length[2] * sign[k] *
box.axis( 2 );
664 box.center + sign[i] *
box.axis( 0 ) + sign[j] *
box.axis( 1 ) + sign[k] *
box.axis( 2 );
666 fprintf( file,
"create vertex %f %f %f\n", corner[0], corner[1], corner[2] );
668 fprintf( file,
"#{i=Id(\"vertex\")-7}\n" );
669 fprintf( file,
"create surface vertex {i } {i+1} {i+3} {i+2}\n" );
670 fprintf( file,
"create surface vertex {i+4} {i+5} {i+7} {i+6}\n" );
671 fprintf( file,
"create surface vertex {i+1} {i+0} {i+4} {i+5}\n" );
672 fprintf( file,
"create surface vertex {i+3} {i+2} {i+6} {i+7}\n" );
673 fprintf( file,
"create surface vertex {i+2} {i+0} {i+4} {i+6}\n" );
674 fprintf( file,
"create surface vertex {i+3} {i+1} {i+5} {i+7}\n" );
675 fprintf( file,
"delete vertex {i}-{i+7}\n" );
676 fprintf( file,
"#{s=Id(\"surface\")-5}\n" );
677 fprintf( file,
"create volume surface {s} {s+1} {s+2} {s+3} {s+4} {s+5} noheal\n" );
678 int id = tool->get_moab_instance()->id_from_handle( node );
679 fprintf( file,
"volume {Id(\"volume\")} name \"cell%d\"\n",
id );
687 VtkWriter( std::string base_name,
Interface* interface ) : baseName( base_name ), instance( interface ) {}
707 rval = instance->get_number_entities_by_handle( node, count );
708 if(
MB_SUCCESS != rval || 0 == count )
return rval;
710 int id = instance->id_from_handle( node );
712 sprintf( id_str,
"%d",
id );
714 std::string file_name( baseName );
719 return instance->write_mesh( file_name.c_str(), &node, 1 );
725 bool have_surface_tree );
737 bool haveSurfTree =
false;
744 if(
verbosity ) std::cout <<
"Failed to read file: \"" <<
filename <<
'"' << std::endl;
758 const void* tagvalues[] = { &
dim };
767 std::cerr <<
"No Surfaces found." << std::endl;
781 std::cerr <<
"get_entities_by_dimension( 2 ) failed." << std::endl;
787 if(
verbosity ) std::cout <<
"File \"" <<
filename <<
"\" contains no 2D elements" << std::endl;
791 if(
verbosity ) std::cout <<
"Building tree from " <<
entities.size() <<
" 2D elements" << std::endl;
796 if(
verbosity ) std::cout <<
"Failed to build tree." << std::endl;
803 if(
verbosity ) std::cout <<
"Building tree from " << surfaces.
size() <<
" surfaces" << std::endl;
806 Range surf_trees, surf_tris;
816 if(
verbosity ) std::cout <<
"Failed to build tree for surface." << std::endl;
819 surf_trees.
insert( surf_root );
828 if(
verbosity ) std::cout <<
"Failed to build tree." << std::endl;
833 std::cout <<
"Built tree from " << surfaces.
size() <<
" surfaces"
834 <<
" (" <<
entities.size() - surfaces.
size() <<
" elements)" << std::endl;
842 name +=
".boxes.jou";
843 FILE* ptr = fopen( name.c_str(),
"w+" );
846 perror( name.c_str() );
850 if(
verbosity ) std::cout <<
"Writing: " << name << std::endl;
851 fprintf( ptr,
"graphics off\n" );
854 fprintf( ptr,
"graphics on\n" );
863 std::cout <<
"Writing leaf contents as : " <<
filename <<
".xxx.vtk where 'xxx' is the set id" << std::endl;
868 if(
verbosity > 3 ) tool.
print( root, std::cout, print_contents );
871 rval = tool.
stats( root, std::cout );
872 if(
MB_SUCCESS != rval ) std::cout <<
"****** Failed to get tree statistics ******" << std::endl;
881 if(
verbosity ) std::cout <<
"Errors traversing tree. Corrupt tree?" << std::endl;
885 if( missing ) result =
false;
890 std::cout << std::endl <<
"No errors detected." << std::endl;
892 std::cout << std::endl <<
"*********************** ERROR SUMMARY **********************" << std::endl;
894 std::cout <<
"* " << op.
child_outside_count <<
" child boxes not contained in parent." << std::endl;
896 std::cout <<
"* " << op.
entity_outside_count <<
" nodes containing entities outside of box." << std::endl;
907 std::cout <<
"* " << op.
multiple_surface_count <<
" surfaces within other surface subtrees." << std::endl;
909 std::cout <<
"* " << op.
non_ortho_count <<
" boxes with non-orthononal axes." << std::endl;
914 std::cout <<
"* " << op.
unsorted_axis_count <<
" boxes axes in unsorted order." << std::endl;
916 std::cout <<
"* " << op.
loose_box_count <<
" boxes that do not fit the contained entities tightly."
922 std::cout <<
"* tree built from " <<
entities.size() <<
" entities contains " << op.
entity_count
923 <<
" entities." << std::endl;
924 if( !result ) std::cout <<
"************************************************************" << std::endl;
932 std::cerr <<
"FAILED TO WRITE '" <<
save_file_name <<
"'" << std::endl;
937 if(
verbosity ) std::cout <<
"Ray fire test failed." << std::endl;
943 if(
verbosity ) std::cout <<
"Closest point test failed" << std::endl;
950 if(
verbosity ) std::cout <<
"delete_tree failed." << std::endl;
957 static void count_non_tol( std::vector< double > intersections,
int& non_tol_count,
double& non_tol_dist )
960 for(
size_t i = 0; i < intersections.size(); ++i )
965 if( intersections[i] < non_tol_dist ) non_tol_dist = intersections[i];
974 double& non_tol_dist,
980 non_tol_dist = std::numeric_limits< double >::max();
983 std::vector< double > intersections;
984 std::vector< EntityHandle > facets;
986 test.direction.array(), 0, &stats );
989 if(
verbosity ) std::cout <<
" Call to OrientedBoxTreeTool::ray_intersect_triangles failed." << std::endl;
995 if( intersections.size() !=
test.expected_hits )
998 std::cout <<
" Expected " <<
test.expected_hits <<
" and got " << intersections.size()
999 <<
" hits for ray fire of " <<
test.description << std::endl;
1002 for(
unsigned j = 0; j < intersections.size(); ++j )
1003 std::cout <<
" " << intersections[j];
1004 std::cout << std::endl;
1009 count_non_tol( intersections, non_tol_count, non_tol_dist );
1018 double& non_tol_dist,
1025 non_tol_dist = std::numeric_limits< double >::max();
1028 const int NUM_NON_TOL_INT = 1;
1030 std::vector< double > intersections;
1031 std::vector< EntityHandle > surfs;
1032 std::vector< EntityHandle > facets;
1037 test.direction.array(), search_win, int_reg_ctxt, &stats );
1041 if(
verbosity ) std::cout <<
" Call to OrientedBoxTreeTool::ray_intersect_sets failed." << std::endl;
1047 if( surfs.size() != intersections.size() )
1049 if(
verbosity ) std::cout <<
" ray_intersect_sets did not return sets for all intersections." << std::endl;
1053 count_non_tol( intersections, non_tol_count, non_tol_dist );
1055 if( non_tol_count > NUM_NON_TOL_INT )
1058 std::cout <<
" Requested " << NUM_NON_TOL_INT <<
"intersections "
1059 <<
" beyond tolerance. Got " << non_tol_count << std::endl;
1072 if(
verbosity > 1 ) std::cout <<
"beginning ray fire tests" << std::endl;
1078 if(
verbosity ) std::cerr <<
"Error getting box for tree root set" << std::endl;
1083 std::cout <<
box << std::endl;
1087 std::vector< RayTest > tests;
1088 RayTest default_tests[] = { {
"large axis through box", 2,
box.center - 1.2 *
box.scaled_axis( 2 ),
box.axis( 2 ) },
1089 {
"small axis through box", 2,
box.center - 1.2 *
box.scaled_axis( 0 ),
box.axis( 0 ) },
1090 {
"parallel miss", 0,
box.center + 2.0 *
box.scaled_axis( 1 ),
box.axis( 2 ) },
1091 {
"skew miss", 0,
box.center +
box.dimensions(),
box.dimensions() *
box.axis( 2 ) } };
1092 const size_t num_def_test =
sizeof( default_tests ) /
sizeof( default_tests[0] );
1093 tests.insert( tests.begin(), &default_tests[0], &default_tests[0] + num_def_test );
1099 const size_t num_test = tests.size();
1100 for(
size_t i = 0; i < num_test; ++i )
1102 tests[i].direction.normalize();
1105 std::cout << ( 0 == i ?
"** Common tests\n" : ( num_def_test == i ?
"** File-specific tests\n" :
"" ) );
1106 std::cout <<
" " << tests[i].description <<
" " << tests[i].point <<
" " << tests[i].direction
1110 int rit_non_tol_count = 0;
1111 double rit_non_tol_dist = std::numeric_limits< double >::max();
1118 if( !haveSurfTree )
continue;
1120 int ris_non_tol_count = 0;
1121 double ris_non_tol_dist = std::numeric_limits< double >::max();
1128 if( !rit_non_tol_count && ris_non_tol_count )
1131 std::cout <<
" ray_intersect_sets returned intersection not found by "
1132 "ray_intersect_triangles"
1137 else if( rit_non_tol_count && !ris_non_tol_count )
1140 std::cout <<
" ray_intersect_sets missed intersection found by ray_intersect_triangles" << std::endl;
1144 else if( rit_non_tol_count && ris_non_tol_count && fabs( rit_non_tol_dist - ris_non_tol_dist ) >
tolerance )
1147 std::cout <<
" ray_intersect_sets and ray_intersect_triangles did not find same "
1148 "closest intersection"
1156 for(
size_t i = 0; i <
rays.size(); i += 2 )
1158 std::cout <<
rays[i] <<
"+" <<
rays[i + 1] <<
" : ";
1163 std::vector< double > intersections;
1164 std::vector< EntityHandle > intersection_facets;
1169 std::cout <<
"FAILED" << std::endl;
1177 std::stringstream s;
1184 std::vector< EntityHandle > sets( leaves.
size() );
1185 std::copy( leaves.
begin(), leaves.
end(), sets.begin() );
1187 if(
verbosity ) std::cout <<
"(Wrote " << name <<
") ";
1191 rays[i + 1].array(), 0 );
1194 std::cout <<
"FAILED" << std::endl;
1199 if( intersections.empty() )
1201 std::cout <<
"(none)" << std::endl;
1205 std::cout << intersections[0];
1206 for(
unsigned j = 1; j < intersections.size(); ++j )
1207 std::cout <<
", " << intersections[j];
1208 std::cout << std::endl;
1212 std::cout <<
" intersected boxes:";
1215 std::cout << std::endl;
1220 std::vector< double > intersections;
1221 std::vector< EntityHandle > surfaces;
1222 std::vector< EntityHandle > facets;
1227 rays[i + 1].array(), search_win, int_reg_ctxt, &stats );
1231 if(
verbosity ) std::cout <<
" Call to OrientedBoxTreeTool::ray_intersect_sets failed." << std::endl;
1239 std::stringstream s;
1247 if(
verbosity ) std::cout <<
"(Wrote " << name <<
") ";
1250 if( intersections.size() != surfaces.size() )
1252 std::cout <<
"Mismatched output lists." << std::endl;
1257 if( intersections.empty() )
1259 std::cout <<
"(none)" << std::endl;
1264 std::vector< int > ids( surfaces.size() );
1268 std::cout <<
"NO GLOBAL_ID TAG ON SURFACE." << std::endl;
1273 std::map< int, double > intmap;
1274 for(
unsigned j = 0; j < intersections.size(); ++j )
1275 intmap[ids[j]] = intersections[j];
1277 std::map< int, double >::iterator it = intmap.begin();
1278 int prevsurf = it->first;
1279 std::cout <<
"Surf" << it->first <<
" " << it->second;
1280 for( ++it; it != intmap.end(); ++it )
1283 if( it->first != prevsurf )
1285 prevsurf = it->first;
1286 std::cout <<
"Surf" << it->first <<
" ";
1288 std::cout << it->second;
1290 std::cout << std::endl;
1296 std::cout <<
"Traversal statistics for ray fire tests: " << std::endl;
1297 stats.
print( std::cout );
1312 rval = instance->
tag_set_data( tag, &root, 1, &tree_root );
1324 rval =
moab->get_connectivity( tri, conn, len,
true );
1326 if( len != 3 )
return MB_FAILURE;
1327 rval =
moab->get_coords( conn, 3, coords[0].array() );
1339 rval =
moab->get_entities_by_type( 0,
MBTRI, triangles );
1342 if( triangles.
empty() )
return MB_FAILURE;
1350 CartVect diff = to_pos - result_pos;
1351 double shortest_dist_sqr = diff % diff;
1353 for( ++i; i != triangles.
end(); ++i )
1359 diff = to_pos - pos;
1360 double dsqr = diff % diff;
1361 if( dsqr < shortest_dist_sqr )
1363 shortest_dist_sqr = dsqr;
1378 return i != tris.
end();
1383 if(
verbosity > 1 ) std::cout <<
"beginning closest point tests" << std::endl;
1396 if(
verbosity ) std::cerr <<
"Invalid tree in do_closest_point_test\n";
1403 CartVect points[] = {
box.center +
box.scaled_axis( 0 ),
box.center + 2 *
box.scaled_axis( 1 ),
1404 box.center + 0.5 *
box.scaled_axis( 2 ),
1405 box.center + -2 *
box.scaled_axis( 0 ) + -2 *
box.scaled_axis( 1 ) +
1406 -2 *
box.scaled_axis( 2 ),
1408 const int num_pts =
sizeof( points ) /
sizeof( points[0] );
1411 for(
int i = 0; i < num_pts; ++i )
1413 if(
verbosity >= 3 ) std::cout <<
"Evaluating closest point to " << points[i] << std::endl;
1422 std::cerr <<
"Internal MOAB error in do_closest_point_test" << std::endl;
1432 std::cout <<
"OrientedBoxTreeTool:: closest_to_location( " << points[i] <<
" ) FAILED!" << std::endl;
1437 CartVect diff = t_result - n_result;
1441 std::cout <<
"Closest point to " << points[i] <<
" INCORRECT! (" << t_result <<
" != " << n_result
1442 <<
")" << std::endl;
1447 if( t_tri != n_tri )
1459 diff1 = n_result - t_result;
1464 std::cout <<
"Triangle closest to " << points[i] <<
" INCORRECT! (" << t_tri <<
" != " << n_tri
1465 <<
")" << std::endl;
1473 if(
verbosity ) std::cout <<
"Surface closest to " << points[i] <<
" INCORRECT!" << std::endl;
1481 std::cout <<
"Traversal statistics for closest point tests: " << std::endl;
1482 stats.
print( std::cout );