From d44401402e67bcaef0a369f478394795307b70bb Mon Sep 17 00:00:00 2001 From: curt Date: Fri, 22 Dec 2000 02:33:37 +0000 Subject: [PATCH] Chasing down a bug in building the contour tree. Also tweaked the remove_dups() routine in the process. --- src/Airports/GenAirports/build.cxx | 8 ++-- src/Lib/Geometry/poly_support.cxx | 75 +++++++++++++++++------------- src/Lib/Polygon/polygon.cxx | 20 ++++++-- 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/src/Airports/GenAirports/build.cxx b/src/Airports/GenAirports/build.cxx index 7fe34fa6..b404b2ef 100644 --- a/src/Airports/GenAirports/build.cxx +++ b/src/Airports/GenAirports/build.cxx @@ -1804,12 +1804,14 @@ void build_airport( string airport_raw, string_list& runways_raw, rwy_polys[k].set_poly( poly ); } - cout << "add nodes/remove dups base " << endl; + cout << "add nodes base " << endl; base_poly = add_nodes_to_poly( base_poly, tmp_nodes ); // write_polygon( base_poly, "base-add" ); + cout << "remove dups base " << endl; base_poly = remove_dups( base_poly ); + cout << "remove bad contours base" << endl; base_poly = remove_bad_contours( base_poly ); - // write_polygon( base_poly, "base-final" ); + // write_polygon( base_poly, "base-fin" ); // tesselate the polygons and prepair them for final output @@ -1828,7 +1830,7 @@ void build_airport( string airport_raw, string_list& runways_raw, rwy_polys[i].set_texcoords( tc ); rwy_polys[i].set_tri_mode( GL_TRIANGLES ); } - + cout << "Tesselating base" << endl; FGPolygon base_tris = polygon_tesselate_alt( base_poly ); diff --git a/src/Lib/Geometry/poly_support.cxx b/src/Lib/Geometry/poly_support.cxx index c4c340e7..2dda2dec 100644 --- a/src/Lib/Geometry/poly_support.cxx +++ b/src/Lib/Geometry/poly_support.cxx @@ -234,7 +234,7 @@ Point3D calc_point_inside_old( const FGPolygon& p, const int contour, // basic triangulation of a polygon with out adding points or -// splitting edges +// splitting edges, this should triangulate around interior holes. void polygon_tesselate( const FGPolygon &p, triele_list &elelist, point_list &out_pts ) @@ -360,6 +360,9 @@ void polygon_tesselate( const FGPolygon &p, // TEMPORARY write_tri_data(&in); + /* cout << "Press return to continue:"; + char junk; + cin >> junk; */ // Triangulate the points. Switches are chosen to read and write // a PSLG (p), number everything from zero (z), and produce an @@ -636,6 +639,9 @@ static void contour_tesselate( FGContourNode *node, const FGPolygon &p, // TEMPORARY write_tri_data(&in); + /* cout << "Press return to continue:"; + char junk; + cin >> junk; */ // Triangulate the points. Switches are chosen to read and write // a PSLG (p), number everything from zero (z), and produce an @@ -762,7 +768,8 @@ static Point3D point_inside_contour( FGContourNode *node, const FGPolygon &p ) { contour_tesselate( node, p, hole_polys, hole_pts, elelist, out_pts ); if ( elelist.size() <= 0 ) { cout << "Error polygon triangulated to zero triangles!" << endl; - exit(-1); + return Point3D( -200, -200, 0 ); + // exit(-1); } // find the largest triangle in the group @@ -856,7 +863,7 @@ static void build_contour_tree( FGContourNode *node, if ( avail[i] ) { // must still be an available contour int cur_contour = node->get_contour_num(); - if ( (cur_contour < 0 ) || p.is_inside( cur_contour, i ) ) { + if ( (cur_contour < 0 ) || p.is_inside( i, cur_contour ) ) { // must be inside the parent (or if the parent is // the root, add all available non-holes. cout << " adding contour = " << i << endl; @@ -880,10 +887,11 @@ static void build_contour_tree( FGContourNode *node, for ( i = 0; i < node->get_num_kids(); ++i ) { for ( int j = 0; j < node->get_num_kids(); ++j ) { + // cout << "working on kid " << i << ", " << j << endl; if ( i != j ) { if ( (node->get_kid(i) != NULL)&&(node->get_kid(j) != NULL) ) { - int A = node->get_kid( i ) -> get_contour_num(); - int B = node->get_kid( j ) -> get_contour_num(); + int A = node->get_kid( i )->get_contour_num(); + int B = node->get_kid( j )->get_contour_num(); if ( p.is_inside( A, B ) ) { // p.write_contour( i, "a" ); // p.write_contour( j, "b" ); @@ -891,8 +899,9 @@ static void build_contour_tree( FGContourNode *node, // need to remove contour j from the kid list avail[ node->get_kid( i ) -> get_contour_num() ] = 1; node->remove_kid( i ); - cout << "removing kid " << i - << " which is inside of kid " << j << endl; + cout << "removing contour " << A + << " which is inside of contour " << B << endl; + continue; } } else { // one of these kids is already NULL, skip @@ -941,41 +950,43 @@ void calc_points_inside( FGPolygon& p ) { // fixed polygon FGPolygon remove_dups( const FGPolygon &poly ) { FGPolygon result; + point_list contour, new_contour; result.erase(); - for ( int i = 0; i < poly.contours(); ++i ) { - Point3D last = poly.get_pt( i, poly.contour_size(i) - 1 ); - bool all_same = true; - for ( int j = 0; j < poly.contour_size(i); ++j ) { - // cout << " " << i << " " << j << endl; - Point3D cur = poly.get_pt( i, j ); - if ( cur == last ) { - // skip - // cout << "skipping a duplicate point" << endl; - } else { - result.add_node( i, cur ); - all_same = false; - last = cur; + FGPolygon tmp = poly; + for ( int i = 0; i < tmp.contours(); ++i ) { + contour = poly.get_contour( i ); + // cout << "testing contour " << i << " size = " << contour.size() + // << " hole = " << poly.get_hole_flag( i ) << endl; + bool have_dups = true; + while ( have_dups ) { + have_dups = false; + new_contour.clear(); + Point3D last = contour[ contour.size() - 1 ]; + for ( int j = 0; j < (int)contour.size(); ++j ) { + // cout << " " << i << " " << j << endl; + Point3D cur = contour[j]; + if ( cur == last ) { + have_dups = true; + // cout << "skipping a duplicate point" << endl; + } else { + new_contour.push_back( cur ); + last = cur; + } } - } - - // make sure the last point doesn't equal the previous or the first. - Point3D begin = poly.get_pt( i, 0 ); - Point3D end = poly.get_pt( i, poly.contour_size(i) - 1 ); - if ( begin == end ) { - // skip - cout << "begin == end!" << endl; - // exit(-1); + contour = new_contour; } - if ( !all_same ) { + // cout << " final size = " << contour.size() << endl; + + if ( contour.size() ) { int flag = poly.get_hole_flag( i ); - result.set_hole_flag( i, flag ); + result.add_contour( contour, flag ); } else { // too small an area ... add a token point to the contour // to keep other things happy, but this "bad" contour will // get nuked later - result.add_node( i, begin ); + result.add_node( i, poly.get_pt( i, 0 ) ); } } diff --git a/src/Lib/Polygon/polygon.cxx b/src/Lib/Polygon/polygon.cxx index 014e26eb..8d60d6f0 100644 --- a/src/Lib/Polygon/polygon.cxx +++ b/src/Lib/Polygon/polygon.cxx @@ -143,7 +143,7 @@ double FGPolygon::minangle_contour( const int contour ) { } -// return true if contour B is inside countour A +// return true if contour A is inside countour B bool FGPolygon::is_inside( int a, int b ) const { // make polygons from each specified contour FGPolygon A, B; @@ -157,14 +157,24 @@ bool FGPolygon::is_inside( int a, int b ) const { pl = get_contour( b ); B.add_contour( pl, 0 ); - // B is "inside" A if the polygon_diff( B, A ) is not null. - FGPolygon result = polygon_diff( B, A ); + // cout << "A size = " << A.total_size() << endl; + // A.write( "A" ); + // cout << "B size = " << B.total_size() << endl; + // B.write( "B" ); + + // A is "inside" B if the polygon_diff( A, B ) is null. + FGPolygon result = polygon_diff( A, B ); + // cout << "result size = " << result.total_size() << endl; + + // char junk; + // cin >> junk; + if ( result.contours() == 0 ) { - // cout << " is_inside() result = true" << endl; + // cout << " " << a << " is_inside() " << b << endl; return true; } - // cout << " is_inside() result = false" << endl; + // cout << " " << a << " not is_inside() " << b << endl; return false; }