Commit 84cf7225 authored by Dick Hollenbeck's avatar Dick Hollenbeck

This is why we cannot have nice things. This is why we test our changes before committing.

Pray for angus johnson who is support too many languages, and needs to find a text editor that removes trailing whitespace.
parent dbb72d16
...@@ -136,7 +136,7 @@ struct Join { ...@@ -136,7 +136,7 @@ struct Join {
inline cInt Round(double val) inline cInt Round(double val)
{ {
if ((val < 0)) return static_cast<cInt>(val - 0.5); if ((val < 0)) return static_cast<cInt>(val - 0.5);
else return static_cast<cInt>(val + 0.5); else return static_cast<cInt>(val + 0.5);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -154,7 +154,7 @@ void PolyTree::Clear() ...@@ -154,7 +154,7 @@ void PolyTree::Clear()
{ {
for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i) for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i)
delete AllNodes[i]; delete AllNodes[i];
AllNodes.resize(0); AllNodes.resize(0);
Childs.resize(0); Childs.resize(0);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -198,27 +198,27 @@ void PolyNode::AddChild(PolyNode& child) ...@@ -198,27 +198,27 @@ void PolyNode::AddChild(PolyNode& child)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
PolyNode* PolyNode::GetNext() const PolyNode* PolyNode::GetNext() const
{ {
if (!Childs.empty()) if (!Childs.empty())
return Childs[0]; return Childs[0];
else else
return GetNextSiblingUp(); return GetNextSiblingUp();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
PolyNode* PolyNode::GetNextSiblingUp() const PolyNode* PolyNode::GetNextSiblingUp() const
{ {
if (!Parent) //protects against PolyTree.GetNextSiblingUp() if (!Parent) //protects against PolyTree.GetNextSiblingUp()
return 0; return 0;
else if (Index == Parent->Childs.size() - 1) else if (Index == Parent->Childs.size() - 1)
return Parent->GetNextSiblingUp(); return Parent->GetNextSiblingUp();
else else
return Parent->Childs[Index + 1]; return Parent->Childs[Index + 1];
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool PolyNode::IsHole() const bool PolyNode::IsHole() const
{ {
bool result = true; bool result = true;
PolyNode* node = Parent; PolyNode* node = Parent;
while (node) while (node)
...@@ -227,13 +227,13 @@ bool PolyNode::IsHole() const ...@@ -227,13 +227,13 @@ bool PolyNode::IsHole() const
node = node->Parent; node = node->Parent;
} }
return result; return result;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool PolyNode::IsOpen() const bool PolyNode::IsOpen() const
{ {
return m_IsOpen; return m_IsOpen;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifndef use_int32 #ifndef use_int32
...@@ -255,15 +255,15 @@ class Int128 ...@@ -255,15 +255,15 @@ class Int128
Int128(cInt _lo = 0) Int128(cInt _lo = 0)
{ {
lo = (cUInt)_lo; lo = (cUInt)_lo;
if (_lo < 0) hi = -1; else hi = 0; if (_lo < 0) hi = -1; else hi = 0;
} }
Int128(const Int128 &val): lo(val.lo), hi(val.hi){} Int128(const Int128 &val): lo(val.lo), hi(val.hi){}
Int128(const cInt& _hi, const ulong64& _lo): lo(_lo), hi(_hi){} Int128(const cInt& _hi, const ulong64& _lo): lo(_lo), hi(_hi){}
Int128& operator = (const cInt &val) Int128& operator = (const cInt &val)
{ {
lo = (ulong64)val; lo = (ulong64)val;
...@@ -331,7 +331,7 @@ class Int128 ...@@ -331,7 +331,7 @@ class Int128
{ {
if (lo == 0) if (lo == 0)
return Int128(-hi,0); return Int128(-hi,0);
else else
return Int128(~hi,~lo +1); return Int128(~hi,~lo +1);
} }
...@@ -362,12 +362,12 @@ class Int128 ...@@ -362,12 +362,12 @@ class Int128
} }
divisor.lo >>= 1; divisor.lo >>= 1;
if ((divisor.hi & 1) == 1) if ((divisor.hi & 1) == 1)
divisor.lo |= 0x8000000000000000LL; divisor.lo |= 0x8000000000000000LL;
divisor.hi = (ulong64)divisor.hi >> 1; divisor.hi = (ulong64)divisor.hi >> 1;
cntr.lo >>= 1; cntr.lo >>= 1;
if ((cntr.hi & 1) == 1) if ((cntr.hi & 1) == 1)
cntr.lo |= 0x8000000000000000LL; cntr.lo |= 0x8000000000000000LL;
cntr.hi >>= 1; cntr.hi >>= 1;
while (cntr.hi != 0 || cntr.lo != 0) while (cntr.hi != 0 || cntr.lo != 0)
...@@ -380,12 +380,12 @@ class Int128 ...@@ -380,12 +380,12 @@ class Int128
} }
divisor.lo >>= 1; divisor.lo >>= 1;
if ((divisor.hi & 1) == 1) if ((divisor.hi & 1) == 1)
divisor.lo |= 0x8000000000000000LL; divisor.lo |= 0x8000000000000000LL;
divisor.hi >>= 1; divisor.hi >>= 1;
cntr.lo >>= 1; cntr.lo >>= 1;
if ((cntr.hi & 1) == 1) if ((cntr.hi & 1) == 1)
cntr.lo |= 0x8000000000000000LL; cntr.lo |= 0x8000000000000000LL;
cntr.hi >>= 1; cntr.hi >>= 1;
} }
if (negate) result = -result; if (negate) result = -result;
...@@ -501,7 +501,7 @@ int PointInPolygon (const IntPoint& pt, OutPt* op) ...@@ -501,7 +501,7 @@ int PointInPolygon (const IntPoint& pt, OutPt* op)
{ {
if (op->Next->Pt.Y == pt.Y) if (op->Next->Pt.Y == pt.Y)
{ {
if ((op->Next->Pt.X == pt.X) || (op->Pt.Y == pt.Y && if ((op->Next->Pt.X == pt.X) || (op->Pt.Y == pt.Y &&
((op->Next->Pt.X > pt.X) == (op->Pt.X < pt.X)))) return -1; ((op->Next->Pt.X > pt.X) == (op->Pt.X < pt.X)))) return -1;
} }
if ((op->Pt.Y < pt.Y) != (op->Next->Pt.Y < pt.Y)) if ((op->Pt.Y < pt.Y) != (op->Next->Pt.Y < pt.Y))
...@@ -511,7 +511,7 @@ int PointInPolygon (const IntPoint& pt, OutPt* op) ...@@ -511,7 +511,7 @@ int PointInPolygon (const IntPoint& pt, OutPt* op)
if (op->Next->Pt.X > pt.X) result = 1 - result; if (op->Next->Pt.X > pt.X) result = 1 - result;
else else
{ {
double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) -
(double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y); (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
if (!d) return -1; if (!d) return -1;
if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result; if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
...@@ -520,16 +520,16 @@ int PointInPolygon (const IntPoint& pt, OutPt* op) ...@@ -520,16 +520,16 @@ int PointInPolygon (const IntPoint& pt, OutPt* op)
{ {
if (op->Next->Pt.X > pt.X) if (op->Next->Pt.X > pt.X)
{ {
double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) -
(double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y); (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
if (!d) return -1; if (!d) return -1;
if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result; if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
} }
} }
} }
op = op->Next; op = op->Next;
if (startOp == op) break; if (startOp == op) break;
} }
return result; return result;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -541,10 +541,10 @@ bool Poly2ContainsPoly1(OutPt* OutPt1, OutPt* OutPt2) ...@@ -541,10 +541,10 @@ bool Poly2ContainsPoly1(OutPt* OutPt1, OutPt* OutPt2)
{ {
int res = PointInPolygon(op->Pt, OutPt2); int res = PointInPolygon(op->Pt, OutPt2);
if (res >= 0) return res != 0; if (res >= 0) return res != 0;
op = op->Next; op = op->Next;
} }
while (op != OutPt1); while (op != OutPt1);
return true; return true;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
...@@ -553,7 +553,7 @@ bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range) ...@@ -553,7 +553,7 @@ bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
#ifndef use_int32 #ifndef use_int32
if (UseFullInt64Range) if (UseFullInt64Range)
return Int128Mul(e1.Delta.Y, e2.Delta.X) == Int128Mul(e1.Delta.X, e2.Delta.Y); return Int128Mul(e1.Delta.Y, e2.Delta.X) == Int128Mul(e1.Delta.X, e2.Delta.Y);
else else
#endif #endif
return e1.Delta.Y * e2.Delta.X == e1.Delta.X * e2.Delta.Y; return e1.Delta.Y * e2.Delta.X == e1.Delta.X * e2.Delta.Y;
} }
...@@ -565,7 +565,7 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, ...@@ -565,7 +565,7 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
#ifndef use_int32 #ifndef use_int32
if (UseFullInt64Range) if (UseFullInt64Range)
return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y); return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y);
else else
#endif #endif
return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y); return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y);
} }
...@@ -577,7 +577,7 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, ...@@ -577,7 +577,7 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
#ifndef use_int32 #ifndef use_int32
if (UseFullInt64Range) if (UseFullInt64Range)
return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y); return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y);
else else
#endif #endif
return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y); return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y);
} }
...@@ -632,11 +632,11 @@ inline cInt TopX(TEdge &edge, const cInt currentY) ...@@ -632,11 +632,11 @@ inline cInt TopX(TEdge &edge, const cInt currentY)
bool IntersectPoint(TEdge &Edge1, TEdge &Edge2, bool IntersectPoint(TEdge &Edge1, TEdge &Edge2,
IntPoint &ip, bool UseFullInt64Range) IntPoint &ip, bool UseFullInt64Range)
{ {
#ifdef use_xyz #ifdef use_xyz
ip.Z = 0; ip.Z = 0;
#endif #endif
double b1, b2; double b1, b2;
//nb: with very large coordinate values, it's possible for SlopesEqual() to //nb: with very large coordinate values, it's possible for SlopesEqual() to
//return false but for the edge.Dx value be equal due to double precision rounding. //return false but for the edge.Dx value be equal due to double precision rounding.
if (SlopesEqual(Edge1, Edge2, UseFullInt64Range) || Edge1.Dx == Edge2.Dx) if (SlopesEqual(Edge1, Edge2, UseFullInt64Range) || Edge1.Dx == Edge2.Dx)
{ {
...@@ -665,8 +665,8 @@ bool IntersectPoint(TEdge &Edge1, TEdge &Edge2, ...@@ -665,8 +665,8 @@ bool IntersectPoint(TEdge &Edge1, TEdge &Edge2,
b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx); b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx);
ip.Y = Round(ip.X / Edge1.Dx + b1); ip.Y = Round(ip.X / Edge1.Dx + b1);
} }
} }
else else
{ {
b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx; b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx;
b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx; b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx;
...@@ -674,11 +674,11 @@ bool IntersectPoint(TEdge &Edge1, TEdge &Edge2, ...@@ -674,11 +674,11 @@ bool IntersectPoint(TEdge &Edge1, TEdge &Edge2,
ip.Y = Round(q); ip.Y = Round(q);
if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
ip.X = Round(Edge1.Dx * q + b1); ip.X = Round(Edge1.Dx * q + b1);
else else
ip.X = Round(Edge2.Dx * q + b2); ip.X = Round(Edge2.Dx * q + b2);
} }
if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y) if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y)
{ {
if (Edge1.Top.Y > Edge2.Top.Y) if (Edge1.Top.Y > Edge2.Top.Y)
ip.Y = Edge1.Top.Y; ip.Y = Edge1.Top.Y;
...@@ -688,7 +688,7 @@ bool IntersectPoint(TEdge &Edge1, TEdge &Edge2, ...@@ -688,7 +688,7 @@ bool IntersectPoint(TEdge &Edge1, TEdge &Edge2,
ip.X = TopX(Edge1, ip.Y); ip.X = TopX(Edge1, ip.Y);
else else
ip.X = TopX(Edge2, ip.Y); ip.X = TopX(Edge2, ip.Y);
} }
return true; return true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -765,7 +765,7 @@ inline void ReverseHorizontal(TEdge &e) ...@@ -765,7 +765,7 @@ inline void ReverseHorizontal(TEdge &e)
cInt tmp = e.Top.X; cInt tmp = e.Top.X;
e.Top.X = e.Bot.X; e.Top.X = e.Bot.X;
e.Bot.X = tmp; e.Bot.X = tmp;
#ifdef use_xyz #ifdef use_xyz
tmp = e.Top.Z; tmp = e.Top.Z;
e.Top.Z = e.Bot.Z; e.Top.Z = e.Bot.Z;
e.Bot.Z = tmp; e.Bot.Z = tmp;
...@@ -860,7 +860,7 @@ OutPt* GetBottomPt(OutPt *pp) ...@@ -860,7 +860,7 @@ OutPt* GetBottomPt(OutPt *pp)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool FindSegment(OutPt* &pp, bool UseFullInt64Range, bool FindSegment(OutPt* &pp, bool UseFullInt64Range,
IntPoint &pt1, IntPoint &pt2) IntPoint &pt1, IntPoint &pt2)
{ {
//OutPt1 & OutPt2 => the overlap segment (if the function returns true) //OutPt1 & OutPt2 => the overlap segment (if the function returns true)
...@@ -914,7 +914,7 @@ OutPt* InsertPolyPtBetween(OutPt* p1, OutPt* p2, const IntPoint Pt) ...@@ -914,7 +914,7 @@ OutPt* InsertPolyPtBetween(OutPt* p1, OutPt* p2, const IntPoint Pt)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool HorzSegmentsOverlap(const IntPoint& pt1a, const IntPoint& pt1b, bool HorzSegmentsOverlap(const IntPoint& pt1a, const IntPoint& pt1b,
const IntPoint& pt2a, const IntPoint& pt2b) const IntPoint& pt2a, const IntPoint& pt2b)
{ {
//precondition: both segments are horizontal //precondition: both segments are horizontal
...@@ -950,10 +950,10 @@ void RangeTest(const IntPoint& Pt, bool& useFullRange) ...@@ -950,10 +950,10 @@ void RangeTest(const IntPoint& Pt, bool& useFullRange)
{ {
if (useFullRange) if (useFullRange)
{ {
if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange)
throw "Coordinate outside allowed range"; throw "Coordinate outside allowed range";
} }
else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange)
{ {
useFullRange = true; useFullRange = true;
RangeTest(Pt, useFullRange); RangeTest(Pt, useFullRange);
...@@ -991,7 +991,7 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise) ...@@ -991,7 +991,7 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise)
else StartX = E->Next->Bot.X; else StartX = E->Next->Bot.X;
if (E->Bot.X != StartX) ReverseHorizontal(*E); if (E->Bot.X != StartX) ReverseHorizontal(*E);
} }
if (Result->OutIdx != Skip) if (Result->OutIdx != Skip)
{ {
if (IsClockwise) if (IsClockwise)
...@@ -1005,31 +1005,31 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise) ...@@ -1005,31 +1005,31 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise)
//unless a Skip edge is encountered when that becomes the top divide //unless a Skip edge is encountered when that becomes the top divide
Horz = Result; Horz = Result;
while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev; while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev;
if (Horz->Prev->Top.X == Result->Next->Top.X) if (Horz->Prev->Top.X == Result->Next->Top.X)
{ {
if (!IsClockwise) Result = Horz->Prev; if (!IsClockwise) Result = Horz->Prev;
} }
else if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev; else if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev;
} }
while (E != Result) while (E != Result)
{ {
E->NextInLML = E->Next; E->NextInLML = E->Next;
if (IsHorizontal(*E) && E != EStart && if (IsHorizontal(*E) && E != EStart &&
E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E); E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
E = E->Next; E = E->Next;
} }
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X) if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X)
ReverseHorizontal(*E); ReverseHorizontal(*E);
Result = Result->Next; //move to the edge just beyond current bound Result = Result->Next; //move to the edge just beyond current bound
} else } else
{ {
while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip) while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip)
Result = Result->Prev; Result = Result->Prev;
if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip) if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip)
{ {
Horz = Result; Horz = Result;
while (IsHorizontal(*Horz->Next)) Horz = Horz->Next; while (IsHorizontal(*Horz->Next)) Horz = Horz->Next;
if (Horz->Next->Top.X == Result->Prev->Top.X) if (Horz->Next->Top.X == Result->Prev->Top.X)
{ {
if (!IsClockwise) Result = Horz->Next; if (!IsClockwise) Result = Horz->Next;
} }
...@@ -1039,17 +1039,17 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise) ...@@ -1039,17 +1039,17 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise)
while (E != Result) while (E != Result)
{ {
E->NextInLML = E->Prev; E->NextInLML = E->Prev;
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E); ReverseHorizontal(*E);
E = E->Prev; E = E->Prev;
} }
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E); ReverseHorizontal(*E);
Result = Result->Prev; //move to the edge just beyond current bound Result = Result->Prev; //move to the edge just beyond current bound
} }
} }
if (Result->OutIdx == Skip) if (Result->OutIdx == Skip)
{ {
//if edges still remain in the current bound beyond the skip edge then //if edges still remain in the current bound beyond the skip edge then
//create another LocMin and call ProcessBound once more //create another LocMin and call ProcessBound once more
...@@ -1073,7 +1073,7 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise) ...@@ -1073,7 +1073,7 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise)
{ {
//there are more edges in the bound beyond result starting with E //there are more edges in the bound beyond result starting with E
if (IsClockwise) if (IsClockwise)
E = Result->Next; E = Result->Next;
else else
E = Result->Prev; E = Result->Prev;
LocalMinima* locMin = new LocalMinima; LocalMinima* locMin = new LocalMinima;
...@@ -1144,10 +1144,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) ...@@ -1144,10 +1144,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
eLoopStop = E; eLoopStop = E;
continue; continue;
} }
if (E->Prev == E->Next) if (E->Prev == E->Next)
break; //only two vertices break; //only two vertices
else if (Closed && else if (Closed &&
SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) && SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) &&
(!m_PreserveCollinear || (!m_PreserveCollinear ||
!Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr))) !Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr)))
{ {
...@@ -1187,9 +1187,9 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) ...@@ -1187,9 +1187,9 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
//Totally flat paths must be handled differently when adding them //Totally flat paths must be handled differently when adding them
//to LocalMinima list to avoid endless loops etc ... //to LocalMinima list to avoid endless loops etc ...
if (IsFlat) if (IsFlat)
{ {
if (Closed) if (Closed)
{ {
delete [] edges; delete [] edges;
return false; return false;
...@@ -1211,7 +1211,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) ...@@ -1211,7 +1211,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
} }
InsertLocalMinima(locMin); InsertLocalMinima(locMin);
m_edges.push_back(edges); m_edges.push_back(edges);
return true; return true;
} }
m_edges.push_back(edges); m_edges.push_back(edges);
...@@ -1228,7 +1228,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) ...@@ -1228,7 +1228,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
LocalMinima* locMin = new LocalMinima; LocalMinima* locMin = new LocalMinima;
locMin->Next = 0; locMin->Next = 0;
locMin->Y = E->Bot.Y; locMin->Y = E->Bot.Y;
if (E->Dx < E->Prev->Dx) if (E->Dx < E->Prev->Dx)
{ {
locMin->LeftBound = E->Prev; locMin->LeftBound = E->Prev;
locMin->RightBound = E; locMin->RightBound = E;
...@@ -1297,7 +1297,7 @@ void ClipperBase::Clear() ...@@ -1297,7 +1297,7 @@ void ClipperBase::Clear()
DisposeLocalMinimaList(); DisposeLocalMinimaList();
for (EdgeList::size_type i = 0; i < m_edges.size(); ++i) for (EdgeList::size_type i = 0; i < m_edges.size(); ++i)
{ {
//for each edge array in turn, find the first used edge and //for each edge array in turn, find the first used edge and
//check for and remove any hiddenPts in each edge in the array. //check for and remove any hiddenPts in each edge in the array.
TEdge* edges = m_edges[i]; TEdge* edges = m_edges[i];
delete [] edges; delete [] edges;
...@@ -1410,7 +1410,7 @@ Clipper::Clipper(int initOptions) : ClipperBase() //constructor ...@@ -1410,7 +1410,7 @@ Clipper::Clipper(int initOptions) : ClipperBase() //constructor
m_StrictSimple = ((initOptions & ioStrictlySimple) != 0); m_StrictSimple = ((initOptions & ioStrictlySimple) != 0);
m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0); m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0);
m_HasOpenPaths = false; m_HasOpenPaths = false;
#ifdef use_xyz #ifdef use_xyz
m_ZFill = 0; m_ZFill = 0;
#endif #endif
} }
...@@ -1423,9 +1423,9 @@ Clipper::~Clipper() //destructor ...@@ -1423,9 +1423,9 @@ Clipper::~Clipper() //destructor
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifdef use_xyz #ifdef use_xyz
void Clipper::ZFillFunction(TZFillCallback zFillFunc) void Clipper::ZFillFunction(TZFillCallback zFillFunc)
{ {
m_ZFill = zFillFunc; m_ZFill = zFillFunc;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -1494,7 +1494,7 @@ void Clipper::FixHoleLinkage(OutRec &outrec) ...@@ -1494,7 +1494,7 @@ void Clipper::FixHoleLinkage(OutRec &outrec)
{ {
//skip OutRecs that (a) contain outermost polygons or //skip OutRecs that (a) contain outermost polygons or
//(b) already have the correct owner/child linkage ... //(b) already have the correct owner/child linkage ...
if (!outrec.FirstLeft || if (!outrec.FirstLeft ||
(outrec.IsHole != outrec.FirstLeft->IsHole && (outrec.IsHole != outrec.FirstLeft->IsHole &&
outrec.FirstLeft->Pts)) return; outrec.FirstLeft->Pts)) return;
...@@ -1524,7 +1524,7 @@ bool Clipper::ExecuteInternal() ...@@ -1524,7 +1524,7 @@ bool Clipper::ExecuteInternal()
botY = topY; botY = topY;
} while (!m_Scanbeam.empty() || m_CurrentLM); } while (!m_Scanbeam.empty() || m_CurrentLM);
} }
catch(...) catch(...)
{ {
succeeded = false; succeeded = false;
} }
...@@ -1599,7 +1599,7 @@ void Clipper::SetWindingCount(TEdge &edge) ...@@ -1599,7 +1599,7 @@ void Clipper::SetWindingCount(TEdge &edge)
edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta);
edge.WindCnt2 = 0; edge.WindCnt2 = 0;
e = m_ActiveEdges; //ie get ready to calc WindCnt2 e = m_ActiveEdges; //ie get ready to calc WindCnt2
} }
else if (edge.WindDelta == 0 && m_ClipType != ctUnion) else if (edge.WindDelta == 0 && m_ClipType != ctUnion)
{ {
edge.WindCnt = 1; edge.WindCnt = 1;
...@@ -1616,7 +1616,7 @@ void Clipper::SetWindingCount(TEdge &edge) ...@@ -1616,7 +1616,7 @@ void Clipper::SetWindingCount(TEdge &edge)
TEdge *e2 = e->PrevInAEL; TEdge *e2 = e->PrevInAEL;
while (e2) while (e2)
{ {
if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0) if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0)
Inside = !Inside; Inside = !Inside;
e2 = e2->PrevInAEL; e2 = e2->PrevInAEL;
} }
...@@ -1628,7 +1628,7 @@ void Clipper::SetWindingCount(TEdge &edge) ...@@ -1628,7 +1628,7 @@ void Clipper::SetWindingCount(TEdge &edge)
} }
edge.WindCnt2 = e->WindCnt2; edge.WindCnt2 = e->WindCnt2;
e = e->NextInAEL; //ie get ready to calc WindCnt2 e = e->NextInAEL; //ie get ready to calc WindCnt2
} }
else else
{ {
//nonZero, Positive or Negative filling ... //nonZero, Positive or Negative filling ...
...@@ -1639,11 +1639,11 @@ void Clipper::SetWindingCount(TEdge &edge) ...@@ -1639,11 +1639,11 @@ void Clipper::SetWindingCount(TEdge &edge)
if (Abs(e->WindCnt) > 1) if (Abs(e->WindCnt) > 1)
{ {
//outside prev poly but still inside another. //outside prev poly but still inside another.
//when reversing direction of prev poly use the same WC //when reversing direction of prev poly use the same WC
if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
//otherwise continue to 'decrease' WC ... //otherwise continue to 'decrease' WC ...
else edge.WindCnt = e->WindCnt + edge.WindDelta; else edge.WindCnt = e->WindCnt + edge.WindDelta;
} }
else else
//now outside all polys of same polytype so set own WC ... //now outside all polys of same polytype so set own WC ...
edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta);
...@@ -1651,7 +1651,7 @@ void Clipper::SetWindingCount(TEdge &edge) ...@@ -1651,7 +1651,7 @@ void Clipper::SetWindingCount(TEdge &edge)
{ {
//prev edge is 'increasing' WindCount (WC) away from zero //prev edge is 'increasing' WindCount (WC) away from zero
//so we're inside the previous polygon ... //so we're inside the previous polygon ...
if (edge.WindDelta == 0) if (edge.WindDelta == 0)
edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1); edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1);
//if wind direction is reversing prev then use same WC //if wind direction is reversing prev then use same WC
else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
...@@ -1715,14 +1715,14 @@ bool Clipper::IsContributing(const TEdge& edge) const ...@@ -1715,14 +1715,14 @@ bool Clipper::IsContributing(const TEdge& edge) const
switch(pft) switch(pft)
{ {
case pftEvenOdd: case pftEvenOdd:
//return false if a subj line has been flagged as inside a subj polygon //return false if a subj line has been flagged as inside a subj polygon
if (edge.WindDelta == 0 && edge.WindCnt != 1) return false; if (edge.WindDelta == 0 && edge.WindCnt != 1) return false;
break; break;
case pftNonZero: case pftNonZero:
if (Abs(edge.WindCnt) != 1) return false; if (Abs(edge.WindCnt) != 1) return false;
break; break;
case pftPositive: case pftPositive:
if (edge.WindCnt != 1) return false; if (edge.WindCnt != 1) return false;
break; break;
default: //pftNegative default: //pftNegative
...@@ -1734,24 +1734,24 @@ bool Clipper::IsContributing(const TEdge& edge) const ...@@ -1734,24 +1734,24 @@ bool Clipper::IsContributing(const TEdge& edge) const
case ctIntersection: case ctIntersection:
switch(pft2) switch(pft2)
{ {
case pftEvenOdd: case pftEvenOdd:
case pftNonZero: case pftNonZero:
return (edge.WindCnt2 != 0); return (edge.WindCnt2 != 0);
case pftPositive: case pftPositive:
return (edge.WindCnt2 > 0); return (edge.WindCnt2 > 0);
default: default:
return (edge.WindCnt2 < 0); return (edge.WindCnt2 < 0);
} }
break; break;
case ctUnion: case ctUnion:
switch(pft2) switch(pft2)
{ {
case pftEvenOdd: case pftEvenOdd:
case pftNonZero: case pftNonZero:
return (edge.WindCnt2 == 0); return (edge.WindCnt2 == 0);
case pftPositive: case pftPositive:
return (edge.WindCnt2 <= 0); return (edge.WindCnt2 <= 0);
default: default:
return (edge.WindCnt2 >= 0); return (edge.WindCnt2 >= 0);
} }
break; break;
...@@ -1759,23 +1759,23 @@ bool Clipper::IsContributing(const TEdge& edge) const ...@@ -1759,23 +1759,23 @@ bool Clipper::IsContributing(const TEdge& edge) const
if (edge.PolyTyp == ptSubject) if (edge.PolyTyp == ptSubject)
switch(pft2) switch(pft2)
{ {
case pftEvenOdd: case pftEvenOdd:
case pftNonZero: case pftNonZero:
return (edge.WindCnt2 == 0); return (edge.WindCnt2 == 0);
case pftPositive: case pftPositive:
return (edge.WindCnt2 <= 0); return (edge.WindCnt2 <= 0);
default: default:
return (edge.WindCnt2 >= 0); return (edge.WindCnt2 >= 0);
} }
else else
switch(pft2) switch(pft2)
{ {
case pftEvenOdd: case pftEvenOdd:
case pftNonZero: case pftNonZero:
return (edge.WindCnt2 != 0); return (edge.WindCnt2 != 0);
case pftPositive: case pftPositive:
return (edge.WindCnt2 > 0); return (edge.WindCnt2 > 0);
default: default:
return (edge.WindCnt2 < 0); return (edge.WindCnt2 < 0);
} }
break; break;
...@@ -1783,15 +1783,15 @@ bool Clipper::IsContributing(const TEdge& edge) const ...@@ -1783,15 +1783,15 @@ bool Clipper::IsContributing(const TEdge& edge) const
if (edge.WindDelta == 0) //XOr always contributing unless open if (edge.WindDelta == 0) //XOr always contributing unless open
switch(pft2) switch(pft2)
{ {
case pftEvenOdd: case pftEvenOdd:
case pftNonZero: case pftNonZero:
return (edge.WindCnt2 == 0); return (edge.WindCnt2 == 0);
case pftPositive: case pftPositive:
return (edge.WindCnt2 <= 0); return (edge.WindCnt2 <= 0);
default: default:
return (edge.WindCnt2 >= 0); return (edge.WindCnt2 >= 0);
} }
else else
return true; return true;
break; break;
default: default:
...@@ -1812,7 +1812,7 @@ OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) ...@@ -1812,7 +1812,7 @@ OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
e2->Side = esRight; e2->Side = esRight;
e = e1; e = e1;
if (e->PrevInAEL == e2) if (e->PrevInAEL == e2)
prevE = e2->PrevInAEL; prevE = e2->PrevInAEL;
else else
prevE = e->PrevInAEL; prevE = e->PrevInAEL;
} else } else
...@@ -1849,9 +1849,9 @@ void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) ...@@ -1849,9 +1849,9 @@ void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
e1->OutIdx = Unassigned; e1->OutIdx = Unassigned;
e2->OutIdx = Unassigned; e2->OutIdx = Unassigned;
} }
else if (e1->OutIdx < e2->OutIdx) else if (e1->OutIdx < e2->OutIdx)
AppendPolygon(e1, e2); AppendPolygon(e1, e2);
else else
AppendPolygon(e2, e1); AppendPolygon(e2, e1);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -1939,8 +1939,8 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) ...@@ -1939,8 +1939,8 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
InsertEdgeIntoAEL(rb, 0); InsertEdgeIntoAEL(rb, 0);
SetWindingCount(*rb); SetWindingCount(*rb);
if (IsContributing(*rb)) if (IsContributing(*rb))
Op1 = AddOutPt(rb, rb->Bot); Op1 = AddOutPt(rb, rb->Bot);
} }
else if (!rb) else if (!rb)
{ {
InsertEdgeIntoAEL(lb, 0); InsertEdgeIntoAEL(lb, 0);
...@@ -1957,7 +1957,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) ...@@ -1957,7 +1957,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
rb->WindCnt = lb->WindCnt; rb->WindCnt = lb->WindCnt;
rb->WindCnt2 = lb->WindCnt2; rb->WindCnt2 = lb->WindCnt2;
if (IsContributing(*lb)) if (IsContributing(*lb))
Op1 = AddLocalMinPoly(lb, rb, lb->Bot); Op1 = AddLocalMinPoly(lb, rb, lb->Bot);
InsertScanbeam(lb->Top.Y); InsertScanbeam(lb->Top.Y);
} }
...@@ -1970,7 +1970,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) ...@@ -1970,7 +1970,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
if (!lb || !rb) continue; if (!lb || !rb) continue;
//if any output polygons share an edge, they'll need joining later ... //if any output polygons share an edge, they'll need joining later ...
if (Op1 && IsHorizontal(*rb) && if (Op1 && IsHorizontal(*rb) &&
m_GhostJoins.size() > 0 && (rb->WindDelta != 0)) m_GhostJoins.size() > 0 && (rb->WindDelta != 0))
{ {
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i) for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
...@@ -1983,7 +1983,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) ...@@ -1983,7 +1983,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
} }
} }
if (lb->OutIdx >= 0 && lb->PrevInAEL && if (lb->OutIdx >= 0 && lb->PrevInAEL &&
lb->PrevInAEL->Curr.X == lb->Bot.X && lb->PrevInAEL->Curr.X == lb->Bot.X &&
lb->PrevInAEL->OutIdx >= 0 && lb->PrevInAEL->OutIdx >= 0 &&
SlopesEqual(*lb->PrevInAEL, *lb, m_UseFullRange) && SlopesEqual(*lb->PrevInAEL, *lb, m_UseFullRange) &&
...@@ -2016,7 +2016,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) ...@@ -2016,7 +2016,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
} }
} }
} }
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
...@@ -2089,7 +2089,7 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, ...@@ -2089,7 +2089,7 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2,
} }
//if intersecting a subj line with a subj poly ... //if intersecting a subj line with a subj poly ...
else if (e1->PolyTyp == e2->PolyTyp && else if (e1->PolyTyp == e2->PolyTyp &&
e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion) e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion)
{ {
if (e1->WindDelta == 0) if (e1->WindDelta == 0)
...@@ -2112,13 +2112,13 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, ...@@ -2112,13 +2112,13 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2,
else if (e1->PolyTyp != e2->PolyTyp) else if (e1->PolyTyp != e2->PolyTyp)
{ {
//toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ... //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ...
if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 && if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 &&
(m_ClipType != ctUnion || e2->WindCnt2 == 0)) (m_ClipType != ctUnion || e2->WindCnt2 == 0))
{ {
AddOutPt(e1, Pt); AddOutPt(e1, Pt);
if (e1Contributing) e1->OutIdx = Unassigned; if (e1Contributing) e1->OutIdx = Unassigned;
} }
else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) && else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) &&
(m_ClipType != ctUnion || e1->WindCnt2 == 0)) (m_ClipType != ctUnion || e1->WindCnt2 == 0))
{ {
AddOutPt(e2, Pt); AddOutPt(e2, Pt);
...@@ -2129,7 +2129,7 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, ...@@ -2129,7 +2129,7 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2,
if (e1stops) if (e1stops)
if (e1->OutIdx < 0) DeleteFromAEL(e1); if (e1->OutIdx < 0) DeleteFromAEL(e1);
else throw clipperException("Error intersecting polylines"); else throw clipperException("Error intersecting polylines");
if (e2stops) if (e2stops)
if (e2->OutIdx < 0) DeleteFromAEL(e2); if (e2->OutIdx < 0) DeleteFromAEL(e2);
else throw clipperException("Error intersecting polylines"); else throw clipperException("Error intersecting polylines");
return; return;
...@@ -2196,10 +2196,10 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, ...@@ -2196,10 +2196,10 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2,
if ( e1Contributing && e2Contributing ) if ( e1Contributing && e2Contributing )
{ {
if ( e1stops || e2stops || if ( e1stops || e2stops ||
(e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
(e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) ) (e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) )
AddLocalMaxPoly(e1, e2, Pt); AddLocalMaxPoly(e1, e2, Pt);
else else
{ {
AddOutPt(e1, Pt); AddOutPt(e1, Pt);
...@@ -2210,7 +2210,7 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, ...@@ -2210,7 +2210,7 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2,
} }
else if ( e1Contributing ) else if ( e1Contributing )
{ {
if (e2Wc == 0 || e2Wc == 1) if (e2Wc == 0 || e2Wc == 1)
{ {
AddOutPt(e1, Pt); AddOutPt(e1, Pt);
SwapSides(*e1, *e2); SwapSides(*e1, *e2);
...@@ -2219,14 +2219,14 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, ...@@ -2219,14 +2219,14 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2,
} }
else if ( e2Contributing ) else if ( e2Contributing )
{ {
if (e1Wc == 0 || e1Wc == 1) if (e1Wc == 0 || e1Wc == 1)
{ {
AddOutPt(e2, Pt); AddOutPt(e2, Pt);
SwapSides(*e1, *e2); SwapSides(*e1, *e2);
SwapPolyIndexes(*e1, *e2); SwapPolyIndexes(*e1, *e2);
} }
} }
else if ( (e1Wc == 0 || e1Wc == 1) && else if ( (e1Wc == 0 || e1Wc == 1) &&
(e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops ) (e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops )
{ {
//neither edge is currently contributing ... //neither edge is currently contributing ...
...@@ -2303,9 +2303,9 @@ void Clipper::SetHoleState(TEdge *e, OutRec *outrec) ...@@ -2303,9 +2303,9 @@ void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2) OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
{ {
//work out which polygon fragment has the correct hole state ... //work out which polygon fragment has the correct hole state ...
if (!outRec1->BottomPt) if (!outRec1->BottomPt)
outRec1->BottomPt = GetBottomPt(outRec1->Pts); outRec1->BottomPt = GetBottomPt(outRec1->Pts);
if (!outRec2->BottomPt) if (!outRec2->BottomPt)
outRec2->BottomPt = GetBottomPt(outRec2->Pts); outRec2->BottomPt = GetBottomPt(outRec2->Pts);
OutPt *OutPt1 = outRec1->BottomPt; OutPt *OutPt1 = outRec1->BottomPt;
OutPt *OutPt2 = outRec2->BottomPt; OutPt *OutPt2 = outRec2->BottomPt;
...@@ -2347,11 +2347,11 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) ...@@ -2347,11 +2347,11 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
OutRec *outRec2 = m_PolyOuts[e2->OutIdx]; OutRec *outRec2 = m_PolyOuts[e2->OutIdx];
OutRec *holeStateRec; OutRec *holeStateRec;
if (Param1RightOfParam2(outRec1, outRec2)) if (Param1RightOfParam2(outRec1, outRec2))
holeStateRec = outRec2; holeStateRec = outRec2;
else if (Param1RightOfParam2(outRec2, outRec1)) else if (Param1RightOfParam2(outRec2, outRec1))
holeStateRec = outRec1; holeStateRec = outRec1;
else else
holeStateRec = GetLowermostRec(outRec1, outRec2); holeStateRec = GetLowermostRec(outRec1, outRec2);
//get the start and ends of both output polygons and //get the start and ends of both output polygons and
...@@ -2552,7 +2552,7 @@ TEdge *GetMaximaPair(TEdge *e) ...@@ -2552,7 +2552,7 @@ TEdge *GetMaximaPair(TEdge *e)
void Clipper::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2) void Clipper::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
{ {
//check that one or other edge hasn't already been removed from AEL ... //check that one or other edge hasn't already been removed from AEL ...
if (Edge1->NextInAEL == Edge1->PrevInAEL || if (Edge1->NextInAEL == Edge1->PrevInAEL ||
Edge2->NextInAEL == Edge2->PrevInAEL) return; Edge2->NextInAEL == Edge2->PrevInAEL) return;
if( Edge1->NextInAEL == Edge2 ) if( Edge1->NextInAEL == Edge2 )
...@@ -2684,10 +2684,10 @@ void Clipper::PrepareHorzJoins(TEdge* horzEdge, bool isTopOfScanbeam) ...@@ -2684,10 +2684,10 @@ void Clipper::PrepareHorzJoins(TEdge* horzEdge, bool isTopOfScanbeam)
//the AEL before we process the horizontal edges at the bottom of the next, //the AEL before we process the horizontal edges at the bottom of the next,
//we need to create 'ghost' Join records of 'contrubuting' horizontals that //we need to create 'ghost' Join records of 'contrubuting' horizontals that
//we can compare with horizontals at the bottom of the next SB. //we can compare with horizontals at the bottom of the next SB.
if (isTopOfScanbeam) if (isTopOfScanbeam)
{ {
if (outPt->Pt == horzEdge->Top) if (outPt->Pt == horzEdge->Top)
AddGhostJoin(outPt, horzEdge->Bot); AddGhostJoin(outPt, horzEdge->Bot);
else else
AddGhostJoin(outPt, horzEdge->Top); AddGhostJoin(outPt, horzEdge->Top);
} }
...@@ -2712,7 +2712,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam) ...@@ -2712,7 +2712,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam)
GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
TEdge* eLastHorz = horzEdge, *eMaxPair = 0; TEdge* eLastHorz = horzEdge, *eMaxPair = 0;
while (eLastHorz->NextInLML && IsHorizontal(*eLastHorz->NextInLML)) while (eLastHorz->NextInLML && IsHorizontal(*eLastHorz->NextInLML))
eLastHorz = eLastHorz->NextInLML; eLastHorz = eLastHorz->NextInLML;
if (!eLastHorz->NextInLML) if (!eLastHorz->NextInLML)
eMaxPair = GetMaximaPair(eLastHorz); eMaxPair = GetMaximaPair(eLastHorz);
...@@ -2725,7 +2725,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam) ...@@ -2725,7 +2725,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam)
{ {
//Break if we've got to the end of an intermediate horizontal edge ... //Break if we've got to the end of an intermediate horizontal edge ...
//nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal. //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal.
if (e->Curr.X == horzEdge->Top.X && horzEdge->NextInLML && if (e->Curr.X == horzEdge->Top.X && horzEdge->NextInLML &&
e->Dx < horzEdge->NextInLML->Dx) break; e->Dx < horzEdge->NextInLML->Dx) break;
TEdge* eNext = GetNextInAEL(e, dir); //saves eNext for later TEdge* eNext = GetNextInAEL(e, dir); //saves eNext for later
...@@ -2733,7 +2733,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam) ...@@ -2733,7 +2733,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam)
if ((dir == dLeftToRight && e->Curr.X <= horzRight) || if ((dir == dLeftToRight && e->Curr.X <= horzRight) ||
(dir == dRightToLeft && e->Curr.X >= horzLeft)) (dir == dRightToLeft && e->Curr.X >= horzLeft))
{ {
if (horzEdge->OutIdx >= 0 && horzEdge->WindDelta != 0) if (horzEdge->OutIdx >= 0 && horzEdge->WindDelta != 0)
PrepareHorzJoins(horzEdge, isTopOfScanbeam); PrepareHorzJoins(horzEdge, isTopOfScanbeam);
//so far we're still in range of the horizontal Edge but make sure //so far we're still in range of the horizontal Edge but make sure
//we're at the last of consec. horizontals when matching with eMaxPair //we're at the last of consec. horizontals when matching with eMaxPair
...@@ -2803,14 +2803,14 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam) ...@@ -2803,14 +2803,14 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam)
} }
} }
else else
UpdateEdgeIntoAEL(horzEdge); UpdateEdgeIntoAEL(horzEdge);
} }
else if (eMaxPair) else if (eMaxPair)
{ {
if (eMaxPair->OutIdx >= 0) if (eMaxPair->OutIdx >= 0)
{ {
if (dir == dLeftToRight) if (dir == dLeftToRight)
IntersectEdges(horzEdge, eMaxPair, horzEdge->Top); IntersectEdges(horzEdge, eMaxPair, horzEdge->Top);
else else
IntersectEdges(eMaxPair, horzEdge, horzEdge->Top); IntersectEdges(eMaxPair, horzEdge, horzEdge->Top);
if (eMaxPair->OutIdx >= 0) if (eMaxPair->OutIdx >= 0)
...@@ -2861,7 +2861,7 @@ bool Clipper::ProcessIntersections(const cInt botY, const cInt topY) ...@@ -2861,7 +2861,7 @@ bool Clipper::ProcessIntersections(const cInt botY, const cInt topY)
if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList(); if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList();
else return false; else return false;
} }
catch(...) catch(...)
{ {
m_SortedEdges = 0; m_SortedEdges = 0;
DisposeIntersectNodes(); DisposeIntersectNodes();
...@@ -2974,7 +2974,7 @@ bool Clipper::FixupIntersectionOrder() ...@@ -2974,7 +2974,7 @@ bool Clipper::FixupIntersectionOrder()
CopyAELToSEL(); CopyAELToSEL();
std::sort(m_IntersectList.begin(), m_IntersectList.end(), IntersectListSort); std::sort(m_IntersectList.begin(), m_IntersectList.end(), IntersectListSort);
size_t cnt = m_IntersectList.size(); size_t cnt = m_IntersectList.size();
for (size_t i = 0; i < cnt; ++i) for (size_t i = 0; i < cnt; ++i)
{ {
if (!EdgesAdjacent(*m_IntersectList[i])) if (!EdgesAdjacent(*m_IntersectList[i]))
{ {
...@@ -3020,7 +3020,7 @@ void Clipper::DoMaxima(TEdge *e) ...@@ -3020,7 +3020,7 @@ void Clipper::DoMaxima(TEdge *e)
#ifdef use_lines #ifdef use_lines
else if (e->WindDelta == 0) else if (e->WindDelta == 0)
{ {
if (e->OutIdx >= 0) if (e->OutIdx >= 0)
{ {
AddOutPt(e, e->Top); AddOutPt(e, e->Top);
e->OutIdx = Unassigned; e->OutIdx = Unassigned;
...@@ -3033,7 +3033,7 @@ void Clipper::DoMaxima(TEdge *e) ...@@ -3033,7 +3033,7 @@ void Clipper::DoMaxima(TEdge *e)
eMaxPair->OutIdx = Unassigned; eMaxPair->OutIdx = Unassigned;
} }
DeleteFromAEL(eMaxPair); DeleteFromAEL(eMaxPair);
} }
#endif #endif
else throw clipperException("DoMaxima error"); else throw clipperException("DoMaxima error");
} }
...@@ -3070,7 +3070,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) ...@@ -3070,7 +3070,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
if (e->OutIdx >= 0) if (e->OutIdx >= 0)
AddOutPt(e, e->Bot); AddOutPt(e, e->Bot);
AddEdgeToSEL(e); AddEdgeToSEL(e);
} }
else else
{ {
e->Curr.X = TopX( *e, topY ); e->Curr.X = TopX( *e, topY );
...@@ -3078,7 +3078,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) ...@@ -3078,7 +3078,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
} }
if (m_StrictSimple) if (m_StrictSimple)
{ {
TEdge* ePrev = e->PrevInAEL; TEdge* ePrev = e->PrevInAEL;
if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) && if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) &&
(ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0)) (ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0))
...@@ -3103,7 +3103,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) ...@@ -3103,7 +3103,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
if(IsIntermediate(e, topY)) if(IsIntermediate(e, topY))
{ {
OutPt* op = 0; OutPt* op = 0;
if( e->OutIdx >= 0 ) if( e->OutIdx >= 0 )
op = AddOutPt(e, e->Top); op = AddOutPt(e, e->Top);
UpdateEdgeIntoAEL(e); UpdateEdgeIntoAEL(e);
...@@ -3152,9 +3152,9 @@ void Clipper::FixupOutPolygon(OutRec &outrec) ...@@ -3152,9 +3152,9 @@ void Clipper::FixupOutPolygon(OutRec &outrec)
} }
//test for duplicate points and collinear edges ... //test for duplicate points and collinear edges ...
if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) || if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) ||
(SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) && (SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) &&
(!m_PreserveCollinear || (!m_PreserveCollinear ||
!Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt)))) !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt))))
{ {
lastOK = 0; lastOK = 0;
...@@ -3243,12 +3243,12 @@ void Clipper::BuildResult2(PolyTree& polytree) ...@@ -3243,12 +3243,12 @@ void Clipper::BuildResult2(PolyTree& polytree)
{ {
OutRec* outRec = m_PolyOuts[i]; OutRec* outRec = m_PolyOuts[i];
if (!outRec->PolyNd) continue; if (!outRec->PolyNd) continue;
if (outRec->IsOpen) if (outRec->IsOpen)
{ {
outRec->PolyNd->m_IsOpen = true; outRec->PolyNd->m_IsOpen = true;
polytree.AddChild(*outRec->PolyNd); polytree.AddChild(*outRec->PolyNd);
} }
else if (outRec->FirstLeft && outRec->FirstLeft->PolyNd) else if (outRec->FirstLeft && outRec->FirstLeft->PolyNd)
outRec->FirstLeft->PolyNd->AddChild(*outRec->PolyNd); outRec->FirstLeft->PolyNd->AddChild(*outRec->PolyNd);
else else
polytree.AddChild(*outRec->PolyNd); polytree.AddChild(*outRec->PolyNd);
...@@ -3271,24 +3271,24 @@ void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2) ...@@ -3271,24 +3271,24 @@ void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2)
inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2) inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
{ {
if (e2.Curr.X == e1.Curr.X) if (e2.Curr.X == e1.Curr.X)
{ {
if (e2.Top.Y > e1.Top.Y) if (e2.Top.Y > e1.Top.Y)
return e2.Top.X < TopX(e1, e2.Top.Y); return e2.Top.X < TopX(e1, e2.Top.Y);
else return e1.Top.X > TopX(e2, e1.Top.Y); else return e1.Top.X > TopX(e2, e1.Top.Y);
} }
else return e2.Curr.X < e1.Curr.X; else return e2.Curr.X < e1.Curr.X;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2, bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2,
cInt& Left, cInt& Right) cInt& Left, cInt& Right)
{ {
if (a1 < a2) if (a1 < a2)
{ {
if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);} if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);}
else {Left = std::max(a1,b2); Right = std::min(a2,b1);} else {Left = std::max(a1,b2); Right = std::min(a2,b1);}
} }
else else
{ {
if (b1 < b2) {Left = std::max(a2,b1); Right = std::min(a1,b2);} if (b1 < b2) {Left = std::max(a2,b1); Right = std::min(a1,b2);}
...@@ -3299,7 +3299,7 @@ bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2, ...@@ -3299,7 +3299,7 @@ bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline void UpdateOutPtIdxs(OutRec& outrec) inline void UpdateOutPtIdxs(OutRec& outrec)
{ {
OutPt* op = outrec.Pts; OutPt* op = outrec.Pts;
do do
{ {
...@@ -3324,11 +3324,11 @@ void Clipper::InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge) ...@@ -3324,11 +3324,11 @@ void Clipper::InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge)
edge->NextInAEL = m_ActiveEdges; edge->NextInAEL = m_ActiveEdges;
m_ActiveEdges->PrevInAEL = edge; m_ActiveEdges->PrevInAEL = edge;
m_ActiveEdges = edge; m_ActiveEdges = edge;
} }
else else
{ {
if(!startEdge) startEdge = m_ActiveEdges; if(!startEdge) startEdge = m_ActiveEdges;
while(startEdge->NextInAEL && while(startEdge->NextInAEL &&
!E2InsertsBeforeE1(*startEdge->NextInAEL , *edge)) !E2InsertsBeforeE1(*startEdge->NextInAEL , *edge))
startEdge = startEdge->NextInAEL; startEdge = startEdge->NextInAEL;
edge->NextInAEL = startEdge->NextInAEL; edge->NextInAEL = startEdge->NextInAEL;
...@@ -3350,7 +3350,7 @@ OutPt* DupOutPt(OutPt* outPt, bool InsertAfter) ...@@ -3350,7 +3350,7 @@ OutPt* DupOutPt(OutPt* outPt, bool InsertAfter)
result->Prev = outPt; result->Prev = outPt;
outPt->Next->Prev = result; outPt->Next->Prev = result;
outPt->Next = result; outPt->Next = result;
} }
else else
{ {
result->Prev = outPt->Prev; result->Prev = outPt->Prev;
...@@ -3374,24 +3374,24 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b, ...@@ -3374,24 +3374,24 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
//So, to facilitate this while inserting Op1b and Op2b ... //So, to facilitate this while inserting Op1b and Op2b ...
//when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b, //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b,
//otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.) //otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.)
if (Dir1 == dLeftToRight) if (Dir1 == dLeftToRight)
{ {
while (op1->Next->Pt.X <= Pt.X && while (op1->Next->Pt.X <= Pt.X &&
op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y)
op1 = op1->Next; op1 = op1->Next;
if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
op1b = DupOutPt(op1, !DiscardLeft); op1b = DupOutPt(op1, !DiscardLeft);
if (op1b->Pt != Pt) if (op1b->Pt != Pt)
{ {
op1 = op1b; op1 = op1b;
op1->Pt = Pt; op1->Pt = Pt;
op1b = DupOutPt(op1, !DiscardLeft); op1b = DupOutPt(op1, !DiscardLeft);
} }
} }
else else
{ {
while (op1->Next->Pt.X >= Pt.X && while (op1->Next->Pt.X >= Pt.X &&
op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y)
op1 = op1->Next; op1 = op1->Next;
if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
op1b = DupOutPt(op1, DiscardLeft); op1b = DupOutPt(op1, DiscardLeft);
...@@ -3405,7 +3405,7 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b, ...@@ -3405,7 +3405,7 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
if (Dir2 == dLeftToRight) if (Dir2 == dLeftToRight)
{ {
while (op2->Next->Pt.X <= Pt.X && while (op2->Next->Pt.X <= Pt.X &&
op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y)
op2 = op2->Next; op2 = op2->Next;
if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
...@@ -3418,8 +3418,8 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b, ...@@ -3418,8 +3418,8 @@ bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
}; };
} else } else
{ {
while (op2->Next->Pt.X >= Pt.X && while (op2->Next->Pt.X >= Pt.X &&
op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y)
op2 = op2->Next; op2 = op2->Next;
if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
op2b = DupOutPt(op2, DiscardLeft); op2b = DupOutPt(op2, DiscardLeft);
...@@ -3468,11 +3468,11 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) ...@@ -3468,11 +3468,11 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
{ {
//Strictly Simple join ... //Strictly Simple join ...
op1b = j->OutPt1->Next; op1b = j->OutPt1->Next;
while (op1b != op1 && (op1b->Pt == j->OffPt)) while (op1b != op1 && (op1b->Pt == j->OffPt))
op1b = op1b->Next; op1b = op1b->Next;
bool reverse1 = (op1b->Pt.Y > j->OffPt.Y); bool reverse1 = (op1b->Pt.Y > j->OffPt.Y);
op2b = j->OutPt2->Next; op2b = j->OutPt2->Next;
while (op2b != op2 && (op2b->Pt == j->OffPt)) while (op2b != op2 && (op2b->Pt == j->OffPt))
op2b = op2b->Next; op2b = op2b->Next;
bool reverse2 = (op2b->Pt.Y > j->OffPt.Y); bool reverse2 = (op2b->Pt.Y > j->OffPt.Y);
if (reverse1 == reverse2) return false; if (reverse1 == reverse2) return false;
...@@ -3499,7 +3499,7 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) ...@@ -3499,7 +3499,7 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
j->OutPt2 = op1b; j->OutPt2 = op1b;
return true; return true;
} }
} }
else if (isHorizontal) else if (isHorizontal)
{ {
//treat horizontal joins differently to non-horizontal joins since with //treat horizontal joins differently to non-horizontal joins since with
...@@ -3529,18 +3529,18 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) ...@@ -3529,18 +3529,18 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
//on the discard Side as either may still be needed for other joins ... //on the discard Side as either may still be needed for other joins ...
IntPoint Pt; IntPoint Pt;
bool DiscardLeftSide; bool DiscardLeftSide;
if (op1->Pt.X >= Left && op1->Pt.X <= Right) if (op1->Pt.X >= Left && op1->Pt.X <= Right)
{ {
Pt = op1->Pt; DiscardLeftSide = (op1->Pt.X > op1b->Pt.X); Pt = op1->Pt; DiscardLeftSide = (op1->Pt.X > op1b->Pt.X);
} }
else if (op2->Pt.X >= Left&& op2->Pt.X <= Right) else if (op2->Pt.X >= Left&& op2->Pt.X <= Right)
{ {
Pt = op2->Pt; DiscardLeftSide = (op2->Pt.X > op2b->Pt.X); Pt = op2->Pt; DiscardLeftSide = (op2->Pt.X > op2b->Pt.X);
} }
else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right) else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right)
{ {
Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->Pt.X; Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->Pt.X;
} }
else else
{ {
Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->Pt.X); Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->Pt.X);
...@@ -3608,12 +3608,12 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) ...@@ -3608,12 +3608,12 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
{ {
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{ {
OutRec* outRec = m_PolyOuts[i]; OutRec* outRec = m_PolyOuts[i];
if (outRec->Pts && outRec->FirstLeft == OldOutRec) if (outRec->Pts && outRec->FirstLeft == OldOutRec)
{ {
if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts)) if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts))
outRec->FirstLeft = NewOutRec; outRec->FirstLeft = NewOutRec;
...@@ -3623,7 +3623,7 @@ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) ...@@ -3623,7 +3623,7 @@ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec)
{ {
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{ {
OutRec* outRec = m_PolyOuts[i]; OutRec* outRec = m_PolyOuts[i];
...@@ -3634,7 +3634,7 @@ void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) ...@@ -3634,7 +3634,7 @@ void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec)
static OutRec* ParseFirstLeft(OutRec* FirstLeft) static OutRec* ParseFirstLeft(OutRec* FirstLeft)
{ {
while (FirstLeft && !FirstLeft->Pts) while (FirstLeft && !FirstLeft->Pts)
FirstLeft = FirstLeft->FirstLeft; FirstLeft = FirstLeft->FirstLeft;
return FirstLeft; return FirstLeft;
} }
...@@ -3696,7 +3696,7 @@ void Clipper::JoinCommonEdges() ...@@ -3696,7 +3696,7 @@ void Clipper::JoinCommonEdges()
if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0)) if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0))
ReversePolyPtLinks(outRec2->Pts); ReversePolyPtLinks(outRec2->Pts);
} else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts)) } else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts))
{ {
//outRec1 is contained by outRec2 ... //outRec1 is contained by outRec2 ...
...@@ -3710,7 +3710,7 @@ void Clipper::JoinCommonEdges() ...@@ -3710,7 +3710,7 @@ void Clipper::JoinCommonEdges()
if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0)) if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0))
ReversePolyPtLinks(outRec1->Pts); ReversePolyPtLinks(outRec1->Pts);
} }
else else
{ {
//the 2 polygons are completely separate ... //the 2 polygons are completely separate ...
...@@ -3720,7 +3720,7 @@ void Clipper::JoinCommonEdges() ...@@ -3720,7 +3720,7 @@ void Clipper::JoinCommonEdges()
//fixup FirstLeft pointers that may need reassigning to OutRec2 //fixup FirstLeft pointers that may need reassigning to OutRec2
if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2); if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2);
} }
} else } else
{ {
//joined 2 polygons together ... //joined 2 polygons together ...
...@@ -3730,7 +3730,7 @@ void Clipper::JoinCommonEdges() ...@@ -3730,7 +3730,7 @@ void Clipper::JoinCommonEdges()
outRec2->Idx = outRec1->Idx; outRec2->Idx = outRec1->Idx;
outRec1->IsHole = holeStateRec->IsHole; outRec1->IsHole = holeStateRec->IsHole;
if (holeStateRec == outRec2) if (holeStateRec == outRec2)
outRec1->FirstLeft = outRec2->FirstLeft; outRec1->FirstLeft = outRec2->FirstLeft;
outRec2->FirstLeft = outRec1; outRec2->FirstLeft = outRec1;
...@@ -3746,7 +3746,7 @@ void Clipper::JoinCommonEdges() ...@@ -3746,7 +3746,7 @@ void Clipper::JoinCommonEdges()
DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2) DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2)
{ {
if(pt2.X == pt1.X && pt2.Y == pt1.Y) if(pt2.X == pt1.X && pt2.Y == pt1.Y)
return DoublePoint(0, 0); return DoublePoint(0, 0);
double Dx = (double)(pt2.X - pt1.X); double Dx = (double)(pt2.X - pt1.X);
...@@ -3807,7 +3807,7 @@ void ClipperOffset::AddPath(const Path& path, JoinType joinType, EndType endType ...@@ -3807,7 +3807,7 @@ void ClipperOffset::AddPath(const Path& path, JoinType joinType, EndType endType
(path[i].Y == newNode->Contour[k].Y && (path[i].Y == newNode->Contour[k].Y &&
path[i].X < newNode->Contour[k].X)) k = j; path[i].X < newNode->Contour[k].X)) k = j;
} }
if ((endType == etClosedPolygon && j < 2) || if ((endType == etClosedPolygon && j < 2) ||
(endType != etClosedPolygon && j < 0)) (endType != etClosedPolygon && j < 0))
{ {
delete newNode; delete newNode;
...@@ -3841,7 +3841,7 @@ void ClipperOffset::FixOrientations() ...@@ -3841,7 +3841,7 @@ void ClipperOffset::FixOrientations()
{ {
//fixup orientations of all closed paths if the orientation of the //fixup orientations of all closed paths if the orientation of the
//closed path with the lowermost vertex is wrong ... //closed path with the lowermost vertex is wrong ...
if (m_lowest.X >= 0 && if (m_lowest.X >= 0 &&
!Orientation(m_polyNodes.Childs[(int)m_lowest.X]->Contour)) !Orientation(m_polyNodes.Childs[(int)m_lowest.X]->Contour))
{ {
for (int i = 0; i < m_polyNodes.ChildCount(); ++i) for (int i = 0; i < m_polyNodes.ChildCount(); ++i)
...@@ -3868,7 +3868,7 @@ void ClipperOffset::Execute(Paths& solution, double delta) ...@@ -3868,7 +3868,7 @@ void ClipperOffset::Execute(Paths& solution, double delta)
solution.clear(); solution.clear();
FixOrientations(); FixOrientations();
DoOffset(delta); DoOffset(delta);
//now clean up 'corners' ... //now clean up 'corners' ...
Clipper clpr; Clipper clpr;
clpr.AddPaths(m_destPolys, ptSubject, true); clpr.AddPaths(m_destPolys, ptSubject, true);
...@@ -3939,7 +3939,7 @@ void ClipperOffset::DoOffset(double delta) ...@@ -3939,7 +3939,7 @@ void ClipperOffset::DoOffset(double delta)
m_delta = delta; m_delta = delta;
//if Zero offset, just copy any CLOSED polygons to m_p and return ... //if Zero offset, just copy any CLOSED polygons to m_p and return ...
if (NEAR_ZERO(delta)) if (NEAR_ZERO(delta))
{ {
m_destPolys.reserve(m_polyNodes.ChildCount()); m_destPolys.reserve(m_polyNodes.ChildCount());
for (int i = 0; i < m_polyNodes.ChildCount(); i++) for (int i = 0; i < m_polyNodes.ChildCount(); i++)
...@@ -3957,12 +3957,12 @@ void ClipperOffset::DoOffset(double delta) ...@@ -3957,12 +3957,12 @@ void ClipperOffset::DoOffset(double delta)
double y; double y;
if (ArcTolerance <= 0.0) y = def_arc_tolerance; if (ArcTolerance <= 0.0) y = def_arc_tolerance;
else if (ArcTolerance > std::fabs(delta) * def_arc_tolerance) else if (ArcTolerance > std::fabs(delta) * def_arc_tolerance)
y = std::fabs(delta) * def_arc_tolerance; y = std::fabs(delta) * def_arc_tolerance;
else y = ArcTolerance; else y = ArcTolerance;
//see offset_triginometry2.svg in the documentation folder ... //see offset_triginometry2.svg in the documentation folder ...
double steps = pi / std::acos(1 - y / std::fabs(delta)); double steps = pi / std::acos(1 - y / std::fabs(delta));
if (steps > std::fabs(delta) * pi) if (steps > std::fabs(delta) * pi)
steps = std::fabs(delta) * pi; //ie excessive precision check steps = std::fabs(delta) * pi; //ie excessive precision check
m_sin = std::sin(two_pi / steps); m_sin = std::sin(two_pi / steps);
m_cos = std::cos(two_pi / steps); m_cos = std::cos(two_pi / steps);
...@@ -4187,7 +4187,7 @@ void ClipperOffset::DoRound(int j, int k) ...@@ -4187,7 +4187,7 @@ void ClipperOffset::DoRound(int j, int k)
void Clipper::DoSimplePolygons() void Clipper::DoSimplePolygons()
{ {
PolyOutList::size_type i = 0; PolyOutList::size_type i = 0;
while (i < m_PolyOuts.size()) while (i < m_PolyOuts.size())
{ {
OutRec* outrec = m_PolyOuts[i++]; OutRec* outrec = m_PolyOuts[i++];
OutPt* op = outrec->Pts; OutPt* op = outrec->Pts;
...@@ -4195,9 +4195,9 @@ void Clipper::DoSimplePolygons() ...@@ -4195,9 +4195,9 @@ void Clipper::DoSimplePolygons()
do //for each Pt in Polygon until duplicate found do ... do //for each Pt in Polygon until duplicate found do ...
{ {
OutPt* op2 = op->Next; OutPt* op2 = op->Next;
while (op2 != outrec->Pts) while (op2 != outrec->Pts)
{ {
if ((op->Pt == op2->Pt) && op2->Next != op && op2->Prev != op) if ((op->Pt == op2->Pt) && op2->Next != op && op2->Prev != op)
{ {
//split the polygon into two ... //split the polygon into two ...
OutPt* op3 = op->Prev; OutPt* op3 = op->Prev;
...@@ -4255,6 +4255,15 @@ void ReversePaths(Paths& p) ...@@ -4255,6 +4255,15 @@ void ReversePaths(Paths& p)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType)
{
Clipper c;
c.StrictlySimple(true);
c.AddPath(in_poly, ptSubject, true);
c.Execute(ctUnion, out_polys, fillType, fillType);
}
//------------------------------------------------------------------------------
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType) void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType)
{ {
Clipper c; Clipper c;
...@@ -4295,7 +4304,7 @@ double DistanceFromLineSqrd( ...@@ -4295,7 +4304,7 @@ double DistanceFromLineSqrd(
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool SlopesNearCollinear(const IntPoint& pt1, bool SlopesNearCollinear(const IntPoint& pt1,
const IntPoint& pt2, const IntPoint& pt3, double distSqrd) const IntPoint& pt2, const IntPoint& pt3, double distSqrd)
{ {
return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd; return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd;
...@@ -4324,10 +4333,10 @@ void CleanPolygon(const Path& in_poly, Path& out_poly, double distance) ...@@ -4324,10 +4333,10 @@ void CleanPolygon(const Path& in_poly, Path& out_poly, double distance)
{ {
//distance = proximity in units/pixels below which vertices //distance = proximity in units/pixels below which vertices
//will be stripped. Default ~= sqrt(2). //will be stripped. Default ~= sqrt(2).
size_t size = in_poly.size(); size_t size = in_poly.size();
if (size == 0) if (size == 0)
{ {
out_poly.clear(); out_poly.clear();
return; return;
...@@ -4344,13 +4353,13 @@ void CleanPolygon(const Path& in_poly, Path& out_poly, double distance) ...@@ -4344,13 +4353,13 @@ void CleanPolygon(const Path& in_poly, Path& out_poly, double distance)
double distSqrd = distance * distance; double distSqrd = distance * distance;
OutPt* op = &outPts[0]; OutPt* op = &outPts[0];
while (op->Idx == 0 && op->Next != op->Prev) while (op->Idx == 0 && op->Next != op->Prev)
{ {
if (PointsAreClose(op->Pt, op->Prev->Pt, distSqrd)) if (PointsAreClose(op->Pt, op->Prev->Pt, distSqrd))
{ {
op = ExcludeOp(op); op = ExcludeOp(op);
size--; size--;
} }
else if (PointsAreClose(op->Prev->Pt, op->Next->Pt, distSqrd)) else if (PointsAreClose(op->Prev->Pt, op->Next->Pt, distSqrd))
{ {
ExcludeOp(op->Next); ExcludeOp(op->Next);
...@@ -4399,7 +4408,7 @@ void CleanPolygons(Paths& polys, double distance) ...@@ -4399,7 +4408,7 @@ void CleanPolygons(Paths& polys, double distance)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Minkowski(const Path& poly, const Path& path, void Minkowski(const Path& poly, const Path& path,
Paths& solution, bool isSum, bool isClosed) Paths& solution, bool isSum, bool isClosed)
{ {
int delta = (isClosed ? 1 : 0); int delta = (isClosed ? 1 : 0);
...@@ -4426,7 +4435,7 @@ void Minkowski(const Path& poly, const Path& path, ...@@ -4426,7 +4435,7 @@ void Minkowski(const Path& poly, const Path& path,
pp.push_back(p); pp.push_back(p);
} }
Paths quads; Paths quads;
quads.reserve((pathCnt + delta) * (polyCnt + 1)); quads.reserve((pathCnt + delta) * (polyCnt + 1));
for (size_t i = 0; i <= pathCnt - 2 + delta; ++i) for (size_t i = 0; i <= pathCnt - 2 + delta; ++i)
for (size_t j = 0; j <= polyCnt - 1; ++j) for (size_t j = 0; j <= polyCnt - 1; ++j)
...@@ -4476,7 +4485,7 @@ void AddPolyNodeToPolygons(const PolyNode& polynode, NodeType nodetype, Paths& p ...@@ -4476,7 +4485,7 @@ void AddPolyNodeToPolygons(const PolyNode& polynode, NodeType nodetype, Paths& p
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths) void PolyTreeToPaths(const PolyTree& polytree, Paths& paths)
{ {
paths.resize(0); paths.resize(0);
paths.reserve(polytree.Total()); paths.reserve(polytree.Total());
AddPolyNodeToPolygons(polytree, ntAny, paths); AddPolyNodeToPolygons(polytree, ntAny, paths);
} }
...@@ -4484,7 +4493,7 @@ void PolyTreeToPaths(const PolyTree& polytree, Paths& paths) ...@@ -4484,7 +4493,7 @@ void PolyTreeToPaths(const PolyTree& polytree, Paths& paths)
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths) void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths)
{ {
paths.resize(0); paths.resize(0);
paths.reserve(polytree.Total()); paths.reserve(polytree.Total());
AddPolyNodeToPolygons(polytree, ntClosed, paths); AddPolyNodeToPolygons(polytree, ntClosed, paths);
} }
...@@ -4492,7 +4501,7 @@ void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths) ...@@ -4492,7 +4501,7 @@ void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths)
void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths) void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths)
{ {
paths.resize(0); paths.resize(0);
paths.reserve(polytree.Total()); paths.reserve(polytree.Total());
//Open paths are top level only, so ... //Open paths are top level only, so ...
for (int i = 0; i < polytree.ChildCount(); ++i) for (int i = 0; i < polytree.ChildCount(); ++i)
...@@ -4534,7 +4543,7 @@ void OffsetPaths(const Paths &in_polys, Paths &out_polys, ...@@ -4534,7 +4543,7 @@ void OffsetPaths(const Paths &in_polys, Paths &out_polys,
double delta, JoinType jointype, EndType_ endtype, double limit) double delta, JoinType jointype, EndType_ endtype, double limit)
{ {
ClipperOffset co(limit, limit); ClipperOffset co(limit, limit);
co.AddPaths(in_polys, jointype, (EndType)endtype); co.AddPaths(in_polys, jointype, (EndType)endtype);
co.Execute(out_polys, delta); co.Execute(out_polys, delta);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment