v0.14.0
Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
ClipperLib::Clipper Class Reference

#include <users_modules/mortar_contact/src/clipper.hpp>

Inheritance diagram for ClipperLib::Clipper:
[legend]
Collaboration diagram for ClipperLib::Clipper:
[legend]

Public Member Functions

 Clipper (int initOptions=0)
 
bool Execute (ClipType clipType, Paths &solution, PolyFillType fillType=pftEvenOdd)
 
bool Execute (ClipType clipType, Paths &solution, PolyFillType subjFillType, PolyFillType clipFillType)
 
bool Execute (ClipType clipType, PolyTree &polytree, PolyFillType fillType=pftEvenOdd)
 
bool Execute (ClipType clipType, PolyTree &polytree, PolyFillType subjFillType, PolyFillType clipFillType)
 
bool ReverseSolution ()
 
void ReverseSolution (bool value)
 
bool StrictlySimple ()
 
void StrictlySimple (bool value)
 
- Public Member Functions inherited from ClipperLib::ClipperBase
 ClipperBase ()
 
virtual ~ClipperBase ()
 
virtual bool AddPath (const Path &pg, PolyType PolyTyp, bool Closed)
 
bool AddPaths (const Paths &ppg, PolyType PolyTyp, bool Closed)
 
virtual void Clear ()
 
IntRect GetBounds ()
 
bool PreserveCollinear ()
 
void PreserveCollinear (bool value)
 

Protected Member Functions

virtual bool ExecuteInternal ()
 
- Protected Member Functions inherited from ClipperLib::ClipperBase
void DisposeLocalMinimaList ()
 
TEdgeAddBoundsToLML (TEdge *e, bool IsClosed)
 
virtual void Reset ()
 
TEdgeProcessBound (TEdge *E, bool IsClockwise)
 
void InsertScanbeam (const cInt Y)
 
bool PopScanbeam (cInt &Y)
 
bool LocalMinimaPending ()
 
bool PopLocalMinima (cInt Y, const LocalMinimum *&locMin)
 
OutRecCreateOutRec ()
 
void DisposeAllOutRecs ()
 
void DisposeOutRec (PolyOutList::size_type index)
 
void SwapPositionsInAEL (TEdge *edge1, TEdge *edge2)
 
void DeleteFromAEL (TEdge *e)
 
void UpdateEdgeIntoAEL (TEdge *&e)
 

Private Types

typedef std::list< cIntMaximaList
 

Private Member Functions

void SetWindingCount (TEdge &edge)
 
bool IsEvenOddFillType (const TEdge &edge) const
 
bool IsEvenOddAltFillType (const TEdge &edge) const
 
void InsertLocalMinimaIntoAEL (const cInt botY)
 
void InsertEdgeIntoAEL (TEdge *edge, TEdge *startEdge)
 
void AddEdgeToSEL (TEdge *edge)
 
bool PopEdgeFromSEL (TEdge *&edge)
 
void CopyAELToSEL ()
 
void DeleteFromSEL (TEdge *e)
 
void SwapPositionsInSEL (TEdge *edge1, TEdge *edge2)
 
bool IsContributing (const TEdge &edge) const
 
bool IsTopHorz (const cInt XPos)
 
void DoMaxima (TEdge *e)
 
void ProcessHorizontals ()
 
void ProcessHorizontal (TEdge *horzEdge)
 
void AddLocalMaxPoly (TEdge *e1, TEdge *e2, const IntPoint &pt)
 
OutPtAddLocalMinPoly (TEdge *e1, TEdge *e2, const IntPoint &pt)
 
OutRecGetOutRec (int idx)
 
void AppendPolygon (TEdge *e1, TEdge *e2)
 
void IntersectEdges (TEdge *e1, TEdge *e2, IntPoint &pt)
 
OutPtAddOutPt (TEdge *e, const IntPoint &pt)
 
OutPtGetLastOutPt (TEdge *e)
 
bool ProcessIntersections (const cInt topY)
 
void BuildIntersectList (const cInt topY)
 
void ProcessIntersectList ()
 
void ProcessEdgesAtTopOfScanbeam (const cInt topY)
 
void BuildResult (Paths &polys)
 
void BuildResult2 (PolyTree &polytree)
 
void SetHoleState (TEdge *e, OutRec *outrec)
 
void DisposeIntersectNodes ()
 
bool FixupIntersectionOrder ()
 
void FixupOutPolygon (OutRec &outrec)
 
void FixupOutPolyline (OutRec &outrec)
 
bool IsHole (TEdge *e)
 
bool FindOwnerFromSplitRecs (OutRec &outRec, OutRec *&currOrfl)
 
void FixHoleLinkage (OutRec &outrec)
 
void AddJoin (OutPt *op1, OutPt *op2, const IntPoint offPt)
 
void ClearJoins ()
 
void ClearGhostJoins ()
 
void AddGhostJoin (OutPt *op, const IntPoint offPt)
 
bool JoinPoints (Join *j, OutRec *outRec1, OutRec *outRec2)
 
void JoinCommonEdges ()
 
void DoSimplePolygons ()
 
void FixupFirstLefts1 (OutRec *OldOutRec, OutRec *NewOutRec)
 
void FixupFirstLefts2 (OutRec *InnerOutRec, OutRec *OuterOutRec)
 
void FixupFirstLefts3 (OutRec *OldOutRec, OutRec *NewOutRec)
 

Private Attributes

JoinList m_Joins
 
JoinList m_GhostJoins
 
IntersectList m_IntersectList
 
ClipType m_ClipType
 
MaximaList m_Maxima
 
TEdgem_SortedEdges
 
bool m_ExecuteLocked
 
PolyFillType m_ClipFillType
 
PolyFillType m_SubjFillType
 
bool m_ReverseOutput
 
bool m_UsingPolyTree
 
bool m_StrictSimple
 

Additional Inherited Members

- Protected Types inherited from ClipperLib::ClipperBase
typedef std::vector< LocalMinimumMinimaList
 
typedef std::priority_queue< cIntScanbeamList
 
- Protected Attributes inherited from ClipperLib::ClipperBase
MinimaList::iterator m_CurrentLM
 
MinimaList m_MinimaList
 
bool m_UseFullRange
 
EdgeList m_edges
 
bool m_PreserveCollinear
 
bool m_HasOpenPaths
 
PolyOutList m_PolyOuts
 
TEdgem_ActiveEdges
 
ScanbeamList m_Scanbeam
 

Detailed Description

Definition at line 261 of file clipper.hpp.

Member Typedef Documentation

◆ MaximaList

typedef std::list<cInt> ClipperLib::Clipper::MaximaList
private

Definition at line 294 of file clipper.hpp.

Constructor & Destructor Documentation

◆ Clipper()

ClipperLib::Clipper::Clipper ( int  initOptions = 0)

Definition at line 1510 of file clipper.cpp.

1510 {
1511  if( m_ExecuteLocked ) return false;
1512  if (m_HasOpenPaths)
1513  throw clipperException("Error: PolyTree struct is needed for open path clipping.");
1514  m_ExecuteLocked = true;
1515  solution.resize(0);
1516  m_SubjFillType = subjFillType;
1517  m_ClipFillType = clipFillType;
1518  m_ClipType = clipType;
1519  m_UsingPolyTree = false;
1520  bool succeeded = ExecuteInternal();
1521  if (succeeded) BuildResult(solution);

Member Function Documentation

◆ AddEdgeToSEL()

void ClipperLib::Clipper::AddEdgeToSEL ( TEdge edge)
private

Definition at line 1936 of file clipper.cpp.

1943 {
1944  Join* j = new Join;
1945  j->OutPt1 = op1;
1946  j->OutPt2 = op2;
1947  j->OffPt = OffPt;
1948  m_Joins.push_back(j);
1949 }
1950 //------------------------------------------------------------------------------
1951 
1952 void Clipper::ClearJoins()
1953 {

◆ AddGhostJoin()

void ClipperLib::Clipper::AddGhostJoin ( OutPt op,
const IntPoint  offPt 
)
private

Definition at line 2004 of file clipper.cpp.

2004  {
2005  InsertEdgeIntoAEL(lb, 0);
2006  InsertEdgeIntoAEL(rb, lb);
2007  SetWindingCount( *lb );
2008  rb->WindCnt = lb->WindCnt;
2009  rb->WindCnt2 = lb->WindCnt2;
2010  if (IsContributing(*lb))
2011  Op1 = AddLocalMinPoly(lb, rb, lb->Bot);

◆ AddJoin()

void ClipperLib::Clipper::AddJoin ( OutPt op1,
OutPt op2,
const IntPoint  offPt 
)
private

Definition at line 1978 of file clipper.cpp.

1979 {
1980  const LocalMinimum *lm;
1981  while (PopLocalMinima(botY, lm))
1982  {
1983  TEdge* lb = lm->LeftBound;
1984  TEdge* rb = lm->RightBound;
1985 

◆ AddLocalMaxPoly()

void ClipperLib::Clipper::AddLocalMaxPoly ( TEdge e1,
TEdge e2,
const IntPoint pt 
)
private

Definition at line 1920 of file clipper.cpp.

1921 {
1922  if (!m_SortedEdges) return false;
1923  edge = m_SortedEdges;
1925  return true;
1926 }
1927 //------------------------------------------------------------------------------
1928 
1929 void Clipper::CopyAELToSEL()
1930 {
1931  TEdge* e = m_ActiveEdges;
1932  m_SortedEdges = e;
1933  while ( e )

◆ AddLocalMinPoly()

OutPt * ClipperLib::Clipper::AddLocalMinPoly ( TEdge e1,
TEdge e2,
const IntPoint pt 
)
private

Definition at line 1877 of file clipper.cpp.

1885 {
1886  AddOutPt( e1, Pt );
1887  if (e2->WindDelta == 0) AddOutPt(e2, Pt);
1888  if( e1->OutIdx == e2->OutIdx )
1889  {
1890  e1->OutIdx = Unassigned;
1891  e2->OutIdx = Unassigned;
1892  }
1893  else if (e1->OutIdx < e2->OutIdx)
1894  AppendPolygon(e1, e2);
1895  else
1896  AppendPolygon(e2, e1);
1897 }
1898 //------------------------------------------------------------------------------
1899 
1900 void Clipper::AddEdgeToSEL(TEdge *edge)
1901 {
1902  //SEL pointers in PEdge are reused to build a list of horizontal edges.
1903  //However, we don't need to worry about order with horizontal edge processing.
1904  if( !m_SortedEdges )
1905  {
1906  m_SortedEdges = edge;
1907  edge->PrevInSEL = 0;
1908  edge->NextInSEL = 0;
1909  }
1910  else
1911  {
1912  edge->NextInSEL = m_SortedEdges;
1913  edge->PrevInSEL = 0;
1914  m_SortedEdges->PrevInSEL = edge;
1915  m_SortedEdges = edge;
1916  }
1917 }

◆ AddOutPt()

OutPt * ClipperLib::Clipper::AddOutPt ( TEdge e,
const IntPoint pt 
)
private

Definition at line 2499 of file clipper.cpp.

2503 {
2504  OutRec *outRec = m_PolyOuts[e->OutIdx];
2505  if (e->Side == esLeft)
2506  return outRec->Pts;
2507  else
2508  return outRec->Pts->Prev;
2509 }
2510 //------------------------------------------------------------------------------
2511 
2513 {
2514  TEdge* horzEdge;
2515  while (PopEdgeFromSEL(horzEdge))
2516  ProcessHorizontal(horzEdge);
2517 }
2518 //------------------------------------------------------------------------------
2519 
2520 inline bool IsMinima(TEdge *e)
2521 {
2522  return e && (e->Prev->NextInLML != e) && (e->Next->NextInLML != e);
2523 }
2524 //------------------------------------------------------------------------------
2525 
2526 inline bool IsMaxima(TEdge *e, const cInt Y)
2527 {
2528  return e && e->Top.Y == Y && !e->NextInLML;
2529 }
2530 //------------------------------------------------------------------------------
2531 
2532 inline bool IsIntermediate(TEdge *e, const cInt Y)
2533 {
2534  return e->Top.Y == Y && e->NextInLML;
2535 }

◆ AppendPolygon()

void ClipperLib::Clipper::AppendPolygon ( TEdge e1,
TEdge e2 
)
private

Definition at line 2403 of file clipper.cpp.

2411  {
2412  if( e2->Side == esRight )
2413  {
2414  //a b c z y x
2415  ReversePolyPtLinks(p2_lft);
2416  p1_rt->Next = p2_rt;
2417  p2_rt->Prev = p1_rt;
2418  p2_lft->Next = p1_lft;
2419  p1_lft->Prev = p2_lft;
2420  } else
2421  {
2422  //a b c x y z
2423  p1_rt->Next = p2_lft;
2424  p2_lft->Prev = p1_rt;
2425  p1_lft->Prev = p2_rt;
2426  p2_rt->Next = p1_lft;
2427  }
2428  }
2429 
2430  outRec1->BottomPt = 0;
2431  if (holeStateRec == outRec2)
2432  {
2433  if (outRec2->FirstLeft != outRec1)
2434  outRec1->FirstLeft = outRec2->FirstLeft;
2435  outRec1->IsHole = outRec2->IsHole;
2436  }
2437  outRec2->Pts = 0;
2438  outRec2->BottomPt = 0;
2439  outRec2->FirstLeft = outRec1;
2440 
2441  int OKIdx = e1->OutIdx;
2442  int ObsoleteIdx = e2->OutIdx;
2443 
2444  e1->OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly
2445  e2->OutIdx = Unassigned;
2446 
2447  TEdge* e = m_ActiveEdges;
2448  while( e )
2449  {
2450  if( e->OutIdx == ObsoleteIdx )
2451  {
2452  e->OutIdx = OKIdx;
2453  e->Side = e1->Side;
2454  break;
2455  }
2456  e = e->NextInAEL;
2457  }
2458 
2459  outRec2->Idx = outRec1->Idx;
2460 }
2461 //------------------------------------------------------------------------------
2462 
2463 OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
2464 {
2465  if( e->OutIdx < 0 )
2466  {
2467  OutRec *outRec = CreateOutRec();
2468  outRec->IsOpen = (e->WindDelta == 0);
2469  OutPt* newOp = new OutPt;
2470  outRec->Pts = newOp;
2471  newOp->Idx = outRec->Idx;
2472  newOp->Pt = pt;
2473  newOp->Next = newOp;
2474  newOp->Prev = newOp;
2475  if (!outRec->IsOpen)
2476  SetHoleState(e, outRec);
2477  e->OutIdx = outRec->Idx;
2478  return newOp;
2479  } else
2480  {
2481  OutRec *outRec = m_PolyOuts[e->OutIdx];
2482  //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most'
2483  OutPt* op = outRec->Pts;
2484 
2485  bool ToFront = (e->Side == esLeft);
2486  if (ToFront && (pt == op->Pt)) return op;
2487  else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev;
2488 
2489  OutPt* newOp = new OutPt;
2490  newOp->Idx = outRec->Idx;
2491  newOp->Pt = pt;
2492  newOp->Next = op;
2493  newOp->Prev = op->Prev;
2494  newOp->Prev->Next = newOp;
2495  op->Prev = newOp;
2496  if (ToFront) outRec->Pts = newOp;

◆ BuildIntersectList()

void ClipperLib::Clipper::BuildIntersectList ( const cInt  topY)
private

Definition at line 2888 of file clipper.cpp.

2903 {
2904  for (size_t i = 0; i < m_IntersectList.size(); ++i)
2905  {
2906  IntersectNode* iNode = m_IntersectList[i];
2907  {
2908  IntersectEdges( iNode->Edge1, iNode->Edge2, iNode->Pt);
2909  SwapPositionsInAEL( iNode->Edge1 , iNode->Edge2 );
2910  }
2911  delete iNode;
2912  }
2913  m_IntersectList.clear();
2914 }
2915 //------------------------------------------------------------------------------
2916 
2917 bool IntersectListSort(IntersectNode* node1, IntersectNode* node2)
2918 {
2919  return node2->Pt.Y < node1->Pt.Y;
2920 }
2921 //------------------------------------------------------------------------------
2922 
2923 inline bool EdgesAdjacent(const IntersectNode &inode)
2924 {
2925  return (inode.Edge1->NextInSEL == inode.Edge2) ||
2926  (inode.Edge1->PrevInSEL == inode.Edge2);
2927 }
2928 //------------------------------------------------------------------------------
2929 
2931 {
2932  //pre-condition: intersections are sorted Bottom-most first.
2933  //Now it's crucial that intersections are made only between adjacent edges,
2934  //so to ensure this the order of intersections may need adjusting ...

◆ BuildResult()

void ClipperLib::Clipper::BuildResult ( Paths polys)
private

Definition at line 3228 of file clipper.cpp.

3233  {
3234  pn->Contour.push_back(op->Pt);
3235  op = op->Prev;
3236  }
3237  }
3238 
3239  //fixup PolyNode links etc ...
3240  polytree.Childs.reserve(m_PolyOuts.size());
3241  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++)
3242  {
3243  OutRec* outRec = m_PolyOuts[i];
3244  if (!outRec->PolyNd) continue;
3245  if (outRec->IsOpen)
3246  {

◆ BuildResult2()

void ClipperLib::Clipper::BuildResult2 ( PolyTree polytree)
private

Definition at line 3249 of file clipper.cpp.

3259 {
3260  //just swap the contents (because fIntersectNodes is a single-linked-list)
3261  IntersectNode inode = int1; //gets a copy of Int1
3262  int1.Edge1 = int2.Edge1;
3263  int1.Edge2 = int2.Edge2;
3264  int1.Pt = int2.Pt;
3265  int2.Edge1 = inode.Edge1;
3266  int2.Edge2 = inode.Edge2;
3267  int2.Pt = inode.Pt;
3268 }
3269 //------------------------------------------------------------------------------
3270 
3271 inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
3272 {
3273  if (e2.Curr.X == e1.Curr.X)
3274  {
3275  if (e2.Top.Y > e1.Top.Y)
3276  return e2.Top.X < TopX(e1, e2.Top.Y);
3277  else return e1.Top.X > TopX(e2, e1.Top.Y);
3278  }
3279  else return e2.Curr.X < e1.Curr.X;
3280 }
3281 //------------------------------------------------------------------------------
3282 
3283 bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2,
3284  cInt& Left, cInt& Right)
3285 {
3286  if (a1 < a2)
3287  {
3288  if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);}
3289  else {Left = std::max(a1,b2); Right = std::min(a2,b1);}
3290  }
3291  else

◆ ClearGhostJoins()

void ClipperLib::Clipper::ClearGhostJoins ( )
private

Definition at line 1996 of file clipper.cpp.

1996  {
1997  InsertEdgeIntoAEL(lb, 0);
1998  SetWindingCount(*lb);
1999  if (IsContributing(*lb))
2000  Op1 = AddOutPt(lb, lb->Bot);
2001  InsertScanbeam(lb->Top.Y);

◆ ClearJoins()

void ClipperLib::Clipper::ClearJoins ( )
private

Definition at line 1988 of file clipper.cpp.

1988  {
1989  //nb: don't insert LB into either AEL or SEL
1990  InsertEdgeIntoAEL(rb, 0);
1991  SetWindingCount(*rb);
1992  if (IsContributing(*rb))
1993  Op1 = AddOutPt(rb, rb->Bot);

◆ CopyAELToSEL()

void ClipperLib::Clipper::CopyAELToSEL ( )
private

Definition at line 1965 of file clipper.cpp.

1969 {
1970  Join* j = new Join;
1971  j->OutPt1 = op;
1972  j->OutPt2 = 0;
1973  j->OffPt = OffPt;
1974  m_GhostJoins.push_back(j);
1975 }

◆ DeleteFromSEL()

void ClipperLib::Clipper::DeleteFromSEL ( TEdge e)
private

Definition at line 2116 of file clipper.cpp.

2118  {
2119  //ignore subject-subject open path intersections UNLESS they
2120  //are both open paths, AND they are both 'contributing maximas' ...
2121  if (e1->WindDelta == 0 && e2->WindDelta == 0) return;
2122 
2123  //if intersecting a subj line with a subj poly ...
2124  else if (e1->PolyTyp == e2->PolyTyp &&
2125  e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion)
2126  {

◆ DisposeIntersectNodes()

void ClipperLib::Clipper::DisposeIntersectNodes ( )
private

Definition at line 2880 of file clipper.cpp.

◆ DoMaxima()

void ClipperLib::Clipper::DoMaxima ( TEdge e)
private

Definition at line 2989 of file clipper.cpp.

2994  {
2995  AddOutPt(eMaxPair, e->Top);
2996  eMaxPair->OutIdx = Unassigned;
2997  }
2998  DeleteFromAEL(eMaxPair);
2999  }
3000 #endif
3001  else throw clipperException("DoMaxima error");
3002 }
3003 //------------------------------------------------------------------------------
3004 
3006 {
3007  TEdge* e = m_ActiveEdges;
3008  while( e )
3009  {
3010  //1. process maxima, treating them as if they're 'bent' horizontal edges,
3011  // but exclude maxima with horizontal edges. nb: e can't be a horizontal.
3012  bool IsMaximaEdge = IsMaxima(e, topY);
3013 
3014  if(IsMaximaEdge)
3015  {
3016  TEdge* eMaxPair = GetMaximaPairEx(e);
3017  IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair));
3018  }
3019 
3020  if(IsMaximaEdge)
3021  {
3022  if (m_StrictSimple) m_Maxima.push_back(e->Top.X);
3023  TEdge* ePrev = e->PrevInAEL;
3024  DoMaxima(e);
3025  if( !ePrev ) e = m_ActiveEdges;
3026  else e = ePrev->NextInAEL;
3027  }
3028  else
3029  {
3030  //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ...
3031  if (IsIntermediate(e, topY) && IsHorizontal(*e->NextInLML))
3032  {
3033  UpdateEdgeIntoAEL(e);
3034  if (e->OutIdx >= 0)
3035  AddOutPt(e, e->Bot);
3036  AddEdgeToSEL(e);
3037  }
3038  else

◆ DoSimplePolygons()

void ClipperLib::Clipper::DoSimplePolygons ( )
private

Definition at line 4250 of file clipper.cpp.

4250  {
4251  //OutRec1 is contained by OutRec2 ...
4252  outrec2->IsHole = outrec->IsHole;
4253  outrec->IsHole = !outrec2->IsHole;
4254  outrec2->FirstLeft = outrec->FirstLeft;
4255  outrec->FirstLeft = outrec2;
4256  if (m_UsingPolyTree) FixupFirstLefts2(outrec, outrec2);
4257  }
4258  else
4259  {
4260  //the 2 polygons are separate ...
4261  outrec2->IsHole = outrec->IsHole;
4262  outrec2->FirstLeft = outrec->FirstLeft;
4263  if (m_UsingPolyTree) FixupFirstLefts1(outrec, outrec2);
4264  }
4265  op2 = op; //ie get ready for the Next iteration
4266  }
4267  op2 = op2->Next;
4268  }
4269  op = op->Next;
4270  }
4271  while (op != outrec->Pts);
4272  }
4273 }
4274 //------------------------------------------------------------------------------
4275 
4276 void ReversePath(Path& p)
4277 {
4278  std::reverse(p.begin(), p.end());
4279 }
4280 //------------------------------------------------------------------------------
4281 
4282 void ReversePaths(Paths& p)
4283 {
4284  for (Paths::size_type i = 0; i < p.size(); ++i)
4285  ReversePath(p[i]);
4286 }
4287 //------------------------------------------------------------------------------
4288 
4289 void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType)
4290 {
4291  Clipper c;
4292  c.StrictlySimple(true);
4293  c.AddPath(in_poly, ptSubject, true);
4294  c.Execute(ctUnion, out_polys, fillType, fillType);
4295 }
4296 //------------------------------------------------------------------------------
4297 
4298 void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType)
4299 {
4300  Clipper c;
4301  c.StrictlySimple(true);
4302  c.AddPaths(in_polys, ptSubject, true);
4303  c.Execute(ctUnion, out_polys, fillType, fillType);
4304 }
4305 //------------------------------------------------------------------------------
4306 
4307 void SimplifyPolygons(Paths &polys, PolyFillType fillType)
4308 {
4309  SimplifyPolygons(polys, polys, fillType);

◆ Execute() [1/4]

bool ClipperLib::Clipper::Execute ( ClipType  clipType,
Paths solution,
PolyFillType  fillType = pftEvenOdd 
)

Definition at line 1532 of file clipper.cpp.

◆ Execute() [2/4]

bool ClipperLib::Clipper::Execute ( ClipType  clipType,
Paths solution,
PolyFillType  subjFillType,
PolyFillType  clipFillType 
)

Definition at line 1544 of file clipper.cpp.

1546 {
1547  //skip OutRecs that (a) contain outermost polygons or
1548  //(b) already have the correct owner/child linkage ...
1549  if (!outrec.FirstLeft ||
1550  (outrec.IsHole != outrec.FirstLeft->IsHole &&
1551  outrec.FirstLeft->Pts)) return;
1552 
1553  OutRec* orfl = outrec.FirstLeft;
1554  while (orfl && ((orfl->IsHole == outrec.IsHole) || !orfl->Pts))
1555  orfl = orfl->FirstLeft;
1556  outrec.FirstLeft = orfl;
1557 }
1558 //------------------------------------------------------------------------------
1559 
1561 {

◆ Execute() [3/4]

bool ClipperLib::Clipper::Execute ( ClipType  clipType,
PolyTree polytree,
PolyFillType  fillType = pftEvenOdd 
)

Definition at line 1538 of file clipper.cpp.

◆ Execute() [4/4]

bool ClipperLib::Clipper::Execute ( ClipType  clipType,
PolyTree polytree,
PolyFillType  subjFillType,
PolyFillType  clipFillType 
)

Definition at line 1564 of file clipper.cpp.

1573  {
1575  ClearGhostJoins();
1576  if (!ProcessIntersections(topY))
1577  {
1578  succeeded = false;

◆ ExecuteInternal()

bool ClipperLib::Clipper::ExecuteInternal ( )
protectedvirtual

Definition at line 1596 of file clipper.cpp.

1606  {
1607  OutRec *outRec = m_PolyOuts[i];
1608  if (!outRec->Pts) continue;
1609  if (outRec->IsOpen)
1610  FixupOutPolyline(*outRec);
1611  else
1612  FixupOutPolygon(*outRec);
1613  }
1614 
1616  }
1617 
1618  ClearJoins();
1619  ClearGhostJoins();
1620  return succeeded;
1621 }
1622 //------------------------------------------------------------------------------
1623 
1624 void Clipper::SetWindingCount(TEdge &edge)
1625 {
1626  TEdge *e = edge.PrevInAEL;
1627  //find the edge of the same polytype that immediately preceeds 'edge' in AEL
1628  while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL;
1629  if (!e)
1630  {
1631  if (edge.WindDelta == 0)
1632  {
1633  PolyFillType pft = (edge.PolyTyp == ptSubject ? m_SubjFillType : m_ClipFillType);
1634  edge.WindCnt = (pft == pftNegative ? -1 : 1);
1635  }
1636  else
1637  edge.WindCnt = edge.WindDelta;
1638  edge.WindCnt2 = 0;
1639  e = m_ActiveEdges; //ie get ready to calc WindCnt2
1640  }
1641  else if (edge.WindDelta == 0 && m_ClipType != ctUnion)
1642  {
1643  edge.WindCnt = 1;
1644  edge.WindCnt2 = e->WindCnt2;
1645  e = e->NextInAEL; //ie get ready to calc WindCnt2
1646  }
1647  else if (IsEvenOddFillType(edge))
1648  {
1649  //EvenOdd filling ...
1650  if (edge.WindDelta == 0)
1651  {
1652  //are we inside a subj polygon ...
1653  bool Inside = true;
1654  TEdge *e2 = e->PrevInAEL;
1655  while (e2)
1656  {
1657  if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0)

◆ FindOwnerFromSplitRecs()

bool ClipperLib::Clipper::FindOwnerFromSplitRecs ( OutRec outRec,
OutRec *&  currOrfl 
)
private

◆ FixHoleLinkage()

void ClipperLib::Clipper::FixHoleLinkage ( OutRec outrec)
private

Definition at line 1581 of file clipper.cpp.

1587  {
1588  succeeded = false;
1589  }
1590 
1591  if (succeeded)
1592  {
1593  //fix orientations ...

◆ FixupFirstLefts1()

void ClipperLib::Clipper::FixupFirstLefts1 ( OutRec OldOutRec,
OutRec NewOutRec 
)
private

Definition at line 3654 of file clipper.cpp.

3660 {
3661  //reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon
3662  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
3663  {
3664  OutRec* outRec = m_PolyOuts[i];
3665  OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
3666  if (outRec->Pts && outRec->FirstLeft == OldOutRec)
3667  outRec->FirstLeft = NewOutRec;

◆ FixupFirstLefts2()

void ClipperLib::Clipper::FixupFirstLefts2 ( OutRec InnerOutRec,
OutRec OuterOutRec 
)
private

Definition at line 3670 of file clipper.cpp.

3673 {
3674  for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
3675  {
3676  Join* join = m_Joins[i];
3677 
3678  OutRec *outRec1 = GetOutRec(join->OutPt1->Idx);
3679  OutRec *outRec2 = GetOutRec(join->OutPt2->Idx);
3680 
3681  if (!outRec1->Pts || !outRec2->Pts) continue;
3682  if (outRec1->IsOpen || outRec2->IsOpen) continue;
3683 
3684  //get the polygon fragment with the correct hole state (FirstLeft)
3685  //before calling JoinPoints() ...
3686  OutRec *holeStateRec;
3687  if (outRec1 == outRec2) holeStateRec = outRec1;
3688  else if (OutRec1RightOfOutRec2(outRec1, outRec2)) holeStateRec = outRec2;
3689  else if (OutRec1RightOfOutRec2(outRec2, outRec1)) holeStateRec = outRec1;
3690  else holeStateRec = GetLowermostRec(outRec1, outRec2);
3691 
3692  if (!JoinPoints(join, outRec1, outRec2)) continue;
3693 

◆ FixupFirstLefts3()

void ClipperLib::Clipper::FixupFirstLefts3 ( OutRec OldOutRec,
OutRec NewOutRec 
)
private

Definition at line 3695 of file clipper.cpp.

3695  {
3696  //instead of joining two polygons, we've just created a new one by
3697  //splitting one polygon into two.
3698  outRec1->Pts = join->OutPt1;
3699  outRec1->BottomPt = 0;
3700  outRec2 = CreateOutRec();
3701  outRec2->Pts = join->OutPt2;
3702 
3703  //update all OutRec2.Pts Idx's ...
3704  UpdateOutPtIdxs(*outRec2);
3705 

◆ FixupIntersectionOrder()

bool ClipperLib::Clipper::FixupIntersectionOrder ( )
private

Definition at line 2966 of file clipper.cpp.

2966  {
2967  IntersectEdges(e, eNext, e->Top);
2968  SwapPositionsInAEL(e, eNext);
2969  eNext = e->NextInAEL;
2970  }
2971 
2972  if(e->OutIdx == Unassigned && eMaxPair->OutIdx == Unassigned)
2973  {
2974  DeleteFromAEL(e);
2975  DeleteFromAEL(eMaxPair);
2976  }
2977  else if( e->OutIdx >= 0 && eMaxPair->OutIdx >= 0 )
2978  {
2979  if (e->OutIdx >= 0) AddLocalMaxPoly(e, eMaxPair, e->Top);
2980  DeleteFromAEL(e);
2981  DeleteFromAEL(eMaxPair);
2982  }
2983 #ifdef use_lines
2984  else if (e->WindDelta == 0)
2985  {
2986  if (e->OutIdx >= 0)

◆ FixupOutPolygon()

void ClipperLib::Clipper::FixupOutPolygon ( OutRec outrec)
private

Definition at line 3172 of file clipper.cpp.

3178 {
3179  if (!Pts) return 0;
3180  int result = 0;
3181  OutPt* p = Pts;
3182  do
3183  {
3184  result++;
3185  p = p->Next;
3186  }
3187  while (p != Pts);
3188  return result;
3189 }
3190 //------------------------------------------------------------------------------
3191 
3192 void Clipper::BuildResult(Paths &polys)
3193 {
3194  polys.reserve(m_PolyOuts.size());
3195  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
3196  {
3197  if (!m_PolyOuts[i]->Pts) continue;
3198  Path pg;
3199  OutPt* p = m_PolyOuts[i]->Pts->Prev;
3200  int cnt = PointCount(p);
3201  if (cnt < 2) continue;
3202  pg.reserve(cnt);
3203  for (int i = 0; i < cnt; ++i)
3204  {
3205  pg.push_back(p->Pt);
3206  p = p->Prev;
3207  }
3208  polys.push_back(pg);
3209  }
3210 }

◆ FixupOutPolyline()

void ClipperLib::Clipper::FixupOutPolyline ( OutRec outrec)
private

Definition at line 3145 of file clipper.cpp.

3146  {
3147  if (pp->Prev == pp || pp->Prev == pp->Next)
3148  {
3149  DisposeOutPts(pp);
3150  outrec.Pts = 0;
3151  return;
3152  }
3153 
3154  //test for duplicate points and collinear edges ...
3155  if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) ||
3156  (SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) &&
3157  (!preserveCol || !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt))))
3158  {
3159  lastOK = 0;
3160  OutPt *tmp = pp;
3161  pp->Prev->Next = pp->Next;
3162  pp->Next->Prev = pp->Prev;
3163  pp = pp->Prev;
3164  delete tmp;
3165  }
3166  else if (pp == lastOK) break;
3167  else
3168  {
3169  if (!lastOK) lastOK = pp;

◆ GetLastOutPt()

OutPt * ClipperLib::Clipper::GetLastOutPt ( TEdge e)
private

Definition at line 2538 of file clipper.cpp.

2539 {
2540  if ((e->Next->Top == e->Top) && !e->Next->NextInLML)
2541  return e->Next;
2542  else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML)
2543  return e->Prev;
2544  else return 0;
2545 }

◆ GetOutRec()

OutRec * ClipperLib::Clipper::GetOutRec ( int  idx)
private

Definition at line 2394 of file clipper.cpp.

2402  {

◆ InsertEdgeIntoAEL()

void ClipperLib::Clipper::InsertEdgeIntoAEL ( TEdge edge,
TEdge startEdge 
)
private

Definition at line 3348 of file clipper.cpp.

3354  {
3355  result->Prev = outPt->Prev;
3356  result->Next = outPt;
3357  outPt->Prev->Next = result;
3358  outPt->Prev = result;
3359  }
3360  return result;
3361 }
3362 //------------------------------------------------------------------------------
3363 
3364 bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
3365  const IntPoint Pt, bool DiscardLeft)
3366 {
3367  Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight);
3368  Direction Dir2 = (op2->Pt.X > op2b->Pt.X ? dRightToLeft : dLeftToRight);
3369  if (Dir1 == Dir2) return false;
3370 
3371  //When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we
3372  //want Op1b to be on the Right. (And likewise with Op2 and Op2b.)
3373  //So, to facilitate this while inserting Op1b and Op2b ...
3374  //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b,

◆ InsertLocalMinimaIntoAEL()

void ClipperLib::Clipper::InsertLocalMinimaIntoAEL ( const cInt  botY)
private

Definition at line 2014 of file clipper.cpp.

2016  {
2017  if (IsHorizontal(*rb))
2018  {
2019  AddEdgeToSEL(rb);
2020  if (rb->NextInLML)
2021  InsertScanbeam(rb->NextInLML->Top.Y);
2022  }
2023  else InsertScanbeam( rb->Top.Y );
2024  }
2025 
2026  if (!lb || !rb) continue;
2027 
2028  //if any output polygons share an edge, they'll need joining later ...
2029  if (Op1 && IsHorizontal(*rb) &&
2030  m_GhostJoins.size() > 0 && (rb->WindDelta != 0))
2031  {
2032  for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
2033  {
2034  Join* jr = m_GhostJoins[i];
2035  //if the horizontal Rb and a 'ghost' horizontal overlap, then convert
2036  //the 'ghost' join to a real join ready for later ...
2037  if (HorzSegmentsOverlap(jr->OutPt1->Pt.X, jr->OffPt.X, rb->Bot.X, rb->Top.X))
2038  AddJoin(jr->OutPt1, Op1, jr->OffPt);
2039  }
2040  }
2041 
2042  if (lb->OutIdx >= 0 && lb->PrevInAEL &&
2043  lb->PrevInAEL->Curr.X == lb->Bot.X &&
2044  lb->PrevInAEL->OutIdx >= 0 &&
2045  SlopesEqual(lb->PrevInAEL->Bot, lb->PrevInAEL->Top, lb->Curr, lb->Top, m_UseFullRange) &&
2046  (lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0))
2047  {
2048  OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot);
2049  AddJoin(Op1, Op2, lb->Top);
2050  }
2051 
2052  if(lb->NextInAEL != rb)
2053  {
2054 
2055  if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 &&
2056  SlopesEqual(rb->PrevInAEL->Curr, rb->PrevInAEL->Top, rb->Curr, rb->Top, m_UseFullRange) &&
2057  (rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0))
2058  {
2059  OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot);
2060  AddJoin(Op1, Op2, rb->Top);
2061  }
2062 
2063  TEdge* e = lb->NextInAEL;
2064  if (e)
2065  {
2066  while( e != rb )
2067  {
2068  //nb: For calculating winding counts etc, IntersectEdges() assumes
2069  //that param1 will be to the Right of param2 ABOVE the intersection ...
2070  IntersectEdges(rb , e , lb->Curr); //order important here
2071  e = e->NextInAEL;
2072  }
2073  }
2074  }
2075 
2076  }
2077 }
2078 //------------------------------------------------------------------------------
2079 
2080 void Clipper::DeleteFromSEL(TEdge *e)
2081 {
2082  TEdge* SelPrev = e->PrevInSEL;
2083  TEdge* SelNext = e->NextInSEL;
2084  if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted
2085  if( SelPrev ) SelPrev->NextInSEL = SelNext;
2086  else m_SortedEdges = SelNext;
2087  if( SelNext ) SelNext->PrevInSEL = SelPrev;
2088  e->NextInSEL = 0;
2089  e->PrevInSEL = 0;
2090 }
2091 //------------------------------------------------------------------------------
2092 
2093 #ifdef use_xyz
2094 void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2)
2095 {
2096  if (pt.Z != 0 || !m_ZFill) return;
2097  else if (pt == e1.Bot) pt.Z = e1.Bot.Z;
2098  else if (pt == e1.Top) pt.Z = e1.Top.Z;
2099  else if (pt == e2.Bot) pt.Z = e2.Bot.Z;
2100  else if (pt == e2.Top) pt.Z = e2.Top.Z;
2101  else (*m_ZFill)(e1.Bot, e1.Top, e2.Bot, e2.Top, pt);
2102 }
2103 //------------------------------------------------------------------------------
2104 #endif
2105 
2106 void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
2107 {
2108  bool e1Contributing = ( e1->OutIdx >= 0 );
2109  bool e2Contributing = ( e2->OutIdx >= 0 );
2110 
2111 #ifdef use_xyz
2112  SetZ(Pt, *e1, *e2);
2113 #endif

◆ IntersectEdges()

void ClipperLib::Clipper::IntersectEdges ( TEdge e1,
TEdge e2,
IntPoint pt 
)
private

Definition at line 2142 of file clipper.cpp.

2145  {
2146  //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ...
2147  if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 &&
2148  (m_ClipType != ctUnion || e2->WindCnt2 == 0))
2149  {
2150  AddOutPt(e1, Pt);
2151  if (e1Contributing) e1->OutIdx = Unassigned;
2152  }
2153  else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) &&
2154  (m_ClipType != ctUnion || e1->WindCnt2 == 0))
2155  {
2156  AddOutPt(e2, Pt);
2157  if (e2Contributing) e2->OutIdx = Unassigned;
2158  }
2159  }
2160  return;
2161  }
2162 #endif
2163 
2164  //update winding counts...
2165  //assumes that e1 will be to the Right of e2 ABOVE the intersection
2166  if ( e1->PolyTyp == e2->PolyTyp )
2167  {
2168  if ( IsEvenOddFillType( *e1) )
2169  {
2170  int oldE1WindCnt = e1->WindCnt;
2171  e1->WindCnt = e2->WindCnt;
2172  e2->WindCnt = oldE1WindCnt;
2173  } else
2174  {
2175  if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt;
2176  else e1->WindCnt += e2->WindDelta;
2177  if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt;
2178  else e2->WindCnt -= e1->WindDelta;
2179  }
2180  } else
2181  {
2182  if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta;
2183  else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0;
2184  if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta;
2185  else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0;
2186  }
2187 
2188  PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2;
2189  if (e1->PolyTyp == ptSubject)
2190  {
2191  e1FillType = m_SubjFillType;
2192  e1FillType2 = m_ClipFillType;
2193  } else
2194  {
2195  e1FillType = m_ClipFillType;
2196  e1FillType2 = m_SubjFillType;
2197  }
2198  if (e2->PolyTyp == ptSubject)
2199  {
2200  e2FillType = m_SubjFillType;
2201  e2FillType2 = m_ClipFillType;
2202  } else
2203  {
2204  e2FillType = m_ClipFillType;
2205  e2FillType2 = m_SubjFillType;
2206  }
2207 
2208  cInt e1Wc, e2Wc;
2209  switch (e1FillType)
2210  {
2211  case pftPositive: e1Wc = e1->WindCnt; break;
2212  case pftNegative: e1Wc = -e1->WindCnt; break;
2213  default: e1Wc = Abs(e1->WindCnt);
2214  }
2215  switch(e2FillType)
2216  {
2217  case pftPositive: e2Wc = e2->WindCnt; break;
2218  case pftNegative: e2Wc = -e2->WindCnt; break;
2219  default: e2Wc = Abs(e2->WindCnt);
2220  }
2221 
2222  if ( e1Contributing && e2Contributing )
2223  {
2224  if ((e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
2225  (e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) )
2226  {
2227  AddLocalMaxPoly(e1, e2, Pt);
2228  }
2229  else
2230  {
2231  AddOutPt(e1, Pt);
2232  AddOutPt(e2, Pt);
2233  SwapSides( *e1 , *e2 );
2234  SwapPolyIndexes( *e1 , *e2 );
2235  }
2236  }
2237  else if ( e1Contributing )
2238  {
2239  if (e2Wc == 0 || e2Wc == 1)
2240  {
2241  AddOutPt(e1, Pt);
2242  SwapSides(*e1, *e2);
2243  SwapPolyIndexes(*e1, *e2);
2244  }
2245  }
2246  else if ( e2Contributing )
2247  {
2248  if (e1Wc == 0 || e1Wc == 1)
2249  {
2250  AddOutPt(e2, Pt);
2251  SwapSides(*e1, *e2);
2252  SwapPolyIndexes(*e1, *e2);
2253  }
2254  }
2255  else if ( (e1Wc == 0 || e1Wc == 1) && (e2Wc == 0 || e2Wc == 1))
2256  {
2257  //neither edge is currently contributing ...
2258 
2259  cInt e1Wc2, e2Wc2;
2260  switch (e1FillType2)
2261  {
2262  case pftPositive: e1Wc2 = e1->WindCnt2; break;
2263  case pftNegative : e1Wc2 = -e1->WindCnt2; break;
2264  default: e1Wc2 = Abs(e1->WindCnt2);
2265  }
2266  switch (e2FillType2)
2267  {
2268  case pftPositive: e2Wc2 = e2->WindCnt2; break;
2269  case pftNegative: e2Wc2 = -e2->WindCnt2; break;
2270  default: e2Wc2 = Abs(e2->WindCnt2);
2271  }
2272 
2273  if (e1->PolyTyp != e2->PolyTyp)
2274  {
2275  AddLocalMinPoly(e1, e2, Pt);
2276  }
2277  else if (e1Wc == 1 && e2Wc == 1)
2278  switch( m_ClipType ) {
2279  case ctIntersection:
2280  if (e1Wc2 > 0 && e2Wc2 > 0)
2281  AddLocalMinPoly(e1, e2, Pt);
2282  break;
2283  case ctUnion:
2284  if ( e1Wc2 <= 0 && e2Wc2 <= 0 )
2285  AddLocalMinPoly(e1, e2, Pt);
2286  break;
2287  case ctDifference:
2288  if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||
2289  ((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0)))
2290  AddLocalMinPoly(e1, e2, Pt);
2291  break;
2292  case ctXor:
2293  AddLocalMinPoly(e1, e2, Pt);
2294  }
2295  else
2296  SwapSides( *e1, *e2 );
2297  }
2298 }
2299 //------------------------------------------------------------------------------
2300 
2301 void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
2302 {
2303  TEdge *e2 = e->PrevInAEL;
2304  TEdge *eTmp = 0;
2305  while (e2)
2306  {
2307  if (e2->OutIdx >= 0 && e2->WindDelta != 0)
2308  {
2309  if (!eTmp) eTmp = e2;
2310  else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0;
2311  }
2312  e2 = e2->PrevInAEL;
2313  }
2314  if (!eTmp)
2315  {
2316  outrec->FirstLeft = 0;
2317  outrec->IsHole = false;
2318  }
2319  else
2320  {
2321  outrec->FirstLeft = m_PolyOuts[eTmp->OutIdx];
2322  outrec->IsHole = !outrec->FirstLeft->IsHole;
2323  }
2324 }
2325 //------------------------------------------------------------------------------
2326 
2327 OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
2328 {
2329  //work out which polygon fragment has the correct hole state ...
2330  if (!outRec1->BottomPt)
2331  outRec1->BottomPt = GetBottomPt(outRec1->Pts);
2332  if (!outRec2->BottomPt)
2333  outRec2->BottomPt = GetBottomPt(outRec2->Pts);
2334  OutPt *OutPt1 = outRec1->BottomPt;

◆ IsContributing()

bool ClipperLib::Clipper::IsContributing ( const TEdge edge) const
private

Definition at line 1777 of file clipper.cpp.

1778  :
1779  return (edge.WindCnt2 > 0);
1780  default:
1781  return (edge.WindCnt2 < 0);
1782  }
1783  break;
1784  case ctUnion:
1785  switch(pft2)
1786  {
1787  case pftEvenOdd:
1788  case pftNonZero:
1789  return (edge.WindCnt2 == 0);
1790  case pftPositive:
1791  return (edge.WindCnt2 <= 0);
1792  default:
1793  return (edge.WindCnt2 >= 0);
1794  }
1795  break;
1796  case ctDifference:
1797  if (edge.PolyTyp == ptSubject)
1798  switch(pft2)
1799  {
1800  case pftEvenOdd:
1801  case pftNonZero:
1802  return (edge.WindCnt2 == 0);
1803  case pftPositive:
1804  return (edge.WindCnt2 <= 0);
1805  default:
1806  return (edge.WindCnt2 >= 0);
1807  }
1808  else
1809  switch(pft2)
1810  {
1811  case pftEvenOdd:
1812  case pftNonZero:
1813  return (edge.WindCnt2 != 0);
1814  case pftPositive:
1815  return (edge.WindCnt2 > 0);
1816  default:
1817  return (edge.WindCnt2 < 0);
1818  }
1819  break;
1820  case ctXor:
1821  if (edge.WindDelta == 0) //XOr always contributing unless open
1822  switch(pft2)
1823  {
1824  case pftEvenOdd:
1825  case pftNonZero:
1826  return (edge.WindCnt2 == 0);
1827  case pftPositive:
1828  return (edge.WindCnt2 <= 0);
1829  default:
1830  return (edge.WindCnt2 >= 0);
1831  }
1832  else
1833  return true;
1834  break;
1835  default:
1836  return true;
1837  }
1838 }
1839 //------------------------------------------------------------------------------
1840 
1841 OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
1842 {
1843  OutPt* result;
1844  TEdge *e, *prevE;
1845  if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx ))
1846  {
1847  result = AddOutPt(e1, Pt);
1848  e2->OutIdx = e1->OutIdx;
1849  e1->Side = esLeft;
1850  e2->Side = esRight;
1851  e = e1;
1852  if (e->PrevInAEL == e2)
1853  prevE = e2->PrevInAEL;
1854  else
1855  prevE = e->PrevInAEL;
1856  } else
1857  {
1858  result = AddOutPt(e2, Pt);
1859  e1->OutIdx = e2->OutIdx;
1860  e1->Side = esRight;
1861  e2->Side = esLeft;
1862  e = e2;
1863  if (e->PrevInAEL == e1)
1864  prevE = e1->PrevInAEL;
1865  else
1866  prevE = e->PrevInAEL;
1867  }
1868 
1869  if (prevE && prevE->OutIdx >= 0)
1870  {
1871  cInt xPrev = TopX(*prevE, Pt.Y);
1872  cInt xE = TopX(*e, Pt.Y);
1873  if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) &&
1874  SlopesEqual(IntPoint(xPrev, Pt.Y), prevE->Top, IntPoint(xE, Pt.Y), e->Top, m_UseFullRange))

