Upgrade Clipper to 68c49e9a9a

This commit is contained in:
Eric Fischer 2016-04-07 13:52:39 -07:00
parent 1e6332bae8
commit 64faa1d79e
8 changed files with 171 additions and 125 deletions

View File

@ -3144,7 +3144,14 @@ void Clipper::ProcessIntersectList()
bool IntersectListSort(IntersectNode* node1, IntersectNode* node2) bool IntersectListSort(IntersectNode* node1, IntersectNode* node2)
{ {
return node2->Pt.Y < node1->Pt.Y; if (node2->Pt.Y != node1->Pt.Y)
{
return node2->Pt.Y < node1->Pt.Y;
}
else
{
return (node2->Edge1->WindCnt2 + node2->Edge2->WindCnt2) > (node1->Edge1->WindCnt2 + node1->Edge2->WindCnt2);
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -3287,6 +3294,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
{ {
m_Maxima.push_back(e->Top.X); m_Maxima.push_back(e->Top.X);
m_Maxima.push_back(e->Bot.X); m_Maxima.push_back(e->Bot.X);
next_maxima.push_back(e->Bot.X);
} }
} }
AddEdgeToSEL(e); AddEdgeToSEL(e);
@ -3299,19 +3307,23 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
//When StrictlySimple and 'e' is being touched by another edge, then //When StrictlySimple and 'e' is being touched by another edge, then
//make sure both edges have a vertex here ... //make sure both edges have a vertex here ...
if (m_StrictSimple) if (m_StrictSimple && e->OutIdx >= 0 && e->WindDelta != 0)
{ {
TEdge* ePrev = e->PrevInAEL; TEdge* ePrev = e->PrevInAEL;
if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) && while (ePrev && ePrev->Curr.X == e->Curr.X)
(ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0))
{ {
IntPoint pt = e->Curr; if (ePrev->OutIdx >= 0 && ePrev->WindDelta != 0 &&
!(e->Bot == ePrev->Bot && e->Top == ePrev->Top))
{
IntPoint pt = e->Curr;
#ifdef use_xyz #ifdef use_xyz
SetZ(pt, *ePrev, *e); SetZ(pt, *ePrev, *e);
#endif #endif
OutPt* op = AddOutPt(ePrev, pt); OutPt* op = AddOutPt(ePrev, pt);
OutPt* op2 = AddOutPt(e, pt); OutPt* op2 = AddOutPt(e, pt);
AddJoin(op, op2, pt); //StrictlySimple (type-3) join AddJoin(op, op2, pt); //StrictlySimple (type-3) join
}
ePrev = ePrev->PrevInAEL;
} }
} }
@ -3933,7 +3945,14 @@ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
if (outRec->Pts && firstLeft == OldOutRec) if (outRec->Pts && firstLeft == OldOutRec)
{ {
if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts)) if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts))
{
if (outRec->IsHole == NewOutRec->IsHole)
{
outRec->IsHole = !outRec->IsHole;
ReversePolyPtLinks(outRec->Pts);
}
outRec->FirstLeft = NewOutRec; outRec->FirstLeft = NewOutRec;
}
} }
} }
} }
@ -3945,7 +3964,6 @@ void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec)
//It's possible that these polygons now wrap around other polygons, so check //It's possible that these polygons now wrap around other polygons, so check
//every polygon that's also contained by OuterOutRec's FirstLeft container //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 ... //(including 0) to see if they've become inner to the new inner polygon ...
OutRec* orfl = ParseFirstLeft(OuterOutRec->FirstLeft);
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];
@ -3953,14 +3971,28 @@ void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec)
if (!outRec->Pts || outRec == OuterOutRec || outRec == InnerOutRec) if (!outRec->Pts || outRec == OuterOutRec || outRec == InnerOutRec)
continue; continue;
OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft); OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
if (firstLeft != orfl && firstLeft != InnerOutRec && firstLeft != OuterOutRec) if (firstLeft != InnerOutRec && firstLeft != OuterOutRec)
continue; continue;
if (Poly2ContainsPoly1(outRec->Pts, InnerOutRec->Pts)) if (Poly2ContainsPoly1(outRec->Pts, InnerOutRec->Pts))
outRec->FirstLeft = InnerOutRec; {
else if (Poly2ContainsPoly1(outRec->Pts, OuterOutRec->Pts)) if (outRec->IsHole == InnerOutRec->IsHole)
outRec->FirstLeft = OuterOutRec; {
else if (firstLeft == InnerOutRec || firstLeft == OuterOutRec) outRec->IsHole = !outRec->IsHole;
outRec->FirstLeft = orfl; ReversePolyPtLinks(outRec->Pts);
}
outRec->FirstLeft = InnerOutRec;
}
else
{
if (outRec->IsHole == OuterOutRec->IsHole)
{
outRec->FirstLeft = ParseFirstLeft(OuterOutRec->FirstLeft);
}
else
{
outRec->FirstLeft = OuterOutRec;
}
}
} }
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -4004,10 +4036,18 @@ void Clipper::JoinCommonEdges()
{ {
//instead of joining two polygons, we've just created a new one by //instead of joining two polygons, we've just created a new one by
//splitting one polygon into two. //splitting one polygon into two.
outRec1->Pts = join->OutPt1;
outRec1->BottomPt = 0; outRec1->BottomPt = 0;
outRec2 = CreateOutRec(); outRec2 = CreateOutRec();
outRec2->Pts = join->OutPt2; if (PointCount(join->OutPt1) > PointCount(join->OutPt2))
{
outRec1->Pts = join->OutPt1;
outRec2->Pts = join->OutPt2;
}
else
{
outRec1->Pts = join->OutPt2;
outRec2->Pts = join->OutPt1;
}
//update all OutRec2.Pts Idx's ... //update all OutRec2.Pts Idx's ...
UpdateOutPtIdxs(*outRec2); UpdateOutPtIdxs(*outRec2);
@ -4635,7 +4675,6 @@ bool Clipper::FixIntersects(std::unordered_multimap<int, OutPtIntersect> & dupeR
{ {
outRec_origin = outRec_k; outRec_origin = outRec_k;
outRec_parent = outRec_origin; outRec_parent = outRec_origin;
outRec_search = outRec_k;
outRec_search = outRec_j; outRec_search = outRec_j;
op_origin_1 = op_k; op_origin_1 = op_k;
op_origin_2 = op_j; op_origin_2 = op_j;
@ -4647,7 +4686,6 @@ bool Clipper::FixIntersects(std::unordered_multimap<int, OutPtIntersect> & dupeR
outRec_origin = outRec_j; outRec_origin = outRec_j;
outRec_parent = ParseFirstLeft(outRec_origin->FirstLeft); outRec_parent = ParseFirstLeft(outRec_origin->FirstLeft);
outRec_search = outRec_k; outRec_search = outRec_k;
outRec_search = outRec_k;
op_origin_1 = op_j; op_origin_1 = op_j;
op_origin_2 = op_k; op_origin_2 = op_k;
} }
@ -4967,9 +5005,17 @@ void Clipper::DoSimplePolygons()
op2->Prev = op3; op2->Prev = op3;
op3->Next = op2; op3->Next = op2;
outrec->Pts = op;
OutRec* outrec2 = CreateOutRec(); OutRec* outrec2 = CreateOutRec();
outrec2->Pts = op2; if (PointCount(op) > PointCount(op2))
{
outrec->Pts = op;
outrec2->Pts = op2;
}
else
{
outrec->Pts = op2;
outrec2->Pts = op;
}
UpdateOutPtIdxs(*outrec); UpdateOutPtIdxs(*outrec);
UpdateOutPtIdxs(*outrec2); UpdateOutPtIdxs(*outrec2);
if (Poly2ContainsPoly1(outrec2->Pts, outrec->Pts)) if (Poly2ContainsPoly1(outrec2->Pts, outrec->Pts))
@ -5031,9 +5077,9 @@ void Clipper::DoSimplePolygons()
} }
if (!outrec->IsHole) if (!outrec->IsHole)
{ {
OutPtIntersect intPt1 = { op, op2 }; OutPtIntersect intPt1 = { outrec->Pts, outrec2->Pts };
OutPtIntersect intPt2 = { op2, op }; OutPtIntersect intPt2 = { outrec2->Pts, outrec->Pts };
dupeRec.emplace(idx_j, intPt1); dupeRec.emplace(outrec->Idx, intPt1);
dupeRec.emplace(outrec2->Idx, intPt2); dupeRec.emplace(outrec2->Idx, intPt2);
} }
} }
@ -5098,9 +5144,9 @@ void Clipper::DoSimplePolygons()
} }
if (!outrec2->IsHole) if (!outrec2->IsHole)
{ {
OutPtIntersect intPt1 = { op, op2 }; OutPtIntersect intPt1 = { outrec->Pts, outrec2->Pts };
OutPtIntersect intPt2 = { op2, op }; OutPtIntersect intPt2 = { outrec2->Pts, outrec->Pts };
dupeRec.emplace(idx_j, intPt1); dupeRec.emplace(outrec->Idx, intPt1);
dupeRec.emplace(outrec2->Idx, intPt2); dupeRec.emplace(outrec2->Idx, intPt2);
} }
} }
@ -5163,9 +5209,9 @@ void Clipper::DoSimplePolygons()
} }
if (outrec2->IsHole) if (outrec2->IsHole)
{ {
OutPtIntersect intPt1 = { op, op2 }; OutPtIntersect intPt1 = { outrec->Pts, outrec2->Pts };
OutPtIntersect intPt2 = { op2, op }; OutPtIntersect intPt2 = { outrec2->Pts, outrec->Pts };
dupeRec.emplace(idx_j, intPt1); dupeRec.emplace(outrec->Idx, intPt1);
dupeRec.emplace(outrec2->Idx, intPt2); dupeRec.emplace(outrec2->Idx, intPt2);
} }
} }

