diff --git a/src/Airports/GenAirports850/airport.cxx b/src/Airports/GenAirports850/airport.cxx index f18f9922..47ba1eed 100644 --- a/src/Airports/GenAirports850/airport.cxx +++ b/src/Airports/GenAirports850/airport.cxx @@ -330,14 +330,11 @@ static TGPolygon calc_elevations( TGAptSurface &surf, void Airport::BuildBtg(const string& root, const string_list& elev_src ) { + ClipPolyType accum; + ClipPolyType line_accum; TGPolygon apt_base; TGPolygon apt_clearing; - TGPolygon accum; - accum.erase(); - TGPolygon line_accum; - line_accum.erase(); - // runways superpoly_list rwy_polys; texparams_list rwy_tps; @@ -486,7 +483,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) boundary->BuildBtg( altitude, &apt_base, &apt_clearing ); } - if ( apt_base.total_size() == 0 ) + if ( apt_base.total_size() == 0 ) { SG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated"); return; diff --git a/src/Airports/GenAirports850/apt_math.cxx b/src/Airports/GenAirports850/apt_math.cxx index 20c9d8d8..ea5be0ef 100644 --- a/src/Airports/GenAirports850/apt_math.cxx +++ b/src/Airports/GenAirports850/apt_math.cxx @@ -112,7 +112,7 @@ void gen_tex_section( const TGPolygon& runway, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, - TGPolygon *accum ) { + ClipPolyType *accum ) { int j, k; diff --git a/src/Airports/GenAirports850/apt_math.hxx b/src/Airports/GenAirports850/apt_math.hxx index da7192d6..88c44685 100644 --- a/src/Airports/GenAirports850/apt_math.hxx +++ b/src/Airports/GenAirports850/apt_math.hxx @@ -24,6 +24,6 @@ void gen_tex_section( const TGPolygon& runway, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, - TGPolygon *accum ); + ClipPolyType *accum ); #endif diff --git a/src/Airports/GenAirports850/closedpoly.cxx b/src/Airports/GenAirports850/closedpoly.cxx index da895200..00840dd9 100644 --- a/src/Airports/GenAirports850/closedpoly.cxx +++ b/src/Airports/GenAirports850/closedpoly.cxx @@ -589,7 +589,7 @@ int ClosedPoly::BuildOsg( osg::Group* airport ) } } -int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ) +int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, ClipPolyType* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ) { TGPolygon base, safe_base; string material; diff --git a/src/Airports/GenAirports850/closedpoly.hxx b/src/Airports/GenAirports850/closedpoly.hxx index 08982fdf..f0733ec8 100644 --- a/src/Airports/GenAirports850/closedpoly.hxx +++ b/src/Airports/GenAirports850/closedpoly.hxx @@ -32,7 +32,7 @@ public: int BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clearing ); // Build BTG for pavements for airports with no boundary - int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ); + int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, ClipPolyType* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ); FeatureList* GetFeatures() { diff --git a/src/Airports/GenAirports850/helipad.cxx b/src/Airports/GenAirports850/helipad.cxx index 77a31027..32898a0e 100644 --- a/src/Airports/GenAirports850/helipad.cxx +++ b/src/Airports/GenAirports850/helipad.cxx @@ -79,7 +79,7 @@ void Helipad::BuildBtg( float alt_m, superpoly_list *rwy_polys, texparams_list *texparams, superpoly_list *rwy_lights, - TGPolygon *accum, TGPolygon* apt_base, TGPolygon* apt_clearing ) + ClipPolyType *accum, TGPolygon* apt_base, TGPolygon* apt_clearing ) { SG_LOG( SG_GENERAL, SG_INFO, "Building helipad = " << heli.designator ); diff --git a/src/Airports/GenAirports850/helipad.hxx b/src/Airports/GenAirports850/helipad.hxx index 8edf67c8..ebb7baa8 100644 --- a/src/Airports/GenAirports850/helipad.hxx +++ b/src/Airports/GenAirports850/helipad.hxx @@ -28,7 +28,7 @@ class Helipad { public: Helipad(char* def); - void BuildBtg( float alt_m, superpoly_list* heli_polys, texparams_list* texparams, superpoly_list* heli_lights, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ); + void BuildBtg( float alt_m, superpoly_list* heli_polys, texparams_list* texparams, superpoly_list* heli_lights, ClipPolyType* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ); private: struct TGRunway { diff --git a/src/Airports/GenAirports850/linearfeature.cxx b/src/Airports/GenAirports850/linearfeature.cxx index fc566181..0fcd9f26 100644 --- a/src/Airports/GenAirports850/linearfeature.cxx +++ b/src/Airports/GenAirports850/linearfeature.cxx @@ -772,7 +772,7 @@ int LinearFeature::Finish() } } -int LinearFeature::BuildBtg(float alt_m, superpoly_list* line_polys, texparams_list* line_tps, TGPolygon* line_accum, superpoly_list* lights ) +int LinearFeature::BuildBtg(float alt_m, superpoly_list* line_polys, texparams_list* line_tps, ClipPolyType* line_accum, superpoly_list* lights ) { TGPolygon poly; TGPolygon clipped; diff --git a/src/Airports/GenAirports850/linearfeature.hxx b/src/Airports/GenAirports850/linearfeature.hxx index 775a9890..7399922b 100644 --- a/src/Airports/GenAirports850/linearfeature.hxx +++ b/src/Airports/GenAirports850/linearfeature.hxx @@ -93,7 +93,7 @@ public: int Finish(); int BuildOsg( osg::Group* airport ); - int BuildBtg( float alt_m, superpoly_list* line_polys, texparams_list* line_tps, TGPolygon* line_accum, superpoly_list* lights ); + int BuildBtg( float alt_m, superpoly_list* line_polys, texparams_list* line_tps, ClipPolyType* line_accum, superpoly_list* lights ); private: Point3D OffsetPointFirst( Point3D *cur, Point3D *next, double offset_by ); diff --git a/src/Airports/GenAirports850/runway.cxx b/src/Airports/GenAirports850/runway.cxx index 678084dd..9d084b57 100644 --- a/src/Airports/GenAirports850/runway.cxx +++ b/src/Airports/GenAirports850/runway.cxx @@ -128,7 +128,7 @@ TGPolygon WaterRunway::GetNodes() } -int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, superpoly_list* rwy_lights, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ) +int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, superpoly_list* rwy_lights, ClipPolyType* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ) { TGPolygon base, safe_base; string material; diff --git a/src/Airports/GenAirports850/runway.hxx b/src/Airports/GenAirports850/runway.hxx index 47c876bc..1eab7fe2 100644 --- a/src/Airports/GenAirports850/runway.hxx +++ b/src/Airports/GenAirports850/runway.hxx @@ -42,7 +42,7 @@ public: } int BuildOsg( osg::Group* airport ); - int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, superpoly_list* rwy_lights, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ); + int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, superpoly_list* rwy_lights, ClipPolyType* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ); private: struct TGRunway { @@ -93,7 +93,7 @@ private: double &start_pct, double &end_pct, superpoly_list* rwy_polys, texparams_list* texparams, - TGPolygon* accum ); + ClipPolyType* accum ); // generate the runway overrun area void gen_runway_overrun( const TGPolygon& runway_half, @@ -101,7 +101,7 @@ private: const std::string& prefix, superpoly_list* rwy_polys, texparams_list* texparams, - TGPolygon* accum ); + ClipPolyType* accum ); // generate a section of runway void gen_runway_section( const TGPolygon& runway, @@ -113,14 +113,14 @@ private: const std::string& material, superpoly_list* rwy_polys, texparams_list* texparams, - TGPolygon* accum ); + ClipPolyType* accum ); - void gen_simple_rwy( double alt_m, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, TGPolygon *accum ); + void gen_simple_rwy( double alt_m, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, ClipPolyType *accum ); void gen_rwy( double alt_m, const std::string& material, superpoly_list* rwy_polys, texparams_list* texparams, - TGPolygon* accum ); + ClipPolyType* accum ); void gen_rw_marking( const TGPolygon& runway, double &start1_pct, double &end1_pct, @@ -128,7 +128,7 @@ private: const string& material, superpoly_list* rwy_polys, texparams_list* texparams, - TGPolygon* accum, int marking); + ClipPolyType* accum, int marking); void gen_runway_lights( float alt_m, superpoly_list* lights ); diff --git a/src/Airports/GenAirports850/rwy_common.cxx b/src/Airports/GenAirports850/rwy_common.cxx index 306dbacf..f3b0e2ec 100644 --- a/src/Airports/GenAirports850/rwy_common.cxx +++ b/src/Airports/GenAirports850/rwy_common.cxx @@ -40,7 +40,7 @@ void Runway::gen_rw_designation( const string& material, double &start_pct, double &end_pct, superpoly_list *rwy_polys, texparams_list *texparams, - TGPolygon *accum ) + ClipPolyType *accum ) { if (rwname != "XX"){ /* Do not create a designation block if the runway name is set to none */ string letter = ""; @@ -118,7 +118,7 @@ void Runway::gen_runway_overrun( const TGPolygon& runway_half, const string& prefix, superpoly_list *rwy_polys, texparams_list *texparams, - TGPolygon* accum ) { + ClipPolyType* accum ) { const float length = rwy.length / 2.0 + 2.0 * SG_FEET_TO_METER; double start1_pct = 0.0; double end1_pct = 0.0; @@ -171,7 +171,7 @@ void Runway::gen_runway_section( const TGPolygon& runway, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, - TGPolygon *accum ) { + ClipPolyType *accum ) { gen_tex_section( runway, startl_pct, endl_pct, startw_pct, endw_pct, diff --git a/src/Airports/GenAirports850/rwy_gen.cxx b/src/Airports/GenAirports850/rwy_gen.cxx index ace8ce54..3064683d 100644 --- a/src/Airports/GenAirports850/rwy_gen.cxx +++ b/src/Airports/GenAirports850/rwy_gen.cxx @@ -40,7 +40,7 @@ void Runway::gen_rw_marking( const TGPolygon& runway, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, - TGPolygon *accum, int marking) { + ClipPolyType *accum, int marking) { std::vector rw_marking_list; @@ -139,7 +139,7 @@ void Runway::gen_rwy( double alt_m, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, - TGPolygon *accum ) + ClipPolyType *accum ) { SG_LOG( SG_GENERAL, SG_INFO, "Building runway = " << rwy.rwnum[0] << " / " << rwy.rwnum[1]); diff --git a/src/Airports/GenAirports850/rwy_simple.cxx b/src/Airports/GenAirports850/rwy_simple.cxx index 78793810..e7cd804e 100644 --- a/src/Airports/GenAirports850/rwy_simple.cxx +++ b/src/Airports/GenAirports850/rwy_simple.cxx @@ -37,7 +37,7 @@ void Runway::gen_simple_rwy( double alt_m, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, - TGPolygon *accum ) + ClipPolyType *accum ) { int i; diff --git a/src/Lib/Polygon/polygon.cxx b/src/Lib/Polygon/polygon.cxx index 259266e7..8b97fc2e 100644 --- a/src/Lib/Polygon/polygon.cxx +++ b/src/Lib/Polygon/polygon.cxx @@ -26,15 +26,6 @@ // http://www.cs.man.ac.uk/aig/staff/alan/software/ // -// which clipping lib to use? -//#define CLIP_GPC -#define CLIP_CLIPPER - -#ifdef CLIP_GPC -extern "C" { -#include -} -#endif #include #include @@ -48,11 +39,6 @@ extern "C" { #include "polygon.hxx" #include "point2d.hxx" -#ifdef CLIP_CLIPPER -#include "clipper.hpp" -using namespace ClipperLib; -#endif - using std::endl; // Constructor @@ -361,6 +347,18 @@ void make_gpc_poly( const TGPolygon& in, gpc_polygon *out ) { delete [] v_list.vertex; } +void make_tg_poly( const gpc_polygon* in, TGPolygon *out ) +{ + for ( int i = 0; i < in->num_contours; ++i ) { + for ( int j = 0; j < in->contour[i].num_vertices; j++ ) { + Point3D p( in->contour[i].vertex[j].x, in->contour[i].vertex[j].y, -9999.0 ); + out->add_node(i, p); + } + + out->set_hole_flag( i, in->hole[i] ); + } +} + // Generic clipping routine TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const TGPolygon& clip ) @@ -399,14 +397,7 @@ TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, gpc_polygon_clip( op, gpc_subject, gpc_clip, gpc_result ); - for ( int i = 0; i < gpc_result->num_contours; ++i ) { - for ( int j = 0; j < gpc_result->contour[i].num_vertices; j++ ) { - Point3D p( gpc_result->contour[i].vertex[j].x, gpc_result->contour[i].vertex[j].y, -9999.0 ); - result.add_node(i, p); - } - - result.set_hole_flag( i, gpc_result->hole[i] ); - } + make_tg_poly( gpc_result, &result ); // free allocated memory gpc_free_polygon( gpc_subject ); @@ -415,11 +406,89 @@ TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, return result; } + +// Generic clipping routine +TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const gpc_polygon& clip ) +{ + TGPolygon result; + + gpc_polygon *gpc_subject = new gpc_polygon; + gpc_subject->num_contours = 0; + gpc_subject->contour = NULL; + gpc_subject->hole = NULL; + make_gpc_poly( subject, gpc_subject ); + + gpc_polygon *gpc_clip = (gpc_polygon*)&clip; + + gpc_polygon *gpc_result = new gpc_polygon; + gpc_result->num_contours = 0; + gpc_result->contour = NULL; + gpc_result->hole = NULL; + + gpc_op op; + if ( poly_op == POLY_DIFF ) { + op = GPC_DIFF; + } else if ( poly_op == POLY_INT ) { + op = GPC_INT; + } else if ( poly_op == POLY_XOR ) { + op = GPC_XOR; + } else if ( poly_op == POLY_UNION ) { + op = GPC_UNION; + } else { + throw sg_exception("Unknown polygon op, exiting."); + } + + gpc_polygon_clip( op, gpc_subject, gpc_clip, gpc_result ); + + make_tg_poly( gpc_result, &result ); + + // free allocated memory + gpc_free_polygon( gpc_subject ); + gpc_free_polygon( gpc_result ); + + return result; +} + +gpc_polygon polygon_clip_keep_native_fmt( clip_op poly_op, const TGPolygon& subject, const gpc_polygon& clip ) +{ + gpc_polygon *gpc_subject = new gpc_polygon; + gpc_subject->num_contours = 0; + gpc_subject->contour = NULL; + gpc_subject->hole = NULL; + make_gpc_poly( subject, gpc_subject ); + + gpc_polygon *gpc_clip = (gpc_polygon*)&clip; + + gpc_polygon result; + result.num_contours = 0; + result.contour = NULL; + result.hole = NULL; + + gpc_op op; + if ( poly_op == POLY_DIFF ) { + op = GPC_DIFF; + } else if ( poly_op == POLY_INT ) { + op = GPC_INT; + } else if ( poly_op == POLY_XOR ) { + op = GPC_XOR; + } else if ( poly_op == POLY_UNION ) { + op = GPC_UNION; + } else { + throw sg_exception("Unknown polygon op, exiting."); + } + + gpc_polygon_clip( op, gpc_subject, gpc_clip, &result ); + + // free allocated memory + gpc_free_polygon( gpc_subject ); + + return result; +} #endif #ifdef CLIP_CLIPPER -#define FIXEDPT (1000000000000) +#define FIXEDPT (10000000000000) IntPoint MakeClipperPoint( Point3D pt ) { @@ -451,15 +520,6 @@ void make_clipper_poly( const TGPolygon& in, Polygons *out ) { // assume contour 0 is boundary, 1..x are holes // create the boundary - -#if 0 - SG_LOG(SG_GENERAL, SG_ALERT, - " make_clipper_poly : processing boundary contour, nodes = " - << in.contour_size(0) << ", hole = " - << in.get_hole_flag(0) - ); -#endif - for (j=0; j +} + +typedef gpc_polygon ClipPolyType; +#endif + +#ifdef CLIP_CLIPPER +#include "clipper.hpp" +using namespace ClipperLib; + +typedef Polygons ClipPolyType; +#endif #include #include @@ -219,6 +237,7 @@ TGPolygon tgPolygon2tristrip( const TGPolygon& poly ); // Difference TGPolygon tgPolygonDiff( const TGPolygon& subject, const TGPolygon& clip ); +TGPolygon tgPolygonDiff( const TGPolygon& subject, const ClipPolyType& clip ); // Intersection TGPolygon tgPolygonInt( const TGPolygon& subject, const TGPolygon& clip ); @@ -228,6 +247,7 @@ TGPolygon tgPolygonXor( const TGPolygon& subject, const TGPolygon& clip ); // Union TGPolygon tgPolygonUnion( const TGPolygon& subject, const TGPolygon& clip ); +ClipPolyType tgPolygonUnion( const TGPolygon& subject, const ClipPolyType& clip ); // Output std::ostream &operator<< (std::ostream &output, const TGPolygon &poly);