|
cgma
|
#include <FBTiler.hpp>
Public Member Functions | |
| FBTiler (std::vector< FB_Coord * > &my_verts, int pd, int sd, int sequence, double a, double b, double c, std::vector< int > *tri_list) | |
| ~FBTiler () | |
| CubitStatus | Tile_Poly (std::vector< int > *coordlist) |
Private Member Functions | |
| int | add_triangle (int v1, int v2, int v3) |
| bool | reflex_angle (int v0, int v1, int v2, std::vector< int > *coordlist) |
| CubitStatus | retriangulate (std::vector< int > *coordlist) |
| void | dud_from_coord_list (int val, std::vector< int > *ivec) |
| void | decrement_list_ptr (std::vector< int >::iterator &it, std::vector< int >::iterator itbegin, std::vector< int >::iterator itend) |
| void | increment_list_ptr (std::vector< int >::iterator &it, std::vector< int >::iterator itbegin, std::vector< int >::iterator itend) |
| int | get_adjacency (int top, int thisone) |
Private Attributes | |
| int | p_dir |
| int | s_dir |
| int | parent |
| double | xnorm |
| double | ynorm |
| double | znorm |
| std::vector< FB_Coord * > | verts |
| std::vector< int > * | my_tri_list |
| std::vector< FBTilerChainVert * > | sortedchainlist |
Definition at line 47 of file FBTiler.hpp.
| FBTiler::FBTiler | ( | std::vector< FB_Coord * > & | my_verts, |
| int | pd, | ||
| int | sd, | ||
| int | sequence, | ||
| double | a, | ||
| double | b, | ||
| double | c, | ||
| std::vector< int > * | tri_list | ||
| ) |
Definition at line 33 of file FBTiler.cpp.
Definition at line 48 of file FBTiler.cpp.
{
}
| int FBTiler::add_triangle | ( | int | v1, |
| int | v2, | ||
| int | v3 | ||
| ) | [private] |
Definition at line 190 of file FBTiler.cpp.
{
int status;
status = 1;
// See if the winding is OK by comparing the normal to the parent's normal.
double xn, yn, zn;
double x1, y1, z1, x2, y2, z2, x3, y3, z3;
double ux, uy, uz, vx, vy, vz, product;
x1 = verts[v1]->coord[0]; y1 = verts[v1]->coord[1]; z1 = verts[v1]->coord[2];
x2 = verts[v2]->coord[0]; y2 = verts[v2]->coord[1]; z2 = verts[v2]->coord[2];
x3 = verts[v3]->coord[0]; y3 = verts[v3]->coord[1]; z3 = verts[v3]->coord[2];
ux = x2 - x1; uy = y2 - y1; uz = z2 - z1;
vx = x3 - x1; vy = y3 - y1; vz = z3 - z1;
xn = uy*vz - uz*vy; yn = uz*vx - ux*vz; zn = ux*vy - uy*vx;
product = xnorm*xn + ynorm*yn + znorm*zn;
if ( product < 0.0 ) { // Must reverse the connections.
int itemp;
itemp = v1; v1 = v2; v2 = itemp;
}
my_tri_list->push_back(v1);
my_tri_list->push_back(v2);
my_tri_list->push_back(v3);
return status;
}
| void FBTiler::decrement_list_ptr | ( | std::vector< int >::iterator & | it, |
| std::vector< int >::iterator | itbegin, | ||
| std::vector< int >::iterator | itend | ||
| ) | [inline, private] |
Definition at line 71 of file FBTiler.hpp.
{
if ( it == itbegin ) it = itend-1;
else it--;
}
| void FBTiler::dud_from_coord_list | ( | int | val, |
| std::vector< int > * | ivec | ||
| ) | [private] |
Definition at line 220 of file FBTiler.cpp.
{
std::vector<int>::iterator itv;
bool ifoundit;
// Also decrements ivec->size() if val was found.
ifoundit = false;
itv = ivec->begin();
do {
if ( ifoundit == false ) {
if ( *itv == val ) {
ifoundit = true;
break;
}
}
itv++;
} while ( itv != ivec->end() );
if ( ifoundit == true ) {
ivec->erase(itv);
}
}
| int FBTiler::get_adjacency | ( | int | top, |
| int | thisone | ||
| ) | [inline, private] |
Definition at line 87 of file FBTiler.hpp.
{
// This code works because LEFT is defined as 1, RIGHT as 2, and BOTH as 3.
// Thus LEFT&LEFT = RIGHT&RIGHT = LEFT&BOTH = RIGHT&BOTH = 1;
// LEFT&RIGHT = 0.
if ( top & thisone ) return 2;
return 1;
}
| void FBTiler::increment_list_ptr | ( | std::vector< int >::iterator & | it, |
| std::vector< int >::iterator | itbegin, | ||
| std::vector< int >::iterator | itend | ||
| ) | [inline, private] |
Definition at line 79 of file FBTiler.hpp.
{
it++;
if ( it == itend ) it = itbegin;
}
| bool FBTiler::reflex_angle | ( | int | v0, |
| int | v1, | ||
| int | v2, | ||
| std::vector< int > * | coordlist | ||
| ) | [private] |
Definition at line 243 of file FBTiler.cpp.
{
double v0x, v0y, v1x, v1y, v2x, v2y, xbary, ybary;
v0x = verts[v0]->coord[s_dir];
v0y = verts[v0]->coord[p_dir];
v1x = verts[v1]->coord[s_dir];
v1y = verts[v1]->coord[p_dir];
v2x = verts[v2]->coord[s_dir];
v2y = verts[v2]->coord[p_dir];
// Are the three points colinear?
if ( fabs((v1x-v0x)*(v2y-v0y) - (v2x-v0x)*(v1y-v0y)) < EPSILON2 )
return true;
// Get coordinates of barycenter of the triangle formed by
// v0, v1, and v2
xbary = (v0x + v1x + v2x)/3.;
ybary = (v0y + v1y + v2y)/3.;
// Do a point-in-polygon test on this point and the polygon formed
// by the chain. If point is in polygon, angle is not reflex;
// otherwise, angle is reflex. Point in polygon algorithm from
// Schneider and Eberly, Geometric Tools for COmputer Graphics,
// Sec. 13.3.
bool inside = false;
std::vector<int>::iterator itv;
int u0, u1;
itv = coordlist->begin();
while ( itv != coordlist->end() ) {
u0 = *itv++;
if ( itv == coordlist->end() )
u1 = *(coordlist->begin());
else
u1 = *itv;
if ( ybary < verts[u1]->coord[p_dir] ) {
// u1 is above the hroizontal ray in s_dir from the barycenter.
if ( verts[u0]->coord[p_dir] <= ybary ) {
// u0 is on or below the ray.
if ( ( (ybary - verts[u0]->coord[p_dir])*
(verts[u1]->coord[s_dir] -verts[ u0]->coord[s_dir]) ) >
( (xbary - verts[u0]->coord[s_dir])*
(verts[u1]->coord[p_dir] - verts[u0]->coord[p_dir]) ) )
inside = !inside;
}
} else if ( ybary < verts[u0]->coord[p_dir] ) {
// U1 is on or below the ray; u0 is above the ray.
if ( ( (ybary - verts[u0]->coord[p_dir])*
(verts[u1]->coord[s_dir] - verts[u0]->coord[s_dir]) ) <
( (xbary - verts[u0]->coord[s_dir])*
(verts[u1]->coord[p_dir] - verts[u0]->coord[p_dir]) ) )
inside = !inside;
}
}
return !inside;
}
| CubitStatus FBTiler::retriangulate | ( | std::vector< int > * | coordlist | ) | [private] |
Definition at line 305 of file FBTiler.cpp.
{
int stacktopadjacency, this_adjacency, adjacency_case;
std::vector<FBTilerChainVert*> vstack;
std::vector<FBTilerChainVert*>::iterator itv, itvlast;
int v0, v1, v2;
unsigned int i, numtris, totaltris;
// Put the first two verts on vstack.
itv = sortedchainlist.begin();
vstack.push_back(*itv++);
vstack.push_back(*itv);
stacktopadjacency = (*itv)->whichchain;
itvlast = itv;
numtris = 0;
totaltris = sortedchainlist.size() - 2;
while(1) {
if ( numtris == totaltris ) break;
*itv++;
if ( itv == sortedchainlist.end() ) {
PRINT_ERROR("Tiler error in FacetBoolean: premature end of list.\n");
return CUBIT_FAILURE;
}
this_adjacency = (*itv)->whichchain;
v0 = (*itv)->v0;
adjacency_case = get_adjacency(stacktopadjacency,this_adjacency);
switch ( adjacency_case ) {
case 1:
{
v1 = vstack[0]->v0;
for ( i = 1; i < vstack.size(); i++ ) {
v2 = vstack[i]->v0;
add_triangle(v0,v1,v2);
dud_from_coord_list(v1,coordlist);
numtris += 1;
v1 = v2;
}
vstack.clear();
vstack.push_back(*itvlast);
vstack.push_back(*itv);
stacktopadjacency = (*itv)->whichchain;
itvlast = itv;
break;
}
case 2:
{
while ( vstack.size() > 1 ) {
int size = vstack.size() - 1;
v1 = vstack[size]->v0;
// int v1chain = vstack[size]->whichchain;
v2 = vstack[size-1]->v0;
// bool isreflex = reflex_angle(v0,v1,v2,v1chain);
bool isreflex = reflex_angle(v0,v1,v2,coordlist);
if ( isreflex == true ) break;
add_triangle(v0,v1,v2);
dud_from_coord_list(v1,coordlist);
numtris += 1;
vstack.pop_back();
}
vstack.push_back(*itv);
stacktopadjacency = (*itv)->whichchain;
itvlast = itv;
break;
}
}
} // endwhile
return CUBIT_SUCCESS;
}
| CubitStatus FBTiler::Tile_Poly | ( | std::vector< int > * | coordlist | ) |
Definition at line 53 of file FBTiler.cpp.
{
int v0, v1, v2, v3;
std::vector<int>::iterator it, itmin, itmax;
double min_p, min_s, max_p, max_s, test_p, test_s;
CubitStatus status;
status = CUBIT_SUCCESS;
it = coordlist->begin();
if ( coordlist->size() == 3 ) {
v1 = *it++; v2 = *it++; v3 = *it++;
add_triangle(v1, v2, v3);
return status;
}
// Get location in list of min and max coord in p_dir.
min_p = min_s = CUBIT_DBL_MAX;
max_p = max_s = -CUBIT_DBL_MAX;
while ( it != coordlist->end() ) {
v0 = *it;
test_p = verts[v0]->coord[p_dir];
test_s = verts[v0]->coord[s_dir];
// if ( test_p < min_p ) {
if ( (test_p - min_p) <= -EPSILON ) {
itmin = it;
min_p = test_p;
if ( test_s < min_s )
min_s = test_s;
}
// if ( test_p > max_p ) {
if ( (test_p - max_p) >= EPSILON ) {
itmax = it;
max_p = test_p;
if ( test_s > max_s )
max_s = test_s;
}
if ( fabs(test_p - min_p) < EPSILON ) {
if ( test_s < min_s ) {
itmin = it;
min_s = test_s;
}
}
if ( fabs(test_p - max_p) < EPSILON ) {
if ( test_s > max_s ) {
itmax = it;
max_s = test_s;
}
}
it++;
}
// Now we've got to start at the min coord and make a single sorted list
// of the coords, from min to max, noting whether the coord is on the
// LEFT or RIGHT chain, or -- for the top and bottom coords -- on BOTH chains.
sortedchainlist.clear();
std::vector<int>::iterator itleft, itright, itlistbegin, itlistend;
it = itleft = itright = itmin;
itlistbegin = coordlist->begin();
itlistend = coordlist->end();
decrement_list_ptr(itleft,itlistbegin,itlistend);
increment_list_ptr(itright,itlistbegin,itlistend);
v0 = *itmin;
int v0left, v0right;
double leftpdircoord, rightpdircoord;
FBTilerChainVert *cvert;
cvert = new FBTilerChainVert(v0,BOTH);
sortedchainlist.push_back(cvert);
v0left = *itleft; v0right = *itright;
leftpdircoord = verts[v0left]->coord[p_dir];
rightpdircoord = verts[v0right]->coord[p_dir];
while(1) {
while ( (leftpdircoord - rightpdircoord) > -EPSILON2 ) {
if ( itright == itmax ) break;
v0 = v0right;
cvert = new FBTilerChainVert(v0,LEFT);
sortedchainlist.push_back(cvert);
increment_list_ptr(itright,itlistbegin,itlistend);
v0right = *itright;
rightpdircoord = verts[v0right]->coord[p_dir];
}
while ( (rightpdircoord - leftpdircoord) > -EPSILON2 ) {
if ( itleft == itmax ) break;
v0 = v0left;
cvert = new FBTilerChainVert(v0,RIGHT);
sortedchainlist.push_back(cvert);
decrement_list_ptr(itleft,itlistbegin,itlistend);
v0left = *itleft;
leftpdircoord = verts[v0left]->coord[p_dir];
}
if ( (itright == itmax) || (itleft == itmax) ) break;
}
// In case we have some horizontal edges (wrt p_dir) left on the list,
// the next two while statements will get them.
while ( itright != itmax ) {
v0 = v0right;
cvert = new FBTilerChainVert(v0,LEFT);
sortedchainlist.push_back(cvert);
increment_list_ptr(itright,itlistbegin,itlistend);
v0right = *itright;
}
while ( itleft != itmax ) {
v0 = v0left;
cvert = new FBTilerChainVert(v0,RIGHT);
sortedchainlist.push_back(cvert);
decrement_list_ptr(itleft,itlistbegin,itlistend);
v0left = *itleft;
}
// Put the top coord on the list.
v0 = *itmax;
cvert = new FBTilerChainVert(v0,BOTH);
sortedchainlist.push_back(cvert);
status = retriangulate(coordlist);
std::vector<FBTilerChainVert*>::iterator itv, itvlast;
itvlast = sortedchainlist.end();
itv = sortedchainlist.begin();
while ( itv != itvlast ) {
delete *itv;
itv++;
}
sortedchainlist.clear();
return status;
}
std::vector<int>* FBTiler::my_tri_list [private] |
Definition at line 64 of file FBTiler.hpp.
int FBTiler::p_dir [private] |
Definition at line 59 of file FBTiler.hpp.
int FBTiler::parent [private] |
Definition at line 61 of file FBTiler.hpp.
int FBTiler::s_dir [private] |
Definition at line 60 of file FBTiler.hpp.
std::vector<FBTilerChainVert*> FBTiler::sortedchainlist [private] |
Definition at line 68 of file FBTiler.hpp.
std::vector<FB_Coord *> FBTiler::verts [private] |
Definition at line 63 of file FBTiler.hpp.
double FBTiler::xnorm [private] |
Definition at line 62 of file FBTiler.hpp.
double FBTiler::ynorm [private] |
Definition at line 62 of file FBTiler.hpp.
double FBTiler::znorm [private] |
Definition at line 62 of file FBTiler.hpp.