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:
parent
1c38c3e455
commit
b013ad6b7b
5 changed files with 242 additions and 115 deletions
|
@ -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,27 +365,31 @@ 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; 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 );
|
||||
}
|
||||
|
||||
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
|
||||
if (runways.size())
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build " << runways.size() << " Runway Polys");
|
||||
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();
|
||||
|
||||
if ( isDebugRunway(i) ) {
|
||||
|
@ -400,13 +413,15 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
}
|
||||
|
||||
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())
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build " << lightobjects.size() << " Light Objects ");
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
@ -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; 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();
|
||||
|
||||
if (boundary.size())
|
||||
|
@ -436,9 +452,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
// Build the pavements
|
||||
if (pavements.size())
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build " << pavements.size() << " Pavement Polys ");
|
||||
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();
|
||||
|
||||
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) );
|
||||
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; 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();
|
||||
|
||||
if ( isDebugTaxiway(i) ) {
|
||||
|
@ -497,9 +515,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
}
|
||||
|
||||
// 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++ )
|
||||
{
|
||||
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() )
|
||||
{
|
||||
|
@ -519,11 +540,15 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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++ )
|
||||
{
|
||||
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() )
|
||||
{
|
||||
|
@ -543,15 +568,17 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
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; 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 );
|
||||
}
|
||||
}
|
||||
|
@ -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,37 +748,49 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
triangulation_start.stamp();
|
||||
|
||||
// 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 )
|
||||
{
|
||||
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());
|
||||
rwy_polys[i].Tesselate();
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << rwy_polys[i].Triangles());
|
||||
rwy_polys[i].Texture();
|
||||
}
|
||||
}
|
||||
|
||||
if ( pvmt_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_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());
|
||||
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_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());
|
||||
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
|
||||
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) );
|
||||
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 );
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
@ -2027,23 +2069,59 @@ tgPolygon tgPolygon::Expand( const tgPolygon& subject, double offset )
|
|||
tgPolygon tgPolygon::Union( const tgPolygon& subject, tgPolygon& clip )
|
||||
{
|
||||
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++ ) {
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in a new issue