◆ IsEvenOddAltFillType()

bool ClipperLib::Clipper::IsEvenOddAltFillType ( const TEdge edge) const
private

Definition at line 1769 of file clipper.cpp.

1771  {
1772  case ctIntersection:
1773  switch(pft2)
1774  {

◆ IsEvenOddFillType()

bool ClipperLib::Clipper::IsEvenOddFillType ( const TEdge edge) const
private

Definition at line 1761 of file clipper.cpp.

1763  :
1764  if (edge.WindCnt != 1) return false;
1765  break;
1766  default: //pftNegative

◆ IsHole()

bool ClipperLib::Clipper::IsHole ( TEdge e)
private

◆ IsTopHorz()

bool ClipperLib::Clipper::IsTopHorz ( const cInt  XPos)
private

◆ JoinCommonEdges()

void ClipperLib::Clipper::JoinCommonEdges ( )
private

Definition at line 3708 of file clipper.cpp.

3718  {
3719  //outRec2 contains outRec1 ...
3720  outRec2->IsHole = outRec1->IsHole;
3721  outRec1->IsHole = !outRec2->IsHole;
3722  outRec2->FirstLeft = outRec1->FirstLeft;
3723  outRec1->FirstLeft = outRec2;
3724 
3725  if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2);
3726 
3727  if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0))
3728  ReversePolyPtLinks(outRec1->Pts);
3729  }
3730  else
3731  {
3732  //the 2 polygons are completely separate ...
3733  outRec2->IsHole = outRec1->IsHole;
3734  outRec2->FirstLeft = outRec1->FirstLeft;
3735 
3736  //fixup FirstLeft pointers that may need reassigning to OutRec2
3737  if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2);
3738  }
3739 
3740  } else
3741  {
3742  //joined 2 polygons together ...
3743 
3744  outRec2->Pts = 0;
3745  outRec2->BottomPt = 0;
3746  outRec2->Idx = outRec1->Idx;
3747 
3748  outRec1->IsHole = holeStateRec->IsHole;
3749  if (holeStateRec == outRec2)
3750  outRec1->FirstLeft = outRec2->FirstLeft;
3751  outRec2->FirstLeft = outRec1;
3752 
3753  if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1);
3754  }
3755  }
3756 }
3757 
3758 //------------------------------------------------------------------------------
3759 // ClipperOffset support functions ...
3760 //------------------------------------------------------------------------------
3761 
3762 DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2)
3763 {
3764  if(pt2.X == pt1.X && pt2.Y == pt1.Y)
3765  return DoublePoint(0, 0);
3766 
3767  double Dx = (double)(pt2.X - pt1.X);
3768  double dy = (double)(pt2.Y - pt1.Y);
3769  double f = 1 *1.0/ std::sqrt( Dx*Dx + dy*dy );
3770  Dx *= f;
3771  dy *= f;
3772  return DoublePoint(dy, -Dx);
3773 }
3774 
3775 //------------------------------------------------------------------------------
3776 // ClipperOffset class
3777 //------------------------------------------------------------------------------
3778 
3779 ClipperOffset::ClipperOffset(double miterLimit, double arcTolerance)
3780 {
3781  this->MiterLimit = miterLimit;
3782  this->ArcTolerance = arcTolerance;
3783  m_lowest.X = -1;
3784 }
3785 //------------------------------------------------------------------------------
3786 
3788 {
3789  Clear();
3790 }
3791 //------------------------------------------------------------------------------
3792 

