41 #if defined( MB_OBB_USE_VECTOR_QUERIES ) && defined( MB_OBB_USE_TYPE_QUERIES )
42 #undef MB_OBB_USE_TYPE_QUERIES
65 const void* data_ptr = 0;
73 : max_leaf_entities( 8 ), max_depth( 0 ), worst_split_ratio( 0.95 ), best_split_ratio( 0.4 ),
80 return max_leaf_entities > 0 && max_depth >= 0 && worst_split_ratio <= 1.0 && best_split_ratio >= 0.0 &&
81 worst_split_ratio >= best_split_ratio;
118 if( settings && !settings->
valid() )
return MB_FAILURE;
126 if( settings && !settings->
valid() )
return MB_FAILURE;
129 std::list< SetData > data;
135 if( elements.
empty() )
continue;
138 SetData& set_data = data.back();
178 std::vector< CartVect > coords;
186 coords.resize( conn_len );
191 for(
int j = 0; j < conn_len; ++j )
192 centroid += coords[j];
193 centroid /= conn_len;
195 if( (
box.axis( axis ) % ( centroid -
box.center ) ) < 0.0 )
243 Range best_left_list, best_right_list;
245 for(
int axis = 2; best_ratio > settings.
best_split_ratio && axis >= 0; --axis )
247 Range left_list, right_list;
256 double ratio = fabs( (
double)right_list.
size() - left_list.
size() ) /
entities.size();
258 if( ratio < best_ratio )
261 best_left_list.
swap( left_list );
262 best_right_list.
swap( right_list );
267 if( !best_left_list.
empty() )
320 const std::list< OrientedBoxTreeTool::SetData >& sets,
321 std::list< OrientedBoxTreeTool::SetData >& left,
322 std::list< OrientedBoxTreeTool::SetData >& right )
327 std::list< OrientedBoxTreeTool::SetData >::const_iterator i;
328 for( i = sets.begin(); i != sets.end(); ++i )
330 CartVect centroid( i->box_data.center / i->box_data.area );
331 if( (
box.axis( axis ) % ( centroid -
box.center ) ) < 0.0 )
332 left.push_back( *i );
334 right.push_back( *i );
346 int count = sets.size();
347 if( 0 == count )
return MB_FAILURE;
355 std::vector< OrientedBox::CovarienceData > data( sets.size() );
357 for( std::list< SetData >::iterator i = sets.begin(); i != sets.end(); ++i )
359 data.push_back( i->box_data );
375 node_set = sets.front().handle;
390 double best_ratio = 2.0;
391 std::list< SetData > best_left_list, best_right_list;
392 for(
int axis = 0; axis < 2; ++axis )
394 std::list< SetData > left_list, right_list;
402 double ratio = fabs( (
double)right_list.size() - left_list.size() ) / sets.size();
404 if( ratio < best_ratio )
407 best_left_list.swap( left_list );
408 best_right_list.swap( right_list );
416 if( best_left_list.empty() || best_right_list.empty() )
418 best_left_list.clear();
419 best_right_list.clear();
420 std::list< SetData >* lists[2] = { &best_left_list, &best_right_list };
422 while( !sets.empty() )
424 lists[i]->push_back( sets.front() );
471 std::vector< EntityHandle >
children;
501 std::vector< EntityHandle >
children;
502 std::vector< Data > the_stack;
503 Data data = { set, 0 };
504 the_stack.push_back( data );
507 while( !the_stack.empty() )
509 data = the_stack.back();
510 the_stack.pop_back();
516 max_depth = std::max( max_depth, data.
depth );
524 if( !descend )
continue;
536 rval = operation.
leaf( data.
set );
544 the_stack.push_back( data );
546 the_stack.push_back( data );
573 std::vector< EntityHandle >& facets_out,
574 std::vector< EntityHandle >* sets_out,
577 const double radsqr = radius * radius;
585 #ifndef MB_OBB_USE_VECTOR_QUERIES
589 std::vector< EntityHandle > tris;
590 std::vector< EntityHandle >::const_iterator t;
593 std::vector< OBBTreeSITFrame > stack;
594 std::vector< EntityHandle >
children;
600 while( !stack.empty() )
604 int current_depth = stack.back().depth;
611 max_depth = std::max( max_depth, current_depth );
614 if( !surf && sets_out )
622 rval =
box( node, b );
626 if( ( closest % closest ) > radsqr )
continue;
645 #ifndef MB_OBB_USE_VECTOR_QUERIES
646 #ifdef MB_OBB_USE_TYPE_QUERIES
658 for( t = tris.
begin(); t != tris.
end(); ++t )
660 #ifndef MB_OBB_USE_VECTOR_QUERIES
662 #elif !defined( MB_OBB_USE_TYPE_QUERIES )
667 if( num_conn != 3 )
continue;
674 if( ( closest % closest ) <= radsqr &&
675 std::find( facets_out.begin(), facets_out.end(), *t ) == facets_out.end() )
677 facets_out.push_back( *t );
678 if( sets_out ) sets_out->push_back( surf );
704 const double* ray_point,
705 const double* unit_ray_dir,
706 const double* ray_length,
709 : tool( tool_ptr ), b( ray_point ), m( unit_ray_dir ), len( ray_length ), tol(
tolerance ), boxes( leaf_boxes )
730 std::vector< EntityHandle >& intersection_facets_out,
733 const double ray_point[3],
734 const double unit_ray_dir[3],
735 const double* ray_length,
736 unsigned int* raytri_test_count )
739 intersection_distances_out.clear();
740 #ifdef MB_OBB_USE_VECTOR_QUERIES
741 std::vector< EntityHandle > tris;
749 #ifndef MB_OBB_USE_VECTOR_QUERIES
751 #ifdef MB_OBB_USE_TYPE_QUERIES
763 #ifndef MB_OBB_USE_VECTOR_QUERIES
766 for( std::vector< EntityHandle >::iterator t = tris.
begin(); t != tris.
end(); ++t )
769 #ifndef MB_OBB_USE_TYPE_QUERIES
782 if( raytri_test_count ) *raytri_test_count += 1;
787 intersection_distances_out.push_back( td );
788 intersection_facets_out.push_back( *t );
797 std::vector< EntityHandle >& intersection_facets_out,
800 const double ray_point[3],
801 const double unit_ray_dir[3],
802 const double* ray_length,
818 const double ray_point[3],
819 const double unit_ray_dir[3],
820 const double* ray_length,
833 descend =
box.intersect_ray( b, m, tol, len );
839 boxes.insert( node );
850 std::vector< EntityHandle >& close_tris,
851 std::vector< int >& close_senses )
853 std::vector< EntityHandle > close_surfs;
859 close_senses.resize( close_surfs.size() );
860 for(
unsigned i = 0; i < close_surfs.size(); ++i )
866 if( vols[0] == vols[1] )
868 std::cerr <<
"error: surf has positive and negative sense wrt same volume" << std::endl;
871 if( *geomVol == vols[0] )
875 else if( *geomVol == vols[1] )
877 close_senses[i] = -1;
912 const double* ray_point,
913 const double* unit_ray_dir,
916 unsigned int* ray_tri_test_count,
918 : tool( tool_ptr ), ray_origin( ray_point ), ray_direction( unit_ray_dir ), search_win( win ), tol(
tolerance ),
919 int_reg_callback( intRegCallback ), surfTriOrient_val( 0 ), raytri_test_count( ray_tri_test_count ),
920 lastSet( 0 ), lastSetDepth( 0 )
927 surfTriOrient = &surfTriOrient_val;
931 surfTriOrient = NULL;
935 if( search_win.first )
937 assert( 0 <= *( search_win.first ) );
939 if( search_win.second )
941 assert( 0 >= *( search_win.second ) );
956 descend =
box.intersect_ray( ray_origin, ray_direction, tol, search_win.first, search_win.second );
958 if( lastSet && depth <= lastSetDepth ) lastSet = 0;
960 if( descend && !lastSet )
963 rval = tool->get_moab_instance()->get_entities_by_type( node,
MBENTITYSET, tmp_sets );
967 if( !tmp_sets.
empty() )
969 if( tmp_sets.
size() > 1 )
return MB_FAILURE;
970 lastSet = *tmp_sets.
begin();
971 lastSetDepth = depth;
973 rval = int_reg_callback.update_orient( lastSet, surfTriOrient );
987 #ifndef MB_OBB_USE_VECTOR_QUERIES
989 #ifdef MB_OBB_USE_TYPE_QUERIES
990 ErrorCode rval = tool->get_moab_instance()->get_entities_by_type( node,
MBTRI, tris );
992 ErrorCode rval = tool->get_moab_instance()->get_entities_by_handle( node, tris );
995 std::vector< EntityHandle > tris;
996 ErrorCode rval = tool->get_moab_instance()->get_entities_by_handle( node, tris );
1001 #ifndef MB_OBB_USE_VECTOR_QUERIES
1004 for( std::vector< EntityHandle >::iterator t = tris.
begin(); t != tris.
end(); ++t )
1007 #ifndef MB_OBB_USE_TYPE_QUERIES
1013 rval = tool->get_moab_instance()->get_connectivity( *t, conn, num_conn,
true );
1018 rval = tool->get_moab_instance()->get_coords( conn, 3, coords[0].array() );
1022 if( raytri_test_count ) *raytri_test_count += 1;
1028 search_win.second, surfTriOrient, &int_type ) )
1030 int_reg_callback.register_intersection( lastSet, *t, int_dist, search_win, int_type );
1037 std::vector< EntityHandle >& sets_out,
1038 std::vector< EntityHandle >& facets_out,
1041 const double ray_point[3],
1042 const double unit_ray_dir[3],
1053 sets_out = int_reg_callback.
get_sets();
1060 std::vector< EntityHandle >& sets_out,
1061 std::vector< EntityHandle >& facets_out,
1064 const double ray_point[3],
1065 const double unit_ray_dir[3],
1066 const double* ray_length,
1084 sets_out = int_reg_ctxt.
get_sets();
1092 const double ray_point[3],
1093 const double unit_ray_dir[3],
1109 : dist_sqr( d ), node( n ), mset( s ), depth( dp )
1127 double smallest_dist_sqr = std::numeric_limits< double >::max();
1131 std::vector< EntityHandle >
children( 2 );
1132 std::vector< double > coords;
1133 std::vector< OBBTreeCPFrame > stack;
1138 while( !stack.empty() )
1143 double dist_sqr = stack.back().dist_sqr;
1144 current_set = stack.back().mset;
1145 int current_depth = stack.back().depth;
1149 if( dist_sqr > smallest_dist_sqr )
continue;
1155 max_depth = std::max( max_depth, current_depth );
1159 if( set_out && !current_set )
1167 current_set = sets.
front();
1194 const double dsqr1 = pt1 % pt1;
1195 const double dsqr2 = pt2 % pt2;
1228 coords.resize( 3 * len );
1238 dist_sqr = diff % diff;
1239 if( dist_sqr < smallest_dist_sqr )
1241 smallest_dist_sqr = dist_sqr;
1243 tmp.
get( point_out );
1244 if( set_out ) *set_out = current_set;
1261 std::vector< EntityHandle >& facets_out,
1262 std::vector< EntityHandle >* sets_out,
1267 double smallest_dist_sqr = std::numeric_limits< double >::max();
1268 double smallest_dist = smallest_dist_sqr;
1272 std::vector< EntityHandle >
children( 2 );
1273 std::vector< double > coords;
1274 std::vector< OBBTreeCPFrame > stack;
1279 while( !stack.empty() )
1284 double dist_sqr = stack.back().dist_sqr;
1285 current_set = stack.back().mset;
1286 int current_depth = stack.back().depth;
1290 if( dist_sqr > smallest_dist_sqr +
tolerance )
continue;
1296 max_depth = std::max( max_depth, current_depth );
1300 if( sets_out && !current_set )
1308 current_set = *sets.
begin();
1335 const double dsqr1 = pt1 % pt1;
1336 const double dsqr2 = pt2 % pt2;
1369 coords.resize( 3 * len );
1379 dist_sqr = diff % diff;
1380 if( dist_sqr < smallest_dist_sqr )
1382 if( 0.5 * dist_sqr < 0.5 * smallest_dist_sqr +
tolerance * ( 0.5 *
tolerance - smallest_dist ) )
1385 if( sets_out ) sets_out->clear();
1387 smallest_dist_sqr = dist_sqr;
1388 smallest_dist = sqrt( smallest_dist_sqr );
1390 facets_out.push_back( *i );
1391 std::swap( facets_out.front(), facets_out.back() );
1394 sets_out->push_back( current_set );
1395 std::swap( sets_out->front(), sets_out->back() );
1398 else if( dist_sqr <= smallest_dist_sqr +
tolerance * (
tolerance + 2 * smallest_dist ) )
1400 facets_out.push_back( *i );
1401 if( sets_out ) sets_out->push_back( current_set );
1432 :
instance( interface ), outputStream( stream )
1440 if( (
unsigned)depth >
path.size() )
1443 path.push_back(
true );
1447 path.resize( depth );
1448 if( depth )
path.back() =
false;
1451 for(
unsigned i = 0; i + 1 <
path.size(); ++i )
1480 const char* id_tag_name,
1507 const char* id_tag_name,
1509 : printContents( list_contents ), printGeometry( list_box ), haveTag( false ), tag( 0 ), gidTag( 0 ),
geomTag( 0 ),
1510 instance( tool_ptr->get_moab_instance() ), tool( tool_ptr ), outputStream( stream )
1518 std::cerr <<
"Could not get tag \"" << id_tag_name <<
"\"\n";
1519 stream <<
"Could not get tag \"" << id_tag_name <<
"\"\n";
1544 const void* tagdata[] = { &two };
1554 outputStream <<
" Surface w/ unknown ID (" << surf <<
")" << std::endl;
1579 <<
'+' << box.
axis( 0 ) <<
" : " <<
length[0] << std::endl
1580 <<
'x' << box.
axis( 1 ) <<
" : " <<
length[1] << std::endl
1581 <<
'x' << box.
axis( 2 ) <<
" : " <<
length[2] << std::endl;
1605 if( range.
empty() )
continue;
1607 std::vector< int > ids( range.
size() );
1611 std::sort( ids.begin(), ids.end() );
1616 std::vector< int >::iterator vi = ids.begin();
1617 while( ri != range.
end() )
1628 unsigned beg = i, end;
1632 }
while( i < ids.size() && ids[end] + 1 == ids[i] );
1635 else if( end == beg + 1 )
1640 if( i == ids.size() )
1662 std::cerr <<
"Errors encountered while printing tree\n";
1663 str <<
"Errors encountered while printing tree\n";
1680 while( nodes_visited_count.size() <= depth )
1682 nodes_visited_count.push_back( 0 );
1683 leaves_visited_count.push_back( 0 );
1684 traversals_ended_count.push_back( 0 );
1686 nodes_visited_count[depth] += 1;
1692 leaves_visited_count[depth] += 1;
1699 traversals_ended_count[depth] += 1;
1705 const std::string h1 =
"OBBTree Depth";
1706 const std::string h2 =
" - NodesVisited";
1707 const std::string h3 =
" - LeavesVisited";
1708 const std::string h4 =
" - TraversalsEnded";
1710 str << h1 << h2 << h3 << h4 << std::endl;
1712 unsigned num_visited = 0, num_leaves = 0, num_traversals = 0;
1713 for(
unsigned i = 0; i < traversals_ended_count.size(); ++i )
1716 num_visited += nodes_visited_count[i];
1717 num_leaves += leaves_visited_count[i];
1718 num_traversals += traversals_ended_count[i];
1720 str << std::setw( h1.length() ) << i << std::setw( h2.length() ) << nodes_visited_count[i]
1721 << std::setw( h3.length() ) << leaves_visited_count[i] << std::setw( h4.length() )
1722 << traversals_ended_count[i] << std::endl;
1725 str << std::setw( h1.length() ) <<
"---- Totals:" << std::setw( h2.length() ) << num_visited
1726 << std::setw( h3.length() ) << num_leaves << std::setw( h4.length() ) << num_traversals << std::endl;
1728 if( ray_tri_tests_count )
1730 str << std::setw( h1.length() ) <<
"---- Total ray-tri tests: " << ray_tri_tests_count << std::endl;
1744 : min( std::numeric_limits< double >::max() ), max( -std::numeric_limits< double >::max() ),
sum( 0.0 ),
1747 hist[0] = hist[1] = hist[2] = hist[3] = hist[4] = hist[5] = hist[6] = hist[7] = hist[8] = hist[9] = 0;
1751 if( v < min ) min = v;
1752 if( v > max ) max = v;
1755 int i = (int)( 10 * v );
1764 template <
typename T >
1771 std::numeric_limits< T > lim;
1773 if( lim.is_integer )
1780 if( v < min ) min = v;
1781 if( v > max ) max = v;
1783 sqr += (double)v * v;
1801 const double tol = 1e-6;
1804 for(
int i = 0; i < 3; ++i )
1818 unsigned& count_out,
1823 std::vector< EntityHandle >
children( 2 );
1829 rval = tool->
box( set, tmp_box );
1855 for(
int i = 0; i < 2; ++i )
1860 double this_measure, chld_measure;
1861 int this_dim =
measure( dimensions_out, this_measure );
1862 int chld_dim =
measure( dims, chld_measure );
1864 if( chld_dim < this_dim )
1867 ratio = chld_measure / this_measure;
1871 count_out = counts[0] + counts[1];
1878 static inline double std_dev(
double sqr,
double sum,
double count )
1882 return sqrt( sqr -
sum *
sum );
1886 #define WE << std::setw( 10 ) <<
1889 unsigned& total_entities,
1891 double& tot_node_volume,
1892 double& tot_to_root_volume,
1893 unsigned& tree_height,
1894 unsigned& node_count,
1895 unsigned& num_leaves )
1906 unsigned min_leaf_depth = tree_height;
1908 unsigned max_leaf_per_depth = 0;
1916 if( val && i < min_leaf_depth ) min_leaf_depth = i;
1917 if( max_leaf_per_depth < val ) max_leaf_per_depth = val;
1919 rv = total_dim[0] * total_dim[1] * total_dim[2];
1920 tot_node_volume = d.
vol.
sum;
1921 tot_to_root_volume = d.
vol.
sum / rv;
1922 node_count = d.
count;
1931 unsigned total_entities, i;
1938 unsigned min_leaf_depth = tree_height, num_leaves = 0;
1939 unsigned max_leaf_per_depth = 0;
1940 double sum_leaf_depth = 0, sqr_leaf_depth = 0;
1945 sum_leaf_depth += (double)val * i;
1946 sqr_leaf_depth += (double)val * i * i;
1947 if( val && i < min_leaf_depth ) min_leaf_depth = i;
1948 if( max_leaf_per_depth < val ) max_leaf_per_depth = val;
1950 unsigned num_non_leaf = d.
count - num_leaves;
1952 double rv = total_dim[0] * total_dim[1] * total_dim[2];
1953 s <<
"entities in tree: " << total_entities << std::endl
1954 <<
"root volume: " << rv << std::endl
1955 <<
"total node volume: " << d.
vol.
sum << std::endl
1956 <<
"total/root volume: " << d.
vol.
sum / rv << std::endl
1957 <<
"tree height: " << tree_height << std::endl
1958 <<
"node count: " << d.
count << std::endl
1959 <<
"leaf count: " << num_leaves << std::endl
1962 double avg_leaf_depth = sum_leaf_depth / num_leaves;
1963 double rms_leaf_depth = sqrt( sqr_leaf_depth / num_leaves );
1964 double std_leaf_depth =
std_dev( sqr_leaf_depth, sum_leaf_depth, num_leaves );
1966 double avg_leaf_ent = d.
leaf_ent.
sum / num_leaves;
1967 double rms_leaf_ent = sqrt( d.
leaf_ent.
sqr / num_leaves );
1970 unsigned num_child = 2 * num_non_leaf;
1972 double avg_vol_ratio = d.
volume.
sum / num_child;
1973 double rms_vol_ratio = sqrt( d.
volume.
sqr / num_child );
1976 double avg_ent_ratio = d.
entities.
sum / num_child;
1977 double rms_ent_ratio = sqrt( d.
entities.
sqr / num_child );
1992 int prec = s.precision();
1993 s <<
" " WW "Minimum" WW "Average" WW "RMS" WW "Maximum" WW "Std.Dev." << std::endl;
1994 s << std::setprecision( 1 )
1995 <<
"Leaf Depth " WW min_leaf_depth
WW avg_leaf_depth
WW rms_leaf_depth
WW d.
leaf_depth.size() -
1998 s << std::setprecision( 0 )
2001 s << std::setprecision( 3 )
2004 s << std::setprecision( 3 )
2007 s << std::setprecision( 3 )
2012 s << std::setprecision( 0 ) <<
"Largest side area " WE d.
area.
min WE avg_area
WE rms_area
WE d.
area.
max WE std_area
2014 s << std::setprecision( prec ) << std::endl;
2016 s <<
"Leaf Depth Histogram (Root depth is 0)" << std::endl;
2017 double f = 60.0 / max_leaf_per_depth;
2018 for( i = min_leaf_depth; i < d.
leaf_depth.size(); ++i )
2019 s << std::setw( 2 ) << i <<
" " << std::setw( 5 ) << d.
leaf_depth[i] <<
" |" << std::setfill(
'*' )
2020 << std::setw( (
int)floor( f * d.
leaf_depth[i] + 0.5 ) ) <<
"" << std::setfill(
' ' ) << std::endl;
2023 s <<
"Child/Parent Volume Ratio Histogram" << std::endl;
2025 for( i = 0; i < 10u; ++i )
2026 s <<
"0." << i <<
" " << std::setw( 5 ) << d.
volume.
hist[i] <<
" |" << std::setfill(
'*' )
2027 << std::setw( (
int)floor( f * d.
volume.
hist[i] + 0.5 ) ) <<
"" << std::setfill(
' ' ) << std::endl;
2030 s <<
"Child/Parent Entity Count Ratio Histogram" << std::endl;
2032 for( i = 0; i < 10u; ++i )
2033 s <<
"0." << i <<
" " << std::setw( 5 ) << d.
entities.
hist[i] <<
" |" << std::setfill(
'*' )
2034 << std::setw( (
int)floor( f * d.
entities.
hist[i] + 0.5 ) ) <<
"" << std::setfill(
' ' ) << std::endl;
2037 s <<
"Inner/Outer Radius Ratio Histogram (~0.70 for cube)" << std::endl;
2042 for( i = 0; i < 7u; ++i )
2043 s <<
"0." << i <<
" " << std::setw( 5 ) << d.
entities.
hist[i] <<
" |" << std::setfill(
'*' )
2044 << std::setw( (
int)floor( f * d.
entities.
hist[i] + 0.5 ) ) <<
"" << std::setfill(
' ' ) << std::endl;