|
MOAB: Mesh Oriented datABase
(version 5.4.1)
|
#include "moab/Core.hpp"#include "moab/Range.hpp"#include "moab/OrientedBoxTreeTool.hpp"#include "moab/OrientedBox.hpp"#include "MBTagConventions.hpp"#include "moab/GeomUtil.hpp"#include "moab/CN.hpp"#include "../TestUtil.hpp"#include <iostream>#include <sstream>#include <cstdlib>#include <limits>#include <cstdio>#include <set>#include <map>
Include dependency graph for obb_test.cpp:Go to the source code of this file.
Classes | |
| struct | RayTest |
| class | TreeValidator |
| class | CubitWriter |
| class | VtkWriter |
Typedefs | |
| typedef std::map< std::string, std::vector< RayTest > >::iterator | ray_test_itr |
Enumerations | |
| enum | TriOption { DISABLE, ENABLE, AUTO } |
Functions | |
| void | initialize_default_files () |
| static void | usage (const char *error, const char *opt) |
| static const char * | get_option (int &i, int argc, char *argv[]) |
| static int | get_int_option (int &i, int argc, char *argv[]) |
| static double | get_double_option (int &i, int argc, char *argv[]) |
| static bool | do_file (const char *filename) |
| static void | parse_ray (int &i, int argc, char *argv[]) |
| int | main (int argc, char *argv[]) |
| static bool | do_ray_fire_test (OrientedBoxTreeTool &tool, EntityHandle root_set, const char *filename, bool have_surface_tree) |
| static bool | do_closest_point_test (OrientedBoxTreeTool &tool, EntityHandle root_set, bool have_surface_tree) |
| static ErrorCode | save_tree (Interface *instance, const char *filename, EntityHandle tree_root) |
| static void | count_non_tol (std::vector< double > intersections, int &non_tol_count, double &non_tol_dist) |
| static bool | check_ray_intersect_tris (OrientedBoxTreeTool &tool, EntityHandle root_set, RayTest &test, int &non_tol_count, double &non_tol_dist, OrientedBoxTreeTool::TrvStats &stats) |
| static bool | check_ray_intersect_sets (OrientedBoxTreeTool &tool, EntityHandle root_set, RayTest &test, int &non_tol_count, double &non_tol_dist, OrientedBoxTreeTool::TrvStats &stats) |
| static ErrorCode | tri_coords (Interface *moab, EntityHandle tri, CartVect coords[3]) |
| static ErrorCode | closest_point_in_triangles (Interface *moab, const CartVect &to_pos, CartVect &result_pos, EntityHandle &result_tri) |
| static bool | tri_in_set (Interface *moab, EntityHandle set, EntityHandle tri) |
Variables | |
| static const char * | NAME = "obb_test" |
| std::map< std::string, std::vector< RayTest > > | default_files_tests |
| static int | verbosity = 1 |
| static OrientedBoxTreeTool::Settings | settings |
| static double | tolerance = 1e-6 |
| static bool | write_cubit = false |
| static bool | write_vtk = false |
| static bool | write_ray_vtk = false |
| static std::vector< CartVect > | rays |
| static const char * | save_file_name = 0 |
| static TriOption | surfTree = AUTO |
| typedef std::map< std::string, std::vector< RayTest > >::iterator ray_test_itr |
Definition at line 34 of file obb_test.cpp.
| enum TriOption |
Definition at line 149 of file obb_test.cpp.
| static bool check_ray_intersect_sets | ( | OrientedBoxTreeTool & | tool, |
| EntityHandle | root_set, | ||
| RayTest & | test, | ||
| int & | non_tol_count, | ||
| double & | non_tol_dist, | ||
| OrientedBoxTreeTool::TrvStats & | stats | ||
| ) | [static] |
Definition at line 1014 of file obb_test.cpp.
References moab::CartVect::array(), count_non_tol(), RayTest::direction, ErrorCode, MB_SUCCESS, RayTest::point, moab::OrientedBoxTreeTool::ray_intersect_sets(), moab::tolerance, and verbosity.
Referenced by do_ray_fire_test().
{
ErrorCode rval;
bool result = true;
non_tol_dist = std::numeric_limits< double >::max();
non_tol_count = 0;
const int NUM_NON_TOL_INT = 1;
std::vector< double > intersections;
std::vector< EntityHandle > surfs;
std::vector< EntityHandle > facets;
OrientedBoxTreeTool::IntersectSearchWindow search_win;
OrientedBoxTreeTool::IntRegCtxt int_reg_ctxt;
rval = tool.ray_intersect_sets( intersections, surfs, facets, root_set, tolerance, test.point.array(),
test.direction.array(), search_win, int_reg_ctxt, &stats );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cout << " Call to OrientedBoxTreeTool::ray_intersect_sets failed." << std::endl;
result = false;
}
else
{
if( surfs.size() != intersections.size() )
{
if( verbosity ) std::cout << " ray_intersect_sets did not return sets for all intersections." << std::endl;
result = false;
}
count_non_tol( intersections, non_tol_count, non_tol_dist );
if( non_tol_count > NUM_NON_TOL_INT )
{
if( verbosity )
std::cout << " Requested " << NUM_NON_TOL_INT << "intersections "
<< " beyond tolerance. Got " << non_tol_count << std::endl;
result = false;
}
}
return result;
}
| static bool check_ray_intersect_tris | ( | OrientedBoxTreeTool & | tool, |
| EntityHandle | root_set, | ||
| RayTest & | test, | ||
| int & | non_tol_count, | ||
| double & | non_tol_dist, | ||
| OrientedBoxTreeTool::TrvStats & | stats | ||
| ) | [static] |
Definition at line 970 of file obb_test.cpp.
References moab::CartVect::array(), count_non_tol(), RayTest::description, RayTest::direction, ErrorCode, RayTest::expected_hits, MB_SUCCESS, RayTest::point, moab::OrientedBoxTreeTool::ray_intersect_triangles(), moab::tolerance, and verbosity.
Referenced by do_ray_fire_test().
{
ErrorCode rval;
bool result = true;
non_tol_dist = std::numeric_limits< double >::max();
non_tol_count = 0;
std::vector< double > intersections;
std::vector< EntityHandle > facets;
rval = tool.ray_intersect_triangles( intersections, facets, root_set, tolerance, test.point.array(),
test.direction.array(), 0, &stats );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cout << " Call to OrientedBoxTreeTool::ray_intersect_triangles failed." << std::endl;
result = false;
}
else
{
if( intersections.size() != test.expected_hits )
{
if( verbosity > 2 )
std::cout << " Expected " << test.expected_hits << " and got " << intersections.size()
<< " hits for ray fire of " << test.description << std::endl;
if( verbosity > 3 )
{
for( unsigned j = 0; j < intersections.size(); ++j )
std::cout << " " << intersections[j];
std::cout << std::endl;
}
result = false;
}
count_non_tol( intersections, non_tol_count, non_tol_dist );
}
return result;
}
| static ErrorCode closest_point_in_triangles | ( | Interface * | moab, |
| const CartVect & | to_pos, | ||
| CartVect & | result_pos, | ||
| EntityHandle & | result_tri | ||
| ) | [static] |
Definition at line 1331 of file obb_test.cpp.
References moab::Range::begin(), moab::GeomUtil::closest_location_on_tri(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Interface::get_entities_by_type(), MB_SUCCESS, MBTRI, and tri_coords().
Referenced by do_closest_point_test().
{
ErrorCode rval;
Range triangles;
rval = moab->get_entities_by_type( 0, MBTRI, triangles );
if( MB_SUCCESS != rval ) return rval;
if( triangles.empty() ) return MB_FAILURE;
Range::iterator i = triangles.begin();
CartVect coords[3];
rval = tri_coords( moab, *i, coords );
if( MB_SUCCESS != rval ) return rval;
result_tri = *i;
GeomUtil::closest_location_on_tri( to_pos, coords, result_pos );
CartVect diff = to_pos - result_pos;
double shortest_dist_sqr = diff % diff;
for( ++i; i != triangles.end(); ++i )
{
rval = tri_coords( moab, *i, coords );
if( MB_SUCCESS != rval ) return rval;
CartVect pos;
GeomUtil::closest_location_on_tri( to_pos, coords, pos );
diff = to_pos - pos;
double dsqr = diff % diff;
if( dsqr < shortest_dist_sqr )
{
shortest_dist_sqr = dsqr;
result_pos = pos;
result_tri = *i;
}
}
return MB_SUCCESS;
}
| static void count_non_tol | ( | std::vector< double > | intersections, |
| int & | non_tol_count, | ||
| double & | non_tol_dist | ||
| ) | [static] |
Definition at line 957 of file obb_test.cpp.
References moab::tolerance.
Referenced by check_ray_intersect_sets(), and check_ray_intersect_tris().
{
for( size_t i = 0; i < intersections.size(); ++i )
{
if( intersections[i] > tolerance )
{
++non_tol_count;
if( intersections[i] < non_tol_dist ) non_tol_dist = intersections[i];
}
}
}
| static bool do_closest_point_test | ( | OrientedBoxTreeTool & | tool, |
| EntityHandle | root_set, | ||
| bool | have_surface_tree | ||
| ) | [static] |
Definition at line 1381 of file obb_test.cpp.
References moab::CartVect::array(), moab::OrientedBoxTreeTool::box(), box(), moab::OrientedBox::center, moab::GeomUtil::closest_location_on_tri(), closest_point_in_triangles(), moab::OrientedBoxTreeTool::closest_to_location(), ErrorCode, moab::OrientedBoxTreeTool::get_moab_instance(), moab::CartVect::length(), MB_SUCCESS, moab::OrientedBoxTreeTool::TrvStats::print(), moab::OrientedBox::scaled_axis(), moab::tolerance, tri_coords(), tri_in_set(), and verbosity.
Referenced by do_file().
{
if( verbosity > 1 ) std::cout << "beginning closest point tests" << std::endl;
ErrorCode rval;
Interface* moab = tool.get_moab_instance();
EntityHandle set;
EntityHandle* set_ptr = have_surface_tree ? &set : 0;
bool result = true;
// get root box
OrientedBox box;
rval = tool.box( root_set, box );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cerr << "Invalid tree in do_closest_point_test\n";
return false;
}
OrientedBoxTreeTool::TrvStats stats;
// chose some points to test
CartVect points[] = { box.center + box.scaled_axis( 0 ), box.center + 2 * box.scaled_axis( 1 ),
box.center + 0.5 * box.scaled_axis( 2 ),
box.center + -2 * box.scaled_axis( 0 ) + -2 * box.scaled_axis( 1 ) +
-2 * box.scaled_axis( 2 ),
CartVect( 100, 100, 100 ) };
const int num_pts = sizeof( points ) / sizeof( points[0] );
// test each point
for( int i = 0; i < num_pts; ++i )
{
if( verbosity >= 3 ) std::cout << "Evaluating closest point to " << points[i] << std::endl;
CartVect n_result, t_result;
EntityHandle n_tri = 0, t_tri;
// find closest point the slow way
rval = closest_point_in_triangles( moab, points[i], n_result, n_tri );
if( MB_SUCCESS != rval )
{
std::cerr << "Internal MOAB error in do_closest_point_test" << std::endl;
result = false;
continue;
}
// find closest point using tree
rval = tool.closest_to_location( points[i].array(), root_set, t_result.array(), t_tri, set_ptr, &stats );
if( MB_SUCCESS != rval )
{
if( verbosity )
std::cout << "OrientedBoxTreeTool:: closest_to_location( " << points[i] << " ) FAILED!" << std::endl;
result = false;
continue;
}
CartVect diff = t_result - n_result;
if( diff.length() > tolerance )
{
if( verbosity )
std::cout << "Closest point to " << points[i] << " INCORRECT! (" << t_result << " != " << n_result
<< ")" << std::endl;
result = false;
continue;
}
if( t_tri != n_tri )
{
// if result point is triangle, then OK because
// already tested that it is the same location
// as the expected value. We just have a case where
// the point was on an edge or vertex.
CartVect coords[3];
CartVect diff1( 1, 1, 1 );
rval = tri_coords( moab, t_tri, coords );
if( MB_SUCCESS == rval )
{
GeomUtil::closest_location_on_tri( points[i], coords, n_result );
diff1 = n_result - t_result;
}
if( ( diff1 % diff1 ) > tolerance )
{
if( verbosity )
std::cout << "Triangle closest to " << points[i] << " INCORRECT! (" << t_tri << " != " << n_tri
<< ")" << std::endl;
result = false;
continue;
}
}
if( set_ptr && !tri_in_set( moab, *set_ptr, t_tri ) )
{
if( verbosity ) std::cout << "Surface closest to " << points[i] << " INCORRECT!" << std::endl;
result = false;
continue;
}
}
if( verbosity > 1 )
{
std::cout << "Traversal statistics for closest point tests: " << std::endl;
stats.print( std::cout );
}
return result;
}
| static bool do_file | ( | const char * | filename | ) | [static] |
Definition at line 731 of file obb_test.cpp.
References moab::Interface::add_entities(), TreeValidator::bad_outer_radius_count, moab::Range::begin(), moab::OrientedBoxTreeTool::build(), TreeValidator::child_outside_count, moab::Range::clear(), moab::OrientedBoxTreeTool::delete_tree(), dim, DISABLE, do_closest_point_test(), do_ray_fire_test(), TreeValidator::duplicate_entity_count, moab::Range::empty(), TreeValidator::empty_leaf_count, ENABLE, moab::Range::end(), entities, TreeValidator::entity_count, TreeValidator::entity_invalid_count, TreeValidator::entity_outside_count, TreeValidator::error_count, ErrorCode, filename, GEOM_DIMENSION_TAG_NAME, moab::Interface::get_entities_by_dimension(), moab::Interface::get_entities_by_type_and_tag(), iface, moab::Range::insert(), TreeValidator::is_valid(), moab::OrientedBoxTreeTool::join_trees(), moab::Interface::load_mesh(), TreeValidator::loose_box_count, MB_ENTITY_NOT_FOUND, MB_SUCCESS, MB_TAG_NOT_FOUND, MB_TYPE_INTEGER, MBENTITYSET, moab::Range::merge(), TreeValidator::missing_surface_count, TreeValidator::multiple_surface_count, TreeValidator::non_empty_non_leaf_count, TreeValidator::non_ortho_count, TreeValidator::non_unit_count, TreeValidator::num_entities_outside, moab::OrientedBoxTreeTool::preorder_traverse(), moab::OrientedBoxTreeTool::print(), save_file_name, save_tree(), settings, moab::Range::size(), moab::OrientedBoxTreeTool::stats(), surfTree, moab::Interface::tag_get_handle(), moab::tolerance, TreeValidator::unsorted_axis_count, verbosity, write_cubit, and write_vtk.
Referenced by main().
{
ErrorCode rval;
Core instance;
Interface* const iface = &instance;
OrientedBoxTreeTool tool( iface );
bool haveSurfTree = false;
if( verbosity ) std::cout << filename << std::endl << "------" << std::endl;
rval = iface->load_mesh( filename );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cout << "Failed to read file: \"" << filename << '"' << std::endl;
return false;
}
// IF building from surfaces, get surfaces.
// If AUTO and less than two surfaces, don't build from surfaces.
Range surfaces;
if( surfTree != DISABLE )
{
Tag surftag;
rval = iface->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, surftag );
if( MB_SUCCESS == rval )
{
int dim = 2;
const void* tagvalues[] = { &dim };
rval = iface->get_entities_by_type_and_tag( 0, MBENTITYSET, &surftag, tagvalues, 1, surfaces );
if( MB_SUCCESS != rval && MB_ENTITY_NOT_FOUND != rval ) return false;
}
else if( MB_TAG_NOT_FOUND != rval )
return false;
if( ENABLE == surfTree && surfaces.empty() )
{
std::cerr << "No Surfaces found." << std::endl;
return false;
}
haveSurfTree = ( ENABLE == surfTree ) || ( surfaces.size() > 1 );
}
EntityHandle root;
Range entities;
if( !haveSurfTree )
{
rval = iface->get_entities_by_dimension( 0, 2, entities );
if( MB_SUCCESS != rval )
{
std::cerr << "get_entities_by_dimension( 2 ) failed." << std::endl;
return false;
}
if( entities.empty() )
{
if( verbosity ) std::cout << "File \"" << filename << "\" contains no 2D elements" << std::endl;
return false;
}
if( verbosity ) std::cout << "Building tree from " << entities.size() << " 2D elements" << std::endl;
rval = tool.build( entities, root, &settings );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cout << "Failed to build tree." << std::endl;
return false;
}
}
else
{
if( verbosity ) std::cout << "Building tree from " << surfaces.size() << " surfaces" << std::endl;
// Build subtree for each surface, get list of all entities to use later
Range surf_trees, surf_tris;
EntityHandle surf_root;
for( Range::iterator s = surfaces.begin(); s != surfaces.end(); ++s )
{
surf_tris.clear();
rval = iface->get_entities_by_dimension( *s, 2, surf_tris );
if( MB_SUCCESS != rval ) return false;
rval = tool.build( surf_tris, surf_root, &settings );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cout << "Failed to build tree for surface." << std::endl;
return false;
}
surf_trees.insert( surf_root );
entities.merge( surf_tris );
rval = iface->add_entities( surf_root, &*s, 1 );
if( MB_SUCCESS != rval ) return false;
}
rval = tool.join_trees( surf_trees, root, &settings );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cout << "Failed to build tree." << std::endl;
return false;
}
if( verbosity )
std::cout << "Built tree from " << surfaces.size() << " surfaces"
<< " (" << entities.size() - surfaces.size() << " elements)" << std::endl;
entities.merge( surfaces );
}
if( write_cubit )
{
std::string name = filename;
name += ".boxes.jou";
FILE* ptr = fopen( name.c_str(), "w+" );
if( !ptr )
{
perror( name.c_str() );
}
else
{
if( verbosity ) std::cout << "Writing: " << name << std::endl;
fprintf( ptr, "graphics off\n" );
CubitWriter op( ptr, &tool );
tool.preorder_traverse( root, op );
fprintf( ptr, "graphics on\n" );
fclose( ptr );
}
}
if( write_vtk )
{
VtkWriter op( filename, iface );
if( verbosity )
std::cout << "Writing leaf contents as : " << filename << ".xxx.vtk where 'xxx' is the set id" << std::endl;
tool.preorder_traverse( root, op );
}
bool print_errors = ( verbosity > 2 ), print_contents = ( verbosity > 4 );
if( verbosity > 3 ) tool.print( root, std::cout, print_contents );
if( verbosity > 1 )
{
rval = tool.stats( root, std::cout );
if( MB_SUCCESS != rval ) std::cout << "****** Failed to get tree statistics ******" << std::endl;
}
TreeValidator op( iface, &tool, print_errors, std::cout, tolerance, haveSurfTree, settings );
rval = tool.preorder_traverse( root, op );
bool result = op.is_valid();
if( MB_SUCCESS != rval )
{
result = false;
if( verbosity ) std::cout << "Errors traversing tree. Corrupt tree?" << std::endl;
}
bool missing = ( op.entity_count != entities.size() );
if( missing ) result = false;
if( verbosity )
{
if( result )
std::cout << std::endl << "No errors detected." << std::endl;
else
std::cout << std::endl << "*********************** ERROR SUMMARY **********************" << std::endl;
if( op.child_outside_count )
std::cout << "* " << op.child_outside_count << " child boxes not contained in parent." << std::endl;
if( op.entity_outside_count )
std::cout << "* " << op.entity_outside_count << " nodes containing entities outside of box." << std::endl;
if( op.num_entities_outside )
std::cout << "* " << op.num_entities_outside << " entities outside boxes." << std::endl;
if( op.empty_leaf_count ) std::cout << "* " << op.empty_leaf_count << " empty leaf nodes." << std::endl;
if( op.non_empty_non_leaf_count )
std::cout << "* " << op.non_empty_non_leaf_count << " non-leaf nodes containing entities." << std::endl;
if( op.duplicate_entity_count )
std::cout << "* " << op.duplicate_entity_count << " duplicate entities in leaves." << std::endl;
if( op.missing_surface_count )
std::cout << "* " << op.missing_surface_count << " leaves outside surface subtrees." << std::endl;
if( op.multiple_surface_count )
std::cout << "* " << op.multiple_surface_count << " surfaces within other surface subtrees." << std::endl;
if( op.non_ortho_count )
std::cout << "* " << op.non_ortho_count << " boxes with non-orthononal axes." << std::endl;
if( op.non_unit_count ) std::cout << "* " << op.non_unit_count << " boxes with non-unit axes." << std::endl;
if( op.bad_outer_radius_count )
std::cout << "* " << op.bad_outer_radius_count << " boxes incorrect outer radius." << std::endl;
if( op.unsorted_axis_count )
std::cout << "* " << op.unsorted_axis_count << " boxes axes in unsorted order." << std::endl;
if( op.loose_box_count )
std::cout << "* " << op.loose_box_count << " boxes that do not fit the contained entities tightly."
<< std::endl;
if( op.error_count + op.entity_invalid_count )
std::cout << "* " << op.error_count + op.entity_invalid_count << " other errors while traversing tree."
<< std::endl;
if( missing )
std::cout << "* tree built from " << entities.size() << " entities contains " << op.entity_count
<< " entities." << std::endl;
if( !result ) std::cout << "************************************************************" << std::endl;
}
if( result && save_file_name )
{
if( MB_SUCCESS == save_tree( iface, save_file_name, root ) )
std::cerr << "Wrote '" << save_file_name << "'" << std::endl;
else
std::cerr << "FAILED TO WRITE '" << save_file_name << "'" << std::endl;
}
if( !do_ray_fire_test( tool, root, filename, haveSurfTree ) )
{
if( verbosity ) std::cout << "Ray fire test failed." << std::endl;
result = false;
}
if( !do_closest_point_test( tool, root, haveSurfTree ) )
{
if( verbosity ) std::cout << "Closest point test failed" << std::endl;
result = false;
}
rval = tool.delete_tree( root );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cout << "delete_tree failed." << std::endl;
result = false;
}
return result;
}
| static bool do_ray_fire_test | ( | OrientedBoxTreeTool & | tool, |
| EntityHandle | root_set, | ||
| const char * | filename, | ||
| bool | have_surface_tree | ||
| ) | [static] |
Definition at line 1067 of file obb_test.cpp.
References moab::OrientedBox::axis(), moab::Range::begin(), moab::OrientedBoxTreeTool::box(), box(), moab::OrientedBox::center, check_ray_intersect_sets(), check_ray_intersect_tris(), default_files_tests, moab::OrientedBox::dimensions(), moab::Range::empty(), moab::Range::end(), ErrorCode, filename, moab::OrientedBoxTreeTool::get_moab_instance(), moab::Interface::globalId_tag(), moab::Interface::id_from_handle(), MB_SUCCESS, origin, moab::OrientedBoxTreeTool::TrvStats::print(), moab::OrientedBoxTreeTool::ray_intersect_boxes(), moab::OrientedBoxTreeTool::ray_intersect_sets(), moab::OrientedBoxTreeTool::ray_intersect_triangles(), rays, moab::OrientedBox::scaled_axis(), moab::Range::size(), moab::Interface::tag_get_data(), moab::tolerance, verbosity, write_cubit, moab::Interface::write_mesh(), and write_ray_vtk.
Referenced by do_file().
{
if( verbosity > 1 ) std::cout << "beginning ray fire tests" << std::endl;
OrientedBox box;
ErrorCode rval = tool.box( root_set, box );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cerr << "Error getting box for tree root set" << std::endl;
return false;
}
/* Do standard ray fire tests */
std::cout << box << std::endl;
CartVect origin( 0., 0., 0. );
CartVect unitDiag( 1., 1., 1. );
std::vector< RayTest > tests;
RayTest default_tests[] = { { "large axis through box", 2, box.center - 1.2 * box.scaled_axis( 2 ), box.axis( 2 ) },
{ "small axis through box", 2, box.center - 1.2 * box.scaled_axis( 0 ), box.axis( 0 ) },
{ "parallel miss", 0, box.center + 2.0 * box.scaled_axis( 1 ), box.axis( 2 ) },
{ "skew miss", 0, box.center + box.dimensions(), box.dimensions() * box.axis( 2 ) } };
const size_t num_def_test = sizeof( default_tests ) / sizeof( default_tests[0] );
tests.insert( tests.begin(), &default_tests[0], &default_tests[0] + num_def_test );
tests.insert( tests.end(), default_files_tests[filename].begin(), default_files_tests[filename].end() );
OrientedBoxTreeTool::TrvStats stats;
bool result = true;
const size_t num_test = tests.size();
for( size_t i = 0; i < num_test; ++i )
{
tests[i].direction.normalize();
if( verbosity > 2 )
{
std::cout << ( 0 == i ? "** Common tests\n" : ( num_def_test == i ? "** File-specific tests\n" : "" ) );
std::cout << " " << tests[i].description << " " << tests[i].point << " " << tests[i].direction
<< std::endl;
}
int rit_non_tol_count = 0;
double rit_non_tol_dist = std::numeric_limits< double >::max();
if( !check_ray_intersect_tris( tool, root_set, tests[i], rit_non_tol_count, rit_non_tol_dist, stats ) )
{
result = false;
continue;
}
if( !haveSurfTree ) continue;
int ris_non_tol_count = 0;
double ris_non_tol_dist = std::numeric_limits< double >::max();
if( !check_ray_intersect_sets( tool, root_set, tests[i], ris_non_tol_count, ris_non_tol_dist, stats ) )
{
result = false;
continue;
}
if( !rit_non_tol_count && ris_non_tol_count )
{
if( verbosity )
std::cout << " ray_intersect_sets returned intersection not found by "
"ray_intersect_triangles"
<< std::endl;
result = false;
continue;
}
else if( rit_non_tol_count && !ris_non_tol_count )
{
if( verbosity )
std::cout << " ray_intersect_sets missed intersection found by ray_intersect_triangles" << std::endl;
result = false;
continue;
}
else if( rit_non_tol_count && ris_non_tol_count && fabs( rit_non_tol_dist - ris_non_tol_dist ) > tolerance )
{
if( verbosity )
std::cout << " ray_intersect_sets and ray_intersect_triangles did not find same "
"closest intersection"
<< std::endl;
result = false;
}
}
/* Do ray fire for any user-specified rays */
for( size_t i = 0; i < rays.size(); i += 2 )
{
std::cout << rays[i] << "+" << rays[i + 1] << " : ";
if( !haveSurfTree )
{
Range leaves;
std::vector< double > intersections;
std::vector< EntityHandle > intersection_facets;
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;
continue;
}
if( !leaves.empty() && write_ray_vtk )
{
std::string num, name( filename );
std::stringstream s;
s << ( i / 2 );
s >> num;
name += "-ray";
name += num;
name += ".vtk";
std::vector< EntityHandle > sets( leaves.size() );
std::copy( leaves.begin(), leaves.end(), sets.begin() );
tool.get_moab_instance()->write_mesh( name.c_str(), &sets[0], sets.size() );
if( verbosity ) std::cout << "(Wrote " << name << ") ";
}
rval = tool.ray_intersect_triangles( intersections, intersection_facets, leaves, tolerance, rays[i].array(),
rays[i + 1].array(), 0 );
if( MB_SUCCESS != rval )
{
std::cout << "FAILED" << std::endl;
result = false;
continue;
}
if( intersections.empty() )
{
std::cout << "(none)" << std::endl;
continue;
}
std::cout << intersections[0];
for( unsigned j = 1; j < intersections.size(); ++j )
std::cout << ", " << intersections[j];
std::cout << std::endl;
if( !leaves.empty() && write_cubit && verbosity > 2 )
{
std::cout << " intersected boxes:";
for( Range::iterator i2 = leaves.begin(); i2 != leaves.end(); ++i2 )
std::cout << " " << tool.get_moab_instance()->id_from_handle( *i2 );
std::cout << std::endl;
}
}
else
{
std::vector< double > intersections;
std::vector< EntityHandle > surfaces;
std::vector< EntityHandle > facets;
OrientedBoxTreeTool::IntersectSearchWindow search_win;
OrientedBoxTreeTool::IntRegCtxt int_reg_ctxt;
rval = tool.ray_intersect_sets( intersections, surfaces, facets, root_set, tolerance, rays[i].array(),
rays[i + 1].array(), search_win, int_reg_ctxt, &stats );
if( MB_SUCCESS != rval )
{
if( verbosity ) std::cout << " Call to OrientedBoxTreeTool::ray_intersect_sets failed." << std::endl;
result = false;
continue;
}
if( !surfaces.empty() && write_ray_vtk )
{
std::string num, name( filename );
std::stringstream s;
s << ( i / 2 );
s >> num;
name += "-ray";
name += num;
name += ".vtk";
tool.get_moab_instance()->write_mesh( name.c_str(), &surfaces[0], surfaces.size() );
if( verbosity ) std::cout << "(Wrote " << name << ") ";
}
if( intersections.size() != surfaces.size() )
{
std::cout << "Mismatched output lists." << std::endl;
result = false;
continue;
}
if( intersections.empty() )
{
std::cout << "(none)" << std::endl;
continue;
}
Tag idtag = tool.get_moab_instance()->globalId_tag();
std::vector< int > ids( surfaces.size() );
rval = tool.get_moab_instance()->tag_get_data( idtag, &surfaces[0], surfaces.size(), &ids[0] );
if( MB_SUCCESS != rval )
{
std::cout << "NO GLOBAL_ID TAG ON SURFACE." << std::endl;
continue;
}
// group by surfaces
std::map< int, double > intmap;
for( unsigned j = 0; j < intersections.size(); ++j )
intmap[ids[j]] = intersections[j];
std::map< int, double >::iterator it = intmap.begin();
int prevsurf = it->first;
std::cout << "Surf" << it->first << " " << it->second;
for( ++it; it != intmap.end(); ++it )
{
std::cout << ", ";
if( it->first != prevsurf )
{
prevsurf = it->first;
std::cout << "Surf" << it->first << " ";
}
std::cout << it->second;
}
std::cout << std::endl;
}
}
if( verbosity > 1 )
{
std::cout << "Traversal statistics for ray fire tests: " << std::endl;
stats.print( std::cout );
}
return result;
}
| static double get_double_option | ( | int & | i, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 138 of file obb_test.cpp.
References get_option(), and usage.
Referenced by main().
{
const char* str = get_option( i, argc, argv );
char* end_ptr;
double val = strtod( str, &end_ptr );
if( !*str || *end_ptr ) usage( "Expected real number following option", argv[i - 1] );
return val;
}
| static int get_int_option | ( | int & | i, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 129 of file obb_test.cpp.
References get_option(), and usage.
Referenced by main().
{
const char* str = get_option( i, argc, argv );
char* end_ptr;
long val = strtol( str, &end_ptr, 0 );
if( !*str || *end_ptr ) usage( "Expected integer following option", argv[i - 1] );
return val;
}
| static const char* get_option | ( | int & | i, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 122 of file obb_test.cpp.
References usage.
Referenced by get_double_option(), get_int_option(), main(), and parse_ray().
{
++i;
if( i == argc ) usage( "Expected argument following option", argv[i - 1] );
return argv[i];
}
| void initialize_default_files | ( | ) |
Definition at line 36 of file obb_test.cpp.
References default_files_tests, num_tests, and STRINGIFY.
Referenced by main().
{
size_t num_tests;
std::vector< RayTest > tests;
std::string file = STRINGIFY( MESHDIR ) "/3k-tri-sphere.vtk";
RayTest set1[] = { { "triangle interior ", 1, CartVect( 0, 0, 0 ), CartVect( 99.8792, -5, 0.121729 ) },
{ "triangle edge ", 2, CartVect( 0, 0, 0 ), CartVect( 4.99167, 0, 99.7502 ) },
{ "triangle node ", 6, CartVect( 0, 0, 0 ), CartVect( 0, 0, 100 ) } };
num_tests = sizeof( set1 ) / sizeof( set1[0] );
tests.insert( tests.begin(), &set1[0], &set1[num_tests] );
default_files_tests[file] = tests;
tests.clear();
#ifdef MOAB_HAVE_HDF5
file = STRINGIFY( MESHDIR ) "/3k-tri-cube.h5m";
#else
file = STRINGIFY( MESHDIR ) "/3k-tri-cube.vtk";
#endif
RayTest set2[] = { { "interior triangle interior ", 1, CartVect( 0, 0, 0 ), CartVect( 0, 0, 5 ) },
{ "interior triangle edge ", 2, CartVect( 0, 0, 0 ), CartVect( -0.25, -0.05, 5 ) },
{ "interior triangle node ", 5, CartVect( 0, 0, 0 ), CartVect( -0.3, -0.3, 5 ) },
{ "edge triangle interior ", 1, CartVect( 0, 0, 0 ), CartVect( 5, 2.9, 2.9 ) },
{ "edge triangle edge ", 2, CartVect( 0, 0, 0 ), CartVect( 5, 5, 2.9 ) },
{ "edge triangle node ", 6, CartVect( 0, 0, 0 ), CartVect( 5, 5, 3 ) },
{ "corner triangle interior ", 1, CartVect( 0, 0, 0 ), CartVect( 5, 4.9, 4.9 ) },
{ "corner triangle edge ", 2, CartVect( 0, 0, 0 ), CartVect( 5, 5, 4.9 ) },
{ "corner triangle node ", 3, CartVect( 0, 0, 0 ), CartVect( 5, 5, 5 ) } };
num_tests = sizeof( set2 ) / sizeof( set2[0] );
tests.insert( tests.begin(), &set2[0], &set2[num_tests] );
default_files_tests[file] = tests;
tests.clear();
}
| int main | ( | int | argc, |
| char * | argv[] | ||
| ) |
Definition at line 168 of file obb_test.cpp.
References moab::OrientedBoxTreeTool::Settings::best_split_ratio, default_files_tests, DISABLE, do_file(), ENABLE, moab::fail(), get_double_option(), get_int_option(), get_option(), moab::Core::impl_version(), initialize_default_files(), moab::OrientedBoxTreeTool::Settings::max_depth, moab::OrientedBoxTreeTool::Settings::max_leaf_entities, MESHSET_SET, parse_ray(), save_file_name, moab::OrientedBoxTreeTool::Settings::set_options, settings, surfTree, moab::tolerance, usage, moab::OrientedBoxTreeTool::Settings::valid(), verbosity, moab::OrientedBoxTreeTool::Settings::worst_split_ratio, write_cubit, write_ray_vtk, and write_vtk.
{
#ifdef MOAB_HAVE_MPI
int fail = MPI_Init( &argc, &argv );
if( fail ) return fail;
#endif
initialize_default_files();
std::vector< const char* > file_names;
bool flags = true;
for( int i = 1; i < argc; ++i )
{
if( flags && argv[i][0] == '-' )
{
if( !argv[i][1] || argv[i][2] ) usage( 0, argv[i] );
switch( argv[i][1] )
{
default:
usage( 0, argv[i] );
break;
case '-':
flags = false;
break;
case 'v':
++verbosity;
break;
case 'q':
verbosity = 0;
break;
case 'h':
usage( 0, 0 );
break;
case 'c':
write_cubit = true;
break;
case 'k':
write_vtk = true;
break;
case 'K':
write_ray_vtk = true;
break;
case 's':
surfTree = ENABLE;
break;
case 'S':
surfTree = DISABLE;
break;
case 'u':
settings.set_options = MESHSET_SET;
break;
case 'U':
settings.set_options = MESHSET_ORDERED;
break;
case 'o':
save_file_name = get_option( i, argc, argv );
break;
case 'n':
settings.max_leaf_entities = get_int_option( i, argc, argv );
break;
case 'l':
settings.max_depth = get_int_option( i, argc, argv );
break;
case 'r':
settings.worst_split_ratio = get_double_option( i, argc, argv );
break;
case 'R':
settings.best_split_ratio = get_double_option( i, argc, argv );
break;
case 't':
tolerance = get_double_option( i, argc, argv );
break;
case 'f':
parse_ray( i, argc, argv );
break;
}
}
else
{
file_names.push_back( argv[i] );
}
}
if( verbosity )
{
Core core;
std::string version;
core.impl_version( &version );
std::cout << version << std::endl;
if( verbosity > 1 )
std::cout << "max_leaf_entities: " << settings.max_leaf_entities << std::endl
<< "max_depth: " << settings.max_depth << std::endl
<< "worst_split_ratio: " << settings.worst_split_ratio << std::endl
<< "best_split_ratio: " << settings.best_split_ratio << std::endl
<< "tolerance: " << tolerance << std::endl
<< "set type: "
<< ( ( settings.set_options & MESHSET_ORDERED ) ? "ordered" : "set" ) << std::endl
<< std::endl;
}
if( !settings.valid() || tolerance < 0.0 )
{
std::cerr << "Invalid settings specified." << std::endl;
return 2;
}
if( file_names.empty() )
{
std::cerr << "No file(s) specified." << std::endl;
for( ray_test_itr file = default_files_tests.begin(); file != default_files_tests.end(); file++ )
{
std::cerr << "Using default file \"" << file->first << '"' << std::endl;
file_names.push_back( file->first.c_str() );
}
}
if( save_file_name && file_names.size() != 1 )
{
std::cout << "Only one input file allowed if \"-o\" option is specified." << std::endl;
std::cout << "Only testing with single file " << file_names[0] << std::endl;
file_names.erase( ++file_names.begin(), file_names.end() );
}
int exit_val = 0;
for( unsigned j = 0; j < file_names.size(); ++j )
if( !do_file( file_names[j] ) ) ++exit_val;
#ifdef MOAB_HAVE_MPI
fail = MPI_Finalize();
if( fail ) return fail;
#endif
return exit_val ? exit_val + 2 : 0;
}
| static void parse_ray | ( | int & | i, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 303 of file obb_test.cpp.
References get_option(), moab::CartVect::normalize(), rays, and usage.
Referenced by main().
{
CartVect point, direction;
if( 6 != sscanf( get_option( i, argc, argv ), "%lf:%lf:%lf:%lf:%lf:%lf", &point[0], &point[1], &point[2],
&direction[0], &direction[1], &direction[2] ) )
usage( "Expected ray specified as <x>:<y>:<z>:<i>:<j>:<k>", 0 );
direction.normalize();
rays.push_back( point );
rays.push_back( direction );
}
| static ErrorCode save_tree | ( | Interface * | instance, |
| const char * | filename, | ||
| EntityHandle | tree_root | ||
| ) | [static] |
Definition at line 1303 of file obb_test.cpp.
References ErrorCode, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_HANDLE, moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and moab::Interface::write_mesh().
Referenced by do_file().
{
ErrorCode rval;
Tag tag;
rval = instance->tag_get_handle( "OBB_ROOT", 1, MB_TYPE_HANDLE, tag, MB_TAG_SPARSE | MB_TAG_CREAT );
if( MB_SUCCESS != rval ) return rval;
const EntityHandle root = 0;
rval = instance->tag_set_data( tag, &root, 1, &tree_root );
if( MB_SUCCESS != rval ) return rval;
return instance->write_mesh( filename );
}
| static ErrorCode tri_coords | ( | Interface * | moab, |
| EntityHandle | tri, | ||
| CartVect | coords[3] | ||
| ) | [static] |
Definition at line 1318 of file obb_test.cpp.
References ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), and MB_SUCCESS.
Referenced by check_common_vertex(), check_point_in_triangles(), closest_point_in_triangles(), do_closest_point_test(), and moab::AdaptiveKDTree::ray_intersect_triangles().
{
ErrorCode rval;
const EntityHandle* conn;
int len;
rval = moab->get_connectivity( tri, conn, len, true );
if( MB_SUCCESS != rval ) return rval;
if( len != 3 ) return MB_FAILURE;
rval = moab->get_coords( conn, 3, coords[0].array() );
return rval;
}
| static bool tri_in_set | ( | Interface * | moab, |
| EntityHandle | set, | ||
| EntityHandle | tri | ||
| ) | [static] |
Definition at line 1372 of file obb_test.cpp.
References moab::Range::end(), ErrorCode, moab::Range::find(), moab::Interface::get_entities_by_type(), MB_SUCCESS, and MBTRI.
Referenced by do_closest_point_test().
{
Range tris;
ErrorCode rval = moab->get_entities_by_type( set, MBTRI, tris );
if( MB_SUCCESS != rval ) return false;
Range::iterator i = tris.find( tri );
return i != tris.end();
}
| static void usage | ( | const char * | error, |
| const char * | opt | ||
| ) | [static] |
Definition at line 75 of file obb_test.cpp.
References moab::error(), and NAME.
{
const char* default_message = "Invalid option";
if( opt && !error ) error = default_message;
std::ostream& str = error ? std::cerr : std::cout;
if( error )
{
str << error;
if( opt ) str << ": " << opt;
str << std::endl;
}
str << "Usage: " << NAME << " [output opts.] [settings] [file ...]" << std::endl;
str << " " << NAME << " -h" << std::endl;
if( !error )
str << " If no file is specified the defautl test files will be used" << std::endl
<< " -h print help text. " << std::endl
<< " -v verbose output (may be specified multiple times) " << std::endl
<< " -q quiet (minimal output) " << std::endl
<< " -f <x>:<y>:<z>:<i>:<j>:<k> Do ray fire" << std::endl
<< " -c write box geometry to Cubit journal file." << std::endl
<< " -k write leaf contents to vtk files." << std::endl
<< " -K write contents of leaf boxes intersected by rays to vtk file." << std::endl
<< " -o <name> Save file containing tree and triangles. Mesh tag \"OBB_ROOT\"." << std::endl
<< " -t <real> specify tolerance" << std::endl
<< " -n <int> specify max entities per leaf node " << std::endl
<< " -l <int> specify max tree levels" << std::endl
<< " -r <real> specify worst cell split ratio" << std::endl
<< " -R <real> specify best cell split ratio" << std::endl
<< " -s force construction of surface tree" << std::endl
<< " -S do not build surface tree." << std::endl
<< " (Default: surface tree if file contains multiple surfaces" << std::endl
<< " -u use unordered (Range) meshsets for tree nodes" << std::endl
<< " -U use ordered (vector) meshsets for tree nodes" << std::endl
<< " Verbosity (-q sets to 0, each -v increments, default is 1):" << std::endl
<< " 0 - no output" << std::endl
<< " 1 - status messages and error summary" << std::endl
<< " 2 - print tree statistics " << std::endl
<< " 3 - output errors for each node" << std::endl
<< " 4 - print tree" << std::endl
<< " 5 - print tree w/ contents of each node" << std::endl
<< " See documentation for OrientedBoxTreeTool::Settings for " << std::endl
<< " a description of tree generation settings." << std::endl;
exit( !!error );
}
| std::map< std::string, std::vector< RayTest > > default_files_tests |
Definition at line 33 of file obb_test.cpp.
Referenced by do_ray_fire_test(), initialize_default_files(), and main().
const char* NAME = "obb_test" [static] |
Definition at line 31 of file obb_test.cpp.
Referenced by vtkMoabReader::CreateSubBlocks(), vtkMoabReader::RequestData(), and usage().
Definition at line 162 of file obb_test.cpp.
Referenced by do_ray_fire_test(), and parse_ray().
const char* save_file_name = 0 [static] |
Definition at line 163 of file obb_test.cpp.
OrientedBoxTreeTool::Settings settings [static] |
Definition at line 157 of file obb_test.cpp.
Referenced by do_file(), initialize_tree(), main(), and TreeValidator::visit().
Definition at line 164 of file obb_test.cpp.
double tolerance = 1e-6 [static] |
Definition at line 158 of file obb_test.cpp.
Referenced by main().
int verbosity = 1 [static] |
Definition at line 156 of file obb_test.cpp.
Referenced by check_ray_intersect_sets(), check_ray_intersect_tris(), do_closest_point_test(), do_file(), do_ray_fire_test(), and main().
bool write_cubit = false [static] |
Definition at line 159 of file obb_test.cpp.
Referenced by do_file(), do_ray_fire_test(), and main().
bool write_ray_vtk = false [static] |
Definition at line 161 of file obb_test.cpp.
Referenced by do_ray_fire_test(), and main().
bool write_vtk = false [static] |
Definition at line 160 of file obb_test.cpp.