clipper.hpp | clipper.hpp | |||
---|---|---|---|---|
/************************************************************************** ***** | /************************************************************************** ***** | |||
* * | * * | |||
* Author : Angus Johnson * | * Author : Angus Johnson * | |||
* Version : 6.2.1 | * Version : 4.8.9 | |||
* | * | |||
* Date : 31 October 2014 | * Date : 25 September 2012 | |||
* | * | |||
* Website : http://www.angusj.com * | * Website : http://www.angusj.com * | |||
* Copyright : Angus Johnson 2010-2014 * | * Copyright : Angus Johnson 2010-2012 * | |||
* * | * * | |||
* License: * | * License: * | |||
* Use, modification & distribution is subject to Boost Software License Ver 1. * | * Use, modification & distribution is subject to Boost Software License Ver 1. * | |||
* http://www.boost.org/LICENSE_1_0.txt * | * http://www.boost.org/LICENSE_1_0.txt * | |||
* * | * * | |||
* Attributions: * | * Attributions: * | |||
* The code in this library is an extension of Bala Vatti's clipping algorit hm: * | * The code in this library is an extension of Bala Vatti's clipping algorit hm: * | |||
* "A generic solution to polygon clipping" * | * "A generic solution to polygon clipping" * | |||
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * | * Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * | |||
* http://portal.acm.org/citation.cfm?id=129906 * | * http://portal.acm.org/citation.cfm?id=129906 * | |||
skipping to change at line 29 | skipping to change at line 29 | |||
* Computer graphics and geometric modeling: implementation and algorithms * | * Computer graphics and geometric modeling: implementation and algorithms * | |||
* By Max K. Agoston * | * By Max K. Agoston * | |||
* Springer; 1 edition (January 4, 2005) * | * Springer; 1 edition (January 4, 2005) * | |||
* http://books.google.com/books?q=vatti+clipping+agoston * | * http://books.google.com/books?q=vatti+clipping+agoston * | |||
* * | * * | |||
* See also: * | * See also: * | |||
* "Polygon Offsetting by Computing Winding Numbers" * | * "Polygon Offsetting by Computing Winding Numbers" * | |||
* Paper no. DETC2005-85513 pp. 565-575 * | * Paper no. DETC2005-85513 pp. 565-575 * | |||
* ASME 2005 International Design Engineering Technical Conferences * | * ASME 2005 International Design Engineering Technical Conferences * | |||
* and Computers and Information in Engineering Conference (IDETC/CIE2005) * | * and Computers and Information in Engineering Conference (IDETC/CIE2005) * | |||
* September 24-28, 2005 , Long Beach, California, USA * | * September 24–28, 2005 , Long Beach, California, USA * | |||
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * | * http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * | |||
* * | * * | |||
*************************************************************************** ****/ | *************************************************************************** ****/ | |||
#ifndef clipper_hpp | #ifndef clipper_hpp | |||
#define clipper_hpp | #define clipper_hpp | |||
#define CLIPPER_VERSION "6.2.0" | ||||
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This | ||||
//improve performance but coordinate values are limited to the range +/- 46 | ||||
340 | ||||
//#define use_int32 | ||||
//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance. | ||||
//#define use_xyz | ||||
//use_lines: Enables line clipping. Adds a very minor cost to performance. | ||||
//#define use_lines | ||||
//use_deprecated: Enables temporary support for the obsolete functions | ||||
//#define use_deprecated | ||||
#include <vector> | #include <vector> | |||
#include <set> | ||||
#include <stdexcept> | #include <stdexcept> | |||
#include <cstring> | #include <cstring> | |||
#include <cstdlib> | #include <cstdlib> | |||
#include <ostream> | #include <ostream> | |||
#include <functional> | ||||
#include <queue> | ||||
namespace ClipperLib { | namespace ClipperLib { | |||
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; | enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; | |||
enum PolyType { ptSubject, ptClip }; | enum PolyType { ptSubject, ptClip }; | |||
//By far the most widely used winding rules for polygon filling are | //By far the most widely used winding rules for polygon filling are | |||
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32 ) | //EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32 ) | |||
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenG L) | //Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenG L) | |||
//see http://glprogramming.com/red/chapter11.html | //see http://glprogramming.com/red/chapter11.html | |||
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; | enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; | |||
#ifdef use_int32 | typedef signed long long long64; | |||
typedef int cInt; | typedef unsigned long long ulong64; | |||
static cInt const loRange = 0x7FFF; | ||||
static cInt const hiRange = 0x7FFF; | ||||
#else | ||||
typedef signed long long cInt; | ||||
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 | ||||
struct IntPoint { | struct IntPoint { | |||
cInt X; | public: | |||
cInt Y; | long64 X; | |||
#ifdef use_xyz | long64 Y; | |||
cInt Z; | IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {}; | |||
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {}; | friend std::ostream& operator <<(std::ostream &s, IntPoint &p); | |||
#else | ||||
IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {}; | ||||
#endif | ||||
friend inline bool operator== (const IntPoint& a, const IntPoint& b) | ||||
{ | ||||
return a.X == b.X && a.Y == b.Y; | ||||
} | ||||
friend inline bool operator!= (const IntPoint& a, const IntPoint& b) | ||||
{ | ||||
return a.X != b.X || a.Y != b.Y; | ||||
} | ||||
}; | }; | |||
//------------------------------------------------------------------------- ----- | ||||
typedef std::vector< IntPoint > Path; | typedef std::vector< IntPoint > Polygon; | |||
typedef std::vector< Path > Paths; | typedef std::vector< Polygon > Polygons; | |||
inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); | std::ostream& operator <<(std::ostream &s, Polygon &p); | |||
return poly;} | std::ostream& operator <<(std::ostream &s, Polygons &p); | |||
inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); | ||||
return polys;} | ||||
std::ostream& operator <<(std::ostream &s, const IntPoint &p); | struct ExPolygon { | |||
std::ostream& operator <<(std::ostream &s, const Path &p); | Polygon outer; | |||
std::ostream& operator <<(std::ostream &s, const Paths &p); | Polygons holes; | |||
}; | ||||
typedef std::vector< ExPolygon > ExPolygons; | ||||
struct DoublePoint | enum JoinType { jtSquare, jtRound, jtMiter }; | |||
{ | ||||
double X; | bool Orientation(const Polygon &poly); | |||
double Y; | double Area(const Polygon &poly); | |||
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {} | void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, | |||
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {} | double delta, JoinType jointype = jtSquare, double MiterLimit = 2); | |||
void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillT | ||||
ype fillType = pftEvenOdd); | ||||
void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFi | ||||
llType fillType = pftEvenOdd); | ||||
void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd); | ||||
void ReversePolygon(Polygon& p); | ||||
void ReversePolygons(Polygons& p); | ||||
//used internally ... | ||||
enum EdgeSide { esNeither = 0, esLeft = 1, esRight = 2, esBoth = 3 }; | ||||
enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 }; | ||||
struct TEdge { | ||||
long64 xbot; | ||||
long64 ybot; | ||||
long64 xcurr; | ||||
long64 ycurr; | ||||
long64 xtop; | ||||
long64 ytop; | ||||
double dx; | ||||
long64 tmpX; | ||||
PolyType polyType; | ||||
EdgeSide side; | ||||
int windDelta; //1 or -1 depending on winding direction | ||||
int windCnt; | ||||
int windCnt2; //winding count of the opposite polytype | ||||
int outIdx; | ||||
TEdge *next; | ||||
TEdge *prev; | ||||
TEdge *nextInLML; | ||||
TEdge *nextInAEL; | ||||
TEdge *prevInAEL; | ||||
TEdge *nextInSEL; | ||||
TEdge *prevInSEL; | ||||
}; | }; | |||
//------------------------------------------------------------------------- ----- | ||||
#ifdef use_xyz | struct IntersectNode { | |||
typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e | TEdge *edge1; | |||
2bot, IntPoint& e2top, IntPoint& pt); | TEdge *edge2; | |||
#endif | IntPoint pt; | |||
IntersectNode *next; | ||||
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCo | }; | |||
llinear = 4}; | ||||
enum JoinType {jtSquare, jtRound, jtMiter}; | ||||
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOp | ||||
enRound}; | ||||
class PolyNode; | struct LocalMinima { | |||
typedef std::vector< PolyNode* > PolyNodes; | long64 Y; | |||
TEdge *leftBound; | ||||
TEdge *rightBound; | ||||
LocalMinima *next; | ||||
}; | ||||
class PolyNode | struct Scanbeam { | |||
{ | long64 Y; | |||
public: | Scanbeam *next; | |||
PolyNode(); | ||||
virtual ~PolyNode(){}; | ||||
Path Contour; | ||||
PolyNodes Childs; | ||||
PolyNode* Parent; | ||||
PolyNode* GetNext() const; | ||||
bool IsHole() const; | ||||
bool IsOpen() const; | ||||
int ChildCount() const; | ||||
private: | ||||
unsigned Index; //node index in Parent.Childs | ||||
bool m_IsOpen; | ||||
JoinType m_jointype; | ||||
EndType m_endtype; | ||||
PolyNode* GetNextSiblingUp() const; | ||||
void AddChild(PolyNode& child); | ||||
friend class Clipper; //to access Index | ||||
friend class ClipperOffset; | ||||
}; | }; | |||
class PolyTree: public PolyNode | struct OutPt; //forward declaration | |||
{ | ||||
public: | struct OutRec { | |||
~PolyTree(){Clear();}; | int idx; | |||
PolyNode* GetFirst() const; | bool isHole; | |||
void Clear(); | OutRec *FirstLeft; | |||
int Total() const; | OutRec *AppendLink; | |||
private: | OutPt *pts; | |||
PolyNodes AllNodes; | OutPt *bottomPt; | |||
friend class Clipper; //to access AllNodes | OutPt *bottomFlag; | |||
EdgeSide sides; | ||||
}; | ||||
struct OutPt { | ||||
int idx; | ||||
IntPoint pt; | ||||
OutPt *next; | ||||
OutPt *prev; | ||||
}; | ||||
struct JoinRec { | ||||
IntPoint pt1a; | ||||
IntPoint pt1b; | ||||
int poly1Idx; | ||||
IntPoint pt2a; | ||||
IntPoint pt2b; | ||||
int poly2Idx; | ||||
}; | }; | |||
bool Orientation(const Path &poly); | struct HorzJoinRec { | |||
double Area(const Path &poly); | TEdge *edge; | |||
int PointInPolygon(const IntPoint &pt, const Path &path); | int savedIdx; | |||
}; | ||||
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fi | ||||
llType = pftEvenOdd); | struct IntRect { long64 left; long64 top; long64 right; long64 bottom; }; | |||
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType | ||||
fillType = pftEvenOdd); | ||||
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd); | ||||
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1. | ||||
415); | ||||
void CleanPolygon(Path& poly, 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 MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, b | ||||
ool pathIsClosed); | ||||
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 ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths); | ||||
void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths); | ||||
void ReversePath(Path& p); | ||||
void ReversePaths(Paths& p); | ||||
struct IntRect { cInt left; cInt top; cInt right; cInt bottom; }; | ||||
//enums that are used internally ... | ||||
enum EdgeSide { esLeft = 1, esRight = 2}; | ||||
//forward declarations (for stuff used internally) ... | ||||
struct TEdge; | ||||
struct IntersectNode; | ||||
struct LocalMinimum; | ||||
struct Scanbeam; | ||||
struct OutPt; | ||||
struct OutRec; | ||||
struct Join; | ||||
typedef std::vector < OutRec* > PolyOutList; | typedef std::vector < OutRec* > PolyOutList; | |||
typedef std::vector < TEdge* > EdgeList; | typedef std::vector < TEdge* > EdgeList; | |||
typedef std::vector < Join* > JoinList; | typedef std::vector < JoinRec* > JoinList; | |||
typedef std::vector < IntersectNode* > IntersectList; | typedef std::vector < HorzJoinRec* > HorzJoinList; | |||
//------------------------------------------------------------------------- | ||||
----- | ||||
//ClipperBase is the ancestor to the Clipper class. It should not be | //ClipperBase is the ancestor to the Clipper class. It should not be | |||
//instantiated directly. This class simply abstracts the conversion of sets of | //instantiated directly. This class simply abstracts the conversion of sets of | |||
//polygon coordinates into edge objects that are stored in a LocalMinima li st. | //polygon coordinates into edge objects that are stored in a LocalMinima li st. | |||
class ClipperBase | class ClipperBase | |||
{ | { | |||
public: | public: | |||
ClipperBase(); | ClipperBase(); | |||
virtual ~ClipperBase(); | virtual ~ClipperBase(); | |||
bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed); | bool AddPolygon(const Polygon &pg, PolyType polyType); | |||
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); | bool AddPolygons( const Polygons &ppg, PolyType polyType); | |||
virtual void Clear(); | virtual void Clear(); | |||
IntRect GetBounds(); | IntRect GetBounds(); | |||
bool PreserveCollinear() {return m_PreserveCollinear;}; | ||||
void PreserveCollinear(bool value) {m_PreserveCollinear = value;}; | ||||
protected: | protected: | |||
void DisposeLocalMinimaList(); | void DisposeLocalMinimaList(); | |||
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed); | TEdge* AddBoundsToLML(TEdge *e); | |||
void PopLocalMinima(); | void PopLocalMinima(); | |||
virtual void Reset(); | virtual void Reset(); | |||
TEdge* ProcessBound(TEdge* E, bool IsClockwise); | void InsertLocalMinima(LocalMinima *newLm); | |||
void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed); | LocalMinima *m_CurrentLM; | |||
TEdge* DescendToMin(TEdge *&E); | LocalMinima *m_MinimaList; | |||
void AscendToMax(TEdge *&E, bool Appending, bool IsClosed); | ||||
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_HasOpenPaths; | ||||
}; | }; | |||
//------------------------------------------------------------------------- ----- | ||||
class Clipper : public virtual ClipperBase | class Clipper : public virtual ClipperBase | |||
{ | { | |||
public: | public: | |||
Clipper(int initOptions = 0); | Clipper(); | |||
~Clipper(); | ~Clipper(); | |||
bool Execute(ClipType clipType, | bool Execute(ClipType clipType, | |||
Paths &solution, | Polygons &solution, | |||
PolyFillType subjFillType = pftEvenOdd, | PolyFillType subjFillType = pftEvenOdd, | |||
PolyFillType clipFillType = pftEvenOdd); | PolyFillType clipFillType = pftEvenOdd); | |||
bool Execute(ClipType clipType, | bool Execute(ClipType clipType, | |||
PolyTree &polytree, | ExPolygons &solution, | |||
PolyFillType subjFillType = pftEvenOdd, | PolyFillType subjFillType = pftEvenOdd, | |||
PolyFillType clipFillType = pftEvenOdd); | PolyFillType clipFillType = pftEvenOdd); | |||
void Clear(); | ||||
bool ReverseSolution() {return m_ReverseOutput;}; | bool ReverseSolution() {return m_ReverseOutput;}; | |||
void ReverseSolution(bool value) {m_ReverseOutput = value;}; | void ReverseSolution(bool value) {m_ReverseOutput = value;}; | |||
bool StrictlySimple() {return m_StrictSimple;}; | ||||
void StrictlySimple(bool value) {m_StrictSimple = value;}; | ||||
//set the callback function for z value filling on intersections (otherwi | ||||
se Z is 0) | ||||
#ifdef use_xyz | ||||
void ZFillFunction(ZFillCallback zFillFunc); | ||||
#endif | ||||
protected: | protected: | |||
void Reset(); | void Reset(); | |||
virtual bool ExecuteInternal(); | virtual bool ExecuteInternal(bool fixHoleLinkages); | |||
private: | private: | |||
PolyOutList m_PolyOuts; | PolyOutList m_PolyOuts; | |||
JoinList m_Joins; | JoinList m_Joins; | |||
JoinList m_GhostJoins; | HorzJoinList m_HorizJoins; | |||
IntersectList m_IntersectList; | ||||
ClipType m_ClipType; | ClipType m_ClipType; | |||
typedef std::priority_queue<cInt> ScanbeamList; | Scanbeam *m_Scanbeam; | |||
ScanbeamList m_Scanbeam; | ||||
TEdge *m_ActiveEdges; | TEdge *m_ActiveEdges; | |||
TEdge *m_SortedEdges; | TEdge *m_SortedEdges; | |||
bool m_ExecuteLocked; | IntersectNode *m_IntersectNodes; | |||
PolyFillType m_ClipFillType; | bool m_ExecuteLocked; | |||
PolyFillType m_SubjFillType; | PolyFillType m_ClipFillType; | |||
bool m_ReverseOutput; | PolyFillType m_SubjFillType; | |||
bool m_UsingPolyTree; | bool m_ReverseOutput; | |||
bool m_StrictSimple; | void DisposeScanbeamList(); | |||
#ifdef use_xyz | ||||
ZFillCallback m_ZFill; //custom callback | ||||
#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); | void InsertScanbeam(const long64 Y); | |||
cInt PopScanbeam(); | long64 PopScanbeam(); | |||
void InsertLocalMinimaIntoAEL(const cInt botY); | void InsertLocalMinimaIntoAEL(const long64 botY); | |||
void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge); | void InsertEdgeIntoAEL(TEdge *edge); | |||
void AddEdgeToSEL(TEdge *edge); | void AddEdgeToSEL(TEdge *edge); | |||
void CopyAELToSEL(); | void CopyAELToSEL(); | |||
void DeleteFromSEL(TEdge *e); | void DeleteFromSEL(TEdge *e); | |||
void DeleteFromAEL(TEdge *e); | void DeleteFromAEL(TEdge *e); | |||
void UpdateEdgeIntoAEL(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 long64 XPos); | |||
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); | void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); | |||
void DoMaxima(TEdge *e); | void DoMaxima(TEdge *e, long64 topY); | |||
void ProcessHorizontals(bool IsTopOfScanbeam); | void ProcessHorizontals(); | |||
void ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam); | void ProcessHorizontal(TEdge *horzEdge); | |||
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); | void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); | |||
OutRec* GetOutRec(int idx); | ||||
void AppendPolygon(TEdge *e1, TEdge *e2); | void AppendPolygon(TEdge *e1, TEdge *e2); | |||
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt); | void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt); | |||
void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt); | ||||
void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt); | ||||
void IntersectEdges(TEdge *e1, TEdge *e2, | ||||
const IntPoint &pt, IntersectProtects protects); | ||||
OutRec* CreateOutRec(); | OutRec* CreateOutRec(); | |||
OutPt* AddOutPt(TEdge *e, const IntPoint &pt); | void AddOutPt(TEdge *e, const IntPoint &pt); | |||
void DisposeAllOutRecs(); | void DisposeBottomPt(OutRec &outRec); | |||
void DisposeAllPolyPts(); | ||||
void DisposeOutRec(PolyOutList::size_type index); | void DisposeOutRec(PolyOutList::size_type index); | |||
bool ProcessIntersections(const cInt topY); | bool ProcessIntersections(const long64 botY, const long64 topY); | |||
void BuildIntersectList(const cInt topY); | void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt); | |||
void BuildIntersectList(const long64 botY, const long64 topY); | ||||
void ProcessIntersectList(); | void ProcessIntersectList(); | |||
void ProcessEdgesAtTopOfScanbeam(const cInt topY); | void ProcessEdgesAtTopOfScanbeam(const long64 topY); | |||
void BuildResult(Paths& polys); | void BuildResult(Polygons& polys); | |||
void BuildResult2(PolyTree& polytree); | void BuildResultEx(ExPolygons& polys); | |||
void SetHoleState(TEdge *e, OutRec *outrec); | void SetHoleState(TEdge *e, OutRec *OutRec); | |||
void DisposeIntersectNodes(); | void DisposeIntersectNodes(); | |||
bool FixupIntersectionOrder(); | bool FixupIntersections(); | |||
void FixupOutPolygon(OutRec &outrec); | void FixupOutPolygon(OutRec &outRec); | |||
bool IsHole(TEdge *e); | bool IsHole(TEdge *e); | |||
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl); | void FixHoleLinkage(OutRec *outRec); | |||
void FixHoleLinkage(OutRec &outrec); | void CheckHoleLinkages1(OutRec *outRec1, OutRec *outRec2); | |||
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt); | void CheckHoleLinkages2(OutRec *outRec1, OutRec *outRec2); | |||
void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1); | ||||
void ClearJoins(); | void ClearJoins(); | |||
void ClearGhostJoins(); | void AddHorzJoin(TEdge *e, int idx); | |||
void AddGhostJoin(OutPt *op, const IntPoint offPt); | void ClearHorzJoins(); | |||
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2); | void JoinCommonEdges(bool fixHoleLinkages); | |||
void JoinCommonEdges(); | ||||
void DoSimplePolygons(); | ||||
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec); | ||||
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec); | ||||
#ifdef use_xyz | ||||
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2); | ||||
#endif | ||||
}; | }; | |||
//------------------------------------------------------------------------- ----- | ||||
class ClipperOffset | //------------------------------------------------------------------------- | |||
{ | ----- | |||
public: | ||||
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25); | ||||
~ClipperOffset(); | ||||
void AddPath(const Path& path, JoinType joinType, EndType endType); | ||||
void AddPaths(const Paths& paths, JoinType joinType, EndType endType); | ||||
void Execute(Paths& solution, double delta); | ||||
void Execute(PolyTree& solution, double delta); | ||||
void Clear(); | ||||
double MiterLimit; | ||||
double ArcTolerance; | ||||
private: | ||||
Paths m_destPolys; | ||||
Path m_srcPoly; | ||||
Path m_destPoly; | ||||
std::vector<DoublePoint> m_normals; | ||||
double m_delta, m_sinA, m_sin, m_cos; | ||||
double m_miterLim, m_StepsPerRad; | ||||
IntPoint m_lowest; | ||||
PolyNode m_polyNodes; | ||||
void FixOrientations(); | ||||
void DoOffset(double delta); | ||||
void OffsetPoint(int j, int& k, JoinType jointype); | ||||
void DoSquare(int j, int k); | ||||
void DoMiter(int j, int k, double r); | ||||
void DoRound(int j, int k); | ||||
}; | ||||
//------------------------------------------------------------------------- ----- | //------------------------------------------------------------------------- ----- | |||
class clipperException : public std::exception | class clipperException : public std::exception | |||
{ | { | |||
public: | public: | |||
clipperException(const char* description): m_descr(description) {} | clipperException(const char* description): m_descr(description) {} | |||
virtual ~clipperException() throw() {} | virtual ~clipperException() throw() {} | |||
virtual const char* what() const throw() {return m_descr.c_str();} | virtual const char* what() const throw() {return m_descr.c_str();} | |||
private: | private: | |||
std::string m_descr; | std::string m_descr; | |||
End of changes. 47 change blocks. | ||||
271 lines changed or deleted | 171 lines changed or added | |||