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<sections> 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 <gpc.h>
-}
-#endif
 
 #include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
@@ -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<in.contour_size(0); ++j)
         {
 	        p = in.get_pt( 0, j );
@@ -470,14 +530,6 @@ void make_clipper_poly( const TGPolygon& in, Polygons *out )
         // create the holes
         for (i=1; i<in.contours(); ++i ) 
         {        
-#if 0
-            SG_LOG(SG_GENERAL, SG_ALERT, 
-                "  make_clipper_poly : processing hole " << i << ", nodes = " 
-                << in.contour_size(i) << ", hole = "
-                << in.get_hole_flag(i) 
-            );
-#endif
-
             contour.clear();
 	        for (j=0; j<in.contour_size(i); ++j) 
             {
@@ -489,6 +541,39 @@ void make_clipper_poly( const TGPolygon& in, Polygons *out )
     }
 }
 
+void make_tg_poly( const ExPolygons& in, TGPolygon *out )
+{
+	int res_contour = 0;
+	out->erase();
+
+  	for (int i=0; i<in.size(); i++)
+    {
+      	const struct ExPolygon* pg = &in[i];
+		IntPoint ip;
+
+		// Get the boundary contour
+        for (int j = 0; j < pg->outer.size(); j++)
+        {
+			ip = IntPoint( pg->outer[j].X, pg->outer[j].Y );
+       	    out->add_node(res_contour, MakeTGPoint(ip));
+        }
+        out->set_hole_flag(res_contour, 0);
+        res_contour++;
+
+        // then the holes
+        for (int j = 0; j < pg->holes.size(); j++)
+        {
+            for (int k = 0; k < pg->holes[j].size(); k++)
+            {
+				ip = IntPoint( pg->holes[j].at(k).X, pg->holes[j].at(k).Y );
+               	out->add_node(res_contour, MakeTGPoint(ip));
+            }
+            out->set_hole_flag(res_contour, 1);
+            res_contour++;
+        }
+    }
+}
+
 TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const TGPolygon& clip )
 {
     TGPolygon result;
@@ -500,7 +585,6 @@ TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const TGPolyg
     make_clipper_poly( clip, &clipper_clip );
 
     ExPolygons clipper_result;
-    //Polygons clipper_result;
 
     ClipType op;
     if ( poly_op == POLY_DIFF ) {
@@ -520,39 +604,84 @@ TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const TGPolyg
 	c.AddPolygons(clipper_subject, ptSubject);
 	c.AddPolygons(clipper_clip, ptClip);
 
-    Point3D p;
-    int res_contour = 0;
-	if (c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd))
-    {
-     	for (int i=0; i<clipper_result.size(); i++)
-        {
-        	struct ExPolygon* pg = &clipper_result[i];
-			IntPoint ip;
+	c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
+	make_tg_poly( clipper_result, &result );
 
-			// Get the boundary contour
-            for (int j = 0; j < pg->outer.size(); j++)
-            {
-				ip = IntPoint( pg->outer[j].X, pg->outer[j].Y );
-        	    result.add_node(res_contour, MakeTGPoint(ip));
-            }
-            result.set_hole_flag(res_contour, 0);
-            res_contour++;
+	return result;
+}
 
-            // then the holes
-            for (int j = 0; j < pg->holes.size(); j++)
-            {
-                for (int k = 0; k < pg->holes[j].size(); k++)
-                {
-					ip = IntPoint( pg->holes[j].at(k).X, pg->holes[j].at(k).Y );
-                   	result.add_node(res_contour, MakeTGPoint(ip));
-                }
-                result.set_hole_flag(res_contour, 1);
-                res_contour++;
-            }
-        }
+TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const Polygons& clipper_clip )
+{
+    TGPolygon result;
+
+    Polygons clipper_subject;
+    make_clipper_poly( subject, &clipper_subject );
+
+    ExPolygons clipper_result;
+
+    ClipType op;
+    if ( poly_op == POLY_DIFF ) {
+	    op = ctDifference;
+    } else if ( poly_op == POLY_INT ) {
+	    op = ctIntersection;
+    } else if ( poly_op == POLY_XOR ) {
+	    op = ctXor;
+    } else if ( poly_op == POLY_UNION ) {
+    	op = ctUnion;
+    } else {
+        throw sg_exception("Unknown polygon op, exiting.");
     }
 
-    return result;
+    Clipper c;
+	c.Clear();
+	c.AddPolygons(clipper_subject, ptSubject);
+	c.AddPolygons(clipper_clip, ptClip);
+
+	c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
+	make_tg_poly( clipper_result, &result );
+
+	return result;
+}
+
+Polygons polygon_clip_keep_native_fmt( clip_op poly_op, const TGPolygon& subject, const Polygons& clipper_clip )
+{
+    Polygons clipper_subject;
+    make_clipper_poly( subject, &clipper_subject );
+
+    ExPolygons clipper_result;
+	Polygons result;
+
+    ClipType op;
+    if ( poly_op == POLY_DIFF ) {
+	    op = ctDifference;
+    } else if ( poly_op == POLY_INT ) {
+	    op = ctIntersection;
+    } else if ( poly_op == POLY_XOR ) {
+	    op = ctXor;
+    } else if ( poly_op == POLY_UNION ) {
+    	op = ctUnion;
+    } else {
+        throw sg_exception("Unknown polygon op, exiting.");
+    }
+
+    Clipper c;
+	c.Clear();
+	c.AddPolygons(clipper_subject, ptSubject);
+	c.AddPolygons(clipper_clip, ptClip);
+
+	c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
+	
+	// copy contours to polygons structure
+	for (int i=0; i<clipper_result.size(); i++)
+	{
+		result.push_back( clipper_result[i].outer );
+		for (int j=0; j<clipper_result[i].holes.size(); j++)
+		{
+			result.push_back( clipper_result[i].holes[j] );
+		}
+	}
+
+	return result;
 }
 #endif
 