View File

@ -12,7 +12,7 @@
}, "features": [ }, "features": [
{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [ { "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "in" }, "features": [ { "type": "FeatureCollection", "properties": { "layer": "in" }, "features": [
{ "type": "Feature", "properties": { "boolean": true, "otherboolean": false, "stringify": "[\"yes\",27.00000000,27,1.4e27,{\"foo\":\"bar\"}]", "escape": "foo\u0001bar,ü\"\\/\u0008\u000c\u000a\u000d\u0009→", "prêt": "ready" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 186.943359, 35.460670 ], [ 179.912109, 36.527295 ], [ 175.781250, 37.160317 ], [ 161.718750, 45.336702 ], [ 156.796875, 55.028022 ], [ 163.476562, 62.431074 ], [ 170.507812, 64.811557 ], [ 177.539062, 67.339861 ], [ 179.912109, 67.542167 ], [ 186.943359, 68.007571 ], [ 186.943359, 63.743631 ], [ 182.109375, 62.593341 ], [ 179.912109, 61.689872 ], [ 174.023438, 58.859224 ], [ 171.562500, 54.418930 ], [ 174.023438, 47.279229 ], [ 179.912109, 45.274886 ], [ 182.460938, 44.339565 ], [ 186.943359, 44.024422 ], [ 186.943359, 35.460670 ] ] ], [ [ [ -177.539062, 44.339565 ], [ -164.882812, 43.389082 ], [ -153.281250, 46.619261 ], [ -144.492188, 51.179343 ], [ -143.789062, 57.183902 ], [ -148.007812, 61.100789 ], [ -158.554688, 63.860036 ], [ -169.453125, 64.510643 ], [ -177.890625, 62.593341 ], [ -180.000000, 61.689872 ], [ -185.976562, 58.859224 ], [ -187.031250, 56.992883 ], [ -187.031250, 65.730626 ], [ -182.460938, 67.339861 ], [ -180.000000, 67.542167 ], [ -169.101562, 68.269387 ], [ -156.093750, 68.138852 ], [ -144.492188, 66.089364 ], [ -134.648438, 62.431074 ], [ -131.835938, 55.379110 ], [ -133.593750, 48.690960 ], [ -146.250000, 38.616870 ], [ -169.453125, 34.957995 ], [ -180.000000, 36.527295 ], [ -184.218750, 37.160317 ], [ -187.031250, 38.891033 ], [ -187.031250, 50.457504 ], [ -185.976562, 47.279229 ], [ -177.539062, 44.339565 ] ] ] ] } } { "type": "Feature", "properties": { "boolean": true, "otherboolean": false, "stringify": "[\"yes\",27.00000000,27,1.4e27,{\"foo\":\"bar\"}]", "escape": "foo\u0001bar,ü\"\\/\u0008\u000c\u000a\u000d\u0009→", "prêt": "ready" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -177.539062, 44.339565 ], [ -164.882812, 43.389082 ], [ -153.281250, 46.619261 ], [ -144.492188, 51.179343 ], [ -143.789062, 57.183902 ], [ -148.007812, 61.100789 ], [ -158.554688, 63.860036 ], [ -169.453125, 64.510643 ], [ -177.890625, 62.593341 ], [ -180.000000, 61.689872 ], [ -185.976562, 58.859224 ], [ -187.031250, 56.992883 ], [ -187.031250, 65.730626 ], [ -182.460938, 67.339861 ], [ -180.000000, 67.542167 ], [ -169.101562, 68.269387 ], [ -156.093750, 68.138852 ], [ -144.492188, 66.089364 ], [ -134.648438, 62.431074 ], [ -131.835938, 55.379110 ], [ -133.593750, 48.690960 ], [ -146.250000, 38.616870 ], [ -169.453125, 34.957995 ], [ -180.000000, 36.527295 ], [ -184.218750, 37.160317 ], [ -187.031250, 38.891033 ], [ -187.031250, 50.457504 ], [ -185.976562, 47.279229 ], [ -177.539062, 44.339565 ] ], [ [ 186.943359, 35.460670 ], [ 179.912109, 36.527295 ], [ 175.781250, 37.160317 ], [ 161.718750, 45.336702 ], [ 156.796875, 55.028022 ], [ 163.476562, 62.431074 ], [ 170.507812, 64.811557 ], [ 177.539062, 67.339861 ], [ 179.912109, 67.542167 ], [ 186.943359, 68.007571 ], [ 186.943359, 63.743631 ], [ 182.109375, 62.593341 ], [ 179.912109, 61.689872 ], [ 174.023438, 58.859224 ], [ 171.562500, 54.418930 ], [ 174.023438, 47.279229 ], [ 179.912109, 45.274886 ], [ 182.460938, 44.339565 ], [ 186.943359, 44.024422 ], [ 186.943359, 35.460670 ] ] ] } }
, ,
{ "type": "Feature", "properties": { "zoom": "z0-2" }, "geometry": { "type": "LineString", "coordinates": [ [ -112.851562, 55.178868 ], [ -117.773438, 44.590467 ], [ -104.414062, 51.179343 ] ] } } { "type": "Feature", "properties": { "zoom": "z0-2" }, "geometry": { "type": "LineString", "coordinates": [ [ -112.851562, 55.178868 ], [ -117.773438, 44.590467 ], [ -104.414062, 51.179343 ] ] } }
] } ] }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long