cgma
|
#include <FBRetriangulate.hpp>
Public Member Functions | |
FBRetriangulate (std::vector< FB_Coord * > &my_verts, std::vector< FB_Triangle * > &my_tris, std::vector< int > &my_newfacets, std::vector< int > &my_newfacetsindex) | |
FBRetriangulate (std::vector< FB_Coord * > &my_verts, std::vector< FB_Triangle * > &my_tris, std::vector< int > &my_newfacets) | |
~FBRetriangulate () | |
CubitStatus | retriangulate_this_tri (int sequence, std::vector< FB_Edge * > &orphaned_edges) |
Private Types | |
enum | WindingType { CCW = 0, CW = 1 } |
Private Member Functions | |
void | make_vert_list () |
CubitStatus | add_bdry_edges (std::vector< FB_Edge * > &orphaned_edges) |
double | get_dist (double x0, double y0, double z0, double x1, double y1, double z1) |
CubitStatus | remove_min_max () |
void | add_edge_up (int v0, int seq) |
void | add_edge_down (int v0, int seq) |
bool | test_for_crossing (int v0, int v1, int v2, int v3) |
void | add_tri_edge (int v0, int v1, int v0_type, int v1_type) |
bool | get_a_chain (std::vector< int > *chainlist) |
void | sort_vertstufflist_edges () |
void | get_next_vert_in_chain (int &vthis, int &vprev, int direction) |
void | add_this_bdry_edge (int v0, int v1, int v0_type, int v1_type) |
void | classify_edges () |
void | get_edge_indices (int v0, int v1, int v2, int parent, int &e0index, int &e1index, int &e2index) |
Private Attributes | |
std::vector< FB_Coord * > | verts |
std::vector< FB_Triangle * > * | tris |
std::vector< int > * | newfacets |
std::vector< int > * | newfacetsindex |
int | p_dir |
int | s_dir |
WindingType | winding |
FB_Triangle * | my_tri |
std::vector< VertexStuff * > | vertstufflist |
Definition at line 35 of file FBRetriangulate.hpp.
enum FBRetriangulate::WindingType [private] |
FBRetriangulate::FBRetriangulate | ( | std::vector< FB_Coord * > & | my_verts, |
std::vector< FB_Triangle * > & | my_tris, | ||
std::vector< int > & | my_newfacets, | ||
std::vector< int > & | my_newfacetsindex | ||
) |
Definition at line 45 of file FBRetriangulate.cpp.
FBRetriangulate::FBRetriangulate | ( | std::vector< FB_Coord * > & | my_verts, |
std::vector< FB_Triangle * > & | my_tris, | ||
std::vector< int > & | my_newfacets | ||
) |
Definition at line 58 of file FBRetriangulate.cpp.
Definition at line 70 of file FBRetriangulate.cpp.
{ }
CubitStatus FBRetriangulate::add_bdry_edges | ( | std::vector< FB_Edge * > & | orphaned_edges | ) | [private] |
Definition at line 276 of file FBRetriangulate.cpp.
{ // For each triangle edge, make a list of pairs of edge points and // vertex numbers that touch the edge. Then sort the list by distance // from the start of the edge. (This was what we really put in the // pair, not the point itself.) Finally, go through this sorted list // and add edges to the edge_list. If the edge_list is empty, we // still must add in the triangle edge itself. CubitStatus status; FB_Edge *edge; std::list< std::pair<double,int> > edge0_list, edge1_list, edge2_list; std::list< std::pair<double,int> >::iterator dp; std::vector<FB_Edge*>::iterator dpe, dpe_orig; double vx0, vy0, vz0, vx1, vy1, vz1, vx2, vy2, vz2, dist; std::pair<double,int> mypair; status = CUBIT_SUCCESS; vx0 = verts[my_tri->v0]->coord[0]; vy0 = verts[my_tri->v0]->coord[1]; vz0 = verts[my_tri->v0]->coord[2]; vx1 = verts[my_tri->v1]->coord[0]; vy1 = verts[my_tri->v1]->coord[1]; vz1 = verts[my_tri->v1]->coord[2]; vx2 = verts[my_tri->v2]->coord[0]; vy2 = verts[my_tri->v2]->coord[1]; vz2 = verts[my_tri->v2]->coord[2]; dpe = my_tri->edge_list.begin(); while ( dpe != my_tri->edge_list.end() ) { edge = *dpe; dpe++; if ( (edge->v0_type == INTERIOR_VERT) && (edge->v1_type == INTERIOR_VERT) ) continue; if ( edge->v0_type == EDGE_0 ) { dist = get_dist(vx0,vy0,vz0,verts[edge->v0]->coord[0], verts[edge->v0]->coord[1],verts[edge->v0]->coord[2]); edge0_list.push_back(std::pair<double,int>(dist,edge->v0)); } else if ( edge->v0_type == EDGE_1 ) { dist = get_dist(vx1,vy1,vz1,verts[edge->v0]->coord[0], verts[edge->v0]->coord[1],verts[edge->v0]->coord[2]); edge1_list.push_back(std::pair<double,int>(dist,edge->v0)); } else if ( edge->v0_type == EDGE_2 ) { dist = get_dist(vx2,vy2,vz2,verts[edge->v0]->coord[0], verts[edge->v0]->coord[1],verts[edge->v0]->coord[2]); edge2_list.push_back(std::pair<double,int>(dist,edge->v0)); } if ( edge->v1_type == EDGE_0 ) { dist = get_dist(vx0,vy0,vz0,verts[edge->v1]->coord[0], verts[edge->v1]->coord[1],verts[edge->v1]->coord[2]); edge0_list.push_back(std::pair<double,int>(dist,edge->v1)); } else if ( edge->v1_type == EDGE_1 ) { dist = get_dist(vx1,vy1,vz1,verts[edge->v1]->coord[0], verts[edge->v1]->coord[1],verts[edge->v1]->coord[2]); edge1_list.push_back(std::pair<double,int>(dist,edge->v1)); } else if ( edge->v1_type == EDGE_2 ) { dist = get_dist(vx2,vy2,vz2,verts[edge->v1]->coord[0], verts[edge->v1]->coord[1],verts[edge->v1]->coord[2]); edge2_list.push_back(std::pair<double,int>(dist,edge->v1)); } } edge0_list.sort(); edge1_list.sort(); edge2_list.sort(); // Now we have to remove all BDRY_EDGEs because they will be made anew // in what follows. Erasing elements from a vector is inefficient, but // this shouldn't happen often. dpe = my_tri->edge_list.begin(); dpe_orig = my_tri->edge_list.end(); while ( dpe != dpe_orig ) { edge = *dpe; if ( edge->edge_type == BDRY_EDGE ) { dpe = my_tri->edge_list.erase(dpe); orphaned_edges.push_back(edge); dpe_orig = my_tri->edge_list.end(); } else { dpe++; } } int newv0, newv1, newv0_type, newv1_type; newv0_type = newv1_type = EDGE_0; newv0 = my_tri->v0; dp = edge0_list.begin(); while ( dp != edge0_list.end() ) { mypair = *dp; newv1 = mypair.second; // It is possible to get the same vert more than once in the list. // After sorting, they will be adjacent. The following if statement // causes duplicate verts to be used only once. if ( newv0 != newv1 ) { add_this_bdry_edge(newv0,newv1,newv0_type,newv1_type); newv0 = newv1; } dp++; } newv1 = my_tri->v1; if ( newv0 != newv1 ) add_this_bdry_edge(newv0,newv1,newv0_type,newv1_type); newv0_type = newv1_type = EDGE_1; newv0 = my_tri->v1; dp = edge1_list.begin(); while ( dp != edge1_list.end() ) { mypair = *dp; newv1 = mypair.second; if ( newv0 != newv1 ) { add_this_bdry_edge(newv0,newv1,newv0_type,newv1_type); newv0 = newv1; } dp++; } newv1 = my_tri->v2; if ( newv0 != newv1 ) add_this_bdry_edge(newv0,newv1,newv0_type,newv1_type); newv0_type = newv1_type = EDGE_2; newv0 = my_tri->v2; dp = edge2_list.begin(); while ( dp != edge2_list.end() ) { mypair = *dp; newv1 = mypair.second; if ( newv0 != newv1 ) { add_this_bdry_edge(newv0,newv1,newv0_type,newv1_type); newv0 = newv1; } dp++; } newv1 = my_tri->v0; if ( newv0 != newv1 ) add_this_bdry_edge(newv0,newv1,newv0_type,newv1_type); return status; }
void FBRetriangulate::add_edge_down | ( | int | v0, |
int | seq | ||
) | [private] |
Definition at line 543 of file FBRetriangulate.cpp.
{ int i, k; int v1, v0test, v1test, v0type, v1type; bool foundit, crossed; FB_Edge *edge; std::vector<FB_Edge*>::iterator dpe; v1 = 0; //To keep compiler from warning that v1 might be used uninitialized. v1type = 0; v0type = vertstufflist[seq]->v0type; for ( k = seq-1; k > -1; k-- ) { foundit = true; v1 = vertstufflist[k]->v0; if ( fabs(verts[v1]->coord[p_dir]-verts[v0]->coord[p_dir]) < EPSILON ) continue; v1type = vertstufflist[k]->v0type; // v0 to v1 is the putative new edge. Test whether it crosses // any existing internal edge. Any such internal edge that it // crosses has to have an endpoint higher than v1. If v1 is the // next-to-top vertex, use it. if ( k == 0 ) { foundit = true; add_tri_edge(v0,v1,v0type,v1type); return; } for ( i = k-1; i > 0; i-- ) { dpe = vertstufflist[i]->edge_list.begin(); while ( dpe != vertstufflist[i]->edge_list.end() ) { edge = *dpe; dpe++; if ( (edge->v0_type != INTERIOR_VERT) && (edge->v1_type != INTERIOR_VERT) ) continue; v0test = edge->v0; v1test = edge->v1; if ( (v0test == v1) || (v1test == v1) ) continue; crossed = test_for_crossing(v0,v1,v0test,v1test); if ( crossed == true ) { foundit = false; break; } } if ( foundit == false ) break; } // end of "for (i ...." if ( foundit == true ) break; } add_tri_edge(v0,v1,v0type,v1type); }
void FBRetriangulate::add_edge_up | ( | int | v0, |
int | seq | ||
) | [private] |
Definition at line 492 of file FBRetriangulate.cpp.
{ unsigned int i, k; int v1, v0test, v1test, v0type, v1type; bool foundit, crossed; FB_Edge *edge; std::vector<FB_Edge*>::iterator dpe; v1 = 0; //To keep compiler from warning that v1 might be used uninitialized. v1type = 0; v0type = vertstufflist[seq]->v0type; for ( k = seq+1; k < vertstufflist.size(); k++ ) { foundit = true; v1 = vertstufflist[k]->v0; if ( fabs(verts[v1]->coord[p_dir]-verts[v0]->coord[p_dir]) < EPSILON ) continue; v1type = vertstufflist[k]->v0type; // v0 to v1 is the putative new edge. Test whether it crosses any // existing internal edge. Any such internal edge that it crosses // has to have an endpoint higher than v1. If v1 is the next-to-top // vertex, use it. if ( k == vertstufflist.size() - 1 ) { foundit = true; add_tri_edge(v0,v1,v0type,v1type); return; } for ( i = k+1; i < vertstufflist.size()-1; i++ ) { dpe = vertstufflist[i]->edge_list.begin(); while ( dpe != vertstufflist[i]->edge_list.end() ) { edge = *dpe; dpe++; if ( (edge->v0_type != INTERIOR_VERT) && (edge->v1_type != INTERIOR_VERT) ) continue; v0test = edge->v0; v1test = edge->v1; if ( (v0test == v1) || (v1test == v1) ) continue; crossed = test_for_crossing(v0,v1,v0test,v1test); if ( crossed == true ) { foundit = false; break; } } if ( foundit == false ) break; } // end of "for (i ...." if ( foundit == true ) break; } add_tri_edge(v0,v1,v0type,v1type); }
void FBRetriangulate::add_this_bdry_edge | ( | int | v0, |
int | v1, | ||
int | v0_type, | ||
int | v1_type | ||
) | [private] |
Definition at line 416 of file FBRetriangulate.cpp.
{ // Add an edge if it doesn't already exist. std::vector<FB_Edge*>::iterator dpe; bool ifoundit; FB_Edge *edge, *new_edge; ifoundit = false; dpe = my_tri->edge_list.begin(); while ( dpe != my_tri->edge_list.end() ) { edge = *dpe; if ( ( ((int)edge->v0 == v0) && ((int)edge->v1 == v1) ) || ( ((int)edge->v0 == v1) && ((int)edge->v1 == v0) ) ) { ifoundit = true; break; } dpe++; } if ( ifoundit == false ) { new_edge = new FB_Edge(v0,v1,v0_type,v1_type,true); new_edge->edge_type = BDRY_EDGE; my_tri->edge_list.push_back(new_edge); } }
void FBRetriangulate::add_tri_edge | ( | int | v0, |
int | v1, | ||
int | v0_type, | ||
int | v1_type | ||
) | [private] |
Definition at line 625 of file FBRetriangulate.cpp.
{ FB_Edge *edge; unsigned int i; edge = new FB_Edge(v0,v1,v0_type,v1_type,false); edge->edge_type = INTERIOR_EDGE; my_tri->edge_list.push_back(edge); for ( i = 0; i < vertstufflist.size(); i++ ) { if ( vertstufflist[i]->v0 == v0 ) { vertstufflist[i]->edge_list.push_back(edge); } if ( vertstufflist[i]->v0 == v1 ) { vertstufflist[i]->edge_list.push_back(edge); v1_type = vertstufflist[i]->v0type; } } }
void FBRetriangulate::classify_edges | ( | ) | [private] |
Definition at line 832 of file FBRetriangulate.cpp.
{ // Flag boundary edges as such. FB_Edge *edge; std::vector<FB_Edge*>::iterator dpe; int type; dpe = my_tri->edge_list.begin(); while ( dpe != my_tri->edge_list.end() ) { edge = *dpe; if ( (edge->v0_type != INTERIOR_VERT) && (edge->v1_type != INTERIOR_VERT) ) { if ( edge->v0_type == edge->v1_type ) edge->edge_type = BDRY_EDGE; else { type = UNKNOWN; switch( edge->v0_type ) { case VERTEX_0: if ( edge->v1_type != EDGE_1 ) { type = BDRY_EDGE; if ( edge->edge_type == INTERSECTION_EDGE) { if ( edge->v1_type == VERTEX_1 ) my_tri->cubitedge0index = INTERSECTION_EDGE; else if ( edge->v1_type == VERTEX_2 ) my_tri->cubitedge2index = INTERSECTION_EDGE; } } break; case VERTEX_1: if ( edge->v1_type != EDGE_2 ) { type = BDRY_EDGE; if ( edge->edge_type == INTERSECTION_EDGE) { if ( edge->v1_type == VERTEX_2 ) my_tri->cubitedge1index = INTERSECTION_EDGE; else if ( edge->v1_type == VERTEX_0 ) my_tri->cubitedge0index = INTERSECTION_EDGE; } } break; case VERTEX_2: if ( edge->v1_type != EDGE_0 ) { type = BDRY_EDGE; if ( edge->edge_type == INTERSECTION_EDGE) { if ( edge->v1_type == VERTEX_1 ) my_tri->cubitedge1index = INTERSECTION_EDGE; else if ( edge->v1_type == VERTEX_0 ) my_tri->cubitedge2index = INTERSECTION_EDGE; } } break; case EDGE_0: if ( (edge->v1_type == VERTEX_0) || (edge->v1_type == VERTEX_1) ) { type = BDRY_EDGE; if ( edge->edge_type == INTERSECTION_EDGE) my_tri->cubitedge0index = INTERSECTION_EDGE; } break; case EDGE_1: if ( (edge->v1_type == VERTEX_1) || (edge->v1_type == VERTEX_2) ) { type = BDRY_EDGE; if ( edge->edge_type == INTERSECTION_EDGE) my_tri->cubitedge1index = INTERSECTION_EDGE; } break; case EDGE_2: if ( (edge->v1_type == VERTEX_2) || (edge->v1_type == VERTEX_0) ) { type = BDRY_EDGE; if ( edge->edge_type == INTERSECTION_EDGE) my_tri->cubitedge2index = INTERSECTION_EDGE; } break; } if ( type == BDRY_EDGE ) edge->edge_type = BDRY_EDGE; } } // else edge->edge_type = INTERIOR_EDGE; dpe++; } }
bool FBRetriangulate::get_a_chain | ( | std::vector< int > * | chainlist | ) | [private] |
Definition at line 645 of file FBRetriangulate.cpp.
{ bool status; int vthis, vprev, vstart; int direction; FB_Edge *edge; std::vector<FB_Edge*>::iterator dpe; status = false; dpe = my_tri->edge_list.begin(); // to keep compiler from warning that edge might be used uninitialized edge = 0; while ( dpe != my_tri->edge_list.end() ) { edge = *dpe; dpe++; // Skip edges that are not interior edges. // if ( edge->v0_type == edge->v1_type ) continue; if ( edge->edge_type == BDRY_EDGE ) continue; if ( edge->num_times < 2 ) { if ( (edge->edge_type == BDRY_EDGE) && (edge->num_times == 1) ) continue; status = true; edge->num_times++; break; } } if ( status == true ) { if ( edge->num_times == 1 ) { vthis = edge->v1; vprev = edge->v0; direction = 1; } else { vthis = edge->v0; vprev = edge->v1; direction = 1; } vstart = vprev; chainlist->push_back(vthis); while ( vthis != vstart ) { get_next_vert_in_chain(vthis,vprev,direction); chainlist->push_back(vthis); } } if ( status == false ) { // There were no interior edges. // So just go around the perimeter. dpe = my_tri->edge_list.begin(); edge = *dpe; if ( edge->num_times != 0 ) { status = false; return status; } edge->num_times = 1; vthis = edge->v0; vprev = edge->v1; direction = 1; vstart = vprev; chainlist->push_back(vthis); while ( vthis != vstart ) { get_next_vert_in_chain(vthis,vprev,direction); chainlist->push_back(vthis); } status = true; } return status; }
double FBRetriangulate::get_dist | ( | double | x0, |
double | y0, | ||
double | z0, | ||
double | x1, | ||
double | y1, | ||
double | z1 | ||
) | [inline, private] |
Definition at line 62 of file FBRetriangulate.hpp.
{
return sqrt( (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0) + (z1-z0)*(z1-z0) );
};
void FBRetriangulate::get_edge_indices | ( | int | v0, |
int | v1, | ||
int | v2, | ||
int | parent, | ||
int & | e0index, | ||
int & | e1index, | ||
int & | e2index | ||
) | [private] |
Definition at line 916 of file FBRetriangulate.cpp.
{ std::vector<FB_Edge*>::iterator itt; std::vector<FB_Triangle*>::iterator itp; FB_Edge *edge; int e_v0, e_v1, e_type, e_v0type, e_v1type; itp = tris->begin(); itp += parent; itt = (*itp)->edge_list.begin(); while ( itt != (*itp)->edge_list.end() ) { edge = *itt; e_v0 = edge->v0; e_v1 = edge->v1; e_v0type = edge->v0_type; e_v1type = edge->v1_type; e_type = edge->edge_type; if ( ( (e_v0 == v0) && (e_v1 == v1) ) || ( (e_v0 == v1) && (e_v1 == v0) ) ) { if ( e_type == INTERSECTION_EDGE ) e0index = INTERSECTION_EDGE; else if ( e_type == INTERIOR_EDGE ) e0index = 0; else if ( (e_v0type == EDGE_0) || (e_v1type == EDGE_0) ) e0index = (*itp)->cubitedge0index; else if ( (e_v0type == EDGE_1) || (e_v1type == EDGE_1) ) e0index = (*itp)->cubitedge1index; else if ( (e_v0type == EDGE_2) || (e_v1type == EDGE_2) ) e0index = (*itp)->cubitedge2index; else if ( ( (e_v0type == VERTEX_0) || (e_v0type == VERTEX_1) ) & ( (e_v1type == VERTEX_0) || (e_v1type == VERTEX_1) ) ) e0index = (*itp)->cubitedge0index; else if ( ( (e_v0type == VERTEX_1) || (e_v0type == VERTEX_2) ) & ( (e_v1type == VERTEX_1) || (e_v1type == VERTEX_2) ) ) e1index = (*itp)->cubitedge1index; else if ( ( (e_v0type == VERTEX_2) || (e_v0type == VERTEX_0) ) & ( (e_v1type == VERTEX_2) || (e_v1type == VERTEX_0) ) ) e2index = (*itp)->cubitedge2index; } else if ( ( (e_v0 == v1) && (e_v1 == v2) ) || ( (e_v0 == v2) && (e_v1 == v1) ) ) { if ( e_type == INTERSECTION_EDGE ) e1index = INTERSECTION_EDGE; else if ( e_type == INTERIOR_EDGE ) e1index = 0; else if ( (e_v0type == EDGE_0) || (e_v1type == EDGE_0) ) e1index = (*itp)->cubitedge0index; else if ( (e_v0type == EDGE_1) || (e_v1type == EDGE_1) ) e1index = (*itp)->cubitedge1index; else if ( (e_v0type == EDGE_2) || (e_v1type == EDGE_2) ) e1index = (*itp)->cubitedge2index; else if ( ( (e_v0type == VERTEX_0) || (e_v0type == VERTEX_1) ) & ( (e_v1type == VERTEX_0) || (e_v1type == VERTEX_1) ) ) e0index = (*itp)->cubitedge0index; else if ( ( (e_v0type == VERTEX_1) || (e_v0type == VERTEX_2) ) & ( (e_v1type == VERTEX_1) || (e_v1type == VERTEX_2) ) ) e1index = (*itp)->cubitedge1index; else if ( ( (e_v0type == VERTEX_2) || (e_v0type == VERTEX_0) ) & ( (e_v1type == VERTEX_2) || (e_v1type == VERTEX_0) ) ) e2index = (*itp)->cubitedge2index; } else if ( ( (e_v0 == v2) && (e_v1 == v0) ) || ( (e_v0 == v0) && (e_v1 == v2) ) ) { if ( e_type == INTERSECTION_EDGE ) e2index = INTERSECTION_EDGE; else if ( e_type == INTERIOR_EDGE ) e2index = 0; else if ( (e_v0type == EDGE_0) || (e_v1type == EDGE_0) ) e2index = (*itp)->cubitedge0index; else if ( (e_v0type == EDGE_1) || (e_v1type == EDGE_1) ) e2index = (*itp)->cubitedge1index; else if ( (e_v0type == EDGE_2) || (e_v1type == EDGE_2) ) e2index = (*itp)->cubitedge2index; else if ( ( (e_v0type == VERTEX_0) || (e_v0type == VERTEX_1) ) & ( (e_v1type == VERTEX_0) || (e_v1type == VERTEX_1) ) ) e0index = (*itp)->cubitedge0index; else if ( ( (e_v0type == VERTEX_1) || (e_v0type == VERTEX_2) ) & ( (e_v1type == VERTEX_1) || (e_v1type == VERTEX_2) ) ) e1index = (*itp)->cubitedge1index; else if ( ( (e_v0type == VERTEX_2) || (e_v0type == VERTEX_0) ) & ( (e_v1type == VERTEX_2) || (e_v1type == VERTEX_0) ) ) e2index = (*itp)->cubitedge2index; } itt++; } }
void FBRetriangulate::get_next_vert_in_chain | ( | int & | vthis, |
int & | vprev, | ||
int | direction | ||
) | [private] |
Definition at line 716 of file FBRetriangulate.cpp.
{ unsigned int i; FB_Edge *edge; std::vector<FB_Edge*>::iterator dpe, dpebegin, dpeend; for ( i = 0; i < vertstufflist.size(); i++ ) { if ( vertstufflist[i]->v0 == (int)vthis ) break; } dpe = dpebegin = vertstufflist[i]->edge_list.begin(); dpeend = vertstufflist[i]->edge_list.end(); while ( dpe != dpeend ) { edge = *dpe; if ( (edge->v0 == vprev) || (edge->v1 == vprev) ) break; dpe++; } if ( direction == 1 ) { if ( dpe == dpebegin ) dpe = vertstufflist[i]->edge_list.end(); dpe--; } else { dpe++; if ( dpe == dpeend ) dpe = dpebegin; } edge = *dpe; vprev = vthis; if ( vthis == edge->v1 ) { // Swap the edge verts. We do this so that next time we see this // edge we will know that it was oriented to point in the direction // of the previous loop. Thus we will know to proceed in the // opposite direction next time. // (see edge->num_times test in get_a_chain().) unsigned int vtemp; vtemp = edge->v0; edge->v0 = edge->v1; edge->v1 = vtemp; vtemp = edge->v0_type; edge->v0_type = edge->v1_type; edge->v1_type = vtemp; } vthis = edge->v1; edge->num_times++; }
void FBRetriangulate::make_vert_list | ( | ) | [private] |
Definition at line 442 of file FBRetriangulate.cpp.
{ unsigned int i; int v0, v1; FB_Edge *edge; VertexStuff *vstuff; std::vector<FB_Edge*>::iterator dpe; bool foundv0, foundv1; dpe = my_tri->edge_list.begin(); while ( dpe != my_tri->edge_list.end() ) { edge = *dpe; dpe++; v0 = edge->v0; v1 = edge->v1; foundv0 = foundv1 = false; for ( i = 0; i < vertstufflist.size(); i++ ) { if ( vertstufflist[i]->v0 == v0 ) { vertstufflist[i]->edge_list.push_back(edge); foundv0 = true; } if ( vertstufflist[i]->v0 == v1 ) { vertstufflist[i]->edge_list.push_back(edge); foundv1 = true; } } if ( foundv0 == false ) { vstuff = new VertexStuff(v0, edge->v0_type,verts[v0]->coord[p_dir], verts[v0]->coord[s_dir]); vstuff->edge_list.push_back(edge); vertstufflist.push_back(vstuff); } if ( foundv1 == false ) { vstuff = new VertexStuff(v1, edge->v1_type,verts[v1]->coord[p_dir], verts[v1]->coord[s_dir]); vstuff->edge_list.push_back(edge); vertstufflist.push_back(vstuff); } } std::vector<VertexStuff* >::iterator vitbegin, vitend; vitbegin = vertstufflist.begin(); vitend = vertstufflist.end(); std::sort(vitbegin,vitend,vertstuffcompfn_less()); }
CubitStatus FBRetriangulate::remove_min_max | ( | ) | [private] |
Definition at line 225 of file FBRetriangulate.cpp.
{ CubitStatus status; FB_Edge *edge; std::vector<FB_Edge*>::iterator dpe; bool goes_down, goes_up; VertexStuff *vstuff; unsigned int i; int this_vert, that_vert; double this_vert_p_dir_coord, that_vert_p_dir_coord; status = CUBIT_SUCCESS; for ( i = 0; i < vertstufflist.size(); i++ ) { vstuff = vertstufflist[i]; if ( vstuff->v0type != INTERIOR_VERT ) continue; goes_down = goes_up = false; this_vert = vstuff->v0; this_vert_p_dir_coord = verts[this_vert]->coord[p_dir]; dpe = vstuff->edge_list.begin(); while ( dpe != vstuff->edge_list.end() ) { edge = *dpe; dpe++; if ( edge->v0 == this_vert ) that_vert = edge->v1; else that_vert = edge->v0; that_vert_p_dir_coord = verts[that_vert]->coord[p_dir]; if ( that_vert_p_dir_coord < this_vert_p_dir_coord ) goes_down = true; else if ( that_vert_p_dir_coord > this_vert_p_dir_coord ) goes_up = true; else { double this_vert_s_dir_coord, that_vert_s_dir_coord; this_vert_s_dir_coord = verts[this_vert]->coord[s_dir]; that_vert_s_dir_coord = verts[that_vert]->coord[s_dir]; if ( this_vert_s_dir_coord < that_vert_s_dir_coord ) goes_up = true; else goes_down = true; } } if ( goes_down == false ) { add_edge_down(this_vert,i); } else if ( goes_up == false ) { add_edge_up(this_vert,i); } } return status; }
CubitStatus FBRetriangulate::retriangulate_this_tri | ( | int | sequence, |
std::vector< FB_Edge * > & | orphaned_edges | ||
) |
Definition at line 75 of file FBRetriangulate.cpp.
{ CubitStatus status; double xspan, yspan, zspan; std::vector<FB_Triangle *>::iterator itt; itt = tris->begin(); itt += sequence; my_tri = *itt; status = CUBIT_SUCCESS; // tri = &itt; xspan = my_tri->boundingbox.xmax - my_tri->boundingbox.xmin; yspan = my_tri->boundingbox.ymax - my_tri->boundingbox.ymin; zspan = my_tri->boundingbox.zmax - my_tri->boundingbox.zmin; if ( ( fabs(my_tri->c) >= fabs(my_tri->a) ) && ( fabs(my_tri->c) >= fabs(my_tri->b) ) ) { p_dir = 1; s_dir = 0; if ( xspan > yspan ) { p_dir = 0; s_dir = 1; } } else if ( fabs(my_tri->b) >= fabs(my_tri->a) ) { p_dir = 2; s_dir = 0; if ( xspan > zspan ) { p_dir = 0; s_dir = 2; } } else { p_dir = 1; s_dir = 2; if ( zspan > yspan ) { p_dir = 2; s_dir = 1; } } if ( p_dir == 0 ) { if ( s_dir == 1 ) { if ( my_tri->c > 0.0 ) winding = CCW; else winding = CW; } else if (s_dir == 2 ) { if ( my_tri->b > 0.0 ) winding = CW; else winding = CCW; } } else if ( p_dir == 1 ) { if ( s_dir == 0 ) { if ( my_tri->c > 0.0 ) winding = CW; else winding = CCW; } else if (s_dir == 2 ) { if ( my_tri->a > 0.0 ) winding = CW; else winding = CCW; } } else if ( p_dir == 2 ) { if ( s_dir == 0 ) { if ( my_tri->b > 0.0 ) winding = CCW; else winding = CW; } else if (s_dir == 1 ) { if ( my_tri->a > 0.0 ) winding = CCW; else winding = CW; } } else{ PRINT_ERROR("Unexpected result.\n"); return CUBIT_FAILURE; } //if ( winding == CCW ) winding = CW; //else winding = CCW; classify_edges(); // Add edges around the perimeter of the triangle to its edge list. status = add_bdry_edges(orphaned_edges); make_vert_list(); // Add internal edges where there is a local min or max status = remove_min_max(); // Get the vertex chains that will be retriangulated. bool chain_status = true; sort_vertstufflist_edges(); std::vector<int> *chainlist = new std::vector<int>; // std::vector<FB_Triangle* > new_tris; unsigned int i, nfsize; nfsize = newfacets->size(); while (chain_status == true ) { chain_status = get_a_chain(chainlist); if ( chain_status == false ) break; FBTiler *tiler = new FBTiler(verts,p_dir,s_dir,sequence, my_tri->a,my_tri->b,my_tri->c,newfacets); status = tiler->Tile_Poly(chainlist); delete tiler; chainlist->clear(); } delete chainlist; unsigned int number_new; int e0index, e1index, e2index; number_new = newfacets->size() - nfsize; if ( number_new > 0 ) { std::vector<int>::iterator itp; itp = newfacets->begin(); itp += nfsize; for ( i = 0; i < number_new; i += 3 ) { FB_Triangle *new_tri; e0index = e1index = e2index = 0; get_edge_indices(*itp,*(itp+1),*(itp+2),sequence, e0index, e1index, e2index); new_tri = new FB_Triangle(*itp,*(itp+1),*(itp+2), sequence,my_tri->cubitsurfaceindex, e0index, e1index, e2index); tris->push_back(new_tri); itp += 3; } if ( newfacetsindex ) newfacetsindex->push_back(nfsize); } for ( i = 0; i < vertstufflist.size(); i++ ) { delete vertstufflist[i]; } vertstufflist.clear(); return status; }
void FBRetriangulate::sort_vertstufflist_edges | ( | ) | [private] |
Definition at line 764 of file FBRetriangulate.cpp.
{ // For each vertex that has more than 2 edges, sort the edges in CCW order. unsigned int i; FB_Edge *edge; std::vector<FB_Edge*>::iterator dpe, dpebegin, dpeend; double x0, y0, x1, y1, slope; int v0; unsigned int quadrant; quadrant = 0; // Initialize so compiler won't warn. for ( i = 0; i < vertstufflist.size(); i++ ) { if ( vertstufflist[i]->edge_list.size() > 2 ) { v0 = vertstufflist[i]->v0; x0 = verts[v0]->coord[p_dir]; y0 = verts[v0]->coord[s_dir]; dpe = vertstufflist[i]->edge_list.begin(); while ( dpe != vertstufflist[i]->edge_list.end() ) { edge = *dpe; dpe++; if ( edge->v0 == v0 ) { x1 = verts[edge->v1]->coord[p_dir]; y1 = verts[edge->v1]->coord[s_dir]; } else { x1 = verts[edge->v0]->coord[p_dir]; y1 = verts[edge->v0]->coord[s_dir]; } if ( fabs(x1-x0) < EPSILON ) { if ( y1 > y0 ) { slope = CUBIT_DBL_MAX; quadrant = 1; } else { slope = -CUBIT_DBL_MAX; quadrant = 4; } } else { slope = (y1-y0)/(x1-x0); if ( (x1 >= x0) && (y1 >= y0) ) quadrant = 1; else if ( (x1 < x0) && (y1 > y0) ) quadrant = 2; else if ( (x1 <= x0) && (y1 <= y0) ) quadrant = 3; else if ( (x1 > x0) && (y1 < y0) ) quadrant = 4; } edge->slope = slope; edge->quadrant = quadrant; } // Now sort the edge list by the value of quadrant or slope. // vertstufflist[i]->edge_list.sort(edgecompfn_less()); // vertstufflist[i]->edge_list.sort(edgecf_less); dpebegin = vertstufflist[i]->edge_list.begin(); dpeend = vertstufflist[i]->edge_list.end(); // if ( winding == CW ) std::sort(dpebegin,dpeend,edgecompfn_less()); // else // std::sort(dpebegin,dpeend,edgecompfn_more()); } dpe = vertstufflist[i]->edge_list.begin(); while ( dpe != vertstufflist[i]->edge_list.end() ) { edge = *dpe; dpe++; } } }
bool FBRetriangulate::test_for_crossing | ( | int | v0, |
int | v1, | ||
int | v2, | ||
int | v3 | ||
) | [private] |
Definition at line 593 of file FBRetriangulate.cpp.
{ double x0, y0, x1, y1, x2, y2, x3, y3, dxa, dya, dxb, dyb, p01x, p01y; double product, dasq, dbsq, prodsq; double s, t; x0 = verts[v0]->coord[p_dir]; y0 = verts[v0]->coord[s_dir]; x1 = verts[v1]->coord[p_dir]; y1 = verts[v1]->coord[s_dir]; x2 = verts[v2]->coord[p_dir]; y2 = verts[v2]->coord[s_dir]; x3 = verts[v3]->coord[p_dir]; y3 = verts[v3]->coord[s_dir]; dxa = x1 - x0; dya = y1 - y0; dxb = x3 - x2; dyb = y3 - y2; product = dxa*dyb - dya*dxb; dasq = dxa*dxa + dya*dya; dbsq = dxb*dxb + dyb*dyb; prodsq = product*product; if ( prodsq > EPSILON2*dasq*dbsq ) { p01x = x2 - x0; p01y = y2 - y0; s = (p01x*dyb - p01y*dxb)/product; if ( (s < 0.0) || (s > 1.0) ) return false; t = (p01x*dya - p01y*dxa)/product; if ( (t < 0.0) || (t > 1.0) ) return false; } return true; }
FB_Triangle* FBRetriangulate::my_tri [private] |
Definition at line 58 of file FBRetriangulate.hpp.
std::vector<int>* FBRetriangulate::newfacets [private] |
Definition at line 53 of file FBRetriangulate.hpp.
std::vector<int>* FBRetriangulate::newfacetsindex [private] |
Definition at line 54 of file FBRetriangulate.hpp.
int FBRetriangulate::p_dir [private] |
Definition at line 55 of file FBRetriangulate.hpp.
int FBRetriangulate::s_dir [private] |
Definition at line 55 of file FBRetriangulate.hpp.
std::vector<FB_Triangle *>* FBRetriangulate::tris [private] |
Definition at line 52 of file FBRetriangulate.hpp.
std::vector<FB_Coord *> FBRetriangulate::verts [private] |
Definition at line 51 of file FBRetriangulate.hpp.
std::vector<VertexStuff* > FBRetriangulate::vertstufflist [private] |
Definition at line 59 of file FBRetriangulate.hpp.
WindingType FBRetriangulate::winding [private] |
Definition at line 57 of file FBRetriangulate.hpp.