1
0
Fork 0

Sync clipper library with latest code from SF

Picked from here:
https://sourceforge.net/p/polyclipping/code/HEAD/tree/trunk/cpp/
This commit is contained in:
Torsten Dreyer 2018-02-12 22:32:52 +01:00
parent 9d25a4c4b1
commit e6f652ab91
4 changed files with 5042 additions and 4948 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,10 @@
/******************************************************************************* /*******************************************************************************
* * * *
* Author : Angus Johnson * * Author : Angus Johnson *
* Version : 6.1.2 * * Version : 6.4.2 *
* Date : 15 December 2013 * * Date : 27 February 2017 *
* Website : http://www.angusj.com * * Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2013 * * Copyright : Angus Johnson 2010-2017 *
* * * *
* License: * * License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. * * Use, modification & distribution is subject to Boost Software License Ver 1. *
@ -34,7 +34,7 @@
#ifndef clipper_hpp #ifndef clipper_hpp
#define clipper_hpp #define clipper_hpp
#define CLIPPER_VERSION "6.1.2" #define CLIPPER_VERSION "6.4.2"
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This //use_int32: When enabled 32bit ints are used instead of 64bit ints. This
//improve performance but coordinate values are limited to the range +/- 46340 //improve performance but coordinate values are limited to the range +/- 46340
@ -44,19 +44,20 @@
//#define use_xyz //#define use_xyz
//use_lines: Enables line clipping. Adds a very minor cost to performance. //use_lines: Enables line clipping. Adds a very minor cost to performance.
//#define use_lines #define use_lines
//use_deprecated: Enables support for the obsolete OffsetPaths() function //use_deprecated: Enables temporary support for the obsolete functions
//which has been replace with the ClipperOffset class. //#define use_deprecated
#define use_deprecated
#include <vector> #include <vector>
#include <list>
#include <set> #include <set>
#include <stdexcept> #include <stdexcept>
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
#include <ostream> #include <ostream>
#include <functional> #include <functional>
#include <queue>
namespace ClipperLib { namespace ClipperLib {
@ -69,11 +70,16 @@ enum PolyType { ptSubject, ptClip };
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
#ifdef use_int32 #ifdef use_int32
typedef int cInt; typedef int cInt;
typedef unsigned int cUInt; static cInt const loRange = 0x7FFF;
static cInt const hiRange = 0x7FFF;
#else #else
typedef signed long long cInt; typedef signed long long cInt;
typedef unsigned long long cUInt; static cInt const loRange = 0x3FFFFFFF;
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
typedef signed long long long64; //used by Int128 class
typedef unsigned long long ulong64;
#endif #endif
struct IntPoint { struct IntPoint {
@ -117,15 +123,12 @@ struct DoublePoint
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifdef use_xyz #ifdef use_xyz
typedef void (*TZFillCallback)(IntPoint& z1, IntPoint& z2, IntPoint& pt); typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
#endif #endif
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4}; enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
enum JoinType {jtSquare, jtRound, jtMiter}; enum JoinType {jtSquare, jtRound, jtMiter};
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound}; enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
#ifdef use_deprecated
enum EndType_ {etClosed, etButt = 2, etSquare, etRound};
#endif
class PolyNode; class PolyNode;
typedef std::vector< PolyNode* > PolyNodes; typedef std::vector< PolyNode* > PolyNodes;
@ -134,6 +137,7 @@ class PolyNode
{ {
public: public:
PolyNode(); PolyNode();
virtual ~PolyNode(){};
Path Contour; Path Contour;
PolyNodes Childs; PolyNodes Childs;
PolyNode* Parent; PolyNode* Parent;
@ -142,6 +146,7 @@ public:
bool IsOpen() const; bool IsOpen() const;
int ChildCount() const; int ChildCount() const;
private: private:
//PolyNode& operator =(PolyNode& other);
unsigned Index; //node index in Parent.Childs unsigned Index; //node index in Parent.Childs
bool m_IsOpen; bool m_IsOpen;
JoinType m_jointype; JoinType m_jointype;
@ -155,22 +160,19 @@ private:
class PolyTree: public PolyNode class PolyTree: public PolyNode
{ {
public: public:
~PolyTree(){Clear();}; ~PolyTree(){ Clear(); };
PolyNode* GetFirst() const; PolyNode* GetFirst() const;
void Clear(); void Clear();
int Total() const; int Total() const;
private: private:
//PolyTree& operator =(PolyTree& other);
PolyNodes AllNodes; PolyNodes AllNodes;
friend class Clipper; //to access AllNodes friend class Clipper; //to access AllNodes
}; };
bool Orientation(const Path &poly); bool Orientation(const Path &poly);
double Area(const Path &poly); double Area(const Path &poly);
int PointInPolygon(const IntPoint &pt, const Path &path);
#ifdef use_deprecated
void OffsetPaths(const Paths &in_polys, Paths &out_polys,
double delta, JoinType jointype, EndType_ endtype, double limit = 0);
#endif
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd); void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd); void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
@ -181,8 +183,9 @@ void CleanPolygon(Path& poly, double distance = 1.415);
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415); void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
void CleanPolygons(Paths& polys, double distance = 1.415); void CleanPolygons(Paths& polys, double distance = 1.415);
void MinkowskiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed); void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
void MinkowskiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed); void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths); void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths); void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
@ -199,8 +202,7 @@ enum EdgeSide { esLeft = 1, esRight = 2};
//forward declarations (for stuff used internally) ... //forward declarations (for stuff used internally) ...
struct TEdge; struct TEdge;
struct IntersectNode; struct IntersectNode;
struct LocalMinima; struct LocalMinimum;
struct Scanbeam;
struct OutPt; struct OutPt;
struct OutRec; struct OutRec;
struct Join; struct Join;
@ -210,7 +212,6 @@ typedef std::vector < TEdge* > EdgeList;
typedef std::vector < Join* > JoinList; typedef std::vector < Join* > JoinList;
typedef std::vector < IntersectNode* > IntersectList; typedef std::vector < IntersectNode* > IntersectList;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//ClipperBase is the ancestor to the Clipper class. It should not be //ClipperBase is the ancestor to the Clipper class. It should not be
@ -221,7 +222,7 @@ class ClipperBase
public: public:
ClipperBase(); ClipperBase();
virtual ~ClipperBase(); virtual ~ClipperBase();
bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed); virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
virtual void Clear(); virtual void Clear();
IntRect GetBounds(); IntRect GetBounds();
@ -230,19 +231,32 @@ public:
protected: protected:
void DisposeLocalMinimaList(); void DisposeLocalMinimaList();
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed); TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
void PopLocalMinima();
virtual void Reset(); virtual void Reset();
TEdge* ProcessBound(TEdge* E, bool IsClockwise); TEdge* ProcessBound(TEdge* E, bool IsClockwise);
void InsertLocalMinima(LocalMinima *newLm); void InsertScanbeam(const cInt Y);
void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed); bool PopScanbeam(cInt &Y);
TEdge* DescendToMin(TEdge *&E); bool LocalMinimaPending();
void AscendToMax(TEdge *&E, bool Appending, bool IsClosed); bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
LocalMinima *m_CurrentLM; OutRec* CreateOutRec();
LocalMinima *m_MinimaList; void DisposeAllOutRecs();
void DisposeOutRec(PolyOutList::size_type index);
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
void DeleteFromAEL(TEdge *e);
void UpdateEdgeIntoAEL(TEdge *&e);
typedef std::vector<LocalMinimum> MinimaList;
MinimaList::iterator m_CurrentLM;
MinimaList m_MinimaList;
bool m_UseFullRange; bool m_UseFullRange;
EdgeList m_edges; EdgeList m_edges;
bool m_PreserveCollinear; bool m_PreserveCollinear;
bool m_HasOpenPaths; bool m_HasOpenPaths;
PolyOutList m_PolyOuts;
TEdge *m_ActiveEdges;
typedef std::priority_queue<cInt> ScanbeamList;
ScanbeamList m_Scanbeam;
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -250,35 +264,37 @@ class Clipper : public virtual ClipperBase
{ {
public: public:
Clipper(int initOptions = 0); Clipper(int initOptions = 0);
~Clipper();
bool Execute(ClipType clipType, bool Execute(ClipType clipType,
Paths &solution, Paths &solution,
PolyFillType subjFillType = pftEvenOdd, PolyFillType fillType = pftEvenOdd);
PolyFillType clipFillType = pftEvenOdd); bool Execute(ClipType clipType,
Paths &solution,
PolyFillType subjFillType,
PolyFillType clipFillType);
bool Execute(ClipType clipType, bool Execute(ClipType clipType,
PolyTree &polytree, PolyTree &polytree,
PolyFillType subjFillType = pftEvenOdd, PolyFillType fillType = pftEvenOdd);
PolyFillType clipFillType = pftEvenOdd); bool Execute(ClipType clipType,
void Clear(); PolyTree &polytree,
bool ReverseSolution() {return m_ReverseOutput;}; PolyFillType subjFillType,
PolyFillType clipFillType);
bool ReverseSolution() { return m_ReverseOutput; };
void ReverseSolution(bool value) {m_ReverseOutput = value;}; void ReverseSolution(bool value) {m_ReverseOutput = value;};
bool StrictlySimple() {return m_StrictSimple;}; bool StrictlySimple() {return m_StrictSimple;};
void StrictlySimple(bool value) {m_StrictSimple = value;}; void StrictlySimple(bool value) {m_StrictSimple = value;};
//set the callback function for z value filling on intersections (otherwise Z is 0) //set the callback function for z value filling on intersections (otherwise Z is 0)
#ifdef use_xyz #ifdef use_xyz
void ZFillFunction(TZFillCallback zFillFunc); void ZFillFunction(ZFillCallback zFillFunc);
#endif #endif
protected: protected:
void Reset();
virtual bool ExecuteInternal(); virtual bool ExecuteInternal();
private: private:
PolyOutList m_PolyOuts;
JoinList m_Joins; JoinList m_Joins;
JoinList m_GhostJoins; JoinList m_GhostJoins;
IntersectList m_IntersectList; IntersectList m_IntersectList;
ClipType m_ClipType; ClipType m_ClipType;
std::set< cInt, std::greater<cInt> > m_Scanbeam; typedef std::list<cInt> MaximaList;
TEdge *m_ActiveEdges; MaximaList m_Maxima;
TEdge *m_SortedEdges; TEdge *m_SortedEdges;
bool m_ExecuteLocked; bool m_ExecuteLocked;
PolyFillType m_ClipFillType; PolyFillType m_ClipFillType;
@ -287,40 +303,32 @@ private:
bool m_UsingPolyTree; bool m_UsingPolyTree;
bool m_StrictSimple; bool m_StrictSimple;
#ifdef use_xyz #ifdef use_xyz
TZFillCallback m_ZFill; //custom callback ZFillCallback m_ZFill; //custom callback
#endif #endif
void SetWindingCount(TEdge& edge); void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const; bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge& edge) const; bool IsEvenOddAltFillType(const TEdge& edge) const;
void InsertScanbeam(const cInt Y);
cInt PopScanbeam();
void InsertLocalMinimaIntoAEL(const cInt botY); void InsertLocalMinimaIntoAEL(const cInt botY);
void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge); void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
void AddEdgeToSEL(TEdge *edge); void AddEdgeToSEL(TEdge *edge);
bool PopEdgeFromSEL(TEdge *&edge);
void CopyAELToSEL(); void CopyAELToSEL();
void DeleteFromSEL(TEdge *e); void DeleteFromSEL(TEdge *e);
void DeleteFromAEL(TEdge *e);
void UpdateEdgeIntoAEL(TEdge *&e);
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
bool IsContributing(const TEdge& edge) const; bool IsContributing(const TEdge& edge) const;
bool IsTopHorz(const cInt XPos); bool IsTopHorz(const cInt XPos);
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
void DoMaxima(TEdge *e); void DoMaxima(TEdge *e);
void PrepareHorzJoins(TEdge* horzEdge, bool isTopOfScanbeam); void ProcessHorizontals();
void ProcessHorizontals(bool IsTopOfScanbeam); void ProcessHorizontal(TEdge *horzEdge);
void ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam);
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutRec* GetOutRec(int idx); OutRec* GetOutRec(int idx);
void AppendPolygon(TEdge *e1, TEdge *e2); void AppendPolygon(TEdge *e1, TEdge *e2);
void IntersectEdges(TEdge *e1, TEdge *e2, void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
const IntPoint &pt, bool protect = false);
OutRec* CreateOutRec();
OutPt* AddOutPt(TEdge *e, const IntPoint &pt); OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
void DisposeAllOutRecs(); OutPt* GetLastOutPt(TEdge *e);
void DisposeOutRec(PolyOutList::size_type index); bool ProcessIntersections(const cInt topY);
bool ProcessIntersections(const cInt botY, const cInt topY); void BuildIntersectList(const cInt topY);
void BuildIntersectList(const cInt botY, const cInt topY);
void ProcessIntersectList(); void ProcessIntersectList();
void ProcessEdgesAtTopOfScanbeam(const cInt topY); void ProcessEdgesAtTopOfScanbeam(const cInt topY);
void BuildResult(Paths& polys); void BuildResult(Paths& polys);
@ -329,6 +337,7 @@ private:
void DisposeIntersectNodes(); void DisposeIntersectNodes();
bool FixupIntersectionOrder(); bool FixupIntersectionOrder();
void FixupOutPolygon(OutRec &outrec); void FixupOutPolygon(OutRec &outrec);
void FixupOutPolyline(OutRec &outrec);
bool IsHole(TEdge *e); bool IsHole(TEdge *e);
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl); bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
void FixHoleLinkage(OutRec &outrec); void FixHoleLinkage(OutRec &outrec);
@ -340,9 +349,10 @@ private:
void JoinCommonEdges(); void JoinCommonEdges();
void DoSimplePolygons(); void DoSimplePolygons();
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec); void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec); void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
#ifdef use_xyz #ifdef use_xyz
void SetZ(IntPoint& pt, TEdge& e); void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
#endif #endif
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View file

@ -110,7 +110,7 @@ void tgChopper::Add( const tgPolygon& subject, const std::string& type )
double clip_top = b_clip.get_center_lat() + 0.0630; double clip_top = b_clip.get_center_lat() + 0.0630;
tgPolygon clip_row, clipped; tgPolygon clip_row, clipped;
SG_LOG( SG_GENERAL, SG_DEBUG, " CLIPPED row " << row << " center lat is " << b_clip.get_center_lat() << " clip_botton is " << clip_bottom << " clip_top is " << clip_top ); SG_LOG( SG_GENERAL, SG_DEBUG, " CLIPPED row " << row << " of " << dy << ", center lat is " << b_clip.get_center_lat() << " clip_botton is " << clip_bottom << " clip_top is " << clip_top );
clip_row.AddNode( 0, SGGeod::fromDeg(-180.0, clip_bottom) ); clip_row.AddNode( 0, SGGeod::fromDeg(-180.0, clip_bottom) );
clip_row.AddNode( 0, SGGeod::fromDeg( 180.0, clip_bottom) ); clip_row.AddNode( 0, SGGeod::fromDeg( 180.0, clip_bottom) );

View file

@ -70,18 +70,18 @@ double CalculateTheta( const SGVec3d& dirCur, const SGVec3d& dirNext )
ClipperLib::IntPoint SGGeod_ToClipper( const SGGeod& p ) ClipperLib::IntPoint SGGeod_ToClipper( const SGGeod& p )
{ {
ClipperLib::cUInt x, y; ClipperLib::cInt x, y;
if ( p.getLongitudeDeg() > 0 ) { if ( p.getLongitudeDeg() > 0 ) {
x = (ClipperLib::cUInt)( (p.getLongitudeDeg() * CLIPPER_FIXEDPT) + 0.5 ); x = (ClipperLib::cInt)( (p.getLongitudeDeg() * CLIPPER_FIXEDPT) + 0.5 );
} else { } else {
x = (ClipperLib::cUInt)( (p.getLongitudeDeg() * CLIPPER_FIXEDPT) - 0.5 ); x = (ClipperLib::cInt)( (p.getLongitudeDeg() * CLIPPER_FIXEDPT) - 0.5 );
} }
if ( p.getLatitudeDeg() > 0 ) { if ( p.getLatitudeDeg() > 0 ) {
y = (ClipperLib::cUInt)( (p.getLatitudeDeg() * CLIPPER_FIXEDPT) + 0.5 ); y = (ClipperLib::cInt)( (p.getLatitudeDeg() * CLIPPER_FIXEDPT) + 0.5 );
} else { } else {
y = (ClipperLib::cUInt)( (p.getLatitudeDeg() * CLIPPER_FIXEDPT) - 0.5 ); y = (ClipperLib::cInt)( (p.getLatitudeDeg() * CLIPPER_FIXEDPT) - 0.5 );
} }
return ClipperLib::IntPoint( x, y ); return ClipperLib::IntPoint( x, y );