LCOV - code coverage report
Current view: top level - src - BVHTree.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 255 410 62.2 %
Date: 2020-12-16 07:07:30 Functions: 12 17 70.6 %
Branches: 416 1304 31.9 %

           Branch data     Line data    Source code
       1                 :            : #include "moab/BVHTree.hpp"
       2                 :            : #include "moab/Interface.hpp"
       3                 :            : #include "moab/ElemEvaluator.hpp"
       4                 :            : #include "moab/ReadUtilIface.hpp"
       5                 :            : #include "moab/CpuTimer.hpp"
       6                 :            : 
       7                 :            : namespace moab
       8                 :            : {
       9                 :            : const char* BVHTree::treeName = "BVHTree";
      10                 :            : 
      11                 :          1 : ErrorCode BVHTree::build_tree( const Range& entities, EntityHandle* tree_root_set, FileOptions* options )
      12                 :            : {
      13                 :            :     ErrorCode rval;
      14         [ +  - ]:          1 :     CpuTimer cp;
      15                 :            : 
      16         [ -  + ]:          1 :     if( options )
      17                 :            :     {
      18         [ #  # ]:          0 :         rval = parse_options( *options );
      19         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return rval;
      20                 :            : 
      21 [ #  # ][ #  # ]:          0 :         if( !options->all_seen() ) return MB_FAILURE;
      22                 :            :     }
      23                 :            : 
      24                 :            :     // calculate bounding box of elements
      25         [ +  - ]:          1 :     BoundBox box;
      26 [ +  - ][ +  - ]:          1 :     rval = box.update( *moab(), entities );
      27         [ -  + ]:          1 :     if( MB_SUCCESS != rval ) return rval;
      28                 :            : 
      29                 :            :     // create tree root
      30                 :            :     EntityHandle tmp_root;
      31         [ +  - ]:          1 :     if( !tree_root_set ) tree_root_set = &tmp_root;
      32 [ +  - ][ +  - ]:          1 :     rval = create_root( box.bMin.array(), box.bMax.array(), *tree_root_set );
                 [ +  - ]
      33         [ -  + ]:          1 :     if( MB_SUCCESS != rval ) return rval;
      34         [ +  - ]:          1 :     rval = mbImpl->add_entities( *tree_root_set, entities );
      35         [ -  + ]:          1 :     if( MB_SUCCESS != rval ) return rval;
      36                 :            : 
      37                 :            :     // a fully balanced tree will have 2*_entities.size()
      38                 :            :     // which is one doubling away..
      39         [ +  - ]:          2 :     std::vector< Node > tree_nodes;
      40 [ +  - ][ +  - ]:          1 :     tree_nodes.reserve( entities.size() / maxPerLeaf );
      41         [ +  - ]:          2 :     std::vector< HandleData > handle_data_vec;
      42         [ +  - ]:          1 :     rval = construct_element_vec( handle_data_vec, entities, boundBox );
      43         [ -  + ]:          1 :     if( MB_SUCCESS != rval ) return rval;
      44                 :            : 
      45                 :            : #ifndef NDEBUG
      46 [ +  - ][ +  - ]:        730 :     for( std::vector< HandleData >::const_iterator i = handle_data_vec.begin(); i != handle_data_vec.end(); ++i )
         [ +  - ][ +  + ]
      47                 :            :     {
      48 [ +  - ][ +  - ]:        729 :         if( !boundBox.intersects_box( i->myBox, 0 ) )
                 [ -  + ]
      49                 :            :         {
      50 [ #  # ][ #  # ]:          0 :             std::cerr << "BB:" << boundBox << "EB:" << i->myBox << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      51                 :          0 :             return MB_FAILURE;
      52                 :            :         }
      53                 :            :     }
      54                 :            : #endif
      55                 :            :     // We only build nonempty trees
      56         [ +  - ]:          1 :     if( !handle_data_vec.empty() )
      57                 :            :     {
      58                 :            :         // initially all bits are set
      59 [ +  - ][ +  - ]:          1 :         tree_nodes.push_back( Node() );
      60         [ +  - ]:          1 :         const int depth = local_build_tree( tree_nodes, handle_data_vec.begin(), handle_data_vec.end(), 0, boundBox );
      61                 :            : #ifndef NDEBUG
      62         [ +  - ]:          1 :         std::set< EntityHandle > entity_handles;
      63 [ +  - ][ +  - ]:        378 :         for( std::vector< Node >::iterator n = tree_nodes.begin(); n != tree_nodes.end(); ++n )
                 [ +  + ]
      64                 :            :         {
      65 [ +  - ][ +  - ]:       1106 :             for( HandleDataVec::const_iterator j = n->entities.begin(); j != n->entities.end(); ++j )
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
      66                 :            :             {
      67 [ +  - ][ +  - ]:        729 :                 entity_handles.insert( j->myHandle );
      68                 :            :             }
      69                 :            :         }
      70 [ +  - ][ -  + ]:          1 :         if( entity_handles.size() != entities.size() ) { std::cout << "Entity Handle Size Mismatch!" << std::endl; }
         [ #  # ][ #  # ]
      71 [ +  - ][ +  - ]:        730 :         for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
         [ +  - ][ +  - ]
                 [ +  + ]
      72                 :            :         {
      73 [ +  - ][ +  - ]:        729 :             if( entity_handles.find( *i ) == entity_handles.end() )
         [ +  - ][ -  + ]
      74 [ #  # ][ #  # ]:          0 :                 std::cout << "Tree is missing an entity! " << std::endl;
      75                 :            :         }
      76                 :            : #endif
      77         [ +  - ]:          1 :         treeDepth = std::max( depth, treeDepth );
      78                 :            :     }
      79                 :            : 
      80                 :            :     // convert vector of Node's to entity sets and vector of TreeNode's
      81         [ +  - ]:          1 :     rval = convert_tree( tree_nodes );
      82         [ -  + ]:          1 :     if( MB_SUCCESS != rval ) return rval;
      83                 :            : 
      84         [ +  - ]:          1 :     treeStats.reset();
      85         [ +  - ]:          1 :     rval               = treeStats.compute_stats( mbImpl, startSetHandle );
      86         [ +  - ]:          1 :     treeStats.initTime = cp.time_elapsed();
      87                 :            : 
      88                 :          2 :     return rval;
      89                 :            : }
      90                 :            : 
      91                 :          1 : ErrorCode BVHTree::convert_tree( std::vector< Node >& tree_nodes )
      92                 :            : {
      93                 :            :     // first construct the proper number of entity sets
      94                 :            :     ReadUtilIface* read_util;
      95         [ +  - ]:          1 :     ErrorCode rval = mbImpl->query_interface( read_util );
      96         [ -  + ]:          1 :     if( MB_SUCCESS != rval ) return rval;
      97                 :            : 
      98                 :            :     {  // isolate potentially-large std::vector so it gets deleted earlier
      99         [ +  - ]:          1 :         std::vector< unsigned int > tmp_flags( tree_nodes.size(), meshsetFlags );
     100 [ +  - ][ +  - ]:          1 :         rval = read_util->create_entity_sets( tree_nodes.size(), &tmp_flags[0], 0, startSetHandle );
     101         [ -  + ]:          1 :         if( MB_SUCCESS != rval ) return rval;
     102         [ +  - ]:          1 :         rval = mbImpl->release_interface( read_util );
     103 [ -  + ][ +  - ]:          1 :         if( MB_SUCCESS != rval ) return rval;
     104                 :            :     }
     105                 :            : 
     106                 :            :     // populate the sets and the TreeNode vector
     107                 :          1 :     EntityHandle set_handle = startSetHandle;
     108                 :          1 :     std::vector< Node >::iterator it;
     109         [ +  - ]:          1 :     myTree.reserve( tree_nodes.size() );
     110 [ +  - ][ +  - ]:        378 :     for( it = tree_nodes.begin(); it != tree_nodes.end(); ++it, set_handle++ )
                 [ +  + ]
     111                 :            :     {
     112 [ +  - ][ +  + ]:        377 :         if( it != tree_nodes.begin() && !it->entities.empty() )
         [ +  - ][ +  + ]
                 [ +  - ]
           [ +  +  #  # ]
     113                 :            :         {
     114         [ +  - ]:        189 :             Range range;
     115 [ +  - ][ +  - ]:        918 :             for( HandleDataVec::iterator hit = it->entities.begin(); hit != it->entities.end(); ++hit )
         [ +  - ][ +  - ]
                 [ +  + ]
     116 [ +  - ][ +  - ]:        729 :                 range.insert( hit->myHandle );
     117         [ +  - ]:        189 :             rval = mbImpl->add_entities( set_handle, range );
     118 [ -  + ][ +  - ]:        189 :             if( MB_SUCCESS != rval ) return rval;
     119                 :            :         }
     120 [ +  - ][ +  - ]:        377 :         myTree.push_back( TreeNode( it->dim, it->child, it->Lmax, it->Rmin, it->box ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     121                 :            : 
     122 [ +  - ][ +  + ]:        377 :         if( it->dim != 3 )
     123                 :            :         {
     124 [ +  - ][ +  - ]:        188 :             rval = mbImpl->add_child_meshset( set_handle, startSetHandle + it->child );
     125         [ -  + ]:        188 :             if( MB_SUCCESS != rval ) return rval;
     126 [ +  - ][ +  - ]:        188 :             rval = mbImpl->add_child_meshset( set_handle, startSetHandle + it->child + 1 );
     127         [ -  + ]:        188 :             if( MB_SUCCESS != rval ) return rval;
     128                 :            :         }
     129                 :            :     }
     130                 :            : 
     131                 :          1 :     return MB_SUCCESS;
     132                 :            : }
     133                 :            : 
     134                 :          1 : ErrorCode BVHTree::parse_options( FileOptions& opts )
     135                 :            : {
     136         [ +  - ]:          1 :     ErrorCode rval = parse_common_options( opts );
     137         [ -  + ]:          1 :     if( MB_SUCCESS != rval ) return rval;
     138                 :            : 
     139                 :            :     //  SPLITS_PER_DIR: number of candidate splits considered per direction; default = 3
     140                 :            :     int tmp_int;
     141         [ +  - ]:          1 :     rval = opts.get_int_option( "SPLITS_PER_DIR", tmp_int );
     142         [ -  + ]:          1 :     if( MB_SUCCESS == rval ) splitsPerDir = tmp_int;
     143                 :            : 
     144                 :          1 :     return MB_SUCCESS;
     145                 :            : }
     146                 :            : 
     147                 :        188 : void BVHTree::establish_buckets( HandleDataVec::const_iterator begin, HandleDataVec::const_iterator end,
     148                 :            :                                  const BoundBox& interval, std::vector< std::vector< Bucket > >& buckets ) const
     149                 :            : {
     150                 :            :     // put each element into its bucket
     151 [ +  - ][ +  - ]:       6686 :     for( HandleDataVec::const_iterator i = begin; i != end; ++i )
                 [ +  + ]
     152                 :            :     {
     153         [ +  - ]:       6498 :         const BoundBox& box = i->myBox;
     154         [ +  + ]:      25992 :         for( unsigned int dim = 0; dim < 3; ++dim )
     155                 :            :         {
     156         [ +  - ]:      19494 :             const unsigned int index = Bucket::bucket_index( splitsPerDir, box, interval, dim );
     157 [ +  - ][ -  + ]:      19494 :             assert( index < buckets[dim].size() );
     158 [ +  - ][ +  - ]:      19494 :             Bucket& bucket = buckets[dim][index];
     159         [ +  + ]:      19494 :             if( bucket.mySize > 0 )
     160         [ +  - ]:      18085 :                 bucket.boundingBox.update( box );
     161                 :            :             else
     162         [ +  - ]:       1409 :                 bucket.boundingBox = box;
     163                 :      19494 :             bucket.mySize++;
     164                 :            :         }
     165                 :            :     }
     166                 :            : 
     167                 :            : #ifndef NDEBUG
     168         [ +  - ]:        188 :     BoundBox elt_union = begin->myBox;
     169 [ +  - ][ +  - ]:       6686 :     for( HandleDataVec::const_iterator i = begin; i != end; ++i )
                 [ +  + ]
     170                 :            :     {
     171         [ +  - ]:       6498 :         const BoundBox& box = i->myBox;
     172         [ +  - ]:       6498 :         elt_union.update( box );
     173         [ +  + ]:      25992 :         for( unsigned int dim = 0; dim < 3; ++dim )
     174                 :            :         {
     175         [ +  - ]:      19494 :             const unsigned int index = Bucket::bucket_index( splitsPerDir, box, interval, dim );
     176 [ +  - ][ +  - ]:      19494 :             Bucket& bucket           = buckets[dim][index];
     177 [ +  - ][ -  + ]:      19494 :             if( !bucket.boundingBox.intersects_box( box ) ) std::cerr << "Buckets not covering elements!" << std::endl;
         [ #  # ][ #  # ]
     178                 :            :         }
     179                 :            :     }
     180 [ +  - ][ -  + ]:        188 :     if( !elt_union.intersects_box( interval ) )
     181                 :            :     {
     182 [ #  # ][ #  # ]:          0 :         std::cout << "element union: " << std::endl << elt_union;
                 [ #  # ]
     183 [ #  # ][ #  # ]:          0 :         std::cout << "intervals: " << std::endl << interval;
                 [ #  # ]
     184 [ #  # ][ #  # ]:          0 :         std::cout << "union of elts does not contain original box!" << std::endl;
     185                 :            :     }
     186 [ +  - ][ -  + ]:        188 :     if( !interval.intersects_box( elt_union ) )
     187                 :            :     {
     188 [ #  # ][ #  # ]:          0 :         std::cout << "original box does not contain union of elts" << std::endl;
     189 [ #  # ][ #  # ]:          0 :         std::cout << interval << std::endl << elt_union << std::endl;
         [ #  # ][ #  # ]
     190                 :            :     }
     191         [ +  + ]:        752 :     for( unsigned int d = 0; d < 3; ++d )
     192                 :            :     {
     193         [ +  - ]:        564 :         std::vector< unsigned int > nonempty;
     194         [ +  - ]:        564 :         const std::vector< Bucket >& buckets_ = buckets[d];
     195                 :        564 :         unsigned int j                        = 0;
     196 [ +  - ][ +  - ]:       2820 :         for( std::vector< Bucket >::const_iterator i = buckets_.begin(); i != buckets_.end(); ++i, ++j )
                 [ +  + ]
     197                 :            :         {
     198 [ +  - ][ +  + ]:       2256 :             if( i->mySize > 0 ) { nonempty.push_back( j ); }
                 [ +  - ]
     199                 :            :         }
     200 [ +  - ][ +  - ]:       1128 :         BoundBox test_box = buckets_[nonempty.front()].boundingBox;
     201         [ +  + ]:       1973 :         for( unsigned int i = 0; i < nonempty.size(); ++i )
     202 [ +  - ][ +  - ]:       1409 :             test_box.update( buckets_[nonempty[i]].boundingBox );
                 [ +  - ]
     203                 :            : 
     204 [ +  - ][ -  + ]:        564 :         if( !test_box.intersects_box( interval ) )
     205 [ #  # ][ #  # ]:          0 :             std::cout << "union of buckets in dimension: " << d << "does not contain original box!" << std::endl;
         [ #  # ][ #  # ]
     206 [ +  - ][ -  + ]:        564 :         if( !interval.intersects_box( test_box ) )
     207                 :            :         {
     208         [ #  # ]:          0 :             std::cout << "original box does "
     209         [ #  # ]:          0 :                       << "not contain union of buckets"
     210 [ #  # ][ #  # ]:          0 :                       << "in dimension: " << d << std::endl;
                 [ #  # ]
     211 [ #  # ][ #  # ]:          0 :             std::cout << interval << std::endl << test_box << std::endl;
         [ #  # ][ #  # ]
     212                 :            :         }
     213                 :        752 :     }
     214                 :            : #endif
     215                 :        188 : }
     216                 :            : 
     217                 :        188 : void BVHTree::initialize_splits( std::vector< std::vector< SplitData > >& splits,
     218                 :            :                                  const std::vector< std::vector< Bucket > >& buckets, const SplitData& data ) const
     219                 :            : {
     220         [ +  + ]:        752 :     for( unsigned int d = 0; d < 3; ++d )
     221                 :            :     {
     222         [ +  - ]:        564 :         std::vector< SplitData >::iterator splits_begin  = splits[d].begin();
     223         [ +  - ]:        564 :         std::vector< SplitData >::iterator splits_end    = splits[d].end();
     224         [ +  - ]:        564 :         std::vector< Bucket >::const_iterator left_begin = buckets[d].begin();
     225         [ +  - ]:        564 :         std::vector< Bucket >::const_iterator _end       = buckets[d].end();
     226 [ +  - ][ +  - ]:        564 :         std::vector< Bucket >::const_iterator left_end   = buckets[d].begin() + 1;
     227 [ +  - ][ +  - ]:       2256 :         for( std::vector< SplitData >::iterator s = splits_begin; s != splits_end; ++s, ++left_end )
         [ +  - ][ +  + ]
     228                 :            :         {
     229 [ +  - ][ +  - ]:       1692 :             s->nl = set_interval( s->leftBox, left_begin, left_end );
                 [ +  - ]
     230 [ +  - ][ +  + ]:       1692 :             if( s->nl == 0 )
     231                 :            :             {
     232 [ +  - ][ +  - ]:        107 :                 s->leftBox         = data.boundingBox;
     233 [ +  - ][ +  - ]:        107 :                 s->leftBox.bMax[d] = s->leftBox.bMin[d];
         [ +  - ][ +  - ]
     234                 :            :             }
     235 [ +  - ][ +  - ]:       1692 :             s->nr = set_interval( s->rightBox, left_end, _end );
                 [ +  - ]
     236 [ +  - ][ +  + ]:       1692 :             if( s->nr == 0 )
     237                 :            :             {
     238 [ +  - ][ +  - ]:        466 :                 s->rightBox         = data.boundingBox;
     239 [ +  - ][ +  - ]:        466 :                 s->rightBox.bMin[d] = s->rightBox.bMax[d];
         [ +  - ][ +  - ]
     240                 :            :             }
     241 [ +  - ][ +  - ]:       1692 :             s->Lmax  = s->leftBox.bMax[d];
                 [ +  - ]
     242 [ +  - ][ +  - ]:       1692 :             s->Rmin  = s->rightBox.bMin[d];
                 [ +  - ]
     243 [ +  - ][ +  - ]:       1692 :             s->split = std::distance( splits_begin, s );
     244         [ +  - ]:       1692 :             s->dim   = d;
     245                 :            :         }
     246                 :            : #ifndef NDEBUG
     247 [ +  - ][ +  - ]:       2256 :         for( std::vector< SplitData >::iterator s = splits_begin; s != splits_end; ++s )
                 [ +  + ]
     248                 :            :         {
     249         [ +  - ]:       1692 :             BoundBox test_box = s->leftBox;
     250 [ +  - ][ +  - ]:       1692 :             test_box.update( s->rightBox );
     251 [ +  - ][ -  + ]:       1692 :             if( !data.boundingBox.intersects_box( test_box ) )
     252                 :            :             {
     253 [ #  # ][ #  # ]:          0 :                 std::cout << "nr: " << s->nr << std::endl;
         [ #  # ][ #  # ]
     254 [ #  # ][ #  # ]:          0 :                 std::cout << "Test box: " << std::endl << test_box;
                 [ #  # ]
     255 [ #  # ][ #  # ]:          0 :                 std::cout << "Left box: " << std::endl << s->leftBox;
         [ #  # ][ #  # ]
     256 [ #  # ][ #  # ]:          0 :                 std::cout << "Right box: " << std::endl << s->rightBox;
         [ #  # ][ #  # ]
     257 [ #  # ][ #  # ]:          0 :                 std::cout << "Interval: " << std::endl << data.boundingBox;
                 [ #  # ]
     258 [ #  # ][ #  # ]:          0 :                 std::cout << "Split boxes larger than bb" << std::endl;
     259                 :            :             }
     260 [ +  - ][ -  + ]:       1692 :             if( !test_box.intersects_box( data.boundingBox ) )
     261 [ #  # ][ #  # ]:          0 :             { std::cout << "bb larger than union of split boxes" << std::endl; }
     262                 :       1692 :         }
     263                 :            : #endif
     264                 :            :     }
     265                 :        188 : }
     266                 :            : 
     267                 :         92 : void BVHTree::median_order( HandleDataVec::iterator& begin, HandleDataVec::iterator& end, SplitData& data ) const
     268                 :            : {
     269                 :         92 :     int dim = data.dim;
     270 [ +  - ][ +  - ]:       1526 :     for( HandleDataVec::iterator i = begin; i != end; ++i )
                 [ +  + ]
     271                 :            :     {
     272 [ +  - ][ +  - ]:       1434 :         i->myDim = 0.5 * ( i->myBox.bMin[dim], i->myBox.bMax[dim] );
         [ +  - ][ +  - ]
                 [ +  - ]
     273                 :            :     }
     274         [ +  - ]:         92 :     std::sort( begin, end, BVHTree::HandleData_comparator() );
     275         [ +  - ]:         92 :     const unsigned int total       = std::distance( begin, end );
     276         [ +  - ]:         92 :     HandleDataVec::iterator middle = begin + ( total / 2 );
     277         [ +  - ]:         92 :     double middle_center           = middle->myDim;
     278 [ +  - ][ +  - ]:         92 :     middle_center += ( ++middle )->myDim;
     279                 :         92 :     middle_center *= 0.5;
     280                 :         92 :     data.split = middle_center;
     281         [ +  - ]:         92 :     data.nl    = std::distance( begin, middle ) + 1;
     282                 :         92 :     data.nr    = total - data.nl;
     283         [ +  - ]:         92 :     ++middle;
     284 [ +  - ][ +  - ]:         92 :     data.leftBox  = begin->myBox;
     285 [ +  - ][ +  - ]:         92 :     data.rightBox = middle->myBox;
     286 [ +  - ][ +  - ]:        964 :     for( HandleDataVec::iterator i = begin; i != middle; ++i )
                 [ +  + ]
     287                 :            :     {
     288         [ +  - ]:        872 :         i->myDim = 0;
     289 [ +  - ][ +  - ]:        872 :         data.leftBox.update( i->myBox );
     290                 :            :     }
     291 [ +  - ][ +  - ]:        654 :     for( HandleDataVec::iterator i = middle; i != end; ++i )
                 [ +  + ]
     292                 :            :     {
     293         [ +  - ]:        562 :         i->myDim = 1;
     294 [ +  - ][ +  - ]:        562 :         data.rightBox.update( i->myBox );
     295                 :            :     }
     296         [ +  - ]:         92 :     data.Rmin = data.rightBox.bMin[data.dim];
     297         [ +  - ]:         92 :     data.Lmax = data.leftBox.bMax[data.dim];
     298                 :            : #ifndef NDEBUG
     299                 :         92 :     BoundBox test_box( data.rightBox );
     300 [ +  - ][ -  + ]:         92 :     if( !data.boundingBox.intersects_box( test_box ) )
     301                 :            :     {
     302 [ #  # ][ #  # ]:          0 :         std::cerr << "MEDIAN: BB Does not contain splits" << std::endl;
     303 [ #  # ][ #  # ]:          0 :         std::cerr << "test_box:         " << test_box << std::endl;
                 [ #  # ]
     304 [ #  # ][ #  # ]:          0 :         std::cerr << "data.boundingBox: " << data.boundingBox << std::endl;
                 [ #  # ]
     305                 :         92 :     }
     306                 :            : #endif
     307                 :         92 : }
     308                 :            : 
     309                 :        188 : void BVHTree::find_split( HandleDataVec::iterator& begin, HandleDataVec::iterator& end, SplitData& data ) const
     310                 :            : {
     311 [ +  - ][ +  - ]:        188 :     std::vector< std::vector< Bucket > > buckets( 3, std::vector< Bucket >( splitsPerDir + 1 ) );
     312 [ +  - ][ +  - ]:        376 :     std::vector< std::vector< SplitData > > splits( 3, std::vector< SplitData >( splitsPerDir, data ) );
     313                 :            : 
     314                 :        188 :     const BoundBox interval = data.boundingBox;
     315 [ +  - ][ +  - ]:        188 :     establish_buckets( begin, end, interval, buckets );
                 [ +  - ]
     316         [ +  - ]:        188 :     initialize_splits( splits, buckets, data );
     317         [ +  - ]:        188 :     choose_best_split( splits, data );
     318 [ +  + ][ -  + ]:        188 :     const bool use_median = ( 0 == data.nl ) || ( data.nr == 0 );
     319         [ +  + ]:        188 :     if( !use_median )
     320         [ +  - ]:         96 :         order_elements( begin, end, data );
     321                 :            :     else
     322         [ +  - ]:         92 :         median_order( begin, end, data );
     323                 :            : 
     324                 :            : #ifndef NDEBUG
     325                 :        188 :     bool seen_one = false, issue = false;
     326                 :        188 :     bool first_left = true, first_right = true;
     327                 :        188 :     unsigned int count_left = 0, count_right = 0;
     328 [ +  - ][ +  - ]:        376 :     BoundBox left_box, right_box;
     329 [ +  - ][ +  - ]:       6686 :     for( HandleDataVec::iterator i = begin; i != end; ++i )
                 [ +  + ]
     330                 :            :     {
     331         [ +  - ]:       6498 :         int order = i->myDim;
     332 [ +  + ][ -  + ]:       6498 :         if( order != 0 && order != 1 )
     333                 :            :         {
     334         [ #  # ]:          0 :             std::cerr << "Invalid order element !";
     335 [ #  # ][ #  # ]:          0 :             std::cerr << order << std::endl;
     336                 :          0 :             std::exit( -1 );
     337                 :            :         }
     338         [ +  + ]:       6498 :         if( order == 1 )
     339                 :            :         {
     340                 :       4315 :             seen_one = 1;
     341                 :       4315 :             count_right++;
     342         [ +  + ]:       4315 :             if( first_right )
     343                 :            :             {
     344 [ +  - ][ +  - ]:        188 :                 right_box   = i->myBox;
     345                 :        188 :                 first_right = false;
     346                 :            :             }
     347                 :            :             else
     348                 :            :             {
     349 [ +  - ][ +  - ]:       4127 :                 right_box.update( i->myBox );
     350                 :            :             }
     351 [ +  - ][ +  - ]:       4315 :             if( !right_box.intersects_box( i->myBox ) )
                 [ -  + ]
     352                 :            :             {
     353 [ #  # ][ #  # ]:          0 :                 if( !issue ) { std::cerr << "Bounding right box issue!" << std::endl; }
                 [ #  # ]
     354                 :          0 :                 issue = true;
     355                 :            :             }
     356                 :            :         }
     357         [ +  + ]:       6498 :         if( order == 0 )
     358                 :            :         {
     359                 :       2183 :             count_left++;
     360         [ +  + ]:       2183 :             if( first_left )
     361                 :            :             {
     362 [ +  - ][ +  - ]:        188 :                 left_box   = i->myBox;
     363                 :        188 :                 first_left = false;
     364                 :            :             }
     365                 :            :             else
     366                 :            :             {
     367 [ +  - ][ +  - ]:       1995 :                 left_box.update( i->myBox );
     368                 :            :             }
     369 [ +  - ][ +  - ]:       2183 :             if( !data.leftBox.intersects_box( i->myBox ) )
                 [ -  + ]
     370                 :            :             {
     371 [ #  # ][ #  # ]:          0 :                 if( !issue ) { std::cerr << "Bounding left box issue!" << std::endl; }
                 [ #  # ]
     372                 :          0 :                 issue = true;
     373                 :            :             }
     374         [ -  + ]:       2183 :             if( seen_one )
     375                 :            :             {
     376 [ #  # ][ #  # ]:          0 :                 std::cerr << "Invalid ordering!" << std::endl;
     377 [ #  # ][ #  # ]:          0 :                 std::cout << ( i - 1 )->myDim << order << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
     378                 :          0 :                 exit( -1 );
     379                 :            :             }
     380                 :            :         }
     381                 :            :     }
     382 [ +  - ][ -  + ]:        188 :     if( !left_box.intersects_box( data.leftBox ) ) std::cout << "left elts do not contain left box" << std::endl;
         [ #  # ][ #  # ]
     383 [ +  - ][ -  + ]:        188 :     if( !data.leftBox.intersects_box( left_box ) ) std::cout << "left box does not contain left elts" << std::endl;
         [ #  # ][ #  # ]
     384 [ +  - ][ -  + ]:        188 :     if( !right_box.intersects_box( data.rightBox ) ) std::cout << "right elts do not contain right box" << std::endl;
         [ #  # ][ #  # ]
     385 [ +  - ][ -  + ]:        188 :     if( !data.rightBox.intersects_box( right_box ) ) std::cout << "right box do not contain right elts" << std::endl;
         [ #  # ][ #  # ]
     386                 :            : 
     387 [ +  - ][ -  + ]:        188 :     if( count_left != data.nl || count_right != data.nr )
     388                 :            :     {
     389 [ #  # ][ #  # ]:          0 :         std::cerr << "counts are off!" << std::endl;
     390 [ #  # ][ #  # ]:          0 :         std::cerr << "total: " << std::distance( begin, end ) << std::endl;
         [ #  # ][ #  # ]
     391 [ #  # ][ #  # ]:          0 :         std::cerr << "Dim: " << data.dim << std::endl;
                 [ #  # ]
     392 [ #  # ][ #  # ]:          0 :         std::cerr << data.Lmax << " , " << data.Rmin << std::endl;
         [ #  # ][ #  # ]
     393 [ #  # ][ #  # ]:          0 :         std::cerr << "Right box: " << std::endl << data.rightBox << "Left box: " << std::endl << data.leftBox;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     394 [ #  # ][ #  # ]:          0 :         std::cerr << "supposed to be: " << data.nl << " " << data.nr << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
     395 [ #  # ][ #  # ]:          0 :         std::cerr << "accountant says: " << count_left << " " << count_right << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
     396                 :          0 :         std::exit( -1 );
     397                 :        188 :     }
     398                 :            : #endif
     399                 :        188 : }
     400                 :            : 
     401                 :        377 : int BVHTree::local_build_tree( std::vector< Node >& tree_nodes, HandleDataVec::iterator begin,
     402                 :            :                                HandleDataVec::iterator end, const int index, const BoundBox& box, const int depth )
     403                 :            : {
     404                 :            : #ifndef NDEBUG
     405 [ +  - ][ +  - ]:       7604 :     for( HandleDataVec::const_iterator i = begin; i != end; ++i )
         [ +  - ][ +  + ]
     406                 :            :     {
     407 [ +  - ][ +  - ]:       7227 :         if( !box.intersects_box( i->myBox, 0 ) )
                 [ -  + ]
     408                 :            :         {
     409 [ #  # ][ #  # ]:          0 :             std::cerr << "depth: " << depth << std::endl;
                 [ #  # ]
     410 [ #  # ][ #  # ]:          0 :             std::cerr << "BB:" << box << "EB:" << i->myBox << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     411                 :          0 :             std::exit( -1 );
     412                 :            :         }
     413                 :            :     }
     414                 :            : #endif
     415                 :            : 
     416                 :        377 :     const unsigned int total_num_elements = std::distance( begin, end );
     417                 :        377 :     tree_nodes[index].box                 = box;
     418                 :            : 
     419                 :            :     // logic for splitting conditions
     420 [ +  + ][ +  - ]:        377 :     if( (int)total_num_elements > maxPerLeaf && depth < maxDepth )
     421                 :            :     {
     422         [ +  - ]:        188 :         SplitData data;
     423         [ +  - ]:        188 :         data.boundingBox = box;
     424         [ +  - ]:        188 :         find_split( begin, end, data );
     425                 :            :         // assign data to node
     426         [ +  - ]:        188 :         tree_nodes[index].Lmax  = data.Lmax;
     427         [ +  - ]:        188 :         tree_nodes[index].Rmin  = data.Rmin;
     428         [ +  - ]:        188 :         tree_nodes[index].dim   = data.dim;
     429         [ +  - ]:        188 :         tree_nodes[index].child = tree_nodes.size();
     430                 :            :         // insert left, right children;
     431 [ +  - ][ +  - ]:        188 :         tree_nodes.push_back( Node() );
     432 [ +  - ][ +  - ]:        188 :         tree_nodes.push_back( Node() );
     433                 :            :         const int left_depth =
     434 [ +  - ][ +  - ]:        188 :             local_build_tree( tree_nodes, begin, begin + data.nl, tree_nodes[index].child, data.leftBox, depth + 1 );
                 [ +  - ]
     435                 :            :         const int right_depth =
     436 [ +  - ][ +  - ]:        188 :             local_build_tree( tree_nodes, begin + data.nl, end, tree_nodes[index].child + 1, data.rightBox, depth + 1 );
                 [ +  - ]
     437         [ +  - ]:        188 :         return std::max( left_depth, right_depth );
     438                 :            :     }
     439                 :            : 
     440                 :        189 :     tree_nodes[index].dim = 3;
     441                 :        189 :     std::copy( begin, end, std::back_inserter( tree_nodes[index].entities ) );
     442                 :        377 :     return depth;
     443                 :            : }
     444                 :            : 
     445                 :          0 : ErrorCode BVHTree::find_point( const std::vector< double >& point, const unsigned int& index, const double iter_tol,
     446                 :            :                                const double inside_tol, std::pair< EntityHandle, CartVect >& result )
     447                 :            : {
     448         [ #  # ]:          0 :     if( index == 0 ) treeStats.numTraversals++;
     449         [ #  # ]:          0 :     const TreeNode& node = myTree[index];
     450                 :          0 :     treeStats.nodesVisited++;
     451         [ #  # ]:          0 :     CartVect params;
     452                 :            :     int is_inside;
     453                 :          0 :     ErrorCode rval = MB_SUCCESS;
     454         [ #  # ]:          0 :     if( node.dim == 3 )
     455                 :            :     {
     456                 :          0 :         treeStats.leavesVisited++;
     457         [ #  # ]:          0 :         Range entities;
     458         [ #  # ]:          0 :         rval = mbImpl->get_entities_by_handle( startSetHandle + index, entities );
     459         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return rval;
     460                 :            : 
     461 [ #  # ][ #  # ]:          0 :         for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
         [ #  # ][ #  # ]
                 [ #  # ]
     462                 :            :         {
     463                 :          0 :             treeStats.traversalLeafObjectTests++;
     464 [ #  # ][ #  # ]:          0 :             myEval->set_ent_handle( *i );
     465 [ #  # ][ #  # ]:          0 :             myEval->reverse_eval( &point[0], iter_tol, inside_tol, params.array(), &is_inside );
                 [ #  # ]
     466         [ #  # ]:          0 :             if( is_inside )
     467                 :            :             {
     468         [ #  # ]:          0 :                 result.first  = *i;
     469                 :          0 :                 result.second = params;
     470                 :          0 :                 return MB_SUCCESS;
     471                 :            :             }
     472                 :            :         }
     473                 :          0 :         result.first = 0;
     474                 :          0 :         return MB_SUCCESS;
     475                 :            :     }
     476                 :            :     // the extra tol here considers the case where
     477                 :            :     // 0 < Rmin - Lmax < 2tol
     478         [ #  # ]:          0 :     std::vector< EntityHandle > children;
     479         [ #  # ]:          0 :     rval = mbImpl->get_child_meshsets( startSetHandle + index, children );
     480 [ #  # ][ #  # ]:          0 :     if( MB_SUCCESS != rval || children.size() != 2 ) return rval;
                 [ #  # ]
     481                 :            : 
     482         [ #  # ]:          0 :     if( ( node.Lmax + iter_tol ) < ( node.Rmin - iter_tol ) )
     483                 :            :     {
     484 [ #  # ][ #  # ]:          0 :         if( point[node.dim] <= ( node.Lmax + iter_tol ) )
     485 [ #  # ][ #  # ]:          0 :             return find_point( point, children[0] - startSetHandle, iter_tol, inside_tol, result );
     486 [ #  # ][ #  # ]:          0 :         else if( point[node.dim] >= ( node.Rmin - iter_tol ) )
     487 [ #  # ][ #  # ]:          0 :             return find_point( point, children[1] - startSetHandle, iter_tol, inside_tol, result );
     488 [ #  # ][ #  # ]:          0 :         result = std::make_pair( 0, CartVect( &point[0] ) );  // point lies in empty space.
         [ #  # ][ #  # ]
     489                 :          0 :         return MB_SUCCESS;
     490                 :            :     }
     491                 :            : 
     492                 :            :     // Boxes overlap
     493                 :            :     // left of Rmin, you must be on the left
     494                 :            :     // we can't be sure about the boundaries since the boxes overlap
     495                 :            :     // this was a typo in the paper which caused pain.
     496 [ #  # ][ #  # ]:          0 :     if( point[node.dim] < ( node.Rmin - iter_tol ) )
     497 [ #  # ][ #  # ]:          0 :         return find_point( point, children[0] - startSetHandle, iter_tol, inside_tol, result );
     498                 :            :     // if you are on the right Lmax, you must be on the right
     499 [ #  # ][ #  # ]:          0 :     else if( point[node.dim] > ( node.Lmax + iter_tol ) )
     500 [ #  # ][ #  # ]:          0 :         return find_point( point, children[1] - startSetHandle, iter_tol, inside_tol, result );
     501                 :            : 
     502                 :            :     /* pg5 of paper
     503                 :            :      * However, instead of always traversing either subtree
     504                 :            :      * first (e.g. left always before right), we first traverse
     505                 :            :      * the subtree whose bounding plane has the larger distance to the
     506                 :            :      * sought point. This results in less overall traversal, and the correct
     507                 :            :      * cell is identified more quickly.
     508                 :            :      */
     509                 :            :     // So far all testing confirms that this 'heuristic' is
     510                 :            :     // significantly slower.
     511                 :            :     // I conjecture this is because it gets improperly
     512                 :            :     // branch predicted..
     513                 :            :     // bool dir = (point[ node.dim] - node.Rmin) <=
     514                 :            :     //                          (node.Lmax - point[ node.dim]);
     515 [ #  # ][ #  # ]:          0 :     find_point( point, children[0] - startSetHandle, iter_tol, inside_tol, result );
     516 [ #  # ][ #  # ]:          0 :     if( result.first == 0 ) { return find_point( point, children[1] - startSetHandle, iter_tol, inside_tol, result ); }
                 [ #  # ]
     517                 :          0 :     return MB_SUCCESS;
     518                 :            : }
     519                 :            : 
     520                 :          0 : EntityHandle BVHTree::bruteforce_find( const double* point, const double iter_tol, const double inside_tol )
     521                 :            : {
     522                 :          0 :     treeStats.numTraversals++;
     523         [ #  # ]:          0 :     CartVect params;
     524         [ #  # ]:          0 :     for( unsigned int i = 0; i < myTree.size(); i++ )
     525                 :            :     {
     526 [ #  # ][ #  # ]:          0 :         if( myTree[i].dim != 3 || !myTree[i].box.contains_point( point, iter_tol ) ) continue;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     527         [ #  # ]:          0 :         if( myEval )
     528                 :            :         {
     529                 :          0 :             EntityHandle entity = 0;
     530                 :          0 :             treeStats.leavesVisited++;
     531                 :            :             ErrorCode rval = myEval->find_containing_entity( startSetHandle + i, point, iter_tol, inside_tol, entity,
     532 [ #  # ][ #  # ]:          0 :                                                              params.array(), &treeStats.traversalLeafObjectTests );
     533         [ #  # ]:          0 :             if( entity )
     534                 :          0 :                 return entity;
     535         [ #  # ]:          0 :             else if( MB_SUCCESS != rval )
     536                 :          0 :                 return 0;
     537                 :            :         }
     538                 :            :         else
     539                 :          0 :             return startSetHandle + i;
     540                 :            :     }
     541                 :          0 :     return 0;
     542                 :            : }
     543                 :            : 
     544                 :      32854 : ErrorCode BVHTree::get_bounding_box( BoundBox& box, EntityHandle* tree_node ) const
     545                 :            : {
     546 [ +  + ][ +  + ]:      32854 :     if( !tree_node || *tree_node == startSetHandle )
     547                 :            :     {
     548                 :       2001 :         box = boundBox;
     549                 :       2001 :         return MB_SUCCESS;
     550                 :            :     }
     551 [ +  - ][ +  - ]:      61706 :     else if( ( tree_node && !startSetHandle ) || *tree_node < startSetHandle ||
           [ +  -  -  + ]
                 [ -  + ]
     552                 :      30853 :              *tree_node - startSetHandle > myTree.size() )
     553                 :          0 :         return MB_FAILURE;
     554                 :            : 
     555                 :      30853 :     box = myTree[*tree_node - startSetHandle].box;
     556                 :      30853 :     return MB_SUCCESS;
     557                 :            : }
     558                 :            : 
     559                 :       2000 : ErrorCode BVHTree::point_search( const double* point, EntityHandle& leaf_out, const double iter_tol,
     560                 :            :                                  const double inside_tol, bool* multiple_leaves, EntityHandle* start_node,
     561                 :            :                                  CartVect* params )
     562                 :            : {
     563                 :       2000 :     treeStats.numTraversals++;
     564                 :            : 
     565         [ -  + ]:       2000 :     EntityHandle this_set = ( start_node ? *start_node : startSetHandle );
     566                 :            :     // convoluted check because the root is different from startSetHandle
     567 [ +  - ][ +  - ]:       2000 :     if( this_set != myRoot && ( this_set < startSetHandle || this_set >= startSetHandle + myTree.size() ) )
         [ -  + ][ -  + ]
     568                 :          0 :         return MB_FAILURE;
     569         [ -  + ]:       2000 :     else if( this_set == myRoot )
     570                 :          0 :         this_set = startSetHandle;
     571                 :            : 
     572         [ +  - ]:       2000 :     std::vector< EntityHandle > candidates,
     573         [ +  - ]:       4000 :         result_list;  // list of subtrees to traverse, and results
     574         [ +  - ]:       2000 :     candidates.push_back( this_set - startSetHandle );
     575                 :            : 
     576         [ +  - ]:       4000 :     BoundBox box;
     577         [ +  + ]:      33853 :     while( !candidates.empty() )
     578                 :            :     {
     579         [ +  - ]:      32853 :         EntityHandle ind = candidates.back();
     580                 :      32853 :         treeStats.nodesVisited++;
     581 [ +  - ][ +  + ]:      32853 :         if( myTree[ind].dim == 3 ) treeStats.leavesVisited++;
     582                 :      32853 :         this_set = startSetHandle + ind;
     583         [ +  - ]:      32853 :         candidates.pop_back();
     584                 :            : 
     585                 :            :         // test box of this node
     586         [ +  - ]:      32853 :         ErrorCode rval = get_bounding_box( box, &this_set );
     587         [ -  + ]:      32853 :         if( MB_SUCCESS != rval ) return rval;
     588 [ +  - ][ +  + ]:      32853 :         if( !box.contains_point( point, iter_tol ) ) continue;
     589                 :            : 
     590                 :            :         // else if not a leaf, test children & put on list
     591 [ +  - ][ +  + ]:      20827 :         else if( myTree[ind].dim != 3 )
     592                 :            :         {
     593 [ +  - ][ +  - ]:      18354 :             candidates.push_back( myTree[ind].child );
     594 [ +  - ][ +  - ]:      18354 :             candidates.push_back( myTree[ind].child + 1 );
     595                 :      18354 :             continue;
     596                 :            :         }
     597 [ +  - ][ +  - ]:       2473 :         else if( myTree[ind].dim == 3 && myEval && params )
         [ +  + ][ +  - ]
                 [ +  + ]
     598                 :            :         {
     599                 :            :             rval = myEval->find_containing_entity( startSetHandle + ind, point, iter_tol, inside_tol, leaf_out,
     600 [ +  - ][ +  - ]:       1142 :                                                    params->array(), &treeStats.traversalLeafObjectTests );
     601 [ +  + ][ -  + ]:       1142 :             if( leaf_out || MB_SUCCESS != rval ) return rval;
     602                 :            :         }
     603                 :            :         else
     604                 :            :         {
     605                 :            :             // leaf node within distance; return in list
     606         [ +  - ]:       1331 :             result_list.push_back( this_set );
     607                 :            :         }
     608                 :            :     }
     609                 :            : 
     610 [ +  - ][ +  - ]:       1000 :     if( !result_list.empty() ) leaf_out = result_list[0];
     611 [ -  + ][ #  # ]:       1000 :     if( multiple_leaves && result_list.size() > 1 ) *multiple_leaves = true;
                 [ -  + ]
     612                 :       3000 :     return MB_SUCCESS;
     613                 :            : }
     614                 :            : 
     615                 :          0 : ErrorCode BVHTree::distance_search( const double from_point[3], const double distance,
     616                 :            :                                     std::vector< EntityHandle >& result_list, const double iter_tol,
     617                 :            :                                     const double inside_tol, std::vector< double >* result_dists,
     618                 :            :                                     std::vector< CartVect >* result_params, EntityHandle* tree_root )
     619                 :            : {
     620                 :            :     // non-NULL root should be in tree
     621                 :            :     // convoluted check because the root is different from startSetHandle
     622         [ #  # ]:          0 :     EntityHandle this_set = ( tree_root ? *tree_root : startSetHandle );
     623 [ #  # ][ #  # ]:          0 :     if( this_set != myRoot && ( this_set < startSetHandle || this_set >= startSetHandle + myTree.size() ) )
         [ #  # ][ #  # ]
     624                 :          0 :         return MB_FAILURE;
     625         [ #  # ]:          0 :     else if( this_set == myRoot )
     626                 :          0 :         this_set = startSetHandle;
     627                 :            : 
     628                 :          0 :     treeStats.numTraversals++;
     629                 :            : 
     630                 :          0 :     const double dist_sqr = distance * distance;
     631         [ #  # ]:          0 :     const CartVect from( from_point );
     632         [ #  # ]:          0 :     std::vector< EntityHandle > candidates;  // list of subtrees to traverse
     633                 :            :                                              // pre-allocate space for default max tree depth
     634         [ #  # ]:          0 :     candidates.reserve( maxDepth );
     635                 :            : 
     636                 :            :     // misc temporary values
     637                 :            :     ErrorCode rval;
     638         [ #  # ]:          0 :     BoundBox box;
     639                 :            : 
     640         [ #  # ]:          0 :     candidates.push_back( this_set - startSetHandle );
     641                 :            : 
     642         [ #  # ]:          0 :     while( !candidates.empty() )
     643                 :            :     {
     644                 :            : 
     645         [ #  # ]:          0 :         EntityHandle ind = candidates.back();
     646                 :          0 :         this_set         = startSetHandle + ind;
     647         [ #  # ]:          0 :         candidates.pop_back();
     648                 :          0 :         treeStats.nodesVisited++;
     649 [ #  # ][ #  # ]:          0 :         if( myTree[ind].dim == 3 ) treeStats.leavesVisited++;
     650                 :            : 
     651                 :            :         // test box of this node
     652         [ #  # ]:          0 :         rval = get_bounding_box( box, &this_set );
     653         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return rval;
     654         [ #  # ]:          0 :         double d_sqr = box.distance_squared( from_point );
     655                 :            : 
     656                 :            :         // if greater than cutoff, continue
     657         [ #  # ]:          0 :         if( d_sqr > dist_sqr ) continue;
     658                 :            : 
     659                 :            :         // else if not a leaf, test children & put on list
     660 [ #  # ][ #  # ]:          0 :         else if( myTree[ind].dim != 3 )
     661                 :            :         {
     662 [ #  # ][ #  # ]:          0 :             candidates.push_back( myTree[ind].child );
     663 [ #  # ][ #  # ]:          0 :             candidates.push_back( myTree[ind].child + 1 );
     664                 :          0 :             continue;
     665                 :            :         }
     666                 :            : 
     667 [ #  # ][ #  # ]:          0 :         if( myEval && result_params )
     668                 :            :         {
     669                 :            :             EntityHandle ent;
     670         [ #  # ]:          0 :             CartVect params;
     671                 :            :             rval = myEval->find_containing_entity( startSetHandle + ind, from_point, iter_tol, inside_tol, ent,
     672 [ #  # ][ #  # ]:          0 :                                                    params.array(), &treeStats.traversalLeafObjectTests );
     673         [ #  # ]:          0 :             if( MB_SUCCESS != rval )
     674                 :          0 :                 return rval;
     675         [ #  # ]:          0 :             else if( ent )
     676                 :            :             {
     677         [ #  # ]:          0 :                 result_list.push_back( ent );
     678         [ #  # ]:          0 :                 result_params->push_back( params );
     679 [ #  # ][ #  # ]:          0 :                 if( result_dists ) result_dists->push_back( 0.0 );
     680                 :          0 :             }
     681                 :            :         }
     682                 :            :         else
     683                 :            :         {
     684                 :            :             // leaf node within distance; return in list
     685         [ #  # ]:          0 :             result_list.push_back( this_set );
     686 [ #  # ][ #  # ]:          0 :             if( result_dists ) result_dists->push_back( sqrt( d_sqr ) );
     687                 :            :         }
     688                 :            :     }
     689                 :            : 
     690                 :          0 :     return MB_SUCCESS;
     691                 :            : }
     692                 :            : 
     693                 :          0 : ErrorCode BVHTree::print_nodes( std::vector< Node >& nodes )
     694                 :            : {
     695                 :            :     int i;
     696                 :          0 :     std::vector< Node >::iterator it;
     697 [ #  # ][ #  # ]:          0 :     for( it = nodes.begin(), i = 0; it != nodes.end(); ++it, i++ )
                 [ #  # ]
     698                 :            :     {
     699 [ #  # ][ #  # ]:          0 :         std::cout << "Node " << i << ": dim = " << it->dim << ", child = " << it->child << ", Lmax/Rmin = " << it->Lmax
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     700 [ #  # ][ #  # ]:          0 :                   << "/" << it->Rmin << ", box = " << it->box << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     701                 :            :     }
     702                 :          0 :     return MB_SUCCESS;
     703                 :            : }
     704                 :            : 
     705                 :          0 : ErrorCode BVHTree::print()
     706                 :            : {
     707                 :            :     int i;
     708                 :          0 :     std::vector< TreeNode >::iterator it;
     709 [ #  # ][ #  # ]:          0 :     for( it = myTree.begin(), i = 0; it != myTree.end(); ++it, i++ )
                 [ #  # ]
     710                 :            :     {
     711 [ #  # ][ #  # ]:          0 :         std::cout << "Node " << i << ": dim = " << it->dim << ", child = " << it->child << ", Lmax/Rmin = " << it->Lmax
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     712 [ #  # ][ #  # ]:          0 :                   << "/" << it->Rmin << ", box = " << it->box << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     713                 :            :     }
     714                 :          0 :     return MB_SUCCESS;
     715                 :            : }
     716                 :            : 
     717 [ +  - ][ +  - ]:          4 : }  // namespace moab

Generated by: LCOV version 1.11