Update Clipper to 6.1.2
This commit is contained in:
parent
1a690589a8
commit
bd133d9434
@ -932,7 +932,7 @@ sub write_gcode {
|
||||
# append full config
|
||||
print $fh "\n";
|
||||
foreach my $opt_key (sort @{$self->config->get_keys}) {
|
||||
next if @{$Slic3r::Config::Options->{$opt_key}{shortcut}};
|
||||
next if $Slic3r::Config::Options->{$opt_key}{shortcut};
|
||||
printf $fh "; %s = %s\n", $opt_key, $self->config->serialize($opt_key);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ BEGIN {
|
||||
use lib "$FindBin::Bin/../lib";
|
||||
}
|
||||
|
||||
use List::Util qw(sum);
|
||||
use Slic3r;
|
||||
use Slic3r::Geometry::Clipper qw(intersection_ex union_ex diff_ex);
|
||||
|
||||
@ -33,7 +34,7 @@ use Slic3r::Geometry::Clipper qw(intersection_ex union_ex diff_ex);
|
||||
];
|
||||
my $intersection = intersection_ex([ $square, $hole_in_square ], [ $square2 ]);
|
||||
|
||||
is_deeply [ map $_->pp, @$intersection ], [[
|
||||
is sum(map $_->area, @$intersection), Slic3r::ExPolygon->new(
|
||||
[
|
||||
[20, 18],
|
||||
[10, 18],
|
||||
@ -46,7 +47,7 @@ use Slic3r::Geometry::Clipper qw(intersection_ex union_ex diff_ex);
|
||||
[16, 14],
|
||||
[14, 14],
|
||||
],
|
||||
]], 'hole is preserved after intersection';
|
||||
)->area, 'hole is preserved after intersection';
|
||||
}
|
||||
|
||||
#==========================================================
|
||||
@ -62,7 +63,8 @@ use Slic3r::Geometry::Clipper qw(intersection_ex union_ex diff_ex);
|
||||
'union of two ccw and one cw is a contour with no holes';
|
||||
|
||||
my $diff = diff_ex([ $contour1, $contour2 ], [ $hole ]);
|
||||
is_deeply [ map $_->pp, @$diff ], [[ [ [40,40], [0,40], [0,0], [40,0] ], [ [15,25], [25,25], [25,15], [15,15] ] ]],
|
||||
is sum(map $_->area, @$diff),
|
||||
Slic3r::ExPolygon->new([ [40,40], [0,40], [0,0], [40,0] ], [ [15,25], [25,25], [25,15], [15,15] ])->area,
|
||||
'difference of a cw from two ccw is a contour with one hole';
|
||||
}
|
||||
|
||||
|
@ -106,15 +106,21 @@ offset(const Slic3r::Polygons &polygons, ClipperLib::Paths &retval, const float
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// read input
|
||||
ClipperLib::Paths* input = new ClipperLib::Paths();
|
||||
Slic3rMultiPoints_to_ClipperPaths(polygons, *input);
|
||||
ClipperLib::Paths input;
|
||||
Slic3rMultiPoints_to_ClipperPaths(polygons, input);
|
||||
|
||||
// scale input
|
||||
scaleClipperPolygons(*input, scale);
|
||||
scaleClipperPolygons(input, scale);
|
||||
|
||||
// perform offset
|
||||
ClipperLib::OffsetPaths(*input, retval, (delta*scale), joinType, ClipperLib::etClosed, miterLimit);
|
||||
delete input;
|
||||
ClipperLib::ClipperOffset co;
|
||||
if (joinType == jtRound) {
|
||||
co.ArcTolerance = miterLimit;
|
||||
} else {
|
||||
co.MiterLimit = miterLimit;
|
||||
}
|
||||
co.AddPaths(input, joinType, ClipperLib::etClosedPolygon);
|
||||
co.Execute(retval, (delta*scale));
|
||||
|
||||
// unscale output
|
||||
scaleClipperPolygons(retval, 1/scale);
|
||||
@ -125,12 +131,11 @@ offset(const Slic3r::Polygons &polygons, Slic3r::Polygons &retval, const float d
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// perform offset
|
||||
ClipperLib::Paths* output = new ClipperLib::Paths();
|
||||
offset(polygons, *output, delta, scale, joinType, miterLimit);
|
||||
ClipperLib::Paths output;
|
||||
offset(polygons, output, delta, scale, joinType, miterLimit);
|
||||
|
||||
// convert into ExPolygons
|
||||
ClipperPaths_to_Slic3rMultiPoints(*output, retval);
|
||||
delete output;
|
||||
ClipperPaths_to_Slic3rMultiPoints(output, retval);
|
||||
}
|
||||
|
||||
void
|
||||
@ -138,15 +143,21 @@ offset(const Slic3r::Polylines &polylines, ClipperLib::Paths &retval, const floa
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// read input
|
||||
ClipperLib::Paths* input = new ClipperLib::Paths();
|
||||
Slic3rMultiPoints_to_ClipperPaths(polylines, *input);
|
||||
ClipperLib::Paths input;
|
||||
Slic3rMultiPoints_to_ClipperPaths(polylines, input);
|
||||
|
||||
// scale input
|
||||
scaleClipperPolygons(*input, scale);
|
||||
scaleClipperPolygons(input, scale);
|
||||
|
||||
// perform offset
|
||||
ClipperLib::OffsetPaths(*input, retval, (delta*scale), joinType, ClipperLib::etButt, miterLimit);
|
||||
delete input;
|
||||
ClipperLib::ClipperOffset co;
|
||||
if (joinType == jtRound) {
|
||||
co.ArcTolerance = miterLimit;
|
||||
} else {
|
||||
co.MiterLimit = miterLimit;
|
||||
}
|
||||
co.AddPaths(input, joinType, ClipperLib::etOpenButt);
|
||||
co.Execute(retval, (delta*scale));
|
||||
|
||||
// unscale output
|
||||
scaleClipperPolygons(retval, 1/scale);
|
||||
@ -201,20 +212,29 @@ offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths &retval, const float
|
||||
const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
|
||||
{
|
||||
// read input
|
||||
ClipperLib::Paths* input = new ClipperLib::Paths();
|
||||
Slic3rMultiPoints_to_ClipperPaths(polygons, *input);
|
||||
ClipperLib::Paths input;
|
||||
Slic3rMultiPoints_to_ClipperPaths(polygons, input);
|
||||
|
||||
// scale input
|
||||
scaleClipperPolygons(*input, scale);
|
||||
scaleClipperPolygons(input, scale);
|
||||
|
||||
// prepare ClipperOffset object
|
||||
ClipperLib::ClipperOffset co;
|
||||
if (joinType == jtRound) {
|
||||
co.ArcTolerance = miterLimit;
|
||||
} else {
|
||||
co.MiterLimit = miterLimit;
|
||||
}
|
||||
|
||||
// perform first offset
|
||||
ClipperLib::Paths* output1 = new ClipperLib::Paths();
|
||||
ClipperLib::OffsetPaths(*input, *output1, (delta1*scale), joinType, ClipperLib::etClosed, miterLimit);
|
||||
delete input;
|
||||
ClipperLib::Paths output1;
|
||||
co.AddPaths(input, joinType, ClipperLib::etClosedPolygon);
|
||||
co.Execute(output1, (delta1*scale));
|
||||
|
||||
// perform second offset
|
||||
ClipperLib::OffsetPaths(*output1, retval, (delta2*scale), joinType, ClipperLib::etClosed, miterLimit);
|
||||
delete output1;
|
||||
co.Clear();
|
||||
co.AddPaths(output1, joinType, ClipperLib::etClosedPolygon);
|
||||
co.Execute(retval, (delta2*scale));
|
||||
|
||||
// unscale output
|
||||
scaleClipperPolygons(retval, 1/scale);
|
||||
@ -444,7 +464,10 @@ void safety_offset(ClipperLib::Paths* &subject)
|
||||
|
||||
// perform offset (delta = scale 1e-05)
|
||||
ClipperLib::Paths* retval = new ClipperLib::Paths();
|
||||
ClipperLib::OffsetPaths(*subject, *retval, 10.0 * CLIPPER_OFFSET_SCALE, ClipperLib::jtMiter, ClipperLib::etClosed, 2);
|
||||
ClipperLib::ClipperOffset co;
|
||||
co.MiterLimit = 2;
|
||||
co.AddPaths(*subject, ClipperLib::jtMiter, ClipperLib::etClosedPolygon);
|
||||
co.Execute(*retval, 10.0 * CLIPPER_OFFSET_SCALE);
|
||||
|
||||
// unscale output
|
||||
scaleClipperPolygons(*retval, 1.0/CLIPPER_OFFSET_SCALE);
|
||||
|
1941
xs/src/clipper.cpp
1941
xs/src/clipper.cpp
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Author : Angus Johnson *
|
||||
* Version : 6.0.0 *
|
||||
* Date : 30 October 2013 *
|
||||
* Version : 6.1.2 *
|
||||
* Date : 15 December 2013 *
|
||||
* Website : http://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2013 *
|
||||
* *
|
||||
@ -34,7 +34,7 @@
|
||||
#ifndef clipper_hpp
|
||||
#define clipper_hpp
|
||||
|
||||
#define CLIPPER_VERSION "6.0.0"
|
||||
#define CLIPPER_VERSION "6.1.2"
|
||||
|
||||
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This
|
||||
//improve performance but coordinate values are limited to the range +/- 46340
|
||||
@ -46,9 +46,8 @@
|
||||
//use_lines: Enables line clipping. Adds a very minor cost to performance.
|
||||
#define use_lines
|
||||
|
||||
//When enabled, code developed with earlier versions of Clipper
|
||||
//(ie prior to ver 6) should compile without changes.
|
||||
//In a future update, this compatability code will be removed.
|
||||
//use_deprecated: Enables support for the obsolete OffsetPaths() function
|
||||
//which has been replace with the ClipperOffset class.
|
||||
//#define use_deprecated
|
||||
|
||||
#include <vector>
|
||||
@ -108,12 +107,6 @@ std::ostream& operator <<(std::ostream &s, const IntPoint &p);
|
||||
std::ostream& operator <<(std::ostream &s, const Path &p);
|
||||
std::ostream& operator <<(std::ostream &s, const Paths &p);
|
||||
|
||||
#ifdef use_deprecated
|
||||
typedef signed long long long64; //backward compatibility only
|
||||
typedef Path Polygon;
|
||||
typedef Paths Polygons;
|
||||
#endif
|
||||
|
||||
struct DoublePoint
|
||||
{
|
||||
double X;
|
||||
@ -127,6 +120,13 @@ struct DoublePoint
|
||||
typedef void (*TZFillCallback)(IntPoint& z1, IntPoint& z2, IntPoint& pt);
|
||||
#endif
|
||||
|
||||
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
|
||||
enum JoinType {jtSquare, jtRound, jtMiter};
|
||||
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
|
||||
#ifdef use_deprecated
|
||||
enum EndType_ {etClosed, etButt = 2, etSquare, etRound};
|
||||
#endif
|
||||
|
||||
class PolyNode;
|
||||
typedef std::vector< PolyNode* > PolyNodes;
|
||||
|
||||
@ -142,11 +142,14 @@ public:
|
||||
bool IsOpen() const;
|
||||
int ChildCount() const;
|
||||
private:
|
||||
bool m_IsOpen;
|
||||
PolyNode* GetNextSiblingUp() const;
|
||||
unsigned Index; //node index in Parent.Childs
|
||||
bool m_IsOpen;
|
||||
JoinType m_jointype;
|
||||
EndType m_endtype;
|
||||
PolyNode* GetNextSiblingUp() const;
|
||||
void AddChild(PolyNode& child);
|
||||
friend class Clipper; //to access Index
|
||||
friend class ClipperOffset;
|
||||
};
|
||||
|
||||
class PolyTree: public PolyNode
|
||||
@ -161,23 +164,13 @@ private:
|
||||
friend class Clipper; //to access AllNodes
|
||||
};
|
||||
|
||||
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
|
||||
enum JoinType {jtSquare, jtRound, jtMiter};
|
||||
enum EndType {etClosed, etButt, etSquare, etRound};
|
||||
|
||||
bool Orientation(const Path &poly);
|
||||
double Area(const Path &poly);
|
||||
|
||||
#ifdef use_deprecated
|
||||
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
|
||||
double delta, JoinType jointype = jtSquare, double limit = 0, bool autoFix = true);
|
||||
void PolyTreeToPolygons(const PolyTree& polytree, Paths& paths);
|
||||
void ReversePolygon(Path& p);
|
||||
void ReversePolygons(Paths& p);
|
||||
#endif
|
||||
|
||||
void OffsetPaths(const Paths &in_polys, Paths &out_polys,
|
||||
double delta, JoinType jointype, EndType endtype, double limit = 0);
|
||||
double delta, JoinType jointype, EndType_ endtype, double limit = 0);
|
||||
#endif
|
||||
|
||||
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
|
||||
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
|
||||
@ -188,8 +181,8 @@ void CleanPolygon(Path& poly, 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 MinkowkiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed);
|
||||
void MinkowkiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed);
|
||||
void MinkowskiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed);
|
||||
void MinkowskiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed);
|
||||
|
||||
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
|
||||
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
|
||||
@ -215,6 +208,8 @@ struct Join;
|
||||
typedef std::vector < OutRec* > PolyOutList;
|
||||
typedef std::vector < TEdge* > EdgeList;
|
||||
typedef std::vector < Join* > JoinList;
|
||||
typedef std::vector < IntersectNode* > IntersectList;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -228,12 +223,6 @@ public:
|
||||
virtual ~ClipperBase();
|
||||
bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
|
||||
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
|
||||
|
||||
#ifdef use_deprecated
|
||||
bool AddPolygon(const Path &pg, PolyType PolyTyp);
|
||||
bool AddPolygons(const Paths &ppg, PolyType PolyTyp);
|
||||
#endif
|
||||
|
||||
virtual void Clear();
|
||||
IntRect GetBounds();
|
||||
bool PreserveCollinear() {return m_PreserveCollinear;};
|
||||
@ -243,6 +232,7 @@ protected:
|
||||
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
|
||||
void PopLocalMinima();
|
||||
virtual void Reset();
|
||||
TEdge* ProcessBound(TEdge* E, bool IsClockwise);
|
||||
void InsertLocalMinima(LocalMinima *newLm);
|
||||
void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed);
|
||||
TEdge* DescendToMin(TEdge *&E);
|
||||
@ -285,11 +275,11 @@ private:
|
||||
PolyOutList m_PolyOuts;
|
||||
JoinList m_Joins;
|
||||
JoinList m_GhostJoins;
|
||||
IntersectList m_IntersectList;
|
||||
ClipType m_ClipType;
|
||||
std::set< cInt, std::greater<cInt> > m_Scanbeam;
|
||||
TEdge *m_ActiveEdges;
|
||||
TEdge *m_SortedEdges;
|
||||
IntersectNode *m_IntersectNodes;
|
||||
bool m_ExecuteLocked;
|
||||
PolyFillType m_ClipFillType;
|
||||
PolyFillType m_SubjFillType;
|
||||
@ -330,7 +320,6 @@ private:
|
||||
void DisposeAllOutRecs();
|
||||
void DisposeOutRec(PolyOutList::size_type index);
|
||||
bool ProcessIntersections(const cInt botY, const cInt topY);
|
||||
void InsertIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt);
|
||||
void BuildIntersectList(const cInt botY, const cInt topY);
|
||||
void ProcessIntersectList();
|
||||
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
|
||||
@ -341,12 +330,13 @@ private:
|
||||
bool FixupIntersectionOrder();
|
||||
void FixupOutPolygon(OutRec &outrec);
|
||||
bool IsHole(TEdge *e);
|
||||
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
|
||||
void FixHoleLinkage(OutRec &outrec);
|
||||
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
|
||||
void ClearJoins();
|
||||
void ClearGhostJoins();
|
||||
void AddGhostJoin(OutPt *op, const IntPoint offPt);
|
||||
bool JoinPoints(const Join *j, OutPt *&p1, OutPt *&p2);
|
||||
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
|
||||
void JoinCommonEdges();
|
||||
void DoSimplePolygons();
|
||||
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
|
||||
@ -357,6 +347,37 @@ private:
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class ClipperOffset
|
||||
{
|
||||
public:
|
||||
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
|
||||
~ClipperOffset();
|
||||
void AddPath(const Path& path, JoinType joinType, EndType endType);
|
||||
void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
|
||||
void Execute(Paths& solution, double delta);
|
||||
void Execute(PolyTree& solution, double delta);
|
||||
void Clear();
|
||||
double MiterLimit;
|
||||
double ArcTolerance;
|
||||
private:
|
||||
Paths m_destPolys;
|
||||
Path m_srcPoly;
|
||||
Path m_destPoly;
|
||||
std::vector<DoublePoint> m_normals;
|
||||
double m_delta, m_sinA, m_sin, m_cos;
|
||||
double m_miterLim, m_StepsPerRad;
|
||||
IntPoint m_lowest;
|
||||
PolyNode m_polyNodes;
|
||||
|
||||
void FixOrientations();
|
||||
void DoOffset(double delta);
|
||||
void OffsetPoint(int j, int& k, JoinType jointype);
|
||||
void DoSquare(int j, int k);
|
||||
void DoMiter(int j, int k, double r);
|
||||
void DoRound(int j, int k);
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class clipperException : public std::exception
|
||||
{
|
||||
public:
|
||||
|
@ -43,10 +43,10 @@ my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square);
|
||||
[95, 95],
|
||||
[205, 95],
|
||||
], [
|
||||
[145, 145],
|
||||
[145, 155],
|
||||
[155, 155],
|
||||
[155, 145],
|
||||
[145, 145],
|
||||
] ], 'offset_ex';
|
||||
}
|
||||
|
||||
@ -58,10 +58,10 @@ my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square);
|
||||
[97, 97],
|
||||
[203, 97],
|
||||
], [
|
||||
[143, 143],
|
||||
[143, 157],
|
||||
[157, 157],
|
||||
[157, 143],
|
||||
[143, 143],
|
||||
] ], 'offset2_ex';
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square);
|
||||
[5000000, 5000000],
|
||||
]);
|
||||
my $result = Slic3r::Geometry::Clipper::offset2_ex([ @$expolygon2 ], -1, +1);
|
||||
is_deeply $result->[0]->pp, $expolygon2->pp, 'offset2_ex';
|
||||
is $result->[0]->area, $expolygon2->area, 'offset2_ex';
|
||||
}
|
||||
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user