MOAB: Mesh Oriented datABase  (version 5.5.0)
TreeValidator Class Reference
+ Inheritance diagram for TreeValidator:
+ Collaboration diagram for TreeValidator:

Public Member Functions

 TreeValidator (Interface *instance_ptr, OrientedBoxTreeTool *tool_ptr, bool print_errors, std::ostream &str, double tol, bool surfs, OrientedBoxTreeTool::Settings s)
 
bool is_valid () const
 
virtual ErrorCode visit (EntityHandle node, int depth, bool &descend)
 Visit a node in the tree during a traversal. More...
 
virtual ErrorCode leaf (EntityHandle)
 Process a leaf node during tree traversal. More...
 
- Public Member Functions inherited from moab::OrientedBoxTreeTool::Op
virtual ~Op ()
 

Public Attributes

unsigned entity_count
 
unsigned loose_box_count
 
unsigned child_outside_count
 
unsigned entity_outside_count
 
unsigned num_entities_outside
 
unsigned non_ortho_count
 
unsigned error_count
 
unsigned empty_leaf_count
 
unsigned non_empty_non_leaf_count
 
unsigned entity_invalid_count
 
unsigned unsorted_axis_count
 
unsigned non_unit_count
 
unsigned duplicate_entity_count
 
unsigned bad_outer_radius_count
 
unsigned missing_surface_count
 
unsigned multiple_surface_count
 
std::set< EntityHandleseen
 
int surface_depth
 
EntityHandle surface_handle
 

Private Member Functions

void print (EntityHandle handle, const char *string)
 
ErrorCode error (EntityHandle handle, const char *string)
 

Private Attributes

Interface *const instance
 
OrientedBoxTreeTool *const tool
 
const bool printing
 
const double epsilon
 
bool surfaces
 
std::ostream & stream
 
OrientedBoxTreeTool::Settings settings
 

Detailed Description

Definition at line 314 of file obb_test.cpp.

Constructor & Destructor Documentation

◆ TreeValidator()

TreeValidator::TreeValidator ( Interface instance_ptr,
OrientedBoxTreeTool tool_ptr,
bool  print_errors,
std::ostream &  str,
double  tol,
bool  surfs,
OrientedBoxTreeTool::Settings  s 
)
inline

Definition at line 359 of file obb_test.cpp.

366  : instance( instance_ptr ), tool( tool_ptr ), printing( print_errors ), epsilon( tol ), surfaces( surfs ),
367  stream( str ), settings( s ), entity_count( 0 ), loose_box_count( 0 ), child_outside_count( 0 ),
372  {
373  }

Member Function Documentation

◆ error()

ErrorCode TreeValidator::error ( EntityHandle  handle,
const char *  string 
)
inlineprivate

Definition at line 330 of file obb_test.cpp.

331  {
332  ++error_count;
333  print( handle, string );
334  return MB_SUCCESS;
335  }

References error_count, and MB_SUCCESS.

◆ is_valid()

◆ leaf()

virtual ErrorCode TreeValidator::leaf ( EntityHandle  node)
inlinevirtual

Process a leaf node during tree traversal.

Implements moab::OrientedBoxTreeTool::Op.

Definition at line 385 of file obb_test.cpp.

386  {
387  return MB_SUCCESS;
388  }

References MB_SUCCESS.

◆ print()

void TreeValidator::print ( EntityHandle  handle,
const char *  string 
)
inlineprivate

Definition at line 325 of file obb_test.cpp.

326  {
327  if( printing ) stream << instance->id_from_handle( handle ) << ": " << string << std::endl;
328  }

References moab::Interface::id_from_handle().

◆ visit()

ErrorCode TreeValidator::visit ( EntityHandle  node,
int  depth,
bool &  descend 
)
virtual

Visit a node in the tree during a traversal.

This method is called for each node in the tree visited during a pre-order traversal.

Parameters
nodeThe EntityHandle for the entity set for the tree node.
depthThe current depth in the tree.
descendOutput: if false, traversal will skip children of the current node, or if the current node is a leaf, the 'leaf' method will not be called.

Implements moab::OrientedBoxTreeTool::Op.

Definition at line 391 of file obb_test.cpp.

392 {
393  ErrorCode rval;
394  descend = true;
395 
396  Range contents;
397  rval = instance->get_entities_by_handle( node, contents );
398  if( MB_SUCCESS != rval ) return error( node, "Error getting contents of tree node. Corrupt tree?" );
399  entity_count += contents.size();
400 
401  if( surfaces )
402  {
403  // if no longer in subtree for previous surface, clear
404  if( depth <= surface_depth ) surface_depth = -1;
405 
406  EntityHandle surface = 0;
407  Range::iterator surf_iter = contents.lower_bound( MBENTITYSET );
408  if( surf_iter != contents.end() )
409  {
410  surface = *surf_iter;
411  contents.erase( surf_iter );
412  }
413 
414  if( surface )
415  {
416  if( surface_depth >= 0 )
417  {
419  print( node, "Multiple surfaces in encountered in same subtree." );
420  }
421  else
422  {
423  surface_depth = depth;
424  surface_handle = surface;
425  }
426  }
427  }
428 
429  std::vector< EntityHandle > children;
431  if( MB_SUCCESS != rval || ( !children.empty() && children.size() != 2 ) )
432  return error( node, "Error getting children. Corrupt tree?" );
433 
435  rval = tool->box( node, box );
436  if( MB_SUCCESS != rval ) return error( node, "Error getting oriented box from tree node. Corrupt tree?" );
437 
438  if( children.empty() && contents.empty() )
439  {
441  print( node, "Empty leaf node.\n" );
442  }
443  else if( !children.empty() && !contents.empty() )
444  {
446  print( node, "Non-leaf node is not empty." );
447  }
448 
449  if( surfaces && children.empty() && surface_depth < 0 )
450  {
452  print( node, "Reached leaf node w/out encountering any surface set." );
453  }
454 
455  double dot_epsilon = epsilon * ( box.axis( 0 ) + box.axis( 1 ) + box.axis( 2 ) ).length();
456  if( box.axis( 0 ) % box.axis( 1 ) > dot_epsilon || box.axis( 0 ) % box.axis( 2 ) > dot_epsilon ||
457  box.axis( 1 ) % box.axis( 2 ) > dot_epsilon )
458  {
459  ++non_ortho_count;
460  print( node, "Box axes are not orthogonal" );
461  }
462 
463  if( !children.empty() )
464  {
465  for( int i = 0; i < 2; ++i )
466  {
467  OrientedBox other_box;
468  rval = tool->box( children[i], other_box );
469  if( MB_SUCCESS != rval )
470  return error( children[i], " Error getting oriented box from tree node. Corrupt tree?" );
471  // else if (!box.contained( other_box, epsilon )) {
472  // ++child_outside_count;
473  // print( children[i], "Parent box does not contain child box." );
474  // char string[64];
475  // sprintf(string, " Volume ratio is %f", other_box.volume()/box.volume() );
476  // print( children [i], string );
477  // }
478  else
479  {
480  double vol_ratio = other_box.volume() / box.volume();
481  if( vol_ratio > 2.0 )
482  {
483  char string[64];
484  sprintf( string, "child/parent volume ratio is %f", vol_ratio );
485  print( children[i], string );
486  sprintf( string, " child/parent area ratio is %f", other_box.area() / box.area() );
487  print( children[i], string );
488  }
489  }
490  }
491  }
492 
493  bool bad_element = false;
494  bool bad_element_handle = false;
495  bool bad_element_conn = false;
496  bool duplicate_element = false;
497  int num_outside = 0;
498  bool boundary[6] = { false, false, false, false, false, false };
499  for( Range::iterator it = contents.begin(); it != contents.end(); ++it )
500  {
501  EntityType type = instance->type_from_handle( *it );
502  int dim = CN::Dimension( type );
503  if( dim != 2 )
504  {
505  bad_element = true;
506  continue;
507  }
508 
509  const EntityHandle* conn;
510  int conn_len;
511  rval = instance->get_connectivity( *it, conn, conn_len );
512  if( MB_SUCCESS != rval )
513  {
514  bad_element_handle = true;
515  continue;
516  }
517 
518  std::vector< CartVect > coords( conn_len );
519  rval = instance->get_coords( conn, conn_len, coords[0].array() );
520  if( MB_SUCCESS != rval )
521  {
522  bad_element_conn = true;
523  continue;
524  }
525 
526  bool outside = false;
527  for( std::vector< CartVect >::iterator j = coords.begin(); j != coords.end(); ++j )
528  {
529  if( !box.contained( *j, epsilon ) )
530  outside = true;
531  else
532  for( int d = 0; d < 3; ++d )
533  {
534 #if MB_ORIENTED_BOX_UNIT_VECTORS
535  double n = box.axis( d ) % ( *j - box.center );
536  if( fabs( n - box.length[d] ) <= epsilon ) boundary[2 * d] = true;
537  if( fabs( n + box.length[d] ) <= epsilon ) boundary[2 * d + 1] = true;
538 #else
539  double ln = box.axis( d ).length();
540  CartVect v1 = *j - box.center - box.axis[d];
541  CartVect v2 = *j - box.center + box.axis[d];
542  if( fabs( v1 % box.axis[d] ) <= ln * epsilon ) boundary[2 * d] = true;
543  if( fabs( v2 % box.axis[d] ) <= ln * epsilon ) boundary[2 * d + 1] = true;
544 #endif
545  }
546  }
547  if( outside ) ++num_outside;
548 
549  if( !seen.insert( *it ).second )
550  {
551  duplicate_element = true;
553  }
554  }
555 
556  CartVect alength( box.axis( 0 ).length(), box.axis( 1 ).length(), box.axis( 2 ).length() );
557 #if MB_ORIENTED_BOX_UNIT_VECTORS
558  CartVect length = box.length;
559 #else
560  CartVect length = alength;
561 #endif
562 
563  if( length[0] > length[1] || length[0] > length[2] || length[1] > length[2] )
564  {
566  print( node, "Box axes are not ordered from shortest to longest." );
567  }
568 
569 #if MB_ORIENTED_BOX_UNIT_VECTORS
570  if( fabs( alength[0] - 1.0 ) > epsilon || fabs( alength[1] - 1.0 ) > epsilon || fabs( alength[2] - 1.0 ) > epsilon )
571  {
572  ++non_unit_count;
573  print( node, "Box axes are not unit vectors." );
574  }
575 #endif
576 
577 #if MB_ORIENTED_BOX_OUTER_RADIUS
578  if( fabs( length.length() - box.radius ) > tolerance )
579  {
581  print( node, "Box has incorrect outer radius." );
582  }
583 #endif
584 
585  if( depth + 1 < settings.max_depth && contents.size() > (unsigned)( 4 * settings.max_leaf_entities ) )
586  {
587  char string[64];
588  sprintf( string, "leaf at depth %d with %u entities", depth, (unsigned)contents.size() );
589  print( node, string );
590  }
591 
592  bool all_boundaries = true;
593  for( int f = 0; f < 6; ++f )
594  all_boundaries = all_boundaries && boundary[f];
595 
596  if( bad_element )
597  {
599  print( node, "Set contained an entity with an inappropriate dimension." );
600  }
601  if( bad_element_handle )
602  {
603  ++error_count;
604  print( node, "Error querying face contained in set." );
605  }
606  if( bad_element_conn )
607  {
608  ++error_count;
609  print( node, "Error querying connectivity of element." );
610  }
611  if( duplicate_element )
612  {
613  print( node, "Elements occur in multiple leaves of tree." );
614  }
615  if( num_outside > 0 )
616  {
618  num_entities_outside += num_outside;
619  if( printing )
620  stream << instance->id_from_handle( node ) << ": " << num_outside << " elements outside box." << std::endl;
621  }
622  else if( !all_boundaries && !contents.empty() )
623  {
624  ++loose_box_count;
625  print( node, "Box does not fit contained elements tightly." );
626  }
627 
628  return MB_SUCCESS;
629 }

References moab::OrientedBox::area(), moab::Range::begin(), box(), children, dim, moab::CN::Dimension(), moab::Range::empty(), moab::Range::end(), moab::Range::erase(), moab::error(), error_count, ErrorCode, length(), moab::Range::lower_bound(), moab::OrientedBoxTreeTool::Settings::max_depth, moab::OrientedBoxTreeTool::Settings::max_leaf_entities, MB_SUCCESS, MBENTITYSET, settings, moab::Range::size(), moab::tolerance, and moab::OrientedBox::volume().

Member Data Documentation

◆ bad_outer_radius_count

unsigned TreeValidator::bad_outer_radius_count

Definition at line 352 of file obb_test.cpp.

Referenced by do_file().

◆ child_outside_count

unsigned TreeValidator::child_outside_count

Definition at line 341 of file obb_test.cpp.

Referenced by do_file().

◆ duplicate_entity_count

unsigned TreeValidator::duplicate_entity_count

Definition at line 351 of file obb_test.cpp.

Referenced by do_file().

◆ empty_leaf_count

unsigned TreeValidator::empty_leaf_count

Definition at line 346 of file obb_test.cpp.

Referenced by do_file().

◆ entity_count

unsigned TreeValidator::entity_count

Definition at line 338 of file obb_test.cpp.

