19 #include <tr1/unordered_map>
33 template <
typename _Entity_handles,
typename _Box,
typename _Moab,
typename _Parametrizer >
41 template <
typename Box,
typename Entity_handle >
44 typedef typename std::vector< std::pair< Box, Entity_handle > > Entities;
49 _Node& operator=(
const _Node& f )
60 template <
typename Split >
61 class Split_comparator
64 typedef Split first_argument_type;
65 typedef Split second_argument_type;
66 typedef bool result_type;
68 inline double objective(
const Split& a )
const
70 return a.Lmax * a.nl - a.Rmin * a.nr;
74 bool operator()(
const Split& a,
const Split& b )
const
76 return objective( a ) < objective( b );
80 template <
typename Iterator >
81 class Iterator_comparator
84 typedef Iterator first_argument_type;
85 typedef Iterator second_argument_type;
86 typedef bool result_type;
89 bool operator()(
const Iterator& a,
const Iterator& b )
const
91 return a->second.second < b->second.second ||
92 ( !( b->second.second < a->second.second ) && a->first < b->first );
105 _Split_data(
const _Split_data& f )
118 _Split_data& operator=(
const _Split_data& f )
141 _Bucket& operator=(
const _Bucket& f )
151 template <
typename _Entity_handles,
typename _Box,
typename _Moab,
typename _Parametrizer >
166 typedef _bvh::_Node< Box, Entity_handle >
Node;
167 typedef typename std::vector< Node >
Nodes;
175 typedef typename Entity_handles::iterator Entity_handle_iterator;
177 typedef typename std::tr1::unordered_map< Entity_handle, Element_data > Entity_map;
178 typedef typename Entity_map::iterator Entity_map_iterator;
179 typedef std::vector< Entity_map_iterator > Vector;
185 #ifdef BVH_TREE_DEBUG
186 for( Entity_map_iterator i = entity_map.begin(); i != entity_map.end(); ++i )
190 std::cerr <<
"BB:" <<
bounding_box <<
"EB:" << i->second.first << std::endl;
196 Vector entity_ordering;
199 if( entity_ordering.size() )
204 #ifdef BVH_TREE_DEBUG
205 typedef typename Nodes::iterator Node_iterator;
206 typedef typename Node::Entities::iterator Entity_iterator;
207 std::set< Entity_handle > entity_handles;
208 for( Node_iterator i =
tree_.begin(); i !=
tree_.end(); ++i )
210 for( Entity_iterator j = i->entities.begin(); j != i->entities.end(); ++j )
212 entity_handles.insert( j->second );
217 std::cout <<
"Entity Handle Size Mismatch!" << std::endl;
219 typedef typename Entity_handles::iterator Entity_iterator_;
222 if( entity_handles.find( *i ) == entity_handles.end() )
224 std::cout <<
"Tree is missing an entity! " << std::endl;
229 std::cout <<
"max tree depth: " << depth << std::endl;
243 #define NUM_BUCKETS ( NUM_SPLITS + 1 )
246 template <
typename Box >
249 const double min = interval.min[
dim];
251 const double center = ( ( box.max[
dim] + box.min[
dim] ) / 2.0 ) - min;
252 #ifdef BVH_TREE_DEBUG
253 #ifdef BVH_SHOW_INDEX
254 std::cout <<
"[ " << min <<
" , " << interval.max[
dim] <<
" ]" << std::endl;
255 std::cout <<
"[ " << box.min[
dim] <<
" , " << box.max[
dim] <<
" ]" << std::endl;
256 std::cout <<
"Length of bucket" <<
length << std::endl;
257 std::cout <<
"Center: " << ( box.max[
dim] + box.min[
dim] ) / 2.0 << std::endl;
258 std::cout <<
"Distance of center from min: " <<
center << std::endl;
260 std::cout <<
"index: " << std::ceil(
center /
length ) - 1 << std::endl;
266 template <
typename Iterator,
typename Bounding_box,
typename Buckets >
269 const Bounding_box& interval,
270 Buckets& buckets )
const
273 for( Iterator i = begin; i != end; ++i )
275 const Bounding_box& box = ( *i )->second.first;
279 _bvh::_Bucket& bucket = buckets[
dim][index];
280 if( bucket.size > 0 )
286 bucket.bounding_box = box;
291 #ifdef BVH_TREE_DEBUG
292 Bounding_box elt_union = ( *begin )->second.first;
293 for( Iterator i = begin; i != end; ++i )
295 const Bounding_box& box = ( *i )->second.first;
300 _bvh::_Bucket& bucket = buckets[
dim][index];
303 std::cerr <<
"Buckets not covering elements!" << std::endl;
309 std::cout <<
"element union: " << std::endl << elt_union;
310 std::cout <<
"intervals: " << std::endl << interval;
311 std::cout <<
"union of elts does not contain original box!" << std::endl;
315 std::cout <<
"original box does not contain union of elts" << std::endl;
316 std::cout << interval << std::endl;
317 std::cout << elt_union << std::endl;
319 typedef typename Buckets::value_type Bucket_list;
320 typedef typename Bucket_list::const_iterator Bucket_iterator;
321 for( std::size_t d = 0; d <
NUM_DIM; ++d )
323 std::vector< std::size_t > nonempty;
324 const Bucket_list& buckets_ = buckets[d];
326 for( Bucket_iterator i = buckets_.begin(); i != buckets_.end(); ++i, ++j )
330 nonempty.push_back( j );
333 Bounding_box test_box = buckets_[nonempty.front()].bounding_box;
334 for( std::size_t i = 0; i < nonempty.size(); ++i )
340 std::cout <<
"union of buckets in dimension: " << d <<
"does not contain original box!" << std::endl;
344 std::cout <<
"original box does "
345 <<
"not contain union of buckets"
346 <<
"in dimension: " << d << std::endl;
347 std::cout << interval << std::endl;
348 std::cout << test_box << std::endl;
354 template <
typename Box,
typename Iterator >
355 std::size_t
set_interval(
Box& interval,
const Iterator begin,
const Iterator end )
const
358 std::size_t count = 0;
359 for( Iterator b = begin; b != end; ++b )
361 const Box& box = b->bounding_box;
379 template <
typename Splits,
typename Buckets,
typename Split_data >
382 typedef typename Buckets::value_type Bucket_list;
383 typedef typename Bucket_list::value_type Bucket;
384 typedef typename Bucket_list::const_iterator Bucket_iterator;
385 typedef typename Splits::value_type Split_list;
386 typedef typename Split_list::value_type Split;
387 typedef typename Split_list::iterator Split_iterator;
388 for( std::size_t d = 0; d <
NUM_DIM; ++d )
390 const Split_iterator splits_begin = splits[d].begin();
391 const Split_iterator splits_end = splits[d].end();
392 const Bucket_iterator left_begin = buckets[d].begin();
393 const Bucket_iterator _end = buckets[d].end();
394 Bucket_iterator left_end = buckets[d].begin() + 1;
395 for( Split_iterator s = splits_begin; s != splits_end; ++s, ++left_end )
397 s->nl =
set_interval( s->left_box, left_begin, left_end );
400 s->left_box = data.bounding_box;
401 s->left_box.max[d] = s->left_box.min[d];
406 s->right_box = data.bounding_box;
407 s->right_box.min[d] = s->right_box.max[d];
409 s->Lmax = s->left_box.max[d];
410 s->Rmin = s->right_box.min[d];
411 s->split = std::distance( splits_begin, s );
414 #ifdef BVH_TREE_DEBUG
415 for( Split_iterator s = splits_begin; s != splits_end; ++s, ++left_end )
417 typename Split::Box test_box = s->left_box;
421 std::cout <<
"nr: " << s->nr << std::endl;
422 std::cout <<
"Test box: " << std::endl << test_box;
423 std::cout <<
"Left box: " << std::endl << s->left_box;
424 std::cout <<
"Right box: " << std::endl << s->right_box;
425 std::cout <<
"Interval: " << std::endl << data.bounding_box;
426 std::cout <<
"Split boxes larger than bb" << std::endl;
430 std::cout <<
"bb larger than union "
431 <<
"of split boxes" << std::endl;
438 template <
typename Iterator,
typename Split_data >
439 void order_elements(
const Iterator& begin,
const Iterator& end,
const Split_data& data )
const
441 typedef typename Iterator::value_type Map_iterator;
442 for( Iterator i = begin; i != end; ++i )
444 const int index =
bucket_index( ( *i )->second.first, data.bounding_box, data.dim );
445 ( *i )->second.second = ( index <= data.split ) ? 0 : 1;
447 std::sort( begin, end, _bvh::Iterator_comparator< Map_iterator >() );
450 template <
typename Iterator,
typename Split_data >
451 void median_order(
const Iterator& begin,
const Iterator& end, Split_data& data )
const
453 typedef typename Iterator::value_type Map_iterator;
454 for( Iterator i = begin; i != end; ++i )
457 ( *i )->second.second =
center;
459 std::sort( begin, end, _bvh::Iterator_comparator< Map_iterator >() );
460 const std::size_t total = std::distance( begin, end );
461 Iterator middle = begin + ( total / 2 );
462 double middle_center = ( *middle )->second.second;
463 middle_center += ( *( ++middle ) )->second.second;
464 middle_center /= 2.0;
465 data.split = middle_center;
466 data.nl = std::distance( begin, middle ) + 1;
467 data.nr = total - data.nl;
469 data.left_box = ( *begin )->second.first;
470 data.right_box = ( *middle )->second.first;
471 for( Iterator i = begin; i != middle; ++i )
473 ( *i )->second.second = 0;
476 for( Iterator i = middle; i != end; ++i )
478 ( *i )->second.second = 1;
481 data.Rmin = data.right_box.min[data.dim];
482 data.Lmax = data.left_box.max[data.dim];
483 #ifdef BVH_TREE_DEBUG
484 typename Split_data::Box test_box = data.left_box;
488 std::cerr <<
"MEDIAN: BB Does not contain splits" << std::endl;
492 std::cerr <<
"MEDIAN: splits do not contain BB" << std::endl;
497 template <
typename Splits,
typename Split_data >
500 typedef typename Splits::const_iterator List_iterator;
501 typedef typename List_iterator::value_type::const_iterator Split_iterator;
502 typedef typename Split_iterator::value_type Split;
503 std::vector< Split > best_splits;
504 typedef typename _bvh::Split_comparator< Split > Comparator;
506 for( List_iterator i = splits.begin(); i != splits.end(); ++i )
508 Split_iterator j = std::min_element( i->begin(), i->end(), compare );
509 best_splits.push_back( *j );
511 data = *std::min_element( best_splits.begin(), best_splits.end(), compare );
514 template <
typename Iterator,
typename Split_data >
515 void find_split(
const Iterator& begin,
const Iterator& end, Split_data& data )
const
517 typedef typename Iterator::value_type Map_iterator;
518 typedef typename Map_iterator::value_type::second_type Box_data;
519 typedef typename Box_data::first_type _Bounding_box;
521 typedef typename std::vector< Split_data > Split_list;
522 typedef typename std::vector< Split_list > Splits;
523 typedef typename Splits::iterator Split_iterator;
524 typedef typename std::vector< _bvh::_Bucket > Bucket_list;
525 typedef typename std::vector< Bucket_list > Buckets;
529 const _Bounding_box interval = data.bounding_box;
533 const bool use_median = ( 0 == data.nl ) || ( data.nr == 0 );
542 #ifdef BVH_TREE_DEBUG
543 bool seen_one =
false, issue =
false;
544 bool first_left =
true, first_right =
true;
545 std::size_t count_left = 0, count_right = 0;
547 for( Iterator i = begin; i != end; ++i )
549 double order = ( *i )->second.second;
550 if( order != 0 && order != 1 )
552 std::cerr <<
"Invalid order element !";
553 std::cerr << order << std::endl;
573 std::cerr <<
"Bounding right box issue!" << std::endl;
594 std::cerr <<
"Bounding left box issue!" << std::endl;
600 std::cerr <<
"Invalid ordering!" << std::endl;
601 std::cout << ( *( i - 1 ) )->second.second << order << std::endl;
608 std::cout <<
"left elts do not contain left box" << std::endl;
612 std::cout <<
"left box does not contain left elts" << std::endl;
616 std::cout <<
"right elts do not contain right box" << std::endl;
620 std::cout <<
"right box do not contain right elts" << std::endl;
622 if( count_left != data.nl || count_right != data.nr )
624 std::cerr <<
"counts are off!" << std::endl;
625 std::cerr <<
"total: " << std::distance( begin, end ) << std::endl;
626 std::cerr <<
"Dim: " << data.dim << std::endl;
627 std::cerr << data.Lmax <<
" , " << data.Rmin << std::endl;
628 std::cerr <<
"Right box: " << std::endl << data.right_box <<
"Left box: " << std::endl << data.left_box;
629 std::cerr <<
"supposed to be: " << data.nl <<
" " << data.nr << std::endl;
630 std::cerr <<
"accountant says: " << count_left <<
" " << count_right << std::endl;
638 template <
typename Iterator >
639 int build_tree(
const Iterator begin,
const Iterator end,
const int index,
const Box& box,
const int depth = 0 )
641 #ifdef BVH_TREE_DEBUG
642 for( Iterator i = begin; i != end; ++i )
646 std::cerr <<
"depth: " << depth << std::endl;
647 std::cerr <<
"BB:" << box <<
"EB:" << ( *i )->second.first << std::endl;
653 const std::size_t total_num_elements = std::distance( begin, end );
656 if( total_num_elements >
SMAX )
658 _bvh::_Split_data data;
659 data.bounding_box = box;
662 node.Lmax = data.Lmax;
663 node.Rmin = data.Rmin;
665 node.child =
tree_.size();
669 const int left_depth =
build_tree( begin, begin + data.nl, node.child, data.left_box, depth + 1 );
670 const int right_depth =
build_tree( begin + data.nl, end, node.child + 1, data.right_box, depth + 1 );
671 return std::max( left_depth, right_depth );
678 template <
typename Vector,
typename Node_index,
typename Result >
679 Result&
_find_point(
const Vector& point,
const Node_index& index,
const double tol, Result& result )
const
681 typedef typename Node::Entities::const_iterator Entity_iterator;
685 for( Entity_iterator i = node.entities.begin(); i != node.entities.end(); ++i )
692 return result = std::make_pair( i->second, r.second );
696 result = Result( 0, point );
701 if( ( node.Lmax + tol ) < ( node.Rmin - tol ) )
703 if( point[node.dim] <= ( node.Lmax + tol ) )
705 return _find_point( point, node.child, tol, result );
707 else if( point[node.dim] >= ( node.Rmin - tol ) )
709 return _find_point( point, node.child + 1, tol, result );
711 result = Result( 0, point );
718 if( point[node.dim] < ( node.Rmin - tol ) )
720 return _find_point( point, node.child, tol, result );
723 else if( point[node.dim] > ( node.Lmax + tol ) )
725 return _find_point( point, node.child + 1, tol, result );
741 _find_point( point, node.child + dir, tol, result );
742 if( result.first == 0 )
744 return _find_point( point, node.child + ( !dir ), tol, result );
751 template <
typename Vector,
typename Result >
752 Result&
find(
const Vector& point,
const double tol, Result& result )
const
754 typedef typename Vector::const_iterator Point_iterator;
760 template <
typename Vector >
763 typedef typename Vector::const_iterator Point_iterator;
764 typedef typename Nodes::value_type
Node;
765 typedef typename Nodes::const_iterator Node_iterator;
766 typedef typename Node::Entities::const_iterator Entity_iterator;
767 for( Node_iterator i =
tree_.begin(); i !=
tree_.end(); ++i )
771 for( Entity_iterator j = i->entities.begin(); j != i->entities.end(); ++j )