Update Clipper to r468. #2028

master
Alessandro Ranellucci 2014-05-26 17:21:31 +02:00
parent b02e459c4b
commit 6a6439576b
3 changed files with 102 additions and 99 deletions

View File

@ -2,7 +2,7 @@
* *
* Author : Angus Johnson *
* Version : 6.1.5 *
* Date : 22 May 2014 *
* Date : 26 May 2014 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2014 *
* *
@ -898,112 +898,38 @@ TEdge* FindNextLocMin(TEdge* E)
}
//------------------------------------------------------------------------------
TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise)
TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward)
{
TEdge *EStart = E, *Result = E;
TEdge *Result = E;
TEdge *Horz = 0;
cInt StartX;
if (IsHorizontal(*E))
{
//first we need to be careful here with open paths because this
//may not be a true local minima (ie may be following a skip edge).
//also, watch for adjacent horz edges to start heading left
//before finishing right ...
if (IsClockwise)
{
if (E->Prev->Bot.Y == E->Bot.Y) StartX = E->Prev->Bot.X;
else StartX = E->Prev->Top.X;
}
else
{
if (E->Next->Bot.Y == E->Bot.Y) StartX = E->Next->Bot.X;
else StartX = E->Next->Top.X;
}
if (E->Bot.X != StartX) ReverseHorizontal(*E);
}
if (Result->OutIdx != Skip)
{
if (IsClockwise)
{
while (Result->Top.Y == Result->Next->Bot.Y && Result->Next->OutIdx != Skip)
Result = Result->Next;
if (IsHorizontal(*Result) && Result->Next->OutIdx != Skip)
{
//nb: at the top of a bound, horizontals are added to the bound
//only when the preceding edge attaches to the horizontal's left vertex
//unless a Skip edge is encountered when that becomes the top divide
Horz = Result;
while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev;
if (Horz->Prev->Top.X == Result->Next->Top.X)
{
if (!IsClockwise) Result = Horz->Prev;
}
else if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev;
}
while (E != Result)
{
E->NextInLML = E->Next;
if (IsHorizontal(*E) && E != EStart &&
E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
E = E->Next;
}
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X)
ReverseHorizontal(*E);
Result = Result->Next; //move to the edge just beyond current bound
} else
{
while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip)
Result = Result->Prev;
if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip)
{
Horz = Result;
while (IsHorizontal(*Horz->Next)) Horz = Horz->Next;
if (Horz->Next->Top.X == Result->Prev->Top.X)
{
if (!IsClockwise) Result = Horz->Next;
}
else if (Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next;
}
while (E != Result)
{
E->NextInLML = E->Prev;
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E);
E = E->Prev;
}
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E);
Result = Result->Prev; //move to the edge just beyond current bound
}
}
if (Result->OutIdx == Skip)
if (E->OutIdx == Skip)
{
//if edges still remain in the current bound beyond the skip edge then
//create another LocMin and call ProcessBound once more
E = Result;
if (IsClockwise)
if (NextIsForward)
{
while (E->Top.Y == E->Next->Bot.Y) E = E->Next;
//don't include top horizontals when parsing a bound a second time,
//they will be contained in the opposite bound ...
while (E != Result && IsHorizontal(*E)) E = E->Prev;
} else
}
else
{
while (E->Top.Y == E->Prev->Bot.Y) E = E->Prev;
while (E != Result && IsHorizontal(*E)) E = E->Next;
}
if (E == Result)
{
if (IsClockwise) Result = E->Next;
if (NextIsForward) Result = E->Next;
else Result = E->Prev;
} else
}
else
{
//there are more edges in the bound beyond result starting with E
if (IsClockwise)
E = Result->Next;
if (NextIsForward)
E = Result->Next;
else
E = Result->Prev;
LocalMinima* locMin = new LocalMinima;
@ -1011,11 +937,88 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool IsClockwise)
locMin->Y = E->Bot.Y;
locMin->LeftBound = 0;
locMin->RightBound = E;
locMin->RightBound->WindDelta = 0;
Result = ProcessBound(locMin->RightBound, IsClockwise);
E->WindDelta = 0;
Result = ProcessBound(E, NextIsForward);
InsertLocalMinima(locMin);
}
return Result;
}
TEdge *EStart;
if (IsHorizontal(*E))
{
//We need to be careful with open paths because this may not be a
//true local minima (ie E may be following a skip edge).
//Also, consecutive horz. edges may start heading left before going right.
if (NextIsForward)
EStart = E->Prev;
else
EStart = E->Next;
if (IsHorizontal(*EStart)) //ie an adjoining horizontal skip edge
{
if (EStart->Bot.X != E->Bot.X && EStart->Top.X != E->Bot.X)
ReverseHorizontal(*E);
}
else if (EStart->Bot.X != E->Bot.X)
ReverseHorizontal(*E);
}
EStart = E;
if (NextIsForward)
{
while (Result->Top.Y == Result->Next->Bot.Y && Result->Next->OutIdx != Skip)
Result = Result->Next;
if (IsHorizontal(*Result) && Result->Next->OutIdx != Skip)
{
//nb: at the top of a bound, horizontals are added to the bound
//only when the preceding edge attaches to the horizontal's left vertex
//unless a Skip edge is encountered when that becomes the top divide
Horz = Result;
while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev;
if (Horz->Prev->Top.X == Result->Next->Top.X)
{
if (!NextIsForward) Result = Horz->Prev;
}
else if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev;
}
while (E != Result)
{
E->NextInLML = E->Next;
if (IsHorizontal(*E) && E != EStart &&
E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
E = E->Next;
}
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X)
ReverseHorizontal(*E);
Result = Result->Next; //move to the edge just beyond current bound
} else
{
while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip)
Result = Result->Prev;
if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip)
{
Horz = Result;
while (IsHorizontal(*Horz->Next)) Horz = Horz->Next;
if (Horz->Next->Top.X == Result->Prev->Top.X)
{
if (!NextIsForward) Result = Horz->Next;
}
else if (Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next;
}
while (E != Result)
{
E->NextInLML = E->Prev;
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E);
E = E->Prev;
}
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E);
Result = Result->Prev; //move to the edge just beyond current bound
}
return Result;
}
//------------------------------------------------------------------------------
@ -1148,7 +1151,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
}
m_edges.push_back(edges);
bool clockwise;
bool leftBoundIsForward;
TEdge* EMin = 0;
//workaround to avoid an endless loop in the while loop below when
@ -1170,12 +1173,12 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
{
locMin->LeftBound = E->Prev;
locMin->RightBound = E;
clockwise = false; //Q.nextInLML = Q.prev
leftBoundIsForward = false; //Q.nextInLML = Q.prev
} else
{
locMin->LeftBound = E;
locMin->RightBound = E->Prev;
clockwise = true; //Q.nextInLML = Q.next
leftBoundIsForward = true; //Q.nextInLML = Q.next
}
locMin->LeftBound->Side = esLeft;
locMin->RightBound->Side = esRight;
@ -1186,15 +1189,15 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
else locMin->LeftBound->WindDelta = 1;
locMin->RightBound->WindDelta = -locMin->LeftBound->WindDelta;
E = ProcessBound(locMin->LeftBound, clockwise);
TEdge* E2 = ProcessBound(locMin->RightBound, !clockwise);
E = ProcessBound(locMin->LeftBound, leftBoundIsForward);
TEdge* E2 = ProcessBound(locMin->RightBound, !leftBoundIsForward);
if (locMin->LeftBound->OutIdx == Skip)
locMin->LeftBound = 0;
else if (locMin->RightBound->OutIdx == Skip)
locMin->RightBound = 0;
InsertLocalMinima(locMin);
if (!clockwise) E = E2;
if (!leftBoundIsForward) E = E2;
}
return true;
}

View File

@ -2,7 +2,7 @@
* *
* Author : Angus Johnson *
* Version : 6.1.5 *
* Date : 22 May 2014 *
* Date : 24 May 2014 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2014 *
* *

View File

@ -4,7 +4,7 @@ use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 18;
use Test::More tests => 19;
my $square = Slic3r::Polygon->new( # ccw
[200, 100],
@ -155,8 +155,8 @@ if (0) { # Clipper does not preserve polyline orientation
}
}
# Disabled until Clipper bug #96 (our issue #2028) is fixed
if (0) {
# Clipper bug #96 (our GH #2028)
{
my $subject = Slic3r::Polyline->new(
[44735000,31936670],[55270000,31936670],[55270000,25270000],[74730000,25270000],[74730000,44730000],[68063296,44730000],[68063296,55270000],[74730000,55270000],[74730000,74730000],[55270000,74730000],[55270000,68063296],[44730000,68063296],[44730000,74730000],[25270000,74730000],[25270000,55270000],[31936670,55270000],[31936670,44730000],[25270000,44730000],[25270000,25270000],[44730000,25270000],[44730000,31936670]
);