@@ -561,6 +690,11 @@ TGPolygon tgPolygonDiff( const TGPolygon& subject, const TGPolygon& clip ) {
     return polygon_clip( POLY_DIFF, subject, clip );
 }
 
+TGPolygon tgPolygonDiff( const TGPolygon& subject, const ClipPolyType& clip ) {
+    return polygon_clip( POLY_DIFF, subject, clip );
+}
+
+
 // Intersection
 TGPolygon tgPolygonInt( const TGPolygon& subject, const TGPolygon& clip ) {
     return polygon_clip( POLY_INT, subject, clip );
@@ -578,6 +712,10 @@ TGPolygon tgPolygonUnion( const TGPolygon& subject, const TGPolygon& clip ) {
     return polygon_clip( POLY_UNION, subject, clip );
 }
 
+ClipPolyType tgPolygonUnion( const TGPolygon& subject, const ClipPolyType& clip ) {
+    return polygon_clip_keep_native_fmt( POLY_UNION, subject, clip );
+}
+
 
 // canonify the polygon winding, outer contour must be anti-clockwise,
 // all inner contours must be clockwise.
diff --git a/src/Lib/Polygon/polygon.hxx b/src/Lib/Polygon/polygon.hxx
index 1e322e56..6a2fb9bc 100644
--- a/src/Lib/Polygon/polygon.hxx
+++ b/src/Lib/Polygon/polygon.hxx
@@ -29,6 +29,24 @@
 # error This library requires C++
 #endif                                   
 
+// which clipping lib to use?
+//#define CLIP_GPC
+#define CLIP_CLIPPER
+
+#ifdef CLIP_GPC
+extern "C" {
+#include <gpc.h>
+}
+
+typedef gpc_polygon	ClipPolyType;
+#endif
+
+#ifdef CLIP_CLIPPER
+#include "clipper.hpp"
+using namespace ClipperLib;
+
+typedef Polygons ClipPolyType;
+#endif
 
 #include <simgear/compiler.h>
 #include <simgear/math/sg_types.hxx>
@@ -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);