|
MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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. | |
| virtual ErrorCode | leaf (EntityHandle) |
| Process a leaf node during tree traversal. | |
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< EntityHandle > | seen |
| 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 |
Definition at line 314 of file obb_test.cpp.
| 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.
: instance( instance_ptr ), tool( tool_ptr ), printing( print_errors ), epsilon( tol ), surfaces( surfs ), stream( str ), settings( s ), entity_count( 0 ), loose_box_count( 0 ), child_outside_count( 0 ), entity_outside_count( 0 ), num_entities_outside( 0 ), non_ortho_count( 0 ), error_count( 0 ), empty_leaf_count( 0 ), non_empty_non_leaf_count( 0 ), entity_invalid_count( 0 ), unsorted_axis_count( 0 ), non_unit_count( 0 ), duplicate_entity_count( 0 ), bad_outer_radius_count( 0 ), missing_surface_count( 0 ), multiple_surface_count( 0 ), surface_depth( -1 ), surface_handle( 0 ) { }
| ErrorCode TreeValidator::error | ( | EntityHandle | handle, |
| const char * | string | ||
| ) | [inline, private] |
Definition at line 330 of file obb_test.cpp.
References error_count, and MB_SUCCESS.
{
++error_count;
print( handle, string );
return MB_SUCCESS;
}
| bool TreeValidator::is_valid | ( | ) | const [inline] |
Definition at line 375 of file obb_test.cpp.
References error_count.
Referenced by do_file().
{
return 0 == loose_box_count + child_outside_count + entity_outside_count + num_entities_outside +
non_ortho_count + error_count + empty_leaf_count + non_empty_non_leaf_count +
entity_invalid_count + unsorted_axis_count + non_unit_count + duplicate_entity_count +
bad_outer_radius_count + missing_surface_count + multiple_surface_count;
}
| virtual ErrorCode TreeValidator::leaf | ( | EntityHandle | node | ) | [inline, virtual] |
Process a leaf node during tree traversal.
Implements moab::OrientedBoxTreeTool::Op.
Definition at line 385 of file obb_test.cpp.
References MB_SUCCESS.
{
return MB_SUCCESS;
}
| void TreeValidator::print | ( | EntityHandle | handle, |
| const char * | string | ||
| ) | [inline, private] |
Definition at line 325 of file obb_test.cpp.
{
if( printing ) stream << instance->id_from_handle( handle ) << ": " << string << std::endl;
}
| 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.
| node | The EntityHandle for the entity set for the tree node. |
| depth | The current depth in the tree. |
| descend | Output: 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.
References moab::OrientedBox::area(), moab::OrientedBox::axis(), moab::Range::begin(), box(), moab::OrientedBox::center, children, moab::OrientedBox::contained(), dim, moab::CN::Dimension(), moab::Range::empty(), moab::Range::end(), moab::Range::erase(), moab::error(), error_count, ErrorCode, length(), moab::OrientedBox::length, moab::CartVect::length(), moab::Range::lower_bound(), moab::OrientedBoxTreeTool::Settings::max_depth, moab::OrientedBoxTreeTool::Settings::max_leaf_entities, MB_SUCCESS, MBENTITYSET, moab::OrientedBox::radius, settings, moab::Range::size(), moab::tolerance, and moab::OrientedBox::volume().
{
ErrorCode rval;
descend = true;
Range contents;
rval = instance->get_entities_by_handle( node, contents );
if( MB_SUCCESS != rval ) return error( node, "Error getting contents of tree node. Corrupt tree?" );
entity_count += contents.size();
if( surfaces )
{
// if no longer in subtree for previous surface, clear
if( depth <= surface_depth ) surface_depth = -1;
EntityHandle surface = 0;
Range::iterator surf_iter = contents.lower_bound( MBENTITYSET );
if( surf_iter != contents.end() )
{
surface = *surf_iter;
contents.erase( surf_iter );
}
if( surface )
{
if( surface_depth >= 0 )
{
++multiple_surface_count;
print( node, "Multiple surfaces in encountered in same subtree." );
}
else
{
surface_depth = depth;
surface_handle = surface;
}
}
}
std::vector< EntityHandle > children;
rval = tool->get_moab_instance()->get_child_meshsets( node, children );
if( MB_SUCCESS != rval || ( !children.empty() && children.size() != 2 ) )
return error( node, "Error getting children. Corrupt tree?" );
OrientedBox box;
rval = tool->box( node, box );
if( MB_SUCCESS != rval ) return error( node, "Error getting oriented box from tree node. Corrupt tree?" );
if( children.empty() && contents.empty() )
{
++empty_leaf_count;
print( node, "Empty leaf node.\n" );
}
else if( !children.empty() && !contents.empty() )
{
++non_empty_non_leaf_count;
print( node, "Non-leaf node is not empty." );
}
if( surfaces && children.empty() && surface_depth < 0 )
{
++missing_surface_count;
print( node, "Reached leaf node w/out encountering any surface set." );
}
double dot_epsilon = epsilon * ( box.axis( 0 ) + box.axis( 1 ) + box.axis( 2 ) ).length();
if( box.axis( 0 ) % box.axis( 1 ) > dot_epsilon || box.axis( 0 ) % box.axis( 2 ) > dot_epsilon ||
box.axis( 1 ) % box.axis( 2 ) > dot_epsilon )
{
++non_ortho_count;
print( node, "Box axes are not orthogonal" );
}
if( !children.empty() )
{
for( int i = 0; i < 2; ++i )
{
OrientedBox other_box;
rval = tool->box( children[i], other_box );
if( MB_SUCCESS != rval )
return error( children[i], " Error getting oriented box from tree node. Corrupt tree?" );
// else if (!box.contained( other_box, epsilon )) {
// ++child_outside_count;
// print( children[i], "Parent box does not contain child box." );
// char string[64];
// sprintf(string, " Volume ratio is %f", other_box.volume()/box.volume() );
// print( children [i], string );
// }
else
{
double vol_ratio = other_box.volume() / box.volume();
if( vol_ratio > 2.0 )
{
char string[64];
sprintf( string, "child/parent volume ratio is %f", vol_ratio );
print( children[i], string );
sprintf( string, " child/parent area ratio is %f", other_box.area() / box.area() );
print( children[i], string );
}
}
}
}
bool bad_element = false;
bool bad_element_handle = false;
bool bad_element_conn = false;
bool duplicate_element = false;
int num_outside = 0;
bool boundary[6] = { false, false, false, false, false, false };
for( Range::iterator it = contents.begin(); it != contents.end(); ++it )
{
EntityType type = instance->type_from_handle( *it );
int dim = CN::Dimension( type );
if( dim != 2 )
{
bad_element = true;
continue;
}
const EntityHandle* conn;
int conn_len;
rval = instance->get_connectivity( *it, conn, conn_len );
if( MB_SUCCESS != rval )
{
bad_element_handle = true;
continue;
}
std::vector< CartVect > coords( conn_len );
rval = instance->get_coords( conn, conn_len, coords[0].array() );
if( MB_SUCCESS != rval )
{
bad_element_conn = true;
continue;
}
bool outside = false;
for( std::vector< CartVect >::iterator j = coords.begin(); j != coords.end(); ++j )
{
if( !box.contained( *j, epsilon ) )
outside = true;
else
for( int d = 0; d < 3; ++d )
{
#if MB_ORIENTED_BOX_UNIT_VECTORS
double n = box.axis( d ) % ( *j - box.center );
if( fabs( n - box.length[d] ) <= epsilon ) boundary[2 * d] = true;
if( fabs( n + box.length[d] ) <= epsilon ) boundary[2 * d + 1] = true;
#else
double ln = box.axis( d ).length();
CartVect v1 = *j - box.center - box.axis[d];
CartVect v2 = *j - box.center + box.axis[d];
if( fabs( v1 % box.axis[d] ) <= ln * epsilon ) boundary[2 * d] = true;
if( fabs( v2 % box.axis[d] ) <= ln * epsilon ) boundary[2 * d + 1] = true;
#endif
}
}
if( outside ) ++num_outside;
if( !seen.insert( *it ).second )
{
duplicate_element = true;
++duplicate_entity_count;
}
}
CartVect alength( box.axis( 0 ).length(), box.axis( 1 ).length(), box.axis( 2 ).length() );
#if MB_ORIENTED_BOX_UNIT_VECTORS
CartVect length = box.length;
#else
CartVect length = alength;
#endif
if( length[0] > length[1] || length[0] > length[2] || length[1] > length[2] )
{
++unsorted_axis_count;
print( node, "Box axes are not ordered from shortest to longest." );
}
#if MB_ORIENTED_BOX_UNIT_VECTORS
if( fabs( alength[0] - 1.0 ) > epsilon || fabs( alength[1] - 1.0 ) > epsilon || fabs( alength[2] - 1.0 ) > epsilon )
{
++non_unit_count;
print( node, "Box axes are not unit vectors." );
}
#endif
#if MB_ORIENTED_BOX_OUTER_RADIUS
if( fabs( length.length() - box.radius ) > tolerance )
{
++bad_outer_radius_count;
print( node, "Box has incorrect outer radius." );
}
#endif
if( depth + 1 < settings.max_depth && contents.size() > (unsigned)( 4 * settings.max_leaf_entities ) )
{
char string[64];
sprintf( string, "leaf at depth %d with %u entities", depth, (unsigned)contents.size() );
print( node, string );
}
bool all_boundaries = true;
for( int f = 0; f < 6; ++f )
all_boundaries = all_boundaries && boundary[f];
if( bad_element )
{
++entity_invalid_count;
print( node, "Set contained an entity with an inappropriate dimension." );
}
if( bad_element_handle )
{
++error_count;
print( node, "Error querying face contained in set." );
}
if( bad_element_conn )
{
++error_count;
print( node, "Error querying connectivity of element." );
}
if( duplicate_element )
{
print( node, "Elements occur in multiple leaves of tree." );
}
if( num_outside > 0 )
{
++entity_outside_count;
num_entities_outside += num_outside;
if( printing )
stream << instance->id_from_handle( node ) << ": " << num_outside << " elements outside box." << std::endl;
}
else if( !all_boundaries && !contents.empty() )
{
++loose_box_count;
print( node, "Box does not fit contained elements tightly." );
}
return MB_SUCCESS;
}
Definition at line 352 of file obb_test.cpp.
Referenced by do_file().
| unsigned TreeValidator::child_outside_count |
Definition at line 341 of file obb_test.cpp.
Referenced by do_file().
Definition at line 351 of file obb_test.cpp.
Referenced by do_file().
| unsigned TreeValidator::empty_leaf_count |
Definition at line 346 of file obb_test.cpp.
Referenced by do_file().
| unsigned TreeValidator::entity_count |
Definition at line 338 of file obb_test.cpp.
Referenced by do_file().
| unsigned TreeValidator::entity_invalid_count |
Definition at line 348 of file obb_test.cpp.
Referenced by do_file().
| unsigned TreeValidator::entity_outside_count |
Definition at line 342 of file obb_test.cpp.
Referenced by do_file().
const double TreeValidator::epsilon [private] |
Definition at line 320 of file obb_test.cpp.
| unsigned TreeValidator::error_count |
Definition at line 345 of file obb_test.cpp.
Referenced by do_file().
Interface* const TreeValidator::instance [private] |
Definition at line 317 of file obb_test.cpp.
| unsigned TreeValidator::loose_box_count |
Definition at line 340 of file obb_test.cpp.
Referenced by do_file().
| unsigned TreeValidator::missing_surface_count |
Definition at line 353 of file obb_test.cpp.
Referenced by do_file().
Definition at line 354 of file obb_test.cpp.
Referenced by do_file().
Definition at line 347 of file obb_test.cpp.
Referenced by do_file().
| unsigned TreeValidator::non_ortho_count |
Definition at line 344 of file obb_test.cpp.
Referenced by do_file().
| unsigned TreeValidator::non_unit_count |
Definition at line 350 of file obb_test.cpp.
Referenced by do_file().
| unsigned TreeValidator::num_entities_outside |
Definition at line 343 of file obb_test.cpp.
Referenced by do_file().
const bool TreeValidator::printing [private] |
Definition at line 319 of file obb_test.cpp.
| std::set< EntityHandle > TreeValidator::seen |
Definition at line 355 of file obb_test.cpp.
Definition at line 323 of file obb_test.cpp.
std::ostream& TreeValidator::stream [private] |
Definition at line 322 of file obb_test.cpp.
Definition at line 356 of file obb_test.cpp.
Definition at line 357 of file obb_test.cpp.
bool TreeValidator::surfaces [private] |
Definition at line 321 of file obb_test.cpp.
OrientedBoxTreeTool* const TreeValidator::tool [private] |
Definition at line 318 of file obb_test.cpp.
| unsigned TreeValidator::unsorted_axis_count |
Definition at line 349 of file obb_test.cpp.
Referenced by do_file().