[MOAB-dev] r3522 - in MOAB/trunk: . test/obb

sjackson at cae.wisc.edu sjackson at cae.wisc.edu
Mon Feb 1 17:03:46 CST 2010


Author: sjackson
Date: 2010-02-01 17:03:46 -0600 (Mon, 01 Feb 2010)
New Revision: 3522

Modified:
   MOAB/trunk/MBOrientedBoxTreeTool.cpp
   MOAB/trunk/MBOrientedBoxTreeTool.hpp
   MOAB/trunk/test/obb/obb_test.cpp
   MOAB/trunk/test/obb/obb_time.cpp
Log:
Add traversal statistics to OBB tree tool.

* All OBB tree queries now take an optional accumulator
  structure into which information about the performance
  of tree traversal is stored.
* These statistics are now gathered in the obb_test
  program and printed if at least one -v argument given.
* These statistics are optionally gathered in the
  obb_time program when -p argument given.
* Very simple testing with obb_time suggests that the
  performance impact of gathering traversal statistics
  is low (<5%).  Statistics are not gathered when not
  requested, so this performance loss is opt-in.
* Three OBB queries (sphere_intersect_triangles and both
  variants of closest_to_location) did not previously keep
  track of traversal depth, a value needed to compute these
  statistics.  They are now changed to track depth.  I have not
  tested the performance impact of this change, but I expect
  it to be trivial.

Modified: MOAB/trunk/MBOrientedBoxTreeTool.cpp
===================================================================
--- MOAB/trunk/MBOrientedBoxTreeTool.cpp	2010-02-01 23:03:45 UTC (rev 3521)
+++ MOAB/trunk/MBOrientedBoxTreeTool.cpp	2010-02-01 23:03:46 UTC (rev 3522)
@@ -470,19 +470,27 @@
 
 struct Data { MBEntityHandle set; int depth; };
 MBErrorCode MBOrientedBoxTreeTool::preorder_traverse( MBEntityHandle set,
-                                                      Op& operation )
+                                                      Op& operation, 
+                                                      TrvStats* accum )
 {
   MBErrorCode rval;
   std::vector<MBEntityHandle> children;
   std::vector<Data> the_stack;
   Data data = { set, 0 };
   the_stack.push_back( data );
+  int max_depth = -1;
   
   while (!the_stack.empty())
   {
     data = the_stack.back();
     the_stack.pop_back();
     
+    // increment traversal statistics
+    if( accum ){
+      accum->increment( data.depth );
+      max_depth = std::max( max_depth, data.depth );
+    }
+
     bool descend = true;
     rval = operation.visit( data.set, data.depth, descend );
     if (MB_SUCCESS != rval)
@@ -511,17 +519,30 @@
       return MB_MULTIPLE_ENTITIES_FOUND;
   }
   
+  if( accum ){
+    accum->end_traversal( max_depth );
+  }
+
   return MB_SUCCESS;
 }
 
 /********************** General Sphere/Triangle Intersection ***************/
 
