Update Clipper to 6.1.3a

This commit is contained in:
Alessandro Ranellucci 2014-03-23 21:40:35 +01:00
parent 5d3c8575c5
commit e9620c30b1
2 changed files with 104 additions and 37 deletions

View File

@ -1,10 +1,10 @@
/******************************************************************************* /*******************************************************************************
* * * *
* Author : Angus Johnson * * Author : Angus Johnson *
* Version : 6.1.2 * * Version : 6.1.3a *
* Date : 15 December 2013 * * Date : 22 January 2014 *
* Website : http://www.angusj.com * * Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2013 * * Copyright : Angus Johnson 2010-2014 *
* * * *
* License: * * License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. * * Use, modification & distribution is subject to Boost Software License Ver 1. *
@ -491,7 +491,52 @@ bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int PointInPolygon (const IntPoint& pt, OutPt* op) int PointInPolygon (const IntPoint &pt, const Path &path)
{
//returns 0 if false, +1 if true, -1 if pt ON polygon boundary
//http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf
int result = 0;
size_t cnt = path.size();
if (cnt < 3) return 0;
IntPoint ip = path[0];
for(size_t i = 1; i <= cnt; ++i)
{
IntPoint ipNext = (i == cnt ? path[0] : path[i]);
if (ipNext.Y == pt.Y)
{
if ((ipNext.X == pt.X) || (ip.Y == pt.Y &&
((ipNext.X > pt.X) == (ip.X < pt.X)))) return -1;
}
if ((ip.Y < pt.Y) != (ipNext.Y < pt.Y))
{
if (ip.X >= pt.X)
{
if (ipNext.X > pt.X) result = 1 - result;
else
{
double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) -
(double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
}
} else
{
if (ipNext.X > pt.X)
{
double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) -
(double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
}
}
}
ip = ipNext;
}
return result;
}
//------------------------------------------------------------------------------
int PointInPolygon (const IntPoint &pt, OutPt *op)
{ {
//returns 0 if false, +1 if true, -1 if pt ON polygon boundary //returns 0 if false, +1 if true, -1 if pt ON polygon boundary
//http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf //http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf
@ -534,7 +579,7 @@ int PointInPolygon (const IntPoint& pt, OutPt* op)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool Poly2ContainsPoly1(OutPt* OutPt1, OutPt* OutPt2) bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2)
{ {
OutPt* op = OutPt1; OutPt* op = OutPt1;
do do
@ -1126,11 +1171,9 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
catch(...) catch(...)
{ {
delete [] edges; delete [] edges;
return false; //almost certainly a vertex has exceeded range throw; //range test fails
} }
TEdge *eStart = &edges[0]; TEdge *eStart = &edges[0];
if (!Closed) eStart->Prev->OutIdx = Skip;
//2. Remove duplicate vertices, and (when closed) collinear edges ... //2. Remove duplicate vertices, and (when closed) collinear edges ...
TEdge *E = eStart, *eLoopStop = eStart; TEdge *E = eStart, *eLoopStop = eStart;
@ -1171,7 +1214,11 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
return false; return false;
} }
if (!Closed) m_HasOpenPaths = true; if (!Closed)
{
m_HasOpenPaths = true;
eStart->Prev->OutIdx = Skip;
}
//3. Do second stage of edge initialization ... //3. Do second stage of edge initialization ...
E = eStart; E = eStart;
@ -1431,21 +1478,12 @@ void Clipper::ZFillFunction(TZFillCallback zFillFunc)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#endif #endif
void Clipper::Clear()
{
if (m_edges.empty()) return; //avoids problems with ClipperBase destructor
DisposeAllOutRecs();
ClipperBase::Clear();
}
//------------------------------------------------------------------------------
void Clipper::Reset() void Clipper::Reset()
{ {
ClipperBase::Reset(); ClipperBase::Reset();
m_Scanbeam.clear(); m_Scanbeam.clear();
m_ActiveEdges = 0; m_ActiveEdges = 0;
m_SortedEdges = 0; m_SortedEdges = 0;
DisposeAllOutRecs();
LocalMinima* lm = m_MinimaList; LocalMinima* lm = m_MinimaList;
while (lm) while (lm)
{ {
@ -1469,6 +1507,7 @@ bool Clipper::Execute(ClipType clipType, Paths &solution,
m_UsingPolyTree = false; m_UsingPolyTree = false;
bool succeeded = ExecuteInternal(); bool succeeded = ExecuteInternal();
if (succeeded) BuildResult(solution); if (succeeded) BuildResult(solution);
DisposeAllOutRecs();
m_ExecuteLocked = false; m_ExecuteLocked = false;
return succeeded; return succeeded;
} }
@ -1485,6 +1524,7 @@ bool Clipper::Execute(ClipType clipType, PolyTree& polytree,
m_UsingPolyTree = true; m_UsingPolyTree = true;
bool succeeded = ExecuteInternal(); bool succeeded = ExecuteInternal();
if (succeeded) BuildResult2(polytree); if (succeeded) BuildResult2(polytree);
DisposeAllOutRecs();
m_ExecuteLocked = false; m_ExecuteLocked = false;
return succeeded; return succeeded;
} }
@ -2674,12 +2714,13 @@ void Clipper::PrepareHorzJoins(TEdge* horzEdge, bool isTopOfScanbeam)
//First, match up overlapping horizontal edges (eg when one polygon's //First, match up overlapping horizontal edges (eg when one polygon's
//intermediate horz edge overlaps an intermediate horz edge of another, or //intermediate horz edge overlaps an intermediate horz edge of another, or
//when one polygon sits on top of another) ... //when one polygon sits on top of another) ...
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i) //for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
{ //{
Join* j = m_GhostJoins[i]; // Join* j = m_GhostJoins[i];
if (HorzSegmentsOverlap(j->OutPt1->Pt, j->OffPt, horzEdge->Bot, horzEdge->Top)) // if (HorzSegmentsOverlap(j->OutPt1->Pt, j->OffPt, horzEdge->Bot, horzEdge->Top))
AddJoin(j->OutPt1, outPt, j->OffPt); // AddJoin(j->OutPt1, outPt, j->OffPt);
} //}
//Also, since horizontal edges at the top of one SB are often removed from //Also, since horizontal edges at the top of one SB are often removed from
//the AEL before we process the horizontal edges at the bottom of the next, //the AEL before we process the horizontal edges at the bottom of the next,
//we need to create 'ghost' Join records of 'contrubuting' horizontals that //we need to create 'ghost' Join records of 'contrubuting' horizontals that
@ -4255,6 +4296,15 @@ void ReversePaths(Paths& p)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType)
{
Clipper c;
c.StrictlySimple(true);
c.AddPath(in_poly, ptSubject, true);
c.Execute(ctUnion, out_polys, fillType, fillType);
}
//------------------------------------------------------------------------------
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType) void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType)
{ {
Clipper c; Clipper c;
@ -4428,8 +4478,8 @@ void Minkowski(const Path& poly, const Path& path,
Paths quads; Paths quads;
quads.reserve((pathCnt + delta) * (polyCnt + 1)); quads.reserve((pathCnt + delta) * (polyCnt + 1));
for (size_t i = 0; i <= pathCnt - 2 + delta; ++i) for (size_t i = 0; i < pathCnt - 1 + delta; ++i)
for (size_t j = 0; j <= polyCnt - 1; ++j) for (size_t j = 0; j < polyCnt; ++j)
{ {
Path quad; Path quad;
quad.reserve(4); quad.reserve(4);
@ -4447,15 +4497,30 @@ void Minkowski(const Path& poly, const Path& path,
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void MinkowskiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed) void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed)
{ {
Minkowski(poly, path, solution, true, isClosed); Minkowski(pattern, path, solution, true, pathIsClosed);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void MinkowskiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed) void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution,
PolyFillType pathFillType, bool pathIsClosed)
{ {
Minkowski(poly, path, solution, false, isClosed); Clipper c;
for (size_t i = 0; i < paths.size(); ++i)
{
Paths tmp;
Minkowski(pattern, paths[i], tmp, true, pathIsClosed);
c.AddPaths(tmp, ptSubject, true);
}
if (pathIsClosed) c.AddPaths(paths, ptClip, true);
c.Execute(ctUnion, solution, pathFillType, pathFillType);
}
//------------------------------------------------------------------------------
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution)
{
Minkowski(poly1, poly2, solution, false, true);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -1,10 +1,10 @@
/******************************************************************************* /*******************************************************************************
* * * *
* Author : Angus Johnson * * Author : Angus Johnson *
* Version : 6.1.2 * * Version : 6.1.3a *
* Date : 15 December 2013 * * Date : 22 January 2014 *
* Website : http://www.angusj.com * * Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2013 * * Copyright : Angus Johnson 2010-2014 *
* * * *
* License: * * License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. * * Use, modification & distribution is subject to Boost Software License Ver 1. *
@ -34,7 +34,7 @@
#ifndef clipper_hpp #ifndef clipper_hpp
#define clipper_hpp #define clipper_hpp
#define CLIPPER_VERSION "6.1.2" #define CLIPPER_VERSION "6.1.3"
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This //use_int32: When enabled 32bit ints are used instead of 64bit ints. This
//improve performance but coordinate values are limited to the range +/- 46340 //improve performance but coordinate values are limited to the range +/- 46340
@ -166,6 +166,7 @@ private:
bool Orientation(const Path &poly); bool Orientation(const Path &poly);
double Area(const Path &poly); double Area(const Path &poly);
int PointInPolygon(const IntPoint &pt, const Path &path);
#ifdef use_deprecated #ifdef use_deprecated
void OffsetPaths(const Paths &in_polys, Paths &out_polys, void OffsetPaths(const Paths &in_polys, Paths &out_polys,
@ -181,8 +182,10 @@ void CleanPolygon(Path& poly, double distance = 1.415);
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415); void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
void CleanPolygons(Paths& polys, double distance = 1.415); void CleanPolygons(Paths& polys, double distance = 1.415);
void MinkowskiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed); void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
void MinkowskiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed); void MinkowskiSum(const Path& pattern, const Paths& paths,
Paths& solution, PolyFillType pathFillType, bool pathIsClosed);
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths); void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths); void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
@ -259,7 +262,6 @@ public:
PolyTree &polytree, PolyTree &polytree,
PolyFillType subjFillType = pftEvenOdd, PolyFillType subjFillType = pftEvenOdd,
PolyFillType clipFillType = pftEvenOdd); PolyFillType clipFillType = pftEvenOdd);
void Clear();
bool ReverseSolution() {return m_ReverseOutput;}; bool ReverseSolution() {return m_ReverseOutput;};
void ReverseSolution(bool value) {m_ReverseOutput = value;}; void ReverseSolution(bool value) {m_ReverseOutput = value;};
bool StrictlySimple() {return m_StrictSimple;}; bool StrictlySimple() {return m_StrictSimple;};