From b013ad6b7b9acb6d8cabd46872ff6c4e46c7fa67 Mon Sep 17 00:00:00 2001 From: Peter Sadrozinski Date: Sat, 17 Nov 2012 11:26:13 -0500 Subject: [PATCH] Fix some gaps in and around airports - these gaps were caused by a late clipper stage that optomizes the resulting polygon after clipping - including removal of nodes whose edges have the same slope. I was unable to disable this optomization without breaking clipper - it would just hang. So all clipper operations now save the subject nodes before, and reinsert after the op. - cleaned up some debug - genapts is so fast now, that we can just print out the summaries. --- src/Airports/GenAirports850/airport.cxx | 234 ++++++++++++--------- src/Airports/GenAirports850/closedpoly.cxx | 4 - src/Airports/GenAirports850/scheduler.cxx | 2 +- src/Lib/Polygon/polygon.cxx | 116 +++++++++- src/Lib/Polygon/polygon.hxx | 1 + 5 files changed, 242 insertions(+), 115 deletions(-) diff --git a/src/Airports/GenAirports850/airport.cxx b/src/Airports/GenAirports850/airport.cxx index 2606c311..80997615 100644 --- a/src/Airports/GenAirports850/airport.cxx +++ b/src/Airports/GenAirports850/airport.cxx @@ -37,6 +37,15 @@ string SGLOG_GREEN = "\033[0;32m"; string SGLOG_NORMAL = "\033[0m"; +static std::string my_ctime(time_t& tt) +{ + char buf[256]; + + strcpy(buf,ctime(&tt)); + buf[strlen(buf)-1]='\0'; + return std::string( buf ); +} + Airport::Airport( int c, char* def) { int numParams; @@ -356,57 +365,63 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) if (features.size()) { + SG_LOG(SG_GENERAL, SG_INFO, "Build " << features.size() << " Linear Feature Polys"); for ( unsigned int i=0; iGetDescription() ); + SG_LOG(SG_GENERAL, SG_DEBUG, "Build Feature Poly " << i + 1 << " of " << features.size() << " : " << features[i]->GetDescription() ); features[i]->BuildBtg( line_polys, rwy_lights, make_shapefiles ); } + + log_time = time(0); + SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Linear Features for " << icao << " at " << my_ctime(log_time) ); } /* Done with the linear features accumulator */ tgPolygonFreeClipperAccumulator(); - log_time = time(0); - SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Linear Features for " << icao << " at " << ctime(&log_time) ); - - // Initialize a new accumulator for the other objects + /* Initialize a new accumulator for the other objects */ tgPolygonInitClipperAccumulator(); // Build runways next - for ( unsigned int i=0; iBuildBtg( rwy_polys, rwy_lights, slivers, shapefile ); - } - else - { - runways[i]->BuildBtg( rwy_polys, rwy_lights, slivers, apt_base, apt_clearing, shapefile ); + SG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway " << i + 1 << " of " << runways.size()); + slivers.clear(); + + if ( isDebugRunway(i) ) { + sprintf( shapefile_name, "runway_%d", i ); + } else { + strcpy( shapefile_name, "" ); + } + shapefile = shapefile_name; + + if (boundary.size()) + { + runways[i]->BuildBtg( rwy_polys, rwy_lights, slivers, shapefile ); + } + else + { + runways[i]->BuildBtg( rwy_polys, rwy_lights, slivers, apt_base, apt_clearing, shapefile ); + } + + // Now try to merge any slivers we found + tgPolygon::MergeSlivers( rwy_polys, slivers ); } - // Now try to merge any slivers we found - tgPolygon::MergeSlivers( rwy_polys, slivers ); + log_time = time(0); + SG_LOG( SG_GENERAL, SG_ALERT, "Finished building runways for " << icao << " at " << my_ctime(log_time) ); } - log_time = time(0); - SG_LOG( SG_GENERAL, SG_ALERT, "Finished building runways for " << icao << " at " << ctime(&log_time) ); - if (lightobjects.size()) { + SG_LOG(SG_GENERAL, SG_INFO, "Build " << lightobjects.size() << " Light Objects "); for ( unsigned int i=0; iBuildBtg( rwy_lights ); } } @@ -414,9 +429,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) // Build helipads (use runway poly- and texture list for this) if (helipads.size()) { + SG_LOG(SG_GENERAL, SG_INFO, "Build " << helipads.size() << " Helipad Polys "); for ( unsigned int i=0; iGetDescription()); + SG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i + 1 << " of " << pavements.size() << " : " << pavements[i]->GetDescription()); slivers.clear(); if ( isDebugPavement(i) ) { @@ -461,17 +478,18 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) tgPolygon::MergeSlivers( rwy_polys, slivers ); tgPolygon::MergeSlivers( pvmt_polys, slivers ); } - } - log_time = time(0); - SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Pavements for " << icao << " at " << ctime(&log_time) ); + log_time = time(0); + SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Pavements for " << icao << " at " << my_ctime(log_time) ); + } // Build the legacy taxiways if (taxiways.size()) { + SG_LOG(SG_GENERAL, SG_INFO, "Build " << taxiways.size() << " Taxiway Polys "); for ( unsigned int i=0; iGetsShoulder() ) + SG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Runway Shoulder Polys "); + for ( unsigned int i=0; iGetsShoulder() ) { - runways[i]->BuildShoulder( rwy_polys, slivers ); - } - else - { - runways[i]->BuildShoulder( rwy_polys, slivers, apt_base, apt_clearing ); - } + slivers.clear(); - // Now try to merge any slivers we found - tgPolygon::MergeSlivers( rwy_polys, slivers ); - tgPolygon::MergeSlivers( pvmt_polys, slivers ); + if (boundary.size()) + { + runways[i]->BuildShoulder( rwy_polys, slivers ); + } + else + { + runways[i]->BuildShoulder( rwy_polys, slivers, apt_base, apt_clearing ); + } + + // Now try to merge any slivers we found + tgPolygon::MergeSlivers( rwy_polys, slivers ); + tgPolygon::MergeSlivers( pvmt_polys, slivers ); + } } } // Build helipad shoulders here - for ( unsigned int i=0; iGetsShoulder() ) + SG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Helipad Shoulder Polys "); + for ( unsigned int i=0; iGetsShoulder() ) { - helipads[i]->BuildShoulder( rwy_polys, slivers ); - } - else - { - helipads[i]->BuildShoulder( rwy_polys, slivers, apt_base, apt_clearing ); - } + slivers.clear(); - // Now try to merge any slivers we found - tgPolygon::MergeSlivers( rwy_polys, slivers ); - tgPolygon::MergeSlivers( pvmt_polys, slivers ); + if (boundary.size()) + { + helipads[i]->BuildShoulder( rwy_polys, slivers ); + } + else + { + helipads[i]->BuildShoulder( rwy_polys, slivers, apt_base, apt_clearing ); + } + + // Now try to merge any slivers we found + tgPolygon::MergeSlivers( rwy_polys, slivers ); + tgPolygon::MergeSlivers( pvmt_polys, slivers ); + } } } // build the base and clearing if there's a boundary if (boundary.size()) { + SG_LOG(SG_GENERAL, SG_INFO, "Build " << boundary.size() << " Boundary Polys "); shapefile = ""; for ( unsigned int i=0; iBuildBtg( apt_base, apt_clearing, shapefile ); } } @@ -578,7 +605,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) // build temporary node list from runways... SG_LOG(SG_GENERAL, SG_INFO, "Build Node List " ); - for ( unsigned int k = 0; k < rwy_polys.size(); ++k ) { tgPolygon poly = rwy_polys[k]; @@ -637,7 +663,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) } log_time = time(0); - SG_LOG( SG_GENERAL, SG_ALERT, "Finished collecting nodes for " << icao << " at " << ctime(&log_time) ); + SG_LOG( SG_GENERAL, SG_ALERT, "Finished collecting nodes for " << icao << " at " << my_ctime(log_time) ); // second pass : runways for ( unsigned int k = 0; k < rwy_polys.size(); ++k ) @@ -667,7 +693,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) } log_time = time(0); - SG_LOG( SG_GENERAL, SG_ALERT, "Finished adding intermediate nodes for " << icao << " at " << ctime(&log_time) ); + SG_LOG( SG_GENERAL, SG_ALERT, "Finished adding intermediate nodes for " << icao << " at " << my_ctime(log_time) ); for ( unsigned int k = 0; k < line_polys.size(); ++k ) { @@ -687,16 +713,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) } log_time = time(0); - SG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning polys for " << icao << " at " << ctime(&log_time) ); - - SG_LOG(SG_GENERAL, SG_DEBUG, "add nodes base "); - SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly); - SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_pvmt_nodes size = " << tmp_pvmt_nodes.get_node_list().size()); - SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_feat_nodes size = " << tmp_feat_nodes.get_node_list().size()); + SG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning polys for " << icao << " at " << my_ctime(log_time) ); base_poly = tgPolygon::AddColinearNodes( base_poly, tmp_pvmt_nodes ); base_poly = tgPolygon::Snap( base_poly, gSnap ); - SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly); // Finally find slivers in base slivers.clear(); @@ -728,36 +748,48 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) triangulation_start.stamp(); // tesselate the polygons and prepair them for final output - for ( unsigned int i = 0; i < rwy_polys.size(); ++i ) + if ( rwy_polys.size() ) { - SG_LOG(SG_GENERAL, SG_INFO, "Tesselating runway poly = " << i + 1 << " of " << rwy_polys.size() ); + SG_LOG(SG_GENERAL, SG_INFO, "Tesselating " << rwy_polys.size() << " Runway Polys " ); + for ( unsigned int i = 0; i < rwy_polys.size(); ++i ) + { + SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating runway poly = " << i + 1 << " of " << rwy_polys.size() ); - SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << rwy_polys[i].Contours() << " total points before = " << rwy_polys[i].TotalNodes()); - rwy_polys[i].Tesselate(); - SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << rwy_polys[i].Triangles()); - rwy_polys[i].Texture(); - } - - // tesselate the polygons and prepair them for final output - for ( unsigned int i = 0; i < pvmt_polys.size(); ++i ) - { - SG_LOG(SG_GENERAL, SG_INFO, "Tesselating pavement poly = " << i + 1 << " of " << pvmt_polys.size() ); - - SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << pvmt_polys[i].Contours() << " total points before = " << pvmt_polys[i].TotalNodes()); - pvmt_polys[i].Tesselate(); - SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << pvmt_polys[i].Triangles()); - pvmt_polys[i].Texture(); + SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << rwy_polys[i].Contours() << " total points before = " << rwy_polys[i].TotalNodes()); + rwy_polys[i].Tesselate(); + SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << rwy_polys[i].Triangles()); + rwy_polys[i].Texture(); + } } - // tesselate the polygons and prepair them for final output - for ( unsigned int i = 0; i < line_polys.size(); ++i ) + if ( pvmt_polys.size() ) { - SG_LOG(SG_GENERAL, SG_INFO, "Tesselating line poly = " << i + 1 << " of " << line_polys.size() ); + // tesselate the polygons and prepair them for final output + SG_LOG(SG_GENERAL, SG_INFO, "Tesselating " << pvmt_polys.size() << " Pavement Polys " ); + for ( unsigned int i = 0; i < pvmt_polys.size(); ++i ) + { + SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating pavement poly = " << i + 1 << " of " << pvmt_polys.size() ); - SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << line_polys[i].Contours() << " total points before = " << line_polys[i].TotalNodes()); - line_polys[i].Tesselate(); - SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << line_polys[i].Triangles()); - line_polys[i].Texture(); + SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << pvmt_polys[i].Contours() << " total points before = " << pvmt_polys[i].TotalNodes()); + pvmt_polys[i].Tesselate(); + SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << pvmt_polys[i].Triangles()); + pvmt_polys[i].Texture(); + } + } + + if ( line_polys.size() ) + { + // tesselate the polygons and prepair them for final output + SG_LOG(SG_GENERAL, SG_INFO, "Tesselating " << line_polys.size() << " Linear Feature Polys " ); + for ( unsigned int i = 0; i < line_polys.size(); ++i ) + { + SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating line poly = " << i + 1 << " of " << line_polys.size() ); + + SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << line_polys[i].Contours() << " total points before = " << line_polys[i].TotalNodes()); + line_polys[i].Tesselate(); + SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << line_polys[i].Triangles()); + line_polys[i].Texture(); + } } /* before tessellating the base, make sure there are no @@ -812,7 +844,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) SGVec3d vnt = SGVec3d::fromGeod( base_poly.GetNode(0, 0) ); vnt = normalize(vnt); Point3D vn = Point3D::fromSGVec3(vnt); - SG_LOG(SG_GENERAL, SG_DEBUG, "found normal for this airport = " << vn); SG_LOG(SG_GENERAL, SG_INFO, "Adding runway nodes and normals"); for ( unsigned int k = 0; k < rwy_polys.size(); ++k ) @@ -1065,7 +1096,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) max_deg.setLongitudeDeg( max_deg.getLongitudeDeg() + 0.01 * dlon ); min_deg.setLatitudeDeg( min_deg.getLatitudeDeg() - 0.01 * dlat ); max_deg.setLatitudeDeg( max_deg.getLatitudeDeg() + 0.01 * dlat ); - SG_LOG(SG_GENERAL, SG_INFO, "min = " << min_deg << " max = " << max_deg ); + SG_LOG(SG_GENERAL, SG_DEBUG, "min = " << min_deg << " max = " << max_deg ); SG_LOG(SG_GENERAL, SG_DEBUG, "Create Apt surface:" ); SG_LOG(SG_GENERAL, SG_DEBUG, " root: " << root ); @@ -1428,6 +1459,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) } string holepath = root + "/AirportArea"; + tgPolygon::Chop( divided_base, holepath, "Hole", false, true ); tgPolygon::Chop( apt_clearing, holepath, "Airport", false, false ); diff --git a/src/Airports/GenAirports850/closedpoly.cxx b/src/Airports/GenAirports850/closedpoly.cxx index d614dc34..6a9aece4 100644 --- a/src/Airports/GenAirports850/closedpoly.cxx +++ b/src/Airports/GenAirports850/closedpoly.cxx @@ -444,8 +444,6 @@ int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, st { if ( is_pavement && pre_tess.Contours() ) { - SG_LOG(SG_GENERAL, SG_INFO, "BuildBtg: original poly has " << pre_tess.Contours() << " contours" << " and " << pre_tess.TotalNodes() << " points : shapefile_name is " << shapefile_name ); - if( shapefile_name.size() ) { tgPolygon::ToShapefile( pre_tess, "./airport_dbg", std::string("preclip"), shapefile_name ); tgPolygon::AccumulatorToShapefiles( "./airport_dbg", "accum" ); @@ -484,8 +482,6 @@ int ClosedPoly::BuildBtg( tgPolygon& apt_base, tgPolygon& apt_clearing, std::str // verify the poly has been generated, and the contour isn't a pavement if ( !is_pavement && pre_tess.Contours() ) { - SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.Contours() << " contours"); - base = tgPolygon::Expand( pre_tess, 2.0); safe_base = tgPolygon::Expand( pre_tess, 5.0); diff --git a/src/Airports/GenAirports850/scheduler.cxx b/src/Airports/GenAirports850/scheduler.cxx index 6f1b8cae..e13ef540 100644 --- a/src/Airports/GenAirports850/scheduler.cxx +++ b/src/Airports/GenAirports850/scheduler.cxx @@ -810,7 +810,7 @@ long Scheduler::FindAirport( string icao ) void Scheduler::RetryAirport( AirportInfo* pai ) { - // retryList.push_back( *pai ); + retryList.push_back( *pai ); } bool Scheduler::AddAirports( long start_pos, tg::Rectangle* boundingBox ) diff --git a/src/Lib/Polygon/polygon.cxx b/src/Lib/Polygon/polygon.cxx index 75b8873d..0fce1acc 100644 --- a/src/Lib/Polygon/polygon.cxx +++ b/src/Lib/Polygon/polygon.cxx @@ -1711,6 +1711,12 @@ tg::Rectangle tgContour::GetBoundingBox( void ) const tgPolygon tgContour::DiffWithAccumulator( const tgContour& subject ) { tgPolygon result; + TGTriNodes all_nodes; + + /* before diff - gather all nodes */ + for ( unsigned int i = 0; i < subject.GetSize(); ++i ) { + all_nodes.unique_add( Point3D::fromSGGeod( subject.GetNode(i) )); + } unsigned int num_hits = 0; tg::Rectangle box1 = subject.GetBoundingBox(); @@ -1740,6 +1746,7 @@ tgPolygon tgContour::DiffWithAccumulator( const tgContour& subject ) exit(-1); } result = tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); } else { result.AddContour( subject ); } @@ -1759,6 +1766,12 @@ void tgContour::AddToAccumulator( const tgContour& subject ) tgPolygon tgPolygon::Union( const tgContour& subject, tgPolygon& clip ) { tgPolygon result; + TGTriNodes all_nodes; + + /* before diff - gather all nodes */ + for ( unsigned int i = 0; i < subject.GetSize(); ++i ) { + all_nodes.unique_add( Point3D::fromSGGeod( subject.GetNode(i) )); + } ClipperLib::Polygon clipper_subject = tgContour::ToClipper( subject ); ClipperLib::Polygons clipper_clip = tgPolygon::ToClipper( clip ); @@ -1770,7 +1783,10 @@ tgPolygon tgPolygon::Union( const tgContour& subject, tgPolygon& clip ) c.AddPolygons(clipper_clip, ClipperLib::ptClip); c.Execute(ClipperLib::ctUnion, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); - return tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); + + return result; } tgContour tgContour::AddColinearNodes( const tgContour& subject, TGTriNodes nodes ) @@ -1912,6 +1928,14 @@ tgPolygon tgPolygon::SplitLongEdges( const tgPolygon& subject, double dist ) tgPolygon tgPolygon::StripHoles( const tgPolygon& subject ) { tgPolygon result; + TGTriNodes all_nodes; + + /* before diff - gather all nodes */ + for ( unsigned int i = 0; i < subject.Contours(); ++i ) { + for ( unsigned int j = 0; j < subject.ContourSize( i ); ++j ) { + all_nodes.unique_add( Point3D::fromSGGeod( subject.GetNode(i, j) ) ); + } + } ClipperLib::Polygons clipper_result; ClipperLib::Clipper c; @@ -1926,6 +1950,8 @@ tgPolygon tgPolygon::StripHoles( const tgPolygon& subject ) c.Execute(ClipperLib::ctUnion, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); result = tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); + result.SetMaterial( subject.GetMaterial() ); result.SetTexParams( subject.GetTexParams() ); @@ -1935,11 +1961,21 @@ tgPolygon tgPolygon::StripHoles( const tgPolygon& subject ) tgPolygon tgPolygon::Simplify( const tgPolygon& subject ) { tgPolygon result; + TGTriNodes all_nodes; + + /* before diff - gather all nodes */ + for ( unsigned int i = 0; i < subject.Contours(); ++i ) { + for ( unsigned int j = 0; j < subject.ContourSize( i ); ++j ) { + all_nodes.unique_add( Point3D::fromSGGeod( subject.GetNode(i, j) ) ); + } + } ClipperLib::Polygons clipper_poly = tgPolygon::ToClipper( subject ); SimplifyPolygons( clipper_poly ); result = tgPolygon::FromClipper( clipper_poly ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); + result.SetMaterial( subject.GetMaterial() ); result.SetTexParams( subject.GetTexParams() ); @@ -2007,6 +2043,12 @@ tgPolygon tgPolygon::FromClipper( const ClipperLib::Polygons& subject ) return result; } +bool clipper_dump = false; +void tgPolygon::SetDump( bool dmp ) +{ + clipper_dump = dmp; +} + tgPolygon tgPolygon::Expand( const tgPolygon& subject, double offset ) { ClipperLib::Polygons clipper_src, clipper_dst; @@ -2026,24 +2068,60 @@ tgPolygon tgPolygon::Expand( const tgPolygon& subject, double offset ) tgPolygon tgPolygon::Union( const tgPolygon& subject, tgPolygon& clip ) { - tgPolygon result; + tgPolygon result; + TGTriNodes all_nodes; + std::ofstream dmpfile; + + /* before union - gather all nodes */ + for ( unsigned int i = 0; i < subject.Contours(); ++i ) { + for ( unsigned int j = 0; j < subject.ContourSize( i ); ++j ) { + all_nodes.unique_add( Point3D::fromSGGeod( subject.GetNode(i, j) ) ); + } + } ClipperLib::Polygons clipper_subject = tgPolygon::ToClipper( subject ); ClipperLib::Polygons clipper_clip = tgPolygon::ToClipper( clip ); ClipperLib::Polygons clipper_result; + if ( clipper_dump ) { + dmpfile.open ("subject.txt"); + dmpfile << clipper_subject; + dmpfile.close(); + + dmpfile.open ("clip.txt"); + dmpfile << clipper_clip; + dmpfile.close(); + } + ClipperLib::Clipper c; c.Clear(); c.AddPolygons(clipper_subject, ClipperLib::ptSubject); c.AddPolygons(clipper_clip, ClipperLib::ptClip); c.Execute(ClipperLib::ctUnion, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); - return tgPolygon::FromClipper( clipper_result ); + if ( clipper_dump ) { + dmpfile.open ("result.txt"); + dmpfile << clipper_result; + dmpfile.close(); + } + + result = tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); + + return result; } tgPolygon tgPolygon::Diff( const tgPolygon& subject, tgPolygon& clip ) { tgPolygon result; + TGTriNodes all_nodes; + + /* before diff - gather all nodes */ + for ( unsigned int i = 0; i < subject.Contours(); ++i ) { + for ( unsigned int j = 0; j < subject.ContourSize( i ); ++j ) { + all_nodes.unique_add( Point3D::fromSGGeod( subject.GetNode(i, j) ) ); + } + } ClipperLib::Polygons clipper_subject = tgPolygon::ToClipper( subject ); ClipperLib::Polygons clipper_clip = tgPolygon::ToClipper( clip ); @@ -2055,12 +2133,23 @@ tgPolygon tgPolygon::Diff( const tgPolygon& subject, tgPolygon& clip ) c.AddPolygons(clipper_clip, ClipperLib::ptClip); c.Execute(ClipperLib::ctDifference, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); - return tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); + + return result; } tgPolygon tgPolygon::Intersect( const tgPolygon& subject, const tgPolygon& clip ) { tgPolygon result; + TGTriNodes all_nodes; + + /* before intersect - gather all nodes */ + for ( unsigned int i = 0; i < subject.Contours(); ++i ) { + for ( unsigned int j = 0; j < subject.ContourSize( i ); ++j ) { + all_nodes.unique_add( Point3D::fromSGGeod( subject.GetNode(i, j) ) ); + } + } ClipperLib::Polygons clipper_subject = tgPolygon::ToClipper( subject ); ClipperLib::Polygons clipper_clip = tgPolygon::ToClipper( clip ); @@ -2073,6 +2162,8 @@ tgPolygon tgPolygon::Intersect( const tgPolygon& subject, const tgPolygon& clip c.Execute(ClipperLib::ctIntersection, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); result = tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); + result.SetMaterial( subject.GetMaterial() ); result.SetTexParams( subject.GetTexParams() ); @@ -2125,6 +2216,14 @@ void tgPolygon::AccumulatorToShapefiles( const std::string& path, const std::str tgPolygon tgPolygon::DiffWithAccumulator( const tgPolygon& subject ) { tgPolygon result; + TGTriNodes all_nodes; + + /* before diff - gather all nodes */ + for ( unsigned int i = 0; i < subject.Contours(); ++i ) { + for ( unsigned int j = 0; j < subject.ContourSize( i ); ++j ) { + all_nodes.unique_add( Point3D::fromSGGeod( subject.GetNode(i, j) ) ); + } + } unsigned int num_hits = 0; tg::Rectangle box1 = subject.GetBoundingBox(); @@ -2153,10 +2252,9 @@ tgPolygon tgPolygon::DiffWithAccumulator( const tgPolygon& subject ) SG_LOG(SG_GENERAL, SG_ALERT, "Diff With Accumulator returned FALSE" ); exit(-1); } - SG_LOG(SG_GENERAL, SG_ALERT, "Diff With Accumulator had " << num_hits << " hits " ); - SG_LOG(SG_GENERAL, SG_ALERT, " cklipper_result has " << clipper_result.size() << " contours " ); - + result = tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); // Make sure we keep texturing info result.SetMaterial( subject.GetMaterial() ); @@ -2222,7 +2320,7 @@ void tgPolygon::RemoveSlivers( tgPolygon& subject, tgcontour_list& slivers ) // And add it to the slive list if it isn't a hole if ( !contour.GetHole() ) { // move sliver contour to sliver list - SG_LOG(SG_GENERAL, SG_INFO, " Found SLIVER!"); + SG_LOG(SG_GENERAL, SG_DEBUG, " Found SLIVER!"); slivers.push_back( contour ); } @@ -2567,7 +2665,7 @@ static void ClipToFile( const tgPolygon& subject, std::string root, SG_LOG(SG_GENERAL, SG_DEBUG, " hole = " << subject.GetContour(ii).GetHole() ); } - result = tgPolygon::Intersect( base, subject ); + result = tgPolygon::Intersect( subject, base ); SG_LOG(SG_GENERAL, SG_DEBUG, "result contours = " << result.Contours() ); for ( unsigned int ii = 0; ii < result.Contours(); ii++ ) { diff --git a/src/Lib/Polygon/polygon.hxx b/src/Lib/Polygon/polygon.hxx index aeefe8af..92a29258 100644 --- a/src/Lib/Polygon/polygon.hxx +++ b/src/Lib/Polygon/polygon.hxx @@ -588,6 +588,7 @@ public: // TODO : Both should be constant // what we really need is multiple accumulators // init_accumulator should return a handle... + static void SetDump( bool dmp ); static tgPolygon Union( const tgContour& subject, tgPolygon& clip ); static tgPolygon Union( const tgPolygon& subject, tgPolygon& clip ); static tgPolygon Diff( const tgPolygon& subject, tgPolygon& clip );