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