33 #if defined( MOAB_HAVE_IEEEFP_H )
37 #define MB_BSP_TREE_DEFAULT_TAG_NAME "BSPTree"
45 for(
int z = 0; z < 2; ++z )
49 corners[4 * z][2] = ranges[z][2];
51 corners[4 * z + 1][0] =
box_max[0];
52 corners[4 * z + 1][1] =
box_min[1];
53 corners[4 * z + 1][2] = ranges[z][2];
55 corners[4 * z + 2][0] =
box_max[0];
56 corners[4 * z + 2][1] =
box_max[1];
57 corners[4 * z + 2][2] = ranges[z][2];
59 corners[4 * z + 3][0] =
box_min[0];
60 corners[4 * z + 3][1] =
box_max[1];
61 corners[4 * z + 3][2] = ranges[z][2];
67 static bool point_in_box(
const double corners[8][3],
const double point[3] )
69 const unsigned side_verts[6][3] = { { 0, 3, 1 }, { 4, 5, 7 }, { 0, 1, 4 }, { 1, 2, 5 }, { 2, 3, 6 }, { 3, 0, 7 } };
73 for(
unsigned s = 0; s < 6; ++s )
75 CartVect v0( corners[side_verts[s][0]] );
76 CartVect v1( corners[side_verts[s][1]] );
77 CartVect v2( corners[side_verts[s][2]] );
78 CartVect N = ( v1 - v0 ) * ( v2 - v0 );
79 if( ( v0 - pt ) % N < 0 )
return false;
86 const double v1[] = { pt2[0] - pt1[0], pt2[1] - pt1[1], pt2[2] - pt1[2] };
87 const double v2[] = { pt3[0] - pt1[0], pt3[1] - pt1[1], pt3[2] - pt1[2] };
88 const double nrm[] = { v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2],
89 v1[0] * v2[1] - v1[1] * v2[0] };
97 std::string rootname( tagname );
116 : mbInstance(
mb ), meshSetFlags( set_flags ), cleanUpTrees( destroy_created_trees )
129 const void* data_ptr = 0;
140 if( fabs( lensqr - 1.0 ) < std::numeric_limits< double >::epsilon() )
143 const double inv_len = 1.0 / sqrt( lensqr );
145 p2.
norm[0] *= inv_len;
146 p2.
norm[1] *= inv_len;
147 p2.
norm[2] *= inv_len;
159 double corners[8][3];
181 const double min[3] = { -HUGE_VAL, -HUGE_VAL, -HUGE_VAL };
182 const double max[3] = { HUGE_VAL, HUGE_VAL, HUGE_VAL };
205 double corners[8][3];
214 std::vector< EntityHandle >
children, dead_sets, current_sets;
215 current_sets.push_back( root_handle );
216 while( !current_sets.empty() )
219 current_sets.pop_back();
220 dead_sets.push_back( set );
223 std::copy(
children.begin(),
children.end(), std::back_inserter( current_sets ) );
283 return split_leaf( leaf, plane, left, right );
306 const std::vector< EntityHandle >& left_entities,
307 const std::vector< EntityHandle >& right_entities )
313 if(
MB_SUCCESS ==
moab()->add_entities( left, &left_entities[0], left_entities.size() ) &&
314 MB_SUCCESS ==
moab()->add_entities( right, &right_entities[0], right_entities.size() ) &&
328 if( iter.
depth() == 1 )
343 std::vector< EntityHandle > stack( iter.
childVect );
347 while( !stack.empty() )
407 if(
mStack.empty() )
return MB_FAILURE;
478 const size_t s =
mStack.size();
479 return ( s > 1 ) && ( s == other_leaf.
mStack.size() ) && ( other_leaf.
mStack[s - 2] ==
mStack[s - 2] ) &&
485 if(
mStack.size() < 2 || other_leaf ==
handle() )
return false;
516 assert(
sizeof(
CartVect ) == 3 *
sizeof(
double ) );
521 rval = poly_out.
set( corners );
525 std::vector< EntityHandle >::const_iterator i =
mStack.begin();
526 std::vector< EntityHandle >::const_iterator here =
mStack.end() - 1;
535 if(
childVect.size() != 2 )
return MB_FAILURE;
564 for(
unsigned i = 0; i < 8u; ++i )
565 result |= plane.
above( hex_coords[i] ) << i;
572 for(
unsigned i = 0; i < 8u; ++i )
580 static inline void copy_coords(
const double src[3],
double dest[3] )
642 const double keep_end_coords[3],
643 double cut_end_coords[3],
646 const CartVect start( keep_end_coords ), end( cut_end_coords );
651 const double t = -( norm % start + plane.
coeff ) / ( norm % m );
652 assert( t > 0.0 && t < 1.0 );
653 xsect_point = start + t * m;
655 end.
get( old_coords_out );
656 xsect_point.
get( cut_end_coords );
672 plane_cut_edge( cut_face_out[0], corners_inout[3], corners_inout[0], plane );
673 plane_cut_edge( cut_face_out[1], corners_inout[2], corners_inout[1], plane );
674 plane_cut_edge( cut_face_out[2], corners_inout[6], corners_inout[5], plane );
675 plane_cut_edge( cut_face_out[3], corners_inout[7], corners_inout[4], plane );
678 plane_cut_edge( cut_face_out[0], corners_inout[0], corners_inout[1], plane );
679 plane_cut_edge( cut_face_out[1], corners_inout[3], corners_inout[2], plane );
680 plane_cut_edge( cut_face_out[2], corners_inout[7], corners_inout[6], plane );
681 plane_cut_edge( cut_face_out[3], corners_inout[4], corners_inout[5], plane );
684 plane_cut_edge( cut_face_out[0], corners_inout[1], corners_inout[2], plane );
685 plane_cut_edge( cut_face_out[1], corners_inout[0], corners_inout[3], plane );
686 plane_cut_edge( cut_face_out[2], corners_inout[4], corners_inout[7], plane );
687 plane_cut_edge( cut_face_out[3], corners_inout[5], corners_inout[6], plane );
690 plane_cut_edge( cut_face_out[0], corners_inout[2], corners_inout[3], plane );
691 plane_cut_edge( cut_face_out[1], corners_inout[1], corners_inout[0], plane );
692 plane_cut_edge( cut_face_out[2], corners_inout[5], corners_inout[4], plane );
693 plane_cut_edge( cut_face_out[3], corners_inout[6], corners_inout[7], plane );
696 plane_cut_edge( cut_face_out[0], corners_inout[7], corners_inout[3], plane );
697 plane_cut_edge( cut_face_out[1], corners_inout[6], corners_inout[2], plane );
698 plane_cut_edge( cut_face_out[2], corners_inout[5], corners_inout[1], plane );
699 plane_cut_edge( cut_face_out[3], corners_inout[4], corners_inout[0], plane );
702 plane_cut_edge( cut_face_out[0], corners_inout[0], corners_inout[4], plane );
703 plane_cut_edge( cut_face_out[1], corners_inout[1], corners_inout[5], plane );
704 plane_cut_edge( cut_face_out[2], corners_inout[2], corners_inout[6], plane );
705 plane_cut_edge( cut_face_out[3], corners_inout[3], corners_inout[7], plane );
714 static inline void copy_coords(
double dest[3],
const double source[3] )
723 double corners_inout[8][3],
857 if(
mStack.empty() )
return MB_FAILURE;
876 if( direction ==
LEFT ) plane.
flip();
909 memcpy( coords,
leafCoords, 24 *
sizeof(
double ) );
914 static void subtr(
double result[3],
const double a[3],
const double b[3] )
916 result[0] = a[0] - b[0];
917 result[1] = a[1] - b[1];
918 result[2] = a[2] - b[2];
922 static void sum(
double result[3],
const double a[3],
const double b[3],
const double c[3],
const double d[3] )
924 result[0] = a[0] + b[0] + c[0] + d[0];
925 result[1] = a[1] + b[1] + c[1] + d[1];
926 result[2] = a[2] + b[2] + c[2] + d[2];
930 static void cross(
double result[3],
const double a[3],
const double b[3] )
932 result[0] = a[1] * b[2] - a[2] * b[1];
933 result[1] = a[2] * b[0] - a[0] * b[2];
934 result[2] = a[0] * b[1] - a[1] * b[0];
937 static double dot(
const double a[3],
const double b[3] )
939 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
945 double f1[3], f2[3], f3[3], f4[3], f5[3], f6[3];
952 double v13[3], v24[3], v65[3];
953 subtr( v13, f1, f3 );
954 subtr( v24, f2, f4 );
955 subtr( v65, f6, f5 );
957 cross( cr, v13, v24 );
958 return ( 1. / 64 ) *
dot( cr, v65 );
965 for(
unsigned i = 0; i < 8u; ++i )
972 if( d > 0.0 ) result |= 1 << i;
1005 for(
unsigned i = 0; i < 8u; ++i )
1007 return count > 0 && count < 8u;
1041 tmp_handle = iter.
handle();
1055 if( tmp_handle == iter.
childVect[0] && s == side )
1070 std::vector< BSPTreeBoxIter > list;
1084 results.push_back( iter );
1091 bool some_above =
false, some_below =
false;
1092 for(
int i = 0; i < 4; ++i )
1095 if( signed_d > -epsilon ) some_above =
true;
1096 if( signed_d < epsilon ) some_below =
true;
1099 if( some_above && some_below )
1101 list.push_back( iter );
1102 list.back().down( plane,
RIGHT );
1105 else if( some_above )
1109 else if( some_below )
1120 if( list.empty() )
break;
1132 return poly_out.
set( ptr );
1137 std::vector< EntityHandle >
children;
1178 template <
typename PlaneIter >
1181 const PlaneIter& begin,
1182 const PlaneIter& end,
1186 const double epsilon = 1e-12;
1190 t_exit = std::numeric_limits< double >::infinity();
1194 for( PlaneIter i = begin; i != end; ++i )
1197 double coeff = i->coeff;
1198 double den = norm % ray_dir;
1199 if( fabs( den ) < epsilon )
1201 if( i->above( ray_pt.
array() ) )
return false;
1205 double t_xsect = ( -coeff - ( norm % ray_pt ) ) / den;
1209 if( t_xsect < t_exit ) t_exit = t_xsect;
1213 if( t_xsect > t_enter ) t_enter = t_xsect;
1218 return t_exit >= t_enter;
1248 static const int box_face_corners[6][4] = { { 0, 1, 5, 4 }, { 1, 2, 6, 5 }, { 2, 3, 7, 6 },
1249 { 3, 0, 4, 7 }, { 3, 2, 1, 0 }, { 4, 5, 6, 7 } };
1255 assert(
sizeof(
CartVect ) ==
sizeof( coords[0] ) );
1257 for(
int i = 0; i < 6; ++i )
1260 CartVect v1 = corners[indices[1]] - corners[indices[0]];
1261 CartVect v2 = corners[indices[3]] - corners[indices[0]];
1268 const double ray_vect[3],
1270 double& t_exit )
const
1312 if( --
pathPos < 0 )
return *
this;
1339 const double ray_vect[3],
1341 double& t_exit )
const
1349 double corners[8][3];
1358 double t2_enter, t2_exit;
1364 if( t_enter < t2_enter ) t_enter = t2_enter;
1365 if( t_exit > t2_exit ) t_exit = t2_exit;
1366 return t_enter <= t_exit;