cgma
|
#include <BoundaryConstrainTool.hpp>
Public Member Functions | |
BoundaryConstrainTool () | |
BoundaryConstrainTool (SURF *ref_face_ptr) | |
~BoundaryConstrainTool () | |
CubitStatus | recover_edge (NODE *n0_ptr, NODE *n1_ptr, EDGE *&recovered_edge_ptr, DLIList< TRI * > *facet_list) |
Private Member Functions | |
CubitStatus | get_crossing_edges (CubitVector &edge_vec, NODE *n0_ptr, NODE *n1_ptr) |
IntersectionType | intersect_from_node (CubitVector &edge_vec, NODE *n0_ptr, TRI *&tri_ptr, EDGE *&edge_ptr, NODE *&node_ptr) |
IntersectionType | intersect_from_edge (CubitVector &edge_vec, NODE *n0_ptr, NODE *n1_ptr, TRI *&tri_ptr, EDGE *&edge_ptr, NODE *&node_ptr) |
CubitStatus | node_at_mid (CubitVector &edge_vec, TRI *tri_ptr, NODE *node_ptr) |
SwapStatus | swap_edge (EDGE *&edge_ptr) |
CubitStatus | edge_intersected (CubitVector &edge_vec, EDGE *edge_ptr, NODE *n0_ptr, NODE *n1_ptr) |
Private Attributes | |
DLIList< TRI * > * | facetList |
SURF * | refFacePtr |
double | zeroTol |
DLIList< EDGE * > | edgeCrossQueue |
Definition at line 16 of file BoundaryConstrainTool.hpp.
BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::BoundaryConstrainTool | ( | ) |
Definition at line 40 of file BoundaryConstrainTool.cpp.
{ refFacePtr = NULL; }
BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::BoundaryConstrainTool | ( | SURF * | ref_face_ptr | ) |
Definition at line 25 of file BoundaryConstrainTool.cpp.
{ refFacePtr = ref_face_ptr; }
BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::~BoundaryConstrainTool | ( | ) |
Definition at line 53 of file BoundaryConstrainTool.cpp.
{ }
CubitStatus BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::edge_intersected | ( | CubitVector & | edge_vec, |
EDGE * | edge_ptr, | ||
NODE * | n0_ptr, | ||
NODE * | n1_ptr | ||
) | [private] |
Definition at line 570 of file BoundaryConstrainTool.cpp.
{ // if the end nodes match the end nodes of the edge we are checking, then // we are OK - no intersection NODE *en0_ptr = edge_ptr->start_node(); NODE *en1_ptr = edge_ptr->end_node(); if (en0_ptr == n0_ptr || en1_ptr == n0_ptr || en0_ptr == n1_ptr || en1_ptr == n1_ptr) return CUBIT_SUCCESS; CubitVector vec1( en0_ptr->coordinates().x() - n0_ptr->coordinates().x(), en0_ptr->coordinates().y() - n0_ptr->coordinates().y(), 0.0 ); double len = sqrt( SQR( vec1.x() ) + SQR( vec1.y() ) ); if (len == 0.0) return CUBIT_FAILURE; vec1.x( vec1.x() / len ); vec1.y( vec1.y() / len ); CubitVector vec2( en1_ptr->coordinates().x() - n0_ptr->coordinates().x(), en1_ptr->coordinates().y() - n0_ptr->coordinates().y(), 0.0 ); len = sqrt( SQR( vec2.x() ) + SQR( vec2.y() ) ); if (len == 0.0) return CUBIT_FAILURE; vec2.x( vec2.x() / len ); vec2.y( vec2.y() / len ); double cross1 = edge_vec.x() * vec1.y() - edge_vec.y() * vec1.x(); double cross2 = edge_vec.x() * vec2.y() - edge_vec.y() * vec2.x(); // if the en0 and en1 are both on opposite sides of edge_vec then // we know that it intersects somewhere if (cross1 * cross2 <= 0.0) { edgeCrossQueue.append( edge_ptr ); } return CUBIT_SUCCESS; }
CubitStatus BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::get_crossing_edges | ( | CubitVector & | edge_vec, |
NODE * | n0_ptr, | ||
NODE * | n1_ptr | ||
) | [private] |
Definition at line 175 of file BoundaryConstrainTool.cpp.
{ CubitStatus status = CUBIT_FAILURE; IntersectionType isect_type = AT_BEGIN; IntersectionType last_isect_type = NO_ISECT; NODE *node_ptr; EDGE *edge_ptr; TRI *tri_ptr; CubitBoolean done = CUBIT_FALSE; do { switch(isect_type) { case AT_BEGIN: last_isect_type = AT_BEGIN; isect_type = intersect_from_node( edge_vec, n0_ptr, tri_ptr, edge_ptr, node_ptr ); break; case AT_EDGE: last_isect_type = AT_EDGE; edgeCrossQueue.append( edge_ptr ); isect_type = intersect_from_edge( edge_vec, n0_ptr, n1_ptr, tri_ptr, edge_ptr, node_ptr ); break; case AT_MID: status = node_at_mid( edge_vec, tri_ptr, node_ptr ); if (status != CUBIT_SUCCESS) { return status; } isect_type = last_isect_type; break; case AT_END: done = CUBIT_TRUE; status = CUBIT_SUCCESS; break; case NO_ISECT: done = 1; return CUBIT_FAILURE; } } while (!done); return status; }
IntersectionType BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::intersect_from_edge | ( | CubitVector & | edge_vec, |
NODE * | n0_ptr, | ||
NODE * | n1_ptr, | ||
TRI *& | tri_ptr, | ||
EDGE *& | edge_ptr, | ||
NODE *& | node_ptr | ||
) | [private] |
Definition at line 354 of file BoundaryConstrainTool.cpp.
{ IntersectionType isect_type = NO_ISECT; assert( edge_ptr != NULL && tri_ptr != NULL); // Get the adjacent face to the edge - there must be exactly two faces // next to this edge otherwise we've left the triangulation DLIList<TRI *> adjtris; edge_ptr->tris( adjtris ); if (adjtris.size() != 2) return NO_ISECT; TRI * nexttri_ptr = adjtris.get_and_step(); if (nexttri_ptr == tri_ptr) { nexttri_ptr = adjtris.get(); assert(nexttri_ptr != NULL && nexttri_ptr != tri_ptr); } tri_ptr = nexttri_ptr; // Check if we've arrived at the end (Does the this triangle contain n1) int ii; NODE *n_ptr[3]; nexttri_ptr->tri_nodes( n_ptr[0], n_ptr[1], n_ptr[2] ); CubitBoolean found = CUBIT_FALSE; for (ii=0; ii<3 && !found; ii++) { if (n_ptr[ii] == n1_ptr) { found = CUBIT_TRUE; edge_ptr = NULL; node_ptr = n1_ptr; tri_ptr = nexttri_ptr; isect_type = AT_END; } } // Determine which edge (or node) the vector intersects if (!found) { NODE *tn0_ptr, *tn1_ptr, *tn2_ptr; tn0_ptr = edge_ptr->start_node(); tn1_ptr = edge_ptr->end_node(); tn2_ptr = tri_ptr->next_node(tn1_ptr); //Checking for CCW order. Correct it if it is wrong if(tn2_ptr == tn0_ptr){ tn0_ptr = tn1_ptr; tn1_ptr = tn2_ptr; tn2_ptr = tri_ptr->next_node(tn1_ptr); } // Determine vector from n0 to tn2 CubitVector vec( tn2_ptr->coordinates().x() - n0_ptr->coordinates().x(), tn2_ptr->coordinates().y() - n0_ptr->coordinates().y(), 0.0 ); double len = sqrt(SQR(vec.x()) + SQR(vec.y())); if (len == 0.0) return NO_ISECT; vec.x( vec.x()/len ); vec.y( vec.y()/len ); // Compute the dot product of the normal to vec (above) // with the edgevec. // One of the following will result: // Dot > 0: edge defined by tn2 - tn0 is intersected // Dot < 0: edge defined by tn1 - tn2 is intersected // Dot = 0: node tn2 is intersected */ vec.z( vec.x() ); vec.x( -vec.y() ); vec.y( vec.z() ); vec.z( 0.0 ); double dot = vec.x() * edge_vec.x() + vec.y() * edge_vec.y(); if (fabs(dot) < ON_LINE_TOL) { isect_type = AT_MID; edge_ptr = NULL; node_ptr = tn2_ptr; } else if (dot > 0) { isect_type = AT_EDGE; edge_ptr = tn0_ptr->shared_edge( tn2_ptr ); node_ptr = NULL; } else { isect_type = AT_EDGE; edge_ptr = tn1_ptr->shared_edge( tn2_ptr ); node_ptr = NULL; } } return isect_type; }
IntersectionType BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::intersect_from_node | ( | CubitVector & | edge_vec, |
NODE * | n0_ptr, | ||
TRI *& | tri_ptr, | ||
EDGE *& | edge_ptr, | ||
NODE *& | node_ptr | ||
) | [private] |
Definition at line 231 of file BoundaryConstrainTool.cpp.
{ IntersectionType isect_type = NO_ISECT; // get all tris adjacent to n0_ptr DLIList<TRI *> tri_list; n0_ptr->tris( tri_list ); CubitBoolean found = CUBIT_FALSE; int itri; for (itri=0; itri<tri_list.size() && !found; itri++) { tri_ptr = tri_list.get_and_step(); // If the dot product of edges radiating from the node // are both greater than zero, then it is a candidate NODE *n1_ptr = tri_ptr->next_node( n0_ptr ); assert( n1_ptr != NULL ); edge_ptr = n0_ptr->shared_edge( n1_ptr ); assert( edge_ptr != NULL ); // define the normal vector to the edge CubitVector vec = n1_ptr->coordinates() - n0_ptr->coordinates(); vec.z( vec.x() ); vec.x( -vec.y() ); vec.y( vec.z() ); vec.z( 0.0 ); double length = sqrt(SQR(vec.x()) + SQR(vec.y())); if (length == 0.0) { node_ptr = NULL; edge_ptr = NULL; tri_ptr = NULL; return NO_ISECT; } vec.x( vec.x() / length ); vec.y( vec.y() / length ); // dot with the recover vector double dot = edge_vec.x() * vec.x() + edge_vec.y() * vec.y(); if (dot > -ON_LINE_TOL) { // Dot product within tolerance of zero means the vector // follows along edge of face and passes through a node if (fabs(dot) < ON_LINE_TOL) { vec = n1_ptr->coordinates() - n0_ptr->coordinates(); double direction = edge_vec.x() * vec.x() + edge_vec.y() * vec.y(); //if vector n1-n0 is in the same direction as edge_vec if(direction > 0){ vec = n1_ptr->coordinates() - n0_ptr->coordinates(); node_ptr = n1_ptr; isect_type = AT_MID; return isect_type; } } // do the same check on the other edge NODE *n2_ptr = tri_ptr->next_node( n1_ptr ); assert( n2_ptr != NULL ); edge_ptr = n0_ptr->shared_edge( n2_ptr ); assert( edge_ptr != NULL ); vec = n0_ptr->coordinates() - n2_ptr->coordinates(); vec.z( vec.x() ); vec.x( -vec.y() ); vec.y( vec.z() ); vec.z( 0.0 ); length = sqrt(SQR(vec.x()) + SQR(vec.y())); if (length == 0.0) { node_ptr = NULL; edge_ptr = NULL; tri_ptr = NULL; return NO_ISECT; } vec.x( vec.x() / length ); vec.y( vec.y() / length ); dot = edge_vec.x() * vec.x() + edge_vec.y() * vec.y(); if (fabs(dot) < ON_LINE_TOL) { node_ptr = n2_ptr; isect_type = AT_MID; return isect_type; } if (dot > -ON_LINE_TOL){ node_ptr = NULL; edge_ptr = n1_ptr->shared_edge( n2_ptr ); isect_type = AT_EDGE; return isect_type; } } } if (!found) { isect_type = NO_ISECT; node_ptr = NULL; edge_ptr = NULL; tri_ptr = NULL; } return isect_type; }
CubitStatus BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::node_at_mid | ( | CubitVector & | edge_vec, |
TRI * | tri_ptr, | ||
NODE * | node_ptr | ||
) | [private] |
Definition at line 463 of file BoundaryConstrainTool.cpp.
{ // don't know what to do here yet return CUBIT_FAILURE; }
CubitStatus BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::recover_edge | ( | NODE * | n0_ptr, |
NODE * | n1_ptr, | ||
EDGE *& | recovered_edge_ptr, | ||
DLIList< TRI * > * | facet_list | ||
) |
Definition at line 75 of file BoundaryConstrainTool.cpp.
{ assert(n0_ptr && n1_ptr); CubitStatus rv = CUBIT_SUCCESS; //Update the private Variable facetList = facet_list; // TRIvial case: edge is already in the triangulation. Return // now with the edge recovered_edge_ptr = n0_ptr->shared_edge(n1_ptr); if ( recovered_edge_ptr != NULL ) return CUBIT_SUCCESS; // Define the vector from node0 to node1. This is the direction // of the edge we want to recover CubitVector edge_vec = n1_ptr->coordinates() - n0_ptr->coordinates(); double length = edge_vec.normalize( ); if (length == 0.0) return CUBIT_FAILURE; zeroTol = length * CUBIT_RESABS; // Initialize the edge cross queue edgeCrossQueue.clean_out(); // Fill in the Queue with edges that cross the edge_vec rv = get_crossing_edges( edge_vec, n0_ptr, n1_ptr ); if (rv != CUBIT_SUCCESS) return rv; // Process each edge in the queue and swap edges on faces // adjacent to the edges crossing the recover vector EDGE *edge_ptr; SwapStatus swap_stat; while (edgeCrossQueue.size() > 0) { edge_ptr = edgeCrossQueue.remove(); swap_stat = swap_edge( edge_ptr ); switch (swap_stat) { case SWAP_FAILURE: return CUBIT_FAILURE; case SWAP_INVALID: // If flip was not valid, then put it back at the end of // the queue to be processed later edgeCrossQueue.append( edge_ptr ); break; case SWAP_SUCCESS: // Check if the edge just created by the flip also // crosses the recover vector. If it does, then // add these at the end of the queue to be processed later if (edgeCrossQueue.size() > 0) { rv = edge_intersected( edge_vec, edge_ptr, n0_ptr, n1_ptr ); if (rv != CUBIT_SUCCESS) return rv; } } } // Retrieve the recovered edge to pass back recovered_edge_ptr = n0_ptr->shared_edge(n1_ptr); if ( recovered_edge_ptr == NULL ) rv = CUBIT_FAILURE; return rv; }
SwapStatus BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::swap_edge | ( | EDGE *& | edge_ptr | ) | [private] |
Definition at line 481 of file BoundaryConstrainTool.cpp.
{ DLIList<TRI *>adjtris; edge_ptr->tris(refFacePtr, adjtris); if(adjtris.size() != 2) return SWAP_FAILURE; // check the potential new triangles TRI * tri0 = adjtris.get_and_step(); TRI * tri1 = adjtris.get(); NODE *n0, *n1, *n2, *n3; n0 = edge_ptr->start_node(); n1 = edge_ptr->end_node(); n2 = tri0 ->next_node(n1); //if direction is not in CCW order, correct it. if(n2 == n0){ n0 = n1; n1 = n2; n2 = tri0->next_node(n1); } n3 = tri1->next_node(n0); CubitVector e1( n1->coordinates().x() - n3->coordinates().x(), n1->coordinates().y() - n3->coordinates().y(), 0.0 ); double len = sqrt(SQR(e1.x()) + SQR(e1.y())); if (len == 0.0) return SWAP_FAILURE; e1.x( e1.x()/len ); e1.y( e1.y()/len ); CubitVector diag( n2->coordinates().x() - n3->coordinates().x(), n2->coordinates().y() - n3->coordinates().y(), 0.0 ); len = sqrt(SQR(diag.x()) + SQR(diag.y())); if (len == 0.0) return SWAP_FAILURE; diag.x( diag.x()/len ); diag.y( diag.y()/len ); CubitVector e2( n0->coordinates().x() - n3->coordinates().x(), n0->coordinates().y() - n3->coordinates().y(), 0.0 ); len = sqrt(SQR(e2.x()) + SQR(e2.y())); if (len == 0.0) return SWAP_FAILURE; e2.x( e2.x()/len ); e2.y( e2.y()/len ); // return now if we would create invalid triangles double cross = e1.x() * diag.y() - e1.y() * diag.x(); if (cross < ON_LINE_TOL) return SWAP_INVALID; cross = diag.x() * e2.y() - diag.y() * e2.x(); if (cross < ON_LINE_TOL) return SWAP_INVALID; // Do the swap // Delete the old triangles facetList->move_to(tri0); facetList->extract(); facetList->move_to(tri1); facetList->extract(); delete tri0; delete tri1; delete edge_ptr; // Create the new triangles tri0 = (TRI *) new TRICHILD( n1, n2, n3, refFacePtr); tri1 = (TRI *) new TRICHILD( n0, n3, n2, refFacePtr); facetList->append(tri0); facetList->append(tri1); edge_ptr = n2->shared_edge( n3 ); return SWAP_SUCCESS; }
DLIList<EDGE *> BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::edgeCrossQueue [private] |
Definition at line 22 of file BoundaryConstrainTool.hpp.
DLIList<TRI *>* BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::facetList [private] |
Definition at line 19 of file BoundaryConstrainTool.hpp.
SURF* BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::refFacePtr [private] |
Definition at line 20 of file BoundaryConstrainTool.hpp.
double BoundaryConstrainTool< SURF, TRI, EDGE, NODE, TRICHILD >::zeroTol [private] |
Definition at line 21 of file BoundaryConstrainTool.hpp.