From cbea4335f465647544aa3ccdf4bc07096118f842 Mon Sep 17 00:00:00 2001 From: Peter Sadrozinski Date: Sat, 10 Mar 2012 17:38:03 -0500 Subject: [PATCH] Instead of snapping whenever clipper converts a poly, just snap before clipping, and after intermediate nodes are added. If we snap before intermediate nodes are added, we generate extra slivers, as the proximity for node insertion may fail when the extra node is snapped away from the line we are checking --- src/Airports/GenAirports850/airport.cxx | 4 ++ src/Airports/GenAirports850/closedpoly.cxx | 11 +++--- src/Airports/GenAirports850/global.hxx | 3 ++ src/Airports/GenAirports850/helipad.cxx | 22 ++++++----- src/Airports/GenAirports850/linearfeature.cxx | 4 +- src/Airports/GenAirports850/main.cxx | 7 +++- src/Airports/GenAirports850/runway.cxx | 3 ++ src/Airports/GenAirports850/rwy_gen.cxx | 11 ++++++ src/Lib/Geometry/point3d.hxx | 13 +++---- src/Lib/Geometry/poly_support.cxx | 37 ++++++------------- src/Lib/Polygon/polygon.cxx | 1 - 11 files changed, 64 insertions(+), 52 deletions(-) diff --git a/src/Airports/GenAirports850/airport.cxx b/src/Airports/GenAirports850/airport.cxx index c4d8f00b..f763bf28 100644 --- a/src/Airports/GenAirports850/airport.cxx +++ b/src/Airports/GenAirports850/airport.cxx @@ -27,6 +27,7 @@ #include +#include "global.hxx" #include "elevations.hxx" @@ -773,12 +774,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) for ( unsigned int k = 0; k < rwy_polys.size(); ++k ) { TGPolygon poly = rwy_polys[k].get_poly(); + poly = snap(poly, gSnap); rwy_polys[k].set_poly( poly ); } for ( unsigned int k = 0; k < pvmt_polys.size(); ++k ) { TGPolygon poly = pvmt_polys[k].get_poly(); + poly = snap(poly, gSnap); pvmt_polys[k].set_poly( poly ); } @@ -808,6 +811,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_feat_nodes size = " << tmp_feat_nodes.get_node_list().size()); base_poly = add_nodes_to_poly( base_poly, tmp_pvmt_nodes ); + base_poly = snap( base_poly, gSnap ); SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly); // Finally find slivers in base diff --git a/src/Airports/GenAirports850/closedpoly.cxx b/src/Airports/GenAirports850/closedpoly.cxx index df6754f2..956a18d8 100644 --- a/src/Airports/GenAirports850/closedpoly.cxx +++ b/src/Airports/GenAirports850/closedpoly.cxx @@ -8,6 +8,7 @@ #include #include +#include "global.hxx" #include "beznode.hxx" #include "closedpoly.hxx" @@ -277,7 +278,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst ) // add the pavement vertex // convert from lat/lon to geo // (maybe later) - check some simgear objects... - curLoc.snap(); dst->push_back( curLoc ); if (p==0) @@ -303,7 +303,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst ) nextLoc = CalculateLinearLocation( curNode->GetLoc(), nextNode->GetLoc(), (1.0f/num_segs) * (p+1) ); // add the feature vertex - curLoc.snap(); dst->push_back( curLoc ); if (p==0) @@ -324,7 +323,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst ) nextLoc = nextNode->GetLoc(); // just add the one vertex - dist is small - curLoc.snap(); dst->push_back( curLoc ); SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")"); @@ -363,6 +361,8 @@ void ClosedPoly::Finish() ConvertContour( holes[i], &dst_contour ); pre_tess.add_contour( dst_contour, 1 ); } + + pre_tess = snap( pre_tess, gSnap ); } // save memory by deleting unneeded resources @@ -441,10 +441,10 @@ int ClosedPoly::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, TGTexParams tp; TGPolygon clipped = tgPolygonDiffClipper( pre_tess, *accum ); - SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours()); - tgPolygonFindSlivers( clipped, slivers ); + SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours()); + sp.erase(); sp.set_poly( clipped ); sp.set_material( material ); @@ -453,6 +453,7 @@ int ClosedPoly::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, rwy_polys->push_back( sp ); *accum = tgPolygonUnionClipper( pre_tess, *accum ); +// *accum = tgPolygonUnionClipper( clipped, *accum ); /* If debugging this poly, write the poly, and clipped poly and the accum buffer into their own layers */ if (ds_id) { diff --git a/src/Airports/GenAirports850/global.hxx b/src/Airports/GenAirports850/global.hxx index 6b303fc9..e612d81b 100644 --- a/src/Airports/GenAirports850/global.hxx +++ b/src/Airports/GenAirports850/global.hxx @@ -28,6 +28,9 @@ extern int nudge; +// Each polygon vertex is snapped to a grid with this resolution (~1cm by default) +extern double gSnap; + // Final grid size for airport surface (in meters) const double coarse_grid = 300.0; diff --git a/src/Airports/GenAirports850/helipad.cxx b/src/Airports/GenAirports850/helipad.cxx index 15685713..119b6987 100644 --- a/src/Airports/GenAirports850/helipad.cxx +++ b/src/Airports/GenAirports850/helipad.cxx @@ -18,6 +18,8 @@ #include #include +#include + #include "global.hxx" #include "apt_math.hxx" #include "helipad.hxx" @@ -61,12 +63,18 @@ void Helipad::gen_helipad( const TGPolygon& runway, Point3D a2 = runway.get_pt(0, 0); Point3D a3 = runway.get_pt(0, 3); +#if 0 if ( startl_pct > 0.0 ) { startl_pct -= nudge * SG_EPSILON; } if ( endl_pct < 1.0 ) { endl_pct += nudge * SG_EPSILON; } +#endif + + if ( startl_pct < 0.0 ) { + startl_pct = 0.0; + } if ( endl_pct > 1.0 ) { endl_pct = 1.0; @@ -77,6 +85,7 @@ void Helipad::gen_helipad( const TGPolygon& runway, // with our polygon clipping code. This attempts to compensate // for that by nudging the areas a bit bigger so we don't end up // with polygon slivers. +#if 0 if ( startw_pct > 0.0 || endw_pct < 1.0 ) { if ( startw_pct > 0.0 ) { startw_pct -= nudge * SG_EPSILON; @@ -85,6 +94,7 @@ void Helipad::gen_helipad( const TGPolygon& runway, endw_pct += nudge * SG_EPSILON; } } +#endif SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct << " end len % = " << endl_pct); @@ -138,6 +148,7 @@ void Helipad::gen_helipad( const TGPolygon& runway, section.add_node( 0, p0 ); section.add_node( 0, p1 ); section.add_node( 0, p3 ); + section = snap( section, gSnap ); // print runway points SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << prefix << material); @@ -149,12 +160,7 @@ void Helipad::gen_helipad( const TGPolygon& runway, } // Clip the new polygon against what ever has already been created. -#if 0 - TGPolygon clipped = tgPolygonDiff( section, *accum ); -#else TGPolygon clipped = tgPolygonDiffClipper( section, *accum ); -#endif - tgPolygonFindSlivers( clipped, slivers ); // Split long edges to create an object that can better flow with @@ -170,11 +176,7 @@ void Helipad::gen_helipad( const TGPolygon& runway, rwy_polys->push_back( sp ); SG_LOG(SG_GENERAL, SG_DEBUG, "section = " << clipped.contours()); -#if 0 - *accum = tgPolygonUnion( section, *accum ); -#else *accum = tgPolygonUnionClipper( section, *accum ); -#endif // Store away what we need to know for texture coordinate // calculation. (CLO 10/20/02: why can't we calculate texture @@ -292,9 +294,11 @@ void Helipad::BuildBtg( superpoly_list *rwy_polys, { TGPolygon base, safe_base; base = gen_runway_area_w_extend( 0.0, maxsize * 0.25 , 0.0, 0.0, maxsize * 0.25 ); + base = snap( base, gSnap ); // also clear a safe area around the pad safe_base = gen_runway_area_w_extend( 0.0, maxsize * 0.5, 0.0, 0.0, maxsize * 0.5 ); + safe_base = snap( safe_base, gSnap ); // add this to the airport clearing *apt_clearing = tgPolygonUnionClipper(safe_base, *apt_clearing); diff --git a/src/Airports/GenAirports850/linearfeature.cxx b/src/Airports/GenAirports850/linearfeature.cxx index cff9bc12..c0cbca55 100644 --- a/src/Airports/GenAirports850/linearfeature.cxx +++ b/src/Airports/GenAirports850/linearfeature.cxx @@ -9,6 +9,7 @@ // for debugging clipping errors #include +#include "global.hxx" #include "beznode.hxx" #include "linearfeature.hxx" #include "math.h" @@ -742,8 +743,6 @@ int LinearFeature::Finish( bool closed, unsigned int idx ) cur_outer = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], offset-width/2.0f ); cur_inner = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], offset+width/2.0f ); } - cur_outer.snap(); - cur_inner.snap(); if ( (prev_inner.x() != 0.0f) && (prev_inner.y() != 0.0f) ) { @@ -756,6 +755,7 @@ int LinearFeature::Finish( bool closed, unsigned int idx ) poly.add_node( 0, prev_outer ); poly.add_node( 0, cur_outer ); poly.add_node( 0, cur_inner ); + poly = snap( poly, gSnap ); #if DEBUG_LF char feature_name[128]; diff --git a/src/Airports/GenAirports850/main.cxx b/src/Airports/GenAirports850/main.cxx index a1a2d609..2d863479 100644 --- a/src/Airports/GenAirports850/main.cxx +++ b/src/Airports/GenAirports850/main.cxx @@ -112,8 +112,9 @@ static void help( int argc, char **argv, const string_list& elev_src ) { } // TODO: where do these belong -int nudge = 10; +int nudge = 0; double slope_max = 0.2; +double gSnap = 0.0000001; int main(int argc, char **argv) { @@ -172,6 +173,10 @@ int main(int argc, char **argv) else if ( arg.find("--nudge=") == 0 ) { nudge = atoi( arg.substr(8).c_str() ); + } + else if ( arg.find("--snap=") == 0 ) + { + gSnap = atof( arg.substr(7).c_str() ); } else if ( arg.find("--last_apt_file=") == 0 ) { diff --git a/src/Airports/GenAirports850/runway.cxx b/src/Airports/GenAirports850/runway.cxx index d4febe9c..f6491d4d 100644 --- a/src/Airports/GenAirports850/runway.cxx +++ b/src/Airports/GenAirports850/runway.cxx @@ -8,6 +8,7 @@ #include #include +#include "global.hxx" #include "apt_math.hxx" #include "beznode.hxx" #include "runway.hxx" @@ -166,9 +167,11 @@ int Runway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, supe // generate area around runways base = gen_runway_area_w_extend( 20.0, -rwy.overrun[0], -rwy.overrun[1], 20.0 ); + base = snap( base, gSnap ); // also clear a safe area around the runway safe_base = gen_runway_area_w_extend( 180.0, -rwy.overrun[0], -rwy.overrun[1], 50.0 ); + safe_base = snap( safe_base, gSnap ); // add this to the airport clearing *apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing ); diff --git a/src/Airports/GenAirports850/rwy_gen.cxx b/src/Airports/GenAirports850/rwy_gen.cxx index ce5af489..7a24db02 100644 --- a/src/Airports/GenAirports850/rwy_gen.cxx +++ b/src/Airports/GenAirports850/rwy_gen.cxx @@ -24,6 +24,8 @@ #include #include +#include + #include "global.hxx" #include "beznode.hxx" #include "runway.hxx" @@ -107,12 +109,18 @@ void Runway::gen_runway_section( const TGPolygon& runway, Point3D a2 = runway.get_pt(0, 0); Point3D a3 = runway.get_pt(0, 3); +#if 0 if ( startl_pct > 0.0 ) { startl_pct -= nudge * SG_EPSILON; } if ( endl_pct < 1.0 ) { endl_pct += nudge * SG_EPSILON; } +#endif + + if ( startl_pct < 0.0 ) { + startl_pct = 0.0; + } if ( endl_pct > 1.0 ) { endl_pct = 1.0; @@ -123,6 +131,7 @@ void Runway::gen_runway_section( const TGPolygon& runway, // with our polygon clipping code. This attempts to compensate // for that by nudging the areas a bit bigger so we don't end up // with polygon slivers. +#if 0 if ( startw_pct > 0.0 || endw_pct < 1.0 ) { if ( startw_pct > 0.0 ) { startw_pct -= nudge * SG_EPSILON; @@ -131,6 +140,7 @@ void Runway::gen_runway_section( const TGPolygon& runway, endw_pct += nudge * SG_EPSILON; } } +#endif SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct << " end len % = " << endl_pct); @@ -184,6 +194,7 @@ void Runway::gen_runway_section( const TGPolygon& runway, section.add_node( 0, p0 ); section.add_node( 0, p1 ); section.add_node( 0, p3 ); + section = snap( section, gSnap ); // print runway points SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << material_prefix << material); diff --git a/src/Lib/Geometry/point3d.hxx b/src/Lib/Geometry/point3d.hxx index bb54eab6..930a276d 100644 --- a/src/Lib/Geometry/point3d.hxx +++ b/src/Lib/Geometry/point3d.hxx @@ -50,9 +50,6 @@ //const double fgPoint3_Epsilon = 0.0000001; const double fgPoint3_Epsilon = 0.000001; -#define DO_SNAP 0 -#define SNAP_GRID (0.0000001) - enum {PX, PY, PZ}; // axes // Kludge for msvc++ 6.0 - requires forward decls of friend functions. @@ -104,7 +101,7 @@ public: void setradius(const double z); void setelev(const double z); - void snap(void); + void snap( double grid ); // Queries @@ -339,11 +336,11 @@ inline void Point3D::setelev(const double z) { n[PZ] = z; } -inline void Point3D::snap( void ) +inline void Point3D::snap( double grid ) { - n[PX] = SNAP_GRID * round( n[PX]/SNAP_GRID ); - n[PY] = SNAP_GRID * round( n[PY]/SNAP_GRID ); - n[PZ] = SNAP_GRID * round( n[PZ]/SNAP_GRID ); + n[PX] = grid * round( n[PX]/grid ); + n[PY] = grid * round( n[PY]/grid ); + n[PZ] = grid * round( n[PZ]/grid ); } // QUERIES diff --git a/src/Lib/Geometry/poly_support.cxx b/src/Lib/Geometry/poly_support.cxx index fcbd80af..5ac1cb6b 100644 --- a/src/Lib/Geometry/poly_support.cxx +++ b/src/Lib/Geometry/poly_support.cxx @@ -929,36 +929,21 @@ TGPolygon remove_dups( const TGPolygon &poly ) { } #endif -static inline double -snap (double value, double grid_size) -{ - // I have no idea if this really works. - double factor = 1.0 / grid_size; - return double(int(value * factor)) / factor; -} - -static inline Point3D -snap (const Point3D &p, double grid_size) -{ - Point3D result; - result.setx(snap(p.x(), grid_size)); - result.sety(snap(p.y(), grid_size)); - result.setz(snap(p.z(), grid_size)); - //cout << result << endl; - return result; -} - // snap all points in a polygon to the given grid size. TGPolygon snap (const TGPolygon &poly, double grid_size) { - TGPolygon result; - for (int contour = 0; contour < poly.contours(); contour++) { - for (int i = 0; i < poly.contour_size(contour); i++) { - result.add_node(contour, snap(poly.get_pt(contour, i), grid_size)); + TGPolygon result; + Point3D pt; + for (int contour = 0; contour < poly.contours(); contour++) { + for (int i = 0; i < poly.contour_size(contour); i++) { + pt = poly.get_pt(contour, i); + pt.snap( grid_size ); + result.add_node(contour, pt); + } + result.set_hole_flag(contour, poly.get_hole_flag(contour)); } - result.set_hole_flag(contour, poly.get_hole_flag(contour)); - } - return result; + + return result; } diff --git a/src/Lib/Polygon/polygon.cxx b/src/Lib/Polygon/polygon.cxx index a0c6a897..42e30101 100644 --- a/src/Lib/Polygon/polygon.cxx +++ b/src/Lib/Polygon/polygon.cxx @@ -502,7 +502,6 @@ Point3D MakeTGPoint( IntPoint pt ) y = (double)( ((double)pt.Y) / (double)FIXEDPT ); tg_pt = Point3D( x, y, -9999.0f); - tg_pt.snap(); return tg_pt; }