◆ JoinPoints()

bool ClipperLib::Clipper::JoinPoints ( Join j,
OutRec outRec1,
OutRec outRec2 
)
private

Definition at line 3487 of file clipper.cpp.

3491  {
3492  op1b = DupOutPt(op1, true);
3493  op2b = DupOutPt(op2, false);
3494  op1->Next = op2;
3495  op2->Prev = op1;
3496  op1b->Prev = op2b;
3497  op2b->Next = op1b;
3498  j->OutPt1 = op1;
3499  j->OutPt2 = op1b;
3500  return true;
3501  }
3502  }
3503  else if (isHorizontal)
3504  {
3505  //treat horizontal joins differently to non-horizontal joins since with
3506  //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt
3507  //may be anywhere along the horizontal edge.
3508  op1b = op1;
3509  while (op1->Prev->Pt.Y == op1->Pt.Y && op1->Prev != op1b && op1->Prev != op2)
3510  op1 = op1->Prev;
3511  while (op1b->Next->Pt.Y == op1b->Pt.Y && op1b->Next != op1 && op1b->Next != op2)
3512  op1b = op1b->Next;
3513  if (op1b->Next == op1 || op1b->Next == op2) return false; //a flat 'polygon'
3514 
3515  op2b = op2;
3516  while (op2->Prev->Pt.Y == op2->Pt.Y && op2->Prev != op2b && op2->Prev != op1b)
3517  op2 = op2->Prev;
3518  while (op2b->Next->Pt.Y == op2b->Pt.Y && op2b->Next != op2 && op2b->Next != op1)
3519  op2b = op2b->Next;
3520  if (op2b->Next == op2 || op2b->Next == op1) return false; //a flat 'polygon'
3521 
3522  cInt Left, Right;
3523  //Op1 --> Op1b & Op2 --> Op2b are the extremites of the horizontal edges
3524  if (!GetOverlap(op1->Pt.X, op1b->Pt.X, op2->Pt.X, op2b->Pt.X, Left, Right))
3525  return false;
3526 
3527  //DiscardLeftSide: when overlapping edges are joined, a spike will created
3528  //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up
3529  //on the discard Side as either may still be needed for other joins ...
3530  IntPoint Pt;
3531  bool DiscardLeftSide;
3532  if (op1->Pt.X >= Left && op1->Pt.X <= Right)
3533  {
3534  Pt = op1->Pt; DiscardLeftSide = (op1->Pt.X > op1b->Pt.X);
3535  }
3536  else if (op2->Pt.X >= Left&& op2->Pt.X <= Right)
3537  {
3538  Pt = op2->Pt; DiscardLeftSide = (op2->Pt.X > op2b->Pt.X);
3539  }
3540  else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right)
3541  {
3542  Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->Pt.X;
3543  }
3544  else
3545  {
3546  Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->Pt.X);
3547  }
3548  j->OutPt1 = op1; j->OutPt2 = op2;
3549  return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide);
3550  } else
3551  {
3552  //nb: For non-horizontal joins ...
3553  // 1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y
3554  // 2. Jr.OutPt1.Pt > Jr.OffPt.Y
3555 
3556  //make sure the polygons are correctly oriented ...
3557  op1b = op1->Next;
3558  while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Next;
3559  bool Reverse1 = ((op1b->Pt.Y > op1->Pt.Y) ||
3560  !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange));
3561  if (Reverse1)
3562  {
3563  op1b = op1->Prev;
3564  while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Prev;
3565  if ((op1b->Pt.Y > op1->Pt.Y) ||
3566  !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)) return false;
3567  };
3568  op2b = op2->Next;
3569  while ((op2b->Pt == op2->Pt) && (op2b != op2))op2b = op2b->Next;
3570  bool Reverse2 = ((op2b->Pt.Y > op2->Pt.Y) ||
3571  !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange));
3572  if (Reverse2)
3573  {
3574  op2b = op2->Prev;
3575  while ((op2b->Pt == op2->Pt) && (op2b != op2)) op2b = op2b->Prev;
3576  if ((op2b->Pt.Y > op2->Pt.Y) ||
3577  !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)) return false;
3578  }
3579 
3580  if ((op1b == op1) || (op2b == op2) || (op1b == op2b) ||
3581  ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false;
3582 
3583  if (Reverse1)
3584  {
3585  op1b = DupOutPt(op1, false);
3586  op2b = DupOutPt(op2, true);
3587  op1->Prev = op2;
3588  op2->Next = op1;
3589  op1b->Next = op2b;
3590  op2b->Prev = op1b;
3591  j->OutPt1 = op1;
3592  j->OutPt2 = op1b;
3593  return true;
3594  } else
3595  {
3596  op1b = DupOutPt(op1, true);
3597  op2b = DupOutPt(op2, false);
3598  op1->Next = op2;
3599  op2->Prev = op1;
3600  op1b->Prev = op2b;
3601  op2b->Next = op1b;
3602  j->OutPt1 = op1;
3603  j->OutPt2 = op1b;
3604  return true;
3605  }
3606  }
3607 }
3608 //----------------------------------------------------------------------
3609 
3610 static OutRec* ParseFirstLeft(OutRec* FirstLeft)
3611 {
3612  while (FirstLeft && !FirstLeft->Pts)
3613  FirstLeft = FirstLeft->FirstLeft;
3614  return FirstLeft;
3615 }
3616 //------------------------------------------------------------------------------
3617 
3618 void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
3619 {
3620  //tests if NewOutRec contains the polygon before reassigning FirstLeft
3621  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
3622  {
3623  OutRec* outRec = m_PolyOuts[i];
3624  OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
3625  if (outRec->Pts && firstLeft == OldOutRec)
3626  {
3627  if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts))
3628  outRec->FirstLeft = NewOutRec;
3629  }
3630  }
3631 }
3632 //----------------------------------------------------------------------
3633 
3634 void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec)
3635 {
3636  //A polygon has split into two such that one is now the inner of the other.
3637  //It's possible that these polygons now wrap around other polygons, so check
3638  //every polygon that's also contained by OuterOutRec's FirstLeft container
3639  //(including 0) to see if they've become inner to the new inner polygon ...
3640  OutRec* orfl = OuterOutRec->FirstLeft;
3641  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
3642  {
3643  OutRec* outRec = m_PolyOuts[i];

◆ PopEdgeFromSEL()

bool ClipperLib::Clipper::PopEdgeFromSEL ( TEdge *&  edge)
private

Definition at line 1956 of file clipper.cpp.

1961 {
1962  for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++)

◆ ProcessEdgesAtTopOfScanbeam()

void ClipperLib::Clipper::ProcessEdgesAtTopOfScanbeam ( const cInt  topY)
private

Definition at line 3041 of file clipper.cpp.

3047  {
3048  TEdge* ePrev = e->PrevInAEL;
3049  if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) &&
3050  (ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0))
3051  {
3052  IntPoint pt = e->Curr;
3053 #ifdef use_xyz
3054  SetZ(pt, *ePrev, *e);
3055 #endif
3056  OutPt* op = AddOutPt(ePrev, pt);
3057  OutPt* op2 = AddOutPt(e, pt);
3058  AddJoin(op, op2, pt); //StrictlySimple (type-3) join
3059  }
3060  }
3061 
3062  e = e->NextInAEL;
3063  }
3064  }
3065 
3066  //3. Process horizontals at the Top of the scanbeam ...
3067  m_Maxima.sort();
3069  m_Maxima.clear();
3070 
3071  //4. Promote intermediate vertices ...
3072  e = m_ActiveEdges;
3073  while(e)
3074  {
3075  if(IsIntermediate(e, topY))
3076  {
3077  OutPt* op = 0;
3078  if( e->OutIdx >= 0 )
3079  op = AddOutPt(e, e->Top);
3080  UpdateEdgeIntoAEL(e);
3081 
3082  //if output polygons share an edge, they'll need joining later ...
3083  TEdge* ePrev = e->PrevInAEL;
3084  TEdge* eNext = e->NextInAEL;
3085  if (ePrev && ePrev->Curr.X == e->Bot.X &&
3086  ePrev->Curr.Y == e->Bot.Y && op &&
3087  ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y &&
3088  SlopesEqual(e->Curr, e->Top, ePrev->Curr, ePrev->Top, m_UseFullRange) &&
3089  (e->WindDelta != 0) && (ePrev->WindDelta != 0))
3090  {
3091  OutPt* op2 = AddOutPt(ePrev, e->Bot);
3092  AddJoin(op, op2, e->Top);
3093  }
3094  else if (eNext && eNext->Curr.X == e->Bot.X &&
3095  eNext->Curr.Y == e->Bot.Y && op &&
3096  eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y &&
3097  SlopesEqual(e->Curr, e->Top, eNext->Curr, eNext->Top, m_UseFullRange) &&
3098  (e->WindDelta != 0) && (eNext->WindDelta != 0))
3099  {
3100  OutPt* op2 = AddOutPt(eNext, e->Bot);
3101  AddJoin(op, op2, e->Top);
3102  }
3103  }
3104  e = e->NextInAEL;
3105  }
3106 }
3107 //------------------------------------------------------------------------------
3108 
3109 void Clipper::FixupOutPolyline(OutRec &outrec)
3110 {
3111  OutPt *pp = outrec.Pts;
3112  OutPt *lastPP = pp->Prev;
3113  while (pp != lastPP)
3114  {
3115  pp = pp->Next;
3116  if (pp->Pt == pp->Prev->Pt)
3117  {
3118  if (pp == lastPP) lastPP = pp->Prev;
3119  OutPt *tmpPP = pp->Prev;
3120  tmpPP->Next = pp->Next;
3121  pp->Next->Prev = tmpPP;
3122  delete pp;
3123  pp = tmpPP;
3124  }
3125  }
3126 
3127  if (pp == pp->Prev)
3128  {
3129  DisposeOutPts(pp);
3130  outrec.Pts = 0;
3131  return;
3132  }
3133 }
3134 //------------------------------------------------------------------------------
3135 
3136 void Clipper::FixupOutPolygon(OutRec &outrec)
3137 {
3138  //FixupOutPolygon() - removes duplicate points and simplifies consecutive
3139  //parallel edges by removing the middle vertex.
3140  OutPt *lastOK = 0;
3141  outrec.BottomPt = 0;
3142  OutPt *pp = outrec.Pts;

◆ ProcessHorizontal()

void ClipperLib::Clipper::ProcessHorizontal ( TEdge horzEdge)
private

Definition at line 2672 of file clipper.cpp.

2674  {
2675 
2676  bool IsLastHorz = (horzEdge == eLastHorz);
2677  TEdge* e = GetNextInAEL(horzEdge, dir);
2678  while(e)
2679  {
2680 
2681  //this code block inserts extra coords into horizontal edges (in output
2682  //polygons) whereever maxima touch these horizontal edges. This helps
2683  //'simplifying' polygons (ie if the Simplify property is set).
2684  if (m_Maxima.size() > 0)
2685  {
2686  if (dir == dLeftToRight)
2687  {
2688  while (maxIt != m_Maxima.end() && *maxIt < e->Curr.X)
2689  {
2690  if (horzEdge->OutIdx >= 0 && !IsOpen)
2691  AddOutPt(horzEdge, IntPoint(*maxIt, horzEdge->Bot.Y));
2692  maxIt++;
2693  }
2694  }
2695  else
2696  {
2697  while (maxRit != m_Maxima.rend() && *maxRit > e->Curr.X)
2698  {
2699  if (horzEdge->OutIdx >= 0 && !IsOpen)
2700  AddOutPt(horzEdge, IntPoint(*maxRit, horzEdge->Bot.Y));
2701  maxRit++;
2702  }
2703  }
2704  };
2705 
2706  if ((dir == dLeftToRight && e->Curr.X > horzRight) ||
2707  (dir == dRightToLeft && e->Curr.X < horzLeft)) break;
2708 
2709  //Also break if we've got to the end of an intermediate horizontal edge ...
2710  //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal.
2711  if (e->Curr.X == horzEdge->Top.X && horzEdge->NextInLML &&
2712  e->Dx < horzEdge->NextInLML->Dx) break;
2713 
2714  if (horzEdge->OutIdx >= 0 && !IsOpen) //note: may be done multiple times
2715  {
2716  op1 = AddOutPt(horzEdge, e->Curr);
2717  TEdge* eNextHorz = m_SortedEdges;
2718  while (eNextHorz)
2719  {
2720  if (eNextHorz->OutIdx >= 0 &&
2721  HorzSegmentsOverlap(horzEdge->Bot.X,
2722  horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X))
2723  {
2724  OutPt* op2 = GetLastOutPt(eNextHorz);
2725  AddJoin(op2, op1, eNextHorz->Top);
2726  }
2727  eNextHorz = eNextHorz->NextInSEL;
2728  }
2729  AddGhostJoin(op1, horzEdge->Bot);
2730  }
2731 
2732  //OK, so far we're still in range of the horizontal Edge but make sure
2733  //we're at the last of consec. horizontals when matching with eMaxPair
2734  if(e == eMaxPair && IsLastHorz)
2735  {
2736  if (horzEdge->OutIdx >= 0)
2737  AddLocalMaxPoly(horzEdge, eMaxPair, horzEdge->Top);
2738  DeleteFromAEL(horzEdge);
2739  DeleteFromAEL(eMaxPair);
2740  return;
2741  }
2742 
2743  if(dir == dLeftToRight)
2744  {
2745  IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y);
2746  IntersectEdges(horzEdge, e, Pt);
2747  }
2748  else
2749  {
2750  IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y);
2751  IntersectEdges( e, horzEdge, Pt);
2752  }
2753  TEdge* eNext = GetNextInAEL(e, dir);
2754  SwapPositionsInAEL( horzEdge, e );
2755  e = eNext;
2756  } //end while(e)
2757 
2758  //Break out of loop if HorzEdge.NextInLML is not also horizontal ...
2759  if (!horzEdge->NextInLML || !IsHorizontal(*horzEdge->NextInLML)) break;
2760 
2761  UpdateEdgeIntoAEL(horzEdge);
2762  if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot);
2763  GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
2764 
2765  } //end for (;;)
2766 
2767  if (horzEdge->OutIdx >= 0 && !op1)
2768  {
2769  op1 = GetLastOutPt(horzEdge);
2770  TEdge* eNextHorz = m_SortedEdges;
2771  while (eNextHorz)
2772  {
2773  if (eNextHorz->OutIdx >= 0 &&
2774  HorzSegmentsOverlap(horzEdge->Bot.X,
2775  horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X))
2776  {
2777  OutPt* op2 = GetLastOutPt(eNextHorz);
2778  AddJoin(op2, op1, eNextHorz->Top);
2779  }
2780  eNextHorz = eNextHorz->NextInSEL;
2781  }
2782  AddGhostJoin(op1, horzEdge->Top);
2783  }
2784 
2785  if (horzEdge->NextInLML)
2786  {
2787  if(horzEdge->OutIdx >= 0)
2788  {
2789  op1 = AddOutPt( horzEdge, horzEdge->Top);
2790  UpdateEdgeIntoAEL(horzEdge);
2791  if (horzEdge->WindDelta == 0) return;
2792  //nb: HorzEdge is no longer horizontal here
2793  TEdge* ePrev = horzEdge->PrevInAEL;
2794  TEdge* eNext = horzEdge->NextInAEL;
2795  if (ePrev && ePrev->Curr.X == horzEdge->Bot.X &&
2796  ePrev->Curr.Y == horzEdge->Bot.Y && ePrev->WindDelta != 0 &&
2797  (ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y &&
2798  SlopesEqual(*horzEdge, *ePrev, m_UseFullRange)))
2799  {
2800  OutPt* op2 = AddOutPt(ePrev, horzEdge->Bot);
2801  AddJoin(op1, op2, horzEdge->Top);
2802  }
2803  else if (eNext && eNext->Curr.X == horzEdge->Bot.X &&
2804  eNext->Curr.Y == horzEdge->Bot.Y && eNext->WindDelta != 0 &&
2805  eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y &&
2806  SlopesEqual(*horzEdge, *eNext, m_UseFullRange))
2807  {
2808  OutPt* op2 = AddOutPt(eNext, horzEdge->Bot);
2809  AddJoin(op1, op2, horzEdge->Top);
2810  }
2811  }
2812  else
2813  UpdateEdgeIntoAEL(horzEdge);
2814  }
2815  else
2816  {
2817  if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Top);
2818  DeleteFromAEL(horzEdge);
2819  }
2820 }
2821 //------------------------------------------------------------------------------
2822 
2823 bool Clipper::ProcessIntersections(const cInt topY)
2824 {
2825  if( !m_ActiveEdges ) return true;
2826  try {
2827  BuildIntersectList(topY);
2828  size_t IlSize = m_IntersectList.size();
2829  if (IlSize == 0) return true;
2830  if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList();
2831  else return false;
2832  }
2833  catch(...)
2834  {
2835  m_SortedEdges = 0;
2837  throw clipperException("ProcessIntersections error");
2838  }
2839  m_SortedEdges = 0;
2840  return true;
2841 }
2842 //------------------------------------------------------------------------------
2843 
2845 {
2846  for (size_t i = 0; i < m_IntersectList.size(); ++i )
2847  delete m_IntersectList[i];
2848  m_IntersectList.clear();
2849 }
2850 //------------------------------------------------------------------------------
2851 
2852 void Clipper::BuildIntersectList(const cInt topY)
2853 {
2854  if ( !m_ActiveEdges ) return;
2855 
2856  //prepare for sorting ...

◆ ProcessHorizontals()

void ClipperLib::Clipper::ProcessHorizontals ( )
private

Definition at line 2548 of file clipper.cpp.

2549 {
2550  //as GetMaximaPair() but returns 0 if MaxPair isn't in AEL (unless it's horizontal)
2551  TEdge* result = GetMaximaPair(e);
2552  if (result && (result->OutIdx == Skip ||
2553  (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return 0;

◆ ProcessIntersections()

bool ClipperLib::Clipper::ProcessIntersections ( const cInt  topY)
private

Definition at line 2859 of file clipper.cpp.

2860  {
2861  e->PrevInSEL = e->PrevInAEL;
2862  e->NextInSEL = e->NextInAEL;
2863  e->Curr.X = TopX( *e, topY );
2864  e = e->NextInAEL;
2865  }
2866 
2867  //bubblesort ...
2868  bool isModified;
2869  do
2870  {
2871  isModified = false;
2872  e = m_SortedEdges;
2873  while( e->NextInSEL )
2874  {
2875  TEdge *eNext = e->NextInSEL;
2876  IntPoint Pt;
2877  if(e->Curr.X > eNext->Curr.X)

◆ ProcessIntersectList()

void ClipperLib::Clipper::ProcessIntersectList ( )
private

Definition at line 2938 of file clipper.cpp.

2939  {
2941  {
2942  size_t j = i + 1;
2943  while (j < cnt && !EdgesAdjacent(*m_IntersectList[j])) j++;
2944  if (j == cnt) return false;
2945  std::swap(m_IntersectList[i], m_IntersectList[j]);
2946  }
2948  }
2949  return true;
2950 }

◆ ReverseSolution() [1/2]

bool ClipperLib::Clipper::ReverseSolution ( )
inline

Definition at line 279 of file clipper.hpp.

279 { return m_ReverseOutput; };

◆ ReverseSolution() [2/2]

void ClipperLib::Clipper::ReverseSolution ( bool  value)
inline

Definition at line 280 of file clipper.hpp.

280 {m_ReverseOutput = value;};

◆ SetHoleState()

void ClipperLib::Clipper::SetHoleState ( TEdge e,
OutRec outrec 
)
private

Definition at line 2337 of file clipper.cpp.

2348 {
2349  do
2350  {
2351  outRec1 = outRec1->FirstLeft;
2352  if (outRec1 == outRec2) return true;
2353  } while (outRec1);
2354  return false;
2355 }
2356 //------------------------------------------------------------------------------
2357 
2358 OutRec* Clipper::GetOutRec(int Idx)
2359 {
2360  OutRec* outrec = m_PolyOuts[Idx];

◆ SetWindingCount()

void ClipperLib::Clipper::SetWindingCount ( TEdge edge)
private

Definition at line 1660 of file clipper.cpp.

1661  : 1);
1662  }
1663  else
1664  {
1665  edge.WindCnt = edge.WindDelta;
1666  }
1667  edge.WindCnt2 = e->WindCnt2;
1668  e = e->NextInAEL; //ie get ready to calc WindCnt2
1669  }
1670  else
1671  {
1672  //nonZero, Positive or Negative filling ...
1673  if (e->WindCnt * e->WindDelta < 0)
1674  {
1675  //prev edge is 'decreasing' WindCount (WC) toward zero
1676  //so we're outside the previous polygon ...
1677  if (Abs(e->WindCnt) > 1)
1678  {
1679  //outside prev poly but still inside another.
1680  //when reversing direction of prev poly use the same WC
1681  if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
1682  //otherwise continue to 'decrease' WC ...
1683  else edge.WindCnt = e->WindCnt + edge.WindDelta;
1684  }
1685  else
1686  //now outside all polys of same polytype so set own WC ...
1687  edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta);
1688  } else
1689  {
1690  //prev edge is 'increasing' WindCount (WC) away from zero
1691  //so we're inside the previous polygon ...
1692  if (edge.WindDelta == 0)
1693  edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1);
1694  //if wind direction is reversing prev then use same WC
1695  else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
1696  //otherwise add to WC ...
1697  else edge.WindCnt = e->WindCnt + edge.WindDelta;
1698  }
1699  edge.WindCnt2 = e->WindCnt2;
1700  e = e->NextInAEL; //ie get ready to calc WindCnt2
1701  }
1702 
1703  //update WindCnt2 ...
1704  if (IsEvenOddAltFillType(edge))
1705  {
1706  //EvenOdd filling ...
1707  while (e != &edge)
1708  {
1709  if (e->WindDelta != 0)
1710  edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0);
1711  e = e->NextInAEL;
1712  }
1713  } else
1714  {
1715  //nonZero, Positive or Negative filling ...
1716  while ( e != &edge )
1717  {
1718  edge.WindCnt2 += e->WindDelta;
1719  e = e->NextInAEL;
1720  }
1721  }
1722 }
1723 //------------------------------------------------------------------------------
1724 
1725 bool Clipper::IsEvenOddFillType(const TEdge& edge) const
1726 {
1727  if (edge.PolyTyp == ptSubject)
1728  return m_SubjFillType == pftEvenOdd; else
1729  return m_ClipFillType == pftEvenOdd;
1730 }
1731 //------------------------------------------------------------------------------
1732 
1733 bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const
1734 {
1735  if (edge.PolyTyp == ptSubject)
1736  return m_ClipFillType == pftEvenOdd; else
1737  return m_SubjFillType == pftEvenOdd;
1738 }
1739 //------------------------------------------------------------------------------
1740 
1741 bool Clipper::IsContributing(const TEdge& edge) const
1742 {
1743  PolyFillType pft, pft2;
1744  if (edge.PolyTyp == ptSubject)
1745  {
1746  pft = m_SubjFillType;
1747  pft2 = m_ClipFillType;
1748  } else
1749  {
1750  pft = m_ClipFillType;
1751  pft2 = m_SubjFillType;
1752  }
1753 
1754  switch(pft)
1755  {
1756  case pftEvenOdd:
1757  //return false if a subj line has been flagged as inside a subj polygon
1758  if (edge.WindDelta == 0 && edge.WindCnt != 1) return false;

◆ StrictlySimple() [1/2]

bool ClipperLib::Clipper::StrictlySimple ( )
inline

Definition at line 281 of file clipper.hpp.

281 {return m_StrictSimple;};

◆ StrictlySimple() [2/2]

void ClipperLib::Clipper::StrictlySimple ( bool  value)
inline

Definition at line 282 of file clipper.hpp.

282 {m_StrictSimple = value;};

◆ SwapPositionsInSEL()

void ClipperLib::Clipper::SwapPositionsInSEL ( TEdge edge1,
TEdge edge2 
)
private

Definition at line 2594 of file clipper.cpp.

2605 {
2606  return dir == dLeftToRight ? e->NextInAEL : e->PrevInAEL;
2607 }
2608 //------------------------------------------------------------------------------
2609 
2610 void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cInt& Right)
2611 {
2612  if (HorzEdge.Bot.X < HorzEdge.Top.X)
2613  {
2614  Left = HorzEdge.Bot.X;
2615  Right = HorzEdge.Top.X;
2616  Dir = dLeftToRight;
2617  } else
2618  {
2619  Left = HorzEdge.Top.X;
2620  Right = HorzEdge.Bot.X;
2621  Dir = dRightToLeft;
2622  }
2623 }
2624 //------------------------------------------------------------------------
2625 
2626 /*******************************************************************************
2627 * Notes: Horizontal edges (HEs) at scanline intersections (ie at the Top or *
2628 * Bottom of a scanbeam) are processed as if layered. The order in which HEs *
2629 * are processed doesn't matter. HEs intersect with other HE Bot.Xs only [#] *
2630 * (or they could intersect with Top.Xs only, ie EITHER Bot.Xs OR Top.Xs), *
2631 * and with other non-horizontal edges [*]. Once these intersections are *
2632 * processed, intermediate HEs then 'promote' the Edge above (NextInLML) into *
2633 * the AEL. These 'promoted' edges may in turn intersect [%] with other HEs. *
2634 *******************************************************************************/
2635 
2636 void Clipper::ProcessHorizontal(TEdge *horzEdge)
2637 {

Member Data Documentation

◆ m_ClipFillType

PolyFillType ClipperLib::Clipper::m_ClipFillType
private

Definition at line 298 of file clipper.hpp.

◆ m_ClipType

ClipType ClipperLib::Clipper::m_ClipType
private

Definition at line 293 of file clipper.hpp.

◆ m_ExecuteLocked

bool ClipperLib::Clipper::m_ExecuteLocked
private

Definition at line 297 of file clipper.hpp.

◆ m_GhostJoins

JoinList ClipperLib::Clipper::m_GhostJoins
private

Definition at line 291 of file clipper.hpp.

◆ m_IntersectList

IntersectList ClipperLib::Clipper::m_IntersectList
private

Definition at line 292 of file clipper.hpp.

◆ m_Joins

JoinList ClipperLib::Clipper::m_Joins
private

Definition at line 290 of file clipper.hpp.

◆ m_Maxima

MaximaList ClipperLib::Clipper::m_Maxima
private

Definition at line 295 of file clipper.hpp.

◆ m_ReverseOutput

bool ClipperLib::Clipper::m_ReverseOutput
private

Definition at line 300 of file clipper.hpp.

◆ m_SortedEdges

TEdge* ClipperLib::Clipper::m_SortedEdges
private

Definition at line 296 of file clipper.hpp.

◆ m_StrictSimple

bool ClipperLib::Clipper::m_StrictSimple
private

Definition at line 302 of file clipper.hpp.

◆ m_SubjFillType

PolyFillType ClipperLib::Clipper::m_SubjFillType
private

Definition at line 299 of file clipper.hpp.

◆ m_UsingPolyTree

bool ClipperLib::Clipper::m_UsingPolyTree
private

Definition at line 301 of file clipper.hpp.


The documentation for this class was generated from the following files:
ClipperLib::OutRec::BottomPt
OutPt * BottomPt
Definition: clipper.cpp:145
a2
constexpr double a2
Definition: hcurl_check_approx_in_2d.cpp:39
ClipperLib::Path
std::vector< IntPoint > Path
Definition: clipper.hpp:106
ClipperLib::Clipper::AddLocalMaxPoly
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt)
Definition: clipper.cpp:1920
ClipperLib::EdgesAdjacent
bool EdgesAdjacent(const IntersectNode &inode)
Definition: clipper.cpp:2959
ClipperLib::Paths
std::vector< Path > Paths
Definition: clipper.hpp:107
ClipperLib::SlopesEqual
bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
Definition: clipper.cpp:577
ClipperLib::Clipper::IntersectEdges
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt)
Definition: clipper.cpp:2142
ClipperLib::Clipper::InsertEdgeIntoAEL
void InsertEdgeIntoAEL(TEdge *edge, TEdge *startEdge)
Definition: clipper.cpp:3348
ClipperLib::DisposeOutPts
void DisposeOutPts(OutPt *&pp)
Definition: clipper.cpp:742
ClipperLib::Clipper::DisposeIntersectNodes
void DisposeIntersectNodes()
Definition: clipper.cpp:2880
ClipperLib::Clipper::m_ClipFillType
PolyFillType m_ClipFillType
Definition: clipper.hpp:298
ClipperLib::ClipperBase::m_UseFullRange
bool m_UseFullRange
Definition: clipper.hpp:249
ClipperLib::GetLowermostRec
OutRec * GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
Definition: clipper.cpp:2363
ClipperLib::Clipper::DoSimplePolygons
void DoSimplePolygons()
Definition: clipper.cpp:4250
ClipperLib::TopX
cInt TopX(TEdge &edge, const cInt currentY)
Definition: clipper.cpp:651
ClipperLib::TEdge::OutIdx
int OutIdx
Definition: clipper.cpp:112
ClipperLib::Clipper::FixupFirstLefts2
void FixupFirstLefts2(OutRec *InnerOutRec, OutRec *OuterOutRec)
Definition: clipper.cpp:3670
ClipperLib::Clipper::DoMaxima
void DoMaxima(TEdge *e)
Definition: clipper.cpp:2989
ClipperLib::ClipperBase::m_HasOpenPaths
bool m_HasOpenPaths
Definition: clipper.hpp:252
ClipperLib::E2InsertsBeforeE1
bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
Definition: clipper.cpp:3307
ClipperLib::Clipper::SetWindingCount
void SetWindingCount(TEdge &edge)
Definition: clipper.cpp:1660
ClipperLib::ctXor
@ ctXor
Definition: clipper.hpp:64
ClipperLib::PolyFillType
PolyFillType
Definition: clipper.hpp:70
ClipperLib::Clipper::AddEdgeToSEL
void AddEdgeToSEL(TEdge *edge)
Definition: clipper.cpp:1936
ClipperLib::Clipper::m_Maxima
MaximaList m_Maxima
Definition: clipper.hpp:295
ClipperLib::pftPositive
@ pftPositive
Definition: clipper.hpp:70
ClipperLib::cInt
signed long long cInt
Definition: clipper.hpp:77
ClipperLib::GetMaximaPair
TEdge * GetMaximaPair(TEdge *e)
Definition: clipper.cpp:2574
ClipperLib::PointCount
int PointCount(OutPt *Pts)
Definition: clipper.cpp:3213
ClipperLib::ptSubject
@ ptSubject
Definition: clipper.hpp:65
ClipperLib::ParseFirstLeft
static OutRec * ParseFirstLeft(OutRec *FirstLeft)
Definition: clipper.cpp:3646
ClipperLib::Clipper::ClearGhostJoins
void ClearGhostJoins()
Definition: clipper.cpp:1996
ClipperLib::Clipper::SwapPositionsInSEL
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2)
Definition: clipper.cpp:2594
ClipperLib::Clipper::ClearJoins
void ClearJoins()
Definition: clipper.cpp:1988
ClipperLib::GetMaximaPairEx
TEdge * GetMaximaPairEx(TEdge *e)
Definition: clipper.cpp:2584
ClipperLib::Clipper::ProcessHorizontal
void ProcessHorizontal(TEdge *horzEdge)
Definition: clipper.cpp:2672
ClipperLib::Clipper::BuildIntersectList
void BuildIntersectList(const cInt topY)
Definition: clipper.cpp:2888
ClipperLib::Area
double Area(const Path &poly)
Definition: clipper.cpp:427
ClipperLib::ctUnion
@ ctUnion
Definition: clipper.hpp:64
ClipperLib::GetOverlap
bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2, cInt &Left, cInt &Right)
Definition: clipper.cpp:3319
ClipperLib::ClipperBase::InsertScanbeam
void InsertScanbeam(const cInt Y)
Definition: clipper.cpp:1371
ClipperLib::Clipper::ProcessIntersections
bool ProcessIntersections(const cInt topY)
Definition: clipper.cpp:2859
ClipperLib::GetBottomPt
OutPt * GetBottomPt(OutPt *pp)
Definition: clipper.cpp:858
ClipperLib::Clipper::AddOutPt
OutPt * AddOutPt(TEdge *e, const IntPoint &pt)
Definition: clipper.cpp:2499
ClipperLib::JoinHorz
bool JoinHorz(OutPt *op1, OutPt *op1b, OutPt *op2, OutPt *op2b, const IntPoint Pt, bool DiscardLeft)
Definition: clipper.cpp:3400
ClipperLib::IntersectListSort
bool IntersectListSort(IntersectNode *node1, IntersectNode *node2)
Definition: clipper.cpp:2953
ClipperLib::ClipperBase::DeleteFromAEL
void DeleteFromAEL(TEdge *e)
Definition: clipper.cpp:1403
ClipperLib::Clipper::m_Joins
JoinList m_Joins
Definition: clipper.hpp:290
ClipperLib::Abs
cInt Abs(cInt val)
Definition: clipper.cpp:179
c
const double c
speed of light (cm/ns)
Definition: initial_diffusion.cpp:39
ClipperLib::ctDifference
@ ctDifference
Definition: clipper.hpp:64
ClipperLib::ClipperBase::m_ActiveEdges
TEdge * m_ActiveEdges
Definition: clipper.hpp:254
ClipperLib::ClipperBase::UpdateEdgeIntoAEL
void UpdateEdgeIntoAEL(TEdge *&e)
Definition: clipper.cpp:1478
ClipperLib::UpdateOutPtIdxs
void UpdateOutPtIdxs(OutRec &outrec)
Definition: clipper.cpp:3336
ClipperLib::TEdge::PrevInSEL
TEdge * PrevInSEL
Definition: clipper.cpp:119
ClipperLib::ReversePolyPtLinks
void ReversePolyPtLinks(OutPt *pp)
Definition: clipper.cpp:728
ClipperLib::Clipper::Clipper
Clipper(int initOptions=0)
Definition: clipper.cpp:1510
ClipperLib::ptClip
@ ptClip
Definition: clipper.hpp:65
ClipperLib::Clipper::FixupFirstLefts1
void FixupFirstLefts1(OutRec *OldOutRec, OutRec *NewOutRec)
Definition: clipper.cpp:3654
a1
constexpr double a1
Definition: hcurl_check_approx_in_2d.cpp:38
ClipperLib::ClipperBase::Clear
virtual void Clear()
Definition: clipper.cpp:1269
ClipperLib::Clipper::AddGhostJoin
void AddGhostJoin(OutPt *op, const IntPoint offPt)
Definition: clipper.cpp:2004
ClipperLib::HorzSegmentsOverlap
bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b)
Definition: clipper.cpp:908
ClipperLib::Clipper::FixupOutPolyline
void FixupOutPolyline(OutRec &outrec)
Definition: clipper.cpp:3145
double
ClipperLib::GetNextInAEL
TEdge * GetNextInAEL(TEdge *e, Direction dir)
Definition: clipper.cpp:2640
ClipperLib::Clipper::IsContributing
bool IsContributing(const TEdge &edge) const
Definition: clipper.cpp:1777
ClipperLib::dLeftToRight
@ dLeftToRight
Definition: clipper.cpp:93
ClipperLib::DupOutPt
OutPt * DupOutPt(OutPt *outPt, bool InsertAfter)
Definition: clipper.cpp:3377
ClipperLib::pftNegative
@ pftNegative
Definition: clipper.hpp:70
ClipperLib::SimplifyPolygons
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType=pftEvenOdd)
Definition: clipper.cpp:4334
ClipperLib::Unassigned
static const int Unassigned
Definition: clipper.cpp:95
ClipperLib::ReversePath
void ReversePath(Path &p)
Definition: clipper.cpp:4312
ClipperLib::Clipper::GetLastOutPt
OutPt * GetLastOutPt(TEdge *e)
Definition: clipper.cpp:2538
ClipperLib::ClipperBase::CreateOutRec
OutRec * CreateOutRec()
Definition: clipper.cpp:1416
ClipperLib::esRight
@ esRight
Definition: clipper.hpp:198
ClipperLib::Clipper::DeleteFromSEL
void DeleteFromSEL(TEdge *e)
Definition: clipper.cpp:2116
ClipperLib::Clipper::FixupFirstLefts3
void FixupFirstLefts3(OutRec *OldOutRec, OutRec *NewOutRec)
Definition: clipper.cpp:3695
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
ClipperLib::Clipper::m_SubjFillType
PolyFillType m_SubjFillType
Definition: clipper.hpp:299
ClipperLib::Clipper::FixupIntersectionOrder
bool FixupIntersectionOrder()
Definition: clipper.cpp:2966
ClipperLib::TEdge::Bot
IntPoint Bot
Definition: clipper.cpp:103
ClipperLib::Clipper::AddLocalMinPoly
OutPt * AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt)
Definition: clipper.cpp:1877
ClipperLib::ClipperBase::PopLocalMinima
bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin)
Definition: clipper.cpp:1322
ClipperLib::Clipper::m_ReverseOutput
bool m_ReverseOutput
Definition: clipper.hpp:300
ClipperLib::Clipper::m_GhostJoins
JoinList m_GhostJoins
Definition: clipper.hpp:291
ClipperLib::IsHorizontal
bool IsHorizontal(TEdge &e)
Definition: clipper.cpp:614
ClipperLib::pftEvenOdd
@ pftEvenOdd
Definition: clipper.hpp:70
ClipperLib::Clipper::m_IntersectList
IntersectList m_IntersectList
Definition: clipper.hpp:292
ClipperLib::GetHorzDirection
void GetHorzDirection(TEdge &HorzEdge, Direction &Dir, cInt &Left, cInt &Right)
Definition: clipper.cpp:2646
ClipperLib::Clipper::FixupOutPolygon
void FixupOutPolygon(OutRec &outrec)
Definition: clipper.cpp:3172
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
ClipperLib::dRightToLeft
@ dRightToLeft
Definition: clipper.cpp:93
ClipperLib::Clipper::m_ExecuteLocked
bool m_ExecuteLocked
Definition: clipper.hpp:297
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
ClipperLib::ClipperOffset::ClipperOffset
ClipperOffset(double miterLimit=2.0, double roundPrecision=0.25)
Definition: clipper.cpp:3815
ClipperLib::Direction
Direction
Definition: clipper.cpp:93
ClipperLib::IsMinima
bool IsMinima(TEdge *e)
Definition: clipper.cpp:2556
ClipperLib::IsMaxima
bool IsMaxima(TEdge *e, const cInt Y)
Definition: clipper.cpp:2562
ClipperLib::Clipper::IsEvenOddAltFillType
bool IsEvenOddAltFillType(const TEdge &edge) const
Definition: clipper.cpp:1769
ClipperLib::pftNonZero
@ pftNonZero
Definition: clipper.hpp:70
ClipperLib::Clipper::ExecuteInternal
virtual bool ExecuteInternal()
Definition: clipper.cpp:1596
ClipperLib::Clipper::PopEdgeFromSEL
bool PopEdgeFromSEL(TEdge *&edge)
Definition: clipper.cpp:1956
ClipperLib::IsIntermediate
bool IsIntermediate(TEdge *e, const cInt Y)
Definition: clipper.cpp:2568
ClipperLib::Clipper::m_UsingPolyTree
bool m_UsingPolyTree
Definition: clipper.hpp:301
ClipperLib::Clipper::m_SortedEdges
TEdge * m_SortedEdges
Definition: clipper.hpp:296
ClipperLib::Skip
static const int Skip
Definition: clipper.cpp:96
ClipperLib::ClipperOffset::~ClipperOffset
~ClipperOffset()
Definition: clipper.cpp:3823
ClipperLib::Clipper::m_ClipType
ClipType m_ClipType
Definition: clipper.hpp:293
ClipperLib::Clipper::GetOutRec
OutRec * GetOutRec(int idx)
Definition: clipper.cpp:2394
ClipperLib::Clipper::CopyAELToSEL
void CopyAELToSEL()
Definition: clipper.cpp:1965
ClipperLib::Poly2ContainsPoly1
bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2)
Definition: clipper.cpp:562
ClipperLib::esLeft
@ esLeft
Definition: clipper.hpp:198
ClipperLib::TEdge::WindCnt
int WindCnt
Definition: clipper.cpp:110
ClipperLib::ctIntersection
@ ctIntersection
Definition: clipper.hpp:64
ClipperLib::OutRec1RightOfOutRec2
bool OutRec1RightOfOutRec2(OutRec *outRec1, OutRec *outRec2)
Definition: clipper.cpp:2383
ClipperLib::ClipperBase::SwapPositionsInAEL
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2)
Definition: clipper.cpp:1431
ClipperLib::GetUnitNormal
DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2)
Definition: clipper.cpp:3798
ClipperLib::Clipper::IsEvenOddFillType
bool IsEvenOddFillType(const TEdge &edge) const
Definition: clipper.cpp:1761
ClipperLib::Clipper::JoinPoints
bool JoinPoints(Join *j, OutRec *outRec1, OutRec *outRec2)
Definition: clipper.cpp:3487
ClipperLib::Clipper::ProcessHorizontals
void ProcessHorizontals()
Definition: clipper.cpp:2548
ClipperLib::SwapPolyIndexes
void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2)
Definition: clipper.cpp:643
ClipperLib::ReversePaths
void ReversePaths(Paths &p)
Definition: clipper.cpp:4318
ClipperLib::Clipper::SetHoleState
void SetHoleState(TEdge *e, OutRec *outrec)
Definition: clipper.cpp:2337
ClipperLib::Clipper::AppendPolygon
void AppendPolygon(TEdge *e1, TEdge *e2)
Definition: clipper.cpp:2403
ClipperLib::ClipperBase::m_PolyOuts
PolyOutList m_PolyOuts
Definition: clipper.hpp:253
ClipperLib::SwapSides
void SwapSides(TEdge &Edge1, TEdge &Edge2)
Definition: clipper.cpp:635
ClipperLib::Pt2IsBetweenPt1AndPt3
bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3)
Definition: clipper.cpp:896
ClipperLib::TEdge::NextInSEL
TEdge * NextInSEL
Definition: clipper.cpp:118
ClipperLib::Clipper::m_StrictSimple
bool m_StrictSimple
Definition: clipper.hpp:302
ClipperLib::Clipper::ProcessEdgesAtTopOfScanbeam
void ProcessEdgesAtTopOfScanbeam(const cInt topY)
Definition: clipper.cpp:3041
ClipperLib::Clipper::ProcessIntersectList
void ProcessIntersectList()
Definition: clipper.cpp:2938
ClipperLib::OutRec::FirstLeft
OutRec * FirstLeft
Definition: clipper.cpp:142
ClipperLib::TEdge::NextInAEL
TEdge * NextInAEL
Definition: clipper.cpp:116
ClipperLib::Clipper::BuildResult
void BuildResult(Paths &polys)
Definition: clipper.cpp:3228
ClipperLib::Clipper::AddJoin
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt)
Definition: clipper.cpp:1978
ClipperLib::SimplifyPolygon
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType=pftEvenOdd)
Definition: clipper.cpp:4325