mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 21:55:59 +08:00
Update to 6.3.0.
This commit is contained in:
parent
1872b4f404
commit
a47101764b
@ -1,8 +1,8 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* *
|
* *
|
||||||
* Author : Angus Johnson *
|
* Author : Angus Johnson *
|
||||||
* Version : 6.2.9 *
|
* Version : 6.3.0 *
|
||||||
* Date : 16 February 2015 *
|
* Date : 19 April 2015 *
|
||||||
* Website : http://www.angusj.com *
|
* Website : http://www.angusj.com *
|
||||||
* Copyright : Angus Johnson 2010-2015 *
|
* Copyright : Angus Johnson 2010-2015 *
|
||||||
* *
|
* *
|
||||||
@ -325,7 +325,7 @@ inline bool SlopesEqual(const cInt dx1, const cInt dy1, const cInt dx2, const cI
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
|
inline bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
|
||||||
{ return SlopesEqual(e1.Delta.x(), e1.Delta.y(), e2.Delta.x(), e2.Delta.y(), UseFullInt64Range); }
|
{ return SlopesEqual(e1.Top.x() - e1.Bot.x(), e1.Top.y() - e1.Bot.y(), e2.Top.x() - e2.Bot.x(), e2.Top.y() - e2.Bot.y(), UseFullInt64Range); }
|
||||||
inline bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, bool UseFullInt64Range)
|
inline bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, bool UseFullInt64Range)
|
||||||
{ return SlopesEqual(pt1.x()-pt2.x(), pt1.y()-pt2.y(), pt2.x()-pt3.x(), pt2.y()-pt3.y(), UseFullInt64Range); }
|
{ return SlopesEqual(pt1.x()-pt2.x(), pt1.y()-pt2.y(), pt2.x()-pt3.x(), pt2.y()-pt3.y(), UseFullInt64Range); }
|
||||||
inline bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, const IntPoint &pt4, bool UseFullInt64Range)
|
inline bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, const IntPoint &pt4, bool UseFullInt64Range)
|
||||||
@ -335,7 +335,7 @@ inline bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2, const IntPoint
|
|||||||
|
|
||||||
inline bool IsHorizontal(TEdge &e)
|
inline bool IsHorizontal(TEdge &e)
|
||||||
{
|
{
|
||||||
return e.Delta.y() == 0;
|
return e.Dx == HORIZONTAL;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -368,7 +368,7 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t y;
|
int64_t y;
|
||||||
if (Edge1.Delta.x() == 0)
|
if (Edge1.Dx == 0)
|
||||||
{
|
{
|
||||||
ip.x() = Edge1.Bot.x();
|
ip.x() = Edge1.Bot.x();
|
||||||
y = IsHorizontal(Edge2) ?
|
y = IsHorizontal(Edge2) ?
|
||||||
@ -376,7 +376,7 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
|
|||||||
Round<int64_t>(ip.x() / Edge2.Dx + Edge2.Bot.y() - (Edge2.Bot.x() / Edge2.Dx));
|
Round<int64_t>(ip.x() / Edge2.Dx + Edge2.Bot.y() - (Edge2.Bot.x() / Edge2.Dx));
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (Edge2.Delta.x() == 0)
|
else if (Edge2.Dx == 0)
|
||||||
{
|
{
|
||||||
ip.x() = Edge2.Bot.x();
|
ip.x() = Edge2.Bot.x();
|
||||||
y = IsHorizontal(Edge1) ?
|
y = IsHorizontal(Edge1) ?
|
||||||
@ -448,11 +448,9 @@ void InitEdge2(TEdge& e, PolyType Pt)
|
|||||||
e.Bot = e.Next->Curr;
|
e.Bot = e.Next->Curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.Delta.x() = (e.Top.x() - e.Bot.x());
|
cInt dy = (e.Top.y() - e.Bot.y());
|
||||||
e.Delta.y() = (e.Top.y() - e.Bot.y());
|
if (dy == 0) e.Dx = HORIZONTAL;
|
||||||
|
else e.Dx = (double)(e.Top.x() - e.Bot.x()) / dy;
|
||||||
if (e.Delta.y() == 0) e.Dx = HORIZONTAL;
|
|
||||||
else e.Dx = (double)(e.Delta.x()) / e.Delta.y();
|
|
||||||
|
|
||||||
e.PolyTyp = Pt;
|
e.PolyTyp = Pt;
|
||||||
}
|
}
|
||||||
@ -934,8 +932,6 @@ bool ClipperBase::AddPathInternal(const Path &pg, int highI, PolyType PolyTyp, b
|
|||||||
locMin.RightBound = E->Prev;
|
locMin.RightBound = E->Prev;
|
||||||
leftBoundIsForward = true; //Q.nextInLML = Q.next
|
leftBoundIsForward = true; //Q.nextInLML = Q.next
|
||||||
}
|
}
|
||||||
locMin.LeftBound->Side = esLeft;
|
|
||||||
locMin.RightBound->Side = esRight;
|
|
||||||
|
|
||||||
if (!Closed) locMin.LeftBound->WindDelta = 0;
|
if (!Closed) locMin.LeftBound->WindDelta = 0;
|
||||||
else if (locMin.LeftBound->Next == locMin.RightBound)
|
else if (locMin.LeftBound->Next == locMin.RightBound)
|
||||||
@ -1204,7 +1200,13 @@ void Clipper::SetWindingCount(TEdge &edge) const
|
|||||||
while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL;
|
while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL;
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta);
|
if (edge.WindDelta == 0)
|
||||||
|
{
|
||||||
|
PolyFillType pft = (edge.PolyTyp == ptSubject ? m_SubjFillType : m_ClipFillType);
|
||||||
|
edge.WindCnt = (pft == pftNegative ? -1 : 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
edge.WindCnt = 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
|
||||||
}
|
}
|
||||||
@ -1421,14 +1423,17 @@ OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
|
|||||||
prevE = e->PrevInAEL;
|
prevE = e->PrevInAEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevE && prevE->OutIdx >= 0 &&
|
if (prevE && prevE->OutIdx >= 0)
|
||||||
(TopX(*prevE, Pt.y()) == TopX(*e, Pt.y())) &&
|
{
|
||||||
SlopesEqual(*e, *prevE, m_UseFullRange) &&
|
cInt xPrev = TopX(*prevE, Pt.y());
|
||||||
(e->WindDelta != 0) && (prevE->WindDelta != 0))
|
cInt xE = TopX(*e, Pt.y());
|
||||||
|
if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) &&
|
||||||
|
SlopesEqual(IntPoint2d(xPrev, Pt.y()), prevE->Top, IntPoint2d(xE, Pt.y()), e->Top, m_UseFullRange))
|
||||||
{
|
{
|
||||||
OutPt* outPt = AddOutPt(prevE, Pt);
|
OutPt* outPt = AddOutPt(prevE, Pt);
|
||||||
m_Joins.emplace_back(Join(result, outPt, e->Top));
|
m_Joins.emplace_back(Join(result, outPt, e->Top));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -1543,7 +1548,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->Bot, lb->PrevInAEL->Top, lb->Curr, lb->Top, m_UseFullRange) &&
|
||||||
(lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0))
|
(lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0))
|
||||||
{
|
{
|
||||||
OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot);
|
OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot);
|
||||||
@ -1554,7 +1559,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 &&
|
if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 &&
|
||||||
SlopesEqual(*rb->PrevInAEL, *rb, m_UseFullRange) &&
|
SlopesEqual(rb->PrevInAEL->Curr, rb->PrevInAEL->Top, rb->Curr, rb->Top, m_UseFullRange) &&
|
||||||
(rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0))
|
(rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0))
|
||||||
{
|
{
|
||||||
OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot);
|
OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot);
|
||||||
@ -1814,19 +1819,27 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
|
|||||||
|
|
||||||
void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
|
void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
|
||||||
{
|
{
|
||||||
bool IsHole = false;
|
|
||||||
TEdge *e2 = e->PrevInAEL;
|
TEdge *e2 = e->PrevInAEL;
|
||||||
|
TEdge *eTmp = 0;
|
||||||
while (e2)
|
while (e2)
|
||||||
{
|
{
|
||||||
if (e2->OutIdx >= 0 && e2->WindDelta != 0)
|
if (e2->OutIdx >= 0 && e2->WindDelta != 0)
|
||||||
{
|
{
|
||||||
IsHole = !IsHole;
|
if (!eTmp) eTmp = e2;
|
||||||
if (! outrec->FirstLeft)
|
else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0;
|
||||||
outrec->FirstLeft = &m_PolyOuts[e2->OutIdx];
|
|
||||||
}
|
}
|
||||||
e2 = e2->PrevInAEL;
|
e2 = e2->PrevInAEL;
|
||||||
}
|
}
|
||||||
if (IsHole) outrec->IsHole = true;
|
if (!eTmp)
|
||||||
|
{
|
||||||
|
outrec->FirstLeft = 0;
|
||||||
|
outrec->IsHole = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outrec->FirstLeft = &m_PolyOuts[eTmp->OutIdx];
|
||||||
|
outrec->IsHole = !outrec->FirstLeft->IsHole;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -1850,7 +1863,7 @@ OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
|
|||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool Param1RightOfParam2(OutRec* outRec1, OutRec* outRec2)
|
bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -1877,9 +1890,9 @@ 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 (OutRec1RightOfOutRec2(outRec1, outRec2))
|
||||||
holeStateRec = outRec2;
|
holeStateRec = outRec2;
|
||||||
else if (Param1RightOfParam2(outRec2, outRec1))
|
else if (OutRec1RightOfOutRec2(outRec2, outRec1))
|
||||||
holeStateRec = outRec1;
|
holeStateRec = outRec1;
|
||||||
else
|
else
|
||||||
holeStateRec = GetLowermostRec(outRec1, outRec2);
|
holeStateRec = GetLowermostRec(outRec1, outRec2);
|
||||||
@ -1892,7 +1905,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
|
|||||||
OutPt* p2_lft = outRec2->Pts;
|
OutPt* p2_lft = outRec2->Pts;
|
||||||
OutPt* p2_rt = p2_lft->Prev;
|
OutPt* p2_rt = p2_lft->Prev;
|
||||||
|
|
||||||
EdgeSide Side;
|
|
||||||
//join e2 poly onto e1 poly and delete pointers to e2 ...
|
//join e2 poly onto e1 poly and delete pointers to e2 ...
|
||||||
if( e1->Side == esLeft )
|
if( e1->Side == esLeft )
|
||||||
{
|
{
|
||||||
@ -1914,7 +1926,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
|
|||||||
p1_rt->Next = p2_lft;
|
p1_rt->Next = p2_lft;
|
||||||
outRec1->Pts = p2_lft;
|
outRec1->Pts = p2_lft;
|
||||||
}
|
}
|
||||||
Side = esLeft;
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
if( e2->Side == esRight )
|
if( e2->Side == esRight )
|
||||||
@ -1933,7 +1944,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
|
|||||||
p1_lft->Prev = p2_rt;
|
p1_lft->Prev = p2_rt;
|
||||||
p2_rt->Next = p1_lft;
|
p2_rt->Next = p1_lft;
|
||||||
}
|
}
|
||||||
Side = esRight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
outRec1->BottomPt = 0;
|
outRec1->BottomPt = 0;
|
||||||
@ -1959,7 +1969,7 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
|
|||||||
if( e->OutIdx == ObsoleteIdx )
|
if( e->OutIdx == ObsoleteIdx )
|
||||||
{
|
{
|
||||||
e->OutIdx = OKIdx;
|
e->OutIdx = OKIdx;
|
||||||
e->Side = Side;
|
e->Side = e1->Side;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
e = e->NextInAEL;
|
e = e->NextInAEL;
|
||||||
@ -2059,16 +2069,20 @@ inline bool IsIntermediate(TEdge *e, const cInt Y)
|
|||||||
|
|
||||||
inline TEdge *GetMaximaPair(TEdge *e)
|
inline TEdge *GetMaximaPair(TEdge *e)
|
||||||
{
|
{
|
||||||
TEdge* result = 0;
|
|
||||||
if ((e->Next->Top == e->Top) && !e->Next->NextInLML)
|
if ((e->Next->Top == e->Top) && !e->Next->NextInLML)
|
||||||
result = e->Next;
|
return e->Next;
|
||||||
else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML)
|
else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML)
|
||||||
result = e->Prev;
|
return e->Prev;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline TEdge *GetMaximaPairEx(TEdge *e)
|
||||||
|
{
|
||||||
|
//as GetMaximaPair() but returns 0 if MaxPair isn't in AEL (unless it's horizontal)
|
||||||
|
TEdge* result = GetMaximaPair(e);
|
||||||
if (result && (result->OutIdx == Skip ||
|
if (result && (result->OutIdx == Skip ||
|
||||||
//result is false if both NextInAEL & PrevInAEL are nil & not horizontal ...
|
(result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return 0;
|
||||||
(result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result))))
|
|
||||||
return 0;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -2196,7 +2210,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
|
|||||||
{
|
{
|
||||||
Direction dir;
|
Direction dir;
|
||||||
cInt horzLeft, horzRight;
|
cInt horzLeft, horzRight;
|
||||||
bool IsOpen = (horzEdge->OutIdx >= 0 && m_PolyOuts[horzEdge->OutIdx].IsOpen);
|
bool IsOpen = (horzEdge->WindDelta == 0);
|
||||||
|
|
||||||
GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
|
GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
|
||||||
|
|
||||||
@ -2464,6 +2478,8 @@ void Clipper::BuildIntersectList(const cInt topY)
|
|||||||
if(e->Curr.x() > eNext->Curr.x())
|
if(e->Curr.x() > eNext->Curr.x())
|
||||||
{
|
{
|
||||||
IntersectPoint(*e, *eNext, Pt);
|
IntersectPoint(*e, *eNext, Pt);
|
||||||
|
|
||||||
|
if (Pt.y() < topY) Pt = IntPoint2d(TopX(*e, topY), topY);
|
||||||
m_IntersectList.emplace_back(IntersectNode(e, eNext, Pt));
|
m_IntersectList.emplace_back(IntersectNode(e, eNext, Pt));
|
||||||
SwapPositionsInSEL(e, eNext);
|
SwapPositionsInSEL(e, eNext);
|
||||||
isModified = true;
|
isModified = true;
|
||||||
@ -2513,7 +2529,7 @@ bool Clipper::FixupIntersectionOrder()
|
|||||||
|
|
||||||
void Clipper::DoMaxima(TEdge *e)
|
void Clipper::DoMaxima(TEdge *e)
|
||||||
{
|
{
|
||||||
TEdge* eMaxPair = GetMaximaPair(e);
|
TEdge* eMaxPair = GetMaximaPairEx(e);
|
||||||
if (!eMaxPair)
|
if (!eMaxPair)
|
||||||
{
|
{
|
||||||
if (e->OutIdx >= 0)
|
if (e->OutIdx >= 0)
|
||||||
@ -2574,7 +2590,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
|
|||||||
|
|
||||||
if(IsMaximaEdge)
|
if(IsMaximaEdge)
|
||||||
{
|
{
|
||||||
TEdge* eMaxPair = GetMaximaPair(e);
|
TEdge* eMaxPair = GetMaximaPairEx(e);
|
||||||
IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair));
|
IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3172,27 +3188,59 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
|
|||||||
}
|
}
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline OutRec* ParseFirstLeft(OutRec* FirstLeft)
|
||||||
|
{
|
||||||
|
while (FirstLeft && !FirstLeft->Pts)
|
||||||
|
FirstLeft = FirstLeft->FirstLeft;
|
||||||
|
return FirstLeft;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// This is potentially very expensive! O(n^3)!
|
// This is potentially very expensive! O(n^3)!
|
||||||
void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
|
void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
|
||||||
{
|
{
|
||||||
//tests if NewOutRec contains the polygon before reassigning FirstLeft
|
//tests if NewOutRec contains the polygon before reassigning FirstLeft
|
||||||
for (OutRec &outRec : m_PolyOuts)
|
for (OutRec &outRec : m_PolyOuts)
|
||||||
{
|
{
|
||||||
if (!outRec.Pts || !outRec.FirstLeft) continue;
|
OutRec* firstLeft = ParseFirstLeft(outRec.FirstLeft);
|
||||||
OutRec* firstLeft = outRec.FirstLeft;
|
if (outRec.Pts && firstLeft == OldOutRec && Poly2ContainsPoly1(outRec.Pts, NewOutRec->Pts))
|
||||||
// Skip empty polygons.
|
|
||||||
while (firstLeft && !firstLeft->Pts) firstLeft = firstLeft->FirstLeft;
|
|
||||||
if (firstLeft == OldOutRec && Poly2ContainsPoly1(outRec.Pts, NewOutRec->Pts))
|
|
||||||
outRec.FirstLeft = NewOutRec;
|
outRec.FirstLeft = NewOutRec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec)
|
void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec)
|
||||||
|
{
|
||||||
|
//A polygon has split into two such that one is now the inner of the other.
|
||||||
|
//It's possible that these polygons now wrap around other polygons, so check
|
||||||
|
//every polygon that's also contained by OuterOutRec's FirstLeft container
|
||||||
|
//(including 0) to see if they've become inner to the new inner polygon ...
|
||||||
|
OutRec* orfl = OuterOutRec->FirstLeft;
|
||||||
|
for (OutRec &outRec : m_PolyOuts)
|
||||||
|
{
|
||||||
|
if (!outRec.Pts || &outRec == OuterOutRec || &outRec == InnerOutRec)
|
||||||
|
continue;
|
||||||
|
OutRec* firstLeft = ParseFirstLeft(outRec.FirstLeft);
|
||||||
|
if (firstLeft != orfl && firstLeft != InnerOutRec && firstLeft != OuterOutRec)
|
||||||
|
continue;
|
||||||
|
if (Poly2ContainsPoly1(outRec.Pts, InnerOutRec->Pts))
|
||||||
|
outRec.FirstLeft = InnerOutRec;
|
||||||
|
else if (Poly2ContainsPoly1(outRec.Pts, OuterOutRec->Pts))
|
||||||
|
outRec.FirstLeft = OuterOutRec;
|
||||||
|
else if (outRec.FirstLeft == InnerOutRec || outRec.FirstLeft == OuterOutRec)
|
||||||
|
outRec.FirstLeft = orfl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void Clipper::FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec)
|
||||||
{
|
{
|
||||||
//reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon
|
//reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon
|
||||||
for (OutRec &outRec : m_PolyOuts)
|
for (OutRec &outRec : m_PolyOuts)
|
||||||
if (outRec.FirstLeft == OldOutRec) outRec.FirstLeft = NewOutRec;
|
{
|
||||||
|
OutRec* firstLeft = ParseFirstLeft(outRec.FirstLeft);
|
||||||
|
if (outRec.Pts && outRec.FirstLeft == OldOutRec)
|
||||||
|
outRec.FirstLeft = NewOutRec;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
@ -3210,8 +3258,8 @@ void Clipper::JoinCommonEdges()
|
|||||||
//before calling JoinPoints() ...
|
//before calling JoinPoints() ...
|
||||||
OutRec *holeStateRec;
|
OutRec *holeStateRec;
|
||||||
if (outRec1 == outRec2) holeStateRec = outRec1;
|
if (outRec1 == outRec2) holeStateRec = outRec1;
|
||||||
else if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2;
|
else if (OutRec1RightOfOutRec2(outRec1, outRec2)) holeStateRec = outRec2;
|
||||||
else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1;
|
else if (OutRec1RightOfOutRec2(outRec2, outRec1)) holeStateRec = outRec1;
|
||||||
else holeStateRec = GetLowermostRec(outRec1, outRec2);
|
else holeStateRec = GetLowermostRec(outRec1, outRec2);
|
||||||
|
|
||||||
if (!JoinPoints(&join, outRec1, outRec2)) continue;
|
if (!JoinPoints(&join, outRec1, outRec2)) continue;
|
||||||
@ -3228,23 +3276,9 @@ void Clipper::JoinCommonEdges()
|
|||||||
//update all OutRec2.Pts Idx's ...
|
//update all OutRec2.Pts Idx's ...
|
||||||
UpdateOutPtIdxs(*outRec2);
|
UpdateOutPtIdxs(*outRec2);
|
||||||
|
|
||||||
//We now need to check every OutRec.FirstLeft pointer. If it points
|
|
||||||
//to OutRec1 it may need to point to OutRec2 instead ...
|
|
||||||
if (m_UsingPolyTree)
|
|
||||||
for (size_t j = 0; j < m_PolyOuts.size() - 1; j++)
|
|
||||||
{
|
|
||||||
OutRec &oRec = m_PolyOuts[j];
|
|
||||||
OutRec* firstLeft = oRec.FirstLeft;
|
|
||||||
while (firstLeft && !firstLeft->Pts) firstLeft = firstLeft->FirstLeft;
|
|
||||||
if (!oRec.Pts || firstLeft != outRec1 ||
|
|
||||||
oRec.IsHole == outRec1->IsHole) continue;
|
|
||||||
if (Poly2ContainsPoly1(oRec.Pts, join.OutPt2))
|
|
||||||
oRec.FirstLeft = outRec2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts))
|
if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts))
|
||||||
{
|
{
|
||||||
//outRec2 is contained by outRec1 ...
|
//outRec1 contains outRec2 ...
|
||||||
outRec2->IsHole = !outRec1->IsHole;
|
outRec2->IsHole = !outRec1->IsHole;
|
||||||
outRec2->FirstLeft = outRec1;
|
outRec2->FirstLeft = outRec1;
|
||||||
|
|
||||||
@ -3256,7 +3290,7 @@ void Clipper::JoinCommonEdges()
|
|||||||
|
|
||||||
} else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts))
|
} else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts))
|
||||||
{
|
{
|
||||||
//outRec1 is contained by outRec2 ...
|
//outRec2 contains outRec1 ...
|
||||||
outRec2->IsHole = outRec1->IsHole;
|
outRec2->IsHole = outRec1->IsHole;
|
||||||
outRec1->IsHole = !outRec2->IsHole;
|
outRec1->IsHole = !outRec2->IsHole;
|
||||||
outRec2->FirstLeft = outRec1->FirstLeft;
|
outRec2->FirstLeft = outRec1->FirstLeft;
|
||||||
@ -3294,7 +3328,7 @@ void Clipper::JoinCommonEdges()
|
|||||||
outRec2->FirstLeft = outRec1;
|
outRec2->FirstLeft = outRec1;
|
||||||
|
|
||||||
// For each m_PolyOuts, replace FirstLeft from outRec2 to outRec1.
|
// For each m_PolyOuts, replace FirstLeft from outRec2 to outRec1.
|
||||||
if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1);
|
if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* *
|
* *
|
||||||
* Author : Angus Johnson *
|
* Author : Angus Johnson *
|
||||||
* Version : 6.2.9 *
|
* Version : 6.3.0 *
|
||||||
* Date : 16 February 2015 *
|
* Date : 19 April 2015 *
|
||||||
* Website : http://www.angusj.com *
|
* Website : http://www.angusj.com *
|
||||||
* Copyright : Angus Johnson 2010-2015 *
|
* Copyright : Angus Johnson 2010-2015 *
|
||||||
* *
|
* *
|
||||||
@ -234,8 +234,6 @@ enum EdgeSide { esLeft = 1, esRight = 2};
|
|||||||
IntPoint Curr;
|
IntPoint Curr;
|
||||||
// Top point of this edge (with maximum Y).
|
// Top point of this edge (with maximum Y).
|
||||||
IntPoint Top;
|
IntPoint Top;
|
||||||
// Vector from Bot to Top.
|
|
||||||
IntPoint Delta;
|
|
||||||
// Slope (dx/dy). For horiontal edges, the slope is set to HORIZONTAL (-1.0E+40).
|
// Slope (dx/dy). For horiontal edges, the slope is set to HORIZONTAL (-1.0E+40).
|
||||||
double Dx;
|
double Dx;
|
||||||
PolyType PolyTyp;
|
PolyType PolyTyp;
|
||||||
@ -529,7 +527,8 @@ private:
|
|||||||
void JoinCommonEdges();
|
void JoinCommonEdges();
|
||||||
void DoSimplePolygons();
|
void DoSimplePolygons();
|
||||||
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
|
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
|
||||||
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec);
|
void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
|
||||||
|
void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
|
||||||
#ifdef CLIPPERLIB_USE_XYZ
|
#ifdef CLIPPERLIB_USE_XYZ
|
||||||
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
|
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user