1
0
Fork 0

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.
This commit is contained in:
Peter Sadrozinski 2012-11-17 11:26:13 -05:00
parent 1c38c3e455
commit b013ad6b7b
5 changed files with 242 additions and 115 deletions

View file

@ -37,6 +37,15 @@
string SGLOG_GREEN = "\033[0;32m"; string SGLOG_GREEN = "\033[0;32m";
string SGLOG_NORMAL = "\033[0m"; 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) Airport::Airport( int c, char* def)
{ {
int numParams; int numParams;
@ -356,27 +365,31 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
if (features.size()) if (features.size())
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build " << features.size() << " Linear Feature Polys");
for ( unsigned int i=0; i<features.size(); i++ ) for ( unsigned int i=0; i<features.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build Feature Poly " << i + 1 << " of " << features.size() << " : " << features[i]->GetDescription() ); 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 ); 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 */ /* Done with the linear features accumulator */
tgPolygonFreeClipperAccumulator(); tgPolygonFreeClipperAccumulator();
log_time = time(0); /* Initialize a new accumulator for the other objects */
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Linear Features for " << icao << " at " << ctime(&log_time) );
// Initialize a new accumulator for the other objects
tgPolygonInitClipperAccumulator(); tgPolygonInitClipperAccumulator();
// Build runways next // Build runways next
if (runways.size())
{
SG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Runway Polys");
for ( unsigned int i=0; i<runways.size(); i++ ) for ( unsigned int i=0; i<runways.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build Runway " << i + 1 << " of " << runways.size()); SG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway " << i + 1 << " of " << runways.size());
slivers.clear(); slivers.clear();
if ( isDebugRunway(i) ) { if ( isDebugRunway(i) ) {
@ -400,13 +413,15 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
} }
log_time = time(0); log_time = time(0);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building runways for " << icao << " at " << ctime(&log_time) ); SG_LOG( SG_GENERAL, SG_ALERT, "Finished building runways for " << icao << " at " << my_ctime(log_time) );
}
if (lightobjects.size()) if (lightobjects.size())
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build " << lightobjects.size() << " Light Objects ");
for ( unsigned int i=0; i<lightobjects.size(); i++ ) for ( unsigned int i=0; i<lightobjects.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build runway light " << i + 1 << " of " << lightobjects.size()); SG_LOG(SG_GENERAL, SG_DEBUG, "Build runway light " << i + 1 << " of " << lightobjects.size());
lightobjects[i]->BuildBtg( rwy_lights ); lightobjects[i]->BuildBtg( 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) // Build helipads (use runway poly- and texture list for this)
if (helipads.size()) if (helipads.size())
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build " << helipads.size() << " Helipad Polys ");
for ( unsigned int i=0; i<helipads.size(); i++ ) for ( unsigned int i=0; i<helipads.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build helipad " << i + 1 << " of " << helipads.size()); SG_LOG(SG_GENERAL, SG_DEBUG, "Build helipad " << i + 1 << " of " << helipads.size());
slivers.clear(); slivers.clear();
if (boundary.size()) if (boundary.size())
@ -436,9 +452,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// Build the pavements // Build the pavements
if (pavements.size()) if (pavements.size())
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build " << pavements.size() << " Pavement Polys ");
for ( unsigned int i=0; i<pavements.size(); i++ ) for ( unsigned int i=0; i<pavements.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build Pavement " << i + 1 << " of " << pavements.size() << " : " << pavements[i]->GetDescription()); SG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i + 1 << " of " << pavements.size() << " : " << pavements[i]->GetDescription());
slivers.clear(); slivers.clear();
if ( isDebugPavement(i) ) { 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( rwy_polys, slivers );
tgPolygon::MergeSlivers( pvmt_polys, slivers ); tgPolygon::MergeSlivers( pvmt_polys, slivers );
} }
}
log_time = time(0); log_time = time(0);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Pavements for " << icao << " at " << ctime(&log_time) ); SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Pavements for " << icao << " at " << my_ctime(log_time) );
}
// Build the legacy taxiways // Build the legacy taxiways
if (taxiways.size()) if (taxiways.size())
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build " << taxiways.size() << " Taxiway Polys ");
for ( unsigned int i=0; i<taxiways.size(); i++ ) for ( unsigned int i=0; i<taxiways.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build Taxiway " << i + 1 << " of " << taxiways.size()); SG_LOG(SG_GENERAL, SG_DEBUG, "Build Taxiway " << i + 1 << " of " << taxiways.size());
slivers.clear(); slivers.clear();
if ( isDebugTaxiway(i) ) { if ( isDebugTaxiway(i) ) {
@ -497,9 +515,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
} }
// Build runway shoulders here // Build runway shoulders here
if ( runways.size() )
{
SG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Runway Shoulder Polys ");
for ( unsigned int i=0; i<runways.size(); i++ ) for ( unsigned int i=0; i<runways.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build Runway shoulder " << i + 1 << " of " << runways.size()); SG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway shoulder " << i + 1 << " of " << runways.size());
if ( runways[i]->GetsShoulder() ) if ( runways[i]->GetsShoulder() )
{ {
@ -519,11 +540,15 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
tgPolygon::MergeSlivers( pvmt_polys, slivers ); tgPolygon::MergeSlivers( pvmt_polys, slivers );
} }
} }
}
// Build helipad shoulders here // Build helipad shoulders here
if ( helipads.size() )
{
SG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Helipad Shoulder Polys ");
for ( unsigned int i=0; i<helipads.size(); i++ ) for ( unsigned int i=0; i<helipads.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build Helipad shoulder " << i + 1 << " of " << helipads.size()); SG_LOG(SG_GENERAL, SG_DEBUG, "Build Helipad shoulder " << i + 1 << " of " << helipads.size());
if ( helipads[i]->GetsShoulder() ) if ( helipads[i]->GetsShoulder() )
{ {
@ -543,15 +568,17 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
tgPolygon::MergeSlivers( pvmt_polys, slivers ); tgPolygon::MergeSlivers( pvmt_polys, slivers );
} }
} }
}
// build the base and clearing if there's a boundary // build the base and clearing if there's a boundary
if (boundary.size()) if (boundary.size())
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build " << boundary.size() << " Boundary Polys ");
shapefile = ""; shapefile = "";
for ( unsigned int i=0; i<boundary.size(); i++ ) for ( unsigned int i=0; i<boundary.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Build Userdefined boundary " << i + 1 << " of " << boundary.size()); SG_LOG(SG_GENERAL, SG_DEBUG, "Build Userdefined boundary " << i + 1 << " of " << boundary.size());
boundary[i]->BuildBtg( apt_base, apt_clearing, shapefile ); boundary[i]->BuildBtg( 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... // build temporary node list from runways...
SG_LOG(SG_GENERAL, SG_INFO, "Build Node List " ); SG_LOG(SG_GENERAL, SG_INFO, "Build Node List " );
for ( unsigned int k = 0; k < rwy_polys.size(); ++k ) for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
{ {
tgPolygon poly = rwy_polys[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); 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 // second pass : runways
for ( unsigned int k = 0; k < rwy_polys.size(); ++k ) 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); 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 ) 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); log_time = time(0);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning polys for " << icao << " at " << ctime(&log_time) ); SG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning polys for " << icao << " at " << my_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());
base_poly = tgPolygon::AddColinearNodes( base_poly, tmp_pvmt_nodes ); base_poly = tgPolygon::AddColinearNodes( base_poly, tmp_pvmt_nodes );
base_poly = tgPolygon::Snap( base_poly, gSnap ); base_poly = tgPolygon::Snap( base_poly, gSnap );
SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly);
// Finally find slivers in base // Finally find slivers in base
slivers.clear(); slivers.clear();
@ -728,37 +748,49 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
triangulation_start.stamp(); triangulation_start.stamp();
// tesselate the polygons and prepair them for final output // tesselate the polygons and prepair them for final output
if ( 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 ) for ( unsigned int i = 0; i < rwy_polys.size(); ++i )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating runway poly = " << i + 1 << " of " << rwy_polys.size() ); 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()); SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << rwy_polys[i].Contours() << " total points before = " << rwy_polys[i].TotalNodes());
rwy_polys[i].Tesselate(); rwy_polys[i].Tesselate();
SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << rwy_polys[i].Triangles()); SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << rwy_polys[i].Triangles());
rwy_polys[i].Texture(); rwy_polys[i].Texture();
} }
}
if ( pvmt_polys.size() )
{
// tesselate the polygons and prepair them for final output // 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 ) 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, "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()); SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << pvmt_polys[i].Contours() << " total points before = " << pvmt_polys[i].TotalNodes());
pvmt_polys[i].Tesselate(); pvmt_polys[i].Tesselate();
SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << pvmt_polys[i].Triangles()); SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << pvmt_polys[i].Triangles());
pvmt_polys[i].Texture(); pvmt_polys[i].Texture();
} }
}
if ( line_polys.size() )
{
// tesselate the polygons and prepair them for final output // 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 ) for ( unsigned int i = 0; i < line_polys.size(); ++i )
{ {
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating line poly = " << i + 1 << " of " << line_polys.size() ); 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()); SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << line_polys[i].Contours() << " total points before = " << line_polys[i].TotalNodes());
line_polys[i].Tesselate(); line_polys[i].Tesselate();
SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << line_polys[i].Triangles()); SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << line_polys[i].Triangles());
line_polys[i].Texture(); line_polys[i].Texture();
} }
}
/* before tessellating the base, make sure there are no /* before tessellating the base, make sure there are no
intersecting contours */ intersecting contours */
@ -812,7 +844,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SGVec3d vnt = SGVec3d::fromGeod( base_poly.GetNode(0, 0) ); SGVec3d vnt = SGVec3d::fromGeod( base_poly.GetNode(0, 0) );
vnt = normalize(vnt); vnt = normalize(vnt);
Point3D vn = Point3D::fromSGVec3(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"); SG_LOG(SG_GENERAL, SG_INFO, "Adding runway nodes and normals");
for ( unsigned int k = 0; k < rwy_polys.size(); ++k ) 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 ); max_deg.setLongitudeDeg( max_deg.getLongitudeDeg() + 0.01 * dlon );
min_deg.setLatitudeDeg( min_deg.getLatitudeDeg() - 0.01 * dlat ); min_deg.setLatitudeDeg( min_deg.getLatitudeDeg() - 0.01 * dlat );
max_deg.setLatitudeDeg( max_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, "Create Apt surface:" );
SG_LOG(SG_GENERAL, SG_DEBUG, " root: " << root ); 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"; string holepath = root + "/AirportArea";
tgPolygon::Chop( divided_base, holepath, "Hole", false, true ); tgPolygon::Chop( divided_base, holepath, "Hole", false, true );
tgPolygon::Chop( apt_clearing, holepath, "Airport", false, false ); tgPolygon::Chop( apt_clearing, holepath, "Airport", false, false );