+struct MBOBBTreeSITFrame { 
+  MBOBBTreeSITFrame( MBEntityHandle n, MBEntityHandle s, int dp )
+    : node(n), surf(s), depth(dp) {}
+  MBEntityHandle node;
+  MBEntityHandle surf;
+  int depth;
+};
+
 MBErrorCode MBOrientedBoxTreeTool::sphere_intersect_triangles( 
                                         const double* center_v,
                                         double radius,
                                         MBEntityHandle tree_root,
                                         std::vector<MBEntityHandle>& facets_out,
-                                        std::vector<MBEntityHandle>* sets_out )
+                                        std::vector<MBEntityHandle>* sets_out, 
+                                        TrvStats* accum )
 {
   const double radsqr = radius * radius;
   MBOrientedBox b;
@@ -539,13 +560,25 @@
   std::vector<MBEntityHandle>::const_iterator t;
 #endif
   
-  std::vector<MBEntityHandle> stack, children;
-  stack.reserve(60);
-  stack.push_back(tree_root);
-  stack.push_back(0);
+  std::vector<MBOBBTreeSITFrame> stack;
+  std::vector<MBEntityHandle> children;
+  stack.reserve(30);
+  stack.push_back( MBOBBTreeSITFrame( tree_root, 0, 0 ) );
+
+  int max_depth = -1;
+
   while (!stack.empty()) {
-    MBEntityHandle surf = stack.back(); stack.pop_back();
-    MBEntityHandle node = stack.back(); stack.pop_back();
+    MBEntityHandle surf = stack.back().surf; 
+    MBEntityHandle node = stack.back().node;
+    int current_depth   = stack.back().depth;
+    stack.pop_back();
+    
+      // increment traversal statistics.  
+    if( accum ){
+      accum->increment( current_depth );
+      max_depth = std::max( max_depth, current_depth );
+    }
+
     if (!surf && sets_out) {
       rval = get_moab_instance()->get_entities_by_type( node, MBENTITYSET, sets );
       if (!sets.empty())
@@ -569,10 +602,8 @@
       return rval;
     if (!children.empty()) {
       assert(children.size() == 2);
-      stack.push_back( children[0] );
-      stack.push_back( surf );
-      stack.push_back( children[1] );
-      stack.push_back( surf );
+      stack.push_back( MBOBBTreeSITFrame( children[0], surf, current_depth + 1 ) );
+      stack.push_back( MBOBBTreeSITFrame( children[1], surf, current_depth + 1 ) );
       continue;
     }
     
@@ -619,6 +650,10 @@
       }
     }
   }
+
+  if( accum ){
+    accum->end_traversal( max_depth );
+  }
   
   return MB_SUCCESS;
 }
@@ -737,12 +772,13 @@
                           double tolerance,
                           const double ray_point[3],
                           const double unit_ray_dir[3],
-                          const double* ray_length )
+                          const double* ray_length, 
+                          TrvStats* accum )
 {
   MBRange boxes;
   MBErrorCode rval;
   
-  rval = ray_intersect_boxes( boxes, root_set, tolerance, ray_point, unit_ray_dir, ray_length );
+  rval = ray_intersect_boxes( boxes, root_set, tolerance, ray_point, unit_ray_dir, ray_length, accum );
   if (MB_SUCCESS != rval)
     return rval;
     
@@ -755,10 +791,11 @@
                           double tolerance,
                           const double ray_point[3],
                           const double unit_ray_dir[3],
-                          const double* ray_length )
+                          const double* ray_length, 
+                          TrvStats* accum )
 {
   RayIntersector op( this, ray_point, unit_ray_dir, ray_length, tolerance, boxes_out );
-  return preorder_traverse( root_set, op );
+  return preorder_traverse( root_set, op, accum );
 }
 
 MBErrorCode RayIntersector::visit( MBEntityHandle node,
@@ -984,11 +1021,12 @@
                                     unsigned min_tolerace_intersections,
                                     const double ray_point[3],
                                     const double unit_ray_dir[3],
-                                    const double* ray_length )
+                                    const double* ray_length, 
+                                    TrvStats* accum )
 {
   RayIntersectSets op( this, ray_point, unit_ray_dir, ray_length, tolerance, 
-                       min_tolerace_intersections, distances_out, sets_out, facets_out );
-  return preorder_traverse( root_set, op );
+                       min_tolerace_intersections, distances_out, sets_out, facets_out ); 
+  return preorder_traverse( root_set, op, accum );
 }
 
 
@@ -996,11 +1034,12 @@
 /********************** Closest Point code ***************/
 
 struct MBOBBTreeCPFrame {
-  MBOBBTreeCPFrame( double d, MBEntityHandle n, MBEntityHandle s )
-    : dist_sqr(d), node(n), mset(s) {}
+  MBOBBTreeCPFrame( double d, MBEntityHandle n, MBEntityHandle s, int dp )
+    : dist_sqr(d), node(n), mset(s), depth(dp) {}
   double dist_sqr;
   MBEntityHandle node;
   MBEntityHandle mset;
+  int depth;
 };
 
 MBErrorCode MBOrientedBoxTreeTool::closest_to_location( 
@@ -1008,7 +1047,8 @@
                                      MBEntityHandle root,
                                      double* point_out,
                                      MBEntityHandle& facet_out,
-                                     MBEntityHandle* set_out ) 
+                                     MBEntityHandle* set_out,
+                                     TrvStats* accum ) 
 {
   MBErrorCode rval;
   const MBCartVect loc( point );
@@ -1019,8 +1059,9 @@
   std::vector<MBEntityHandle> children(2);
   std::vector<double> coords;
   std::vector<MBOBBTreeCPFrame> stack;
-    
-  stack.push_back( MBOBBTreeCPFrame(0.0, root, current_set) );
+  int max_depth = -1;
+
+  stack.push_back( MBOBBTreeCPFrame(0.0, root, current_set, 0) );
   
   while( !stack.empty() ) {
 
@@ -1028,12 +1069,19 @@
     MBEntityHandle node = stack.back().node;
     double dist_sqr = stack.back().dist_sqr;
     current_set = stack.back().mset;
+    int current_depth = stack.back().depth;
     stack.pop_back();
 
       // If current best result is closer than the box, skip this tree node.
     if (dist_sqr > smallest_dist_sqr)
       continue;
 
+      // increment traversal statistics.  
+    if( accum ){
+      accum->increment( current_depth );
+      max_depth = std::max( max_depth, current_depth );
+    }
+
       // Check if this node has a set associated with it
     if (set_out && !current_set) {
       sets.clear();
@@ -1076,12 +1124,12 @@
       
         // push children on tree such that closer one is on top
       if (dsqr1 < dsqr2) {
-        stack.push_back( MBOBBTreeCPFrame(dsqr2, children[1], current_set ) );
-        stack.push_back( MBOBBTreeCPFrame(dsqr1, children[0], current_set ) );
+        stack.push_back( MBOBBTreeCPFrame(dsqr2, children[1], current_set, current_depth+1 ) );
+        stack.push_back( MBOBBTreeCPFrame(dsqr1, children[0], current_set, current_depth+1 ) );
       }
       else {
-        stack.push_back( MBOBBTreeCPFrame(dsqr1, children[0], current_set ) );
-        stack.push_back( MBOBBTreeCPFrame(dsqr2, children[1], current_set ) );
+        stack.push_back( MBOBBTreeCPFrame(dsqr1, children[0], current_set, current_depth+1 ) );
+        stack.push_back( MBOBBTreeCPFrame(dsqr2, children[1], current_set, current_depth+1 ) );
       }
     }
     else { // LEAF NODE
@@ -1120,6 +1168,10 @@
       }
     } // LEAF NODE
   }
+
+  if( accum ){
+    accum->end_traversal( max_depth );
+  }
   
   return MB_SUCCESS;
 }
@@ -1128,7 +1180,8 @@
                                      MBEntityHandle root,
                                      double tolerance,
                                      std::vector<MBEntityHandle>& facets_out,
