1
/*******************************************************************************
3
* Author : Angus Johnson *
5
* Date : 30 August 2012 *
6
* Website : http://www.angusj.com *
7
* Copyright : Angus Johnson 2010-2012 *
10
* Use, modification & distribution is subject to Boost Software License Ver 1. *
11
* http://www.boost.org/LICENSE_1_0.txt *
14
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
15
* "A generic solution to polygon clipping" *
16
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
17
* http://portal.acm.org/citation.cfm?id=129906 *
19
* Computer graphics and geometric modeling: implementation and algorithms *
21
* Springer; 1 edition (January 4, 2005) *
22
* http://books.google.com/books?q=vatti+clipping+agoston *
25
* "Polygon Offsetting by Computing Winding Numbers" *
26
* Paper no. DETC2005-85513 pp. 565-575 *
27
* ASME 2005 International Design Engineering Technical Conferences *
28
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
29
* September 24�28, 2005 , Long Beach, California, USA *
30
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
32
*******************************************************************************/
43
namespace ClipperLib {
45
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
46
enum PolyType { ptSubject, ptClip };
47
//By far the most widely used winding rules for polygon filling are
48
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
49
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
50
//see http://glprogramming.com/red/chapter11.html
51
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
53
typedef signed long long long64;
54
typedef unsigned long long ulong64;
60
IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {};
61
friend std::ostream& operator <<(std::ostream &s, IntPoint &p);
64
typedef std::vector< IntPoint > Polygon;
65
typedef std::vector< Polygon > Polygons;
67
std::ostream& operator <<(std::ostream &s, Polygon &p);
68
std::ostream& operator <<(std::ostream &s, Polygons &p);
74
typedef std::vector< ExPolygon > ExPolygons;
76
enum JoinType { jtSquare, jtRound, jtMiter };
78
bool Orientation(const Polygon &poly);
79
double Area(const Polygon &poly);
80
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
81
double delta, JoinType jointype = jtSquare, double MiterLimit = 2);
82
void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
83
void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
84
void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd);
86
void ReversePolygon(Polygon& p);
87
void ReversePolygons(Polygons& p);
90
enum EdgeSide { esNeither = 0, esLeft = 1, esRight = 2, esBoth = 3 };
91
enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 };
104
int windDelta; //1 or -1 depending on winding direction
106
int windCnt2; //winding count of the opposite polytype
117
struct IntersectNode {
136
struct OutPt; //forward declaration
170
struct IntRect { long64 left; long64 top; long64 right; long64 bottom; };
172
typedef std::vector < OutRec* > PolyOutList;
173
typedef std::vector < TEdge* > EdgeList;
174
typedef std::vector < JoinRec* > JoinList;
175
typedef std::vector < HorzJoinRec* > HorzJoinList;
177
//ClipperBase is the ancestor to the Clipper class. It should not be
178
//instantiated directly. This class simply abstracts the conversion of sets of
179
//polygon coordinates into edge objects that are stored in a LocalMinima list.
184
virtual ~ClipperBase();
185
bool AddPolygon(const Polygon &pg, PolyType polyType);
186
bool AddPolygons( const Polygons &ppg, PolyType polyType);
187
virtual void Clear();
190
void DisposeLocalMinimaList();
191
TEdge* AddBoundsToLML(TEdge *e);
192
void PopLocalMinima();
193
virtual void Reset();
194
void InsertLocalMinima(LocalMinima *newLm);
195
LocalMinima *m_CurrentLM;
196
LocalMinima *m_MinimaList;
201
class Clipper : public virtual ClipperBase
206
bool Execute(ClipType clipType,
208
PolyFillType subjFillType = pftEvenOdd,
209
PolyFillType clipFillType = pftEvenOdd);
210
bool Execute(ClipType clipType,
211
ExPolygons &solution,
212
PolyFillType subjFillType = pftEvenOdd,
213
PolyFillType clipFillType = pftEvenOdd);
215
bool ReverseSolution() {return m_ReverseOutput;};
216
void ReverseSolution(bool value) {m_ReverseOutput = value;};
219
virtual bool ExecuteInternal(bool fixHoleLinkages);
221
PolyOutList m_PolyOuts;
223
HorzJoinList m_HorizJoins;
225
Scanbeam *m_Scanbeam;
226
TEdge *m_ActiveEdges;
227
TEdge *m_SortedEdges;
228
IntersectNode *m_IntersectNodes;
229
bool m_ExecuteLocked;
230
PolyFillType m_ClipFillType;
231
PolyFillType m_SubjFillType;
232
bool m_ReverseOutput;
233
void DisposeScanbeamList();
234
void SetWindingCount(TEdge& edge);
235
bool IsEvenOddFillType(const TEdge& edge) const;
236
bool IsEvenOddAltFillType(const TEdge& edge) const;
237
void InsertScanbeam(const long64 Y);
238
long64 PopScanbeam();
239
void InsertLocalMinimaIntoAEL(const long64 botY);
240
void InsertEdgeIntoAEL(TEdge *edge);
241
void AddEdgeToSEL(TEdge *edge);
243
void DeleteFromSEL(TEdge *e);
244
void DeleteFromAEL(TEdge *e);
245
void UpdateEdgeIntoAEL(TEdge *&e);
246
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
247
bool IsContributing(const TEdge& edge) const;
248
bool IsTopHorz(const long64 XPos);
249
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
250
void DoMaxima(TEdge *e, long64 topY);
251
void ProcessHorizontals();
252
void ProcessHorizontal(TEdge *horzEdge);
253
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
254
void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
255
void AppendPolygon(TEdge *e1, TEdge *e2);
256
void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
257
void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
258
void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
259
void IntersectEdges(TEdge *e1, TEdge *e2,
260
const IntPoint &pt, IntersectProtects protects);
261
OutRec* CreateOutRec();
262
void AddOutPt(TEdge *e, const IntPoint &pt);
263
void DisposeBottomPt(OutRec &outRec);
264
void DisposeAllPolyPts();
265
void DisposeOutRec(PolyOutList::size_type index);
266
bool ProcessIntersections(const long64 botY, const long64 topY);
267
void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt);
268
void BuildIntersectList(const long64 botY, const long64 topY);
269
void ProcessIntersectList();
270
void ProcessEdgesAtTopOfScanbeam(const long64 topY);
271
void BuildResult(Polygons& polys);
272
void BuildResultEx(ExPolygons& polys);
273
void SetHoleState(TEdge *e, OutRec *OutRec);
274
void DisposeIntersectNodes();
275
bool FixupIntersections();
276
void FixupOutPolygon(OutRec &outRec);
277
bool IsHole(TEdge *e);
278
void FixHoleLinkage(OutRec *outRec);
279
void CheckHoleLinkages1(OutRec *outRec1, OutRec *outRec2);
280
void CheckHoleLinkages2(OutRec *outRec1, OutRec *outRec2);
281
void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1);
283
void AddHorzJoin(TEdge *e, int idx);
284
void ClearHorzJoins();
285
void JoinCommonEdges(bool fixHoleLinkages);
288
//------------------------------------------------------------------------------
289
//------------------------------------------------------------------------------
291
class clipperException : public std::exception
294
clipperException(const char* description): m_descr(description) {}
295
virtual ~clipperException() throw() {}
296
virtual const char* what() const throw() {return m_descr.c_str();}
300
//------------------------------------------------------------------------------
302
} //ClipperLib namespace