View file

@ -444,8 +444,6 @@ int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, st
{ {
if ( is_pavement && pre_tess.Contours() ) 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() ) { if( shapefile_name.size() ) {
tgPolygon::ToShapefile( pre_tess, "./airport_dbg", std::string("preclip"), shapefile_name ); tgPolygon::ToShapefile( pre_tess, "./airport_dbg", std::string("preclip"), shapefile_name );
tgPolygon::AccumulatorToShapefiles( "./airport_dbg", "accum" ); 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 // verify the poly has been generated, and the contour isn't a pavement
if ( !is_pavement && pre_tess.Contours() ) 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); base = tgPolygon::Expand( pre_tess, 2.0);
safe_base = tgPolygon::Expand( pre_tess, 5.0); safe_base = tgPolygon::Expand( pre_tess, 5.0);

View file

@ -810,7 +810,7 @@ long Scheduler::FindAirport( string icao )
void Scheduler::RetryAirport( AirportInfo* pai ) void Scheduler::RetryAirport( AirportInfo* pai )
{ {
// retryList.push_back( *pai ); retryList.push_back( *pai );
} }
bool Scheduler::AddAirports( long start_pos, tg::Rectangle* boundingBox ) bool Scheduler::AddAirports( long start_pos, tg::Rectangle* boundingBox )

View file

@ -1711,6 +1711,12 @@ tg::Rectangle tgContour::GetBoundingBox( void ) const
tgPolygon tgContour::DiffWithAccumulator( const tgContour& subject ) tgPolygon tgContour::DiffWithAccumulator( const tgContour& subject )
{ {
tgPolygon result; 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; unsigned int num_hits = 0;
tg::Rectangle box1 = subject.GetBoundingBox(); tg::Rectangle box1 = subject.GetBoundingBox();
@ -1740,6 +1746,7 @@ tgPolygon tgContour::DiffWithAccumulator( const tgContour& subject )
exit(-1); exit(-1);
} }
result = tgPolygon::FromClipper( clipper_result ); result = tgPolygon::FromClipper( clipper_result );
result = tgPolygon::AddColinearNodes( result, all_nodes );
} else { } else {
result.AddContour( subject ); result.AddContour( subject );
} }
@ -1759,6 +1766,12 @@ void tgContour::AddToAccumulator( const tgContour& subject )
tgPolygon tgPolygon::Union( const tgContour& subject, tgPolygon& clip ) tgPolygon tgPolygon::Union( const tgContour& subject, tgPolygon& clip )
{ {
tgPolygon result; 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::Polygon clipper_subject = tgContour::ToClipper( subject );
ClipperLib::Polygons clipper_clip = tgPolygon::ToClipper( clip ); 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.AddPolygons(clipper_clip, ClipperLib::ptClip);
c.Execute(ClipperLib::ctUnion, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); 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 ) 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 tgPolygon::StripHoles( const tgPolygon& subject )
{ {
tgPolygon result; 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::Polygons clipper_result;
ClipperLib::Clipper c; ClipperLib::Clipper c;
@ -1926,6 +1950,8 @@ tgPolygon tgPolygon::StripHoles( const tgPolygon& subject )
c.Execute(ClipperLib::ctUnion, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); c.Execute(ClipperLib::ctUnion, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
result = tgPolygon::FromClipper( clipper_result ); result = tgPolygon::FromClipper( clipper_result );
result = tgPolygon::AddColinearNodes( result, all_nodes );
result.SetMaterial( subject.GetMaterial() ); result.SetMaterial( subject.GetMaterial() );
result.SetTexParams( subject.GetTexParams() ); result.SetTexParams( subject.GetTexParams() );
@ -1935,11 +1961,21 @@ tgPolygon tgPolygon::StripHoles( const tgPolygon& subject )
tgPolygon tgPolygon::Simplify( const tgPolygon& subject ) tgPolygon tgPolygon::Simplify( const tgPolygon& subject )
{ {
tgPolygon result; 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 ); ClipperLib::Polygons clipper_poly = tgPolygon::ToClipper( subject );
SimplifyPolygons( clipper_poly ); SimplifyPolygons( clipper_poly );
result = tgPolygon::FromClipper( clipper_poly ); result = tgPolygon::FromClipper( clipper_poly );
result = tgPolygon::AddColinearNodes( result, all_nodes );
result.SetMaterial( subject.GetMaterial() ); result.SetMaterial( subject.GetMaterial() );
result.SetTexParams( subject.GetTexParams() ); result.SetTexParams( subject.GetTexParams() );
@ -2007,6 +2043,12 @@ tgPolygon tgPolygon::FromClipper( const ClipperLib::Polygons& subject )
return result; return result;
} }
bool clipper_dump = false;
void tgPolygon::SetDump( bool dmp )
{
clipper_dump = dmp;
}
tgPolygon tgPolygon::Expand( const tgPolygon& subject, double offset ) tgPolygon tgPolygon::Expand( const tgPolygon& subject, double offset )
{ {
ClipperLib::Polygons clipper_src, clipper_dst; ClipperLib::Polygons clipper_src, clipper_dst;
@ -2027,23 +2069,59 @@ tgPolygon tgPolygon::Expand( const tgPolygon& subject, double offset )
tgPolygon tgPolygon::Union( const tgPolygon& subject, tgPolygon& clip ) 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_subject = tgPolygon::ToClipper( subject );
ClipperLib::Polygons clipper_clip = tgPolygon::ToClipper( clip ); ClipperLib::Polygons clipper_clip = tgPolygon::ToClipper( clip );
ClipperLib::Polygons clipper_result; 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; ClipperLib::Clipper c;
c.Clear(); c.Clear();
c.AddPolygons(clipper_subject, ClipperLib::ptSubject); c.AddPolygons(clipper_subject, ClipperLib::ptSubject);
c.AddPolygons(clipper_clip, ClipperLib::ptClip); c.AddPolygons(clipper_clip, ClipperLib::ptClip);
c.Execute(ClipperLib::ctUnion, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); 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 tgPolygon::Diff( const tgPolygon& subject, tgPolygon& clip )
{ {
tgPolygon result; 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_subject = tgPolygon::ToClipper( subject );
ClipperLib::Polygons clipper_clip = tgPolygon::ToClipper( clip ); 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.AddPolygons(clipper_clip, ClipperLib::ptClip);
c.Execute(ClipperLib::ctDifference, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); 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 tgPolygon::Intersect( const tgPolygon& subject, const tgPolygon& clip )
{ {
tgPolygon result; 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_subject = tgPolygon::ToClipper( subject );
ClipperLib::Polygons clipper_clip = tgPolygon::ToClipper( clip ); 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); c.Execute(ClipperLib::ctIntersection, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
result = tgPolygon::FromClipper( clipper_result ); result = tgPolygon::FromClipper( clipper_result );
result = tgPolygon::AddColinearNodes( result, all_nodes );
result.SetMaterial( subject.GetMaterial() ); result.SetMaterial( subject.GetMaterial() );
result.SetTexParams( subject.GetTexParams() ); 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 tgPolygon::DiffWithAccumulator( const tgPolygon& subject )
{ {
tgPolygon result; 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; unsigned int num_hits = 0;
tg::Rectangle box1 = subject.GetBoundingBox(); 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" ); SG_LOG(SG_GENERAL, SG_ALERT, "Diff With Accumulator returned FALSE" );
exit(-1); 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::FromClipper( clipper_result );
result = tgPolygon::AddColinearNodes( result, all_nodes );
// Make sure we keep texturing info // Make sure we keep texturing info
result.SetMaterial( subject.GetMaterial() ); 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 // And add it to the slive list if it isn't a hole
if ( !contour.GetHole() ) { if ( !contour.GetHole() ) {
// move sliver contour to sliver list // 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 ); 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() ); 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() ); SG_LOG(SG_GENERAL, SG_DEBUG, "result contours = " << result.Contours() );
for ( unsigned int ii = 0; ii < result.Contours(); ii++ ) { for ( unsigned int ii = 0; ii < result.Contours(); ii++ ) {

View file

@ -588,6 +588,7 @@ public:
// TODO : Both should be constant // TODO : Both should be constant
// what we really need is multiple accumulators // what we really need is multiple accumulators
// init_accumulator should return a handle... // init_accumulator should return a handle...
static void SetDump( bool dmp );
static tgPolygon Union( const tgContour& subject, tgPolygon& clip ); static tgPolygon Union( const tgContour& subject, tgPolygon& clip );
static tgPolygon Union( const tgPolygon& subject, tgPolygon& clip ); static tgPolygon Union( const tgPolygon& subject, tgPolygon& clip );
static tgPolygon Diff( const tgPolygon& subject, tgPolygon& clip ); static tgPolygon Diff( const tgPolygon& subject, tgPolygon& clip );