25 #define MB_AD_KD_TREE_DEFAULT_TAG_NAME
28 #define MB_AD_KD_TREE_USE_SINGLE_TAG
34 #define MB_AD_KD_TREE_USE_TWO_DOUBLE_TAG
37 :
Tree(
iface ), planeTag( 0 ), axisTag( 0 ), splitsPerDir( 3 ), planeSet( SUBDIVISION_SNAP ), spherical( false ),
47 const Range& entities,
50 :
Tree(
iface ), planeTag( 0 ), axisTag( 0 ), splitsPerDir( 3 ), planeSet( SUBDIVISION_SNAP ), spherical( false ),
65 rval =
build_tree( entities, tree_root_set, opts );
90 if( !options->
all_seen() )
return MB_FAILURE;
100 if( !tree_root_set ) tree_root_set = &tmp_root;
109 std::vector< double > tmp_data;
110 std::vector< EntityHandle > tmp_data2;
118 const size_t p_count = pcount;
119 Range best_left, best_right, best_both;
120 Plane best_plane = { HUGE_VAL, -1 };
148 if( best_plane.
norm >= 0 )
150 best_left.
merge( best_both );
151 best_right.
merge( best_both );
152 rval =
split_leaf( iter, best_plane, best_left, best_right );
216 std::vector< Tag >& created_tags )
219 iface->tag_get_handle( name.c_str(), count, type, tag_handle,
MB_TAG_CREAT | storage, default_val );
223 if( std::find( created_tags.begin(), created_tags.end(), tag_handle ) == created_tags.end() )
224 created_tags.push_back( tag_handle );
228 while( !created_tags.empty() )
230 iface->tag_delete( created_tags.back() );
231 created_tags.pop_back();
242 std::vector< Tag > ctl;
244 #ifndef MB_AD_KD_TREE_USE_SINGLE_TAG
254 #elif defined( MB_AD_KD_TREE_USE_TWO_DOUBLE_TAG )
256 std::string double_tag_name = std::string(
treeName ) + std::string(
"_coord_norm" );
264 #ifdef MOAB_HAVE_HDF5
267 std::string type_tag_name =
"__hdf5_tag_type_";
273 hid_t handle = H5Tcreate( H5T_COMPOUND,
sizeof(
Plane ) );
274 H5Tinsert( handle,
"coord", &( p.
coord ) - &p, H5T_NATIVE_DOUBLE );
275 H5Tinsert( handle,
"norm", &( p.axis ) - &p, H5T_NATIVE_INT );
287 #ifndef MB_AD_KD_TREE_USE_SINGLE_TAG
292 #elif defined( MB_AD_KD_TREE_USE_TWO_DOUBLE_TAG )
295 plane.
coord = values[0];
296 plane.
norm = (int)values[1];
305 #ifndef MB_AD_KD_TREE_USE_SINGLE_TAG
310 #elif defined( MB_AD_KD_TREE_USE_TWO_DOUBLE_TAG )
311 double values[2] = { plane.
coord,
static_cast< double >( plane.
norm ) };
374 return split_leaf( leaf, plane, left, right );
379 const Range& left_entities,
380 const Range& right_entities )
400 const std::vector< EntityHandle >& left_entities,
401 const std::vector< EntityHandle >& right_entities )
407 if(
MB_SUCCESS ==
moab()->add_entities( left, &left_entities[0], left_entities.size() ) &&
408 MB_SUCCESS ==
moab()->add_entities( right, &right_entities[0], right_entities.size() ) &&
422 if( iter.
depth() == 1 )
445 std::vector< EntityHandle > stack( iter.
childVect );
448 while( !stack.empty() )
477 const double bmin[3],
478 const double bmax[3],
530 if(
mStack.empty() )
return MB_FAILURE;
580 std::vector< AdaptiveKDTreeIter >& results,
581 double epsilon )
const
591 node = iter.
mStack.back();
599 parent = iter.
mStack.back();
611 if( plane.
norm == norm && (
int)neg == child_idx )
618 iter.
mStack.push_back( node );
631 std::vector< AdaptiveKDTreeIter > list;
637 node = iter.
mStack.back();
647 results.push_back( iter );
655 if( plane.
norm == norm )
660 iter.
mStack.push_back( node );
669 list.push_back( iter );
676 iter.
mStack.push_back( node );
684 assert( plane.
coord - this->mBox[
BMAX][plane.
norm] <= epsilon );
688 iter.
mStack.push_back( node );
693 if( list.empty() )
break;
733 const size_t s =
mStack.size();
734 return ( s > 1 ) && ( s == other_leaf.
mStack.size() ) &&
740 if(
mStack.size() < 2 || other_leaf ==
handle() )
return false;
768 const double ray_vect[3],
770 double& t_exit )
const
774 CartVect( ray_vect ), t_enter, t_exit );
785 double& metric_value )
802 const double max_tol = std::max( dim[0], std::max( dim[1], dim[2] ) ) / 10;
818 for( i = elems.
begin(); i != elem_begin; ++i )
824 bool lo =
false, ro =
false;
825 if( coords[0][plane.
norm] <= plane.
coord ) lo =
true;
826 if( coords[0][plane.
norm] >= plane.
coord ) ro =
true;
829 both_ins = both_tris.
insert( both_ins, *i, *i );
831 left_ins = left_tris.
insert( left_ins, *i, *i );
833 right_ins = right_tris.
insert( right_ins, *i, *i );
837 std::vector< EntityHandle > dum_vector;
838 for( i = elem_begin; i != poly_begin; ++i )
843 if( count > (
int)(
sizeof( coords ) /
sizeof( coords[0] ) ) )
return MB_FAILURE;
847 bool lo =
false, ro =
false;
848 for(
int j = 0; j < count; ++j )
850 if( coords[j][plane.
norm] <= plane.
coord ) lo =
true;
851 if( coords[j][plane.
norm] >= plane.
coord ) ro =
true;
864 while( !lo && !ro && tol <= max_tol )
876 both_ins = both_tris.
insert( both_ins, *i, *i );
878 left_ins = left_tris.
insert( left_ins, *i, *i );
880 right_ins = right_tris.
insert( right_ins, *i, *i );
884 for( i = poly_begin; i != set_begin; ++i )
891 bool lo =
false, ro =
false;
892 for(
int j = 0; j < count; ++j )
897 for(
int k = 0; k < count2; ++k )
901 if( coords[0][plane.
norm] <= plane.
coord ) lo =
true;
902 if( coords[0][plane.
norm] >= plane.
coord ) ro =
true;
907 both_ins = both_tris.
insert( both_ins, *i, *i );
909 left_ins = left_tris.
insert( left_ins, *i, *i );
911 right_ins = right_tris.
insert( right_ins, *i, *i );
916 for( i = set_begin; i != elems.
end(); ++i )
922 bool lo =
false, ro =
false;
927 both_ins = both_tris.
insert( both_ins, *i, *i );
929 left_ins = left_tris.
insert( left_ins, *i, *i );
931 right_ins = right_tris.
insert( right_ins, *i, *i );
935 double area_left = left_dim[0] * left_dim[1] + left_dim[1] * left_dim[2] + left_dim[2] * left_dim[0];
936 double area_right = right_dim[0] * right_dim[1] + right_dim[1] * right_dim[2] + right_dim[2] * right_dim[0];
937 double area_both = box_dim[0] * box_dim[1] + box_dim[1] * box_dim[2] + box_dim[2] * box_dim[0];
938 metric_value = ( area_left * left_tris.
size() + area_right * right_tris.
size() ) / area_both + both_tris.
size();
950 double metric_val = std::numeric_limits< unsigned >::max();
960 const size_t p_count = entities.
size();
962 for(
int axis = 0; axis < 3; ++axis )
964 int plane_count = num_planes;
965 if( ( num_planes + 1 ) * eps >= diff[axis] ) plane_count = (int)( diff[axis] / eps ) - 1;
967 for(
int p = 1; p <= plane_count; ++p )
970 Range left, right, both;
974 const size_t sdiff = p_count - both.
size();
975 if( left.
size() == sdiff || right.
size() == sdiff )
continue;
977 if( val >= metric_val )
continue;
981 best_left.
swap( left );
982 best_right.
swap( right );
983 best_both.
swap( both );
996 std::vector< double >& tmp_data,
999 double metric_val = std::numeric_limits< unsigned >::max();
1004 Range entities, vertices;
1007 const size_t p_count = entities.
size();
1011 unsigned int nverts = vertices.
size();
1012 tmp_data.resize( 3 * nverts );
1013 r = iter.
tool()->
moab()->
get_coords( vertices, &tmp_data[0], &tmp_data[nverts], &tmp_data[2 * nverts] );
1024 for(
int dir = 0; dir < 3; dir++ )
1026 double amin = tmp_data[dir * nverts];
1028 double* p = &tmp_data[dir * nverts + 1];
1029 for(
unsigned int i = 1; i < nverts; i++ )
1031 if( *p < amin ) amin = *p;
1032 if( *p > amax ) amax = *p;
1040 for(
int axis = 0; axis < 3; ++axis )
1042 int plane_count = num_planes;
1045 if( eps > 0.0 && std::isfinite(diff[axis]) && ( num_planes + 1 ) * eps >= diff[axis] )
1046 plane_count = (int)( diff[axis] / eps ) - 1;
1048 for(
int p = 1; p <= plane_count; ++p )
1052 double coord =
box_min[axis] + ( p / ( 1.0 + plane_count ) ) * diff[axis];
1055 unsigned int istrt = axis * nverts;
1056 double closest_coord = tmp_data[istrt];
1057 for(
unsigned i = 1; i < nverts; ++i )
1058 if( fabs( coord - tmp_data[istrt + i] ) < fabs( coord - closest_coord ) )
1059 closest_coord = tmp_data[istrt + i];
1060 if( closest_coord -
box_min[axis] <= eps ||
box_max[axis] - closest_coord <= eps )
continue;
1064 Range left, right, both;
1068 const size_t d = p_count - both.
size();
1069 if( left.
size() == d || right.
size() == d )
continue;
1071 if( val >= metric_val )
continue;
1075 best_left.
swap( left );
1076 best_right.
swap( right );
1077 best_both.
swap( both );
1090 std::vector< double >& coords,
1093 double metric_val = std::numeric_limits< unsigned >::max();
1099 Range entities, vertices;
1102 const size_t p_count = entities.
size();
1106 coords.resize( vertices.
size() );
1107 for(
int axis = 0; axis < 3; ++axis )
1111 double* ptrs[] = { 0, 0, 0 };
1112 ptrs[axis] = &coords[0];
1116 std::sort( coords.begin(), coords.end() );
1117 std::vector< double >::iterator citer;
1118 citer = std::upper_bound( coords.begin(), coords.end(),
box_min[axis] + eps );
1119 const size_t count = std::upper_bound( citer, coords.end(),
box_max[axis] - eps ) - citer;
1121 int np = num_planes;
1122 if( count < 2 * (
size_t)num_planes )
1129 step = count / ( num_planes + 1 );
1132 for(
int p = 1; p <= np; ++p )
1137 Range left, right, both;
1141 const size_t diff = p_count - both.
size();
1142 if( left.
size() == diff || right.
size() == diff )
continue;
1144 if( val >= metric_val )
continue;
1148 best_left.
swap( left );
1149 best_right.
swap( right );
1150 best_both.
swap( both );
1163 std::vector< double >& coords,
1164 std::vector< EntityHandle >& indices,
1167 const size_t random_elem_threshold = 20 * num_planes;
1168 double metric_val = std::numeric_limits< unsigned >::max();
1174 Range entities, vertices;
1180 const size_t p_count = entities.
size();
1181 coords.resize( 3 * num_planes );
1182 if( p_count < random_elem_threshold )
1189 indices.resize( random_elem_threshold );
1190 const int num_rand = p_count / RAND_MAX + 1;
1191 for(
size_t j = 0; j < random_elem_threshold; ++j )
1193 size_t rnd = rand();
1194 for(
int i = num_rand; i > 1; --i )
1197 indices[j] = entities[rnd];
1204 coords.resize( vertices.
size() );
1205 for(
int axis = 0; axis < 3; ++axis )
1209 double* ptrs[] = { 0, 0, 0 };
1210 ptrs[axis] = &coords[0];
1214 size_t num_valid_coords = 0;
1215 for(
size_t i = 0; i < coords.size(); ++i )
1216 if( coords[i] >
box_min[axis] + eps && coords[i] <
box_max[axis] - eps ) ++num_valid_coords;
1218 if( 2 * (
size_t)num_planes > num_valid_coords )
1221 for(
size_t i = 0; i < coords.size(); ++i )
1222 if( coords[i] >
box_min[axis] + eps && coords[i] <
box_max[axis] - eps ) indices.push_back( i );
1226 indices.resize( num_planes );
1228 const int num_rand = coords.size() / RAND_MAX + 1;
1229 for(
int j = 0; j < num_planes; ++j )
1235 for(
int i = num_rand; i > 1; --i )
1237 rnd %= coords.size();
1238 }
while( coords[rnd] <=
box_min[axis] + eps || coords[rnd] >=
box_max[axis] - eps );
1243 for(
unsigned p = 0; p < indices.size(); ++p )
1247 Range left, right, both;
1251 const size_t diff = p_count - both.
size();
1252 if( left.
size() == diff || right.
size() == diff )
continue;
1254 if( val >= metric_val )
continue;
1258 best_left.
swap( left );
1259 best_right.
swap( right );
1260 best_both.
swap( both );
1269 const double iter_tol,
1270 const double inside_tol,
1271 bool* multiple_leaves,
1275 std::vector< EntityHandle > children;
1282 if( multiple_leaves ) *multiple_leaves =
false;
1294 while( !children.empty() )
1301 const double d = point[plane.
norm] - plane.
coord;
1302 node = children[( d > 0.0 )];
1324 const double iter_tol,
1326 bool* multiple_leaves,
1333 if( multiple_leaves ) *multiple_leaves =
false;
1374 const int idx = ( point[plane.
norm] > plane.
coord );
1375 leaf_it.
mStack.push_back(
1390 const double distance,
1391 std::vector< EntityHandle >& result_list,
1392 const double iter_tol,
1393 const double inside_tol,
1394 std::vector< double >* result_dists,
1395 std::vector< CartVect >* result_params,
1399 const double dist_sqr = distance * distance;
1401 std::vector< NodeDistance > list,
1410 std::vector< EntityHandle > children;
1427 for(
int i = 0; i < 3; ++i )
1429 if( from_point[i] < box.
bMin[i] )
1430 node.
dist[i] = box.
bMin[i] - from_point[i];
1431 else if( from_point[i] > box.
bMax[i] )
1432 node.
dist[i] = from_point[i] - box.
bMax[i];
1434 if( node.
dist % node.
dist > dist_sqr )
1443 list.push_back( node );
1445 while( !list.empty() )
1455 if( children.empty() )
1458 if(
myEval && result_params )
1468 result_list.push_back( ent );
1469 result_params->push_back(
params );
1470 if( result_dists ) result_dists->push_back( 0.0 );
1475 result_list_nodes.push_back( node );
1484 const double d = from[plane.
norm] - plane.
coord;
1489 node.
handle = children[1];
1490 list.push_back( node );
1497 if( node.
dist % node.
dist <= dist_sqr )
1499 node.
handle = children[0];
1500 list.push_back( node );
1507 node.
handle = children[0];
1508 list.push_back( node );
1512 if( -d <= distance )
1515 if( node.
dist % node.
dist <= dist_sqr )
1517 node.
handle = children[1];
1518 list.push_back( node );
1528 result_list.reserve( result_list_nodes.size() );
1529 for( std::vector< NodeDistance >::iterator vit = result_list_nodes.begin(); vit != result_list_nodes.end(); ++vit )
1530 result_list.push_back( ( *vit ).handle );
1532 if( result_dists && distance > 0.0 )
1534 result_dists->reserve( result_list_nodes.size() );
1535 for( std::vector< NodeDistance >::iterator vit = result_list_nodes.begin(); vit != result_list_nodes.end();
1537 result_dists->push_back( ( *vit ).dist.length() );
1546 double& shortest_dist_sqr,
1557 rval =
moab->get_connectivity( *i, conn, len );
1560 rval =
moab->get_coords( conn, 3, verts[0].array() );
1565 double dist_sqr = diff % diff;
1566 if( dist_sqr < shortest_dist_sqr )
1569 shortest_dist_sqr = dist_sqr;
1581 double& shortest_dist_sqr,
1588 rval =
moab->get_entities_by_type( set_handle,
MBTRI, tris );
1595 const double from[3],
1602 std::vector< EntityHandle > stack;
1603 std::vector< EntityHandle > children( 2 );
1604 stack.reserve( 30 );
1606 stack.push_back( root );
1608 while( !stack.empty() )
1621 if( children.empty() )
break;
1630 int rs =
split.right_side( from );
1631 node = children[rs];
1632 stack.push_back( children[1 - rs] );
1642 double dist_sqr = HUGE_VAL;
1765 const double from_coords[3],
1766 double closest_point_out[3],
1770 double shortest_dist_sqr = HUGE_VAL;
1771 std::vector< EntityHandle > leaves;
1772 const CartVect from( from_coords );
1778 assert( tree_root );
1786 rval =
distance_search( from_coords, sqrt( diff % diff ), leaves, 1.0e-10, 1.0e-6, NULL, NULL, &tree_root );
1791 for(
unsigned i = 0; i < leaves.size(); ++i )
1798 closest_pt.
get( closest_point_out );
1805 std::vector< EntityHandle >& triangles )
1808 std::vector< EntityHandle > leaves;
1816 assert( tree_root );
1821 for(
unsigned i = 0; i < leaves.size(); ++i )
1835 if( ( closest_pt % closest_pt ) <= ( rad * rad ) ) triangles.push_back( *j );
1840 std::sort( triangles.begin(), triangles.end() );
1841 triangles.erase( std::unique( triangles.begin(), triangles.end() ), triangles.end() );
1854 const double ray_dir_in[3],
1855 const double ray_pt_in[3],
1856 std::vector< EntityHandle >& tris_out,
1857 std::vector< double >& dists_out,
1862 double ray_beg = 0.0;
1863 if( ray_end < 0.0 ) ray_end = HUGE_VAL;
1868 const CartVect ray_pt( ray_pt_in ), ray_dir( ray_dir_in );
1884 std::vector< EntityHandle > children;
1885 std::vector< NodeSeg > list;
1886 NodeSeg seg( root, ray_beg, ray_end );
1887 list.push_back( seg );
1889 while( !list.empty() )
1898 if( seg.
beg > ray_end )
continue;
1904 if( children.empty() )
1911 for( iter = tris.
begin(); iter != tris.
end(); ++iter )
1922 if( std::find( tris_out.begin(), tris_out.end(), *iter ) == tris_out.end() )
1924 tris_out.push_back( *iter );
1925 dists_out.push_back( tri_t );
1928 else if( tri_t < ray_end )
1930 if( std::find( tris_out.begin(), tris_out.end(), *iter ) == tris_out.end() )
1932 if( tris_out.size() < (
unsigned)max_ints )
1934 tris_out.resize( tris_out.size() + 1 );
1935 dists_out.resize( dists_out.size() + 1 );
1937 int w = tris_out.size() - 1;
1938 for( ; w > 0 && tri_t < dists_out[w - 1]; --w )
1940 tris_out[w] = tris_out[w - 1];
1941 dists_out[w] = dists_out[w - 1];
1943 tris_out[w] = *iter;
1944 dists_out[w] = tri_t;
1945 if( tris_out.size() >= (
unsigned)max_ints )
1949 ray_end = dists_out.back();
1965 const double inv_dir = 1.0 / ray_dir[plane.
norm];
1966 const double t = ( plane.
coord - ray_pt[plane.
norm] ) * inv_dir;
1967 const double diff = tol * inv_dir;
1977 const int fwd_child = ( ray_dir[plane.
norm] > 0.0 );
1984 if( ray_pt[plane.
norm] - tol <= plane.
coord ) list.push_back(
NodeSeg( children[0], seg.
beg, seg.
end ) );
1985 if( ray_pt[plane.
norm] + tol >= plane.
coord ) list.push_back(
NodeSeg( children[1], seg.
beg, seg.
end ) );
1989 else if( seg.
end + diff < t )
1995 list.push_back(
NodeSeg( children[1 - fwd_child], seg.
beg, seg.
end ) );
2000 else if( seg.
beg - diff > t )
2006 list.push_back(
NodeSeg( children[fwd_child], seg.
beg, seg.
end ) );
2012 else if( t <= seg.
beg )
2014 list.push_back(
NodeSeg( children[1 - fwd_child], seg.
beg, seg.
beg ) );
2015 list.push_back(
NodeSeg( children[fwd_child], seg.
beg, seg.
end ) );
2017 else if( t >= seg.
end )
2019 list.push_back(
NodeSeg( children[1 - fwd_child], seg.
beg, seg.
end ) );
2020 list.push_back(
NodeSeg( children[fwd_child], seg.
end, seg.
end ) );
2024 list.push_back(
NodeSeg( children[1 - fwd_child], seg.
beg, t ) );
2025 list.push_back(
NodeSeg( children[fwd_child], t, seg.
end ) );
2037 min_depth = max_depth = iter.
depth();
2039 int num_of_elements = 0, max, min;
2041 max = min = num_of_elements;
2046 max = std::max( max, temp );
2047 min = std::min( min, temp );
2048 if( iter.
depth() > max_depth )
2049 max_depth = iter.
depth();
2050 else if( iter.
depth() < min_depth )
2051 min_depth = iter.
depth();
2071 if( mem > 9 * 1024 )
2073 mem = ( mem + 512 ) / 1024;
2074 strcpy(
unit,
"kB" );
2076 if( mem > 9 * 1024 )
2078 mem = ( mem + 512 ) / 1024;
2079 strcpy(
unit,
"MB" );
2081 if( mem > 9 * 1024 )
2083 mem = ( mem + 512 ) / 1024;
2084 strcpy(
unit,
"GB" );
2087 snprintf(
buffer, 256,
"%lu %s", mem,
unit );
2091 template <
typename T >
2097 void add( T value );
2104 return sqrt( (
double)
sqr /
count );
2114 template <
typename T >
2116 : min( std::numeric_limits< T >::max() ), max( std::numeric_limits< T >::min() ),
sum( 0 ), sqr( 0 ), count( 0 )
2120 template <
typename T >
2123 if( value < min ) min = value;
2124 if( value > max ) max = value;
2126 sqr += value * value;
2134 Range tree_sets, elem2d, elem3d, verts, all;
2138 std::vector< EntityHandle > elem2d_vec, elem3d_vec, verts_vec;
2145 std::sort( elem2d_vec.begin(), elem2d_vec.end() );
2146 std::copy( elem2d_vec.rbegin(), elem2d_vec.rend(),
range_inserter( elem2d ) );
2147 std::sort( elem3d_vec.begin(), elem3d_vec.end() );
2148 std::copy( elem3d_vec.rbegin(), elem3d_vec.rend(),
range_inserter( elem3d ) );
2149 std::sort( verts_vec.begin(), verts_vec.end() );
2150 std::copy( verts_vec.rbegin(), verts_vec.rend(),
range_inserter( verts ) );
2154 all.
merge( elem2d );
2155 all.
merge( elem3d );
2157 unsigned long long set_used, set_amortized, set_store_used, set_store_amortized, set_tag_used, set_tag_amortized,
2158 elem_used, elem_amortized;
2159 moab()->
estimated_memory_use( tree_sets, &set_used, &set_amortized, &set_store_used, &set_store_amortized, 0, 0, 0,
2160 0, &set_tag_used, &set_tag_amortized );
2163 int num_2d = 0, num_3d = 0;
2172 double tree_vol = diff[0] * diff[1] * diff[2];
2173 double tree_surf_area = 2 * ( diff[0] * diff[1] + diff[1] * diff[2] + diff[2] * diff[0] );
2186 size.
add( num_leaf_elem );
2188 const double* n = iter.
box_min();
2189 const double* x = iter.
box_max();
2190 double dims[3] = { x[0] - n[0], x[1] - n[1], x[2] - n[2] };
2192 double leaf_vol = dims[0] * dims[1] * dims[2];
2193 vol.
add( leaf_vol );
2195 double area = 2.0 * ( dims[0] * dims[1] + dims[1] * dims[2] + dims[2] * dims[0] );
2200 printf(
"------------------------------------------------------------------\n" );
2201 printf(
"tree volume: %f\n", tree_vol );
2202 printf(
"total elements: %d\n", num_2d + num_3d );
2203 printf(
"number of leaves: %lu\n", (
unsigned long)depth.
count );
2204 printf(
"number of nodes: %lu\n", (
unsigned long)tree_sets.
size() );
2205 printf(
"volume ratio: %0.2f%%\n", 100 * ( vol.
sum / tree_vol ) );
2206 printf(
"surface ratio: %0.2f%%\n", 100 * ( surf.
sum / tree_surf_area ) );
2207 printf(
"\nmemory: used amortized\n" );
2208 printf(
" ---------- ----------\n" );
2211 printf(
"sets %10s %10s\n",
mem_to_string( set_store_used ).c_str(),
2213 printf(
"set tags %10s %10s\n",
mem_to_string( set_tag_used ).c_str(),
2215 printf(
"\nleaf stats: min avg rms max std.dev\n" );
2216 printf(
" ---------- ---------- ---------- ---------- ----------\n" );
2217 printf(
"depth %10u %10.1f %10.1f %10u %10.2f\n", depth.
min, depth.
avg(), depth.
rms(), depth.
max,
2219 printf(
"triangles %10u %10.1f %10.1f %10u %10.2f\n", size.
min, size.
avg(), size.
rms(), size.
max, size.
dev() );
2220 printf(
"volume %10.2g %10.2g %10.2g %10.2g %10.2g\n", vol.
min, vol.
avg(), vol.
rms(), vol.
max, vol.
dev() );
2221 printf(
"surf. area %10.2g %10.2g %10.2g %10.2g %10.2g\n", surf.
min, surf.
avg(), surf.
rms(), surf.
max,
2223 printf(
"------------------------------------------------------------------\n" );