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 ),
50 :
Tree(
iface ), planeTag( 0 ), axisTag( 0 ), splitsPerDir( 3 ), planeSet( SUBDIVISION_SNAP ), spherical( false ),
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();
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( ( num_planes + 1 ) * eps >= diff[axis] ) plane_count = (int)( diff[axis] / eps ) - 1;
1047 for(
int p = 1; p <= plane_count; ++p )
1051 double coord =
box_min[axis] + ( p / ( 1.0 + plane_count ) ) * diff[axis];
1054 unsigned int istrt = axis * nverts;
1055 double closest_coord = tmp_data[istrt];
1056 for(
unsigned i = 1; i < nverts; ++i )
1057 if( fabs( coord - tmp_data[istrt + i] ) < fabs( coord - closest_coord ) )
1058 closest_coord = tmp_data[istrt + i];
1059 if( closest_coord -
box_min[axis] <= eps ||
box_max[axis] - closest_coord <= eps )
continue;
1063 Range left, right, both;
1067 const size_t d = p_count - both.
size();
1068 if( left.
size() == d || right.
size() == d )
continue;
1070 if( val >= metric_val )
continue;
1074 best_left.
swap( left );
1075 best_right.
swap( right );
1076 best_both.
swap( both );
1089 std::vector< double >& coords,
1092 double metric_val = std::numeric_limits< unsigned >::max();
1101 const size_t p_count =
entities.size();
1105 coords.resize( vertices.
size() );
1106 for(
int axis = 0; axis < 3; ++axis )
1110 double* ptrs[] = { 0, 0, 0 };
1111 ptrs[axis] = &coords[0];
1115 std::sort( coords.begin(), coords.end() );
1116 std::vector< double >::iterator citer;
1117 citer = std::upper_bound( coords.begin(), coords.end(),
box_min[axis] + eps );
1118 const size_t count = std::upper_bound( citer, coords.end(),
box_max[axis] - eps ) - citer;
1120 int np = num_planes;
1121 if( count < 2 * (
size_t)num_planes )
1128 step = count / ( num_planes + 1 );
1131 for(
int p = 1; p <= np; ++p )
1136 Range left, right, both;
1140 const size_t diff = p_count - both.
size();
1141 if( left.
size() == diff || right.
size() == diff )
continue;
1143 if( val >= metric_val )
continue;
1147 best_left.
swap( left );
1148 best_right.
swap( right );
1149 best_both.
swap( both );
1162 std::vector< double >& coords,
1163 std::vector< EntityHandle >& indices,
1166 const size_t random_elem_threshold = 20 * num_planes;
1167 double metric_val = std::numeric_limits< unsigned >::max();
1179 const size_t p_count =
entities.size();
1180 coords.resize( 3 * num_planes );
1181 if( p_count < random_elem_threshold )
1188 indices.resize( random_elem_threshold );
1189 const int num_rand = p_count / RAND_MAX + 1;
1190 for(
size_t j = 0; j < random_elem_threshold; ++j )
1192 size_t rnd = rand();
1193 for(
int i = num_rand; i > 1; --i )
1203 coords.resize( vertices.
size() );
1204 for(
int axis = 0; axis < 3; ++axis )
1208 double* ptrs[] = { 0, 0, 0 };
1209 ptrs[axis] = &coords[0];
1213 size_t num_valid_coords = 0;
1214 for(
size_t i = 0; i < coords.size(); ++i )
1215 if( coords[i] >
box_min[axis] + eps && coords[i] <
box_max[axis] - eps ) ++num_valid_coords;
1217 if( 2 * (
size_t)num_planes > num_valid_coords )
1220 for(
size_t i = 0; i < coords.size(); ++i )
1221 if( coords[i] >
box_min[axis] + eps && coords[i] <
box_max[axis] - eps ) indices.push_back( i );
1225 indices.resize( num_planes );
1227 const int num_rand = coords.size() / RAND_MAX + 1;
1228 for(
int j = 0; j < num_planes; ++j )
1234 for(
int i = num_rand; i > 1; --i )
1236 rnd %= coords.size();
1237 }
while( coords[rnd] <=
box_min[axis] + eps || coords[rnd] >=
box_max[axis] - eps );
1242 for(
unsigned p = 0; p < indices.size(); ++p )
1246 Range left, right, both;
1250 const size_t diff = p_count - both.
size();
1251 if( left.
size() == diff || right.
size() == diff )
continue;
1253 if( val >= metric_val )
continue;
1257 best_left.
swap( left );
1258 best_right.
swap( right );
1259 best_both.
swap( both );
1268 const double iter_tol,
1269 const double inside_tol,
1270 bool* multiple_leaves,
1274 std::vector< EntityHandle >
children;
1281 if( multiple_leaves ) *multiple_leaves =
false;
1300 const double d = point[plane.
norm] - plane.
coord;
1323 const double iter_tol,
1325 bool* multiple_leaves,
1332 if( multiple_leaves ) *multiple_leaves =
false;
1373 const int idx = ( point[plane.
norm] > plane.
coord );
1374 leaf_it.
mStack.push_back(
1389 const double distance,
1390 std::vector< EntityHandle >& result_list,
1391 const double iter_tol,
1392 const double inside_tol,
1393 std::vector< double >* result_dists,
1394 std::vector< CartVect >* result_params,
1398 const double dist_sqr = distance * distance;
1400 std::vector< NodeDistance > list,
1409 std::vector< EntityHandle >
children;
1426 for(
int i = 0; i < 3; ++i )
1428 if( from_point[i] < box.
bMin[i] )
1429 node.
dist[i] = box.
bMin[i] - from_point[i];
1430 else if( from_point[i] > box.
bMax[i] )
1431 node.
dist[i] = from_point[i] - box.
bMax[i];
1433 if( node.
dist % node.
dist > dist_sqr )
1442 list.push_back( node );
1444 while( !list.empty() )
1457 if(
myEval && result_params )
1467 result_list.push_back( ent );
1468 result_params->push_back( params );
1469 if( result_dists ) result_dists->push_back( 0.0 );
1474 result_list_nodes.push_back( node );
1483 const double d = from[plane.
norm] - plane.
coord;
1489 list.push_back( node );
1496 if( node.
dist % node.
dist <= dist_sqr )
1499 list.push_back( node );
1507 list.push_back( node );
1511 if( -d <= distance )
1514 if( node.
dist % node.
dist <= dist_sqr )
1517 list.push_back( node );
1527 result_list.reserve( result_list_nodes.size() );
1528 for( std::vector< NodeDistance >::iterator vit = result_list_nodes.begin(); vit != result_list_nodes.end(); ++vit )
1529 result_list.push_back( ( *vit ).handle );
1531 if( result_dists && distance > 0.0 )
1533 result_dists->reserve( result_list_nodes.size() );
1534 for( std::vector< NodeDistance >::iterator vit = result_list_nodes.begin(); vit != result_list_nodes.end();
1536 result_dists->push_back( ( *vit ).dist.length() );
1545 double& shortest_dist_sqr,
1556 rval =
moab->get_connectivity( *i, conn, len );
1559 rval =
moab->get_coords( conn, 3, verts[0].array() );
1564 double dist_sqr = diff % diff;
1565 if( dist_sqr < shortest_dist_sqr )
1568 shortest_dist_sqr = dist_sqr;
1580 double& shortest_dist_sqr,
1587 rval =
moab->get_entities_by_type( set_handle,
MBTRI, tris );
1594 const double from[3],
1601 std::vector< EntityHandle > stack;
1602 std::vector< EntityHandle >
children( 2 );
1603 stack.reserve( 30 );
1605 stack.push_back( root );
1607 while( !stack.empty() )
1629 int rs =
split.right_side( from );
1631 stack.push_back(
children[1 - rs] );
1641 double dist_sqr = HUGE_VAL;
1764 const double from_coords[3],
1765 double closest_point_out[3],
1769 double shortest_dist_sqr = HUGE_VAL;
1770 std::vector< EntityHandle > leaves;
1771 const CartVect from( from_coords );
1777 assert( tree_root );
1785 rval =
distance_search( from_coords, sqrt( diff % diff ), leaves, 1.0e-10, 1.0e-6, NULL, NULL, &tree_root );
1790 for(
unsigned i = 0; i < leaves.size(); ++i )
1797 closest_pt.
get( closest_point_out );
1804 std::vector< EntityHandle >& triangles )
1807 std::vector< EntityHandle > leaves;
1815 assert( tree_root );
1820 for(
unsigned i = 0; i < leaves.size(); ++i )
1834 if( ( closest_pt % closest_pt ) <= ( rad * rad ) ) triangles.push_back( *j );
1839 std::sort( triangles.begin(), triangles.end() );
1840 triangles.erase( std::unique( triangles.begin(), triangles.end() ), triangles.end() );
1853 const double ray_dir_in[3],
1854 const double ray_pt_in[3],
1855 std::vector< EntityHandle >& tris_out,
1856 std::vector< double >& dists_out,
1861 double ray_beg = 0.0;
1862 if( ray_end < 0.0 ) ray_end = HUGE_VAL;
1867 const CartVect ray_pt( ray_pt_in ), ray_dir( ray_dir_in );
1883 std::vector< EntityHandle >
children;
1884 std::vector< NodeSeg > list;
1885 NodeSeg seg( root, ray_beg, ray_end );
1886 list.push_back( seg );
1888 while( !list.empty() )
1897 if( seg.
beg > ray_end )
continue;
1910 for( iter = tris.
begin(); iter != tris.
end(); ++iter )
1921 if( std::find( tris_out.begin(), tris_out.end(), *iter ) == tris_out.end() )
1923 tris_out.push_back( *iter );
1924 dists_out.push_back( tri_t );
1927 else if( tri_t < ray_end )
1929 if( std::find( tris_out.begin(), tris_out.end(), *iter ) == tris_out.end() )
1931 if( tris_out.size() < (
unsigned)max_ints )
1933 tris_out.resize( tris_out.size() + 1 );
1934 dists_out.resize( dists_out.size() + 1 );
1936 int w = tris_out.size() - 1;
1937 for( ; w > 0 && tri_t < dists_out[w - 1]; --w )
1939 tris_out[w] = tris_out[w - 1];
1940 dists_out[w] = dists_out[w - 1];
1942 tris_out[w] = *iter;
1943 dists_out[w] = tri_t;
1944 if( tris_out.size() >= (
unsigned)max_ints )
1948 ray_end = dists_out.back();
1964 const double inv_dir = 1.0 / ray_dir[plane.
norm];
1965 const double t = ( plane.
coord - ray_pt[plane.
norm] ) * inv_dir;
1966 const double diff = tol * inv_dir;
1976 const int fwd_child = ( ray_dir[plane.
norm] > 0.0 );
1988 else if( seg.
end + diff < t )
1999 else if( seg.
beg - diff > t )
2011 else if( t <= seg.
beg )
2016 else if( t >= seg.
end )
2036 min_depth = max_depth = iter.
depth();
2038 int num_of_elements = 0, max, min;
2040 max = min = num_of_elements;
2045 max = std::max( max, temp );
2046 min = std::min( min, temp );
2047 if( iter.
depth() > max_depth )
2048 max_depth = iter.
depth();
2049 else if( iter.
depth() < min_depth )
2050 min_depth = iter.
depth();
2070 if( mem > 9 * 1024 )
2072 mem = ( mem + 512 ) / 1024;
2073 strcpy(
unit,
"kB" );
2075 if( mem > 9 * 1024 )
2077 mem = ( mem + 512 ) / 1024;
2078 strcpy(
unit,
"MB" );
2080 if( mem > 9 * 1024 )
2082 mem = ( mem + 512 ) / 1024;
2083 strcpy(
unit,
"GB" );
2086 snprintf(
buffer, 256,
"%lu %s", mem,
unit );
2090 template <
typename T >
2096 void add( T value );
2103 return sqrt( (
double)
sqr /
count );
2113 template <
typename T >
2115 : min( std::numeric_limits< T >::max() ), max( std::numeric_limits< T >::min() ),
sum( 0 ), sqr( 0 ), count( 0 )
2119 template <
typename T >
2122 if( value < min ) min = value;
2123 if( value > max ) max = value;
2125 sqr += value * value;
2133 Range tree_sets, elem2d, elem3d, verts, all;
2137 std::vector<EntityHandle> elem2d_vec, elem3d_vec, verts_vec;
2144 std::sort(elem2d_vec.begin(), elem2d_vec.end());
2145 std::copy( elem2d_vec.rbegin(), elem2d_vec.rend(),
range_inserter( elem2d ) );
2146 std::sort(elem3d_vec.begin(), elem3d_vec.end());
2147 std::copy( elem3d_vec.rbegin(), elem3d_vec.rend(),
range_inserter( elem3d ) );
2148 std::sort(verts_vec.begin(), verts_vec.end());
2149 std::copy( verts_vec.rbegin(), verts_vec.rend(),
range_inserter( verts ) );
2153 all.
merge( elem2d );
2154 all.
merge( elem3d );
2156 unsigned long long set_used, set_amortized, set_store_used, set_store_amortized, set_tag_used, set_tag_amortized,
2157 elem_used, elem_amortized;
2158 moab()->
estimated_memory_use( tree_sets, &set_used, &set_amortized, &set_store_used, &set_store_amortized, 0, 0, 0,
2159 0, &set_tag_used, &set_tag_amortized );
2162 int num_2d = 0, num_3d = 0;
2171 double tree_vol = diff[0] * diff[1] * diff[2];
2172 double tree_surf_area = 2 * ( diff[0] * diff[1] + diff[1] * diff[2] + diff[2] * diff[0] );
2185 size.add( num_leaf_elem );
2187 const double* n = iter.
box_min();
2188 const double* x = iter.
box_max();
2189 double dims[3] = { x[0] - n[0], x[1] - n[1], x[2] - n[2] };
2191 double leaf_vol = dims[0] * dims[1] * dims[2];
2192 vol.
add( leaf_vol );
2194 double area = 2.0 * ( dims[0] * dims[1] + dims[1] * dims[2] + dims[2] * dims[0] );
2199 printf(
"------------------------------------------------------------------\n" );
2200 printf(
"tree volume: %f\n", tree_vol );
2201 printf(
"total elements: %d\n", num_2d + num_3d );
2202 printf(
"number of leaves: %lu\n", (
unsigned long)depth.
count );
2203 printf(
"number of nodes: %lu\n", (
unsigned long)tree_sets.
size() );
2204 printf(
"volume ratio: %0.2f%%\n", 100 * ( vol.
sum / tree_vol ) );
2205 printf(
"surface ratio: %0.2f%%\n", 100 * ( surf.
sum / tree_surf_area ) );
2206 printf(
"\nmemory: used amortized\n" );
2207 printf(
" ---------- ----------\n" );
2210 printf(
"sets %10s %10s\n",
mem_to_string( set_store_used ).c_str(),
2212 printf(
"set tags %10s %10s\n",
mem_to_string( set_tag_used ).c_str(),
2214 printf(
"\nleaf stats: min avg rms max std.dev\n" );
2215 printf(
" ---------- ---------- ---------- ---------- ----------\n" );
2216 printf(
"depth %10u %10.1f %10.1f %10u %10.2f\n", depth.
min, depth.
avg(), depth.
rms(), depth.
max,
2218 printf(
"triangles %10u %10.1f %10.1f %10u %10.2f\n",
size.min,
size.avg(),
size.rms(),
size.max,
size.dev() );
2219 printf(
"volume %10.2g %10.2g %10.2g %10.2g %10.2g\n", vol.
min, vol.
avg(), vol.
rms(), vol.
max, vol.
dev() );
2220 printf(
"surf. area %10.2g %10.2g %10.2g %10.2g %10.2g\n", surf.
min, surf.
avg(), surf.
rms(), surf.
max,
2222 printf(
"------------------------------------------------------------------\n" );