1
0
Fork 0

[closedpoly] Maintenance

This commit is contained in:
scttgs0 2023-05-14 02:46:13 -05:00
parent a077dbe97a
commit 34ea056c5d
2 changed files with 179 additions and 234 deletions

View file

@ -1,28 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <terragear/tg_polygon.hxx> #include <terragear/tg_polygon.hxx>
#include <terragear/tg_shapefile.hxx> #include <terragear/tg_shapefile.hxx>
#include "global.hxx"
#include "beznode.hxx" #include "beznode.hxx"
#include "closedpoly.hxx" #include "closedpoly.hxx"
#include "global.hxx"
#define NO_BEZIER (0) #define NO_BEZIER (0)
static void stringPurifier( std::string& s ) static void stringPurifier(std::string& s)
{ {
for ( std::string::iterator it = s.begin(), itEnd = s.end(); it!=itEnd; ++it) { for (std::string::iterator it = s.begin(), itEnd = s.end(); it != itEnd; ++it) {
if ( static_cast<unsigned int>(*it) < 32 || static_cast<unsigned int>(*it) > 127 ) { if (static_cast<unsigned int>(*it) < 32 || static_cast<unsigned int>(*it) > 127) {
(*it) = ' '; (*it) = ' ';
} }
} }
} }
ClosedPoly::ClosedPoly( char* desc ) : ClosedPoly::ClosedPoly(char* desc) : is_pavement(false),
is_pavement(false),
is_border(false), is_border(false),
has_feature(false), has_feature(false),
surface_type(0), surface_type(0),
@ -38,8 +34,7 @@ ClosedPoly::ClosedPoly( char* desc ) :
cur_contour.clear(); cur_contour.clear();
} }
ClosedPoly::ClosedPoly( int st, float s, float th, char* desc ) : ClosedPoly::ClosedPoly(int st, float s, float th, char* desc) : ClosedPoly(desc)
ClosedPoly( desc )
{ {
surface_type = st; surface_type = st;
smoothness = s; smoothness = s;
@ -52,27 +47,24 @@ ClosedPoly::ClosedPoly( int st, float s, float th, char* desc ) :
ClosedPoly::~ClosedPoly() ClosedPoly::~ClosedPoly()
{ {
TG_LOG( SG_GENERAL, SG_DEBUG, "Deleting ClosedPoly " << description ); TG_LOG(SG_GENERAL, SG_DEBUG, "Deleting ClosedPoly " << description);
} }
void ClosedPoly::AddNode( std::shared_ptr<BezNode> node ) void ClosedPoly::AddNode(std::shared_ptr<BezNode> node)
{ {
cur_contour.push_back( node ); using namespace std::string_literals;
TG_LOG(SG_GENERAL, SG_DEBUG, "CLOSEDPOLY::ADDNODE : " << node->GetLoc() ); cur_contour.push_back(node);
TG_LOG(SG_GENERAL, SG_DEBUG, "CLOSEDPOLY::ADDNODE : " << node->GetLoc());
// For pavement polys, add a linear feature for each contour // For pavement polys, add a linear feature for each contour
if (has_feature) if (has_feature) {
{ if (!cur_feature) {
if (!cur_feature) std::string feature_desc = description + " - "s;
{ if (boundary.size() == 0) {
std::string feature_desc = description + " - ";
if (boundary.size() == 0)
{
feature_desc += "hole"; feature_desc += "hole";
} } else {
else
{
feature_desc += "boundary"; feature_desc += "boundary";
} }
@ -80,7 +72,7 @@ void ClosedPoly::AddNode( std::shared_ptr<BezNode> node )
TG_LOG(SG_GENERAL, SG_DEBUG, " Adding node " << node->GetLoc() << " to current linear feature " << cur_feature); TG_LOG(SG_GENERAL, SG_DEBUG, " Adding node " << node->GetLoc() << " to current linear feature " << cur_feature);
} }
cur_feature->AddNode( node ); cur_feature->AddNode(node);
} }
} }
@ -90,10 +82,10 @@ void ClosedPoly::CloseCurContour()
// if we are recording a pavement marking - it must be closed - // if we are recording a pavement marking - it must be closed -
// add the first node of the poly // add the first node of the poly
if (cur_feature) if (cur_feature) {
{
TG_LOG(SG_GENERAL, SG_DEBUG, "We still have an active linear feature - add the first node to close it"); TG_LOG(SG_GENERAL, SG_DEBUG, "We still have an active linear feature - add the first node to close it");
cur_feature->Finish(true, features.size() );
cur_feature->Finish(true, features.size());
features.push_back(cur_feature); features.push_back(cur_feature);
cur_feature.reset(); cur_feature.reset();
@ -102,23 +94,20 @@ void ClosedPoly::CloseCurContour()
// add the contour to the poly - first one is the outer boundary // add the contour to the poly - first one is the outer boundary
// subsequent contours are holes // subsequent contours are holes
if ( boundary.size() == 0 ) if (boundary.size() == 0) {
{
boundary = cur_contour; boundary = cur_contour;
// generate the convex hull from the bezcontour node locations // generate the convex hull from the bezcontour node locations
// CreateConvexHull(); // CreateConvexHull();
cur_contour.clear(); cur_contour.clear();
} } else {
else holes.push_back(cur_contour);
{
holes.push_back( cur_contour );
cur_contour.clear(); cur_contour.clear();
} }
} }
void ClosedPoly::ConvertContour( const BezContour& src, tgContour& dst ) void ClosedPoly::ConvertContour(const BezContour& src, tgContour& dst)
{ {
std::shared_ptr<BezNode> curNode; std::shared_ptr<BezNode> curNode;
std::shared_ptr<BezNode> nextNode; std::shared_ptr<BezNode> nextNode;
@ -138,90 +127,66 @@ void ClosedPoly::ConvertContour( const BezContour& src, tgContour& dst )
dst.Erase(); dst.Erase();
// iterate through each bezier node in the contour // iterate through each bezier node in the contour
for (unsigned int i = 0; i < src.size(); ++i) for (unsigned int i = 0; i < src.size(); ++i) {
{
TG_LOG(SG_GENERAL, SG_DEBUG, "\nHandling Node " << i << "\n\n"); TG_LOG(SG_GENERAL, SG_DEBUG, "\nHandling Node " << i << "\n\n");
curNode = src.at(i); curNode = src.at(i);
if (i < src.size() - 1) if (i < src.size() - 1) {
{
nextNode = src.at(i + 1); nextNode = src.at(i + 1);
} } else {
else
{
// for the last node, next is the first node, as all contours are closed // for the last node, next is the first node, as all contours are closed
nextNode = src.at(0); nextNode = src.at(0);
} }
// now determine how we will iterate from current node to next node // now determine how we will iterate from current node to next node
if( curNode->HasNextCp() ) if (curNode->HasNextCp()) {
{
// next curve is cubic or quadratic // next curve is cubic or quadratic
if( nextNode->HasPrevCp() ) if (nextNode->HasPrevCp()) {
{
// curve is cubic : need both control points // curve is cubic : need both control points
curve_type = CURVE_CUBIC; curve_type = CURVE_CUBIC;
cp1 = curNode->GetNextCp(); cp1 = curNode->GetNextCp();
cp2 = nextNode->GetPrevCp(); cp2 = nextNode->GetPrevCp();
total_dist = CubicDistance( curNode->GetLoc(), cp1, cp2, nextNode->GetLoc() ); total_dist = CubicDistance(curNode->GetLoc(), cp1, cp2, nextNode->GetLoc());
} } else {
else
{
// curve is quadratic using current nodes cp as the cp // curve is quadratic using current nodes cp as the cp
curve_type = CURVE_QUADRATIC; curve_type = CURVE_QUADRATIC;
cp1 = curNode->GetNextCp(); cp1 = curNode->GetNextCp();
total_dist = QuadraticDistance( curNode->GetLoc(), cp1, nextNode->GetLoc() ); total_dist = QuadraticDistance(curNode->GetLoc(), cp1, nextNode->GetLoc());
} }
} } else {
else
{
// next curve is quadratic or linear // next curve is quadratic or linear
if( nextNode->HasPrevCp() ) if (nextNode->HasPrevCp()) {
{
// curve is quadratic using next nodes cp as the cp // curve is quadratic using next nodes cp as the cp
curve_type = CURVE_QUADRATIC; curve_type = CURVE_QUADRATIC;
cp1 = nextNode->GetPrevCp(); cp1 = nextNode->GetPrevCp();
total_dist = QuadraticDistance( curNode->GetLoc(), cp1, nextNode->GetLoc() ); total_dist = QuadraticDistance(curNode->GetLoc(), cp1, nextNode->GetLoc());
} } else {
else
{
// curve is linear // curve is linear
curve_type = CURVE_LINEAR; curve_type = CURVE_LINEAR;
total_dist = LinearDistance( curNode->GetLoc(), nextNode->GetLoc() ); total_dist = LinearDistance(curNode->GetLoc(), nextNode->GetLoc());
} }
} }
if (total_dist < 8.0f) if (total_dist < 8.0f) {
{ if (curve_type != CURVE_LINEAR) {
if (curve_type != CURVE_LINEAR)
{
// If total distance is < 4 meters, then we need to modify num Segments so that each segment >= 2 meters // If total distance is < 4 meters, then we need to modify num Segments so that each segment >= 2 meters
num_segs = ((int)total_dist + 1); num_segs = ((int)total_dist + 1);
TG_LOG(SG_GENERAL, SG_DEBUG, "Segment from " << curNode->GetLoc() << " to " << nextNode->GetLoc() ); TG_LOG(SG_GENERAL, SG_DEBUG, "Segment from " << curNode->GetLoc() << " to " << nextNode->GetLoc());
TG_LOG(SG_GENERAL, SG_DEBUG, " Distance is " << total_dist << " ( < 16.0) so num_segs is " << num_segs ); TG_LOG(SG_GENERAL, SG_DEBUG, " Distance is " << total_dist << " ( < 16.0) so num_segs is " << num_segs);
} } else {
else
{
num_segs = 1; num_segs = 1;
} }
} } else if (total_dist > 800.0f) {
else if (total_dist > 800.0f)
{
// If total distance is > 800 meters, then we need to modify num Segments so that each segment <= 100 meters // If total distance is > 800 meters, then we need to modify num Segments so that each segment <= 100 meters
num_segs = total_dist / 100.0f + 1; num_segs = total_dist / 100.0f + 1;
TG_LOG(SG_GENERAL, SG_DEBUG, "Segment from " << curNode->GetLoc() << " to " << nextNode->GetLoc() ); TG_LOG(SG_GENERAL, SG_DEBUG, "Segment from " << curNode->GetLoc() << " to " << nextNode->GetLoc());
TG_LOG(SG_GENERAL, SG_DEBUG, " Distance is " << total_dist << " ( > 100.0) so num_segs is " << num_segs ); TG_LOG(SG_GENERAL, SG_DEBUG, " Distance is " << total_dist << " ( > 100.0) so num_segs is " << num_segs);
} } else {
else if (curve_type != CURVE_LINEAR) {
{
if (curve_type != CURVE_LINEAR)
{
num_segs = 8; num_segs = 8;
TG_LOG(SG_GENERAL, SG_DEBUG, "Segment from " << curNode->GetLoc() << " to " << nextNode->GetLoc() ); TG_LOG(SG_GENERAL, SG_DEBUG, "Segment from " << curNode->GetLoc() << " to " << nextNode->GetLoc());
TG_LOG(SG_GENERAL, SG_DEBUG, " Distance is " << total_dist << " (OK) so num_segs is " << num_segs ); TG_LOG(SG_GENERAL, SG_DEBUG, " Distance is " << total_dist << " (OK) so num_segs is " << num_segs);
} } else {
else
{
// make sure linear segments don't got over 100m // make sure linear segments don't got over 100m
num_segs = total_dist / 100.0f + 1; num_segs = total_dist / 100.0f + 1;
} }
@ -232,78 +197,60 @@ void ClosedPoly::ConvertContour( const BezContour& src, tgContour& dst )
#endif #endif
// if only one segment, revert to linear // if only one segment, revert to linear
if (num_segs == 1) if (num_segs == 1) {
{
curve_type = CURVE_LINEAR; curve_type = CURVE_LINEAR;
} }
// initialize current location // initialize current location
curLoc = curNode->GetLoc(); curLoc = curNode->GetLoc();
if (curve_type != CURVE_LINEAR) if (curve_type != CURVE_LINEAR) {
{ for (int p = 0; p < num_segs; ++p) {
for (int p=0; p<num_segs; p++)
{
// calculate next location // calculate next location
if (curve_type == CURVE_QUADRATIC) if (curve_type == CURVE_QUADRATIC) {
{ nextLoc = CalculateQuadraticLocation(curNode->GetLoc(), cp1, nextNode->GetLoc(), (1.0f / num_segs) * (p + 1));
nextLoc = CalculateQuadraticLocation( curNode->GetLoc(), cp1, nextNode->GetLoc(), (1.0f/num_segs) * (p+1) ); } else {
} nextLoc = CalculateCubicLocation(curNode->GetLoc(), cp1, cp2, nextNode->GetLoc(), (1.0f / num_segs) * (p + 1));
else
{
nextLoc = CalculateCubicLocation( curNode->GetLoc(), cp1, cp2, nextNode->GetLoc(), (1.0f/num_segs) * (p+1) );
} }
// add the pavement vertex // add the pavement vertex
// convert from lat/lon to geo // convert from lat/lon to geo
// (maybe later) - check some simgear objects... // (maybe later) - check some simgear objects...
dst.AddNode( curLoc ); dst.AddNode(curLoc);
if (p==0) if (p == 0) {
{ TG_LOG(SG_GENERAL, SG_DEBUG, "adding Curve Anchor node (type " << curve_type << ") at " << curLoc);
TG_LOG(SG_GENERAL, SG_DEBUG, "adding Curve Anchor node (type " << curve_type << ") at " << curLoc ); } else {
} TG_LOG(SG_GENERAL, SG_DEBUG, " add bezier node (type " << curve_type << ") at " << curLoc);
else
{
TG_LOG(SG_GENERAL, SG_DEBUG, " add bezier node (type " << curve_type << ") at " << curLoc );
} }
// now set set cur location for the next iteration // now set set cur location for the next iteration
curLoc = nextLoc; curLoc = nextLoc;
} }
} } else {
else if (num_segs > 1) {
{ for (int p = 0; p < num_segs; ++p) {
if (num_segs > 1)
{
for (int p=0; p<num_segs; p++)
{
// calculate next location // calculate next location
nextLoc = CalculateLinearLocation( curNode->GetLoc(), nextNode->GetLoc(), (1.0f/num_segs) * (p+1) ); nextLoc = CalculateLinearLocation(curNode->GetLoc(), nextNode->GetLoc(), (1.0f / num_segs) * (p + 1));
// add the feature vertex // add the feature vertex
dst.AddNode( curLoc ); dst.AddNode(curLoc);
if (p==0) if (p == 0) {
{ TG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear anchor node at " << curLoc);
TG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear anchor node at " << curLoc ); } else {
} TG_LOG(SG_GENERAL, SG_DEBUG, " add linear node at " << curLoc);
else
{
TG_LOG(SG_GENERAL, SG_DEBUG, " add linear node at " << curLoc );
} }
// now set set prev and cur locations for the next iteration // now set set prev and cur locations for the next iteration
curLoc = nextLoc; curLoc = nextLoc;
} }
} } else {
else
{
nextLoc = nextNode->GetLoc(); nextLoc = nextNode->GetLoc();
// just add the one vertex - dist is small // just add the one vertex - dist is small
dst.AddNode( curLoc ); dst.AddNode(curLoc);
TG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at " << curLoc ); TG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at " << curLoc);
curLoc = nextLoc; curLoc = nextLoc;
} }
@ -317,33 +264,30 @@ void ClosedPoly::Finish()
tgContour dst_contour; tgContour dst_contour;
// error handling // error handling
if (boundary.size() == 0) if (boundary.size() == 0) {
{
TG_LOG(SG_GENERAL, SG_ALERT, "no boundary"); TG_LOG(SG_GENERAL, SG_ALERT, "no boundary");
} }
TG_LOG(SG_GENERAL, SG_DEBUG, "Converting a poly with " << holes.size() << " holes"); TG_LOG(SG_GENERAL, SG_DEBUG, "Converting a poly with " << holes.size() << " holes");
if (boundary.size() != 0) if (boundary.size() != 0) {
{
// create the boundary // create the boundary
ConvertContour( boundary, dst_contour ); ConvertContour(boundary, dst_contour);
dst_contour.SetHole( false ); dst_contour.SetHole(false);
// and add it to the geometry // and add it to the geometry
pre_tess.AddContour( dst_contour ); pre_tess.AddContour(dst_contour);
// Then convert the hole contours // Then convert the hole contours
for (unsigned int i=0; i<holes.size(); i++) for (unsigned i = 0; i < holes.size(); ++i) {
{ ConvertContour(holes[i], dst_contour);
ConvertContour( holes[i], dst_contour ); dst_contour.SetHole(true);
dst_contour.SetHole( true );
pre_tess.AddContour( dst_contour ); pre_tess.AddContour(dst_contour);
} }
pre_tess = tgPolygon::Snap( pre_tess, gSnap ); pre_tess = tgPolygon::Snap(pre_tess, gSnap);
pre_tess = tgPolygon::RemoveDups( pre_tess ); pre_tess = tgPolygon::RemoveDups(pre_tess);
} }
// save memory by deleting unneeded resources // save memory by deleting unneeded resources
@ -353,11 +297,11 @@ void ClosedPoly::Finish()
holes.clear(); holes.clear();
} }
std::string ClosedPoly::GetMaterial( int surface ) std::string ClosedPoly::GetMaterial(int surface)
{ {
std::string material; std::string material;
switch( surface ) { switch (surface) {
case 1: case 1:
material = "pa_tiedown"; // Asphalt material = "pa_tiedown"; // Asphalt
break; break;
@ -394,75 +338,78 @@ std::string ClosedPoly::GetMaterial( int surface )
break; break;
default: default:
TG_LOG(SG_GENERAL, SG_ALERT, "ClosedPoly::BuildBtg: unknown surface type " << surface_type ); TG_LOG(SG_GENERAL, SG_ALERT, "ClosedPoly::BuildBtg: unknown surface type " << surface_type);
exit(1); exit(1);
} }
return material; return material;
} }
int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, tgpolygon_list& apt_base_polys, tgpolygon_list& apt_clearing_polys, tgAccumulator& accum, std::string& shapefile_name ) int ClosedPoly::BuildBtg(tgpolygon_list& rwy_polys,
tgcontour_list& slivers,
tgpolygon_list& apt_base_polys,
tgpolygon_list& apt_clearing_polys,
tgAccumulator& accum,
std::string& shapefile_name)
{ {
if ( is_pavement && pre_tess.Contours() ) if (is_pavement && pre_tess.Contours()) {
{
tgPolygon base, safe_base; tgPolygon base, safe_base;
BuildBtg( rwy_polys, slivers, accum, shapefile_name ); BuildBtg(rwy_polys, slivers, accum, shapefile_name);
base = tgPolygon::Expand( pre_tess, 20.0 ); base = tgPolygon::Expand(pre_tess, 20.0);
safe_base = tgPolygon::Expand( pre_tess, 50.0); safe_base = tgPolygon::Expand(pre_tess, 50.0);
// add this to the airport clearing // add this to the airport clearing
apt_clearing_polys.push_back( safe_base ); apt_clearing_polys.push_back(safe_base);
// and add the clearing to the base // and add the clearing to the base
apt_base_polys.push_back( base ); apt_base_polys.push_back(base);
} }
// clean up to save ram : we're done here... // clean up to save ram : we're done here...
return 1; return 1;
} }
int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, tgAccumulator& accum, std::string& shapefile_name ) int ClosedPoly::BuildBtg(tgpolygon_list& rwy_polys, tgcontour_list& slivers, tgAccumulator& accum, std::string& shapefile_name)
{ {
if ( is_pavement && pre_tess.Contours() ) using namespace std::string_literals;
{
char layer[128];
if( shapefile_name.size() ) { if (is_pavement && pre_tess.Contours()) {
snprintf(layer, 128, "%s_preclip", shapefile_name.c_str()); std::string layer;
tgShapefile::FromPolygon(pre_tess, "./airport_dbg", layer, std::string("preclip"));
if (shapefile_name.size()) {
layer = shapefile_name + "_preclip"s;
tgShapefile::FromPolygon(pre_tess, "./airport_dbg"s, layer, "preclip"s);
pre_tess.Tesselate(); pre_tess.Tesselate();
snprintf(layer, 128, "%s_preclip_tris", shapefile_name.c_str()); layer = shapefile_name + "s_preclip_tris"s;
tgShapefile::FromTriangles(pre_tess, "./airport_dbg", layer, std::string("preclip")); tgShapefile::FromTriangles(pre_tess, "./airport_dbg"s, layer, "preclip"s);
//accum.ToShapefiles( "./airport_dbg", "accum", true );
} }
tgPolygon clipped = accum.Diff( pre_tess ); tgPolygon clipped = accum.Diff(pre_tess);
if ( clipped.Contours() ) { if (clipped.Contours()) {
if( shapefile_name.size() ) { if (shapefile_name.size()) {
snprintf(layer, 128, "%s_postclip", shapefile_name.c_str()); layer = shapefile_name + "s_postclip"s;
tgShapefile::FromPolygon(clipped, "./airport_dbg", layer, std::string("postclip")); tgShapefile::FromPolygon(clipped, "./airport_dbg"s, layer, "postclip"s);
} }
// tgPolygon::RemoveSlivers( clipped, slivers ); // tgPolygon::RemoveSlivers( clipped, slivers );
if( shapefile_name.size() ) { if (shapefile_name.size()) {
clipped.Tesselate(); clipped.Tesselate();
snprintf(layer, 128, "%s_postclip_tris", shapefile_name.c_str()); layer = shapefile_name + "s_postclip_tris"s;
tgShapefile::FromTriangles(clipped, "./airport_dbg", layer, std::string("postclip")); tgShapefile::FromTriangles(clipped, "./airport_dbg", layer, "postclip"s);
} }
clipped.SetMaterial( GetMaterial( surface_type ) ); clipped.SetMaterial(GetMaterial(surface_type));
clipped.SetTexParams( clipped.GetNode(0,0), 5.0, 5.0, texture_heading ); clipped.SetTexParams(clipped.GetNode(0, 0), 5.0, 5.0, texture_heading);
clipped.SetTexLimits( 0.0, 0.0, 1.0, 1.0 ); clipped.SetTexLimits(0.0, 0.0, 1.0, 1.0);
clipped.SetTexMethod( TG_TEX_BY_TPS_NOCLIP ); clipped.SetTexMethod(TG_TEX_BY_TPS_NOCLIP);
rwy_polys.push_back( clipped ); rwy_polys.push_back(clipped);
accum.Add( pre_tess ); accum.Add(pre_tess);
} }
} }
@ -472,21 +419,20 @@ int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, tg
// Just used for user defined border - add a little bit, as some modelers made the border exactly on the edges // Just used for user defined border - add a little bit, as some modelers made the border exactly on the edges
// - resulting in no base, which we can't handle // - resulting in no base, which we can't handle
int ClosedPoly::BuildBtg( tgPolygon& apt_base, tgPolygon& apt_clearing, std::string& shapefile_name ) int ClosedPoly::BuildBtg(tgPolygon& apt_base, tgPolygon& apt_clearing, std::string& shapefile_name)
{ {
tgPolygon base, safe_base; tgPolygon base, safe_base;
// 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_border && pre_tess.Contours() ) if (is_border && pre_tess.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);
// add this to the airport clearing // add this to the airport clearing
apt_clearing = tgPolygon::Union( safe_base, apt_clearing); apt_clearing = tgPolygon::Union(safe_base, apt_clearing);
// and add the clearing to the base // and add the clearing to the base
apt_base = tgPolygon::Union( base, apt_base ); apt_base = tgPolygon::Union(base, apt_base);
} }
return 1; return 1;

View file

@ -45,11 +45,10 @@ public:
private: private:
// convert the BezierPoly to a normal Poly (adding nodes for the curves) // convert the BezierPoly to a normal Poly (adding nodes for the curves)
void CreateConvexHull(void); void CreateConvexHull();
void ConvertContour(const BezContour& src, tgContour& dst); void ConvertContour(const BezContour& src, tgContour& dst);
std::string GetMaterial(int surface); std::string GetMaterial(int surface);
bool is_pavement; bool is_pavement;
bool is_border; bool is_border;
bool has_feature; bool has_feature;