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>
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.