-                                     std::vector<MBEntityHandle>* sets_out )
+                                     std::vector<MBEntityHandle>* sets_out, 
+                                     TrvStats* accum )
 {
   MBErrorCode rval;
   const MBCartVect loc( point );
@@ -1140,8 +1193,9 @@
   std::vector<MBEntityHandle> children(2);
   std::vector<double> coords;
   std::vector<MBOBBTreeCPFrame> stack;
-    
-  stack.push_back( MBOBBTreeCPFrame(0.0, root, current_set) );
+  int max_depth = -1;
+
+  stack.push_back( MBOBBTreeCPFrame(0.0, root, current_set, 0) );
   
   while( !stack.empty() ) {
 
@@ -1149,12 +1203,19 @@
     MBEntityHandle node = stack.back().node;
     double dist_sqr = stack.back().dist_sqr;
     current_set = stack.back().mset;
+    int current_depth = stack.back().depth;
     stack.pop_back();
 
       // If current best result is closer than the box, skip this tree node.
     if (dist_sqr > smallest_dist_sqr + tolerance)
       continue;
 
+      // increment traversal statistics.  
+    if( accum ){
+      accum->increment( current_depth );
+      max_depth = std::max( max_depth, current_depth );
+    }
+
       // Check if this node has a set associated with it
     if (sets_out && !current_set) {
       sets.clear();
@@ -1197,12 +1258,12 @@
       
         // push children on tree such that closer one is on top
       if (dsqr1 < dsqr2) {
-        stack.push_back( MBOBBTreeCPFrame(dsqr2, children[1], current_set ) );
-        stack.push_back( MBOBBTreeCPFrame(dsqr1, children[0], current_set ) );
+        stack.push_back( MBOBBTreeCPFrame(dsqr2, children[1], current_set, current_depth+1 ) );
+        stack.push_back( MBOBBTreeCPFrame(dsqr1, children[0], current_set, current_depth+1 ) );
       }
       else {
-        stack.push_back( MBOBBTreeCPFrame(dsqr1, children[0], current_set ) );
-        stack.push_back( MBOBBTreeCPFrame(dsqr2, children[1], current_set ) );
+        stack.push_back( MBOBBTreeCPFrame(dsqr1, children[0], current_set, current_depth+1 ) );
+        stack.push_back( MBOBBTreeCPFrame(dsqr2, children[1], current_set, current_depth+1 ) );
       }
     }
     else { // LEAF NODE
@@ -1255,6 +1316,10 @@
       }
     } // LEAF NODE
   }
+
+  if( accum ){
+    accum->end_traversal( max_depth );
+  }
   
   return MB_SUCCESS;
 }
@@ -1527,6 +1592,55 @@
 }
 
 
+/********************* Traversal Metrics Code  **************************/
+
+void MBOrientedBoxTreeTool::TrvStats::reset(){
+  nodes_visited_count.clear();
+  traversals_ended_count.clear();
+}
+
+void MBOrientedBoxTreeTool::TrvStats::increment( unsigned depth ){
+
+  while( nodes_visited_count.size() <= depth ){
+    nodes_visited_count.push_back(0);
+    traversals_ended_count.push_back(0);
+  }
+  nodes_visited_count[depth] += 1;
+}
+
+void MBOrientedBoxTreeTool::TrvStats::end_traversal( unsigned depth ){
+  // assume safe depth, because increment is always called on a given 
+  // tree level first
+  traversals_ended_count[depth] += 1;
+}
+
+void MBOrientedBoxTreeTool::TrvStats::print( std::ostream& str ) const {
+
+  const std::string h1 = "OBBTree Depth";
+  const std::string h2 = " - NodesVisited";
+  const std::string h3 = " - TraversalsEnded";
+
+  str << h1 << h2 << h3 << std::endl;
+
+  unsigned num_visited = 0, num_traversals = 0;
+  for( unsigned i = 0; i < traversals_ended_count.size(); ++i){
+
+    num_visited    += nodes_visited_count[i];
+    num_traversals += traversals_ended_count[i];
+   
+    str << std::setw(h1.length()) << i 
+        << std::setw(h2.length()) << nodes_visited_count[i] 
+        << std::setw(h3.length()) << traversals_ended_count[i] 
+        << std::endl;
+  }
+  
+  str << std::setw(h1.length()) << "---- Totals:" 
+      << std::setw(h2.length()) << num_visited 
+      << std::setw(h3.length()) << num_traversals 
+      << std::endl;
+
+}
+
 /********************** Tree Statistics Code ****************************/
 
 

Modified: MOAB/trunk/MBOrientedBoxTreeTool.hpp
===================================================================
--- MOAB/trunk/MBOrientedBoxTreeTool.hpp	2010-02-01 23:03:45 UTC (rev 3521)
+++ MOAB/trunk/MBOrientedBoxTreeTool.hpp	2010-02-01 23:03:46 UTC (rev 3522)
@@ -25,6 +25,7 @@
 
 #include <iosfwd>
 #include <list>
+#include <vector>
 
 class MBRange;
 class MBOrientedBox;
@@ -120,6 +121,43 @@
                             MBEntityHandle& root_set_out,
                             const Settings* settings = 0 );
 
+    /**\brief Traversal statistics structure
+     *
+     * Structure to accumulate statistics on traversal performance. Passed optionally
+     * to query functions, this structure contains the count of nodes visited at each
+     * level in a tree, and the count of traversals that ended at each level.
+     * One TrvStats structure can be used with multiple OBB trees or multiple queries,
+     * or used on only a single tree or a single query.
+     *
+     * Note that these traversal statistics are not related to the stats() query below,
+     * which calculates static information about a tree.  These statistics relate
+     * to a tree's dynamic behavior on particular operations.
+     */
+    class TrvStats{ 
+      public:
+
+        //! return counts of nodes visited, indexed by tree depth
+        const std::vector< unsigned >& nodes_visited() const ;
+        //! return counts of traversals ended, indexed by tree depth
+        const std::vector< unsigned >& traversals_ended() const ;
+        //! reset all counters on this structure
+        void reset();
+        //! print the contents of this structure to given stream
+        void print( std::ostream& str ) const ;
+
+      private: 
+      
+        std::vector< unsigned > nodes_visited_count;
+        std::vector< unsigned > traversals_ended_count;
+        
+        void increment( unsigned depth );
+        void end_traversal( unsigned depth );
+
+      friend class MBOrientedBoxTreeTool;
+
+    };
+
+
     /**\brief Intersect a ray with the triangles contained within the tree
      *
      * Intersect a ray with the triangles contained in the tree and return
@@ -136,7 +174,8 @@
                                          double tolerance,
                                          const double ray_point[3],
                                          const double unit_ray_dir[3],
-                                         const double* ray_length = 0 );
+                                         const double* ray_length = 0,
+                                         TrvStats* accum = 0 );
     
     /**\brief Intersect ray with tree
      *
@@ -153,7 +192,8 @@
                                      double tolerance,
                                      const double ray_point[3],
                                      const double unit_ray_dir[3],
-                                     const double* ray_length = 0 );
+                                     const double* ray_length = 0,
+                                     TrvStats* accum = 0 );
 
     /**\brief Intersect ray with triangles contained in passed MBENTITYSETs */
     MBErrorCode ray_intersect_triangles( 
@@ -194,7 +234,8 @@
                                     unsigned min_tolerace_intersections,
                                     const double ray_point[3],
                                     const double unit_ray_dir[3],
-                                    const double* ray_length = 0 );
+                                    const double* ray_length = 0,
+                                    TrvStats* accum = 0 );
     
     /**\brief Find closest surface, facet in surface, and location on facet
      *
@@ -209,7 +250,8 @@
                                      MBEntityHandle tree_root,
                                      double* point_out,
                                      MBEntityHandle& facet_out,
-                                     MBEntityHandle* set_out = 0);
+                                     MBEntityHandle* set_out = 0, 
+                                     TrvStats* accum = 0 );
                                      
     /**\brief Find closest facet(s) to input position.
      *
@@ -222,7 +264,8 @@
                                      MBEntityHandle tree_root,
                                      double tolerance,
                                      std::vector<MBEntityHandle>& facets_out,
-                                     std::vector<MBEntityHandle>* sets_out = 0 );
+                                     std::vector<MBEntityHandle>* sets_out = 0, 
+                                     TrvStats* accum = 0 );
     
     /**\brief Find facets intersected by a sphere 
      *
@@ -239,7 +282,8 @@
                                         double radius,
                                         MBEntityHandle tree_root,
                                         std::vector<MBEntityHandle>& facets_out,
-                                        std::vector<MBEntityHandle>* sets_out = 0 );
+                                        std::vector<MBEntityHandle>* sets_out = 0, 
+                                        TrvStats* accum = 0 );
     
     /**\brief Get oriented box at node in tree
      *
@@ -342,7 +386,8 @@
      * traversal will not descend to the children of the current node.
      */
     MBErrorCode preorder_traverse( MBEntityHandle root_set,
-                                   Op& operation );
+                                   Op& operation, 
+                                   TrvStats* accum = 0 );
   
     MBInterface* get_moab_instance() const { return instance; }
   

