[mapnik-vector-tile] 04/04: Update clipper to 150f2c4f58a72c051bcad76c84f10362797bf5ab.
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Fri Mar 11 12:31:37 UTC 2016
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 46232be8f065a01ea328199957aeb5d1bb5ace5d
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Fri Mar 11 13:31:10 2016 +0100
Update clipper to 150f2c4f58a72c051bcad76c84f10362797bf5ab.
---
debian/changelog | 2 +-
debian/clipper.cpp | 453 +++++++++++++++++++++++++++++++++++++++++++++++++++--
debian/clipper.hpp | 3 +
3 files changed, 441 insertions(+), 17 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index fcd5352..715d990 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,7 +5,7 @@ mapnik-vector-tile (1.0.4+dfsg-1) UNRELEASED; urgency=medium
* Refresh patches.
* Bump protozero dependency to 1.3.0.
* Bump Standards-Version to 3.9.7, no changes.
- * Update clipper to b82601d67830a84179888360e3dea645c1125a26.
+ * Update clipper to 150f2c4f58a72c051bcad76c84f10362797bf5ab.
-- Bas Couwenberg <sebastic at debian.org> Fri, 11 Mar 2016 13:29:45 +0100
diff --git a/debian/clipper.cpp b/debian/clipper.cpp
index 3772e1e..bf369ec 100644
--- a/debian/clipper.cpp
+++ b/debian/clipper.cpp
@@ -633,7 +633,7 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
ip.x = TopX(Edge1, ip.y);
return;
}
- else if (Edge1.Dx == 0)
+ else if (Edge1.Dx == 0.0)
{
ip.x = Edge1.Bot.x;
if (IsHorizontal(Edge2))
@@ -641,10 +641,14 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
else
{
b2 = Edge2.Bot.y - (Edge2.Bot.x / Edge2.Dx);
- ip.y = Round(ip.x / Edge2.Dx + b2);
+ if (Edge2.Bot.x == Edge1.Bot.x) ip.y = Round(ip.x / Edge2.Dx + b2);
+ else if (Edge2.Bot.x < Edge1.Bot.x) ip.y = Round((ip.x - 0.5) / Edge2.Dx + b2);
+ else ip.y = Round((ip.x + 0.5) / Edge2.Dx + b2);
+ if (Edge2.Dx > 0.0 && ip.y < Edge2.Bot.y) ip.y = Edge2.Bot.y;
+ else if (Edge2.Dx < 0.0 && ip.y > Edge2.Bot.y) ip.y = Edge2.Bot.y;
}
}
- else if (Edge2.Dx == 0)
+ else if (Edge2.Dx == 0.0)
{
ip.x = Edge2.Bot.x;
if (IsHorizontal(Edge1))
@@ -652,7 +656,11 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
else
{
b1 = Edge1.Bot.y - (Edge1.Bot.x / Edge1.Dx);
- ip.y = Round(ip.x / Edge1.Dx + b1);
+ if (Edge1.Bot.x == Edge2.Bot.x) ip.y = Round(ip.x / Edge1.Dx + b1);
+ else if (Edge1.Bot.x < Edge2.Bot.x) ip.y = Round((ip.x - 0.5) / Edge1.Dx + b1);
+ else ip.y = Round((ip.x + 0.5) / Edge1.Dx + b1);
+ if (Edge1.Dx > 0.0 && ip.y < Edge1.Bot.y) ip.y = Edge1.Bot.y;
+ else if (Edge1.Dx < 0.0 && ip.y > Edge1.Bot.y) ip.y = Edge1.Bot.y;
}
}
else
@@ -665,6 +673,85 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
ip.x = Round(Edge1.Dx * q + b1);
else
ip.x = Round(Edge2.Dx * q + b2);
+ // the idea is simply to looking closer
+ // towards the origins of the lines (Edge1.Bot and Edge2.Bot)
+ // until we do not find pixels that both lines travel through
+ bool keep_searching = false;
+ double by1 = Edge1.Bot.y - (Edge1.Bot.x / Edge1.Dx);
+ double by2 = Edge2.Bot.y - (Edge2.Bot.x / Edge2.Dx);
+ double bx1 = Edge1.Bot.x - (Edge1.Bot.y * Edge1.Dx);
+ double bx2 = Edge2.Bot.x - (Edge2.Bot.y * Edge2.Dx);
+ do
+ {
+ keep_searching = false;
+ cInt y1 = ip.y;
+ cInt y2 = ip.y;
+ if (Edge1.Bot.x > ip.x)
+ {
+ y1 = Round((ip.x + 0.5) / Edge1.Dx + by1);
+ if (ip.y >= Edge1.Bot.y && y1 < Edge1.Bot.y) y1 = Edge1.Bot.y;
+ else if (ip.y <= Edge1.Bot.y && y1 > Edge1.Bot.y) y1 = Edge1.Bot.y;
+ }
+ else if (Edge1.Bot.x < ip.x)
+ {
+ y1 = Round((ip.x - 0.5) / Edge1.Dx + by1);
+ }
+ if (ip.y >= Edge1.Bot.y && y1 < Edge1.Bot.y) y1 = Edge1.Bot.y;
+ else if (ip.y <= Edge1.Bot.y && y1 > Edge1.Bot.y) y1 = Edge1.Bot.y;
+ if (Edge2.Bot.x > ip.x)
+ {
+ y2 = Round((ip.x + 0.5) / Edge2.Dx + by2);
+ }
+ else if (Edge2.Bot.x < ip.x)
+ {
+ y2 = Round((ip.x - 0.5) / Edge2.Dx + by2);
+ }
+ if (ip.y >= Edge2.Bot.y && y2 < Edge2.Bot.y) y2 = Edge2.Bot.y;
+ else if (ip.y <= Edge2.Bot.y && y2 > Edge2.Bot.y) y2 = Edge2.Bot.y;
+ cInt x1 = ip.x;
+ cInt x2 = ip.x;
+ if (Edge1.Bot.y > ip.y)
+ {
+ x1 = Round((ip.y + 0.5) * Edge1.Dx + bx1);
+ }
+ else if (Edge1.Bot.y < ip.y)
+ {
+ x1 = Round((ip.y - 0.5) * Edge1.Dx + bx1);
+ }
+ if (ip.x >= Edge1.Bot.x && x1 < Edge1.Bot.x) x1 = Edge1.Bot.x;
+ else if (ip.x <= Edge1.Bot.x && x1 > Edge1.Bot.x) x1 = Edge1.Bot.x;
+ if (Edge2.Bot.y > ip.y)
+ {
+ x2 = Round((ip.y + 0.5) * Edge2.Dx + bx2);
+ }
+ else if (Edge2.Bot.y < ip.y)
+ {
+ x2 = Round((ip.y - 0.5) * Edge2.Dx + bx2);
+ }
+ if (ip.x >= Edge2.Bot.x && x2 < Edge2.Bot.x) x2 = Edge2.Bot.x;
+ else if (ip.x <= Edge2.Bot.x && x2 > Edge2.Bot.x) x2 = Edge2.Bot.x;
+ if (y1 > ip.y && y2 > ip.y)
+ {
+ ip.y = std::min(y1,y2);
+ keep_searching = true;
+ }
+ else if (y1 < ip.y && y2 < ip.y)
+ {
+ ip.y = std::max(y1,y2);
+ keep_searching = true;
+ }
+ if (x1 > ip.x && x2 > ip.x)
+ {
+ ip.x = std::min(x1,x2);
+ keep_searching = true;
+ }
+ else if (x1 < ip.x && x2 < ip.x)
+ {
+ ip.x = std::max(x1,x2);
+ keep_searching = true;
+ }
+ }
+ while (keep_searching);
}
if (ip.y < Edge1.Top.y || ip.y < Edge2.Top.y)
@@ -1963,6 +2050,14 @@ void Clipper::ClearJoins()
}
//------------------------------------------------------------------------------
+void Clipper::ClearSSJoins()
+{
+ for (JoinList::size_type i = 0; i < m_SSJoins.size(); i++)
+ delete m_SSJoins[i];
+ m_SSJoins.resize(0);
+}
+//------------------------------------------------------------------------------
+
void Clipper::ClearGhostJoins()
{
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++)
@@ -1981,6 +2076,16 @@ void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt)
}
//------------------------------------------------------------------------------
+void Clipper::AddSSJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt)
+{
+ Join* j = new Join;
+ j->OutPt1 = op1;
+ j->OutPt2 = op2;
+ j->OffPt = OffPt;
+ m_SSJoins.push_back(j);
+}
+//------------------------------------------------------------------------------
+
void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
{
const LocalMinimum *lm;
@@ -1996,14 +2101,46 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
InsertEdgeIntoAEL(rb, 0);
SetWindingCount(*rb);
if (IsContributing(*rb))
- Op1 = AddOutPt(rb, rb->Bot);
+ {
+ Op1 = AddOutPt(rb, rb->Bot);
+ TEdge* ePrev = rb->PrevInAEL;
+ if ((rb->OutIdx >= 0) && (rb->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) &&
+ (ePrev->Curr.x == rb->Curr.x) && (ePrev->WindDelta != 0))
+ {
+ IntPoint pt = rb->Curr;
+ AddOutPt(ePrev, pt);
+ }
+ TEdge* eNext = rb->NextInAEL;
+ if ((rb->OutIdx >= 0) && (rb->WindDelta != 0) && eNext && (eNext->OutIdx >= 0) &&
+ (eNext->Curr.x == rb->Curr.x) && (eNext->WindDelta != 0))
+ {
+ IntPoint pt = rb->Curr;
+ AddOutPt(eNext, pt);
+ }
+ }
}
else if (!rb)
{
InsertEdgeIntoAEL(lb, 0);
SetWindingCount(*lb);
if (IsContributing(*lb))
- Op1 = AddOutPt(lb, lb->Bot);
+ {
+ Op1 = AddOutPt(lb, lb->Bot);
+ TEdge* ePrev = lb->PrevInAEL;
+ if ((lb->OutIdx >= 0) && (lb->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) &&
+ (ePrev->Curr.x == lb->Curr.x) && (ePrev->WindDelta != 0))
+ {
+ IntPoint pt = lb->Curr;
+ AddOutPt(ePrev, pt);
+ }
+ TEdge* eNext = lb->NextInAEL;
+ if ((lb->OutIdx >= 0) && (lb->WindDelta != 0) && eNext && (eNext->OutIdx >= 0) &&
+ (eNext->Curr.x == lb->Curr.x) && (eNext->WindDelta != 0))
+ {
+ IntPoint pt = lb->Curr;
+ AddOutPt(eNext, pt);
+ }
+ }
InsertScanbeam(lb->Top.y);
}
else
@@ -2014,7 +2151,23 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
rb->WindCnt = lb->WindCnt;
rb->WindCnt2 = lb->WindCnt2;
if (IsContributing(*lb))
- Op1 = AddLocalMinPoly(lb, rb, lb->Bot);
+ {
+ Op1 = AddLocalMinPoly(lb, rb, lb->Bot);
+ TEdge* ePrev = lb->PrevInAEL;
+ if ((lb->OutIdx >= 0) && (lb->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) &&
+ (ePrev->Curr.x == lb->Curr.x) && (ePrev->WindDelta != 0))
+ {
+ IntPoint pt = lb->Curr;
+ AddOutPt(ePrev, pt);
+ }
+ TEdge* eNext = rb->NextInAEL;
+ if ((rb->OutIdx >= 0) && (rb->WindDelta != 0) && eNext && (eNext->OutIdx >= 0) &&
+ (eNext->Curr.x == rb->Curr.x) && (eNext->WindDelta != 0))
+ {
+ IntPoint pt = rb->Curr;
+ AddOutPt(eNext, pt);
+ }
+ }
InsertScanbeam(lb->Top.y);
}
@@ -2793,6 +2946,27 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
if(horzEdge->OutIdx >= 0)
{
op1 = AddOutPt( horzEdge, horzEdge->Top);
+ //When StrictlySimple and 'horzEdge' is being touched by another edge, then
+ //make sure both edges have a vertex here ...
+ if (m_StrictSimple)
+ {
+ TEdge* ePrev = horzEdge->PrevInAEL;
+ if ((horzEdge->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) &&
+ (ePrev->Curr.x == horzEdge->Top.x) && (ePrev->WindDelta != 0))
+ {
+ IntPoint pt = horzEdge->Top;
+ OutPt* op = AddOutPt(ePrev, pt);
+ AddJoin(op, op1, pt); //StrictlySimple (type-3) join
+ }
+ TEdge* eNext = horzEdge->NextInAEL;
+ if ((horzEdge->WindDelta != 0) && eNext && (eNext->OutIdx >= 0) &&
+ (eNext->Curr.x == horzEdge->Top.x) && (eNext->WindDelta != 0))
+ {
+ IntPoint pt = horzEdge->Top;
+ OutPt* op = AddOutPt(eNext, pt);
+ AddJoin(op, op1, pt); //StrictlySimple (type-3) join
+ }
+ }
UpdateEdgeIntoAEL(horzEdge);
if (horzEdge->WindDelta == 0) return;
//nb: HorzEdge is no longer horizontal here
@@ -2962,17 +3136,96 @@ void Clipper::DoMaxima(TEdge *e)
if (!eMaxPair)
{
if (e->OutIdx >= 0)
+ {
AddOutPt(e, e->Top);
+ if (e->WindDelta != 0)
+ {
+ TEdge* ePrev = e->PrevInAEL;
+ while (ePrev)
+ {
+ if (e->Top == ePrev->Top)
+ {
+ ePrev = ePrev->PrevInAEL;
+ continue;
+ }
+ if (ePrev->Curr.x != e->Curr.x) break;
+ if ((ePrev->OutIdx >= 0) && (ePrev->WindDelta != 0))
+ {
+ IntPoint pt = e->Curr;
+ AddOutPt(ePrev, pt);
+ }
+ ePrev = ePrev->PrevInAEL;
+ }
+ TEdge* eNext = e->NextInAEL;
+ while (eNext)
+ {
+ if (e->Top == eNext->Top)
+ {
+ eNext = eNext->NextInAEL;
+ continue;
+ }
+ if (eNext->Curr.x != e->Curr.x) break;
+ if ((eNext->OutIdx >= 0) && (eNext->WindDelta != 0))
+ {
+ IntPoint pt = e->Curr;
+ AddOutPt(eNext, pt);
+ }
+ eNext = eNext->NextInAEL;
+ }
+ }
+ }
DeleteFromAEL(e);
return;
}
-
+
+ IntPoint pt = e->Top;
TEdge* eNext = e->NextInAEL;
- while(eNext && eNext != eMaxPair)
+ TEdge* ePrev = e->PrevInAEL;
+ if (e->WindDelta != 0)
+ {
+ while (eNext)
+ {
+ if (pt == eNext->Top)
+ {
+ eNext = eNext->NextInAEL;
+ continue;
+ }
+ if (TopX(*eNext, pt.y) != pt.x)
+ {
+ eNext = 0;
+ break;
+ }
+ else if ((eNext->OutIdx >= 0) && (eNext->WindDelta != 0))
+ {
+ break;
+ }
+ eNext = eNext->NextInAEL;
+ }
+ while (ePrev)
+ {
+ if (pt == ePrev->Top)
+ {
+ ePrev = ePrev->PrevInAEL;
+ continue;
+ }
+ if (TopX(*ePrev, pt.y) != pt.x)
+ {
+ ePrev = 0;
+ break;
+ }
+ else if ((ePrev->OutIdx >= 0) && (ePrev->WindDelta != 0))
+ {
+ break;
+ }
+ ePrev = ePrev->PrevInAEL;
+ }
+ }
+ TEdge* eNext2 = e->NextInAEL;
+ while(eNext2 && eNext2 != eMaxPair)
{
- IntersectEdges(e, eNext, e->Top);
- SwapPositionsInAEL(e, eNext);
- eNext = e->NextInAEL;
+ IntersectEdges(e, eNext2, e->Top);
+ SwapPositionsInAEL(e, eNext2);
+ eNext2 = e->NextInAEL;
}
if(e->OutIdx == Unassigned && eMaxPair->OutIdx == Unassigned)
@@ -2982,9 +3235,17 @@ void Clipper::DoMaxima(TEdge *e)
}
else if( e->OutIdx >= 0 && eMaxPair->OutIdx >= 0 )
{
- if (e->OutIdx >= 0) AddLocalMaxPoly(e, eMaxPair, e->Top);
- DeleteFromAEL(e);
- DeleteFromAEL(eMaxPair);
+ AddLocalMaxPoly(e, eMaxPair, e->Top);
+ if (ePrev)
+ {
+ AddOutPt(ePrev, pt);
+ }
+ if (eNext)
+ {
+ AddOutPt(eNext, pt);
+ }
+ DeleteFromAEL(e);
+ DeleteFromAEL(eMaxPair);
}
#ifdef use_lines
else if (e->WindDelta == 0)
@@ -3471,8 +3732,165 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
if (isHorizontal && (j->OffPt == j->OutPt1->Pt) &&
(j->OffPt == j->OutPt2->Pt))
{
+ if (outRec1 != outRec2)
+ {
+ // First Op1 Next and Op2 Prev
+ op1b = j->OutPt1->Next;
+ while (op1b != op1 && (op1b->Pt == j->OffPt))
+ op1b = op1b->Next;
+ op2b = j->OutPt2->Prev;
+ while (op2b != op2 && (op2b->Pt == j->OffPt))
+ op2b = op2b->Prev;
+ if (op1b->Pt == op2b->Pt)
+ {
+ OutPt* op1b_prev = op1b->Prev;
+ OutPt* op2b_next = op2b->Next;
+ op1b->Prev = op2b;
+ op2b->Next = op1b;
+ op1b_prev->Next = op2b_next;
+ op2b_next->Prev = op1b_prev;
+ return true;
+ }
+ bool reverse1 = (op1b->Pt.y > j->OffPt.y);
+
+ // Second Op1 Prev and Op2 Next
+ op2b = j->OutPt2->Next;
+ while (op2b != op2 && (op2b->Pt == j->OffPt))
+ op2b = op2b->Next;
+ op1b = j->OutPt1->Prev;
+ while (op1b != op1 && (op1b->Pt == j->OffPt))
+ op1b = op1b->Prev;
+ if (op2b->Pt == op1b->Pt)
+ {
+ OutPt* op2b_prev = op2b->Prev;
+ OutPt* op1b_next = op1b->Next;
+ op2b->Prev = op1b;
+ op1b->Next = op2b;
+ op2b_prev->Next = op1b_next;
+ op1b_next->Prev = op2b_prev;
+ return true;
+ }
+ bool reverse2 = (op2b->Pt.y > j->OffPt.y);
+ if (reverse1 == reverse2) return false;
+ // See if there was a situation where these
+ // two were split into seperate polygons
+ // with a SS join
+ for (auto & sj : m_SSJoins)
+ {
+ if (!sj->OutPt1 || !sj->OutPt2) continue;
+ OutRec *sjOutRec1 = GetOutRec(sj->OutPt1->Idx);
+ OutRec *sjOutRec2 = GetOutRec(sj->OutPt2->Idx);
+ if (sjOutRec1->Idx == outRec1->Idx && sjOutRec2->Idx == outRec2->Idx)
+ {
+ // We a previous SS join that has the same ids, so we might need to make
+ // a different join type.
+ op1b = j->OutPt1->Next;
+ while (op1b != op1 && op1b != sj->OutPt1)
+ {
+ op1b = op1b->Next;
+ }
+ if (op1b == op1) continue;
+ op2b = j->OutPt2->Next;
+ while (op2b != op2 && op2b != sj->OutPt2)
+ {
+ op2b = op2b->Next;
+ }
+ if (op2b == op2) continue;
+ OutPt* op1b_next = op1b->Next;
+ OutPt* op2b_next = op2b->Next;
+ OutPt* op1_next = op1->Next;
+ OutPt* op2_next = op2->Next;
+ op2b->Next= op1b_next;
+ op1b->Next = op2b_next;
+ op2b_next->Prev = op1b;
+ op1b_next->Prev = op2b;
+ op2->Next= op1_next;
+ op1->Next = op2_next;
+ op2_next->Prev = op1;
+ op1_next->Prev = op2;
+ sj->OutPt1 = 0;
+ sj->OutPt2 = 0;
+ }
+ else if (sjOutRec1->Idx == outRec2->Idx && sjOutRec2->Idx == outRec1->Idx)
+ {
+ // We a previous SS join that has the same ids, so we might need to make
+ // a different join type.
+ op1b = j->OutPt1->Next;
+ while (op1b != op1 && op1b != sj->OutPt2)
+ {
+ op1b = op1b->Next;
+ }
+ if (op1b == op1) continue;
+ op2b = j->OutPt2->Next;
+ while (op2b != op2 && op2b != sj->OutPt1)
+ {
+ op2b = op2b->Next;
+ }
+ if (op2b == op2) continue;
+ OutPt* op1b_next = op1b->Next;
+ OutPt* op2b_next = op2b->Next;
+ OutPt* op1_next = op1->Next;
+ OutPt* op2_next = op2->Next;
+ op2b->Next= op1b_next;
+ op1b->Next = op2b_next;
+ op2b_next->Prev = op1b;
+ op1b_next->Prev = op2b;
+ op2->Next= op1_next;
+ op1->Next = op2_next;
+ op2_next->Prev = op1;
+ op1_next->Prev = op2;
+ sj->OutPt1 = 0;
+ sj->OutPt2 = 0;
+ }
+ else
+ {
+ continue;
+ }
+ // We still will return false here
+ // because if we returned true it would
+ // continue and think these two polygons should be merged
+ bool holeState = (Area(j->OutPt1) > 0) && m_ReverseOutput;
+ if (outRec1->IsHole == holeState) // outRec1 is "parent"
+ {
+ outRec1->Pts = j->OutPt2;
+ outRec1->BottomPt = 0;
+ outRec2->Pts = 0;
+ outRec2->BottomPt = 0;
+ outRec2->Idx = outRec1->Idx;
+ outRec2->FirstLeft = outRec1;
+ outRec2->IsHole = outRec1->IsHole;
+ if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1);
+ OutRec * outRec3 = CreateOutRec();
+ outRec3->Pts = j->OutPt1;
+ UpdateOutPtIdxs(*outRec1);
+ UpdateOutPtIdxs(*outRec3);
+ outRec3->FirstLeft = outRec1->FirstLeft;
+ //fixup FirstLeft pointers that may need reassigning to OutRec3
+ if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec3);
+ }
+ else
+ {
+ outRec2->Pts = j->OutPt1;
+ outRec2->BottomPt = 0;
+ outRec1->Pts = 0;
+ outRec1->BottomPt = 0;
+ outRec1->Idx = outRec2->Idx;
+ outRec1->FirstLeft = outRec2;
+ outRec1->IsHole = outRec2->IsHole;
+ if (m_UsingPolyTree) FixupFirstLefts3(outRec1, outRec2);
+ OutRec * outRec3 = CreateOutRec();
+ outRec3->Pts = j->OutPt2;
+ UpdateOutPtIdxs(*outRec2);
+ UpdateOutPtIdxs(*outRec3);
+ outRec3->FirstLeft = outRec2->FirstLeft;
+ //fixup FirstLeft pointers that may need reassigning to OutRec3
+ if (m_UsingPolyTree) FixupFirstLefts1(outRec2, outRec3);
+ }
+ return false;
+ }
+ return false;
+ }
//Strictly Simple join ...
- if (outRec1 != outRec2) return false;
op1b = j->OutPt1->Next;
while (op1b != op1 && (op1b->Pt == j->OffPt))
op1b = op1b->Next;
@@ -3492,6 +3910,7 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
op2b->Prev = op1b;
j->OutPt1 = op1;
j->OutPt2 = op1b;
+ AddSSJoin(op1, op1b, j->OffPt);
return true;
} else
{
@@ -3503,6 +3922,7 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
op2b->Next = op1b;
j->OutPt1 = op1;
j->OutPt2 = op1b;
+ AddSSJoin(op1, op1b, j->OffPt);
return true;
}
}
@@ -3760,6 +4180,7 @@ void Clipper::JoinCommonEdges()
if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1);
}
}
+ ClearSSJoins();
}
//------------------------------------------------------------------------------
diff --git a/debian/clipper.hpp b/debian/clipper.hpp
index 7831b0b..d0845fe 100644
--- a/debian/clipper.hpp
+++ b/debian/clipper.hpp
@@ -320,6 +320,7 @@ protected:
private:
JoinList m_Joins;
JoinList m_GhostJoins;
+ JoinList m_SSJoins;
IntersectList m_IntersectList;
ClipType m_ClipType;
typedef std::list<cInt> MaximaList;
@@ -373,7 +374,9 @@ private:
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
void ClearJoins();
void ClearGhostJoins();
+ void ClearSSJoins();
void AddGhostJoin(OutPt *op, const IntPoint offPt);
+ void AddSSJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
void JoinCommonEdges();
void DoSimplePolygons();
--
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