[mapnik-vector-tile] 04/06: Update clipper to r496-mapnik.
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Sat Oct 3 10:01:08 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository mapnik-vector-tile.
commit 717dd91e229664a3fccdc4bb447b0a244205255e
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sat Oct 3 11:00:26 2015 +0200
Update clipper to r496-mapnik.
---
debian/changelog | 1 +
debian/clipper.cpp | 563 +++++++++++++++++++++++++++++------------------------
debian/clipper.hpp | 46 ++---
3 files changed, 331 insertions(+), 279 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index c354974..2da5401 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
mapnik-vector-tile (0.11.0+dfsg-1) UNRELEASED; urgency=medium
* New upstream release.
+ * Update clipper to r496-mapnik.
-- Bas Couwenberg <sebastic at debian.org> Sat, 03 Oct 2015 10:58:35 +0200
diff --git a/debian/clipper.cpp b/debian/clipper.cpp
index da47cb6..8658562 100644
--- a/debian/clipper.cpp
+++ b/debian/clipper.cpp
@@ -1,8 +1,8 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
-* Version : 6.2.9 *
-* Date : 16 February 2015 *
+* Version : 6.4.0 *
+* Date : 2 July 2015 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2015 *
* *
@@ -66,12 +66,11 @@ static int const Skip = -2; //edge that would otherwise close a path
struct TEdge {
IntPoint Bot;
- IntPoint Curr;
+ IntPoint Curr; //current (updated for every new scanbeam)
IntPoint Top;
- IntPoint Delta;
double Dx;
PolyType PolyTyp;
- EdgeSide Side;
+ EdgeSide Side; //side only refers to current side of solution poly
int WindDelta; //1 or -1 depending on winding direction
int WindCnt;
int WindCnt2; //winding count of the opposite polytype
@@ -99,6 +98,8 @@ struct LocalMinimum {
struct OutPt;
+//OutRec: contains a path in the clipping solution. Edges in the AEL will
+//carry a pointer to an OutRec when they are part of the clipping solution.
struct OutRec {
int Idx;
bool IsHole;
@@ -403,19 +404,25 @@ double Area(const Path &poly)
}
//------------------------------------------------------------------------------
-double Area(const OutRec &outRec)
+double Area(const OutPt *op)
{
- OutPt *op = outRec.Pts;
+ const OutPt *startOp = op;
if (!op) return 0;
double a = 0;
do {
a += (double)(op->Prev->Pt.x + op->Pt.x) * (double)(op->Prev->Pt.y - op->Pt.y);
op = op->Next;
- } while (op != outRec.Pts);
+ } while (op != startOp);
return a * 0.5;
}
//------------------------------------------------------------------------------
+double Area(const OutRec &outRec)
+{
+ return Area(outRec.Pts);
+}
+//------------------------------------------------------------------------------
+
bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
{
OutPt *pp2 = pp;
@@ -536,10 +543,12 @@ bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
{
#ifndef use_int32
if (UseFullInt64Range)
- return Int128Mul(e1.Delta.y, e2.Delta.x) == Int128Mul(e1.Delta.x, e2.Delta.y);
+ return Int128Mul(e1.Top.y - e1.Bot.y, e2.Top.x - e2.Bot.x) ==
+ Int128Mul(e1.Top.x - e1.Bot.x, e2.Top.y - e2.Bot.y);
else
#endif
- return e1.Delta.y * e2.Delta.x == e1.Delta.x * e2.Delta.y;
+ return (e1.Top.y - e1.Bot.y) * (e2.Top.x - e2.Bot.x) ==
+ (e1.Top.x - e1.Bot.x) * (e2.Top.y - e2.Bot.y);
}
//------------------------------------------------------------------------------
@@ -569,7 +578,7 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
inline bool IsHorizontal(TEdge &e)
{
- return e.Delta.y == 0;
+ return e.Dx == HORIZONTAL;
}
//------------------------------------------------------------------------------
@@ -582,11 +591,9 @@ inline double GetDx(const IntPoint pt1, const IntPoint pt2)
inline void SetDx(TEdge &e)
{
- e.Delta.x = (e.Top.x - e.Bot.x);
- e.Delta.y = (e.Top.y - e.Bot.y);
-
- if (e.Delta.y == 0) e.Dx = HORIZONTAL;
- else e.Dx = (double)(e.Delta.x) / e.Delta.y;
+ cInt dy = (e.Top.y - e.Bot.y);
+ if (dy == 0) e.Dx = HORIZONTAL;
+ else e.Dx = (double)(e.Top.x - e.Bot.x) / dy;
}
//---------------------------------------------------------------------------
@@ -626,7 +633,7 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
ip.x = TopX(Edge1, ip.y);
return;
}
- else if (Edge1.Delta.x == 0)
+ else if (Edge1.Dx == 0)
{
ip.x = Edge1.Bot.x;
if (IsHorizontal(Edge2))
@@ -637,7 +644,7 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
ip.y = Round(ip.x / Edge2.Dx + b2);
}
}
- else if (Edge2.Delta.x == 0)
+ else if (Edge2.Dx == 0)
{
ip.x = Edge2.Bot.x;
if (IsHorizontal(Edge1))
@@ -804,7 +811,12 @@ bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
p = btmPt2->Next;
while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next;
double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt));
- return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
+
+ if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) &&
+ std::min(dx1p, dx1n) == std::min(dx2p, dx2n))
+ return Area(btmPt1) > 0; //if otherwise identical use orientation
+ else
+ return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
}
//------------------------------------------------------------------------------
@@ -1191,8 +1203,6 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
locMin.RightBound = E->Prev;
leftBoundIsForward = true; //Q.nextInLML = Q.next
}
- locMin.LeftBound->Side = esLeft;
- locMin.RightBound->Side = esRight;
if (!Closed) locMin.LeftBound->WindDelta = 0;
else if (locMin.LeftBound->Next == locMin.RightBound)
@@ -1231,8 +1241,6 @@ void ClipperBase::Clear()
DisposeLocalMinimaList();
for (EdgeList::size_type i = 0; i < m_edges.size(); ++i)
{
- //for each edge array in turn, find the first used edge and
- //check for and remove any hiddenPts in each edge in the array.
TEdge* edges = m_edges[i];
delete [] edges;
}
@@ -1248,9 +1256,11 @@ void ClipperBase::Reset()
if (m_CurrentLM == m_MinimaList.end()) return; //ie nothing to process
std::stable_sort(m_MinimaList.begin(), m_MinimaList.end(), LocMinSorter());
+ m_Scanbeam = ScanbeamList(); //clears/resets priority_queue
//reset all edges ...
for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm)
{
+ InsertScanbeam(lm->y);
TEdge* e = lm->LeftBound;
if (e)
{
@@ -1267,6 +1277,8 @@ void ClipperBase::Reset()
e->OutIdx = Unassigned;
}
}
+ m_ActiveEdges = 0;
+ m_CurrentLM = m_MinimaList.begin();
}
//------------------------------------------------------------------------------
@@ -1277,10 +1289,12 @@ void ClipperBase::DisposeLocalMinimaList()
}
//------------------------------------------------------------------------------
-void ClipperBase::PopLocalMinima()
+bool ClipperBase::PopLocalMinima(cInt Y, const LocalMinimum *&locMin)
{
- if (m_CurrentLM == m_MinimaList.end()) return;
+ if (m_CurrentLM == m_MinimaList.end() || (*m_CurrentLM).y != Y) return false;
+ locMin = &(*m_CurrentLM);
++m_CurrentLM;
+ return true;
}
//------------------------------------------------------------------------------
@@ -1299,6 +1313,7 @@ IntRect ClipperBase::GetBounds()
result.bottom = lm->LeftBound->Bot.y;
while (lm != m_MinimaList.end())
{
+ //todo - needs fixing for open paths
result.bottom = std::max(result.bottom, lm->LeftBound->Bot.y);
TEdge* e = lm->LeftBound;
for (;;) {
@@ -1321,6 +1336,142 @@ IntRect ClipperBase::GetBounds()
}
return result;
}
+//------------------------------------------------------------------------------
+
+void ClipperBase::InsertScanbeam(const cInt Y)
+{
+ m_Scanbeam.push(Y);
+}
+//------------------------------------------------------------------------------
+
+bool ClipperBase::PopScanbeam(cInt &Y)
+{
+ if (m_Scanbeam.empty()) return false;
+ Y = m_Scanbeam.top();
+ m_Scanbeam.pop();
+ while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
+ return true;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DisposeAllOutRecs(){
+ for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+ DisposeOutRec(i);
+ m_PolyOuts.clear();
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DisposeOutRec(PolyOutList::size_type index)
+{
+ OutRec *outRec = m_PolyOuts[index];
+ if (outRec->Pts) DisposeOutPts(outRec->Pts);
+ delete outRec;
+ m_PolyOuts[index] = 0;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DeleteFromAEL(TEdge *e)
+{
+ TEdge* AelPrev = e->PrevInAEL;
+ TEdge* AelNext = e->NextInAEL;
+ if (!AelPrev && !AelNext && (e != m_ActiveEdges)) return; //already deleted
+ if (AelPrev) AelPrev->NextInAEL = AelNext;
+ else m_ActiveEdges = AelNext;
+ if (AelNext) AelNext->PrevInAEL = AelPrev;
+ e->NextInAEL = 0;
+ e->PrevInAEL = 0;
+}
+//------------------------------------------------------------------------------
+
+OutRec* ClipperBase::CreateOutRec()
+{
+ OutRec* result = new OutRec;
+ result->IsHole = false;
+ result->IsOpen = false;
+ result->FirstLeft = 0;
+ result->Pts = 0;
+ result->BottomPt = 0;
+ result->PolyNd = 0;
+ m_PolyOuts.push_back(result);
+ result->Idx = (int)m_PolyOuts.size() - 1;
+ return result;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
+{
+ //check that one or other edge hasn't already been removed from AEL ...
+ if (Edge1->NextInAEL == Edge1->PrevInAEL ||
+ Edge2->NextInAEL == Edge2->PrevInAEL) return;
+
+ if (Edge1->NextInAEL == Edge2)
+ {
+ TEdge* Next = Edge2->NextInAEL;
+ if (Next) Next->PrevInAEL = Edge1;
+ TEdge* Prev = Edge1->PrevInAEL;
+ if (Prev) Prev->NextInAEL = Edge2;
+ Edge2->PrevInAEL = Prev;
+ Edge2->NextInAEL = Edge1;
+ Edge1->PrevInAEL = Edge2;
+ Edge1->NextInAEL = Next;
+ }
+ else if (Edge2->NextInAEL == Edge1)
+ {
+ TEdge* Next = Edge1->NextInAEL;
+ if (Next) Next->PrevInAEL = Edge2;
+ TEdge* Prev = Edge2->PrevInAEL;
+ if (Prev) Prev->NextInAEL = Edge1;
+ Edge1->PrevInAEL = Prev;
+ Edge1->NextInAEL = Edge2;
+ Edge2->PrevInAEL = Edge1;
+ Edge2->NextInAEL = Next;
+ }
+ else
+ {
+ TEdge* Next = Edge1->NextInAEL;
+ TEdge* Prev = Edge1->PrevInAEL;
+ Edge1->NextInAEL = Edge2->NextInAEL;
+ if (Edge1->NextInAEL) Edge1->NextInAEL->PrevInAEL = Edge1;
+ Edge1->PrevInAEL = Edge2->PrevInAEL;
+ if (Edge1->PrevInAEL) Edge1->PrevInAEL->NextInAEL = Edge1;
+ Edge2->NextInAEL = Next;
+ if (Edge2->NextInAEL) Edge2->NextInAEL->PrevInAEL = Edge2;
+ Edge2->PrevInAEL = Prev;
+ if (Edge2->PrevInAEL) Edge2->PrevInAEL->NextInAEL = Edge2;
+ }
+
+ if (!Edge1->PrevInAEL) m_ActiveEdges = Edge1;
+ else if (!Edge2->PrevInAEL) m_ActiveEdges = Edge2;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
+{
+ if (!e->NextInLML)
+ throw clipperException("UpdateEdgeIntoAEL: invalid call");
+
+ e->NextInLML->OutIdx = e->OutIdx;
+ TEdge* AelPrev = e->PrevInAEL;
+ TEdge* AelNext = e->NextInAEL;
+ if (AelPrev) AelPrev->NextInAEL = e->NextInLML;
+ else m_ActiveEdges = e->NextInLML;
+ if (AelNext) AelNext->PrevInAEL = e->NextInLML;
+ e->NextInLML->Side = e->Side;
+ e->NextInLML->WindDelta = e->WindDelta;
+ e->NextInLML->WindCnt = e->WindCnt;
+ e->NextInLML->WindCnt2 = e->WindCnt2;
+ e = e->NextInLML;
+ e->Curr = e->Bot;
+ e->PrevInAEL = AelPrev;
+ e->NextInAEL = AelNext;
+ if (!IsHorizontal(*e)) InsertScanbeam(e->Top.y);
+}
+//------------------------------------------------------------------------------
+
+bool ClipperBase::LocalMinimaPending()
+{
+ return (m_CurrentLM != m_MinimaList.end());
+}
//------------------------------------------------------------------------------
// TClipper methods ...
@@ -1328,8 +1479,6 @@ IntRect ClipperBase::GetBounds()
Clipper::Clipper(int initOptions) : ClipperBase() //constructor
{
- m_ActiveEdges = 0;
- m_SortedEdges = 0;
m_ExecuteLocked = false;
m_UseFullRange = false;
m_ReverseOutput = ((initOptions & ioReverseSolution) != 0);
@@ -1342,12 +1491,6 @@ Clipper::Clipper(int initOptions) : ClipperBase() //constructor
}
//------------------------------------------------------------------------------
-Clipper::~Clipper() //destructor
-{
- Clear();
-}
-//------------------------------------------------------------------------------
-
#ifdef use_xyz
void Clipper::ZFillFunction(ZFillCallback zFillFunc)
{
@@ -1356,18 +1499,6 @@ void Clipper::ZFillFunction(ZFillCallback zFillFunc)
//------------------------------------------------------------------------------
#endif
-void Clipper::Reset()
-{
- ClipperBase::Reset();
- m_Scanbeam = ScanbeamList();
- m_Maxima = MaximaList();
- m_ActiveEdges = 0;
- m_SortedEdges = 0;
- for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm)
- InsertScanbeam(lm->y);
-}
-//------------------------------------------------------------------------------
-
bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType fillType)
{
return Execute(clipType, solution, fillType, fillType);
@@ -1437,19 +1568,26 @@ bool Clipper::ExecuteInternal()
bool succeeded = true;
try {
Reset();
- if (m_CurrentLM == m_MinimaList.end()) return true;
- cInt botY = PopScanbeam();
- do {
- InsertLocalMinimaIntoAEL(botY);
+ m_Maxima = MaximaList();
+ m_SortedEdges = 0;
+
+ succeeded = true;
+ cInt botY, topY;
+ if (!PopScanbeam(botY)) return false;
+ InsertLocalMinimaIntoAEL(botY);
+ while (PopScanbeam(topY) || LocalMinimaPending())
+ {
ProcessHorizontals();
- ClearGhostJoins();
- if (m_Scanbeam.empty()) break;
- cInt topY = PopScanbeam();
- succeeded = ProcessIntersections(topY);
- if (!succeeded) break;
+ ClearGhostJoins();
+ if (!ProcessIntersections(topY))
+ {
+ succeeded = false;
+ break;
+ }
ProcessEdgesAtTopOfScanbeam(topY);
botY = topY;
- } while (!m_Scanbeam.empty() || m_CurrentLM != m_MinimaList.end());
+ InsertLocalMinimaIntoAEL(botY);
+ }
}
catch(std::exception const&)
{
@@ -1489,37 +1627,6 @@ bool Clipper::ExecuteInternal()
}
//------------------------------------------------------------------------------
-void Clipper::InsertScanbeam(const cInt Y)
-{
- m_Scanbeam.push(Y);
-}
-//------------------------------------------------------------------------------
-
-cInt Clipper::PopScanbeam()
-{
- const cInt Y = m_Scanbeam.top();
- m_Scanbeam.pop();
- while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
- return Y;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DisposeAllOutRecs(){
- for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
- DisposeOutRec(i);
- m_PolyOuts.clear();
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DisposeOutRec(PolyOutList::size_type index)
-{
- OutRec *outRec = m_PolyOuts[index];
- if (outRec->Pts) DisposeOutPts(outRec->Pts);
- delete outRec;
- m_PolyOuts[index] = 0;
-}
-//------------------------------------------------------------------------------
-
void Clipper::SetWindingCount(TEdge &edge)
{
TEdge *e = edge.PrevInAEL;
@@ -1527,7 +1634,13 @@ void Clipper::SetWindingCount(TEdge &edge)
while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL;
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;
e = m_ActiveEdges; //ie get ready to calc WindCnt2
}
@@ -1759,13 +1872,16 @@ OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
prevE = e->PrevInAEL;
}
- if (prevE && prevE->OutIdx >= 0 &&
- (TopX(*prevE, Pt.y) == TopX(*e, Pt.y)) &&
- SlopesEqual(*e, *prevE, m_UseFullRange) &&
- (e->WindDelta != 0) && (prevE->WindDelta != 0))
+ if (prevE && prevE->OutIdx >= 0)
{
- OutPt* outPt = AddOutPt(prevE, Pt);
- AddJoin(result, outPt, e->Top);
+ cInt xPrev = TopX(*prevE, Pt.y);
+ cInt xE = TopX(*e, Pt.y);
+ if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) &&
+ SlopesEqual(IntPoint(xPrev, Pt.y), prevE->Top, IntPoint(xE, Pt.y), e->Top, m_UseFullRange))
+ {
+ OutPt* outPt = AddOutPt(prevE, Pt);
+ AddJoin(result, outPt, e->Top);
+ }
}
return result;
}
@@ -1807,6 +1923,15 @@ void Clipper::AddEdgeToSEL(TEdge *edge)
}
//------------------------------------------------------------------------------
+bool Clipper::PopEdgeFromSEL(TEdge *&edge)
+{
+ if (!m_SortedEdges) return false;
+ edge = m_SortedEdges;
+ DeleteFromSEL(m_SortedEdges);
+ return true;
+}
+//------------------------------------------------------------------------------
+
void Clipper::CopyAELToSEL()
{
TEdge* e = m_ActiveEdges;
@@ -1858,11 +1983,12 @@ void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt)
void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
{
- while (m_CurrentLM != m_MinimaList.end() && (m_CurrentLM->y == botY))
+ const LocalMinimum *lm;
+ while (PopLocalMinima(botY, lm))
{
- TEdge* lb = m_CurrentLM->LeftBound;
- TEdge* rb = m_CurrentLM->RightBound;
- PopLocalMinima();
+ TEdge* lb = lm->LeftBound;
+ TEdge* rb = lm->RightBound;
+
OutPt *Op1 = 0;
if (!lb)
{
@@ -1894,15 +2020,20 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
if (rb)
{
- if(IsHorizontal(*rb)) AddEdgeToSEL(rb);
- else InsertScanbeam( rb->Top.y );
+ if (IsHorizontal(*rb))
+ {
+ AddEdgeToSEL(rb);
+ if (rb->NextInLML)
+ InsertScanbeam(rb->NextInLML->Top.y);
+ }
+ else InsertScanbeam( rb->Top.y );
}
if (!lb || !rb) continue;
//if any output polygons share an edge, they'll need joining later ...
if (Op1 && IsHorizontal(*rb) &&
- m_GhostJoins.size() > 0 && (rb->WindDelta != 0))
+ !m_GhostJoins.empty() && (rb->WindDelta != 0))
{
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
{
@@ -1917,7 +2048,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
if (lb->OutIdx >= 0 && lb->PrevInAEL &&
lb->PrevInAEL->Curr.x == lb->Bot.x &&
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))
{
OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot);
@@ -1928,7 +2059,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
{
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))
{
OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot);
@@ -1952,19 +2083,6 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
}
//------------------------------------------------------------------------------
-void Clipper::DeleteFromAEL(TEdge *e)
-{
- TEdge* AelPrev = e->PrevInAEL;
- TEdge* AelNext = e->NextInAEL;
- if( !AelPrev && !AelNext && (e != m_ActiveEdges) ) return; //already deleted
- if( AelPrev ) AelPrev->NextInAEL = AelNext;
- else m_ActiveEdges = AelNext;
- if( AelNext ) AelNext->PrevInAEL = AelPrev;
- e->NextInAEL = 0;
- e->PrevInAEL = 0;
-}
-//------------------------------------------------------------------------------
-
void Clipper::DeleteFromSEL(TEdge *e)
{
TEdge* SelPrev = e->PrevInSEL;
@@ -2188,19 +2306,27 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
{
- bool IsHole = false;
TEdge *e2 = e->PrevInAEL;
+ TEdge *eTmp = 0;
while (e2)
{
if (e2->OutIdx >= 0 && e2->WindDelta != 0)
{
- IsHole = !IsHole;
- if (! outrec->FirstLeft)
- outrec->FirstLeft = m_PolyOuts[e2->OutIdx];
+ if (!eTmp) eTmp = e2;
+ else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0;
}
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;
+ }
}
//------------------------------------------------------------------------------
@@ -2224,7 +2350,7 @@ OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
}
//------------------------------------------------------------------------------
-bool Param1RightOfParam2(OutRec* outRec1, OutRec* outRec2)
+bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2)
{
do
{
@@ -2251,9 +2377,9 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
OutRec *outRec2 = m_PolyOuts[e2->OutIdx];
OutRec *holeStateRec;
- if (Param1RightOfParam2(outRec1, outRec2))
+ if (OutRec1RightOfOutRec2(outRec1, outRec2))
holeStateRec = outRec2;
- else if (Param1RightOfParam2(outRec2, outRec1))
+ else if (OutRec1RightOfOutRec2(outRec2, outRec1))
holeStateRec = outRec1;
else
holeStateRec = GetLowermostRec(outRec1, outRec2);
@@ -2266,7 +2392,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
OutPt* p2_lft = outRec2->Pts;
OutPt* p2_rt = p2_lft->Prev;
- EdgeSide Side;
//join e2 poly onto e1 poly and delete pointers to e2 ...
if( e1->Side == esLeft )
{
@@ -2288,7 +2413,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
p1_rt->Next = p2_lft;
outRec1->Pts = p2_lft;
}
- Side = esLeft;
} else
{
if( e2->Side == esRight )
@@ -2307,7 +2431,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
p1_lft->Prev = p2_rt;
p2_rt->Next = p1_lft;
}
- Side = esRight;
}
outRec1->BottomPt = 0;
@@ -2333,7 +2456,7 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
if( e->OutIdx == ObsoleteIdx )
{
e->OutIdx = OKIdx;
- e->Side = Side;
+ e->Side = e1->Side;
break;
}
e = e->NextInAEL;
@@ -2343,21 +2466,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
}
//------------------------------------------------------------------------------
-OutRec* Clipper::CreateOutRec()
-{
- OutRec* result = new OutRec;
- result->IsHole = false;
- result->IsOpen = false;
- result->FirstLeft = 0;
- result->Pts = 0;
- result->BottomPt = 0;
- result->PolyNd = 0;
- m_PolyOuts.push_back(result);
- result->Idx = (int)m_PolyOuts.size()-1;
- return result;
-}
-//------------------------------------------------------------------------------
-
OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
{
if( e->OutIdx < 0 )
@@ -2409,13 +2517,9 @@ OutPt* Clipper::GetLastOutPt(TEdge *e)
void Clipper::ProcessHorizontals()
{
- TEdge* horzEdge = m_SortedEdges;
- while(horzEdge)
- {
- DeleteFromSEL(horzEdge);
+ TEdge* horzEdge;
+ while (PopEdgeFromSEL(horzEdge))
ProcessHorizontal(horzEdge);
- horzEdge = m_SortedEdges;
- }
}
//------------------------------------------------------------------------------
@@ -2439,64 +2543,21 @@ inline bool IsIntermediate(TEdge *e, const cInt Y)
TEdge *GetMaximaPair(TEdge *e)
{
- TEdge* result = 0;
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)
- result = e->Prev;
-
- if (result && (result->OutIdx == Skip ||
- //result is false if both NextInAEL & PrevInAEL are nil & not horizontal ...
- (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result))))
- return 0;
- return result;
+ return e->Prev;
+ else return 0;
}
//------------------------------------------------------------------------------
-void Clipper::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
+TEdge *GetMaximaPairEx(TEdge *e)
{
- //check that one or other edge hasn't already been removed from AEL ...
- if (Edge1->NextInAEL == Edge1->PrevInAEL ||
- Edge2->NextInAEL == Edge2->PrevInAEL) return;
-
- if( Edge1->NextInAEL == Edge2 )
- {
- TEdge* Next = Edge2->NextInAEL;
- if( Next ) Next->PrevInAEL = Edge1;
- TEdge* Prev = Edge1->PrevInAEL;
- if( Prev ) Prev->NextInAEL = Edge2;
- Edge2->PrevInAEL = Prev;
- Edge2->NextInAEL = Edge1;
- Edge1->PrevInAEL = Edge2;
- Edge1->NextInAEL = Next;
- }
- else if( Edge2->NextInAEL == Edge1 )
- {
- TEdge* Next = Edge1->NextInAEL;
- if( Next ) Next->PrevInAEL = Edge2;
- TEdge* Prev = Edge2->PrevInAEL;
- if( Prev ) Prev->NextInAEL = Edge1;
- Edge1->PrevInAEL = Prev;
- Edge1->NextInAEL = Edge2;
- Edge2->PrevInAEL = Edge1;
- Edge2->NextInAEL = Next;
- }
- else
- {
- TEdge* Next = Edge1->NextInAEL;
- TEdge* Prev = Edge1->PrevInAEL;
- Edge1->NextInAEL = Edge2->NextInAEL;
- if( Edge1->NextInAEL ) Edge1->NextInAEL->PrevInAEL = Edge1;
- Edge1->PrevInAEL = Edge2->PrevInAEL;
- if( Edge1->PrevInAEL ) Edge1->PrevInAEL->NextInAEL = Edge1;
- Edge2->NextInAEL = Next;
- if( Edge2->NextInAEL ) Edge2->NextInAEL->PrevInAEL = Edge2;
- Edge2->PrevInAEL = Prev;
- if( Edge2->PrevInAEL ) Edge2->PrevInAEL->NextInAEL = Edge2;
- }
-
- if( !Edge1->PrevInAEL ) m_ActiveEdges = Edge1;
- else if( !Edge2->PrevInAEL ) m_ActiveEdges = Edge2;
+ //as GetMaximaPair() but returns 0 if MaxPair isn't in AEL (unless it's horizontal)
+ TEdge* result = GetMaximaPair(e);
+ if (result && (result->OutIdx == Skip ||
+ (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return 0;
+ return result;
}
//------------------------------------------------------------------------------
@@ -2582,7 +2643,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
{
Direction dir;
cInt horzLeft, horzRight;
- bool IsOpen = (horzEdge->OutIdx >= 0 && m_PolyOuts[horzEdge->OutIdx]->IsOpen);
+ bool IsOpen = (horzEdge->WindDelta == 0);
GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
@@ -2594,7 +2655,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
MaximaList::const_iterator maxIt;
MaximaList::const_reverse_iterator maxRit;
- if (m_Maxima.size() > 0)
+ if (!m_Maxima.empty())
{
//get the first maxima in range (X) ...
if (dir == dLeftToRight)
@@ -2626,7 +2687,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
//this code block inserts extra coords into horizontal edges (in output
//polygons) whereever maxima touch these horizontal edges. This helps
//'simplifying' polygons (ie if the Simplify property is set).
- if (m_Maxima.size() > 0)
+ if (!m_Maxima.empty())
{
if (dir == dLeftToRight)
{
@@ -2765,29 +2826,6 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
}
//------------------------------------------------------------------------------
-void Clipper::UpdateEdgeIntoAEL(TEdge *&e)
-{
- if( !e->NextInLML )
- throw clipperException("UpdateEdgeIntoAEL: invalid call");
-
- e->NextInLML->OutIdx = e->OutIdx;
- TEdge* AelPrev = e->PrevInAEL;
- TEdge* AelNext = e->NextInAEL;
- if (AelPrev) AelPrev->NextInAEL = e->NextInLML;
- else m_ActiveEdges = e->NextInLML;
- if (AelNext) AelNext->PrevInAEL = e->NextInLML;
- e->NextInLML->Side = e->Side;
- e->NextInLML->WindDelta = e->WindDelta;
- e->NextInLML->WindCnt = e->WindCnt;
- e->NextInLML->WindCnt2 = e->WindCnt2;
- e = e->NextInLML;
- e->Curr = e->Bot;
- e->PrevInAEL = AelPrev;
- e->NextInAEL = AelNext;
- if (!IsHorizontal(*e)) InsertScanbeam(e->Top.y);
-}
-//------------------------------------------------------------------------------
-
bool Clipper::ProcessIntersections(const cInt topY)
{
if( !m_ActiveEdges ) return true;
@@ -2845,6 +2883,7 @@ void Clipper::BuildIntersectList(const cInt topY)
if(e->Curr.x > eNext->Curr.x)
{
IntersectPoint(*e, *eNext, Pt);
+ if (Pt.y < topY) Pt = IntPoint(TopX(*e, topY), topY);
IntersectNode * newNode = new IntersectNode;
newNode->Edge1 = e;
newNode->Edge2 = eNext;
@@ -2919,7 +2958,7 @@ bool Clipper::FixupIntersectionOrder()
void Clipper::DoMaxima(TEdge *e)
{
- TEdge* eMaxPair = GetMaximaPair(e);
+ TEdge* eMaxPair = GetMaximaPairEx(e);
if (!eMaxPair)
{
if (e->OutIdx >= 0)
@@ -2980,7 +3019,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
if(IsMaximaEdge)
{
- TEdge* eMaxPair = GetMaximaPair(e);
+ TEdge* eMaxPair = GetMaximaPairEx(e);
IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair));
}
@@ -3052,7 +3091,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
if (ePrev && ePrev->Curr.x == e->Bot.x &&
ePrev->Curr.y == e->Bot.y && op &&
ePrev->OutIdx >= 0 && ePrev->Curr.y > ePrev->Top.y &&
- SlopesEqual(*e, *ePrev, m_UseFullRange) &&
+ SlopesEqual(e->Curr, e->Top, ePrev->Curr, ePrev->Top, m_UseFullRange) &&
(e->WindDelta != 0) && (ePrev->WindDelta != 0))
{
OutPt* op2 = AddOutPt(ePrev, e->Bot);
@@ -3061,7 +3100,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
else if (eNext && eNext->Curr.x == e->Bot.x &&
eNext->Curr.y == e->Bot.y && op &&
eNext->OutIdx >= 0 && eNext->Curr.y > eNext->Top.y &&
- SlopesEqual(*e, *eNext, m_UseFullRange) &&
+ SlopesEqual(e->Curr, e->Top, eNext->Curr, eNext->Top, m_UseFullRange) &&
(e->WindDelta != 0) && (eNext->WindDelta != 0))
{
OutPt* op2 = AddOutPt(eNext, e->Bot);
@@ -3588,9 +3627,8 @@ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
OutRec* outRec = m_PolyOuts[i];
- if (!outRec->Pts || !outRec->FirstLeft) continue;
OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
- if (firstLeft == OldOutRec)
+ if (outRec->Pts && firstLeft == OldOutRec)
{
if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts))
outRec->FirstLeft = NewOutRec;
@@ -3599,13 +3637,40 @@ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* 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 (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+ {
+ OutRec* outRec = m_PolyOuts[i];
+
+ 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
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
OutRec* outRec = m_PolyOuts[i];
- if (outRec->FirstLeft == OldOutRec) outRec->FirstLeft = NewOutRec;
+ OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
+ if (outRec->Pts && outRec->FirstLeft == OldOutRec)
+ outRec->FirstLeft = NewOutRec;
}
}
//----------------------------------------------------------------------
@@ -3626,8 +3691,8 @@ void Clipper::JoinCommonEdges()
//before calling JoinPoints() ...
OutRec *holeStateRec;
if (outRec1 == outRec2) holeStateRec = outRec1;
- else if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2;
- else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1;
+ else if (OutRec1RightOfOutRec2(outRec1, outRec2)) holeStateRec = outRec2;
+ else if (OutRec1RightOfOutRec2(outRec2, outRec1)) holeStateRec = outRec1;
else holeStateRec = GetLowermostRec(outRec1, outRec2);
if (!JoinPoints(join, outRec1, outRec2)) continue;
@@ -3644,25 +3709,12 @@ void Clipper::JoinCommonEdges()
//update all OutRec2.Pts Idx's ...
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 (PolyOutList::size_type j = 0; j < m_PolyOuts.size() - 1; j++)
- {
- OutRec* oRec = m_PolyOuts[j];
- if (!oRec->Pts || ParseFirstLeft(oRec->FirstLeft) != outRec1 ||
- oRec->IsHole == outRec1->IsHole) continue;
- if (Poly2ContainsPoly1(oRec->Pts, join->OutPt2))
- oRec->FirstLeft = outRec2;
- }
-
if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts))
{
- //outRec2 is contained by outRec1 ...
+ //outRec1 contains outRec2 ...
outRec2->IsHole = !outRec1->IsHole;
outRec2->FirstLeft = outRec1;
- //fixup FirstLeft pointers that may need reassigning to OutRec1
if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1);
if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0))
@@ -3670,13 +3722,12 @@ void Clipper::JoinCommonEdges()
} else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts))
{
- //outRec1 is contained by outRec2 ...
+ //outRec2 contains outRec1 ...
outRec2->IsHole = outRec1->IsHole;
outRec1->IsHole = !outRec2->IsHole;
outRec2->FirstLeft = outRec1->FirstLeft;
outRec1->FirstLeft = outRec2;
- //fixup FirstLeft pointers that may need reassigning to OutRec1
if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2);
if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0))
@@ -3705,8 +3756,7 @@ void Clipper::JoinCommonEdges()
outRec1->FirstLeft = outRec2->FirstLeft;
outRec2->FirstLeft = outRec1;
- //fixup FirstLeft pointers that may need reassigning to OutRec1
- if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1);
+ if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1);
}
}
}
@@ -3858,7 +3908,7 @@ void ClipperOffset::Execute(Paths& solution, double delta)
clpr.AddPath(outer, ptSubject, true);
clpr.ReverseSolution(true);
clpr.Execute(ctUnion, solution, pftNegative, pftNegative);
- if (solution.size() > 0) solution.erase(solution.begin());
+ if (!solution.empty()) solution.erase(solution.begin());
}
}
//------------------------------------------------------------------------------
@@ -4404,6 +4454,7 @@ void CleanPolygon(Path& poly, double distance)
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance)
{
+ out_polys.resize(in_polys.size());
for (Paths::size_type i = 0; i < in_polys.size(); ++i)
CleanPolygon(in_polys[i], out_polys[i], distance);
}
diff --git a/debian/clipper.hpp b/debian/clipper.hpp
index 41fd305..7831b0b 100644
--- a/debian/clipper.hpp
+++ b/debian/clipper.hpp
@@ -1,8 +1,8 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
-* Version : 6.2.9 *
-* Date : 16 February 2015 *
+* Version : 6.4.0 *
+* Date : 2 July 2015 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2015 *
* *
@@ -251,7 +251,7 @@ class ClipperBase
public:
ClipperBase();
virtual ~ClipperBase();
- bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
+ virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
virtual void Clear();
IntRect GetBounds();
@@ -260,11 +260,18 @@ public:
protected:
void DisposeLocalMinimaList();
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
- void PopLocalMinima();
virtual void Reset();
TEdge* ProcessBound(TEdge* E, bool IsClockwise);
- TEdge* DescendToMin(TEdge *&E);
- void AscendToMax(TEdge *&E, bool Appending, bool IsClosed);
+ void InsertScanbeam(const cInt Y);
+ bool PopScanbeam(cInt &Y);
+ bool LocalMinimaPending();
+ bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
+ OutRec* CreateOutRec();
+ void DisposeAllOutRecs();
+ void DisposeOutRec(PolyOutList::size_type index);
+ void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
+ void DeleteFromAEL(TEdge *e);
+ void UpdateEdgeIntoAEL(TEdge *&e);
typedef std::vector<LocalMinimum> MinimaList;
MinimaList::iterator m_CurrentLM;
@@ -272,8 +279,13 @@ protected:
bool m_UseFullRange;
EdgeList m_edges;
- bool m_PreserveCollinear;
- bool m_HasOpenPaths;
+ bool m_PreserveCollinear;
+ bool m_HasOpenPaths;
+ PolyOutList m_PolyOuts;
+ TEdge *m_ActiveEdges;
+
+ typedef std::priority_queue<cInt> ScanbeamList;
+ ScanbeamList m_Scanbeam;
};
//------------------------------------------------------------------------------
@@ -281,7 +293,6 @@ class Clipper : public virtual ClipperBase
{
public:
Clipper(int initOptions = 0);
- ~Clipper();
bool Execute(ClipType clipType,
Paths &solution,
PolyFillType fillType = pftEvenOdd);
@@ -305,19 +316,14 @@ public:
void ZFillFunction(ZFillCallback zFillFunc);
#endif
protected:
- void Reset();
virtual bool ExecuteInternal();
private:
- PolyOutList m_PolyOuts;
JoinList m_Joins;
JoinList m_GhostJoins;
IntersectList m_IntersectList;
ClipType m_ClipType;
- typedef std::priority_queue<cInt> ScanbeamList;
- ScanbeamList m_Scanbeam;
typedef std::list<cInt> MaximaList;
MaximaList m_Maxima;
- TEdge *m_ActiveEdges;
TEdge *m_SortedEdges;
bool m_ExecuteLocked;
PolyFillType m_ClipFillType;
@@ -331,19 +337,15 @@ private:
void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge& edge) const;
- void InsertScanbeam(const cInt Y);
- cInt PopScanbeam();
void InsertLocalMinimaIntoAEL(const cInt botY);
void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
void AddEdgeToSEL(TEdge *edge);
+ bool PopEdgeFromSEL(TEdge *&edge);
void CopyAELToSEL();
void DeleteFromSEL(TEdge *e);
- void DeleteFromAEL(TEdge *e);
- void UpdateEdgeIntoAEL(TEdge *&e);
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
bool IsContributing(const TEdge& edge) const;
bool IsTopHorz(const cInt XPos);
- void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
void DoMaxima(TEdge *e);
void ProcessHorizontals();
void ProcessHorizontal(TEdge *horzEdge);
@@ -352,11 +354,8 @@ private:
OutRec* GetOutRec(int idx);
void AppendPolygon(TEdge *e1, TEdge *e2);
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
- OutRec* CreateOutRec();
OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
OutPt* GetLastOutPt(TEdge *e);
- void DisposeAllOutRecs();
- void DisposeOutRec(PolyOutList::size_type index);
bool ProcessIntersections(const cInt topY);
void BuildIntersectList(const cInt topY);
void ProcessIntersectList();
@@ -379,7 +378,8 @@ private:
void JoinCommonEdges();
void DoSimplePolygons();
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 use_xyz
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapnik-vector-tile.git
More information about the Pkg-grass-devel
mailing list