diff --git a/src/Airports/GenAirports850/airport.cxx b/src/Airports/GenAirports850/airport.cxx index e59b7b17..9c5d2dcf 100644 --- a/src/Airports/GenAirports850/airport.cxx +++ b/src/Airports/GenAirports850/airport.cxx @@ -285,7 +285,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src ) // Add the linear features if (features.size()) { - tgAccumulator lf_accum; + tgAccumulator lf_accum(icao); TG_LOG(SG_GENERAL, SG_INFO, "Build " << features.size() << " Linear Feature Polys"); for ( unsigned int i=0; i #include #include +#include #include @@ -12,6 +13,8 @@ tgPolygon tgAccumulator::Diff( const tgContour& subject ) { tgPolygon result; UniqueSGGeodSet all_nodes; + bool done = false; + unsigned int max_hits = UINT_MAX; /* before diff - gather all nodes */ for ( unsigned int i = 0; i < subject.GetSize(); ++i ) { @@ -28,31 +31,42 @@ tgPolygon tgAccumulator::Diff( const tgContour& subject ) ClipperLib::Path clipper_subject = tgContour::ToClipper( subject ); ClipperLib::Paths clipper_result; - ClipperLib::Clipper c; - c.Clear(); + while ( !done && max_hits > 0 ) { + ClipperLib::Clipper c; + c.Clear(); - c.AddPath(clipper_subject, ClipperLib::ptSubject, true); + c.AddPath(clipper_subject, ClipperLib::ptSubject, true); - // clip result against all polygons in the accum that intersect our bb - for (unsigned int i=0; i < accum.size(); i++) { - tgRectangle box2 = BoundingBox_FromClipper( accum[i] ); + // clip result against all polygons in the accum that intersect our bb + for (unsigned int i=0; i < accum.size(); i++) { + tgRectangle box2 = BoundingBox_FromClipper( accum[i] ); - if ( box2.intersects(box1) ) - { - c.AddPaths(accum[i], ClipperLib::ptClip, true); - num_hits++; + if ( box2.intersects(box1) ) + { + if ( num_hits < max_hits ) { + c.AddPaths(accum[i], ClipperLib::ptClip, true); + num_hits++; + } + } } - } - if (num_hits) { - if ( !c.Execute(ClipperLib::ctDifference, clipper_result, ClipperLib::pftNonZero, ClipperLib::pftNonZero) ) { - SG_LOG(SG_GENERAL, SG_ALERT, "Diff With Accumulator returned FALSE" ); - exit(-1); + if (num_hits) { + if ( !c.Execute(ClipperLib::ctDifference, clipper_result, ClipperLib::pftNonZero, ClipperLib::pftNonZero) ) { + SG_LOG(SG_GENERAL, SG_ALERT, "Diff With Accumulator returned FALSE - reducing accumulator" ); + max_hits = num_hits-1; + + FILE* fp = fopen( "./accumulator_fail.log", "a" ); + fprintf( fp, "%s : reduce from %d to %d\n", debugstr.c_str(), num_hits, max_hits ); + fclose(fp); + } else { + result = tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); + done = true; + } + } else { + result.AddContour( subject ); + done = true; } - result = tgPolygon::FromClipper( clipper_result ); - result = tgPolygon::AddColinearNodes( result, all_nodes ); - } else { - result.AddContour( subject ); } return result; @@ -62,6 +76,8 @@ tgPolygon tgAccumulator::Diff( const tgPolygon& subject ) { tgPolygon result; UniqueSGGeodSet all_nodes; + bool done = false; + unsigned int max_hits = UINT_MAX; /* before diff - gather all nodes */ for ( unsigned int i = 0; i < subject.Contours(); ++i ) { @@ -80,36 +96,44 @@ tgPolygon tgAccumulator::Diff( const tgPolygon& subject ) ClipperLib::Paths clipper_subject = tgPolygon::ToClipper( subject ); ClipperLib::Paths clipper_result; - ClipperLib::Clipper c; - c.Clear(); + while ( !done && max_hits > 0 ) { + ClipperLib::Clipper c; + c.Clear(); - c.AddPaths(clipper_subject, ClipperLib::ptSubject, true); + c.AddPaths(clipper_subject, ClipperLib::ptSubject, true); - // clip result against all polygons in the accum that intersect our bb - for (unsigned int i=0; i < accum.size(); i++) { - tgRectangle box2 = BoundingBox_FromClipper( accum[i] ); + // clip result against all polygons in the accum that intersect our bb + for (unsigned int i=0; i < accum.size(); i++) { + tgRectangle box2 = BoundingBox_FromClipper( accum[i] ); - if ( box2.intersects(box1) ) - { - c.AddPaths(accum[i], ClipperLib::ptClip, true); - num_hits++; - } - } - - if (num_hits) { - if ( !c.Execute(ClipperLib::ctDifference, clipper_result, ClipperLib::pftNonZero, ClipperLib::pftNonZero) ) { - SG_LOG(SG_GENERAL, SG_ALERT, "Diff With Accumulator returned FALSE" ); - exit(-1); + if ( box2.intersects(box1) ) + { + c.AddPaths(accum[i], ClipperLib::ptClip, true); + num_hits++; + } } - result = tgPolygon::FromClipper( clipper_result ); - result = tgPolygon::AddColinearNodes( result, all_nodes ); + if (num_hits) { + if ( !c.Execute(ClipperLib::ctDifference, clipper_result, ClipperLib::pftNonZero, ClipperLib::pftNonZero) ) { + SG_LOG(SG_GENERAL, SG_ALERT, "Diff With Accumulator returned FALSE - reducing accumulator" ); + max_hits = num_hits-1; - // Make sure we keep texturing info - result.SetMaterial( subject.GetMaterial() ); - result.SetTexParams( subject.GetTexParams() ); - } else { - result = subject; + FILE* fp = fopen( "./accumulator_fail.log", "a" ); + fprintf( fp, "%s : reduce from %d to %d\n", debugstr.c_str(), num_hits, max_hits ); + fclose(fp); + } else { + result = tgPolygon::FromClipper( clipper_result ); + result = tgPolygon::AddColinearNodes( result, all_nodes ); + + // Make sure we keep texturing info + result.SetMaterial( subject.GetMaterial() ); + result.SetTexParams( subject.GetTexParams() ); + done = true; + } + } else { + result = subject; + done = true; + } } return result; diff --git a/src/Lib/terragear/tg_accumulator.hxx b/src/Lib/terragear/tg_accumulator.hxx index 3b4b4eba..fa38b75e 100644 --- a/src/Lib/terragear/tg_accumulator.hxx +++ b/src/Lib/terragear/tg_accumulator.hxx @@ -8,6 +8,8 @@ class tgAccumulator { public: + tgAccumulator( const std::string& d ) : debugstr(d) {} + tgPolygon Diff( const tgContour& subject ); tgPolygon Diff( const tgPolygon& subject ); @@ -22,6 +24,7 @@ private: clipper_polygons_list accum; UniqueSGGeodSet nodes; + std::string debugstr; }; #endif // _TGACCUMULATOR_HXX \ No newline at end of file diff --git a/src/Lib/terragear/tg_contour.cxx b/src/Lib/terragear/tg_contour.cxx index 2a006078..f5d22974 100644 --- a/src/Lib/terragear/tg_contour.cxx +++ b/src/Lib/terragear/tg_contour.cxx @@ -924,7 +924,7 @@ tgpolygon_list tgContour::ExpandToPolygons( const tgContour& subject, double wid tgContour expanded; tgPolygon segment; - tgAccumulator accum; + tgAccumulator accum("ExpandToPolygons"); tgpolygon_list result; // generate poly and texparam lists for each line segment