Add an optimization to BuildBtg - the accumulator is kept in the native
clipping library format, so it doesn't have to be converted / reconverted between clipping and TGPolygon types for each operation - shaves about 12 seconds from KATL build.
This commit is contained in:
parent
59b534616f
commit
db1a734b19
16 changed files with 253 additions and 98 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,35 +604,80 @@ 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))
|
||||
c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
|
||||
make_tg_poly( clipper_result, &result );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
struct ExPolygon* pg = &clipper_result[i];
|
||||
IntPoint ip;
|
||||
|
||||
// Get the boundary contour
|
||||
for (int j = 0; j < pg->outer.size(); j++)
|
||||
result.push_back( clipper_result[i].outer );
|
||||
for (int j=0; j<clipper_result[i].holes.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++;
|
||||
|
||||
// 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++;
|
||||
}
|
||||
result.push_back( clipper_result[i].holes[j] );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue