nndeploy C++ API  0.2.0
nndeploy C++ API
clipper.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * *
3  * Author : Angus Johnson * Version : 6.4.2 * Date : 27 February
4  *2017 * Website :
5  *http://www.angusj.com * Copyright :
6  *Angus Johnson 2010-2017 *
7  * *
8  * License: * Use, modification & distribution is subject to Boost Software
9  *License Ver 1. * http://www.boost.org/LICENSE_1_0.txt *
10  * *
11  * Attributions: * The code in this library is an extension of Bala Vatti's
12  *clipping algorithm: * "A generic solution to polygon clipping" *
13  * Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
14  * http://portal.acm.org/citation.cfm?id=129906 *
15  * *
16  * Computer graphics and geometric modeling: implementation and algorithms * By
17  *Max K. Agoston *
18  * Springer; 1 edition (January 4, 2005) *
19  * http://books.google.com/books?q=vatti+clipping+agoston *
20  * *
21  * See also: * "Polygon Offsetting by Computing Winding Numbers" * Paper no.
22  *DETC2005-85513 pp. 565-575 * ASME 2005
23  *International Design Engineering Technical Conferences * and
24  *Computers and Information in Engineering Conference (IDETC/CIE2005) *
25  * September 24-28, 2005 , Long Beach, California, USA *
26  * http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
27  * *
28  *******************************************************************************/
29 
30 #pragma once
31 #ifndef clipper_hpp
32 #define clipper_hpp
33 
34 #define CLIPPER_VERSION "6.4.2"
35 
36 // use_int32: When enabled 32bit ints are used instead of 64bit ints. This
37 // improve performance but coordinate values are limited to the range +/- 46340
38 //#define use_int32
39 
40 // use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
41 //#define use_xyz
42 
43 // use_lines: Enables line clipping. Adds a very minor cost to performance.
44 #define use_lines
45 
46 // use_deprecated: Enables temporary support for the obsolete functions
47 //#define use_deprecated
48 
49 #include <cstdlib>
50 #include <cstring>
51 #include <functional>
52 #include <list>
53 #include <ostream>
54 #include <queue>
55 #include <set>
56 #include <stdexcept>
57 #include <vector>
58 
59 namespace ClipperLib {
60 
63 // By far the most widely used winding rules for polygon filling are
64 // EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
65 // Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
66 // see http://glprogramming.com/red/chapter11.html
68 
69 #ifdef use_int32
70 typedef int cInt;
71 static cInt const loRange = 0x7FFF;
72 static cInt const hiRange = 0x7FFF;
73 #else
74 typedef signed long long cInt;
75 static cInt const loRange = 0x3FFFFFFF;
76 static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
77 typedef signed long long long64; // used by Int128 class
78 typedef unsigned long long ulong64;
79 
80 #endif
81 
82 struct IntPoint {
85 #ifdef use_xyz
86  cInt Z;
87  IntPoint(cInt x = 0, cInt y = 0, cInt z = 0) : X(x), Y(y), Z(z){};
88 #else
89  IntPoint(cInt x = 0, cInt y = 0) : X(x), Y(y){};
90 #endif
91 
92  friend inline bool operator==(const IntPoint &a, const IntPoint &b) {
93  return a.X == b.X && a.Y == b.Y;
94  }
95  friend inline bool operator!=(const IntPoint &a, const IntPoint &b) {
96  return a.X != b.X || a.Y != b.Y;
97  }
98 };
99 //------------------------------------------------------------------------------
100 
101 typedef std::vector<IntPoint> Path;
102 typedef std::vector<Path> Paths;
103 
104 inline Path &operator<<(Path &poly, const IntPoint &p) {
105  poly.push_back(p);
106  return poly;
107 }
108 inline Paths &operator<<(Paths &polys, const Path &p) {
109  polys.push_back(p);
110  return polys;
111 }
112 
113 std::ostream &operator<<(std::ostream &s, const IntPoint &p);
114 std::ostream &operator<<(std::ostream &s, const Path &p);
115 std::ostream &operator<<(std::ostream &s, const Paths &p);
116 
117 struct DoublePoint {
118  double X;
119  double Y;
120  DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
121  DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
122 };
123 //------------------------------------------------------------------------------
124 
125 #ifdef use_xyz
126 typedef void (*ZFillCallback)(IntPoint &e1bot, IntPoint &e1top, IntPoint &e2bot,
127  IntPoint &e2top, IntPoint &pt);
128 #endif
129 
134 };
136 enum EndType {
142 };
143 
144 class PolyNode;
145 typedef std::vector<PolyNode *> PolyNodes;
146 
147 class PolyNode {
148  public:
150  virtual ~PolyNode(){};
154  PolyNode *GetNext() const;
155  bool IsHole() const;
156  bool IsOpen() const;
157  int ChildCount() const;
158 
159  private:
160  // PolyNode& operator =(PolyNode& other);
161  unsigned Index; // node index in Parent.Childs
162  bool m_IsOpen;
163  JoinType m_jointype;
164  EndType m_endtype;
165  PolyNode *GetNextSiblingUp() const;
166  void AddChild(PolyNode &child);
167  friend class Clipper; // to access Index
168  friend class ClipperOffset;
169 };
170 
171 class PolyTree : public PolyNode {
172  public:
173  ~PolyTree() { Clear(); };
174  PolyNode *GetFirst() const;
175  void Clear();
176  int Total() const;
177 
178  private:
179  // PolyTree& operator =(PolyTree& other);
180  PolyNodes AllNodes;
181  friend class Clipper; // to access AllNodes
182 };
183 
184 bool Orientation(const Path &poly);
185 double Area(const Path &poly);
186 int PointInPolygon(const IntPoint &pt, const Path &path);
187 
188 void SimplifyPolygon(const Path &in_poly, Paths &out_polys,
189  PolyFillType fillType = pftEvenOdd);
190 void SimplifyPolygons(const Paths &in_polys, Paths &out_polys,
191  PolyFillType fillType = pftEvenOdd);
193 
194 void CleanPolygon(const Path &in_poly, Path &out_poly, double distance = 1.415);
195 void CleanPolygon(Path &poly, double distance = 1.415);
196 void CleanPolygons(const Paths &in_polys, Paths &out_polys,
197  double distance = 1.415);
198 void CleanPolygons(Paths &polys, double distance = 1.415);
199 
200 void MinkowskiSum(const Path &pattern, const Path &path, Paths &solution,
201  bool pathIsClosed);
202 void MinkowskiSum(const Path &pattern, const Paths &paths, Paths &solution,
203  bool pathIsClosed);
204 void MinkowskiDiff(const Path &poly1, const Path &poly2, Paths &solution);
205 
206 void PolyTreeToPaths(const PolyTree &polytree, Paths &paths);
207 void ClosedPathsFromPolyTree(const PolyTree &polytree, Paths &paths);
208 void OpenPathsFromPolyTree(PolyTree &polytree, Paths &paths);
209 
210 void ReversePath(Path &p);
212 
213 struct IntRect {
218 };
219 
220 // enums that are used internally ...
221 enum EdgeSide { esLeft = 1, esRight = 2 };
222 
223 // forward declarations (for stuff used internally) ...
224 struct TEdge;
225 struct IntersectNode;
226 struct LocalMinimum;
227 struct OutPt;
228 struct OutRec;
229 struct Join;
230 
231 typedef std::vector<OutRec *> PolyOutList;
232 typedef std::vector<TEdge *> EdgeList;
233 typedef std::vector<Join *> JoinList;
234 typedef std::vector<IntersectNode *> IntersectList;
235 
236 //------------------------------------------------------------------------------
237 
238 // ClipperBase is the ancestor to the Clipper class. It should not be
239 // instantiated directly. This class simply abstracts the conversion of sets of
240 // polygon coordinates into edge objects that are stored in a LocalMinima list.
241 class ClipperBase {
242  public:
244  virtual ~ClipperBase();
245  virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
246  bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
247  virtual void Clear();
250  void PreserveCollinear(bool value) { m_PreserveCollinear = value; };
251 
252  protected:
254  TEdge *AddBoundsToLML(TEdge *e, bool IsClosed);
255  virtual void Reset();
256  TEdge *ProcessBound(TEdge *E, bool IsClockwise);
257  void InsertScanbeam(const cInt Y);
258  bool PopScanbeam(cInt &Y);
260  bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
261  OutRec *CreateOutRec();
263  void DisposeOutRec(PolyOutList::size_type index);
264  void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
265  void DeleteFromAEL(TEdge *e);
266  void UpdateEdgeIntoAEL(TEdge *&e);
267 
268  typedef std::vector<LocalMinimum> MinimaList;
269  MinimaList::iterator m_CurrentLM;
271 
278 
279  typedef std::priority_queue<cInt> ScanbeamList;
281 };
282 //------------------------------------------------------------------------------
283 
284 class Clipper : public virtual ClipperBase {
285  public:
286  Clipper(int initOptions = 0);
287  bool Execute(ClipType clipType, Paths &solution,
288  PolyFillType fillType = pftEvenOdd);
289  bool Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType,
290  PolyFillType clipFillType);
291  bool Execute(ClipType clipType, PolyTree &polytree,
292  PolyFillType fillType = pftEvenOdd);
293  bool Execute(ClipType clipType, PolyTree &polytree, PolyFillType subjFillType,
294  PolyFillType clipFillType);
295  bool ReverseSolution() { return m_ReverseOutput; };
296  void ReverseSolution(bool value) { m_ReverseOutput = value; };
297  bool StrictlySimple() { return m_StrictSimple; };
298  void StrictlySimple(bool value) { m_StrictSimple = value; };
299 // set the callback function for z value filling on intersections (otherwise Z
300 // is 0)
301 #ifdef use_xyz
302  void ZFillFunction(ZFillCallback zFillFunc);
303 #endif
304  protected:
305  virtual bool ExecuteInternal();
306 
307  private:
308  JoinList m_Joins;
309  JoinList m_GhostJoins;
310  IntersectList m_IntersectList;
311  ClipType m_ClipType;
312  typedef std::list<cInt> MaximaList;
313  MaximaList m_Maxima;
314  TEdge *m_SortedEdges;
315  bool m_ExecuteLocked;
316  PolyFillType m_ClipFillType;
317  PolyFillType m_SubjFillType;
318  bool m_ReverseOutput;
319  bool m_UsingPolyTree;
320  bool m_StrictSimple;
321 #ifdef use_xyz
322  ZFillCallback m_ZFill; // custom callback
323 #endif
324  void SetWindingCount(TEdge &edge);
325  bool IsEvenOddFillType(const TEdge &edge) const;
326  bool IsEvenOddAltFillType(const TEdge &edge) const;
327  void InsertLocalMinimaIntoAEL(const cInt botY);
328  void InsertEdgeIntoAEL(TEdge *edge, TEdge *startEdge);
329  void AddEdgeToSEL(TEdge *edge);
330  bool PopEdgeFromSEL(TEdge *&edge);
331  void CopyAELToSEL();
332  void DeleteFromSEL(TEdge *e);
333  void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
334  bool IsContributing(const TEdge &edge) const;
335  bool IsTopHorz(const cInt XPos);
336  void DoMaxima(TEdge *e);
337  void ProcessHorizontals();
338  void ProcessHorizontal(TEdge *horzEdge);
339  void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
340  OutPt *AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
341  OutRec *GetOutRec(int idx);
342  void AppendPolygon(TEdge *e1, TEdge *e2);
343  void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
344  OutPt *AddOutPt(TEdge *e, const IntPoint &pt);
345  OutPt *GetLastOutPt(TEdge *e);
346  bool ProcessIntersections(const cInt topY);
347  void BuildIntersectList(const cInt topY);
348  void ProcessIntersectList();
349  void ProcessEdgesAtTopOfScanbeam(const cInt topY);
350  void BuildResult(Paths &polys);
351  void BuildResult2(PolyTree &polytree);
352  void SetHoleState(TEdge *e, OutRec *outrec);
353  void DisposeIntersectNodes();
354  bool FixupIntersectionOrder();
355  void FixupOutPolygon(OutRec &outrec);
356  void FixupOutPolyline(OutRec &outrec);
357  bool IsHole(TEdge *e);
358  bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
359  void FixHoleLinkage(OutRec &outrec);
360  void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
361  void ClearJoins();
362  void ClearGhostJoins();
363  void AddGhostJoin(OutPt *op, const IntPoint offPt);
364  bool JoinPoints(Join *j, OutRec *outRec1, OutRec *outRec2);
365  void JoinCommonEdges();
366  void DoSimplePolygons();
367  void FixupFirstLefts1(OutRec *OldOutRec, OutRec *NewOutRec);
368  void FixupFirstLefts2(OutRec *InnerOutRec, OutRec *OuterOutRec);
369  void FixupFirstLefts3(OutRec *OldOutRec, OutRec *NewOutRec);
370 #ifdef use_xyz
371  void SetZ(IntPoint &pt, TEdge &e1, TEdge &e2);
372 #endif
373 };
374 //------------------------------------------------------------------------------
375 
377  public:
378  ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
380  void AddPath(const Path &path, JoinType joinType, EndType endType);
381  void AddPaths(const Paths &paths, JoinType joinType, EndType endType);
382  void Execute(Paths &solution, double delta);
383  void Execute(PolyTree &solution, double delta);
384  void Clear();
385  double MiterLimit;
386  double ArcTolerance;
387 
388  private:
389  Paths m_destPolys;
390  Path m_srcPoly;
391  Path m_destPoly;
392  std::vector<DoublePoint> m_normals;
393  double m_delta, m_sinA, m_sin, m_cos;
394  double m_miterLim, m_StepsPerRad;
395  IntPoint m_lowest;
396  PolyNode m_polyNodes;
397 
398  void FixOrientations();
399  void DoOffset(double delta);
400  void OffsetPoint(int j, int &k, JoinType jointype);
401  void DoSquare(int j, int k);
402  void DoMiter(int j, int k, double r);
403  void DoRound(int j, int k);
404 };
405 //------------------------------------------------------------------------------
406 
407 class clipperException : public std::exception {
408  public:
409  clipperException(const char *description) : m_descr(description) {}
410  virtual ~clipperException() throw() {}
411  virtual const char *what() const throw() { return m_descr.c_str(); }
412 
413  private:
414  std::string m_descr;
415 };
416 //------------------------------------------------------------------------------
417 
418 } // namespace ClipperLib
419 
420 #endif // clipper_hpp
virtual void Reset()
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed)
TEdge * ProcessBound(TEdge *E, bool IsClockwise)
void UpdateEdgeIntoAEL(TEdge *&e)
virtual void Clear()
std::priority_queue< cInt > ScanbeamList
Definition: clipper.h:279
virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
ScanbeamList m_Scanbeam
Definition: clipper.h:280
TEdge * AddBoundsToLML(TEdge *e, bool IsClosed)
void DeleteFromAEL(TEdge *e)
MinimaList m_MinimaList
Definition: clipper.h:270
void PreserveCollinear(bool value)
Definition: clipper.h:250
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2)
MinimaList::iterator m_CurrentLM
Definition: clipper.h:269
void InsertScanbeam(const cInt Y)
bool PopScanbeam(cInt &Y)
std::vector< LocalMinimum > MinimaList
Definition: clipper.h:268
PolyOutList m_PolyOuts
Definition: clipper.h:276
void DisposeOutRec(PolyOutList::size_type index)
bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin)
void AddPath(const Path &path, JoinType joinType, EndType endType)
void AddPaths(const Paths &paths, JoinType joinType, EndType endType)
void Execute(PolyTree &solution, double delta)
ClipperOffset(double miterLimit=2.0, double roundPrecision=0.25)
void Execute(Paths &solution, double delta)
virtual bool ExecuteInternal()
bool Execute(ClipType clipType, Paths &solution, PolyFillType fillType=pftEvenOdd)
bool Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType, PolyFillType clipFillType)
void ReverseSolution(bool value)
Definition: clipper.h:296
bool StrictlySimple()
Definition: clipper.h:297
bool Execute(ClipType clipType, PolyTree &polytree, PolyFillType subjFillType, PolyFillType clipFillType)
void StrictlySimple(bool value)
Definition: clipper.h:298
bool Execute(ClipType clipType, PolyTree &polytree, PolyFillType fillType=pftEvenOdd)
bool ReverseSolution()
Definition: clipper.h:295
Clipper(int initOptions=0)
bool IsHole() const
int ChildCount() const
PolyNode * GetNext() const
PolyNodes Childs
Definition: clipper.h:152
PolyNode * Parent
Definition: clipper.h:153
virtual ~PolyNode()
Definition: clipper.h:150
bool IsOpen() const
PolyNode * GetFirst() const
virtual const char * what() const
Definition: clipper.h:411
clipperException(const char *description)
Definition: clipper.h:409
unsigned long long ulong64
Definition: clipper.h:78
std::vector< IntPoint > Path
Definition: clipper.h:101
@ ioReverseSolution
Definition: clipper.h:131
@ ioPreserveCollinear
Definition: clipper.h:133
@ ioStrictlySimple
Definition: clipper.h:132
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType=pftEvenOdd)
void PolyTreeToPaths(const PolyTree &polytree, Paths &paths)
std::vector< Path > Paths
Definition: clipper.h:102
@ ctIntersection
Definition: clipper.h:61
@ ctUnion
Definition: clipper.h:61
@ ctDifference
Definition: clipper.h:61
double Area(const Path &poly)
void CleanPolygons(const Paths &in_polys, Paths &out_polys, double distance=1.415)
@ ptClip
Definition: clipper.h:62
@ ptSubject
Definition: clipper.h:62
std::vector< PolyNode * > PolyNodes
Definition: clipper.h:144
signed long long cInt
Definition: clipper.h:74
void MinkowskiDiff(const Path &poly1, const Path &poly2, Paths &solution)
Path & operator<<(Path &poly, const IntPoint &p)
Definition: clipper.h:104
signed long long long64
Definition: clipper.h:77
bool Orientation(const Path &poly)
void ClosedPathsFromPolyTree(const PolyTree &polytree, Paths &paths)
std::vector< TEdge * > EdgeList
Definition: clipper.h:232
PolyFillType
Definition: clipper.h:67
@ pftNegative
Definition: clipper.h:67
@ pftPositive
Definition: clipper.h:67
@ pftEvenOdd
Definition: clipper.h:67
@ pftNonZero
Definition: clipper.h:67
void OpenPathsFromPolyTree(PolyTree &polytree, Paths &paths)
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType=pftEvenOdd)
@ jtSquare
Definition: clipper.h:135
std::vector< OutRec * > PolyOutList
Definition: clipper.h:229
void ReversePath(Path &p)
@ etOpenButt
Definition: clipper.h:139
@ etOpenRound
Definition: clipper.h:141
@ etClosedLine
Definition: clipper.h:138
@ etClosedPolygon
Definition: clipper.h:137
@ etOpenSquare
Definition: clipper.h:140
int PointInPolygon(const IntPoint &pt, const Path &path)
void MinkowskiSum(const Path &pattern, const Path &path, Paths &solution, bool pathIsClosed)
void ReversePaths(Paths &p)
std::vector< IntersectNode * > IntersectList
Definition: clipper.h:234
void CleanPolygon(const Path &in_poly, Path &out_poly, double distance=1.415)
std::vector< Join * > JoinList
Definition: clipper.h:233
DoublePoint(double x=0, double y=0)
Definition: clipper.h:120
DoublePoint(IntPoint ip)
Definition: clipper.h:121
friend bool operator==(const IntPoint &a, const IntPoint &b)
Definition: clipper.h:92
IntPoint(cInt x=0, cInt y=0)
Definition: clipper.h:89
friend bool operator!=(const IntPoint &a, const IntPoint &b)
Definition: clipper.h:95