moab
|
#include <FBEngine.hpp>
Public Member Functions | |
FBEngine (Interface *impl, GeomTopoTool *geomTopoTool=NULL, const bool smooth=false) | |
~FBEngine () | |
ErrorCode | Init () |
ErrorCode | getRootSet (EntityHandle *root_set) |
ErrorCode | getNumEntSets (EntityHandle set, int num_hops, int *all_sets) |
ErrorCode | createEntSet (int isList, EntityHandle *pSet) |
ErrorCode | addEntSet (EntityHandle entity_set_to_add, EntityHandle entity_set_handle) |
ErrorCode | getEntities (EntityHandle root_set, int ent_type, Range &gentities) |
ErrorCode | addEntArrToSet (Range entities, EntityHandle set) |
ErrorCode | getNumOfType (EntityHandle set, int ent_type, int *pNum) |
ErrorCode | getEntType (EntityHandle gent, int *type) |
ErrorCode | getEntBoundBox (EntityHandle this_gent, double *x0, double *y0, double *z0, double *x1, double *y1, double *z1) |
ErrorCode | getEntClosestPt (EntityHandle this_gent, double x, double y, double z, double *x1, double *y1, double *y3) |
ErrorCode | getVtxCoord (EntityHandle this_gent, double *x0, double *y0, double *z0) |
ErrorCode | gsubtract (EntityHandle entity_set_1, EntityHandle entity_set_2, EntityHandle result_entity_set) |
ErrorCode | getEntNrmlXYZ (EntityHandle entity_handle, double x, double y, double z, double *nrml_i, double *nrml_j, double *nrml_k) |
ErrorCode | getPntRayIntsct (double x, double y, double z, double dir_x, double dir_y, double dir_z, std::vector< EntityHandle > &intersect_entity_handles, std::vector< double > &intersect_coords, std::vector< double > ¶m_coords) |
ErrorCode | createTag (const char *tag_name, int tag_num_type_values, int tag_type, Tag &tag_handle_out) |
Interface * | moab_instance () |
ErrorCode | getArrData (const moab::EntityHandle *entity_handles, int entity_handles_size, Tag tag_handle, void *tag_values_out) |
ErrorCode | setArrData (const EntityHandle *entity_handles, int entity_handles_size, Tag tag_handle, const void *tag_values) |
ErrorCode | getEntAdj (EntityHandle handle, int type_requested, Range &adjEnts) |
ErrorCode | getEgFcSense (EntityHandle mbedge, EntityHandle mbface, int &sense) |
ErrorCode | measure (const EntityHandle *moab_entities, int entities_size, double *measures) |
ErrorCode | getEntNrmlSense (EntityHandle face, EntityHandle region, int &sense) |
ErrorCode | getEgEvalXYZ (EntityHandle edge, double x, double y, double z, double &on_x, double &on_y, double &on_z, double &tngt_i, double &tngt_j, double &tngt_k, double &cvtr_i, double &cvtr_j, double &cvtr_k) |
ErrorCode | getFcEvalXYZ (EntityHandle face, double x, double y, double z, double &on_x, double &on_y, double &on_z, double &nrml_i, double &nrml_j, double &nrml_k, double &cvtr1_i, double &cvtr1_j, double &cvtr1_k, double &cvtr2_i, double &cvtr2_j, double &cvtr2_k) |
ErrorCode | getEgVtxSense (EntityHandle edge, EntityHandle vtx1, EntityHandle vtx2, int &sense) |
ErrorCode | getEntURange (EntityHandle edge, double &u_min, double &u_max) |
ErrorCode | getEntUtoXYZ (EntityHandle edge, double u, double &x, double &y, double &z) |
ErrorCode | getEntTgntU (EntityHandle edge, double u, double &i, double &j, double &k) |
ErrorCode | isEntAdj (EntityHandle entity1, EntityHandle entity2, bool &adjacent_out) |
ErrorCode | split_surface_with_direction (EntityHandle face, std::vector< double > &xyz, double *direction, int closed, double min_dot, EntityHandle &oNewFace) |
ErrorCode | split_surface (EntityHandle face, std::vector< EntityHandle > &chainedEdges, std::vector< EntityHandle > &splittingNodes, EntityHandle &newFace) |
ErrorCode | split_edge_at_point (EntityHandle edge, CartVect &point, EntityHandle &new_edge) |
ErrorCode | split_edge_at_mesh_node (EntityHandle edge, EntityHandle node, EntityHandle &new_edge) |
ErrorCode | split_bedge_at_new_mesh_node (EntityHandle b_edge, EntityHandle atNode, EntityHandle brokenEdge, EntityHandle &new_edge) |
void | clean () |
void | delete_smooth_tags () |
GeomTopoTool * | get_gtt () |
ErrorCode | create_volume_with_direction (EntityHandle newFace1, EntityHandle newFace2, double *direction, EntityHandle &volume) |
ErrorCode | get_nodes_from_edge (EntityHandle gedge, std::vector< EntityHandle > &nodes) |
ErrorCode | weave_lateral_face_from_edges (EntityHandle bEdge, EntityHandle tEdge, double *direction, EntityHandle &newLatFace) |
ErrorCode | chain_edges (double min_dot) |
ErrorCode | chain_two_edges (EntityHandle edge, EntityHandle next_edge) |
ErrorCode | get_vert_edges (EntityHandle edge, EntityHandle &v1, EntityHandle &v2) |
void | set_smooth () |
Private Member Functions | |
ErrorCode | initializeSmoothing () |
ErrorCode | getAdjacentEntities (const EntityHandle from, const int to_dim, Range &adj_ents) |
ErrorCode | compute_intersection_points (EntityHandle &face, EntityHandle from, EntityHandle to, CartVect &Dir, std::vector< CartVect > &points, std::vector< EntityHandle > &entities, std::vector< EntityHandle > &triangles) |
ErrorCode | BreakTriangle (EntityHandle tri, EntityHandle e1, EntityHandle e3, EntityHandle n1, EntityHandle n2, EntityHandle n3) |
ErrorCode | BreakTriangle2 (EntityHandle tri, EntityHandle e1, EntityHandle e2, EntityHandle n1, EntityHandle n2) |
void | print_debug_triangle (EntityHandle triangle) |
ErrorCode | create_new_gedge (std::vector< EntityHandle > &nodesAlongPolyline, EntityHandle &new_geo_edge) |
ErrorCode | separate (EntityHandle face, std::vector< EntityHandle > &chainedEdges, Range &first, Range &second) |
ErrorCode | smooth_new_intx_points (EntityHandle face, std::vector< EntityHandle > &chainedEdges) |
ErrorCode | split_boundary (EntityHandle face, EntityHandle atNode) |
bool | find_vertex_set_for_node (EntityHandle iNode, EntityHandle &oVertexSet) |
ErrorCode | redistribute_boundary_edges_to_faces (EntityHandle face, EntityHandle newFace, std::vector< EntityHandle > &chainedEdges) |
ErrorCode | set_neumann_tags (EntityHandle face, EntityHandle newFace) |
ErrorCode | split_quads () |
ErrorCode | boundary_nodes_on_face (EntityHandle face, std::vector< EntityHandle > &boundary_nodes) |
ErrorCode | boundary_mesh_edges_on_face (EntityHandle face, Range &boundary_mesh_edges) |
ErrorCode | split_internal_edge (EntityHandle &edge, EntityHandle &newVertex) |
ErrorCode | divide_triangle (EntityHandle triangle, EntityHandle &newVertex) |
ErrorCode | set_default_neumann_tags () |
ErrorCode | chain_able_edge (EntityHandle edge, double min_dot, EntityHandle &next_edge, bool &chainable) |
Private Attributes | |
Interface * | _mbImpl |
GeomTopoTool * | _my_geomTopoTool |
bool | _t_created |
bool | _smooth |
bool | _initialized |
Range | _my_gsets [5] |
std::map< EntityHandle, SmoothFace * > | _faces |
std::map< EntityHandle, SmoothCurve * > | _edges |
SmoothFace ** | _smthFace |
SmoothCurve ** | _smthCurve |
Range | _piercedTriangles |
Range | _newTriangles |
Range | _piercedEdges |
std::map< EntityHandle, EntityHandle > | _brokenEdges |
Definition at line 23 of file FBEngine.hpp.
moab::FBEngine::FBEngine | ( | Interface * | impl, |
GeomTopoTool * | geomTopoTool = NULL , |
||
const bool | smooth = false |
||
) |
Definition at line 183 of file FBEngine.cpp.
: _mbImpl(impl), _my_geomTopoTool(topoTool), _t_created(false), _smooth(smooth), _initialized(false), _smthFace(NULL), _smthCurve(NULL) { if (!_my_geomTopoTool) { _my_geomTopoTool = new GeomTopoTool(_mbImpl); _t_created = true; } // should this be part of the constructor or not? //Init(); }
Definition at line 194 of file FBEngine.cpp.
ErrorCode moab::FBEngine::addEntArrToSet | ( | Range | entities, |
EntityHandle | set | ||
) |
Definition at line 474 of file FBEngine.cpp.
ErrorCode moab::FBEngine::addEntSet | ( | EntityHandle | entity_set_to_add, |
EntityHandle | entity_set_handle | ||
) |
Definition at line 479 of file FBEngine.cpp.
{ return MBI->add_entities(entity_set_handle, &entity_set_to_add, 1); }
ErrorCode moab::FBEngine::boundary_mesh_edges_on_face | ( | EntityHandle | face, |
Range & | boundary_mesh_edges | ||
) | [private] |
Definition at line 3021 of file FBEngine.cpp.
{ // this list is used only for finding the intersecting mesh edge for starting the // polygonal cutting line at boundary (if !closed) Range bound_edges; ErrorCode rval = getAdjacentEntities(face, 1, bound_edges); MBERRORR(rval, " can't get boundary edges"); for (Range::iterator it =bound_edges.begin(); it!=bound_edges.end(); it++ ) { EntityHandle b_edge = *it; // get all edges in range //Range mesh_edges; rval = _mbImpl->get_entities_by_dimension(b_edge, 1, boundary_mesh_edges); MBERRORR(rval, " can't get mesh edges"); } return MB_SUCCESS; }
ErrorCode moab::FBEngine::boundary_nodes_on_face | ( | EntityHandle | face, |
std::vector< EntityHandle > & | boundary_nodes | ||
) | [private] |
Definition at line 3039 of file FBEngine.cpp.
{ // even if we repeat some nodes, it is OK // this list is used only for finding the closest boundary node for starting the // polygonal cutting line at boundary (if !closed) Range bound_edges; ErrorCode rval = getAdjacentEntities(face, 1, bound_edges); MBERRORR(rval, " can't get boundary edges"); Range b_nodes; for (Range::iterator it =bound_edges.begin(); it!=bound_edges.end(); it++ ) { EntityHandle b_edge = *it; // get all edges in range Range mesh_edges; rval = _mbImpl->get_entities_by_dimension(b_edge, 1, mesh_edges); MBERRORR(rval, " can't get mesh edges"); rval = _mbImpl->get_connectivity(mesh_edges, b_nodes); MBERRORR(rval, " can't get nodes from mesh edges"); } // create now a vector based on Range of nodes boundary_nodes.resize(b_nodes.size()); std::copy(b_nodes.begin(), b_nodes.end(), boundary_nodes.begin()); return MB_SUCCESS; }
ErrorCode moab::FBEngine::BreakTriangle | ( | EntityHandle | tri, |
EntityHandle | e1, | ||
EntityHandle | e3, | ||
EntityHandle | n1, | ||
EntityHandle | n2, | ||
EntityHandle | n3 | ||
) | [private] |
Definition at line 1937 of file FBEngine.cpp.
{ std::cout<< "FBEngine::BreakTriangle not implemented yet\n"; return MB_FAILURE; }
ErrorCode moab::FBEngine::BreakTriangle2 | ( | EntityHandle | tri, |
EntityHandle | e1, | ||
EntityHandle | e2, | ||
EntityHandle | n1, | ||
EntityHandle | n2 | ||
) | [private] |
Definition at line 1944 of file FBEngine.cpp.
{ // we have the nodes, we just need to reconnect to form new triangles ErrorCode rval; const EntityHandle * conn3; int nnodes; rval = _mbImpl->get_connectivity(tri, conn3, nnodes); MBERRORR(rval, "Failed to get connectivity"); assert(3 == nnodes); EntityType et1= _mbImpl->type_from_handle(e1); EntityType et2= _mbImpl->type_from_handle(e2); if (MBVERTEX == et1) { // find the vertex in conn3, and form 2 other triangles int index =-1; for (index=0; index<3; index++) { if (conn3[index]==e1)// also n1 break; } if (index==3) return MB_FAILURE; // 2 triangles: n1, index+1, n2, and n1, n2, index+2 EntityHandle conn[6]={ n1, conn3[(index+1)%3], n2, n1, n2, conn3[(index+2)%3]}; EntityHandle newTriangle; rval = _mbImpl->create_element(MBTRI, conn, 3, newTriangle); MBERRORR(rval, "Failed to create a new triangle"); _newTriangles.insert(newTriangle); if (debug_splits) print_debug_triangle(newTriangle); rval = _mbImpl->create_element(MBTRI, conn+3, 3, newTriangle);// the second triangle MBERRORR(rval, "Failed to create a new triangle"); _newTriangles.insert(newTriangle); if (debug_splits) print_debug_triangle(newTriangle); return MB_SUCCESS; } else if (MBVERTEX == et2) { int index =-1; for (index=0; index<3; index++) { if (conn3[index]==e2) // also n2 break; } if (index==3) return MB_FAILURE; // 2 triangles: n1, index+1, n2, and n1, n2, index+2 EntityHandle conn[6]={ n2, conn3[(index+1)%3], n1, n2, n1, conn3[(index+2)%3]}; EntityHandle newTriangle; rval = _mbImpl->create_element(MBTRI, conn, 3, newTriangle); MBERRORR(rval, "Failed to create a new triangle"); _newTriangles.insert(newTriangle); if (debug_splits) print_debug_triangle(newTriangle); rval = _mbImpl->create_element(MBTRI, conn+3, 3, newTriangle);// the second triangle MBERRORR(rval, "Failed to create a new triangle"); _newTriangles.insert(newTriangle); if (debug_splits) print_debug_triangle(newTriangle); return MB_SUCCESS; } else { // both are edges adjacent to triangle tri // there are several configurations possible for n1, n2, between conn3 nodes. int num1, num2, sense, offset; rval = _mbImpl->side_number(tri, e1, num1, sense, offset); MBERRORR(rval, "edge not adjacent"); rval = _mbImpl->side_number(tri, e2, num2, sense, offset); MBERRORR(rval, "edge not adjacent"); const EntityHandle * conn12; // connectivity for edge 1 const EntityHandle * conn22; // connectivity for edge 2 //int nnodes; rval = _mbImpl->get_connectivity(e1, conn12, nnodes); MBERRORR(rval, "Failed to get connectivity of edge 1"); assert(2 == nnodes); rval = _mbImpl->get_connectivity(e2, conn22, nnodes); MBERRORR(rval, "Failed to get connectivity of edge 2"); assert(2 == nnodes); // now, having the side number, work through if (debug_splits) { std::cout << "tri conn3:" << conn3[0] << " "<< conn3[1] <<" " << conn3[2] << "\n"; std::cout << " edge1: conn12:" << conn12[0] << " "<< conn12[1] <<" side: " << num1 << "\n"; std::cout << " edge2: conn22:" << conn22[0] << " "<< conn22[1] <<" side: " << num2 << "\n"; } int unaffectedSide = 3-num1-num2; int i3 = (unaffectedSide+2)%3;// to 0 is 2, to 1 is 0, to 2 is 1 // triangles will be formed with triVertexIndex , n1, n2 (in what order?) EntityHandle v1, v2; // to hold the 2 nodes on edges if (num1==i3) { v1 = n1; v2 = n2; } else // if (num2==i3) { v1 = n2; v2 = n1; } // three triangles are formed int i1 = (i3+1)%3; int i2 = (i3+2)%3; // we could break the surface differently EntityHandle conn[9]={ conn3[i3], v1, v2, v1, conn3[i1], conn3[i2], v2, v1, conn3[i2]}; EntityHandle newTriangle; if (debug_splits) std::cout << "Split 2 edges :\n"; rval = _mbImpl->create_element(MBTRI, conn, 3, newTriangle); MBERRORR(rval, "Failed to create a new triangle"); _newTriangles.insert(newTriangle); if (debug_splits) print_debug_triangle(newTriangle); rval = _mbImpl->create_element(MBTRI, conn+3, 3, newTriangle);// the second triangle MBERRORR(rval, "Failed to create a new triangle"); _newTriangles.insert(newTriangle); if (debug_splits) print_debug_triangle(newTriangle); rval = _mbImpl->create_element(MBTRI, conn+6, 3, newTriangle);// the second triangle MBERRORR(rval, "Failed to create a new triangle"); _newTriangles.insert(newTriangle); if (debug_splits) print_debug_triangle(newTriangle); return MB_SUCCESS; } return MB_SUCCESS; }
ErrorCode moab::FBEngine::chain_able_edge | ( | EntityHandle | edge, |
double | min_dot, | ||
EntityHandle & | next_edge, | ||
bool & | chainable | ||
) | [private] |
Definition at line 3639 of file FBEngine.cpp.
{ // get the end, then get all parents of end // see if some are the starts of chainable = false; EntityHandle v1, v2; ErrorCode rval = get_vert_edges(edge, v1, v2); MBERRORR(rval, "can't get vertices"); if (v1==v2) return MB_SUCCESS;// it is periodic, can't chain it with another edge! // v2 is a set, get its parents, which should be edges Range edges; rval = _mbImpl->get_parent_meshsets(v2, edges); MBERRORR(rval, "can't get parents of vertex set"); // get parents of current edge (faces) Range faces; rval = _mbImpl->get_parent_meshsets(edge, faces); MBERRORR(rval, "can't get parents of edge set"); // get also the last edge "tangent" at the vertex std::vector<EntityHandle> mesh_edges; rval = _mbImpl->get_entities_by_type(edge, MBEDGE, mesh_edges); MBERRORR(rval, "can't get mesh edges from edge set"); EntityHandle lastMeshEdge= mesh_edges[mesh_edges.size()-1]; const EntityHandle * conn2; int len; rval = _mbImpl->get_connectivity(lastMeshEdge, conn2, len); MBERRORR(rval, "can't connectivity of last mesh edge"); // get the coordinates of last edge if (len!=2) MBERRORR(MB_FAILURE, "bad number of vertices"); CartVect P[2]; rval = _mbImpl->get_coords(conn2, len, (double*) &P[0]); MBERRORR(rval, "Failed to get coordinates"); CartVect vec1(P[1] - P[0]); vec1.normalize(); for (Range::iterator edgeIter = edges.begin(); edgeIter!=edges.end(); edgeIter++) { EntityHandle otherEdge = *edgeIter; if (edge==otherEdge) continue; // get faces parents of this edge Range faces2; rval = _mbImpl->get_parent_meshsets(otherEdge, faces2); MBERRORR(rval, "can't get parents of other edge set"); if (faces!=faces2) continue; // now, if the first mesh edge is within given angle, we can go on std::vector<EntityHandle> mesh_edges2; rval = _mbImpl->get_entities_by_type(otherEdge, MBEDGE, mesh_edges2); MBERRORR(rval, "can't get mesh edges from other edge set"); EntityHandle firstMeshEdge= mesh_edges2[0]; const EntityHandle * conn22; int len2; rval = _mbImpl->get_connectivity(firstMeshEdge, conn22, len2); MBERRORR(rval, "can't connectivity of first mesh edge"); if (len2!=2) MBERRORR(MB_FAILURE, "bad number of vertices"); if (conn2[1]!=conn22[0]) continue; // the mesh edges are not one after the other // get the coordinates of first edge //CartVect P2[2]; rval = _mbImpl->get_coords(conn22, len, (double*) &P[0]); CartVect vec2(P[1] - P[0]); vec2.normalize(); if (vec1%vec2 < min_dot) continue; // we found our edge, victory! we can get out next_edge = otherEdge; chainable = true; return MB_SUCCESS; } return MB_SUCCESS;// in general, hard to come by chain-able edges }
ErrorCode moab::FBEngine::chain_edges | ( | double | min_dot | ) |
Definition at line 3601 of file FBEngine.cpp.
{ Range sets[5]; ErrorCode rval; while (1)// break out only if no edges are chained { rval = _my_geomTopoTool->find_geomsets(sets); MBERRORR(rval, "can't get geo sets"); // these gentities are "always" current, while the ones in this-> _my_gsets[0:4] are // the "originals" before FBEngine modifications int nedges=(int)sets[1].size(); // as long as we have chainable edges, continue; bool chain=false; for (int i=0; i<nedges; i++) { EntityHandle edge=sets[1][i]; EntityHandle next_edge; bool chainable=false; rval = chain_able_edge(edge, min_dot, next_edge, chainable); MBERRORR(rval, "can't determine chain-ability"); if ( chainable ) { rval = chain_two_edges(edge, next_edge); MBERRORR(rval, "can't chain 2 edges"); chain = true; break; // interrupt for loop } } if (!chain) { break; // break out of while loop } } return MB_SUCCESS; }
ErrorCode moab::FBEngine::chain_two_edges | ( | EntityHandle | edge, |
EntityHandle | next_edge | ||
) |
Definition at line 3719 of file FBEngine.cpp.
{ // the biggest thing is to see the sense tags; or maybe not... // they should be correct :) // get the vertex sets EntityHandle v11, v12, v21, v22; ErrorCode rval = get_vert_edges( edge, v11, v12); MBERRORR(rval, "can't get vert sets"); rval = get_vert_edges( next_edge, v21, v22); MBERRORR(rval, "can't get vert sets"); assert(v12==v21); std::vector<EntityHandle> mesh_edges; rval = MBI->get_entities_by_type(next_edge, MBEDGE, mesh_edges); MBERRORR(rval, "can't get mesh edges"); rval = _mbImpl->add_entities(edge, &mesh_edges[0], (int)mesh_edges.size()); MBERRORR(rval, "can't add new mesh edges"); // remove the child - parent relation for second vertex of first edge rval = _mbImpl->remove_parent_child(edge, v12); MBERRORR(rval, "can't remove parent - child relation between first edge and middle vertex"); if (v22!=v11) // the edge would become periodic, do not add again the relationship { rval = _mbImpl->add_parent_child(edge, v22); MBERRORR(rval, "can't add second vertex to edge "); } // we can now safely eliminate next_edge rval = _mbImpl->remove_parent_child(next_edge, v21); MBERRORR(rval, "can't remove child - parent relation "); rval = _mbImpl->remove_parent_child(next_edge, v22); MBERRORR(rval, "can't remove child - parent relation "); // remove the next_edge relation to the faces Range faces; rval = _mbImpl->get_parent_meshsets(next_edge, faces); MBERRORR(rval, "can't get parent faces "); for (Range::iterator it=faces.begin(); it!=faces.end(); it++) { EntityHandle ff=*it; rval = _mbImpl->remove_parent_child(ff, next_edge); MBERRORR(rval, "can't remove parent-edge rel "); } rval = _mbImpl->delete_entities(&next_edge, 1); MBERRORR(rval, "can't remove edge set "); // delete the vertex set that is idle now (v12 = v21) rval = _mbImpl->delete_entities(&v12, 1); MBERRORR(rval, "can't remove edge set "); return MB_SUCCESS; }
void moab::FBEngine::clean | ( | ) |
Definition at line 200 of file FBEngine.cpp.
{ if (_smooth) { _faces.clear(); _edges.clear(); int size1 = _my_gsets[1].size(); int i = 0; for (i = 0; i < size1; i++) delete _smthCurve[i]; delete[] _smthCurve; _smthCurve = NULL; size1 = _my_gsets[2].size(); for (i = 0; i < size1; i++) delete _smthFace[i]; delete[] _smthFace; _smthFace = NULL; //_smooth = false; } for (int j = 0; j < 5; j++) _my_gsets[j].clear(); if (_t_created) delete _my_geomTopoTool; _my_geomTopoTool = NULL; _t_created = false; }
ErrorCode moab::FBEngine::compute_intersection_points | ( | EntityHandle & | face, |
EntityHandle | from, | ||
EntityHandle | to, | ||
CartVect & | Dir, | ||
std::vector< CartVect > & | points, | ||
std::vector< EntityHandle > & | entities, | ||
std::vector< EntityHandle > & | triangles | ||
) | [private] |
Definition at line 2084 of file FBEngine.cpp.
{ // keep a stack of triangles to process, and do not add those already processed // either mark them, or maybe keep them in a local set? // from and to are now nodes, start from them CartVect p1, p2;// the position of from and to ErrorCode rval = _mbImpl->get_coords(&from, 1, (double *)&p1); MBERRORR(rval, "failed to get 'from' coordinates"); rval = _mbImpl->get_coords(&to, 1, (double *)&p2); MBERRORR(rval, "failed to get 'from' coordinates"); CartVect vect(p2 - p1); double dist2 = vect.length(); if (dist2 < tolerance_segment) { // we are done, return return MB_SUCCESS; } CartVect normPlane = Dir * vect; normPlane.normalize(); std::set<EntityHandle> visitedTriangles; CartVect currentPoint = p1; // push the current point if it is empty if (points.size() == 0) { points.push_back(p1); entities.push_back(from);// this is a node now } // these will be used in many loops CartVect intx = p1;// somewhere to start double param = -1.; // first intersection EntityHandle currentBoundary = from;// it is a node, in the beginning vect = p2 - currentPoint; while (vect.length() > 0.) { // advance towards "to" node, from boundary handle EntityType etype = _mbImpl->type_from_handle(currentBoundary); //if vertex, look for other triangles connected which intersect our plane (defined by p1, p2, dir) std::vector<EntityHandle> adj_tri; rval = _mbImpl->get_adjacencies(¤tBoundary, 1, 2, false, adj_tri); unsigned int j = 0; EntityHandle tri; for (; j < adj_tri.size(); j++) { tri = adj_tri[j]; if (visitedTriangles.find(tri) != visitedTriangles.end()) continue;// get another triangle, this one was already visited // check if it is one of the triangles that was pierced already if (_piercedTriangles.find(tri) != _piercedTriangles.end()) continue; // if vertex, look for opposite edge // if edge, look for 2 opposite edges // get vertices int nnodes; const EntityHandle * conn3; rval = _mbImpl->get_connectivity(tri, conn3, nnodes); MBERRORR(rval, "Failed to get connectivity"); // if one of the nodes is to, stop right there { if (conn3[0]==to || conn3[1]==to || conn3[2]==to) { visitedTriangles.insert(tri); triangles.push_back(tri); currentPoint = p2; points.push_back(p2); entities.push_back(to);// we are done break;// this is break from for loop, we still need to get out of while // we will get out, because vect will become 0, (p2-p2) } } EntityHandle nn2[2]; if (MBVERTEX == etype) { nn2[0] = conn3[0]; nn2[1] = conn3[1]; if (nn2[0] == currentBoundary) nn2[0] = conn3[2]; if (nn2[1] == currentBoundary) nn2[1] = conn3[2]; // get coordinates CartVect Pt[2]; rval = _mbImpl->get_coords(nn2, 2, (double*) &Pt[0]); MBERRORR(rval, "Failed to get coordinates"); // see the intersection if (intersect_segment_and_plane_slice(Pt[0], Pt[1], currentPoint, p2, Dir, normPlane, intx, param)) { // we should stop for loop, and decide if it is edge or vertex if (param == 0.) currentBoundary = nn2[0]; else { if (param == 1.) currentBoundary = nn2[1]; else // param between 0 and 1, so edge { //find the edge between vertices std::vector<EntityHandle> edges1; // change the create flag to true, because that edge must exist in current triangle // if we want to advance; nn2 are 2 nodes in current triangle!! rval = _mbImpl->get_adjacencies(nn2, 2, 1, true, edges1, Interface::INTERSECT); MBERRORR(rval, "Failed to get edges"); if (edges1.size() != 1) MBERRORR(MB_FAILURE, "Failed to get adjacent edges to 2 nodes"); currentBoundary = edges1[0]; } } visitedTriangles.insert(tri); currentPoint = intx; points.push_back(intx); entities.push_back(currentBoundary); triangles.push_back(tri); if (debug_splits) std::cout << "vtx new tri : " << _mbImpl->id_from_handle(tri) << " type bdy:" << _mbImpl->type_from_handle(currentBoundary) << "\n"; break; // out of for loop over triangles } } else // this is MBEDGE, we have the other triangle to try out { //first find the nodes from existing boundary int nnodes2; const EntityHandle * conn2; rval = _mbImpl->get_connectivity(currentBoundary, conn2, nnodes2); MBERRORR(rval, "Failed to get connectivity"); int thirdIndex = -1; for (int tj = 0; tj < 3; tj++) { if ((conn3[tj] != conn2[0]) && (conn3[tj] != conn2[1])) { thirdIndex = tj; break; } } if (-1 == thirdIndex) MBERRORR(MB_FAILURE, " can't get third node"); CartVect Pt[3]; rval = _mbImpl->get_coords(conn3, 3, (double*) &Pt[0]); MBERRORR(rval, "Failed to get coords"); int indexFirst = (thirdIndex + 1) % 3; int indexSecond = (thirdIndex + 2) % 3; int index[2] = { indexFirst, indexSecond }; for (int k = 0; k < 2; k++) { nn2[0] = conn3[index[k]], nn2[1] = conn3[thirdIndex]; if (intersect_segment_and_plane_slice(Pt[index[k]], Pt[thirdIndex], currentPoint, p2, Dir, normPlane, intx, param)) { // we should stop for loop, and decide if it is edge or vertex if (param == 0.) currentBoundary = conn3[index[k]];//it is not really possible else { if (param == 1.) currentBoundary = conn3[thirdIndex]; else // param between 0 and 1, so edge is fine { //find the edge between vertices std::vector<EntityHandle> edges1; // change the create flag to true, because that edge must exist in current triangle // if we want to advance; nn2 are 2 nodes in current triangle!! rval = _mbImpl->get_adjacencies(nn2, 2, 1, true, edges1, Interface::INTERSECT); MBERRORR(rval, "Failed to get edges"); if (edges1.size() != 1) MBERRORR(MB_FAILURE, "Failed to get adjacent edges to 2 nodes"); currentBoundary = edges1[0]; } } visitedTriangles.insert(tri); currentPoint = intx; points.push_back(intx); entities.push_back(currentBoundary); triangles.push_back(tri); if (debug_splits) { std::cout << "edge new tri : " << _mbImpl->id_from_handle(tri) << " type bdy: " << _mbImpl->type_from_handle( currentBoundary) << " id: " << _mbImpl->id_from_handle(currentBoundary) << "\n"; _mbImpl->list_entity(currentBoundary); } break; // out of for loop over triangles } // we should not reach here } } } /*if (j==adj_tri.size()) { MBERRORR(MB_FAILURE, "did not advance"); }*/ vect = p2 - currentPoint; } if (debug_splits) std::cout << "nb entities: " << entities.size() << " triangles:" << triangles.size() << " points.size(): " << points.size() << "\n"; return MB_SUCCESS; }
ErrorCode moab::FBEngine::create_new_gedge | ( | std::vector< EntityHandle > & | nodesAlongPolyline, |
EntityHandle & | new_geo_edge | ||
) | [private] |
Definition at line 1819 of file FBEngine.cpp.
{ ErrorCode rval = _mbImpl->create_meshset(MESHSET_ORDERED, new_geo_edge); MBERRORR(rval, "can't create geo edge"); // now, get the edges, or create if not existing std::vector<EntityHandle> mesh_edges; for (unsigned int i=0; i<nodesAlongPolyline.size()-1; i++) { EntityHandle n1 = nodesAlongPolyline[i], n2 = nodesAlongPolyline[i+1]; EntityHandle nn2[2]; nn2[0] = n1; nn2[1] = n2; std::vector<EntityHandle> adjacent; rval = _mbImpl->get_adjacencies(nn2, 2, 1, false, adjacent, Interface::INTERSECT); // see if there is an edge between those 2 already, and if it is oriented as we like bool new_edge = true; if (adjacent.size()>=1) { // check the orientation const EntityHandle * conn2; int nnodes; rval = _mbImpl->get_connectivity(adjacent[0], conn2, nnodes); MBERRORR(rval, "can't get connectivity"); if (conn2[0]==nn2[0] && conn2[1]==nn2[1]) { // everything is fine mesh_edges.push_back(adjacent[0]); new_edge = false;// we found one that's good, no need to create a new one } else { _piercedEdges.insert(adjacent[0]);// we want to remove this one, it will be not needed } } if (new_edge) { // there is no edge between n1 and n2, create one EntityHandle mesh_edge; rval = _mbImpl->create_element(MBEDGE, nn2, 2, mesh_edge); MBERRORR(rval, "Failed to create a new edge"); mesh_edges.push_back(mesh_edge); } } // add loops edges to the edge set rval = _mbImpl->add_entities(new_geo_edge, &mesh_edges[0], mesh_edges.size());// only one edge MBERRORR(rval, "can't add edges to new_geo_set"); // check vertex sets for vertex 1 and vertex 2? // get all sets of dimension 0 from database, and see if our ends are here or not Range ends_geo_edge; ends_geo_edge.insert(nodesAlongPolyline[0]); ends_geo_edge.insert(nodesAlongPolyline[nodesAlongPolyline.size()-1]); for (unsigned int k = 0; k<ends_geo_edge.size(); k++ ) { EntityHandle node = ends_geo_edge[k]; EntityHandle nodeSet; bool found=find_vertex_set_for_node(node, nodeSet); if (!found) { // create a node set and add the node rval = _mbImpl->create_meshset(MESHSET_SET, nodeSet); MBERRORR(rval, "Failed to create a new vertex set"); rval = _mbImpl->add_entities(nodeSet, &node, 1); MBERRORR(rval, "Failed to add the node to the set"); rval = _my_geomTopoTool->add_geo_set(nodeSet, 0);// MBERRORR(rval, "Failed to commit the node set"); if (debug_splits) { std::cout<<" create a vertex set " << _mbImpl->id_from_handle(nodeSet) << " global id:"<< this->_my_geomTopoTool->global_id(nodeSet) << " for node " << node << "\n"; } } rval = _mbImpl ->add_parent_child( new_geo_edge, nodeSet); MBERRORR(rval, "Failed to add parent child relation"); } // finally, put the edge in the range of edges _my_geomTopoTool->add_geo_set(new_geo_edge, 1); return rval; }
ErrorCode moab::FBEngine::create_volume_with_direction | ( | EntityHandle | newFace1, |
EntityHandle | newFace2, | ||
double * | direction, | ||
EntityHandle & | volume | ||
) |
Definition at line 3168 of file FBEngine.cpp.
{ // MESHSET // ErrorCode rval = _mbImpl->create_meshset(MESHSET_ORDERED, new_geo_edge); ErrorCode rval = _mbImpl->create_meshset(MESHSET_SET, volume); MBERRORR(rval, "can't create volume"); int volumeMatId = 1;// just give a mat id, for debugging, mostly Tag matTag; rval = _mbImpl->tag_get_handle(MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, matTag); MBERRORR(rval, "can't get material tag"); rval=_mbImpl->tag_set_data(matTag, &volume, 1, &volumeMatId); MBERRORR(rval, "can't set material tag value on volume"); // get the edges of those 2 faces, and get the vertices of those edges // in order, they should be created in the same order (?); check for that, anyway rval=_mbImpl->add_parent_child(volume, newFace1); MBERRORR(rval, "can't add first face to volume"); rval=_mbImpl->add_parent_child(volume, newFace2); MBERRORR(rval, "can't add second face to volume"); // first is bottom, so it is negatively oriented rval = _my_geomTopoTool->add_geo_set(volume, 3); MBERRORR(rval, "can't add volume to the gtt"); // set senses // bottom face is negatively oriented, its normal is toward interior of the volume rval = _my_geomTopoTool->set_sense(newFace1, volume, -1); MBERRORR(rval, "can't set bottom face sense to the volume"); // the top face is positively oriented rval = _my_geomTopoTool->set_sense(newFace2, volume, 1); MBERRORR(rval, "can't set top face sense to the volume"); // the children should be in the same direction // get the side edges of each face, and form lateral faces, along direction std::vector<EntityHandle> edges1; std::vector<EntityHandle> edges2; rval = _mbImpl->get_child_meshsets(newFace1, edges1); // no hops MBERRORR(rval, "can't get children edges or first face, bottom"); rval = _mbImpl->get_child_meshsets(newFace2, edges2); // no hops MBERRORR(rval, "can't get children edges for second face, top"); if (edges1.size()!=edges2.size()) MBERRORR(MB_FAILURE, "wrong correspondence "); for (unsigned int i = 0; i < edges1.size(); ++i) { EntityHandle newLatFace; rval = weave_lateral_face_from_edges(edges1[i], edges2[i], direction, newLatFace); MBERRORR(rval, "can't weave lateral face"); rval=_mbImpl->add_parent_child(volume, newLatFace); MBERRORR(rval, "can't add lateral face to volume"); // set sense as positive rval = _my_geomTopoTool->set_sense(newLatFace, volume, 1); MBERRORR(rval, "can't set lateral face sense to the volume"); } rval = set_default_neumann_tags(); MBERRORR(rval, "can't set new neumann tags"); return MB_SUCCESS; }
ErrorCode moab::FBEngine::createEntSet | ( | int | isList, |
EntityHandle * | pSet | ||
) |
Definition at line 439 of file FBEngine.cpp.
{ ErrorCode rval; if (isList) rval = MBI->create_meshset(MESHSET_ORDERED, *pSet); else rval = MBI->create_meshset(MESHSET_SET, *pSet); return rval; }
ErrorCode moab::FBEngine::createTag | ( | const char * | tag_name, |
int | tag_num_type_values, | ||
int | tag_type, | ||
Tag & | tag_handle_out | ||
) |
Definition at line 862 of file FBEngine.cpp.
{ // this is copied from iMesh_MOAB.cpp; different name to not have trouble // with it // also, we do not want to depend on iMesh.h... // iMesh is more complicated, because of the options passed DataType mb_data_type_table2[] = { MB_TYPE_OPAQUE, MB_TYPE_INTEGER, MB_TYPE_DOUBLE, MB_TYPE_HANDLE, MB_TYPE_HANDLE }; moab::TagType storage = MB_TAG_SPARSE; ErrorCode result; result = MBI->tag_get_handle(tag_name, tag_size, mb_data_type_table2[tag_type], tag_handle_out, storage | MB_TAG_EXCL); if (MB_SUCCESS != result) { std::string msg("iMesh_createTag: "); if (MB_ALREADY_ALLOCATED == result) { msg += "Tag already exists with name: \""; msg += tag_name; std::cout<<msg << "\n"; } else { std::cout<< "Failed to create tag with name: " << tag_name << "\n"; return MB_FAILURE; } } // end copy return MB_SUCCESS; }
void moab::FBEngine::delete_smooth_tags | ( | ) |
Definition at line 374 of file FBEngine.cpp.
{ // get all tags from database that are created for smooth data, and // delete them; it will delete all data associated with them // first tags from faces, edges: std::vector<Tag> smoothTags; int size1 = (int)_my_gsets[2].size(); for (int i=0; i<size1; i++) { // these 2 will append gradient tag and plane tag _smthFace[i]->append_smooth_tags(smoothTags); } // then , get other tags: // "TANGENTS", "MARKER", "CONTROLEDGE", "CONTROLFACE", "CONTROLEDGEFACE" Tag tag_handle; ErrorCode rval = _mbImpl->tag_get_handle( "TANGENTS", 6, MB_TYPE_DOUBLE, tag_handle ); if (rval != MB_TAG_NOT_FOUND) smoothTags.push_back(tag_handle); rval = _mbImpl->tag_get_handle( "MARKER", 1, MB_TYPE_BIT, tag_handle ); if (rval != MB_TAG_NOT_FOUND) smoothTags.push_back(tag_handle); rval = _mbImpl->tag_get_handle( "CONTROLEDGE", 9, MB_TYPE_DOUBLE, tag_handle ); if (rval != MB_TAG_NOT_FOUND) smoothTags.push_back(tag_handle); rval = _mbImpl->tag_get_handle( "CONTROLFACE", 18, MB_TYPE_DOUBLE, tag_handle ); if (rval != MB_TAG_NOT_FOUND) smoothTags.push_back(tag_handle); rval = _mbImpl->tag_get_handle( "CONTROLEDGEFACE", 27, MB_TYPE_DOUBLE, tag_handle ); if (rval != MB_TAG_NOT_FOUND) smoothTags.push_back(tag_handle); // a lot of tags, delete them for (unsigned int k = 0; k<smoothTags.size(); k++ ) { // could be a lot of data _mbImpl->tag_delete(smoothTags[k]); } }
ErrorCode moab::FBEngine::divide_triangle | ( | EntityHandle | triangle, |
EntityHandle & | newVertex | ||
) | [private] |
Definition at line 3122 of file FBEngine.cpp.
{ // _piercedTriangles.insert(triangle); int nnodes; const EntityHandle * conn3; ErrorCode rval = _mbImpl->get_connectivity(triangle, conn3, nnodes); MBERRORR(rval, "can't get nodes"); EntityHandle t1[]={conn3[0], conn3[1], newVertex}; EntityHandle t2[]={conn3[1], conn3[2], newVertex}; EntityHandle t3[]={conn3[2], conn3[0], newVertex}; EntityHandle newTriangle, newTriangle2, newTriangle3; rval = _mbImpl->create_element(MBTRI, t1, 3, newTriangle); MBERRORR(rval, "can't create triangle"); _newTriangles.insert(newTriangle); rval = _mbImpl->create_element(MBTRI, t2, 3, newTriangle3); MBERRORR(rval, "can't create triangle"); _newTriangles.insert(newTriangle3); rval = _mbImpl->create_element(MBTRI, t3, 3, newTriangle2); MBERRORR(rval, "can't create triangle"); _newTriangles.insert(newTriangle2); // create all edges std::vector<EntityHandle> edges0; rval = _mbImpl->get_adjacencies(&newTriangle, 1, 1, true, edges0); MBERRORR(rval, "can't get new edges"); edges0.clear(); rval = _mbImpl->get_adjacencies(&newTriangle2, 1, 1, true, edges0); MBERRORR(rval, "can't get new edges"); if (debug_splits) { std::cout<<"3 triangles formed:\n"; _mbImpl->list_entity(newTriangle); print_debug_triangle(newTriangle); _mbImpl->list_entity(newTriangle3); print_debug_triangle(newTriangle3); _mbImpl->list_entity(newTriangle2); print_debug_triangle(newTriangle2); std::cout<<"original nodes in tri:\n"; _mbImpl->list_entity(conn3[0]); _mbImpl->list_entity(conn3[1]); _mbImpl->list_entity(conn3[2]); } return MB_SUCCESS; }
bool moab::FBEngine::find_vertex_set_for_node | ( | EntityHandle | iNode, |
EntityHandle & | oVertexSet | ||
) | [private] |
Definition at line 2815 of file FBEngine.cpp.
{ bool found = false; Range vertex_sets; const int zero = 0; const void* const zero_val[] = { &zero }; Tag geom_tag; ErrorCode rval = MBI->tag_get_handle(GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag); if (MB_SUCCESS!=rval) return false; rval = _mbImpl->get_entities_by_type_and_tag(0, MBENTITYSET, &geom_tag, zero_val, 1, vertex_sets); if (MB_SUCCESS!=rval) return false; // local _gsets, as we might have not updated the local lists // see if ends of geo edge generated is in a geo set 0 or not for( Range::iterator vsit=vertex_sets.begin(); vsit!=vertex_sets.end(); vsit++) { EntityHandle vset=*vsit; // is the node part of this set? if (_mbImpl->contains_entities(vset, &iNode, 1)) { found = true; oVertexSet = vset; break; } } return found; }
GeomTopoTool* moab::FBEngine::get_gtt | ( | ) | [inline] |
Definition at line 148 of file FBEngine.hpp.
{ return this->_my_geomTopoTool ; }
ErrorCode moab::FBEngine::get_nodes_from_edge | ( | EntityHandle | gedge, |
std::vector< EntityHandle > & | nodes | ||
) |
Definition at line 3239 of file FBEngine.cpp.
{ std::vector<EntityHandle> ents; ErrorCode rval = _mbImpl->get_entities_by_type(gedge, MBEDGE, ents); if (MB_SUCCESS != rval) return rval; if (ents.size() < 1) return MB_FAILURE; nodes.resize(ents.size() +1); const EntityHandle* conn = NULL; int len; for (unsigned int i=0; i<ents.size(); ++i) { rval = _mbImpl->get_connectivity(ents[i], conn, len); MBERRORR(rval, "can't get edge connectivity"); nodes[i] = conn[0]; } // the last one is conn[1] nodes[ents.size()] = conn[1]; return MB_SUCCESS; }
ErrorCode moab::FBEngine::get_vert_edges | ( | EntityHandle | edge, |
EntityHandle & | v1, | ||
EntityHandle & | v2 | ||
) |
Definition at line 3772 of file FBEngine.cpp.
{ // need to decide first or second vertex // important for moab Range children; //EntityHandle v1, v2; ErrorCode rval = _mbImpl->get_child_meshsets(edge, children); MBERRORR(rval, "can't get child meshsets"); if (children.size()==1) { // this is periodic edge, get out early v1 = children[0]; v2 = v1; return MB_SUCCESS; } else if (children.size()>2) MBERRORR(MB_FAILURE, "too many vertices in one edge"); // edge: get one vertex as part of the vertex set Range entities; rval = MBI->get_entities_by_type(children[0], MBVERTEX, entities); MBERRORR(rval, "can't get entities from vertex set"); if (entities.size() < 1) MBERRORR(MB_FAILURE, "no mesh nodes in vertex set"); EntityHandle node0 = entities[0]; // the first vertex entities.clear(); // now get the edges, and get the first node and the last node in sequence of edges // the order is important... // these are ordered sets !! std::vector<EntityHandle> ents; rval = MBI->get_entities_by_type(edge, MBEDGE, ents); MBERRORR(rval, "can't get mesh edges"); if (ents.size() < 1) MBERRORR(MB_FAILURE, "no mesh edges in edge set"); const EntityHandle* conn = NULL; int len; rval = MBI->get_connectivity(ents[0], conn, len); MBERRORR(rval, "can't connectivity of first mesh edge"); if (conn[0]==node0) { v1 = children[0]; v2 = children[1]; } else // the other way around, although we should check (we are paranoid) { v2 = children[0]; v1 = children[1]; } return MB_SUCCESS; }
ErrorCode moab::FBEngine::getAdjacentEntities | ( | const EntityHandle | from, |
const int | to_dim, | ||
Range & | adj_ents | ||
) | [private] |
Definition at line 803 of file FBEngine.cpp.
{ int this_dim = -1; for (int i = 0; i < 4; i++) { if (_my_geomTopoTool->geoRanges()[i].find(from) != _my_geomTopoTool->geoRanges()[i].end()) { this_dim = i; break; } } // check target dimension if (-1 == this_dim) { //ProcessError(iBase_FAILURE, "Entity not a geometry entity."); return MB_FAILURE; } else if (0 > to_dim || 3 < to_dim) { //ProcessError(iBase_FAILURE, "To dimension must be between 0 and 3."); return MB_FAILURE; } else if (to_dim == this_dim) { //ProcessError(iBase_FAILURE, // "To dimension must be different from entity dimension."); return MB_FAILURE; } ErrorCode rval = MB_SUCCESS; adjs.clear(); if (to_dim > this_dim) { int diffDim = to_dim-this_dim; rval = MBI->get_parent_meshsets(from, adjs, diffDim); if (MB_SUCCESS != rval) return rval; if (diffDim>1) { // subtract the parents that come with diffDim-1 hops Range extra; rval = MBI->get_parent_meshsets(from, extra, diffDim-1); if (MB_SUCCESS != rval) return rval; adjs = subtract(adjs, extra); } } else { int diffDim = this_dim - to_dim; rval = MBI->get_child_meshsets(from, adjs, diffDim); if (MB_SUCCESS != rval) return rval; if (diffDim > 1) { // subtract the children that come with diffDim-1 hops Range extra; rval = MBI->get_child_meshsets(from, extra, diffDim-1); if (MB_SUCCESS != rval) return rval; adjs = subtract(adjs, extra); } } return rval; }
ErrorCode moab::FBEngine::getArrData | ( | const moab::EntityHandle * | entity_handles, |
int | entity_handles_size, | ||
Tag | tag_handle, | ||
void * | tag_values_out | ||
) |
Definition at line 898 of file FBEngine.cpp.
{ // responsibility of the user to have tag_values_out properly allocated // only some types of Tags are possible (double, int, etc) return MBI->tag_get_data(tag_handle, entity_handles, entity_handles_size, tag_values_out); }
ErrorCode moab::FBEngine::getEgEvalXYZ | ( | EntityHandle | edge, |
double | x, | ||
double | y, | ||
double | z, | ||
double & | on_x, | ||
double & | on_y, | ||
double & | on_z, | ||
double & | tngt_i, | ||
double & | tngt_j, | ||
double & | tngt_k, | ||
double & | cvtr_i, | ||
double & | cvtr_j, | ||
double & | cvtr_k | ||
) |
Definition at line 1014 of file FBEngine.cpp.
{ return MB_NOT_IMPLEMENTED; // not implemented }
ErrorCode moab::FBEngine::getEgFcSense | ( | EntityHandle | mbedge, |
EntityHandle | mbface, | ||
int & | sense | ||
) |
Definition at line 922 of file FBEngine.cpp.
{ // this one is important, for establishing the orientation of the edges in faces // use senses std::vector<EntityHandle> faces; std::vector<int> senses; // 0 is forward and 1 is backward ErrorCode rval = _my_geomTopoTool->get_senses(mbedge, faces, senses); if (MB_SUCCESS != rval) return rval; for (unsigned int i = 0; i < faces.size(); i++) { if (faces[i] == mbface) { sense_out = senses[i]; return MB_SUCCESS; } } return MB_FAILURE; }
ErrorCode moab::FBEngine::getEgVtxSense | ( | EntityHandle | edge, |
EntityHandle | vtx1, | ||
EntityHandle | vtx2, | ||
int & | sense | ||
) |
Definition at line 1029 of file FBEngine.cpp.
{ // need to decide first or second vertex // important for moab int type; EntityHandle v1, v2; ErrorCode rval = getEntType(vtx1, &type); if (MB_SUCCESS != rval || type != 0) return MB_FAILURE; // edge: get one vertex as part of the vertex set Range entities; rval = MBI->get_entities_by_type(vtx1, MBVERTEX, entities); if (MB_SUCCESS != rval) return rval; if (entities.size() < 1) return MB_FAILURE; v1 = entities[0]; // the first vertex entities.clear(); rval = getEntType(vtx2, &type); if (MB_SUCCESS != rval || type != 0) return MB_FAILURE; rval = MBI->get_entities_by_type(vtx2, MBVERTEX, entities); if (MB_SUCCESS != rval) return rval; if (entities.size() < 1) return MB_FAILURE; v2 = entities[0]; // the first vertex entities.clear(); // now get the edges, and get the first node and the last node in sequence of edges // the order is important... // these are ordered sets !! std::vector<EntityHandle> ents; rval = MBI->get_entities_by_type(edge, MBEDGE, ents); if (MB_SUCCESS != rval) return rval; if (ents.size() < 1) return MB_FAILURE; const EntityHandle* conn = NULL; int len; EntityHandle startNode, endNode; rval = MBI->get_connectivity(ents[0], conn, len); if (MB_SUCCESS != rval) return rval; startNode = conn[0]; rval = MBI->get_connectivity(ents[ents.size() - 1], conn, len); if (MB_SUCCESS != rval) return rval; endNode = conn[1]; sense = 1; // if ((startNode == endNode) && (v1 == startNode)) { sense = 0; // periodic } if ((startNode == v1) && (endNode == v2)) { sense = 1; // forward } if ((startNode == v2) && (endNode == v1)) { sense = -1; // reverse } return MB_SUCCESS; }
ErrorCode moab::FBEngine::getEntAdj | ( | EntityHandle | handle, |
int | type_requested, | ||
Range & | adjEnts | ||
) |
Definition at line 916 of file FBEngine.cpp.
{ return getAdjacentEntities(handle, type_requested, adjEnts); }
ErrorCode moab::FBEngine::getEntBoundBox | ( | EntityHandle | this_gent, |
double * | x0, | ||
double * | y0, | ||
double * | z0, | ||
double * | x1, | ||
double * | y1, | ||
double * | z1 | ||
) |
Definition at line 534 of file FBEngine.cpp.
{ ErrorCode rval; int type; rval = getEntType(gent, &type); MBERRORR(rval, "Failed to get entity type."); if (type == 0) { rval = getVtxCoord(gent, min_x, min_y, min_z); MBERRORR(rval, "Failed to get vertex coordinates."); max_x = min_x; max_y = min_y; max_z = min_z; } else if (type == 1) { rval = MB_FAILURE; MBERRORR(rval, "iGeom_getEntBoundBox is not supported for Edge entity type."); } else if (type == 2 || type == 3) { EntityHandle root; CartVect center, axis[3]; rval = _my_geomTopoTool->get_root(gent, root); MBERRORR(rval, "Failed to get tree root in iGeom_getEntBoundBox."); rval = _my_geomTopoTool->obb_tree()->box(root, center.array(), axis[0].array(), axis[1].array(), axis[2].array()); MBERRORR(rval, "Failed to get closest point in iGeom_getEntBoundBox."); CartVect absv[3]; for (int i = 0; i < 3; i++) { absv[i] = CartVect(fabs(axis[i][0]), fabs(axis[i][1]), fabs(axis[i][2])); } CartVect min, max; min = center - absv[0] - absv[1] - absv[2]; max = center + absv[0] + absv[1] + absv[2]; *min_x = min[0]; *min_y = min[1]; *min_z = min[2]; *max_x = max[0]; *max_y = max[1]; *max_z = max[2]; } else return MB_FAILURE; return MB_SUCCESS; }
ErrorCode moab::FBEngine::getEntClosestPt | ( | EntityHandle | this_gent, |
double | x, | ||
double | y, | ||
double | z, | ||
double * | x1, | ||
double * | y1, | ||
double * | y3 | ||
) |
Definition at line 579 of file FBEngine.cpp.
{ ErrorCode rval; int type; rval = getEntType(this_gent, &type); MBERRORR(rval, "Failed to get entity type."); if (type == 0) { rval = getVtxCoord(this_gent, on_x, on_y, on_z); MBERRORR(rval, "Failed to get vertex coordinates."); } else if (_smooth && type == 1) { *on_x = near_x; *on_y = near_y; *on_z = near_z; SmoothCurve * smthcurve = _edges[this_gent]; // call the new method from smooth edge smthcurve->move_to_curve( *on_x, *on_y, *on_z); } else if (type == 2 || type == 3) { double point[3] = { near_x, near_y, near_z }; double point_out[3]; EntityHandle root, facet_out; if (_smooth && 2 == type) { SmoothFace* smthFace = _faces[this_gent]; *on_x = near_x; *on_y = near_y; *on_z = near_z; smthFace->move_to_surface(*on_x, *on_y, *on_z); } else { rval = _my_geomTopoTool->get_root(this_gent, root); MBERRORR(rval, "Failed to get tree root in iGeom_getEntClosestPt."); rval = _my_geomTopoTool->obb_tree()->closest_to_location(point, root, point_out, facet_out); MBERRORR(rval, "Failed to get closest point in iGeom_getEntClosestPt."); *on_x = point_out[0]; *on_y = point_out[1]; *on_z = point_out[2]; } } else return MB_TYPE_OUT_OF_RANGE; return MB_SUCCESS; }
ErrorCode moab::FBEngine::getEntities | ( | EntityHandle | root_set, |
int | ent_type, | ||
Range & | gentities | ||
) |
Definition at line 451 of file FBEngine.cpp.
{ int i; if (0 > entity_type || 4 < entity_type) { return MB_FAILURE; } else if (entity_type < 4) {// 4 means all entities gentities = _my_geomTopoTool->geoRanges()[entity_type];// all from root set! } else { gentities.clear(); for (i = 0; i < 4; i++) { gentities.merge(_my_geomTopoTool->geoRanges()[i]); } } Range sets; // see now if they are in the set passed as input or not ErrorCode rval = MBI->get_entities_by_type(set_handle, MBENTITYSET, sets); MBERRORR(rval, "can't get sets in the initial set"); gentities = intersect(gentities, sets); return MB_SUCCESS; }
ErrorCode moab::FBEngine::getEntNrmlSense | ( | EntityHandle | face, |
EntityHandle | region, | ||
int & | sense | ||
) |
Definition at line 1008 of file FBEngine.cpp.
{ return MB_NOT_IMPLEMENTED; // not implemented }
ErrorCode moab::FBEngine::getEntNrmlXYZ | ( | EntityHandle | entity_handle, |
double | x, | ||
double | y, | ||
double | z, | ||
double * | nrml_i, | ||
double * | nrml_j, | ||
double * | nrml_k | ||
) |
Definition at line 676 of file FBEngine.cpp.
{ // just do for surface and volume int type; ErrorCode rval = getEntType(entity_handle, &type); MBERRORR(rval, "Failed to get entity type in iGeom_getEntNrmlXYZ."); if (type != 2 && type != 3) { MBERRORR(MB_FAILURE, "Entities passed into gentityNormal must be face or volume."); } if (_smooth && 2 == type) { SmoothFace* smthFace = _faces[entity_handle]; //*on_x = near_x; *on_y = near_y; *on_z = near_z; smthFace-> normal_at(x, y, z, *nrml_i, *nrml_j, *nrml_k); } else { // get closest location and facet double point[3] = { x, y, z }; double point_out[3]; EntityHandle root, facet_out; _my_geomTopoTool->get_root(entity_handle, root); rval = _my_geomTopoTool->obb_tree()->closest_to_location(point, root, point_out, facet_out); MBERRORR(rval , "Failed to get closest location in iGeom_getEntNrmlXYZ."); // get facet normal const EntityHandle* conn; int len; CartVect coords[3], normal; rval = MBI->get_connectivity(facet_out, conn, len); MBERRORR(rval, "Failed to get triangle connectivity in iGeom_getEntNrmlXYZ."); if (len != 3) MBERRORR(MB_FAILURE, " not a triangle, error "); rval = MBI->get_coords(conn, len, coords[0].array()); MBERRORR(rval, "Failed to get triangle coordinates in iGeom_getEntNrmlXYZ."); coords[1] -= coords[0]; coords[2] -= coords[0]; normal = coords[1] * coords[2]; normal.normalize(); *nrml_i = normal[0]; *nrml_j = normal[1]; *nrml_k = normal[2]; } return MB_SUCCESS; }
ErrorCode moab::FBEngine::getEntTgntU | ( | EntityHandle | edge, |
double | u, | ||
double & | i, | ||
double & | j, | ||
double & | k | ||
) |
Definition at line 1112 of file FBEngine.cpp.
{ SmoothCurve * smoothCurve = _edges[edge];// this is a map // now, call smoothCurve methods double tg[3]; double x, y, z; smoothCurve -> position_from_u(u, x, y, z, tg); i = tg[0]; j = tg[1]; k = tg[2]; return MB_SUCCESS; }
ErrorCode moab::FBEngine::getEntType | ( | EntityHandle | gent, |
int * | type | ||
) |
Definition at line 523 of file FBEngine.cpp.
{ for (int i = 0; i < 4; i++) { if (_my_geomTopoTool->geoRanges()[i].find(gent) != _my_geomTopoTool->geoRanges()[i].end()) { *type = i; return MB_SUCCESS; } } *type = -1; // failure return MB_FAILURE; }
ErrorCode moab::FBEngine::getEntURange | ( | EntityHandle | edge, |
double & | u_min, | ||
double & | u_max | ||
) |
Definition at line 1094 of file FBEngine.cpp.
{ SmoothCurve * smoothCurve = _edges[edge];// this is a map // now, call smoothCurve methods smoothCurve -> get_param_range(u_min, u_max); return MB_SUCCESS; }
ErrorCode moab::FBEngine::getEntUtoXYZ | ( | EntityHandle | edge, |
double | u, | ||
double & | x, | ||
double & | y, | ||
double & | z | ||
) |
Definition at line 1103 of file FBEngine.cpp.
{ SmoothCurve * smoothCurve = _edges[edge];// this is a map // now, call smoothCurve methods smoothCurve -> position_from_u(u, x, y, z); return MB_SUCCESS; }
ErrorCode moab::FBEngine::getFcEvalXYZ | ( | EntityHandle | face, |
double | x, | ||
double | y, | ||
double | z, | ||
double & | on_x, | ||
double & | on_y, | ||
double & | on_z, | ||
double & | nrml_i, | ||
double & | nrml_j, | ||
double & | nrml_k, | ||
double & | cvtr1_i, | ||
double & | cvtr1_j, | ||
double & | cvtr1_k, | ||
double & | cvtr2_i, | ||
double & | cvtr2_j, | ||
double & | cvtr2_k | ||
) |
Definition at line 1021 of file FBEngine.cpp.
{ return MB_NOT_IMPLEMENTED; // not implemented }
ErrorCode moab::FBEngine::getNumEntSets | ( | EntityHandle | set, |
int | num_hops, | ||
int * | all_sets | ||
) |
Definition at line 432 of file FBEngine.cpp.
ErrorCode moab::FBEngine::getNumOfType | ( | EntityHandle | set, |
int | ent_type, | ||
int * | pNum | ||
) |
Definition at line 485 of file FBEngine.cpp.
{ if (0 > ent_type || 4 < ent_type) { std::cout << "Invalid type\n"; return MB_FAILURE; } // get sets of geom dimension tag from here, and intersect with the gentities from goe // ranges // get the geom dimensions sets in the set (AKA gentities) Range geom_sets; Tag geom_tag; ErrorCode rval = _mbImpl->tag_get_handle(GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, MB_TAG_SPARSE|MB_TAG_CREAT); MBERRORR(rval, "Failed to get geom tag."); rval = _mbImpl->get_entities_by_type_and_tag(set, MBENTITYSET, &geom_tag, NULL, 1, geom_sets, Interface::UNION); MBERRORR(rval, "Failed to get gentities from set"); if (ent_type==4) { *pNum=0; for (int k=0; k<=3; k++) { Range gEntsOfTypeK = intersect(geom_sets, _my_geomTopoTool->geoRanges()[k]); *pNum += (int)gEntsOfTypeK.size(); } } else { Range gEntsOfType = intersect(geom_sets, _my_geomTopoTool->geoRanges()[ent_type]); *pNum = (int)gEntsOfType.size(); } // we do not really check if it is in the set or not; // _my_gsets[i].find(gent) != _my_gsets[i].end() return MB_SUCCESS; }
ErrorCode moab::FBEngine::getPntRayIntsct | ( | double | x, |
double | y, | ||
double | z, | ||
double | dir_x, | ||
double | dir_y, | ||
double | dir_z, | ||
std::vector< EntityHandle > & | intersect_entity_handles, | ||
std::vector< double > & | intersect_coords, | ||
std::vector< double > & | param_coords | ||
) |
Definition at line 726 of file FBEngine.cpp.
{ // this is pretty cool // we will return only surfaces (gentities ) // ErrorCode rval; unsigned int numfaces = _my_gsets[2].size(); // do ray fire const double point[] = { x, y, z }; const double dir[] = { dir_x, dir_y, dir_z }; CartVect P(point); CartVect V(dir); //std::vector<double> distances; std::vector<EntityHandle> facets; //std::vector<EntityHandle> sets; unsigned int i; for (i = 0; i < numfaces; i++) { EntityHandle face = _my_gsets[2][i]; EntityHandle rootForFace; rval = _my_geomTopoTool->get_root(face, rootForFace); MBERRORR(rval, "Failed to get root of face."); std::vector<double> distances_out; std::vector<EntityHandle> sets_out; std::vector<EntityHandle> facets_out; rval = _my_geomTopoTool->obb_tree()-> ray_intersect_sets(distances_out, sets_out, facets_out, rootForFace, tolerance, min_tolerace_intersections, point, dir); unsigned int j; for (j = 0; j < distances_out.size(); j++) param_coords.push_back(distances_out[j]); for (j = 0; j < sets_out.size(); j++) intersect_entity_handles.push_back(sets_out[j]); for (j = 0; j < facets_out.size(); j++) facets.push_back(facets_out[j]); MBERRORR(rval, "Failed to get ray intersections."); } // facets.size == distances.size()!! for (i = 0; i < param_coords.size(); i++) { CartVect intx = P + param_coords[i] * V; for (int j = 0; j < 3; j++) intersect_coords.push_back(intx[j]); } if (_smooth) { // correct the intersection point and the distance for smooth surfaces for (i = 0; i < intersect_entity_handles.size(); i++) { //EntityHandle geoSet = MBH_cast(sets[i]); SmoothFace* sFace = _faces[intersect_entity_handles[i]]; // correct coordinates and distance from point /*moab::ErrorCode ray_intersection_correct(moab::EntityHandle facet, // (IN) the facet where the patch is defined moab::CartVect &pt, // (IN) shoot from moab::CartVect &ray, // (IN) ray direction moab::CartVect &eval_pt, // (INOUT) The intersection point double & distance, // (IN OUT) the new distance bool &outside);*/ CartVect pos(&(intersect_coords[3 * i])); double dist = param_coords[i]; bool outside = false; rval = sFace->ray_intersection_correct(facets[i], P, V, pos, dist, outside); MBERRORR(rval, "Failed to get better point on ray."); param_coords[i] = dist; for (int j = 0; j < 3; j++) intersect_coords[3 * i + j] = pos[j]; } } return MB_SUCCESS; }
ErrorCode moab::FBEngine::getRootSet | ( | EntityHandle * | root_set | ) |
Definition at line 426 of file FBEngine.cpp.
{ *root_set = _my_geomTopoTool-> get_root_model_set(); return MB_SUCCESS; }
ErrorCode moab::FBEngine::getVtxCoord | ( | EntityHandle | this_gent, |
double * | x0, | ||
double * | y0, | ||
double * | z0 | ||
) |
Definition at line 625 of file FBEngine.cpp.
{ int type; ErrorCode rval = getEntType(vertex_handle, &type); MBERRORR(rval, "Failed to get entity type in getVtxCoord."); if (type != 0) { rval = MB_FAILURE; MBERRORR(rval, "Entity is not a vertex type."); } Range entities; rval = MBI->get_entities_by_type(vertex_handle, MBVERTEX, entities); MBERRORR(rval, "can't get nodes in vertex set."); if (entities.size() != 1) { MBERRORR(MB_FAILURE, "Vertex has multiple points."); } double coords[3]; EntityHandle node = entities[0]; rval = MBI->get_coords(&node, 1, coords); MBERRORR(rval, "can't get coordinates."); *x0 = coords[0]; *y0 = coords[1]; *z0 = coords[2]; return MB_SUCCESS; }
ErrorCode moab::FBEngine::gsubtract | ( | EntityHandle | entity_set_1, |
EntityHandle | entity_set_2, | ||
EntityHandle | result_entity_set | ||
) |
Definition at line 655 of file FBEngine.cpp.
{ /*result_entity_set = subtract(entity_set_1, entity_set_2);*/ Range ents1, ents2; ErrorCode rval = MBI->get_entities_by_type(entity_set_1, MBENTITYSET, ents1); MBERRORR(rval, "can't get entities from set 1."); rval = MBI->get_entities_by_type(entity_set_2, MBENTITYSET, ents2); MBERRORR(rval, "can't get entities from set 2."); ents1 = subtract(ents1, ents2); rval = MBI->clear_meshset(&result_entity_set, 1); MBERRORR(rval, "can't empty set."); rval = MBI->add_entities(result_entity_set, ents1); MBERRORR(rval, "can't add result to set."); return rval; }
Definition at line 227 of file FBEngine.cpp.
{ if (!_initialized) { if (!_my_geomTopoTool) return MB_FAILURE; ErrorCode rval = _my_geomTopoTool->find_geomsets(_my_gsets); assert(rval == MB_SUCCESS); if (MB_SUCCESS != rval){return rval;} rval = split_quads(); assert (rval == MB_SUCCESS); rval = _my_geomTopoTool->construct_obb_trees(); assert(rval == MB_SUCCESS); if (_smooth) rval = initializeSmoothing(); assert(rval == MB_SUCCESS); _initialized = true; } return MB_SUCCESS; }
ErrorCode moab::FBEngine::initializeSmoothing | ( | ) | [private] |
Definition at line 252 of file FBEngine.cpp.
{ // /*ErrorCode rval = Init(); MBERRORR(rval, "failed initialize");*/ // first of all, we need to retrieve all the surfaces from the (root) set // in icesheet_test we use iGeom, but maybe that is a stretch // get directly the sets with geom dim 2, and from there create the SmoothFace Tag geom_tag, gid_tag; ErrorCode rval = MBI->tag_get_handle(GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag); MBERRORR(rval, "can't get geom tag"); rval = MBI->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, gid_tag); MBERRORR(rval, "can't get id tag"); int numSurfaces = _my_gsets[2].size(); //SmoothFace ** smthFace = new SmoothFace *[numSurfaces]; _smthFace = new SmoothFace *[numSurfaces]; // there should also be a map from surfaces to evaluators //std::map<MBEntityHandle, SmoothFace*> mapSurfaces; int i = 0; Range::iterator it; for (it = _my_gsets[2].begin(); it != _my_gsets[2].end(); it++, i++) { EntityHandle face = *it; _smthFace[i] = new SmoothFace(MBI, face, _my_geomTopoTool);// geom topo tool will be used for searching, // among other things; also for senses in edge sets... _faces[face] = _smthFace[i]; } int numCurves = _my_gsets[1].size();//csets.size(); //SmoothCurve ** smthCurve = new SmoothCurve *[numCurves]; _smthCurve = new SmoothCurve *[numCurves]; // there should also be a map from surfaces to evaluators //std::map<MBEntityHandle, SmoothCurve*> mapCurves; i = 0; for (it = _my_gsets[1].begin(); it != _my_gsets[1].end(); it++, i++) { EntityHandle curve = *it; _smthCurve[i] = new SmoothCurve(MBI, curve, _my_geomTopoTool); _edges[curve] = _smthCurve[i]; } for (i = 0; i < numSurfaces; i++) { _smthFace[i]->init_gradient();// this will also retrieve the triangles in each surface _smthFace[i]->compute_tangents_for_each_edge();// this one will consider all edges internal, so the // tangents are all in the direction of the edge; a little bit of waste, as we store // one tangent for each edge node , even though they are equal here... // no loops are considered } // this will be used to mark boundary edges, so for them the control points are computed earlier unsigned char value = 0; // default value is "not used"=0 for the tag // unsigned char def_data_bit = 1;// valid by default // rval = mb->tag_create("valid", 1, MB_TAG_BIT, validTag, &def_data_bit); Tag markTag; rval = MBI->tag_get_handle("MARKER", 1, MB_TYPE_BIT, markTag, MB_TAG_EXCL|MB_TAG_BIT, &value); // default value : 0 = not computed yet // each feature edge will need to have a way to retrieve at every moment the surfaces it belongs to // from edge sets, using the sense tag, we can get faces, and from each face, using the map, we can get // the SmoothFace (surface evaluator), that has everything, including the normals!!! assert(rval==MB_SUCCESS); // create the tag also for control points on the edges double defCtrlPoints[9] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. }; Tag edgeCtrlTag; rval = MBI->tag_get_handle("CONTROLEDGE", 9, MB_TYPE_DOUBLE, edgeCtrlTag, MB_TAG_DENSE|MB_TAG_CREAT, &defCtrlPoints ); assert(rval == MB_SUCCESS); Tag facetCtrlTag; double defControls[18] = { 0. }; rval = MBI->tag_get_handle("CONTROLFACE", 18, MB_TYPE_DOUBLE, facetCtrlTag, MB_TAG_CREAT|MB_TAG_DENSE, &defControls); assert(rval == MB_SUCCESS); Tag facetEdgeCtrlTag; double defControls2[27] = { 0. }; // corresponding to 9 control points on edges, in order from edge 0, 1, 2 ( 1-2, 2-0, 0-1 ) rval = MBI->tag_get_handle("CONTROLEDGEFACE", 27, MB_TYPE_DOUBLE, facetEdgeCtrlTag, MB_TAG_CREAT|MB_TAG_DENSE, &defControls2); assert(rval == MB_SUCCESS); // if the double min_dot = -1.0; // depends on _angle, but now we ignore it, for the time being for (i = 0; i < numCurves; i++) { _smthCurve[i]->compute_tangents_for_each_edge();// do we need surfaces now? or just the chains? // the computed edges will be marked accordingly; later one, only internal edges to surfaces are left _smthCurve[i]->compute_control_points_on_boundary_edges(min_dot, _faces, edgeCtrlTag, markTag); } // when done with boundary edges, compute the control points on all edges in the surfaces for (i = 0; i < numSurfaces; i++) { // also pass the tags for _smthFace[i]->compute_control_points_on_edges(min_dot, edgeCtrlTag, markTag); } // now we should be able to compute the control points for the facets for (i = 0; i < numSurfaces; i++) { // also pass the tags for edge and facet control points _smthFace[i]->compute_internal_control_points_on_facets(min_dot, facetCtrlTag, facetEdgeCtrlTag); } // we will need to compute the tangents for all edges in the model // they will be needed for control points for each edge // the boundary edges and the feature edges are more complicated // the boundary edges need to consider their loops, but feature edges need to consider loops and the normals // on each connected surface // some control points if (Debug_surf_eval) for (i = 0; i < numSurfaces; i++) _smthFace[i]->DumpModelControlPoints(); return MB_SUCCESS; }
ErrorCode moab::FBEngine::isEntAdj | ( | EntityHandle | entity1, |
EntityHandle | entity2, | ||
bool & | adjacent_out | ||
) |
Definition at line 1126 of file FBEngine.cpp.
{ int type1, type2; ErrorCode rval = getEntType(entity1, &type1); if (MB_SUCCESS != rval) return rval; rval = getEntType(entity2, &type2); if (MB_SUCCESS != rval) return rval; Range adjs; if (type1 < type2) { rval = MBI->get_parent_meshsets(entity1, adjs, type2 - type1); if (MB_SUCCESS != rval) return rval;// MBERRORR("Failed to get parent meshsets in iGeom_isEntAdj."); } else { // note: if they ave the same type, they will not be adjacent, in our definition rval = MBI->get_child_meshsets(entity1, adjs, type1 - type2); if (MB_SUCCESS != rval) return rval;//MBERRORR("Failed to get child meshsets in iGeom_isEntAdj."); } //adjacent_out = adjs.find(entity2) != _my_gsets[type2].end(); // hmmm, possible bug here; is this called? adjacent_out = adjs.find(entity2) != adjs.end(); return MB_SUCCESS; }
ErrorCode moab::FBEngine::measure | ( | const EntityHandle * | moab_entities, |
int | entities_size, | ||
double * | measures | ||
) |
Definition at line 944 of file FBEngine.cpp.
{ ErrorCode rval; for (int i = 0; i < entities_size; i++) { measures[i] = 0.; int type; EntityHandle gset = moab_entities[i]; rval = getEntType(gset, &type); if (MB_SUCCESS != rval) return rval; if (type == 1) { // edge: get all edges part of the edge set Range entities; rval = MBI->get_entities_by_type(gset, MBEDGE, entities); if (MB_SUCCESS != rval) return rval; for (Range::iterator it = entities.begin(); it != entities.end(); it++) { EntityHandle edge = *it; CartVect vv[2]; const EntityHandle *conn2 = NULL; int num_nodes; rval = MBI->get_connectivity(edge, conn2, num_nodes); if (MB_SUCCESS != rval || num_nodes != 2) return MB_FAILURE; rval = MBI->get_coords(conn2, 2, (double *) &(vv[0][0])); if (MB_SUCCESS != rval) return rval; vv[0] = vv[1] - vv[0]; measures[i] += vv[0].length(); } } if (type == 2) { // surface // get triangles in surface; TODO: quads! Range entities; rval = MBI->get_entities_by_type(gset, MBTRI, entities); if (MB_SUCCESS != rval) return rval; for (Range::iterator it = entities.begin(); it != entities.end(); it++) { EntityHandle tri = *it; CartVect vv[3]; const EntityHandle *conn3 = NULL; int num_nodes; rval = MBI->get_connectivity(tri, conn3, num_nodes); if (MB_SUCCESS != rval || num_nodes != 3) return MB_FAILURE; rval = MBI->get_coords(conn3, 3, (double *) &(vv[0][0])); if (MB_SUCCESS != rval) return rval; vv[1] = vv[1] - vv[0]; vv[2] = vv[2] - vv[0]; vv[0] = vv[1] * vv[2]; measures[i] += vv[0].length() / 2;// area of triangle } } } return MB_SUCCESS; }
Interface* moab::FBEngine::moab_instance | ( | ) | [inline] |
Definition at line 76 of file FBEngine.hpp.
{ return _mbImpl; }
void moab::FBEngine::print_debug_triangle | ( | EntityHandle | triangle | ) | [private] |
Definition at line 1915 of file FBEngine.cpp.
{ std::cout<< " triangle id:" << _mbImpl->id_from_handle(t) << "\n"; const EntityHandle * conn3; int nnodes; _mbImpl->get_connectivity(t, conn3, nnodes); // get coords CartVect P[3]; _mbImpl->get_coords(conn3, 3, (double*) &P[0]); std::cout <<" nodes:" << conn3[0] << " " << conn3[1] << " " << conn3[2] << "\n"; CartVect PP[3]; PP[0] = P[1]-P[0]; PP[1] = P[2]-P[1]; PP[2] = P[0] - P[2]; std::cout <<" pos:" << P[0] << " " << P[1] << " " << P[2] << "\n"; std::cout <<" x,y diffs " << PP[0][0] <<" " << PP[0][1] << ", " << PP[1][0] <<" " << PP[1][1] << ", " << PP[2][0] <<" " << PP[2][1] << "\n"; return; }
ErrorCode moab::FBEngine::redistribute_boundary_edges_to_faces | ( | EntityHandle | face, |
EntityHandle | newFace, | ||
std::vector< EntityHandle > & | chainedEdges | ||
) | [private] |
Definition at line 2847 of file FBEngine.cpp.
{ // so far, original boundary edges are all parent/child relations for face // we should get them all, and see if they are truly adjacent to face or newFace // decide also on the orientation/sense with respect to the triangles Range r1; // range in old face Range r2; // range of tris in new face ErrorCode rval = _mbImpl->get_entities_by_dimension(face, 2, r1); MBERRORR(rval, " can't get triangles from old face"); rval = _mbImpl->get_entities_by_dimension(newFace, 2, r2); MBERRORR(rval, " can't get triangles from new face"); // right now, all boundary edges are children of face // we need to get them all, and verify if they indeed are adjacent to face Range children; rval = _mbImpl->get_child_meshsets(face, children);// only direct children are of interest MBERRORR(rval, " can't get children sets from face"); for (Range::iterator it = children.begin(); it!=children.end(); it++) { EntityHandle edge=*it; if (std::find(chainedEdges.begin(), chainedEdges.end(), edge)!=chainedEdges.end()) continue; // we already set this one fine // get one mesh edge from the edge; we have to get all of them!! if (_my_geomTopoTool->dimension(edge)!=1) continue; // not an edge Range mesh_edges; rval = _mbImpl->get_entities_by_handle(edge, mesh_edges); MBERRORR(rval, " can't get mesh edges from edge"); if (mesh_edges.empty()) MBERRORR(MB_FAILURE, " no mesh edges"); EntityHandle mesh_edge = mesh_edges[0]; // first one is enough //get its triangles; see which one is in r1 or r2; it should not be in both Range triangles; rval = _mbImpl->get_adjacencies(&mesh_edge, 1, 2, false, triangles); MBERRORR(rval, " can't get adjacent triangles"); Range intx1 = intersect(triangles, r1); Range intx2 = intersect(triangles, r2); if (!intx1.empty() && !intx2.empty()) MBERRORR(MB_FAILURE, " at least one should be empty"); if (intx2.empty()) { // it means it is in the range r1; the sense should be fine, no need to reset // the sense should have been fine, also continue; } // so it must be a triangle in r2; EntityHandle triangle = intx2[0];// one triangle only // remove the edge from boundary of face, and add it to the boundary of newFace // remove_parent_child( EntityHandle parent, EntityHandle child ) rval = _mbImpl->remove_parent_child(face, edge); MBERRORR(rval, " can't remove parent child relation for edge"); // add to the new face rval = _mbImpl->add_parent_child(newFace, edge); MBERRORR(rval, " can't add parent child relation for edge"); // set some sense, based on the sense of the mesh_edge in triangle int num1, sense, offset; rval = _mbImpl->side_number(triangle, mesh_edge, num1, sense, offset); MBERRORR(rval, "mesh edge not adjacent to triangle"); rval = this->_my_geomTopoTool->set_sense(edge, newFace, sense); MBERRORR(rval, "can't set proper sense of edge in face"); } return MB_SUCCESS; }
ErrorCode moab::FBEngine::separate | ( | EntityHandle | face, |
std::vector< EntityHandle > & | chainedEdges, | ||
Range & | first, | ||
Range & | second | ||
) | [private] |
Definition at line 1624 of file FBEngine.cpp.
{ //Range unaffectedTriangles = subtract(iniTriangles, _piercedTriangles); // insert in each // start with a new triangle, and flood to get the first range; what is left is the // second range // flood fill is considering edges adjacent to seed triangles; if there is // an edge in the new_geo_edge, it is skipped; triangles in the // triangles to delete are not added // first, create all edges of the new triangles // // new face will have the new edge oriented positively // get mesh edges from geo edge (splitting gedge); Range mesh_edges; ErrorCode rval; // mesh_edges for(unsigned int j=0; j<chainedEdges.size(); j++) { // this will keep adding edges to the mesh_edges range // when we get out, the mesh_edges will be in this range, but not ordered rval = _mbImpl->get_entities_by_type(chainedEdges[j], MBEDGE, mesh_edges); MBERRORR(rval, "can't get new polyline edges"); if (debug_splits) { std::cout << " At chained edge " << j << " " << _mbImpl->id_from_handle(chainedEdges[j]) << " mesh_edges Range size:" << mesh_edges.size() << "\n"; } } // get a positive triangle adjacent to mesh_edge[0] // add to first triangles to the left, second triangles to the right of the mesh_edges ; // create a temp tag, and when done, delete it // default value: 0 // 3 to be deleted, pierced // 1 first set // 2 second set // create the tag also for control points on the edges int defVal = 0; Tag separateTag; rval = MBI->tag_get_handle("SEPARATE_TAG", 1, MB_TYPE_INTEGER, separateTag, MB_TAG_DENSE|MB_TAG_CREAT, &defVal ); MBERRORR(rval, "can't create temp tag for separation"); // the deleted triangles will get a value 3, from start int delVal = 3; for (Range::iterator it1=this->_piercedTriangles.begin(); it1!=_piercedTriangles.end(); it1++) { EntityHandle trToDelete= *it1; rval = _mbImpl->tag_set_data(separateTag, &trToDelete, 1, &delVal ); MBERRORR(rval, "can't set delete tag value"); } // find a triangle that will be in the first range, positively oriented about the splitting edge EntityHandle seed1=0; for (Range::iterator it = mesh_edges.begin(); it!=mesh_edges.end() && !seed1; it++) { EntityHandle meshEdge = *it; Range adj_tri; rval = _mbImpl->get_adjacencies(&meshEdge, 1, 2, false, adj_tri); MBERRORR(rval, "can't get adj_tris to mesh edge"); for ( Range::iterator it2=adj_tri.begin(); it2!=adj_tri.end(); it2++) { EntityHandle tr=*it2; if (_piercedTriangles.find(tr)!=_piercedTriangles.end()) continue;// do not attach pierced triangles, they are not good int num1, sense, offset; rval = _mbImpl->side_number(tr, meshEdge, num1, sense, offset); MBERRORR(rval, "edge not adjacent"); if (sense==1) { //firstSet.insert(tr); if (!seed1) { seed1=tr; break; } } } } // flood fill first set, the rest will be in second set // the edges from new_geo_edge will not be crossed // get edges of face (adjacencies) // also get the old boundary edges, from face; they will be edges to not cross, too Range bound_edges; rval = getAdjacentEntities(face, 1, bound_edges); MBERRORR(rval, "can't get boundary edges"); // add to the do not cross edges range, all edges from initial boundary Range initialBoundaryEdges; for (Range::iterator it= bound_edges.begin(); it!=bound_edges.end(); it++) { EntityHandle bound_edge=*it; rval = _mbImpl->get_entities_by_dimension(bound_edge, 1, initialBoundaryEdges); } Range doNotCrossEdges = unite(initialBoundaryEdges, mesh_edges);// add the splitting edges ! // use a second method, with tags // std::queue<EntityHandle> queue1; queue1.push(seed1); std::vector<EntityHandle> arr1; while(!queue1.empty()) { // start copy EntityHandle currentTriangle=queue1.front(); queue1.pop(); arr1.push_back(currentTriangle); // add new triangles that share an edge Range currentEdges; rval = _mbImpl->get_adjacencies(¤tTriangle, 1, 1, true, currentEdges, Interface::UNION); MBERRORR(rval, "can't get adjacencies"); for (Range::iterator it=currentEdges.begin(); it!=currentEdges.end(); it++) { EntityHandle frontEdge= *it; if ( doNotCrossEdges.find(frontEdge)==doNotCrossEdges.end()) { // this is an edge that can be crossed Range adj_tri; rval = _mbImpl->get_adjacencies(&frontEdge, 1, 2, false, adj_tri, Interface::UNION); MBERRORR(rval, "can't get adj_tris"); // if the triangle is not in first range, add it to the queue for (Range::iterator it2=adj_tri.begin(); it2!=adj_tri.end(); it2++) { EntityHandle tri2=*it2; int val =0; rval = _mbImpl->tag_get_data(separateTag, &tri2, 1, &val ); MBERRORR(rval, "can't get tag value"); if (val) continue; // else, set it to 1 val =1; rval = _mbImpl->tag_set_data(separateTag, &tri2, 1, &val ); MBERRORR(rval, "can't get tag value"); queue1.push(tri2); } }// end edge do not cross }// end while } std::sort(arr1.begin(), arr1.end()); //Range first1; std::copy(arr1.rbegin(), arr1.rend(), range_inserter(first)); //std::cout<< "\n first1.size() " << first1.size() << " first.size(): " << first.size() << "\n"; if (debug_splits) { EntityHandle tmpSet; _mbImpl->create_meshset(MESHSET_SET, tmpSet); _mbImpl->add_entities(tmpSet, first); _mbImpl->write_file("dbg1.vtk", "vtk", 0, &tmpSet, 1); } // now, decide the set 2: // first, get all ini tris Range initr; rval = _mbImpl -> get_entities_by_type(face, MBTRI, initr); MBERRORR(rval, "can't get tris "); second = unite(initr, _newTriangles); Range second2 = subtract(second, _piercedTriangles); second = subtract(second2, first); _newTriangles.clear(); if (debug_splits) { std::cout<< "\n second.size() " << second.size() << " first.size(): " << first.size() << "\n"; // debugging code EntityHandle tmpSet2; _mbImpl->create_meshset(MESHSET_SET, tmpSet2); _mbImpl->add_entities(tmpSet2, second); _mbImpl->write_file("dbg2.vtk", "vtk", 0, &tmpSet2, 1); } /*Range intex = intersect(first, second); if (!intex.empty() && debug_splits) { std::cout << "error, the sets should be disjoint\n"; for (Range::iterator it1=intex.begin(); it1!=intex.end(); ++it1) { std::cout<<_mbImpl->id_from_handle(*it1) << "\n"; } }*/ rval = _mbImpl->tag_delete(separateTag); MBERRORR(rval, "can't delete tag "); return MB_SUCCESS; }
ErrorCode moab::FBEngine::set_default_neumann_tags | ( | ) | [private] |
Definition at line 3576 of file FBEngine.cpp.
{ // these are for debugging purposes only // check the initial tag, then Tag ntag; ErrorCode rval = _mbImpl->tag_get_handle(NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, ntag); MBERRORR(rval, "can't get tag handle"); // get all surfaces in the model now Range sets[5]; rval = _my_geomTopoTool->find_geomsets(sets); MBERRORR(rval, "can't get geo sets"); int nfaces = (int)sets[2].size(); int * vals = new int [nfaces]; for (int i=0; i<nfaces; i++) { vals[i] = i+1; } rval = _mbImpl->tag_set_data(ntag, sets[2], (void*)vals); MBERRORR(rval, "can't set tag values for neumann sets"); delete [] vals; return MB_SUCCESS; }
ErrorCode moab::FBEngine::set_neumann_tags | ( | EntityHandle | face, |
EntityHandle | newFace | ||
) | [private] |
Definition at line 2918 of file FBEngine.cpp.
{ // these are for debugging purposes only // check the initial tag, then Tag ntag; ErrorCode rval = _mbImpl->tag_get_handle(NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, ntag); MBERRORR(rval, "can't get tag handle"); // check the value for face int nval; rval = _mbImpl->tag_get_data(ntag, &face, 1, &nval); if (MB_SUCCESS == rval) { nval++; } else { nval = 1; rval = _mbImpl->tag_set_data(ntag, &face, 1, &nval); MBERRORR(rval, "can't set tag"); nval = 2; } rval = _mbImpl->tag_set_data(ntag, &newFace, 1, &nval); MBERRORR(rval, "can't set tag"); return MB_SUCCESS; }
void moab::FBEngine::set_smooth | ( | ) | [inline] |
Definition at line 176 of file FBEngine.hpp.
{ _smooth = true;}
ErrorCode moab::FBEngine::setArrData | ( | const EntityHandle * | entity_handles, |
int | entity_handles_size, | ||
Tag | tag_handle, | ||
const void * | tag_values | ||
) |
Definition at line 907 of file FBEngine.cpp.
{ // responsibility of the user to have tag_values_out properly allocated // only some types of Tags are possible (double, int, etc) return MBI->tag_set_data(tag_handle, entity_handles, entity_handles_size, tag_values); }
ErrorCode moab::FBEngine::smooth_new_intx_points | ( | EntityHandle | face, |
std::vector< EntityHandle > & | chainedEdges | ||
) | [private] |
Definition at line 1568 of file FBEngine.cpp.
{ // do not move nodes from the original face // first get all triangles, and then all nodes from those triangles Range tris; ErrorCode rval = _mbImpl->get_entities_by_type(face, MBTRI, tris); MBERRORR(rval, "can't get triangles"); Range ini_nodes; rval = _mbImpl->get_connectivity( tris, ini_nodes); MBERRORR(rval, "can't get connectivities"); SmoothFace* smthFace = _faces[face]; // get all nodes from chained edges Range mesh_edges; for (unsigned int j= 0; j<chainedEdges.size(); j++) { // keep adding to the range of mesh edges rval = _mbImpl->get_entities_by_dimension(chainedEdges[j], 1, mesh_edges); MBERRORR(rval, "can't get mesh edges"); } // nodes along polyline Range nodes_on_polyline; rval = _mbImpl->get_connectivity(mesh_edges, nodes_on_polyline, true); // corners only MBERRORR(rval, "can't get nodes on the polyline"); Range new_intx_nodes = subtract(nodes_on_polyline, ini_nodes); std::vector<double> ini_coords; int num_points = (int)new_intx_nodes.size(); ini_coords.resize(3*num_points); rval = _mbImpl->get_coords(new_intx_nodes, &(ini_coords[0])); MBERRORR(rval, "can't get coordinates"); int i=0; for (Range::iterator it = new_intx_nodes.begin(); it != new_intx_nodes.end(); ++it) { /*EntityHandle node = *it;*/ int i3=3*i; smthFace->move_to_surface(ini_coords[i3], ini_coords[i3+1], ini_coords[i3+2]); // reset the coordinates of this node ++i; } rval = _mbImpl->set_coords(new_intx_nodes, &(ini_coords[0])); MBERRORR(rval, "can't set smoothed coordinates for the new nodes"); return MB_SUCCESS; }
ErrorCode moab::FBEngine::split_bedge_at_new_mesh_node | ( | EntityHandle | b_edge, |
EntityHandle | atNode, | ||
EntityHandle | brokenEdge, | ||
EntityHandle & | new_edge | ||
) |
Definition at line 2533 of file FBEngine.cpp.
{ // the node should be in the list of nodes int dim = _my_geomTopoTool->dimension(edge); if (dim != 1) return MB_FAILURE; // not an edge if (debug_splits) { std::cout << "Split edge " << _mbImpl->id_from_handle(edge) << " with global id: " << _my_geomTopoTool->global_id(edge) << " at new node:" << _mbImpl->id_from_handle(node) << "breaking mesh edge" << _mbImpl->id_from_handle(brokenEdge)<< "\n"; } // now get the edges // the order is important... // these are ordered sets !! std::vector<EntityHandle> ents; ErrorCode rval = _mbImpl->get_entities_by_type(edge, MBEDGE, ents); if (MB_SUCCESS != rval) return rval; if (ents.size() < 1) return MB_FAILURE; // no edges const EntityHandle* conn = NULL; int len; // the edge connected to the splitting node is brokenEdge // find the small edges it is broken into, which are connected to // new vertex (node) and its ends; also, if necessary, reorient these small edges // for proper orientation rval = _mbImpl->get_connectivity(brokenEdge, conn, len); MBERRORR(rval, "Failed to get connectivity of broken edge"); // we already created the new edges, make sure they are oriented fine; if not, revert them EntityHandle conn02[]={conn[0], node}; // first node and new node // default, intersect std::vector<EntityHandle> adj_edges; rval = _mbImpl->get_adjacencies(conn02, 2, 1, false, adj_edges); if (adj_edges.size()<1 || rval !=MB_SUCCESS) MBERRORR(MB_FAILURE, " Can't find small split edge"); // get this edge connectivity; EntityHandle firstEdge=adj_edges[0]; const EntityHandle * connActual; rval = _mbImpl->get_connectivity(firstEdge, connActual, len); MBERRORR(rval, "Failed to get connectivity of first split edge"); // if it is the same as conn02, we are happy if (conn02[0]!=connActual[0]) { // reset connectivity of edge rval = _mbImpl->set_connectivity(firstEdge, conn02, 2); MBERRORR(rval, "Failed to reset connectivity of first split edge"); } // now treat the second edge adj_edges.clear(); // EntityHandle conn21[]={node, conn[1]}; // new node and second node rval = _mbImpl->get_adjacencies(conn21, 2, 1, false, adj_edges); if (adj_edges.size()<1 || rval !=MB_SUCCESS) MBERRORR(MB_FAILURE, " Can't find second small split edge"); // get this edge connectivity; EntityHandle secondEdge=adj_edges[0]; rval = _mbImpl->get_connectivity(firstEdge, connActual, len); MBERRORR(rval, "Failed to get connectivity of first split edge"); // if it is the same as conn21, we are happy if (conn21[0]!=connActual[0]) { // reset connectivity of edge rval = _mbImpl->set_connectivity(secondEdge, conn21, 2); MBERRORR(rval, "Failed to reset connectivity of first split edge"); } int num_mesh_edges = (int) ents.size(); int index_edge;// this is the index of the edge that will be removed (because it is split) // the rest of edges will be put in order in the (remaining) edge and new edge for (index_edge = 0; index_edge < num_mesh_edges; index_edge++) if (brokenEdge==ents[index_edge]) break; if (index_edge>=num_mesh_edges) MBERRORR(MB_FAILURE, "can't find the broken edge"); //so the edges up to index_edge and firstEdge, will form the "old" edge // the edges secondEdge and from index_edge+1 to end will form the new_edge // here, we have 0 ... index_edge edges in the first set, // create a vertex set and add the node to it if (debug_splits) { std::cout << "Split edge with " << num_mesh_edges << " mesh edges, at index (0 based) " << index_edge << "\n"; } // at this moment, the node set should have been already created in new_geo_edge EntityHandle nodeSet; // the node set that has the node (find it!) bool found = find_vertex_set_for_node(node, nodeSet); if (!found) { // create a node set and add the node // must be an error, but create one nevertheless rval = _mbImpl->create_meshset(MESHSET_SET, nodeSet); MBERRORR(rval, "Failed to create a new vertex set"); rval = _mbImpl->add_entities(nodeSet, &node, 1); MBERRORR(rval, "Failed to add the node to the set"); rval = _my_geomTopoTool->add_geo_set(nodeSet, 0);// MBERRORR(rval, "Failed to commit the node set"); if (debug_splits) { std::cout << " create a vertex set (this should have been created before!)" << _mbImpl->id_from_handle(nodeSet) << " global id:" << this->_my_geomTopoTool->global_id(nodeSet) << "\n"; } } // we need to remove the remaining mesh edges from first set, and add it // to the second set, in order rval = _mbImpl->create_meshset(MESHSET_ORDERED, new_edge); MBERRORR(rval, "can't create geo edge"); int remaining = num_mesh_edges - 1 - index_edge; // add edges to the new edge set rval = _mbImpl->add_entities(new_edge, &secondEdge, 1); // add the second split edge to new edge MBERRORR(rval, "can't add second split edge to the new edge"); // then add the rest rval = _mbImpl->add_entities(new_edge, &ents[index_edge + 1], remaining); MBERRORR(rval, "can't add edges to the new edge"); // also, remove the second node set from old edge // remove the edges index_edge and up rval = _mbImpl->remove_entities(edge, &ents[index_edge], remaining+1);// include the MBERRORR(rval, "can't remove edges from the old edge"); // add the firstEdge too rval = _mbImpl->add_entities(edge, &firstEdge, 1); // add the second split edge to new edge MBERRORR(rval, "can't add first split edge to the old edge"); // need to find the adjacent vertex sets Range vertexRange; rval = getAdjacentEntities(edge, 0, vertexRange); EntityHandle secondSet; if (vertexRange.size() == 1) { // initially a periodic edge, OK to add the new set to both edges, and the // second set secondSet = vertexRange[0]; } else { if (vertexRange.size() > 2) return MB_FAILURE; // something must be wrong with too many vertices // find first node EntityHandle firstNode; rval = MBI->get_connectivity(ents[0], conn, len); if (MB_SUCCESS != rval) return rval; firstNode = conn[0]; // this is the first node of the initial edge // we will use it to identify the vertex set associated with it int k; for (k = 0; k < 2; k++) { Range verts; rval = _mbImpl->get_entities_by_type(vertexRange[k], MBVERTEX, verts); MBERRORR(rval, "can't get vertices from vertex set"); if (verts.size() != 1) MBERRORR(MB_FAILURE, " node set not defined well"); if (firstNode == verts[0]) { secondSet = vertexRange[1 - k]; // the other set; it is 1 or 0 break; } } if (k >= 2) { // it means we didn't find the right node set MBERRORR(MB_FAILURE, " can't find the right vertex"); } // remove the second set from the connectivity with the // edge (parent-child relation) //remove_parent_child( EntityHandle parent, // EntityHandle child ) rval = _mbImpl->remove_parent_child(edge, secondSet); MBERRORR(rval, " can't remove the second vertex from edge"); } // at this point, we just need to add to both edges the new node set (vertex) rval = _mbImpl->add_parent_child(edge, nodeSet); MBERRORR(rval, " can't add new vertex to old edge"); rval = _mbImpl->add_parent_child(new_edge, nodeSet); MBERRORR(rval, " can't add new vertex to new edge"); // one thing that I forgot: add the secondSet as a child to new edge!!! // (so far, the new edge has only one end vertex!) rval = _mbImpl->add_parent_child(new_edge, secondSet); MBERRORR(rval, " can't add second vertex to new edge"); // now, add the edge and vertex to geo tool rval = _my_geomTopoTool->add_geo_set(new_edge, 1); MBERRORR(rval, " can't add new edge"); // next, get the adjacent faces to initial edge, and add them as parents // to the new edge // need to find the adjacent face sets Range faceRange; rval = getAdjacentEntities(edge, 2, faceRange); // these faces will be adjacent to the new edge too! // need to set the senses of new edge within faces for (Range::iterator it = faceRange.begin(); it != faceRange.end(); it++) { EntityHandle face = *it; rval = _mbImpl->add_parent_child(face, new_edge); MBERRORR(rval, " can't add new edge - face parent relation"); int sense; rval = _my_geomTopoTool->get_sense(edge, face, sense); MBERRORR(rval, " can't get initial sense of edge in the adjacent face"); // keep the same sense for the new edge within the faces rval = _my_geomTopoTool->set_sense(new_edge, face, sense); MBERRORR(rval, " can't set sense of new edge in the adjacent face"); } return MB_SUCCESS; }
ErrorCode moab::FBEngine::split_boundary | ( | EntityHandle | face, |
EntityHandle | atNode | ||
) | [private] |
Definition at line 2763 of file FBEngine.cpp.
{ // find the boundary edges, and split the one that we find it is a part of if (debug_splits) { std::cout<<"Split face " << _mbImpl->id_from_handle(face) << " at node:" << _mbImpl->id_from_handle(atNode) << "\n"; } Range bound_edges; ErrorCode rval = getAdjacentEntities(face, 1, bound_edges); MBERRORR(rval, " can't get boundary edges"); bool brokEdge = _brokenEdges.find(atNode)!=_brokenEdges.end(); for (Range::iterator it =bound_edges.begin(); it!=bound_edges.end(); it++ ) { EntityHandle b_edge = *it; // get all edges in range Range mesh_edges; rval = _mbImpl->get_entities_by_dimension(b_edge, 1, mesh_edges); MBERRORR(rval, " can't get mesh edges"); if (brokEdge) { EntityHandle brokenEdge = _brokenEdges[atNode]; if (mesh_edges.find(brokenEdge)!=mesh_edges.end()) { EntityHandle new_edge; rval = split_bedge_at_new_mesh_node(b_edge, atNode, brokenEdge, new_edge); return rval; } } else { Range nodes; rval = _mbImpl->get_connectivity(mesh_edges, nodes); MBERRORR(rval, " can't get nodes from mesh edges"); if (nodes.find(atNode)!=nodes.end()) { // we found our boundary edge candidate EntityHandle new_edge; rval = split_edge_at_mesh_node(b_edge, atNode, new_edge); return rval; } } } // if the node was not found in any "current" boundary, it broke an existing // boundary edge MBERRORR(MB_FAILURE, " we did not find an appropriate boundary edge"); ; // return MB_FAILURE; // needed to suppress compile warning }
ErrorCode moab::FBEngine::split_edge_at_mesh_node | ( | EntityHandle | edge, |
EntityHandle | node, | ||
EntityHandle & | new_edge | ||
) |
Definition at line 2336 of file FBEngine.cpp.
{ // the node should be in the list of nodes int dim = _my_geomTopoTool->dimension(edge); if (dim!=1) return MB_FAILURE; // not an edge if (debug_splits) { std::cout<<"Split edge " << _mbImpl->id_from_handle(edge) << " with global id: "<< _my_geomTopoTool->global_id(edge) << " at node:" << _mbImpl->id_from_handle(node) << "\n"; } // now get the edges // the order is important... // these are ordered sets !! std::vector<EntityHandle> ents; ErrorCode rval = _mbImpl->get_entities_by_type(edge, MBEDGE, ents); if (MB_SUCCESS != rval) return rval; if (ents.size() < 1) return MB_FAILURE; // no edges const EntityHandle* conn = NULL; int len; // find the edge connected to the splitting node int num_mesh_edges = (int)ents.size(); int index_edge; EntityHandle firstNode = conn[0]; // will be used to decide vertex sets adjacencies for (index_edge = 0; index_edge<num_mesh_edges; index_edge++) { rval = MBI->get_connectivity(ents[index_edge], conn, len); if (MB_SUCCESS != rval) return rval; if (conn[0] == node) { if (index_edge==0) { new_edge = 0; // no need to split, it is the first node return MB_SUCCESS; // no split } else return MB_FAILURE; // we should have found the node already , wrong // connectivity } else if (conn[1] == node) { // we found the index of interest break; } } if (index_edge==num_mesh_edges-1) { new_edge = 0; // no need to split, it is the last node return MB_SUCCESS; // no split } // here, we have 0 ... index_edge edges in the first set, // create a vertex set and add the node to it if (debug_splits) { std::cout<<"Split edge with " << num_mesh_edges << " mesh edges, at index (0 based) " << index_edge << "\n"; } // at this moment, the node set should have been already created in new_geo_edge EntityHandle nodeSet; // the node set that has the node (find it!) bool found=find_vertex_set_for_node(node, nodeSet); if (!found) { // create a node set and add the node // must be an error, but create one nevertheless rval = _mbImpl->create_meshset(MESHSET_SET, nodeSet); MBERRORR(rval, "Failed to create a new vertex set"); rval = _mbImpl->add_entities(nodeSet, &node, 1); MBERRORR(rval, "Failed to add the node to the set"); rval = _my_geomTopoTool->add_geo_set(nodeSet, 0);// MBERRORR(rval, "Failed to commit the node set"); if (debug_splits) { std::cout<<" create a vertex set (this should have been created before!)" << _mbImpl->id_from_handle(nodeSet) << " global id:"<< this->_my_geomTopoTool->global_id(nodeSet) << "\n"; } } // we need to remove the remaining mesh edges from first set, and add it // to the second set, in order rval = _mbImpl->create_meshset(MESHSET_ORDERED, new_edge); MBERRORR(rval, "can't create geo edge"); int remaining= num_mesh_edges - 1 - index_edge; // add edges to the edge set rval = _mbImpl->add_entities(new_edge, &ents[index_edge+1], remaining); MBERRORR(rval, "can't add edges to the new edge"); // also, remove the second node set from old edge // remove the edges index_edge+1 and up rval = _mbImpl->remove_entities(edge, &ents[index_edge+1], remaining); MBERRORR(rval, "can't remove edges from the old edge"); // need to find the adjacent vertex sets Range vertexRange; rval = getAdjacentEntities(edge, 0, vertexRange); EntityHandle secondSet; if (vertexRange.size() == 1) { // initially a periodic edge, OK to add the new set to both edges, and the // second set secondSet = vertexRange[0]; } else { if (vertexRange.size() > 2) return MB_FAILURE; // something must be wrong with too many vertices // find first node int k; for (k=0; k<2; k++) { Range verts; rval = _mbImpl->get_entities_by_type(vertexRange[k], MBVERTEX, verts); MBERRORR(rval, "can't get vertices from vertex set"); if (verts.size()!=1) MBERRORR(MB_FAILURE, " node set not defined well"); if (firstNode == verts[0]) { secondSet = vertexRange[1-k]; // the other set; it is 1 or 0 break; } } if (k>=2) { // it means we didn't find the right node set MBERRORR(MB_FAILURE, " can't find the right vertex"); } // remove the second set from the connectivity with the // edge (parent-child relation) //remove_parent_child( EntityHandle parent, // EntityHandle child ) rval = _mbImpl->remove_parent_child(edge, secondSet); MBERRORR(rval, " can't remove the second vertex from edge"); } // at this point, we just need to add to both edges the new node set (vertex) rval = _mbImpl->add_parent_child(edge, nodeSet); MBERRORR(rval, " can't add new vertex to old edge"); rval = _mbImpl->add_parent_child(new_edge, nodeSet); MBERRORR(rval, " can't add new vertex to new edge"); // one thing that I forgot: add the secondSet as a child to new edge!!! // (so far, the new edge has only one end vertex!) rval = _mbImpl->add_parent_child(new_edge, secondSet); MBERRORR(rval, " can't add second vertex to new edge"); // now, add the edge and vertex to geo tool rval = _my_geomTopoTool->add_geo_set(new_edge, 1); MBERRORR(rval, " can't add new edge"); // next, get the adjacent faces to initial edge, and add them as parents // to the new edge // need to find the adjacent face sets Range faceRange; rval = getAdjacentEntities(edge, 2, faceRange); // these faces will be adjacent to the new edge too! // need to set the senses of new edge within faces for (Range::iterator it= faceRange.begin(); it!=faceRange.end(); it++) { EntityHandle face = *it; rval = _mbImpl->add_parent_child(face, new_edge); MBERRORR(rval, " can't add new edge - face parent relation"); int sense; rval = _my_geomTopoTool->get_sense(edge, face, sense); MBERRORR(rval, " can't get initial sense of edge in the adjacent face"); // keep the same sense for the new edge within the faces rval = _my_geomTopoTool->set_sense(new_edge, face, sense); MBERRORR(rval, " can't set sense of new edge in the adjacent face"); } return MB_SUCCESS; }
ErrorCode moab::FBEngine::split_edge_at_point | ( | EntityHandle | edge, |
CartVect & | point, | ||
EntityHandle & | new_edge | ||
) |
Definition at line 2288 of file FBEngine.cpp.
{ //return MB_NOT_IMPLEMENTED; // first, we need to find the closest point on the smooth edge, then // split the smooth edge, then call the split_edge_at_mesh_node // or maybe just find the closest node?? // first of all, we need to find a point on the smooth edge, close by // then split the mesh edge (if needed) // this would be quite a drama, as the new edge has to be inserted in // order for proper geo edge definition // first of all, find a closest point // usually called for if (debug_splits) { std::cout<<"Split edge " << _mbImpl->id_from_handle(edge) << " at point:" << point << "\n"; } int dim = _my_geomTopoTool->dimension(edge); if (dim !=1) return MB_FAILURE; if (!_smooth) return MB_FAILURE; // call it only for smooth option... // maybe we should do something for linear too SmoothCurve * curve = this->_edges[edge]; EntityHandle closeNode; int edgeIndex; double u = curve-> u_from_position(point[0], point[1], point[2], closeNode, edgeIndex) ; if (0==closeNode) { // we really need to split an existing edge // do not do that yet // evaluate from u: /*double pos[3]; curve->position_from_u(u, pos[0], pos[1], pos[2] );*/ // create a new node here, and split one edge // change also connectivity, create new triangles on both sides ... std::cout << "not found a close node, u is: " << u << " edge index: " << edgeIndex << "\n"; return MB_FAILURE;// not implemented yet } return split_edge_at_mesh_node(edge, closeNode, new_edge); }
ErrorCode moab::FBEngine::split_internal_edge | ( | EntityHandle & | edge, |
EntityHandle & | newVertex | ||
) | [private] |
Definition at line 3065 of file FBEngine.cpp.
{ // split the edge, and form 4 new triangles and 2 edges // get 2 triangles adjacent to edge Range adj_tri; ErrorCode rval = _mbImpl->get_adjacencies(&edge, 1, 2, false, adj_tri); MBERRORR(rval, "can't get adj_tris"); adj_tri = subtract(adj_tri, _piercedTriangles); if (adj_tri.size()>=3) { std::cout<< "WARNING: non manifold geometry. Are you sure?"; } for (Range::iterator it=adj_tri.begin(); it!=adj_tri.end(); ++it) { EntityHandle tri = *it; _piercedTriangles.insert(tri); const EntityHandle * conn3; int nnodes; rval = _mbImpl->get_connectivity(tri, conn3, nnodes); MBERRORR(rval, "can't get nodes"); int num1, sense, offset; rval = _mbImpl->side_number(tri, edge, num1, sense, offset); MBERRORR(rval, "can't get side number"); // after we know the side number, we can split in 2 triangles // node i is opposite to edge i int num2 = (num1+1)%3; int num3 = (num2+1)%3; // the edge from num1 to num2 is split into 2 edges EntityHandle t1[]={conn3[num2], conn3[num3], newVertex}; EntityHandle t2[]={conn3[num1], newVertex, conn3[num3]}; EntityHandle newTriangle, newTriangle2; rval = _mbImpl->create_element(MBTRI, t1, 3, newTriangle); MBERRORR(rval, "can't create triangle"); _newTriangles.insert(newTriangle); rval = _mbImpl->create_element(MBTRI, t2, 3, newTriangle2); MBERRORR(rval, "can't create triangle"); _newTriangles.insert(newTriangle2); // create edges with this, indirectly std::vector<EntityHandle> edges0; rval = _mbImpl->get_adjacencies(&newTriangle, 1, 1, true, edges0); MBERRORR(rval, "can't get new edges"); edges0.clear(); rval = _mbImpl->get_adjacencies(&newTriangle2, 1, 1, true, edges0); MBERRORR(rval, "can't get new edges"); if (debug_splits) { std::cout<<"2 (out of 4) triangles formed:\n"; _mbImpl->list_entity(newTriangle); print_debug_triangle(newTriangle); _mbImpl->list_entity(newTriangle2); print_debug_triangle(newTriangle2); } } return MB_SUCCESS; }
ErrorCode moab::FBEngine::split_quads | ( | ) | [private] |
Definition at line 2947 of file FBEngine.cpp.
{ // first see if we have any quads in the 2d faces // _my_gsets[2] is a range of surfaces (moab sets of dimension 2) int num_quads=0; for (Range::iterator it=_my_gsets[2].begin(); it!=_my_gsets[2].end(); it++) { EntityHandle surface = *it; int num_q=0; _mbImpl->get_number_entities_by_type(surface, MBQUAD, num_q); num_quads+=num_q; } if (num_quads==0) return MB_SUCCESS; // nothing to do GeomTopoTool * new_gtt = NULL; ErrorCode rval = _my_geomTopoTool->duplicate_model(new_gtt); MBERRORR(rval, "can't duplicate model"); if (this->_t_created) delete _my_geomTopoTool; _t_created = true; // this one is for sure created here, even if the original gtt was not // if we were using smart pointers, we would decrease the reference to the _my_geomTopoTool, at least _my_geomTopoTool = new_gtt; // replace the _my_gsets with the new ones, from the new set _my_geomTopoTool->find_geomsets(_my_gsets); // we have duplicated now the model, and the quads are part of the new _my_gsets[2] // we will split them now, by creating triangles along the smallest diagonal // maybe we will come up with a better criteria, but for the time being, it should be fine. // what we will do: we will remove all quads from the surface sets, and split them for (Range::iterator it2=_my_gsets[2].begin(); it2!=_my_gsets[2].end(); it2++) { EntityHandle surface = *it2; Range quads; rval = _mbImpl->get_entities_by_type(surface, MBQUAD, quads); MBERRORR(rval, "can't get quads from the surface set"); rval = _mbImpl->remove_entities(surface, quads); MBERRORR(rval, "can't remove quads from the surface set"); // they are not deleted, just removed from the set for (Range::iterator it=quads.begin(); it!=quads.end(); it++) { EntityHandle quad = *it; int nnodes; const EntityHandle * conn; rval = _mbImpl->get_connectivity(quad, conn, nnodes); MBERRORR(rval, "can't get quad connectivity"); // get all vertices position, to see which one is the shortest diagonal CartVect pos[4]; rval = _mbImpl->get_coords(conn, 4, (double*) &pos[0]); MBERRORR(rval, "can't get node coordinates"); bool diag1 = ( (pos[2]-pos[0]).length_squared() < (pos[3]-pos[1]).length_squared() ); EntityHandle newTris[2]; EntityHandle tri1[3]= { conn[0], conn[1], conn[2] }; EntityHandle tri2[3]= { conn[0], conn[2], conn[3] }; if (!diag1) { tri1[2] = conn[3]; tri2[0] = conn[1]; } rval = _mbImpl->create_element(MBTRI, tri1, 3, newTris[0]); MBERRORR(rval, "can't create triangle 1"); rval = _mbImpl->create_element(MBTRI, tri2, 3, newTris[1]); MBERRORR(rval, "can't create triangle 2"); rval = _mbImpl->add_entities(surface, newTris, 2); MBERRORR(rval, "can't add triangles to the set"); } // } return MB_SUCCESS; }
ErrorCode moab::FBEngine::split_surface | ( | EntityHandle | face, |
std::vector< EntityHandle > & | chainedEdges, | ||
std::vector< EntityHandle > & | splittingNodes, | ||
EntityHandle & | newFace | ||
) |
this method splits along the polyline defined by points and entities the polyline will be defined with // the entities are now only nodes and edges, no triangles!!! the first and last ones are also nodes for sure
Definition at line 1455 of file FBEngine.cpp.
{ // use now the chained edges to create a new face (loop or clean split) // use a fill to determine the new sets, up to the polyline // points on the polyline will be moved to the closest point location, with some constraints // then the sets will be reset, geometry recomputed. new vertices, new edges, etc. Range iniTris; ErrorCode rval; rval = _mbImpl -> get_entities_by_type(face, MBTRI, iniTris); MBERRORR(rval, "can't get initial triangles"); // start from a triangle that is not in the triangles to delete // flood fill bool closed = splittingNodes.size()==0; if (!closed) { // if (splittingNodes.size()!=2) MBERRORR(MB_FAILURE, "need to have exactly 2 nodes for splitting"); // we will have to split the boundary edges // first, find the actual boundary, and try to split with the 2 end points (nodes) // get the adjacent edges, and see which one has the end nodes rval = split_boundary(face, splittingNodes[0]); MBERRORR(rval, "can't split with first node"); rval = split_boundary(face, splittingNodes[1]); MBERRORR(rval, "can't split with second node)"); } // we will separate triangles to delete, unaffected, new_triangles, // nodesAlongPolyline, Range first, second; rval = separate (face, chainedEdges, first, second); // now, we are done with the computations; // we need to put the new nodes on the smooth surface if (this->_smooth) { rval = smooth_new_intx_points(face, chainedEdges); MBERRORR(rval, "can't smooth new points"); } // create the new set rval = _mbImpl->create_meshset(MESHSET_SET, newFace); MBERRORR(rval, "can't create a new face"); _my_geomTopoTool->add_geo_set(newFace, 2); // the new face will have the first set (positive sense triangles, to the left) rval = _mbImpl->add_entities(newFace, first); MBERRORR(rval, "can't add first range triangles to new face"); for (unsigned int j=0; j<chainedEdges.size(); j++) { EntityHandle new_geo_edge = chainedEdges[j]; // both faces will have the edge now rval = _mbImpl ->add_parent_child( face, new_geo_edge); MBERRORR(rval, "can't add parent child relations for new edge"); rval = _mbImpl ->add_parent_child( newFace, new_geo_edge); MBERRORR(rval, "can't add parent child relations for new edge"); // add senses // sense newFace is 1, old face is -1 rval = _my_geomTopoTool-> set_sense( new_geo_edge, newFace, 1); MBERRORR(rval, "can't set sense for new edge"); rval = _my_geomTopoTool-> set_sense( new_geo_edge, face, -1); MBERRORR(rval, "can't set sense for new edge in original face"); } rval = set_neumann_tags(face, newFace); MBERRORR(rval, "can't set NEUMANN set tags"); // now, we should remove from the original set all tris, and put the "second" range rval = _mbImpl->remove_entities(face, iniTris); MBERRORR(rval, "can't remove original tris from initial face set"); rval = _mbImpl->add_entities(face, second); MBERRORR(rval, "can't add second range to the original set"); if (!closed) { rval = redistribute_boundary_edges_to_faces(face, newFace, chainedEdges); MBERRORR(rval, "fail to reset the proper boundary faces"); } /*if (_smooth) delete_smooth_tags();// they need to be recomputed, anyway // this will remove the extra smooth faces and edges clean();*/ // also, these nodes need to be moved to the smooth surface, sometimes before deleting the old // triangles // remove the triangles from the set, then delete triangles (also some edges need to be deleted!) rval=_mbImpl->delete_entities( _piercedTriangles ); MBERRORR(rval, "can't delete triangles"); _piercedTriangles.clear(); // delete edges that are broke up in 2 rval=_mbImpl->delete_entities(_piercedEdges); MBERRORR(rval, "can't delete edges"); _piercedEdges.clear(); if (debug_splits) { _mbImpl->write_file("newFace.vtk", "vtk", 0, &newFace, 1); _mbImpl->write_file("leftoverFace.vtk", "vtk", 0, &face, 1); } return MB_SUCCESS; }
ErrorCode moab::FBEngine::split_surface_with_direction | ( | EntityHandle | face, |
std::vector< double > & | xyz, | ||
double * | direction, | ||
int | closed, | ||
double | min_dot, | ||
EntityHandle & | oNewFace | ||
) |
the segment is the first or last segment in the polyline
Definition at line 1158 of file FBEngine.cpp.
{ // first of all, find all intersection points (piercing in the face along the direction) // assume it is robust; what if it is not sufficiently robust? // if the polyline is open, find the intersection with the boundary edges, of the // polyline extruded at ends ErrorCode rval; // then find the position int numIniPoints = (int) xyz.size() / 3; if ( (closed && numIniPoints < 3) || (!closed && numIniPoints<2) ) MBERRORR(MB_FAILURE, "not enough polyline points "); EntityHandle rootForFace; rval = _my_geomTopoTool->get_root(face, rootForFace); MBERRORR(rval, "Failed to get root of face."); const double dir[] = { direction[0], direction[1], direction[2] }; std::vector<EntityHandle> nodes; // get the nodes closest to the ray traces of interest // these are nodes on the boundary of original face; // if the cutting line is not closed, the starting - ending vertices of the // polygonal line must come from this list std::vector<CartVect> b_pos; std::vector<EntityHandle> boundary_nodes; std::vector<EntityHandle> splittingNodes; Range boundary_mesh_edges; if (!closed) { rval = boundary_nodes_on_face(face, boundary_nodes); MBERRORR(rval, "Failed to get boundary nodes."); b_pos.resize(boundary_nodes.size()); rval = _mbImpl->get_coords(&(boundary_nodes[0]), boundary_nodes.size(), (double *)(&b_pos[0][0])); MBERRORR(rval, "Failed to get coordinates for boundary nodes."); rval = boundary_mesh_edges_on_face(face, boundary_mesh_edges); MBERRORR(rval, "Failed to get mesh boundary edges for face."); } // int i = 0; CartVect dirct(direction); dirct.normalize(); // maybe an overkill? for (; i < numIniPoints; i++) { const double point[] = { xyz[3 * i], xyz[3 * i + 1], xyz[3 * i + 2] };// or even point( &(xyz[3*i]) ); // CartVect p1(point); if (!closed && ( (0==i) || (numIniPoints-1==i) ) ) { // find the intersection point between a plane and boundary mesh edges // this will be the closest point on the boundary of face int i1 = i+1; if (i==numIniPoints-1) i1= i-1;// previous point if the last // the direction is from point to point1 const double point1[] = { xyz[3 * i1], xyz[3 * i1 + 1], xyz[3 * i1 + 2] }; CartVect p2(point1); CartVect normPlane=(p2-p1)*dirct; normPlane.normalize(); //(roughly, from p1 to p2, perpendicular to dirct, in the "xy" plane // if the intx point is "outside" p1 - p2, skip if the intx point is closer to p2 CartVect perpDir = dirct*normPlane; Range::iterator ite=boundary_mesh_edges.begin(); // do a linear search for the best intersection point position (on a boundary edge) if (debug_splits) { std::cout << " p1:" << p1 <<"\n"; std::cout << " p2:" << p2 <<"\n"; std::cout << " perpDir:" << perpDir << "\n"; std::cout<<" boundary edges size:" << boundary_mesh_edges.size() << "\n"; } for ( ; ite!=boundary_mesh_edges.end(); ite++) { EntityHandle candidateEdge = *ite; const EntityHandle * conn2; int nno; rval= _mbImpl->get_connectivity(candidateEdge, conn2, nno); MBERRORR(rval, "Failed to get conn for boundary edge"); CartVect pts[2]; rval = _mbImpl->get_coords(conn2, 2, &(pts[0][0])); MBERRORR(rval, "Failed to get coords of nodes for boundary edge"); CartVect intx_point; double parPos; bool intersect = intersect_segment_and_plane_slice(pts[0], pts[1], p1, p2, dirct, normPlane, intx_point, parPos); if (debug_splits) { std::cout << " Edge:" << _mbImpl->id_from_handle(candidateEdge)<<"\n"; std::cout << " Node 1:" << _mbImpl->id_from_handle(conn2[0]) << pts[0] <<"\n"; std::cout << " Node 2:" << _mbImpl->id_from_handle(conn2[1]) << pts[1] <<"\n"; std::cout << " Intersect bool:" << intersect << "\n"; } if (intersect) { double proj1 = (intx_point-p1)%perpDir; double proj2 = (intx_point-p2)%perpDir; if ( ( fabs(proj1) > fabs(proj2) ) // this means it is closer to p2 than p1 ) continue; // basically, this means the intersection point is with a // boundary edge on the other side, closer to p2 than p1, so we skip it if (parPos==0) { //close to vertex 1, nothing to do nodes.push_back(conn2[0]); splittingNodes.push_back(conn2[0]); } else if (parPos ==1.) { //close to vertex 2, nothing to do nodes.push_back(conn2[1]); splittingNodes.push_back(conn2[1]); } else { // break the edge, create a new node at intersection point (will be smoothed out) EntityHandle newVertex; rval = _mbImpl->create_vertex(&(intx_point[0]), newVertex); MBERRORR(rval, "can't create vertex"); nodes.push_back(newVertex); split_internal_edge(candidateEdge, newVertex); splittingNodes.push_back(newVertex); _brokenEdges[newVertex] = candidateEdge; _piercedEdges.insert(candidateEdge); } break; // break from the loop over boundary edges, we are interested in the first // split (hopefully, the only split) } } if (ite==boundary_mesh_edges.end()) MBERRORR(MB_FAILURE, "Failed to find boundary intersection edge. Bail out"); } else { std::vector<double> distances_out; std::vector<EntityHandle> sets_out; std::vector<EntityHandle> facets_out; rval = _my_geomTopoTool->obb_tree()-> ray_intersect_sets(distances_out, sets_out, facets_out, rootForFace, tolerance, min_tolerace_intersections, point, dir); MBERRORR(rval, "Failed to get ray intersections."); if (distances_out.size() < 1) MBERRORR(MB_FAILURE, "Failed to get one intersection point, bad direction."); if (distances_out.size() > 1) { std::cout << " too many intersection points. Only the first one considered\n"; } std::vector<EntityHandle>::iterator pFace = std::find(sets_out.begin(), sets_out.end(), face); if (pFace == sets_out.end()) MBERRORR(MB_FAILURE, "Failed to intersect given face, bad direction."); unsigned int index = pFace-sets_out.begin(); // get the closest node of the triangle, and modify locally the triangle(s), so the // intersection point is at a new vertex, if needed CartVect P(point); CartVect Dir(dir); CartVect newPoint = P + distances_out[index] * Dir; // get the triangle coordinates double area_coord[3]; EntityHandle boundary_handle =0; // if 0, not on a boundary rval = area_coordinates(_mbImpl, facets_out[index], newPoint, area_coord, boundary_handle); MBERRORR(rval, "Failed to get area coordinates"); if (debug_splits) { std::cout <<" int point:" << newPoint << " area coord " << area_coord[0] << " " << area_coord[1] << " " << area_coord[2] << "\n"; std::cout << " triangle: " << _mbImpl->id_from_handle(facets_out[index]) << " boundary:" << boundary_handle << "\n"; } EntityType type; if (boundary_handle) type = _mbImpl->type_from_handle(boundary_handle); if (boundary_handle&& (type == MBVERTEX)) { // nothing to do, we are happy nodes.push_back(boundary_handle); } else { // for an edge, we will split 2 triangles // for interior point, we will create 3 triangles out of one // create a new vertex EntityHandle newVertex; rval = _mbImpl->create_vertex(&(newPoint[0]), newVertex); if (boundary_handle)// this is edge { split_internal_edge(boundary_handle, newVertex); _piercedEdges.insert(boundary_handle);// to be removed at the end } else divide_triangle(facets_out[index], newVertex); nodes.push_back(newVertex); } } } // now, we have to find more intersection points, either interior to triangles, or on edges, or on vertices // use the same tolerance as before // starting from 2 points on 2 triangles, and having the direction, get more intersection points // between the plane formed by direction and those 2 points, and edges from triangulation (the triangles // involved will be part of the same gentity , original face ( moab set) //int closed = 1;// closed = 0 if the polyline is not closed CartVect Dir(direction); std::vector<EntityHandle> chainedEdges; for (i = 0; i < numIniPoints - 1 + closed; i++) { int nextIndex = (i + 1) % numIniPoints; std::vector<EntityHandle> trianglesAlong; std::vector<CartVect> points; // otherwise to edges or even nodes std::vector<EntityHandle> entities; //start with initial points, intersect along the direction, find the facets rval = compute_intersection_points(face, nodes[i], nodes[nextIndex], Dir, points, entities, trianglesAlong); MBERRORR(rval, "can't get intersection points along a line"); std::vector<EntityHandle> nodesAlongPolyline; // refactor code; move some edge creation for each 2 intersection points nodesAlongPolyline.push_back(entities[0]); // it is for sure a node int num_points = (int) points.size(); // it should be num_triangles + 1 for (int j = 0; j < num_points-1; j++) { EntityHandle tri = trianglesAlong[j]; // this is happening in trianglesAlong i EntityHandle e1 = entities[j]; EntityHandle e2 = entities[j + 1]; EntityType et1 = _mbImpl->type_from_handle(e1); //EntityHandle vertex1 = nodesAlongPolyline[i];// irrespective of the entity type i, // we already have the vertex there EntityType et2 = _mbImpl->type_from_handle(e2); if (et2 == MBVERTEX) { nodesAlongPolyline.push_back(e2); } else // if (et2==MBEDGE) { CartVect coord_vert=points[j+1]; EntityHandle newVertex; rval = _mbImpl->create_vertex((double*)&coord_vert, newVertex); MBERRORR(rval, "can't create vertex"); nodesAlongPolyline.push_back(newVertex); } // if vertices, do not split anything, just get the edge for polyline if (et2 == MBVERTEX && et1 == MBVERTEX) { // nothing to do, just continue; continue; // continue the for loop } if (debug_splits) { std::cout <<"tri: type: " << _mbImpl->type_from_handle(tri) << " id:" << _mbImpl->id_from_handle(tri) << "\n e1:" << e1 << " id:" <<_mbImpl->id_from_handle(e1) << " e2:" << e2 << " id:" <<_mbImpl->id_from_handle(e2) <<"\n"; } // here, at least one is an edge rval = BreakTriangle2( tri, e1, e2, nodesAlongPolyline[j], nodesAlongPolyline[j+1]); MBERRORR(rval, "can't break triangle 2"); if (et2==MBEDGE) _piercedEdges.insert(e2); _piercedTriangles.insert(tri); } // nodesAlongPolyline will define a new geometric edge if (debug_splits) { std::cout<<"nodesAlongPolyline: " << nodesAlongPolyline.size() << "\n"; std::cout << "points: " << num_points << "\n"; } // if needed, create edges along polyline, or revert the existing ones, to // put them in a new edge set EntityHandle new_geo_edge; rval = create_new_gedge(nodesAlongPolyline, new_geo_edge); MBERRORR(rval, "can't create a new edge"); chainedEdges.push_back(new_geo_edge); // end copy } // the segment between point_i and point_i+1 is in trianglesAlong_i // points_i is on entities_i // all these edges are oriented correctly rval = split_surface(face, chainedEdges, splittingNodes, oNewFace); MBERRORR(rval, "can't split surface"); // rval = chain_edges(min_dot); // acos(0.8)~= 36 degrees MBERRORR(rval, "can't chain edges"); return MB_SUCCESS; }
ErrorCode moab::FBEngine::weave_lateral_face_from_edges | ( | EntityHandle | bEdge, |
EntityHandle | tEdge, | ||
double * | direction, | ||
EntityHandle & | newLatFace | ||
) |
Definition at line 3261 of file FBEngine.cpp.
{ // in weird cases might need to create new vertices in the interior; // in most cases, it is OK ErrorCode rval = _mbImpl->create_meshset(MESHSET_SET, newLatFace); MBERRORR(rval, "can't create new lateral face"); EntityHandle v[4]; // vertex sets // bot edge will be v1->v2 // top edge will be v3->v4 // we need to create edges from v1 to v3 and from v2 to v4 std::vector<EntityHandle> adj; rval = _mbImpl->get_child_meshsets(bEdge, adj); MBERRORR(rval, "can't get children nodes"); bool periodic = false; if (adj.size()==1) { v[0] = v[1] = adj[0]; periodic = true; } else { v[0]=adj[0]; v[1]=adj[1]; } int senseB; rval = getEgVtxSense( bEdge, v[0], v[1], senseB ); MBERRORR(rval, "can't get bottom edge sense"); if (-1==senseB) { v[1]=adj[0];// so , bEdge will be oriented from v[0] to v[1], and will start at nodes1, coords1.. v[0]=adj[1]; } adj.clear(); rval = _mbImpl->get_child_meshsets(tEdge, adj); MBERRORR(rval, "can't get children nodes"); if (adj.size()==1) { v[2]=v[3]=adj[0]; if (!periodic) MBERRORR(MB_FAILURE, "top edge is periodic, but bottom edge is not"); } else { v[2]=adj[0]; v[3]=adj[1]; if (periodic) MBERRORR(MB_FAILURE, "top edge is not periodic, but bottom edge is"); } // now, using nodes on bottom edge and top edge, create triangles, oriented outwards the // volume (sense positive on bottom edge) std::vector<EntityHandle> nodes1; rval = get_nodes_from_edge(bEdge, nodes1); MBERRORR(rval, "can't get nodes from bott edge"); std::vector<EntityHandle> nodes2; rval = get_nodes_from_edge(tEdge, nodes2); MBERRORR(rval, "can't get nodes from top edge"); std::vector<CartVect> coords1, coords2; coords1.resize(nodes1.size()); coords2.resize(nodes2.size()); int N1 = (int)nodes1.size(); int N2 = (int)nodes2.size(); rval = _mbImpl->get_coords(&(nodes1[0]), nodes1.size(), (double*) &(coords1[0])); MBERRORR(rval, "can't get coords of nodes from bott edge"); rval = _mbImpl->get_coords(&(nodes2[0]), nodes2.size(), (double*) &(coords2[0])); MBERRORR(rval, "can't get coords of nodes from top edge"); CartVect up(direction); // see if the start and end coordinates are matching, if not, reverse edge 2 nodes and coordinates CartVect v1 = (coords1[0]-coords2[0])*up; CartVect v2 = (coords1[0]-coords2[N2-1])*up; if (v1.length_squared()>v2.length_squared()) { // we need to reverse coords2 and node2, as nodes are not above each other // the edges need to be found between v0 and v3, v1 and v2! for (unsigned int k=0 ; k<nodes2.size()/2; k++) { EntityHandle tmp=nodes2[k]; nodes2[k] = nodes2[N2-1-k]; nodes2[N2-1-k] = tmp; CartVect tv = coords2[k]; coords2[k] = coords2[N2-1-k]; coords2[N2-1-k]= tv; } } // make sure v[2] has nodes2[0], if not, reverse v[2] and v[3] if (!_mbImpl->contains_entities(v[2], &(nodes2[0]), 1)) { //reverse v[2] and v[3], so v[2] will be above v[0] EntityHandle tmp = v[2]; v[2] = v[3]; v[3]= tmp; } // now we know that v[0]--v[3] will be vertex sets in the order we want EntityHandle nd[4]={nodes1[0], nodes1[N1-1], nodes2[0], nodes2[N2-1]}; adj.clear(); EntityHandle e1, e2; // find edge 1 between v[0] and v[2], and e2 between v[1] and v[3] rval=_mbImpl->get_parent_meshsets(v[0], adj); MBERRORR(rval, "can't get edges connected to vertex set 1"); bool found = false; for (unsigned int j =0; j< adj.size(); j++) { EntityHandle ed=adj[j]; Range vertices; rval = _mbImpl->get_child_meshsets(ed, vertices); if (vertices.find(v[2])!=vertices.end()) { found = true; e1 = ed; break; } } if (!found) { // create an edge from v[0] to v[2] rval = _mbImpl->create_meshset(MESHSET_SET, e1); MBERRORR(rval, "can't create edge 1"); rval=_mbImpl->add_parent_child(e1, v[0]); MBERRORR(rval, "can't add parent - child relation"); rval=_mbImpl->add_parent_child(e1, v[2]); MBERRORR(rval, "can't add parent - child relation"); EntityHandle nn2[2] = {nd[0], nd[2]}; EntityHandle medge; rval = _mbImpl->create_element(MBEDGE, nn2, 2, medge); MBERRORR(rval, "can't create mesh edge"); rval = _mbImpl->add_entities(e1, &medge, 1); MBERRORR(rval, "can't add mesh edge to geo edge"); rval = this->_my_geomTopoTool->add_geo_set(e1, 1); MBERRORR(rval, "can't add edge to gtt"); } // find the edge from v2 to v4 (if not, create one) rval=_mbImpl->get_parent_meshsets(v[1], adj); MBERRORR(rval, "can't get edges connected to vertex set 2"); found = false; for (unsigned int i =0; i< adj.size(); i++) { EntityHandle ed=adj[i]; Range vertices; rval = _mbImpl->get_child_meshsets(ed, vertices); if (vertices.find(v[3])!=vertices.end()) { found = true; e2 = ed; break; } } if (!found) { // create an edge from v2 to v4 rval = _mbImpl->create_meshset(MESHSET_SET, e2); MBERRORR(rval, "can't create edge 1"); rval=_mbImpl->add_parent_child(e2, v[1]); MBERRORR(rval, "can't add parent - child relation"); rval=_mbImpl->add_parent_child(e2, v[3]); MBERRORR(rval, "can't add parent - child relation"); EntityHandle nn2[2] = {nd[1], nd[3]}; EntityHandle medge; rval = _mbImpl->create_element(MBEDGE, nn2, 2, medge); MBERRORR(rval, "can't create mesh edge"); rval = _mbImpl->add_entities(e2, &medge, 1); MBERRORR(rval, "can't add mesh edge to geo edge"); rval = _my_geomTopoTool->add_geo_set(e2, 1); MBERRORR(rval, "can't add edge to gtt"); } // now we have the four edges, add them to the face, as children // add children to face rval=_mbImpl->add_parent_child(newLatFace, bEdge); MBERRORR(rval, "can't add parent - child relation"); rval=_mbImpl->add_parent_child(newLatFace, tEdge); MBERRORR(rval, "can't add parent - child relation"); rval=_mbImpl->add_parent_child(newLatFace, e1); MBERRORR(rval, "can't add parent - child relation"); rval=_mbImpl->add_parent_child(newLatFace, e2); MBERRORR(rval, "can't add parent - child relation"); rval = _my_geomTopoTool->add_geo_set(newLatFace, 2); MBERRORR(rval, "can't add face to gtt"); // add senses // rval = _my_geomTopoTool->set_sense(bEdge, newLatFace, 1); MBERRORR(rval, "can't set bottom edge sense to the lateral face"); int Tsense; rval = getEgVtxSense( tEdge, v[3], v[2], Tsense ); MBERRORR(rval, "can't get top edge sense"); // we need to see what sense has topEdge in face rval = _my_geomTopoTool->set_sense(tEdge, newLatFace, Tsense); MBERRORR(rval, "can't set top edge sense to the lateral face"); rval = _my_geomTopoTool->set_sense(e1, newLatFace, -1); MBERRORR(rval, "can't set first vert edge sense"); rval = _my_geomTopoTool->set_sense(e2, newLatFace, 1); MBERRORR(rval, "can't set second edge sense to the lateral face"); // first, create edges along direction, for the int indexB=0, indexT=0;// indices of the current nodes in the weaving process // weaving is either up or down; the triangles are oriented positively either way // up is nodes1[indexB], nodes2[indexT+1], nodes2[indexT] // down is nodes1[indexB], nodes1[indexB+1], nodes2[indexT] // the decision to weave up or down is based on which one is closer to the direction normal /* * * --------*------*-----------* ^ * / . \ . . ------> dir1 | up * /. \ . . | * -----*------------*----* * */ // we have to change the logic to account for cases when the curve in xy plane is not straight // (for example, when merging curves with a min_dot < -0.5, which means that the edges // could be even closed (periodic), with one vertex // the top and bottom curves should follow the same path in the "xy" plane (better to say // the plane perpendicular to the direction of weaving) // in this logic, the vector dir1 varies along the curve !!! CartVect dir1= coords1[1] - coords1[0];// we should have at least 2 nodes, N1>=2!! CartVect planeNormal = dir1*up; dir1 = up * planeNormal; dir1.normalize(); // this direction will be updated constantly with the direction of last edge added bool weaveDown = true; CartVect startP = coords1[0]; // used for origin of comparisons while(1) { if ((indexB == N1-1) && (indexT == N2-1)) break; // we cannot advance anymore if (indexB == N1-1) { weaveDown = false; } else if (indexT==N2-1) { weaveDown = true; } else { // none are at the end, we have to decide which way to go, based on which index + 1 is closer double proj1 = (coords1[indexB+1]-startP)%dir1; double proj2 = (coords2[indexT+1]-startP)%dir1; if (proj1 < proj2) weaveDown = true; else weaveDown = false; } EntityHandle nTri[3] = { nodes1[indexB], nodes2[indexT+1], nodes2[indexT]}; if (weaveDown) { nTri[1] = nodes1[indexB+1]; nTri[2] = nodes2[indexT]; indexB++; } else indexT++; EntityHandle triangle; rval = _mbImpl->create_element(MBTRI, nTri, 3, triangle); MBERRORR(rval, "can't create triangle"); rval = _mbImpl->add_entities(newLatFace, &triangle, 1); MBERRORR(rval, "can't add triangle to face set"); if (weaveDown) { // increase was from nodes1[indexB-1] to nodes1[indexb] dir1= coords1[indexB] - coords1[indexB-1];// we should have at least 2 nodes, N1>=2!! } else { dir1= coords2[indexT] - coords2[indexT-1]; } dir1 = up * (dir1*up); dir1.normalize(); } // we do not check yet if the triangles are inverted // if yes, we should correct them. HOW? // we probably need a better meshing strategy, one that can overcome really bad meshes. // again, these faces are not what we should use for geometry, maybe we should use the // extruded quads, identified AFTER hexa are created. // right now, I see only a cosmetic use of these lateral faces // the whole idea of volume maybe is overrated // volume should be just quads extruded from bottom ? // return MB_SUCCESS; }
std::map<EntityHandle, EntityHandle> moab::FBEngine::_brokenEdges [private] |
Definition at line 263 of file FBEngine.hpp.
std::map<EntityHandle, SmoothCurve*> moab::FBEngine::_edges [private] |
Definition at line 256 of file FBEngine.hpp.
std::map<EntityHandle, SmoothFace*> moab::FBEngine::_faces [private] |
Definition at line 255 of file FBEngine.hpp.
bool moab::FBEngine::_initialized [private] |
Definition at line 246 of file FBEngine.hpp.
Interface* moab::FBEngine::_mbImpl [private] |
Definition at line 236 of file FBEngine.hpp.
GeomTopoTool* moab::FBEngine::_my_geomTopoTool [private] |
Definition at line 243 of file FBEngine.hpp.
Range moab::FBEngine::_my_gsets[5] [private] |
Definition at line 250 of file FBEngine.hpp.
Range moab::FBEngine::_newTriangles [private] |
Definition at line 261 of file FBEngine.hpp.
Range moab::FBEngine::_piercedEdges [private] |
Definition at line 262 of file FBEngine.hpp.
Range moab::FBEngine::_piercedTriangles [private] |
Definition at line 260 of file FBEngine.hpp.
bool moab::FBEngine::_smooth [private] |
Definition at line 245 of file FBEngine.hpp.
SmoothCurve** moab::FBEngine::_smthCurve [private] |
Definition at line 258 of file FBEngine.hpp.
SmoothFace** moab::FBEngine::_smthFace [private] |
Definition at line 257 of file FBEngine.hpp.
bool moab::FBEngine::_t_created [private] |
Definition at line 244 of file FBEngine.hpp.