1
0
Fork 0

Handle another possible case of degenerate output from our polygon clipping

code.
This commit is contained in:
curt 2005-10-31 18:53:13 +00:00
parent b78684b6dd
commit 507e78357b

View file

@ -502,13 +502,13 @@ static void contour_tesselate( TGContourNode *node, const TGPolygon &p,
// list of points // list of points
int contour_num = node->get_contour_num(); int contour_num = node->get_contour_num();
//cout << "Tesselating contour = " << contour_num << endl; // cout << "Tesselating contour = " << contour_num << endl;
point_list contour = p.get_contour( contour_num ); point_list contour = p.get_contour( contour_num );
double max_x = contour[0].x(); double max_x = contour[0].x();
int total_pts = contour.size(); int total_pts = contour.size();
//cout << "contour = " << contour_num << " nodes = " << total_pts << endl; // cout << "contour = " << contour_num << " nodes = " << total_pts << endl;
#if 0 #if 0
// testing ... don't enable this if not testing // testing ... don't enable this if not testing
@ -526,6 +526,7 @@ static void contour_tesselate( TGContourNode *node, const TGPolygon &p,
} }
in.numberofpoints = total_pts; in.numberofpoints = total_pts;
// cout << "total points = " << total_pts << endl;
in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL)); in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL));
counter = 0; counter = 0;
@ -757,9 +758,11 @@ static Point3D point_inside_contour( TGContourNode *node, const TGPolygon &p ) {
hole_pts.clear(); hole_pts.clear();
// build list of hole points // build list of hole points
// cout << "contour has " << node->get_num_kids() << " kids" << endl;
for ( i = 0; i < node->get_num_kids(); ++i ) { for ( i = 0; i < node->get_num_kids(); ++i ) {
if ( node->get_kid( i ) != NULL ) { if ( node->get_kid( i ) != NULL ) {
contour_num = node->get_kid(i)->get_contour_num(); contour_num = node->get_kid(i)->get_contour_num();
// cout << " child = " << contour_num << endl;
hole_pts.push_back( p.get_point_inside( contour_num ) ); hole_pts.push_back( p.get_point_inside( contour_num ) );
point_list contour = p.get_contour( contour_num ); point_list contour = p.get_contour( contour_num );
hole_polys.add_contour( contour, 1 ); hole_polys.add_contour( contour, 1 );
@ -768,12 +771,14 @@ static Point3D point_inside_contour( TGContourNode *node, const TGPolygon &p ) {
triele_list elelist; triele_list elelist;
point_list out_pts; point_list out_pts;
// cout << "before contour tesselate" << endl;
contour_tesselate( node, p, hole_polys, hole_pts, elelist, out_pts ); contour_tesselate( node, p, hole_polys, hole_pts, elelist, out_pts );
if ( elelist.size() <= 0 ) { if ( elelist.size() <= 0 ) {
cout << "Error polygon triangulated to zero triangles!" << endl; cout << "Error polygon triangulated to zero triangles!" << endl;
return Point3D( -200, -200, 0 ); return Point3D( -200, -200, 0 );
// exit(-1); // exit(-1);
} }
// cout << "after contour tesselate" << endl;
// find the largest triangle in the group // find the largest triangle in the group
double max_area = 0.0; double max_area = 0.0;
@ -810,16 +815,19 @@ static Point3D point_inside_contour( TGContourNode *node, const TGPolygon &p ) {
// recurse the contour tree and build up the point inside list for // recurse the contour tree and build up the point inside list for
// each contour/hole // each contour/hole
static void calc_point_inside( TGContourNode *node, TGPolygon &p ) { static void calc_point_inside( TGContourNode *node, TGPolygon &p ) {
int contour_num = node->get_contour_num();
// cout << "starting calc_point_inside() with contour = " << contour_num
// << endl;
for ( int i = 0; i < node->get_num_kids(); ++i ) { for ( int i = 0; i < node->get_num_kids(); ++i ) {
if ( node->get_kid( i ) != NULL ) { if ( node->get_kid( i ) != NULL ) {
calc_point_inside( node->get_kid( i ), p ); calc_point_inside( node->get_kid( i ), p );
} }
} }
int contour_num = node->get_contour_num();
if ( contour_num >= 0 ) { if ( contour_num >= 0 ) {
Point3D pi = point_inside_contour( node, p ); Point3D pi = point_inside_contour( node, p );
//cout << endl << "point inside(" << contour_num << ") = " << pi // cout << endl << "point inside(" << contour_num << ") = " << pi
// << endl << endl; // << endl << endl;
p.set_point_inside( contour_num, pi ); p.set_point_inside( contour_num, pi );
} }
@ -940,11 +948,13 @@ void calc_points_inside( TGPolygon& p ) {
TGContourNode *ct = new TGContourNode( -1 ); TGContourNode *ct = new TGContourNode( -1 );
// recursively build the tree // recursively build the tree
// cout << "building contour tree" << endl;
build_contour_tree( ct, p, avail ); build_contour_tree( ct, p, avail );
//print_contour_tree( ct, "" ); // print_contour_tree( ct, "" );
// recurse the tree and build up the point inside list for each // recurse the tree and build up the point inside list for each
// contour/hole // contour/hole
// cout << " calc_point_inside()\n";
calc_point_inside( ct, p ); calc_point_inside( ct, p );
} }
@ -1045,9 +1055,7 @@ bool find_intermediate_node( const Point3D& start, const Point3D& end,
Point3D p0 = start; Point3D p0 = start;
Point3D p1 = end; Point3D p1 = end;
// cout << " add_intermediate_nodes()" << endl; // cout << " find_intermediate_nodes() " << p0 << " <=> " << p1 << endl;
// printf(" %.7f %.7f %.7f <=> %.7f %.7f %.7f\n",
// p0.x(), p0.y(), p0.z(), p1.x(), p1.y(), p1.z() );
double xdist = fabs(p0.x() - p1.x()); double xdist = fabs(p0.x() - p1.x());
double ydist = fabs(p0.y() - p1.y()); double ydist = fabs(p0.y() - p1.y());
@ -1168,10 +1176,13 @@ static point_list reduce_contour_degeneracy( const point_list& contour ) {
while ( !done ) { while ( !done ) {
// traverse the contour until we find the first bad node or // traverse the contour until we find the first bad node or
// hit the end of the contour // hit the end of the contour
//cout << " ... not done ... " << endl; // cout << " ... reduce_degeneracy(): not done ... " << endl;
bool bad = false; bool bad = false;
int i = 0; int i = 0;
int j = 0;
// look for stray intermediate nodes
while ( i < (int)result.size() - 1 && !bad ) { while ( i < (int)result.size() - 1 && !bad ) {
p0 = result[i]; p0 = result[i];
p1 = result[i+1]; p1 = result[i+1];
@ -1186,7 +1197,35 @@ static point_list reduce_contour_degeneracy( const point_list& contour ) {
bad = find_intermediate_node( p0, p1, result, &bad_node ); bad = find_intermediate_node( p0, p1, result, &bad_node );
} }
// CLO: look for later nodes that match earlier segment end points
// (i.e. a big cycle.) There's no good automatic fix to this
// so just drop the problematic point and live with our
// contour changing shape.
//
// WARNING: FIXME??? By changing the shape of a polygon at
// this point we are introducing some overlap which could show
// up as flickering/depth-buffer fighting at run time. The
// better fix would be to split up the two regions into
// separate contours, but I just don't have the energy to
// think though that right now.
if ( !bad ) {
i = 0;
while ( i < (int)result.size() - 1 && !bad ) {
j = i + 1;
while ( j < (int)result.size() && !bad ) {
if ( result[i] == result[j] ) {
bad = true;
bad_node = result[j];
}
j++;
}
i++;
}
}
if ( bad ) { if ( bad ) {
cout << "found a bad node = " << bad_node << endl;
// remove bad node from contour // remove bad node from contour
point_list tmp; tmp.clear(); point_list tmp; tmp.clear();
for ( int j = 0; j < (int)result.size(); ++j ) { for ( int j = 0; j < (int)result.size(); ++j ) {
@ -1211,6 +1250,7 @@ TGPolygon reduce_degeneracy( const TGPolygon& poly ) {
TGPolygon result; TGPolygon result;
for ( int i = 0; i < poly.contours(); ++i ) { for ( int i = 0; i < poly.contours(); ++i ) {
// cout << "reduce_degeneracy() contour = " << i << endl;
point_list contour = poly.get_contour(i); point_list contour = poly.get_contour(i);
contour = reduce_contour_degeneracy( contour ); contour = reduce_contour_degeneracy( contour );
result.add_contour( contour, poly.get_hole_flag(i) ); result.add_contour( contour, poly.get_hole_flag(i) );
@ -1222,8 +1262,8 @@ TGPolygon reduce_degeneracy( const TGPolygon& poly ) {
return result; return result;
} }
// find short cycles in a contour and snip them out.
static point_list remove_contour_cycles( const point_list& contour ) { static point_list remove_small_cycles( const point_list& contour ) {
point_list result; point_list result;
result.clear(); result.clear();
@ -1256,7 +1296,7 @@ TGPolygon remove_cycles( const TGPolygon& poly ) {
// cout << "remove cycles: " << poly << endl; // cout << "remove cycles: " << poly << endl;
for ( int i = 0; i < poly.contours(); ++i ) { for ( int i = 0; i < poly.contours(); ++i ) {
point_list contour = poly.get_contour(i); point_list contour = poly.get_contour(i);
contour = remove_contour_cycles( contour ); contour = remove_small_cycles( contour );
result.add_contour( contour, poly.get_hole_flag(i) ); result.add_contour( contour, poly.get_hole_flag(i) );
} }