moab
|
Public Member Functions | |
RayIntersectSets (OrientedBoxTreeTool *tool_ptr, const double *ray_point, const double *unit_ray_dir, const double *nonneg_ray_length, const double *neg_ray_length, double tolerance, int min_tol_intersections, std::vector< double > &inters, std::vector< EntityHandle > &surfaces, std::vector< EntityHandle > &facts, EntityHandle *root_set, const EntityHandle *geom_volume, const Tag *sense_tag, const int *desired_orient, const std::vector< EntityHandle > *prev_facets, unsigned int *tmp_count) | |
virtual ErrorCode | visit (EntityHandle node, int depth, bool &descend) |
Visit a node in the tree during a traversal. | |
virtual ErrorCode | leaf (EntityHandle node) |
Process a leaf node during tree traversal. | |
Private Member Functions | |
void | add_intersection (double t, EntityHandle facet) |
Private Attributes | |
OrientedBoxTreeTool * | tool |
const CartVect | ray_origin |
const CartVect | ray_direction |
const double * | nonneg_ray_len |
const double * | neg_ray_len |
const double | tol |
const int | minTolInt |
std::vector< double > & | intersections |
std::vector< EntityHandle > & | sets |
std::vector< EntityHandle > & | facets |
const EntityHandle * | rootSet |
const EntityHandle * | geomVol |
const Tag * | senseTag |
const int * | desiredOrient |
int * | surfTriOrient |
int | surfTriOrient_val |
const std::vector< EntityHandle > * | prevFacets |
unsigned int * | raytri_test_count |
EntityHandle | lastSet |
int | lastSetDepth |
std::vector< std::vector < EntityHandle > > | neighborhoods |
std::vector< EntityHandle > | neighborhood |
Definition at line 980 of file OrientedBoxTreeTool.cpp.
moab::RayIntersectSets::RayIntersectSets | ( | OrientedBoxTreeTool * | tool_ptr, |
const double * | ray_point, | ||
const double * | unit_ray_dir, | ||
const double * | nonneg_ray_length, | ||
const double * | neg_ray_length, | ||
double | tolerance, | ||
int | min_tol_intersections, | ||
std::vector< double > & | inters, | ||
std::vector< EntityHandle > & | surfaces, | ||
std::vector< EntityHandle > & | facts, | ||
EntityHandle * | root_set, | ||
const EntityHandle * | geom_volume, | ||
const Tag * | sense_tag, | ||
const int * | desired_orient, | ||
const std::vector< EntityHandle > * | prev_facets, | ||
unsigned int * | tmp_count | ||
) | [inline] |
Definition at line 1025 of file OrientedBoxTreeTool.cpp.
: tool(tool_ptr), ray_origin(ray_point), ray_direction(unit_ray_dir), nonneg_ray_len(nonneg_ray_length), neg_ray_len(neg_ray_length), tol(tolerance), minTolInt(min_tol_intersections), intersections(inters), sets(surfaces), facets(facts), rootSet(root_set), geomVol(geom_volume), senseTag(sense_tag), desiredOrient(desired_orient), prevFacets(prev_facets), raytri_test_count(tmp_count), lastSet(0) { // specified orientation should be 1 or -1, indicating ray and surface // normal in the same or opposite directions, respectively. if(desiredOrient) { assert(1==*desiredOrient || -1==*desiredOrient); surfTriOrient = &surfTriOrient_val; } else { surfTriOrient = NULL; } // check the limits if(nonneg_ray_len) { assert(0 <= *nonneg_ray_len); } if(neg_ray_len) { assert(0 > *neg_ray_len); } }
void moab::RayIntersectSets::add_intersection | ( | double | t, |
EntityHandle | facet | ||
) | [private] |
Definition at line 1271 of file OrientedBoxTreeTool.cpp.
{ // Mode 1, detected by non-null neg_ray_len pointer // keep the closest nonneg intersection and one negative intersection, if closer if(neg_ray_len && nonneg_ray_len) { if(2 != intersections.size()) { intersections.resize(2,0); sets.resize(2,0); facets.resize(2,0); // must initialize this for comparison below intersections[0] = -std::numeric_limits<double>::max(); } // negative case if(0.0>t) { intersections[0] = t; sets[0] = lastSet; facets[0] = facet; neg_ray_len = &intersections[0]; // nonnegative case } else { intersections[1] = t; sets[1] = lastSet; facets[1] = facet; nonneg_ray_len = &intersections[1]; // if the intersection is closer than the negative one, remove the negative one if(t < -(*neg_ray_len) ) { intersections[0] = -intersections[1]; sets[0] = 0; facets[0] = 0; neg_ray_len = &intersections[0]; } } // std::cout << "add_intersection: t = " << t << " neg_ray_len=" << *neg_ray_len // << " nonneg_ray_len=" << *nonneg_ray_len << std::endl; return; } // --------------------------------------------------------------------------- // Mode 2 // If minTolInt is less than zero, return all intersections if (minTolInt < 0 && t > -tol) { intersections.push_back(t); sets.push_back(lastSet); facets.push_back(facet); neighborhoods.push_back(neighborhood); return; } // Check if the 'len' pointer is pointing into the intersection // list. If this is the case, then the list contains, at that // location, an intersection greater than the tolerance away from // the base point of the ray. int len_idx = -1; if (nonneg_ray_len && nonneg_ray_len >= &intersections[0] && nonneg_ray_len < &intersections[0] + intersections.size()) len_idx = nonneg_ray_len - &intersections[0]; // If the intersection is within tol of the ray base point, we // always add it to the list. if (t <= tol) { // If the list contains an intersection outside the tolerance... if (len_idx >= 0) { // If we no longer want an intersection outside the tolerance, // remove it. if ((int)intersections.size() >= minTolInt) { intersections[len_idx] = t; sets[len_idx] = lastSet; facets[len_idx] = facet; // From now on, we want only intersections within the tolerance, // so update length accordingly nonneg_ray_len = &tol; } // Otherwise appended to the list and update pointer else { intersections.push_back(t); sets.push_back(lastSet); facets.push_back(facet); nonneg_ray_len = &intersections[len_idx]; } } // Otherwise just append it else { intersections.push_back(t); sets.push_back(lastSet); facets.push_back(facet); // If we have all the intersections we want, set // length such that we will only find further intersections // within the tolerance if ((int)intersections.size() >= minTolInt) nonneg_ray_len = &tol; } } // Otherwise the intersection is outside the tolerance // If we already have an intersection outside the tolerance and // this one is closer, replace the existing one with this one. else if (len_idx >= 0) { if (t <= *nonneg_ray_len) { intersections[len_idx] = t; sets[len_idx] = lastSet; facets[len_idx] = facet; } } // Otherwise if we want an intersection outside the tolerance // and don'thave one yet, add it. else if ((int)intersections.size() < minTolInt) { intersections.push_back( t ); sets.push_back( lastSet ); facets.push_back(facet); // update length. this is currently the closest intersection, so // only want further intersections that are closer than this one. nonneg_ray_len = &intersections.back(); } }
ErrorCode moab::RayIntersectSets::leaf | ( | EntityHandle | node | ) | [virtual] |
Process a leaf node during tree traversal.
Implements moab::OrientedBoxTreeTool::Op.
Definition at line 1137 of file OrientedBoxTreeTool.cpp.
{ assert(lastSet); if (!lastSet) // if no surface has been visited yet, something's messed up. return MB_FAILURE; #ifndef MB_OBB_USE_VECTOR_QUERIES Range tris; # ifdef MB_OBB_USE_TYPE_QUERIES ErrorCode rval = tool->get_moab_instance()->get_entities_by_type( node, MBTRI, tris ); # else ErrorCode rval = tool->get_moab_instance()->get_entities_by_handle( node, tris ); # endif #else std::vector<EntityHandle> tris; ErrorCode rval = tool->get_moab_instance()->get_entities_by_handle( node, tris ); #endif assert(MB_SUCCESS == rval); if (MB_SUCCESS != rval) return rval; #ifndef MB_OBB_USE_VECTOR_QUERIES for (Range::iterator t = tris.begin(); t != tris.end(); ++t) #else for (std::vector<EntityHandle>::iterator t = tris.begin(); t != tris.end(); ++t) #endif { #ifndef MB_OBB_USE_TYPE_QUERIES if (TYPE_FROM_HANDLE(*t) != MBTRI) continue; #endif const EntityHandle* conn; int num_conn; rval = tool->get_moab_instance()->get_connectivity( *t, conn, num_conn, true ); assert(MB_SUCCESS == rval); if (MB_SUCCESS != rval) return rval; CartVect coords[3]; rval = tool->get_moab_instance()->get_coords( conn, 3, coords[0].array() ); assert(MB_SUCCESS == rval); if (MB_SUCCESS != rval) return rval; if( raytri_test_count ) *raytri_test_count += 1; double int_dist; GeomUtil::intersection_type int_type = GeomUtil::NONE; // Note: tol is not used in the ray-tri test. if (GeomUtil::plucker_ray_tri_intersect( coords, ray_origin, ray_direction, tol, int_dist, nonneg_ray_len, neg_ray_len, surfTriOrient, &int_type )) { // Do not accept intersections if they are in the vector of previously intersected // facets. if( prevFacets && ((*prevFacets).end() != find((*prevFacets).begin(), (*prevFacets).end(), *t) ) ) continue; // Do not accept intersections if they are in the neighborhood of previous // intersections. bool same_neighborhood = false; for(unsigned i=0; i<neighborhoods.size(); ++i) { if( neighborhoods[i].end() != find(neighborhoods[i].begin(), neighborhoods[i].end(), *t ) ) { same_neighborhood = true; continue; } } if(same_neighborhood) continue; // Handle special case of edge/node intersection. Accept piercing // intersections and reject glancing intersections. // The edge_node_intersection function needs to know surface sense wrt volume. // A less-robust implementation could work without sense information. // Would it ever be useful to accept a glancing intersection? if(GeomUtil::INTERIOR != int_type && rootSet && geomVol && senseTag) { // get triangles in the proximity of the intersection CartVect int_pt = ray_origin + int_dist*ray_direction; std::vector<EntityHandle> close_tris; std::vector<EntityHandle> close_surfs; rval = tool->sphere_intersect_triangles( int_pt.array(), tol, *rootSet, close_tris, &close_surfs ); assert(MB_SUCCESS == rval); if(MB_SUCCESS != rval) return rval; // for each surface, get the surf sense wrt parent volume std::vector<int> close_senses(close_surfs.size()); for(unsigned i=0; i<close_surfs.size(); ++i) { EntityHandle vols[2]; rval = tool->get_moab_instance()->tag_get_data( *senseTag, &lastSet, 1, vols ); assert(MB_SUCCESS == rval); if(MB_SUCCESS != rval) return rval; if(vols[0] == vols[1]) { std::cerr << "error: surf has positive and negative sense wrt same volume" << std::endl; return MB_FAILURE; } if (*geomVol == vols[0]) { close_senses[i] = 1; } else if(*geomVol == vols[1]) { close_senses[i] = -1; } else { return MB_FAILURE; } } neighborhood.clear(); bool piercing = edge_node_intersect( *t, ray_direction, int_type, close_tris, close_senses, tool->get_moab_instance(), &neighborhood ); if(!piercing) continue; } else { neighborhood.clear(); neighborhood.push_back( *t ); } // NOTE: add_intersection may modify the 'neg_ray_len' and 'nonneg_ray_len' // members, which will affect subsequent calls to ray_tri_intersect // in this loop. add_intersection( int_dist, *t ); } } return MB_SUCCESS; }
ErrorCode moab::RayIntersectSets::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 1076 of file OrientedBoxTreeTool.cpp.
{ OrientedBox box; ErrorCode rval = tool->box( node, box ); assert(MB_SUCCESS == rval); if (MB_SUCCESS != rval) return rval; descend = box.intersect_ray( ray_origin, ray_direction, tol, nonneg_ray_len, neg_ray_len ); if (lastSet && depth <= lastSetDepth) lastSet = 0; if (descend && !lastSet) { Range tmp_sets; rval = tool->get_moab_instance()->get_entities_by_type( node, MBENTITYSET, tmp_sets ); assert(MB_SUCCESS == rval); if (MB_SUCCESS != rval) return rval; if (!tmp_sets.empty()) { if (tmp_sets.size() > 1) return MB_FAILURE; lastSet = *tmp_sets.begin(); lastSetDepth = depth; // Get desired orientation of surface wrt volume. Use this to return only // exit or entrance intersections. if(geomVol && senseTag && desiredOrient && surfTriOrient) { if(1!=*desiredOrient && -1!=*desiredOrient) { std::cerr << "error: desired orientation must be 1 (forward) or -1 (reverse)" << std::endl; } EntityHandle vols[2]; rval = tool->get_moab_instance()->tag_get_data( *senseTag, &lastSet, 1, vols ); assert(MB_SUCCESS == rval); if(MB_SUCCESS != rval) return rval; if(vols[0] == vols[1]) { std::cerr << "error: surface has positive and negative sense wrt same volume" << std::endl; return MB_FAILURE; } // surfTriOrient will be used by plucker_ray_tri_intersect to avoid // intersections with wrong orientation. if (*geomVol == vols[0]) { *surfTriOrient = *desiredOrient*1; } else if(*geomVol == vols[1]) { *surfTriOrient = *desiredOrient*(-1); } else { assert(false); return MB_FAILURE; } } } } return MB_SUCCESS; }
const int* moab::RayIntersectSets::desiredOrient [private] |
Definition at line 1004 of file OrientedBoxTreeTool.cpp.
std::vector<EntityHandle>& moab::RayIntersectSets::facets [private] |
Definition at line 997 of file OrientedBoxTreeTool.cpp.
const EntityHandle* moab::RayIntersectSets::geomVol [private] |
Definition at line 1001 of file OrientedBoxTreeTool.cpp.
std::vector<double>& moab::RayIntersectSets::intersections [private] |
Definition at line 995 of file OrientedBoxTreeTool.cpp.
EntityHandle moab::RayIntersectSets::lastSet [private] |
Definition at line 1017 of file OrientedBoxTreeTool.cpp.
int moab::RayIntersectSets::lastSetDepth [private] |
Definition at line 1018 of file OrientedBoxTreeTool.cpp.
const int moab::RayIntersectSets::minTolInt [private] |
Definition at line 992 of file OrientedBoxTreeTool.cpp.
const double* moab::RayIntersectSets::neg_ray_len [private] |
Definition at line 988 of file OrientedBoxTreeTool.cpp.
std::vector<EntityHandle> moab::RayIntersectSets::neighborhood [private] |
Definition at line 1020 of file OrientedBoxTreeTool.cpp.
std::vector< std::vector<EntityHandle> > moab::RayIntersectSets::neighborhoods [private] |
Definition at line 1019 of file OrientedBoxTreeTool.cpp.
const double* moab::RayIntersectSets::nonneg_ray_len [private] |
Definition at line 987 of file OrientedBoxTreeTool.cpp.
const std::vector<EntityHandle>* moab::RayIntersectSets::prevFacets [private] |
Definition at line 1012 of file OrientedBoxTreeTool.cpp.
const CartVect moab::RayIntersectSets::ray_direction [private] |
Definition at line 986 of file OrientedBoxTreeTool.cpp.
const CartVect moab::RayIntersectSets::ray_origin [private] |
Definition at line 985 of file OrientedBoxTreeTool.cpp.
unsigned int* moab::RayIntersectSets::raytri_test_count [private] |
Definition at line 1016 of file OrientedBoxTreeTool.cpp.
const EntityHandle* moab::RayIntersectSets::rootSet [private] |
Definition at line 1000 of file OrientedBoxTreeTool.cpp.
const Tag* moab::RayIntersectSets::senseTag [private] |
Definition at line 1002 of file OrientedBoxTreeTool.cpp.
std::vector<EntityHandle>& moab::RayIntersectSets::sets [private] |
Definition at line 996 of file OrientedBoxTreeTool.cpp.
int* moab::RayIntersectSets::surfTriOrient [private] |
Definition at line 1008 of file OrientedBoxTreeTool.cpp.
int moab::RayIntersectSets::surfTriOrient_val [private] |
Definition at line 1009 of file OrientedBoxTreeTool.cpp.
const double moab::RayIntersectSets::tol [private] |
Definition at line 989 of file OrientedBoxTreeTool.cpp.
OrientedBoxTreeTool* moab::RayIntersectSets::tool [private] |
Definition at line 984 of file OrientedBoxTreeTool.cpp.