Modified: MOAB/trunk/test/obb/obb_test.cpp
===================================================================
--- MOAB/trunk/test/obb/obb_test.cpp	2010-02-01 23:03:45 UTC (rev 3521)
+++ MOAB/trunk/test/obb/obb_test.cpp	2010-02-01 23:03:46 UTC (rev 3522)
@@ -920,6 +920,8 @@
    { "skew miss",                 0, box.center + box.dimensions(),          box.dimensions() * box.axis[2] }
    };
   
+  MBOrientedBoxTreeTool::TrvStats stats;
+
   bool result = true;
   const size_t num_test = sizeof(tests)/sizeof(tests[0]);
   for (size_t i = 0; i < num_test; ++i) {
@@ -928,7 +930,7 @@
       std::cout << "  " << tests[i].description << " " << tests[i].point << " " << tests[i].direction << std::endl;
     
     std::vector<double> intersections;
-    rval = tool.ray_intersect_triangles( intersections, root_set, tolerance, tests[i].point.array(), tests[i].direction.array(), 0 );
+    rval = tool.ray_intersect_triangles( intersections, root_set, tolerance, tests[i].point.array(), tests[i].direction.array(), 0, &stats );
     if (MB_SUCCESS != rval) {
       if (verbosity)
         std::cout << "  Call to MBOrientedBoxTreeTool::ray_intersect_triangles failed." << std::endl;
@@ -955,7 +957,7 @@
     const int NUM_NON_TOL_INT = 1;
     std::vector<double> intersections2;
     std::vector<MBEntityHandle> surf_handles, facet_handles;
-    rval = tool.ray_intersect_sets( intersections2, surf_handles, facet_handles, root_set, tolerance, NUM_NON_TOL_INT, tests[i].point.array(), tests[i].direction.array(), 0 );
+    rval = tool.ray_intersect_sets( intersections2, surf_handles, facet_handles, root_set, tolerance, NUM_NON_TOL_INT, tests[i].point.array(), tests[i].direction.array(), 0, &stats );
     if (MB_SUCCESS != rval) {
       if (verbosity)
         std::cout << "  Call to MBOrientedBoxTreeTool::ray_intersect_sets failed." << std::endl;
@@ -1027,7 +1029,7 @@
     if (!haveSurfTree) {
       MBRange leaves;
       std::vector<double> intersections;
-      rval = tool.ray_intersect_boxes( leaves, root_set, tolerance, rays[i].array(), rays[i+1].array(), 0 );
+      rval = tool.ray_intersect_boxes( leaves, root_set, tolerance, rays[i].array(), rays[i+1].array(), 0, &stats );
       if (MB_SUCCESS != rval) {
         std::cout << "FAILED" << std::endl;
         result = false;
@@ -1077,7 +1079,7 @@
     else {
       std::vector<double> intersections;
       std::vector<MBEntityHandle> surfaces, facets;
-      rval = tool.ray_intersect_sets( intersections, surfaces, facets, root_set, tolerance, 1000, rays[i].array(), rays[i+1].array(), 0 );
+      rval = tool.ray_intersect_sets( intersections, surfaces, facets, root_set, tolerance, 1000, rays[i].array(), rays[i+1].array(), 0, &stats );
       if (MB_SUCCESS != rval) {
         std::cout << "FAILED" << std::endl;
         result = false;
@@ -1143,6 +1145,11 @@
     }
   }
   
+  if( verbosity > 1 ){
+    std::cout << "Traversal statistics for ray fire tests: " << std::endl;
+    stats.print(std::cout);
+  }
+
   return result;
 }
 
@@ -1252,6 +1259,9 @@
                                    MBEntityHandle root_set,
                                    bool have_surface_tree )
 {
+  if (verbosity > 1)
+    std::cout << "beginning closest point tests" << std::endl;
+
   MBErrorCode rval;
   MBInterface* moab = tool.get_moab_instance();
   MBEntityHandle set;
@@ -1265,6 +1275,8 @@
     if (verbosity) std::cerr << "Invalid tree in do_closest_point_test\n";
     return false;
   }
+
+  MBOrientedBoxTreeTool::TrvStats stats;
   
     // chose some points to test
   MBCartVect points[] = { box.center + box.scaled_axis(0),
@@ -1297,7 +1309,8 @@
                                      root_set,
                                      t_result.array(),
                                      t_tri,
-                                     set_ptr );
+                                     set_ptr,
+                                     &stats );
     if (MB_SUCCESS != rval) {
       if (verbosity)
         std::cout << "MBOrientedBoxTreeTool:: closest_to_location( " << points[i] << " ) FAILED!" << std::endl;
@@ -1342,6 +1355,11 @@
       continue;
     }
   }
+
+  if( verbosity > 1 ){
+    std::cout << "Traversal statistics for closest point tests: " << std::endl;
+    stats.print(std::cout);
+  }
   
   return result;
 }

Modified: MOAB/trunk/test/obb/obb_time.cpp
===================================================================
--- MOAB/trunk/test/obb/obb_time.cpp	2010-02-01 23:03:45 UTC (rev 3521)
+++ MOAB/trunk/test/obb/obb_time.cpp	2010-02-01 23:03:46 UTC (rev 3522)
@@ -20,6 +20,7 @@
       << "  -i - Specify total intersecting rays to fire." << std::endl
       << "       Zero implies unbounded. Default: " << NUM_XSCT << std::endl
       << "  -s - Use set-based tree." << std::endl
+      << "  -p - Measure and report traversal performance statistics" << std::endl
       << "  The input file should be generated using the '-s'" << std::endl
       << "  option with 'obb_test'" << std::endl;
   exit(1);
@@ -77,6 +78,7 @@
 int num_xsct = NUM_XSCT;
 const char* filename = 0;
 bool do_sets = false;
+bool do_trv_stats = false;
 
 // global to make accessable to signal handler
 int rays = 0, xsct = 0, gen = 0;
@@ -131,6 +133,9 @@
     else if (!strcmp( argv[i], "-s")) {
       do_sets = true;
     }
+    else if (!strcmp( argv[i], "-p")) {
+      do_trv_stats = true;
+    }
     else if (filename) {
       std::cerr << "Invalid options or multiple file names specified." << std::endl;
         usage();
@@ -160,6 +165,11 @@
     std::cerr << "Corrupt tree.  Cannot get box for root node." << std::endl;
     return 3;
   }
+
+  MBOrientedBoxTreeTool::TrvStats* stats = NULL;
+  if( do_trv_stats ){
+    stats = new MBOrientedBoxTreeTool::TrvStats;
+  }
   
   const unsigned cached = 1000;
   std::vector<double> intersections;
@@ -198,10 +208,10 @@
     if (do_sets) {
       sets.clear();
       facets.clear();
-      rval = tool.ray_intersect_sets( intersections, sets, facets, root, 1e-6, 1, point.array(), dir.array() );
+      rval = tool.ray_intersect_sets( intersections, sets, facets, root, 1e-6, 1, point.array(), dir.array(), 0,  stats );
     }
     else {
-      rval = tool.ray_intersect_triangles( intersections, root, 1e-6, point.array(), dir.array() );
+      rval = tool.ray_intersect_triangles( intersections, root, 1e-6, point.array(), dir.array(), 0, stats );
     }
     if (MB_SUCCESS != rval) {
       std::cerr << "Rayfire #" << rays << " failed." << std::endl;
@@ -225,6 +235,11 @@
             << xsct << " intersecting fires" << std::endl
             << (double)t/CLOCKS_PER_SEC << " seconds" << std::endl;
   
+  if( do_trv_stats ){
+    std::cout << "Traversal statistics: " << std::endl;
+    stats->print( std::cout );
+  }
+
   return 0;
 }
 



More information about the moab-dev mailing list