Referenced by do_file().

◆ entity_invalid_count

unsigned TreeValidator::entity_invalid_count

Definition at line 348 of file obb_test.cpp.

Referenced by do_file().

◆ entity_outside_count

unsigned TreeValidator::entity_outside_count

Definition at line 342 of file obb_test.cpp.

Referenced by do_file().

◆ epsilon

const double TreeValidator::epsilon
private

Definition at line 320 of file obb_test.cpp.

◆ error_count

unsigned TreeValidator::error_count

Definition at line 345 of file obb_test.cpp.

Referenced by do_file().

◆ instance

Interface* const TreeValidator::instance
private

Definition at line 317 of file obb_test.cpp.

◆ loose_box_count

unsigned TreeValidator::loose_box_count

Definition at line 340 of file obb_test.cpp.

Referenced by do_file().

◆ missing_surface_count

unsigned TreeValidator::missing_surface_count

Definition at line 353 of file obb_test.cpp.

Referenced by do_file().

◆ multiple_surface_count

unsigned TreeValidator::multiple_surface_count

Definition at line 354 of file obb_test.cpp.

Referenced by do_file().

◆ non_empty_non_leaf_count

unsigned TreeValidator::non_empty_non_leaf_count

Definition at line 347 of file obb_test.cpp.

Referenced by do_file().

◆ non_ortho_count

unsigned TreeValidator::non_ortho_count

Definition at line 344 of file obb_test.cpp.

Referenced by do_file().

◆ non_unit_count

unsigned TreeValidator::non_unit_count

Definition at line 350 of file obb_test.cpp.

Referenced by do_file().

◆ num_entities_outside

unsigned TreeValidator::num_entities_outside

Definition at line 343 of file obb_test.cpp.

Referenced by do_file().

◆ printing

const bool TreeValidator::printing
private

Definition at line 319 of file obb_test.cpp.

◆ seen

std::set< EntityHandle > TreeValidator::seen

Definition at line 355 of file obb_test.cpp.

◆ settings

OrientedBoxTreeTool::Settings TreeValidator::settings
private

Definition at line 323 of file obb_test.cpp.

◆ stream

std::ostream& TreeValidator::stream
private

Definition at line 322 of file obb_test.cpp.

◆ surface_depth

int TreeValidator::surface_depth

Definition at line 356 of file obb_test.cpp.

◆ surface_handle

EntityHandle TreeValidator::surface_handle

Definition at line 357 of file obb_test.cpp.

◆ surfaces

bool TreeValidator::surfaces
private

Definition at line 321 of file obb_test.cpp.

◆ tool

OrientedBoxTreeTool* const TreeValidator::tool
private

Definition at line 318 of file obb_test.cpp.

◆ unsorted_axis_count

unsigned TreeValidator::unsorted_axis_count

Definition at line 349 of file obb_test.cpp.

Referenced by do_file().


The documentation for this class was generated from the following file: