Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
ClipperLib Namespace Reference

Classes

class  Clipper
 
class  ClipperBase
 
class  clipperException
 
class  ClipperOffset
 
struct  IntersectNode
 
struct  IntRect
 
struct  Join
 
struct  LocalMinimum
 
struct  OutPt
 
struct  OutRec
 
class  PolyNode
 
class  PolyTree
 
struct  TEdge
 

Typedefs

using cInt = int32_t
 
using CrossProductType = int64_t
 
using IntPoint = Eigen::Matrix< cInt, 2, 1, Eigen::DontAlign >
 
using DoublePoint = Eigen::Matrix< double, 2, 1, Eigen::DontAlign >
 
template<typename BaseType >
using Allocator = tbb::scalable_allocator< BaseType >
 
using Path = std::vector< IntPoint, Allocator< IntPoint > >
 
using Paths = std::vector< Path, Allocator< Path > >
 
typedef std::vector< PolyNode *, Allocator< PolyNode * > > PolyNodes
 
using OutPts = std::vector< OutPt, Allocator< OutPt > >
 

Enumerations

enum  Direction { dRightToLeft , dLeftToRight }
 
enum  NodeType { ntAny , ntOpen , ntClosed }
 
enum  ClipType { ctIntersection , ctUnion , ctDifference , ctXor }
 
enum  PolyType { ptSubject , ptClip }
 
enum  PolyFillType { pftEvenOdd , pftNonZero , pftPositive , pftNegative }
 
enum  InitOptions { ioReverseSolution = 1 , ioStrictlySimple = 2 , ioPreserveCollinear = 4 }
 
enum  JoinType { jtSquare , jtRound , jtMiter }
 
enum  EndType {
  etClosedPolygon , etClosedLine , etOpenButt , etOpenSquare ,
  etOpenRound
}
 
enum  EdgeSide { esLeft = 1 , esRight = 2 }
 

Functions

IntPoint IntPoint2d (cInt x, cInt y)
 
cInt Round (double val)
 
bool operator== (const IntPoint &l, const IntPoint &r)
 
bool operator!= (const IntPoint &l, const IntPoint &r)
 
double Area (const Path &poly)
 
double Area (const OutPt *op)
 
double Area (const OutRec &outRec)
 
bool PointIsVertex (const IntPoint &Pt, OutPt *pp)
 
int PointInPolygon (const IntPoint &pt, const Path &path)
 
int PointInPolygon (const IntPoint &pt, OutPt *op)
 
bool Poly2ContainsPoly1 (OutPt *OutPt1, OutPt *OutPt2)
 
bool SlopesEqual (const cInt dx1, const cInt dy1, const cInt dx2, const cInt dy2, bool)
 
bool SlopesEqual (const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
 
bool SlopesEqual (const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, bool UseFullInt64Range)
 
bool SlopesEqual (const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, const IntPoint &pt4, bool UseFullInt64Range)
 
bool IsHorizontal (TEdge &e)
 
double GetDx (const IntPoint &pt1, const IntPoint &pt2)
 
cInt TopX (TEdge &edge, const cInt currentY)
 
void IntersectPoint (TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
 
void ReversePolyPtLinks (OutPt *pp)
 
void InitEdge (TEdge *e, TEdge *eNext, TEdge *ePrev, const IntPoint &Pt)
 
void InitEdge2 (TEdge &e, PolyType Pt)
 
TEdgeRemoveEdge (TEdge *e)
 
void ReverseHorizontal (TEdge &e)
 
bool GetOverlapSegment (IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, IntPoint pt2b, IntPoint &pt1, IntPoint &pt2)
 
bool FirstIsBottomPt (const OutPt *btmPt1, const OutPt *btmPt2)
 
OutPtGetBottomPt (OutPt *pp)
 
bool Pt2IsBetweenPt1AndPt3 (const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3)
 
bool HorzSegmentsOverlap (cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b)
 
static void RangeTest (const IntPoint &pt)
 
TEdgeFindNextLocMin (TEdge *E)
 
OutRecGetLowermostRec (OutRec *outRec1, OutRec *outRec2)
 
bool Param1RightOfParam2 (OutRec *outRec1, OutRec *outRec2)
 
bool IsMaxima (TEdge *e, const cInt Y)
 
bool IsIntermediate (TEdge *e, const cInt Y)
 
TEdgeGetMaximaPair (TEdge *e)
 
void GetHorzDirection (TEdge &HorzEdge, Direction &Dir, cInt &Left, cInt &Right)
 
bool EdgesAdjacent (const IntersectNode &inode)
 
int PointCount (OutPt *Pts)
 
bool E2InsertsBeforeE1 (TEdge &e1, TEdge &e2)
 
bool GetOverlap (const cInt a1, const cInt a2, const cInt b1, const cInt b2, cInt &Left, cInt &Right)
 
void UpdateOutPtIdxs (OutRec &outrec)
 
DoublePoint GetUnitNormal (const IntPoint &pt1, const IntPoint &pt2)
 
void ReversePath (Path &p)
 
void ReversePaths (Paths &p)
 
Paths SimplifyPolygon (const Path &in_poly, PolyFillType fillType, bool strictly_simple)
 
double DistanceSqrd (const IntPoint &pt1, const IntPoint &pt2)
 
double DistanceFromLineSqrd (const IntPoint &pt, const IntPoint &ln1, const IntPoint &ln2)
 
bool SlopesNearCollinear (const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, double distSqrd)
 
bool PointsAreClose (IntPoint pt1, IntPoint pt2, double distSqrd)
 
OutPtExcludeOp (OutPt *op)
 
void CleanPolygon (const Path &in_poly, Path &out_poly, double distance)
 
void CleanPolygon (Path &poly, double distance)
 
void CleanPolygons (const Paths &in_polys, Paths &out_polys, double distance)
 
void CleanPolygons (Paths &polys, double distance)
 
void Minkowski (const Path &poly, const Path &path, Paths &solution, bool isSum, bool isClosed)
 
void MinkowskiSum (const Path &pattern, const Path &path, Paths &solution, bool pathIsClosed)
 
void TranslatePath (const Path &input, Path &output, const IntPoint &delta)
 
void MinkowskiSum (const Path &pattern, const Paths &paths, Paths &solution, bool pathIsClosed)
 
void MinkowskiDiff (const Path &poly1, const Path &poly2, Paths &solution)
 
void AddPolyNodeToPaths (const PolyNode &polynode, NodeType nodetype, Paths &paths)
 
void AddPolyNodeToPaths (PolyNode &&polynode, NodeType nodetype, Paths &paths)
 
void PolyTreeToPaths (const PolyTree &polytree, Paths &paths)
 
void PolyTreeToPaths (PolyTree &&polytree, Paths &paths)
 
void ClosedPathsFromPolyTree (const PolyTree &polytree, Paths &paths)
 
void OpenPathsFromPolyTree (PolyTree &polytree, Paths &paths)
 
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)
 
Pathoperator<< (Path &poly, const IntPoint &p)
 
Pathsoperator<< (Paths &polys, const Path &p)
 
bool Orientation (const Path &poly)
 
template<typename PathsProvider >
Paths SimplifyPolygons (PathsProvider &&in_polys, PolyFillType fillType=pftNonZero, bool strictly_simple=true)
 

Variables

static double const pi = 3.141592653589793238
 
static double const two_pi = pi *2
 
static double const def_arc_tolerance = 0.25
 
static int const Unassigned = -1
 
static int const Skip = -2
 

Class Documentation

◆ ClipperLib::IntRect

struct ClipperLib::IntRect
Class Members
cInt bottom
cInt left
cInt right
cInt top

◆ ClipperLib::LocalMinimum

struct ClipperLib::LocalMinimum
+ Collaboration diagram for ClipperLib::LocalMinimum:
Class Members
TEdge * LeftBound
TEdge * RightBound
cInt Y

◆ ClipperLib::OutPt

struct ClipperLib::OutPt
+ Collaboration diagram for ClipperLib::OutPt:
Class Members
int Idx
OutPt * Next
OutPt * Prev
IntPoint Pt

◆ ClipperLib::OutRec

struct ClipperLib::OutRec
+ Collaboration diagram for ClipperLib::OutRec:
Class Members
OutPt * BottomPt
OutRec * FirstLeft
int Idx
bool IsHole
bool IsOpen
PolyNode * PolyNd
OutPt * Pts

◆ ClipperLib::TEdge

struct ClipperLib::TEdge
+ Collaboration diagram for ClipperLib::TEdge:
Class Members
IntPoint Bot
IntPoint Curr
IntPoint Delta
double Dx
TEdge * Next
TEdge * NextInAEL
TEdge * NextInLML
TEdge * NextInSEL
int OutIdx
PolyType PolyTyp
TEdge * Prev
TEdge * PrevInAEL
TEdge * PrevInSEL
EdgeSide Side
IntPoint Top
int WindCnt
int WindCnt2
int WindDelta

Typedef Documentation

◆ Allocator

template<typename BaseType >
using ClipperLib::Allocator = typedef tbb::scalable_allocator<BaseType>

◆ cInt

using ClipperLib::cInt = typedef int32_t

◆ CrossProductType

◆ DoublePoint

using ClipperLib::DoublePoint = typedef Eigen::Matrix<double, 2, 1, Eigen::DontAlign>

◆ IntPoint

◆ OutPts

using ClipperLib::OutPts = typedef std::vector<OutPt, Allocator<OutPt> >

◆ Path

using ClipperLib::Path = typedef std::vector<IntPoint, Allocator<IntPoint> >

◆ Paths

using ClipperLib::Paths = typedef std::vector<Path, Allocator<Path> >

◆ PolyNodes

typedef std::vector<PolyNode*, Allocator<PolyNode*> > ClipperLib::PolyNodes

Enumeration Type Documentation

◆ ClipType

Enumerator
ctIntersection 
ctUnion 
ctDifference 
ctXor 
@ ctXor
Definition clipper.hpp:75
@ ctIntersection
Definition clipper.hpp:75
@ ctUnion
Definition clipper.hpp:75
@ ctDifference
Definition clipper.hpp:75

◆ Direction

Enumerator
dRightToLeft 
dLeftToRight 
@ dRightToLeft
Definition clipper.cpp:67
@ dLeftToRight
Definition clipper.cpp:67

◆ EdgeSide

Enumerator
esLeft 
esRight 
226{ esLeft = 1, esRight = 2};
@ esLeft
Definition clipper.hpp:226
@ esRight
Definition clipper.hpp:226

◆ EndType

Enumerator
etClosedPolygon 
etClosedLine 
etOpenButt 
etOpenSquare 
etOpenRound 
@ etOpenButt
Definition clipper.hpp:139
@ etOpenRound
Definition clipper.hpp:139
@ etClosedLine
Definition clipper.hpp:139
@ etClosedPolygon
Definition clipper.hpp:139
@ etOpenSquare
Definition clipper.hpp:139

◆ InitOptions

Enumerator
ioReverseSolution 
ioStrictlySimple 
ioPreserveCollinear 
@ ioReverseSolution
Definition clipper.hpp:137
@ ioPreserveCollinear
Definition clipper.hpp:137
@ ioStrictlySimple
Definition clipper.hpp:137

◆ JoinType

Enumerator
jtSquare 
jtRound 
jtMiter 
@ jtSquare
Definition clipper.hpp:138
@ jtMiter
Definition clipper.hpp:138
@ jtRound
Definition clipper.hpp:138

◆ NodeType

Enumerator
ntAny 
ntOpen 
ntClosed 
@ ntAny
Definition clipper.cpp:4075
@ ntClosed
Definition clipper.cpp:4075
@ ntOpen
Definition clipper.cpp:4075

◆ PolyFillType

Enumerator
pftEvenOdd 
pftNonZero 
pftPositive 
pftNegative 
@ pftNegative
Definition clipper.hpp:81
@ pftPositive
Definition clipper.hpp:81
@ pftEvenOdd
Definition clipper.hpp:81
@ pftNonZero
Definition clipper.hpp:81

◆ PolyType

Enumerator
ptSubject 
ptClip 
76{ ptSubject, ptClip };
@ ptClip
Definition clipper.hpp:76
@ ptSubject
Definition clipper.hpp:76

Function Documentation

◆ AddPolyNodeToPaths() [1/2]

void ClipperLib::AddPolyNodeToPaths ( const PolyNode polynode,
NodeType  nodetype,
Paths paths 
)
4078{
4079 bool match = true;
4080 if (nodetype == ntClosed) match = !polynode.IsOpen();
4081 else if (nodetype == ntOpen) return;
4082
4083 if (!polynode.Contour.empty() && match)
4084 paths.emplace_back(polynode.Contour);
4085 for (int i = 0; i < polynode.ChildCount(); ++i)
4086 AddPolyNodeToPaths(*polynode.Childs[i], nodetype, paths);
4087}
int ChildCount() const
Definition clipper.hpp:156
Path Contour
Definition clipper.hpp:149
PolyNodes Childs
Definition clipper.hpp:150
bool IsOpen() const
Definition clipper.hpp:155
void AddPolyNodeToPaths(const PolyNode &polynode, NodeType nodetype, Paths &paths)
Definition clipper.cpp:4077

References AddPolyNodeToPaths(), ClipperLib::PolyNode::ChildCount(), ClipperLib::PolyNode::Childs, ClipperLib::PolyNode::Contour, ClipperLib::PolyNode::IsOpen(), ntClosed, and ntOpen.

Referenced by AddPolyNodeToPaths(), AddPolyNodeToPaths(), ClosedPathsFromPolyTree(), PolyTreeToPaths(), and PolyTreeToPaths().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ AddPolyNodeToPaths() [2/2]

void ClipperLib::AddPolyNodeToPaths ( PolyNode &&  polynode,
NodeType  nodetype,
Paths paths 
)
4090{
4091 bool match = true;
4092 if (nodetype == ntClosed) match = !polynode.IsOpen();
4093 else if (nodetype == ntOpen) return;
4094
4095 if (!polynode.Contour.empty() && match)
4096 paths.emplace_back(std::move(polynode.Contour));
4097 for (int i = 0; i < polynode.ChildCount(); ++i)
4098 AddPolyNodeToPaths(std::move(*polynode.Childs[i]), nodetype, paths);
4099}

References AddPolyNodeToPaths(), ntClosed, and ntOpen.

+ Here is the call graph for this function:

◆ Area() [1/3]

double ClipperLib::Area ( const OutPt op)
167{
168 const OutPt *startOp = op;
169 if (!op) return 0;
170 double a = 0;
171 do {
172 a += (double)(op->Prev->Pt.x() + op->Pt.x()) * (double)(op->Prev->Pt.y() - op->Pt.y());
173 op = op->Next;
174 } while (op != startOp);
175 return a * 0.5;
176}
OutPt * Next
Definition clipper.hpp:282
OutPt * Prev
Definition clipper.hpp:284
IntPoint Pt
Definition clipper.hpp:280
Definition clipper.hpp:276

References Area(), ClipperLib::OutPt::Next, ClipperLib::OutPt::Prev, and ClipperLib::OutPt::Pt.

+ Here is the call graph for this function:

◆ Area() [2/3]

double ClipperLib::Area ( const OutRec outRec)
180{
181 return Area(outRec.Pts);
182}
double Area(const Path &poly)
Definition clipper.cpp:151
OutPt * Pts
Definition clipper.hpp:304

References Area(), and ClipperLib::OutRec::Pts.

+ Here is the call graph for this function:

◆ Area() [3/3]

double ClipperLib::Area ( const Path poly)
152{
153 int size = (int)poly.size();
154 if (size < 3) return 0;
155
156 double a = 0;
157 for (int i = 0, j = size -1; i < size; ++i)
158 {
159 a += ((double)poly[j].x() + poly[i].x()) * ((double)poly[j].y() - poly[i].y());
160 j = i;
161 }
162 return -a * 0.5;
163}

References Area().

Referenced by Area(), Area(), Area(), ClipperLib::Clipper::ExecuteInternal(), Slic3r::expolygons_to_zpaths_shrunk(), FirstIsBottomPt(), ClipperLib::Clipper::JoinCommonEdges(), Orientation(), Slic3r::Arachne::removeSmallAreas(), Slic3r::simplify_polygon_impl(), Slic3r::variable_offset_inner_raw(), Slic3r::variable_offset_outer_ex(), and Slic3r::variable_offset_outer_raw().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CleanPolygon() [1/2]

void ClipperLib::CleanPolygon ( const Path in_poly,
Path out_poly,
double  distance 
)
3908{
3909 //distance = proximity in units/pixels below which vertices
3910 //will be stripped. Default ~= sqrt(2).
3911
3912 size_t size = in_poly.size();
3913
3914 if (size == 0)
3915 {
3916 out_poly.clear();
3917 return;
3918 }
3919
3920 OutPts outPts(size);
3921 for (size_t i = 0; i < size; ++i)
3922 {
3923 outPts[i].Pt = in_poly[i];
3924 outPts[i].Next = &outPts[(i + 1) % size];
3925 outPts[i].Next->Prev = &outPts[i];
3926 outPts[i].Idx = 0;
3927 }
3928
3929 double distSqrd = distance * distance;
3930 OutPt* op = &outPts[0];
3931 while (op->Idx == 0 && op->Next != op->Prev)
3932 {
3933 if (PointsAreClose(op->Pt, op->Prev->Pt, distSqrd))
3934 {
3935 op = ExcludeOp(op);
3936 size--;
3937 }
3938 else if (PointsAreClose(op->Prev->Pt, op->Next->Pt, distSqrd))
3939 {
3940 ExcludeOp(op->Next);
3941 op = ExcludeOp(op);
3942 size -= 2;
3943 }
3944 else if (SlopesNearCollinear(op->Prev->Pt, op->Pt, op->Next->Pt, distSqrd))
3945 {
3946 op = ExcludeOp(op);
3947 size--;
3948 }
3949 else
3950 {
3951 op->Idx = 1;
3952 op = op->Next;
3953 }
3954 }
3955
3956 if (size < 3) size = 0;
3957 out_poly.resize(size);
3958 for (size_t i = 0; i < size; ++i)
3959 {
3960 out_poly[i] = op->Pt;
3961 op = op->Next;
3962 }
3963}
OutPt * ExcludeOp(OutPt *op)
Definition clipper.cpp:3896
bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd)
Definition clipper.cpp:3888
bool SlopesNearCollinear(const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, double distSqrd)
Definition clipper.cpp:3861
constexpr auto size(const C &c) -> decltype(c.size())
Definition span.hpp:183
double distance(const P &p1, const P &p2)
Definition geometry_traits.hpp:329

References ExcludeOp(), ClipperLib::OutPt::Idx, ClipperLib::OutPt::Next, PointsAreClose(), ClipperLib::OutPt::Prev, ClipperLib::OutPt::Pt, and SlopesNearCollinear().

Referenced by CleanPolygon(), and CleanPolygons().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CleanPolygon() [2/2]

void ClipperLib::CleanPolygon ( Path poly,
double  distance 
)
3967{
3968 CleanPolygon(poly, poly, distance);
3969}
void CleanPolygon(const Path &in_poly, Path &out_poly, double distance)
Definition clipper.cpp:3907

References CleanPolygon().

+ Here is the call graph for this function:

◆ CleanPolygons() [1/2]

void ClipperLib::CleanPolygons ( const Paths in_polys,
Paths out_polys,
double  distance 
)
3973{
3974 for (Paths::size_type i = 0; i < in_polys.size(); ++i)
3975 CleanPolygon(in_polys[i], out_polys[i], distance);
3976}

References CleanPolygon().

Referenced by CleanPolygons(), and Slic3r::Emboss::heal_shape().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CleanPolygons() [2/2]

void ClipperLib::CleanPolygons ( Paths polys,
double  distance 
)
3980{
3981 CleanPolygons(polys, polys, distance);
3982}
void CleanPolygons(const Paths &in_polys, Paths &out_polys, double distance)
Definition clipper.cpp:3972

References CleanPolygons().

+ Here is the call graph for this function:

◆ ClosedPathsFromPolyTree()

void ClipperLib::ClosedPathsFromPolyTree ( const PolyTree polytree,
Paths paths 
)
4120{
4121 paths.clear();
4122 paths.reserve(polytree.Total());
4123 AddPolyNodeToPaths(polytree, ntClosed, paths);
4124}
int Total() const
Definition clipper.cpp:100

References AddPolyNodeToPaths(), ntClosed, and ClipperLib::PolyTree::Total().

+ Here is the call graph for this function:

◆ DistanceFromLineSqrd()

double ClipperLib::DistanceFromLineSqrd ( const IntPoint pt,
const IntPoint ln1,
const IntPoint ln2 
)
3846{
3847 //The equation of a line in general form (Ax + By + C = 0)
3848 //given 2 points (x¹,y¹) & (x²,y²) is ...
3849 //(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0
3850 //A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹
3851 //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²)
3852 //see http://en.wikipedia.org/wiki/Perpendicular_distance
3853 double A = double(ln1.y() - ln2.y());
3854 double B = double(ln2.x() - ln1.x());
3855 double C = A * ln1.x() + B * ln1.y();
3856 C = A * pt.x() + B * pt.y() - C;
3857 return (C * C) / (A * A + B * B);
3858}

Referenced by SlopesNearCollinear().

+ Here is the caller graph for this function:

◆ DistanceSqrd()

double ClipperLib::DistanceSqrd ( const IntPoint pt1,
const IntPoint pt2 
)
inline
3837{
3838 auto Dx = double(pt1.x() - pt2.x());
3839 auto dy = double(pt1.y() - pt2.y());
3840 return (Dx*Dx + dy*dy);
3841}

◆ E2InsertsBeforeE1()

bool ClipperLib::E2InsertsBeforeE1 ( TEdge e1,
TEdge e2 
)
inline
2832{
2833 if (e2.Curr.x() == e1.Curr.x())
2834 {
2835 if (e2.Top.y() > e1.Top.y())
2836 return e2.Top.x() < TopX(e1, e2.Top.y());
2837 else return e1.Top.x() > TopX(e2, e1.Top.y());
2838 }
2839 else return e2.Curr.x() < e1.Curr.x();
2840}
cInt TopX(TEdge &edge, const cInt currentY)
Definition clipper.cpp:333
IntPoint Top
Definition clipper.hpp:236
IntPoint Curr
Definition clipper.hpp:234

References ClipperLib::TEdge::Curr, ClipperLib::TEdge::Top, and TopX().

Referenced by ClipperLib::Clipper::InsertEdgeIntoAEL().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ EdgesAdjacent()

bool ClipperLib::EdgesAdjacent ( const IntersectNode inode)
inline
2480{
2481 return (inode.Edge1->NextInSEL == inode.Edge2) ||
2482 (inode.Edge1->PrevInSEL == inode.Edge2);
2483}
TEdge * NextInSEL
Definition clipper.hpp:256
TEdge * PrevInSEL
Definition clipper.hpp:257
TEdge * Edge1
Definition clipper.hpp:263
TEdge * Edge2
Definition clipper.hpp:264

References ClipperLib::IntersectNode::Edge1, ClipperLib::IntersectNode::Edge2, ClipperLib::TEdge::NextInSEL, and ClipperLib::TEdge::PrevInSEL.

Referenced by ClipperLib::Clipper::FixupIntersectionOrder().

+ Here is the caller graph for this function:

◆ ExcludeOp()

OutPt * ClipperLib::ExcludeOp ( OutPt op)
3897{
3898 OutPt* result = op->Prev;
3899 result->Next = op->Next;
3900 op->Next->Prev = result;
3901 result->Idx = 0;
3902 return result;
3903}
int Idx
Definition clipper.hpp:278

References ClipperLib::OutPt::Idx, ClipperLib::OutPt::Next, and ClipperLib::OutPt::Prev.

Referenced by CleanPolygon().

+ Here is the caller graph for this function:

◆ FindNextLocMin()

TEdge * ClipperLib::FindNextLocMin ( TEdge E)
inline
620{
621 for (;;)
622 {
623 while (E->Bot != E->Prev->Bot || E->Curr == E->Top) E = E->Next;
624 if (!IsHorizontal(*E) && !IsHorizontal(*E->Prev)) break;
625 while (IsHorizontal(*E->Prev)) E = E->Prev;
626 TEdge* E2 = E;
627 while (IsHorizontal(*E)) E = E->Next;
628 if (E->Top.y() == E->Prev->Bot.y()) continue; //ie just an intermediate horz.
629 if (E2->Prev->Bot.x() < E->Bot.x()) E = E2;
630 break;
631 }
632 return E;
633}
TEdge * Prev
Definition clipper.hpp:251
IntPoint Bot
Definition clipper.hpp:232
bool IsHorizontal(TEdge &e)
Definition clipper.cpp:320
Definition clipper.hpp:230

References ClipperLib::TEdge::Bot, FindNextLocMin(), IsHorizontal(), and ClipperLib::TEdge::Prev.

Referenced by ClipperLib::ClipperBase::AddPathInternal(), and FindNextLocMin().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ FirstIsBottomPt()

bool ClipperLib::FirstIsBottomPt ( const OutPt btmPt1,
const OutPt btmPt2 
)
504{
505 OutPt *p = btmPt1->Prev;
506 while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Prev;
507 double dx1p = std::fabs(GetDx(btmPt1->Pt, p->Pt));
508 p = btmPt1->Next;
509 while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Next;
510 double dx1n = std::fabs(GetDx(btmPt1->Pt, p->Pt));
511
512 p = btmPt2->Prev;
513 while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Prev;
514 double dx2p = std::fabs(GetDx(btmPt2->Pt, p->Pt));
515 p = btmPt2->Next;
516 while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next;
517 double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt));
518
519 if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) &&
520 std::min(dx1p, dx1n) == std::min(dx2p, dx2n))
521 return Area(btmPt1) > 0; //if otherwise identical use orientation
522 else
523 return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
524}
double GetDx(const IntPoint &pt1, const IntPoint &pt2)
Definition clipper.cpp:326

References Area(), FirstIsBottomPt(), GetDx(), ClipperLib::OutPt::Next, ClipperLib::OutPt::Prev, and ClipperLib::OutPt::Pt.

Referenced by FirstIsBottomPt(), GetBottomPt(), and GetLowermostRec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetBottomPt()

OutPt * ClipperLib::GetBottomPt ( OutPt pp)
529{
530 OutPt* dups = nullptr;
531 OutPt* p = pp->Next;
532 while (p != pp)
533 {
534 if (p->Pt.y() > pp->Pt.y())
535 {
536 pp = p;
537 dups = nullptr;
538 }
539 else if (p->Pt.y() == pp->Pt.y() && p->Pt.x() <= pp->Pt.x())
540 {
541 if (p->Pt.x() < pp->Pt.x())
542 {
543 dups = nullptr;
544 pp = p;
545 } else
546 {
547 if (p->Next != pp && p->Prev != pp) dups = p;
548 }
549 }
550 p = p->Next;
551 }
552 if (dups)
553 {
554 //there appears to be at least 2 vertices at BottomPt so ...
555 while (dups != p)
556 {
557 if (!FirstIsBottomPt(p, dups)) pp = dups;
558 dups = dups->Next;
559 while (dups->Pt != pp->Pt) dups = dups->Next;
560 }
561 }
562 return pp;
563}
bool FirstIsBottomPt(const OutPt *btmPt1, const OutPt *btmPt2)
Definition clipper.cpp:503

References FirstIsBottomPt(), GetBottomPt(), ClipperLib::OutPt::Next, ClipperLib::OutPt::Prev, and ClipperLib::OutPt::Pt.

Referenced by GetBottomPt(), and GetLowermostRec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetDx()

double ClipperLib::GetDx ( const IntPoint pt1,
const IntPoint pt2 
)
inline
327{
328 return (pt1.y() == pt2.y()) ?
329 HORIZONTAL : (double)(pt2.x() - pt1.x()) / (pt2.y() - pt1.y());
330}
#define HORIZONTAL
Definition clipper.cpp:72

References GetDx(), and HORIZONTAL.

Referenced by FirstIsBottomPt(), and GetDx().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetHorzDirection()

void ClipperLib::GetHorzDirection ( TEdge HorzEdge,
Direction Dir,
cInt Left,
cInt Right 
)
inline
2166{
2167 if (HorzEdge.Bot.x() < HorzEdge.Top.x())
2168 {
2169 Left = HorzEdge.Bot.x();
2170 Right = HorzEdge.Top.x();
2171 Dir = dLeftToRight;
2172 } else
2173 {
2174 Left = HorzEdge.Top.x();
2175 Right = HorzEdge.Bot.x();
2176 Dir = dRightToLeft;
2177 }
2178}

References ClipperLib::TEdge::Bot, dLeftToRight, dRightToLeft, and ClipperLib::TEdge::Top.

Referenced by ClipperLib::Clipper::ProcessHorizontal().

+ Here is the caller graph for this function:

◆ GetLowermostRec()

OutRec * ClipperLib::GetLowermostRec ( OutRec outRec1,
OutRec outRec2 
)
1830{
1831 //work out which polygon fragment has the correct hole state ...
1832 if (!outRec1->BottomPt)
1833 outRec1->BottomPt = GetBottomPt(outRec1->Pts);
1834 if (!outRec2->BottomPt)
1835 outRec2->BottomPt = GetBottomPt(outRec2->Pts);
1836 OutPt *OutPt1 = outRec1->BottomPt;
1837 OutPt *OutPt2 = outRec2->BottomPt;
1838 if (OutPt1->Pt.y() > OutPt2->Pt.y()) return outRec1;
1839 else if (OutPt1->Pt.y() < OutPt2->Pt.y()) return outRec2;
1840 else if (OutPt1->Pt.x() < OutPt2->Pt.x()) return outRec1;
1841 else if (OutPt1->Pt.x() > OutPt2->Pt.x()) return outRec2;
1842 else if (OutPt1->Next == OutPt1) return outRec2;
1843 else if (OutPt2->Next == OutPt2) return outRec1;
1844 else if (FirstIsBottomPt(OutPt1, OutPt2)) return outRec1;
1845 else return outRec2;
1846}
OutPt * GetBottomPt(OutPt *pp)
Definition clipper.cpp:528
OutPt * BottomPt
Definition clipper.hpp:305

References ClipperLib::OutRec::BottomPt, FirstIsBottomPt(), GetBottomPt(), ClipperLib::OutPt::Next, ClipperLib::OutPt::Pt, and ClipperLib::OutRec::Pts.

Referenced by ClipperLib::Clipper::AppendPolygon(), and ClipperLib::Clipper::JoinCommonEdges().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetMaximaPair()

TEdge * ClipperLib::GetMaximaPair ( TEdge e)
inline
2057{
2058 TEdge* result = 0;
2059 if ((e->Next->Top == e->Top) && !e->Next->NextInLML)
2060 result = e->Next;
2061 else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML)
2062 result = e->Prev;
2063
2064 if (result && (result->OutIdx == Skip ||
2065 //result is false if both NextInAEL & PrevInAEL are nil & not horizontal ...
2066 (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result))))
2067 return 0;
2068 return result;
2069}
TEdge * NextInLML
Definition clipper.hpp:253
TEdge * PrevInAEL
Definition clipper.hpp:255
TEdge * NextInAEL
Definition clipper.hpp:254
int OutIdx
Definition clipper.hpp:247
TEdge * Next
Definition clipper.hpp:249

References IsHorizontal(), ClipperLib::TEdge::Next, ClipperLib::TEdge::NextInAEL, ClipperLib::TEdge::NextInLML, ClipperLib::TEdge::OutIdx, ClipperLib::TEdge::Prev, ClipperLib::TEdge::PrevInAEL, Skip, and ClipperLib::TEdge::Top.

Referenced by ClipperLib::Clipper::DoMaxima(), ClipperLib::Clipper::ProcessEdgesAtTopOfScanbeam(), and ClipperLib::Clipper::ProcessHorizontal().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetOverlap()

bool ClipperLib::GetOverlap ( const cInt  a1,
const cInt  a2,
const cInt  b1,
const cInt  b2,
cInt Left,
cInt Right 
)
2845{
2846 if (a1 < a2)
2847 {
2848 if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);}
2849 else {Left = std::max(a1,b2); Right = std::min(a2,b1);}
2850 }
2851 else
2852 {
2853 if (b1 < b2) {Left = std::max(a2,b1); Right = std::min(a1,b2);}
2854 else {Left = std::max(a2,b2); Right = std::min(a1,b1);}
2855 }
2856 return Left < Right;
2857}

Referenced by ClipperLib::Clipper::JoinPoints().

+ Here is the caller graph for this function:

◆ GetOverlapSegment()

bool ClipperLib::GetOverlapSegment ( IntPoint  pt1a,
IntPoint  pt1b,
IntPoint  pt2a,
IntPoint  pt2b,
IntPoint pt1,
IntPoint pt2 
)
483{
484 //precondition: segments are Collinear.
485 if (std::abs(pt1a.x() - pt1b.x()) > std::abs(pt1a.y() - pt1b.y()))
486 {
487 if (pt1a.x() > pt1b.x()) std::swap(pt1a, pt1b);
488 if (pt2a.x() > pt2b.x()) std::swap(pt2a, pt2b);
489 if (pt1a.x() > pt2a.x()) pt1 = pt1a; else pt1 = pt2a;
490 if (pt1b.x() < pt2b.x()) pt2 = pt1b; else pt2 = pt2b;
491 return pt1.x() < pt2.x();
492 } else
493 {
494 if (pt1a.y() < pt1b.y()) std::swap(pt1a, pt1b);
495 if (pt2a.y() < pt2b.y()) std::swap(pt2a, pt2b);
496 if (pt1a.y() < pt2a.y()) pt1 = pt1a; else pt1 = pt2a;
497 if (pt1b.y() > pt2b.y()) pt2 = pt1b; else pt2 = pt2b;
498 return pt1.y() > pt2.y();
499 }
500}

References GetOverlapSegment().

Referenced by GetOverlapSegment().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetUnitNormal()

DoublePoint ClipperLib::GetUnitNormal ( const IntPoint pt1,
const IntPoint pt2 
)
3303{
3304 if(pt2.x() == pt1.x() && pt2.y() == pt1.y())
3305 return DoublePoint(0, 0);
3306
3307 double Dx = double(pt2.x() - pt1.x());
3308 double dy = double(pt2.y() - pt1.y());
3309 double f = 1.0 / std::sqrt( Dx*Dx + dy*dy );
3310 Dx *= f;
3311 dy *= f;
3312 return DoublePoint(dy, -Dx);
3313}

Referenced by ClipperLib::ClipperOffset::DoOffset().

+ Here is the caller graph for this function:

◆ HorzSegmentsOverlap()

bool ClipperLib::HorzSegmentsOverlap ( cInt  seg1a,
cInt  seg1b,
cInt  seg2a,
cInt  seg2b 
)
580{
581 if (seg1a > seg1b) std::swap(seg1a, seg1b);
582 if (seg2a > seg2b) std::swap(seg2a, seg2b);
583 return (seg1a < seg2b) && (seg2a < seg1b);
584}

References HorzSegmentsOverlap().

Referenced by HorzSegmentsOverlap(), ClipperLib::Clipper::InsertLocalMinimaIntoAEL(), and ClipperLib::Clipper::ProcessHorizontal().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ InitEdge()

void ClipperLib::InitEdge ( TEdge e,
TEdge eNext,
TEdge ePrev,
const IntPoint Pt 
)
inline
426{
427 std::memset(e, 0, sizeof(TEdge));
428 e->Next = eNext;
429 e->Prev = ePrev;
430 e->Curr = Pt;
431 e->OutIdx = Unassigned;
432}
static int const Unassigned
Definition clipper.cpp:69

References ClipperLib::TEdge::Curr, InitEdge(), ClipperLib::TEdge::Next, ClipperLib::TEdge::OutIdx, ClipperLib::TEdge::Prev, and Unassigned.

Referenced by ClipperLib::ClipperBase::AddPathInternal(), and InitEdge().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ InitEdge2()

void ClipperLib::InitEdge2 ( TEdge e,
PolyType  Pt 
)
436{
437 if (e.Curr.y() >= e.Next->Curr.y())
438 {
439 e.Bot = e.Curr;
440 e.Top = e.Next->Curr;
441 } else
442 {
443 e.Top = e.Curr;
444 e.Bot = e.Next->Curr;
445 }
446
447 e.Delta.x() = (e.Top.x() - e.Bot.x());
448 e.Delta.y() = (e.Top.y() - e.Bot.y());
449
450 if (e.Delta.y() == 0) e.Dx = HORIZONTAL;
451 else e.Dx = (double)(e.Delta.x()) / e.Delta.y();
452
453 e.PolyTyp = Pt;
454}
double Dx
Definition clipper.hpp:240
PolyType PolyTyp
Definition clipper.hpp:241
IntPoint Delta
Definition clipper.hpp:238

References ClipperLib::TEdge::Bot, ClipperLib::TEdge::Curr, ClipperLib::TEdge::Delta, ClipperLib::TEdge::Dx, HORIZONTAL, InitEdge2(), ClipperLib::TEdge::Next, ClipperLib::TEdge::PolyTyp, and ClipperLib::TEdge::Top.

Referenced by ClipperLib::ClipperBase::AddPathInternal(), and InitEdge2().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IntersectPoint()

void ClipperLib::IntersectPoint ( TEdge Edge1,
TEdge Edge2,
IntPoint ip 
)
342{
343#ifdef CLIPPERLIB_USE_XYZ
344 ip.z() = 0;
345#endif
346
347 double b1, b2;
348 if (Edge1.Dx == Edge2.Dx)
349 {
350 ip.y() = Edge1.Curr.y();
351 ip.x() = TopX(Edge1, ip.y());
352 return;
353 }
354 else if (Edge1.Delta.x() == 0)
355 {
356 ip.x() = Edge1.Bot.x();
357 if (IsHorizontal(Edge2))
358 ip.y() = Edge2.Bot.y();
359 else
360 {
361 b2 = Edge2.Bot.y() - (Edge2.Bot.x() / Edge2.Dx);
362 ip.y() = Round(ip.x() / Edge2.Dx + b2);
363 }
364 }
365 else if (Edge2.Delta.x() == 0)
366 {
367 ip.x() = Edge2.Bot.x();
368 if (IsHorizontal(Edge1))
369 ip.y() = Edge1.Bot.y();
370 else
371 {
372 b1 = Edge1.Bot.y() - (Edge1.Bot.x() / Edge1.Dx);
373 ip.y() = Round(ip.x() / Edge1.Dx + b1);
374 }
375 }
376 else
377 {
378 b1 = double(Edge1.Bot.x()) - double(Edge1.Bot.y()) * Edge1.Dx;
379 b2 = double(Edge2.Bot.x()) - double(Edge2.Bot.y()) * Edge2.Dx;
380 double q = (b2-b1) / (Edge1.Dx - Edge2.Dx);
381 ip.y() = Round(q);
382 ip.x() = (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) ?
383 Round(Edge1.Dx * q + b1) :
384 Round(Edge2.Dx * q + b2);
385 }
386
387 if (ip.y() < Edge1.Top.y() || ip.y() < Edge2.Top.y())
388 {
389 if (Edge1.Top.y() > Edge2.Top.y())
390 ip.y() = Edge1.Top.y();
391 else
392 ip.y() = Edge2.Top.y();
393 if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
394 ip.x() = TopX(Edge1, ip.y());
395 else
396 ip.x() = TopX(Edge2, ip.y());
397 }
398 //finally, don't allow 'ip' to be BELOW curr.y() (ie bottom of scanbeam) ...
399 if (ip.y() > Edge1.Curr.y())
400 {
401 ip.y() = Edge1.Curr.y();
402 //use the more vertical edge to derive X ...
403 if (std::fabs(Edge1.Dx) > std::fabs(Edge2.Dx))
404 ip.x() = TopX(Edge2, ip.y()); else
405 ip.x() = TopX(Edge1, ip.y());
406 }
407}
cInt Round(double val)
Definition clipper.cpp:87

References ClipperLib::TEdge::Bot, ClipperLib::TEdge::Curr, ClipperLib::TEdge::Delta, ClipperLib::TEdge::Dx, IntersectPoint(), IsHorizontal(), Round(), ClipperLib::TEdge::Top, and TopX().

Referenced by ClipperLib::Clipper::BuildIntersectList(), and IntersectPoint().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IntPoint2d()

IntPoint ClipperLib::IntPoint2d ( cInt  x,
cInt  y 
)
inline
79{
80 return IntPoint(x, y
82 , 0
83#endif // CLIPPERLIB_USE_XYZ
84 );
85}
#define CLIPPERLIB_USE_XYZ
Definition clipper_z.cpp:4

References CLIPPERLIB_USE_XYZ, and IntPoint2d().

Referenced by ClipperLib::ClipperOffset::AddPath(), ClipperLib::ClipperOffset::DoMiter(), ClipperLib::ClipperOffset::DoOffset(), ClipperLib::ClipperOffset::DoRound(), ClipperLib::ClipperOffset::DoSquare(), ClipperLib::ClipperOffset::Execute(), ClipperLib::ClipperOffset::Execute(), IntPoint2d(), Minkowski(), ClipperLib::ClipperOffset::OffsetPoint(), ClipperLib::Clipper::ProcessHorizontal(), and TranslatePath().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IsHorizontal()

bool ClipperLib::IsHorizontal ( TEdge e)
inline
321{
322 return e.Delta.y() == 0;
323}

References ClipperLib::TEdge::Delta, and IsHorizontal().

Referenced by ClipperLib::Clipper::AddLocalMinPoly(), FindNextLocMin(), GetMaximaPair(), ClipperLib::Clipper::InsertLocalMinimaIntoAEL(), IntersectPoint(), IsHorizontal(), ClipperLib::ClipperBase::ProcessBound(), ClipperLib::Clipper::ProcessEdgesAtTopOfScanbeam(), ClipperLib::Clipper::ProcessHorizontal(), and ClipperLib::Clipper::UpdateEdgeIntoAEL().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IsIntermediate()

bool ClipperLib::IsIntermediate ( TEdge e,
const cInt  Y 
)
inline
2051{
2052 return e->Top.y() == Y && e->NextInLML;
2053}

References ClipperLib::TEdge::NextInLML, and ClipperLib::TEdge::Top.

Referenced by ClipperLib::Clipper::ProcessEdgesAtTopOfScanbeam().

+ Here is the caller graph for this function:

◆ IsMaxima()

bool ClipperLib::IsMaxima ( TEdge e,
const cInt  Y 
)
inline
2045{
2046 return e && e->Top.y() == Y && !e->NextInLML;
2047}

References ClipperLib::TEdge::NextInLML, and ClipperLib::TEdge::Top.

Referenced by ClipperLib::Clipper::ProcessEdgesAtTopOfScanbeam().

+ Here is the caller graph for this function:

◆ Minkowski()

void ClipperLib::Minkowski ( const Path poly,
const Path path,
Paths solution,
bool  isSum,
bool  isClosed 
)
3987{
3988 int delta = (isClosed ? 1 : 0);
3989 size_t polyCnt = poly.size();
3990 size_t pathCnt = path.size();
3991 Paths pp;
3992 pp.reserve(pathCnt);
3993 if (isSum)
3994 for (size_t i = 0; i < pathCnt; ++i)
3995 {
3996 Path p;
3997 p.reserve(polyCnt);
3998 for (size_t j = 0; j < poly.size(); ++j)
3999 p.emplace_back(IntPoint2d(path[i].x() + poly[j].x(), path[i].y() + poly[j].y()));
4000 pp.emplace_back(p);
4001 }
4002 else
4003 for (size_t i = 0; i < pathCnt; ++i)
4004 {
4005 Path p;
4006 p.reserve(polyCnt);
4007 for (size_t j = 0; j < poly.size(); ++j)
4008 p.emplace_back(IntPoint2d(path[i].x() - poly[j].x(), path[i].y() - poly[j].y()));
4009 pp.emplace_back(p);
4010 }
4011
4012 solution.clear();
4013 solution.reserve((pathCnt + delta) * (polyCnt + 1));
4014 for (size_t i = 0; i < pathCnt - 1 + delta; ++i)
4015 for (size_t j = 0; j < polyCnt; ++j)
4016 {
4017 Path quad;
4018 quad.reserve(4);
4019 quad.emplace_back(pp[i % pathCnt][j % polyCnt]);
4020 quad.emplace_back(pp[(i + 1) % pathCnt][j % polyCnt]);
4021 quad.emplace_back(pp[(i + 1) % pathCnt][(j + 1) % polyCnt]);
4022 quad.emplace_back(pp[i % pathCnt][(j + 1) % polyCnt]);
4023 if (!Orientation(quad)) ReversePath(quad);
4024 solution.emplace_back(quad);
4025 }
4026}
std::vector< IntPoint, Allocator< IntPoint > > Path
Definition clipper.hpp:121
IntPoint IntPoint2d(cInt x, cInt y)
Definition clipper.cpp:78
void ReversePath(Path &p)
Definition clipper.cpp:3811
std::vector< Path, Allocator< Path > > Paths
Definition clipper.hpp:122
Orientation
Definition geometry_traits.hpp:131

References IntPoint2d(), and ReversePath().

Referenced by MinkowskiDiff(), MinkowskiSum(), and MinkowskiSum().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ MinkowskiDiff()

void ClipperLib::MinkowskiDiff ( const Path poly1,
const Path poly2,
Paths solution 
)
4067{
4068 Minkowski(poly1, poly2, solution, false, true);
4069 Clipper c;
4070 c.AddPaths(solution, ptSubject, true);
4071 c.Execute(ctUnion, solution, pftNonZero, pftNonZero);
4072}
Definition clipper.hpp:420
void Minkowski(const Path &poly, const Path &path, Paths &solution, bool isSum, bool isClosed)
Definition clipper.cpp:3985

References ctUnion, Minkowski(), pftNonZero, and ptSubject.

+ Here is the call graph for this function:

◆ MinkowskiSum() [1/2]

void ClipperLib::MinkowskiSum ( const Path pattern,
const Path path,
Paths solution,
bool  pathIsClosed 
)
4030{
4031 Minkowski(pattern, path, solution, true, pathIsClosed);
4032 Clipper c;
4033 c.AddPaths(solution, ptSubject, true);
4034 c.Execute(ctUnion, solution, pftNonZero, pftNonZero);
4035}

References ctUnion, Minkowski(), pftNonZero, and ptSubject.

+ Here is the call graph for this function:

◆ MinkowskiSum() [2/2]

void ClipperLib::MinkowskiSum ( const Path pattern,
const Paths paths,
Paths solution,
bool  pathIsClosed 
)
4048{
4049 Clipper c;
4050 for (size_t i = 0; i < paths.size(); ++i)
4051 {
4052 Paths tmp;
4053 Minkowski(pattern, paths[i], tmp, true, pathIsClosed);
4054 c.AddPaths(tmp, ptSubject, true);
4055 if (pathIsClosed)
4056 {
4057 Path tmp2;
4058 TranslatePath(paths[i], tmp2, pattern[0]);
4059 c.AddPath(tmp2, ptClip, true);
4060 }
4061 }
4062 c.Execute(ctUnion, solution, pftNonZero, pftNonZero);
4063}
void TranslatePath(const Path &input, Path &output, const IntPoint &delta)
Definition clipper.cpp:4038

References ctUnion, Minkowski(), pftNonZero, ptClip, ptSubject, and TranslatePath().

+ Here is the call graph for this function:

◆ OpenPathsFromPolyTree()

void ClipperLib::OpenPathsFromPolyTree ( PolyTree polytree,
Paths paths 
)
4128{
4129 paths.clear();
4130 paths.reserve(polytree.Total());
4131 //Open paths are top level only, so ...
4132 for (int i = 0; i < polytree.ChildCount(); ++i)
4133 if (polytree.Childs[i]->IsOpen())
4134 paths.emplace_back(polytree.Childs[i]->Contour);
4135}

References ClipperLib::PolyNode::ChildCount(), ClipperLib::PolyNode::Childs, and ClipperLib::PolyTree::Total().

+ Here is the call graph for this function:

◆ operator!=()

bool ClipperLib::operator!= ( const IntPoint l,
const IntPoint r 
)
inline
94{ return l.x() != r.x() || l.y() != r.y(); }

References operator!=().

Referenced by operator!=().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ operator<<() [1/5]

Path & ClipperLib::operator<< ( Path poly,
const IntPoint p 
)
inline
124{poly.push_back(p); return poly;}

◆ operator<<() [2/5]

Paths & ClipperLib::operator<< ( Paths polys,
const Path p 
)
inline
125{polys.push_back(p); return polys;}

◆ operator<<() [3/5]

std::ostream & ClipperLib::operator<< ( std::ostream &  s,
const IntPoint p 
)
4139{
4140 s << "(" << p.x() << "," << p.y() << ")";
4141 return s;
4142}

◆ operator<<() [4/5]

std::ostream & ClipperLib::operator<< ( std::ostream &  s,
const Path p 
)
4146{
4147 if (p.empty()) return s;
4148 Path::size_type last = p.size() -1;
4149 for (Path::size_type i = 0; i < last; i++)
4150 s << "(" << p[i].x() << "," << p[i].y() << "), ";
4151 s << "(" << p[last].x() << "," << p[last].y() << ")\n";
4152 return s;
4153}

◆ operator<<() [5/5]

std::ostream & ClipperLib::operator<< ( std::ostream &  s,
const Paths p 
)
4157{
4158 for (Paths::size_type i = 0; i < p.size(); i++)
4159 s << p[i];
4160 s << "\n";
4161 return s;
4162}

◆ operator==()

bool ClipperLib::operator== ( const IntPoint l,
const IntPoint r 
)
inline
93{ return l.x() == r.x() && l.y() == r.y(); }

References operator==().

Referenced by operator==().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Orientation()

bool ClipperLib::Orientation ( const Path poly)
inline
200{ return Area(poly) >= 0; }

References Area().

Referenced by Slic3r::Polygon::is_counter_clockwise(), Slic3r::raw_offset(), and Slic3r::Algorithm::wavefront_step().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Param1RightOfParam2()

bool ClipperLib::Param1RightOfParam2 ( OutRec outRec1,
OutRec outRec2 
)
1850{
1851 do
1852 {
1853 outRec1 = outRec1->FirstLeft;
1854 if (outRec1 == outRec2) return true;
1855 } while (outRec1);
1856 return false;
1857}
OutRec * FirstLeft
Definition clipper.hpp:300

References ClipperLib::OutRec::FirstLeft.

Referenced by ClipperLib::Clipper::AppendPolygon(), and ClipperLib::Clipper::JoinCommonEdges().

+ Here is the caller graph for this function:

◆ PointCount()

int ClipperLib::PointCount ( OutPt Pts)
2740{
2741 if (!Pts) return 0;
2742 int result = 0;
2743 OutPt* p = Pts;
2744 do
2745 {
2746 result++;
2747 p = p->Next;
2748 }
2749 while (p != Pts);
2750 return result;
2751}

References ClipperLib::OutPt::Next.

Referenced by ClipperLib::Clipper::BuildResult(), and ClipperLib::Clipper::BuildResult2().

+ Here is the caller graph for this function:

◆ PointInPolygon() [1/2]

int ClipperLib::PointInPolygon ( const IntPoint pt,
const Path path 
)
201{
202 //returns 0 if false, +1 if true, -1 if pt ON polygon boundary
203 int result = 0;
204 size_t cnt = path.size();
205 if (cnt < 3) return 0;
206 IntPoint ip = path[0];
207 for(size_t i = 1; i <= cnt; ++i)
208 {
209 IntPoint ipNext = (i == cnt ? path[0] : path[i]);
210 if (ipNext.y() == pt.y() && ((ipNext.x() == pt.x()) || (ip.y() == pt.y() && ((ipNext.x() > pt.x()) == (ip.x() < pt.x())))))
211 return -1;
212 if ((ip.y() < pt.y()) != (ipNext.y() < pt.y()))
213 {
214 if (ip.x() >= pt.x())
215 {
216 if (ipNext.x() > pt.x()) result = 1 - result;
217 else
218 {
219 auto d = CrossProductType(ip.x() - pt.x()) * CrossProductType(ipNext.y() - pt.y()) - CrossProductType(ipNext.x() - pt.x()) * CrossProductType(ip.y() - pt.y());
220 if (!d) return -1;
221 if ((d > 0) == (ipNext.y() > ip.y())) result = 1 - result;
222 }
223 } else
224 {
225 if (ipNext.x() > pt.x())
226 {
227 auto d = CrossProductType(ip.x() - pt.x()) * CrossProductType(ipNext.y() - pt.y()) - CrossProductType(ipNext.x() - pt.x()) * CrossProductType(ip.y() - pt.y());
228 if (!d) return -1;
229 if ((d > 0) == (ipNext.y() > ip.y())) result = 1 - result;
230 }
231 }
232 }
233 ip = ipNext;
234 }
235 return result;
236}
int64_t CrossProductType
Definition clipper.hpp:92

References PointInPolygon().

Referenced by Slic3r::contains(), Slic3r::contains(), PointInPolygon(), PointInPolygon(), and Poly2ContainsPoly1().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PointInPolygon() [2/2]

int ClipperLib::PointInPolygon ( const IntPoint pt,
OutPt op 
)
241{
242 //returns 0 if false, +1 if true, -1 if pt ON polygon boundary
243 int result = 0;
244 OutPt* startOp = op;
245 do
246 {
247 if (op->Next->Pt.y() == pt.y())
248 {
249 if ((op->Next->Pt.x() == pt.x()) || (op->Pt.y() == pt.y() &&
250 ((op->Next->Pt.x() > pt.x()) == (op->Pt.x() < pt.x())))) return -1;
251 }
252 if ((op->Pt.y() < pt.y()) != (op->Next->Pt.y() < pt.y()))
253 {
254 if (op->Pt.x() >= pt.x())
255 {
256 if (op->Next->Pt.x() > pt.x()) result = 1 - result;
257 else
258 {
259 auto d = CrossProductType(op->Pt.x() - pt.x()) * CrossProductType(op->Next->Pt.y() - pt.y()) - CrossProductType(op->Next->Pt.x() - pt.x()) * CrossProductType(op->Pt.y() - pt.y());
260 if (!d) return -1;
261 if ((d > 0) == (op->Next->Pt.y() > op->Pt.y())) result = 1 - result;
262 }
263 } else
264 {
265 if (op->Next->Pt.x() > pt.x())
266 {
267 auto d = CrossProductType(op->Pt.x() - pt.x()) * CrossProductType(op->Next->Pt.y() - pt.y()) - CrossProductType(op->Next->Pt.x() - pt.x()) * CrossProductType(op->Pt.y() - pt.y());
268 if (!d) return -1;
269 if ((d > 0) == (op->Next->Pt.y() > op->Pt.y())) result = 1 - result;
270 }
271 }
272 }
273 op = op->Next;
274 } while (startOp != op);
275 return result;
276}

References ClipperLib::OutPt::Next, PointInPolygon(), and ClipperLib::OutPt::Pt.

+ Here is the call graph for this function:

◆ PointIsVertex()

bool ClipperLib::PointIsVertex ( const IntPoint Pt,
OutPt pp 
)
186{
187 OutPt *pp2 = pp;
188 do
189 {
190 if (pp2->Pt == Pt) return true;
191 pp2 = pp2->Next;
192 }
193 while (pp2 != pp);
194 return false;
195}

References ClipperLib::OutPt::Next, PointIsVertex(), and ClipperLib::OutPt::Pt.

Referenced by PointIsVertex().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PointsAreClose()

bool ClipperLib::PointsAreClose ( IntPoint  pt1,
IntPoint  pt2,
double  distSqrd 
)
3889{
3890 auto Dx = double(pt1.x() - pt2.x());
3891 auto dy = double(pt1.y() - pt2.y());
3892 return ((Dx * Dx) + (dy * dy) <= distSqrd);
3893}

Referenced by CleanPolygon().

+ Here is the caller graph for this function:

◆ Poly2ContainsPoly1()

bool ClipperLib::Poly2ContainsPoly1 ( OutPt OutPt1,
OutPt OutPt2 
)
281{
282 OutPt* op = OutPt1;
283 do
284 {
285 //nb: PointInPolygon returns 0 if false, +1 if true, -1 if pt on polygon
286 int res = PointInPolygon(op->Pt, OutPt2);
287 if (res >= 0) return res > 0;
288 op = op->Next;
289 }
290 while (op != OutPt1);
291 return true;
292}
int PointInPolygon(const IntPoint &pt, const Path &path)
Definition clipper.cpp:200

References ClipperLib::OutPt::Next, PointInPolygon(), Poly2ContainsPoly1(), and ClipperLib::OutPt::Pt.

Referenced by ClipperLib::Clipper::DoSimplePolygons(), ClipperLib::Clipper::FixupFirstLefts1(), ClipperLib::Clipper::JoinCommonEdges(), and Poly2ContainsPoly1().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PolyTreeToPaths() [1/2]

void ClipperLib::PolyTreeToPaths ( const PolyTree polytree,
Paths paths 
)
4104{
4105 paths.clear();
4106 paths.reserve(polytree.Total());
4107 AddPolyNodeToPaths(polytree, ntAny, paths);
4108}

References AddPolyNodeToPaths(), ntAny, and ClipperLib::PolyTree::Total().

+ Here is the call graph for this function:

◆ PolyTreeToPaths() [2/2]

void ClipperLib::PolyTreeToPaths ( PolyTree &&  polytree,
Paths paths 
)
4111{
4112 paths.clear();
4113 paths.reserve(polytree.Total());
4114 AddPolyNodeToPaths(std::move(polytree), ntAny, paths);
4115}

References AddPolyNodeToPaths(), and ntAny.

+ Here is the call graph for this function:

◆ Pt2IsBetweenPt1AndPt3()

bool ClipperLib::Pt2IsBetweenPt1AndPt3 ( const IntPoint pt1,
const IntPoint pt2,
const IntPoint pt3 
)
569{
570 if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2))
571 return false;
572 else if (pt1.x() != pt3.x())
573 return (pt2.x() > pt1.x()) == (pt2.x() < pt3.x());
574 else
575 return (pt2.y() > pt1.y()) == (pt2.y() < pt3.y());
576}

References Pt2IsBetweenPt1AndPt3().

Referenced by ClipperLib::ClipperBase::AddPathInternal(), ClipperLib::Clipper::FixupOutPolygon(), and Pt2IsBetweenPt1AndPt3().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RangeTest()

static void ClipperLib::RangeTest ( const IntPoint pt)
inlinestatic
592{
593#ifndef NDEBUG
594 static constexpr const int32_t hi = 65536 * 16383;
595 if (pt.x() > hi || pt.y() > hi || -pt.x() > hi || -pt.y() > hi)
596 throw clipperException("Coordinate outside allowed range");
597#endif // NDEBUG
598}
Definition clipper.hpp:580
__int32 int32_t
Definition unistd.h:75

References RangeTest().

Referenced by ClipperLib::ClipperBase::AddPathInternal(), and RangeTest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RemoveEdge()

TEdge * ClipperLib::RemoveEdge ( TEdge e)
inline
459{
460 //removes e from double_linked_list (but without removing from memory)
461 e->Prev->Next = e->Next;
462 e->Next->Prev = e->Prev;
463 TEdge* result = e->Next;
464 e->Prev = 0; //flag as removed (see ClipperBase.Clear)
465 return result;
466}

References ClipperLib::TEdge::Next, ClipperLib::TEdge::Prev, and RemoveEdge().

Referenced by ClipperLib::ClipperBase::AddPathInternal(), and RemoveEdge().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReverseHorizontal()

void ClipperLib::ReverseHorizontal ( TEdge e)
inline
470{
471 //swap horizontal edges' Top and Bottom x's so they follow the natural
472 //progression of the bounds - ie so their xbots will align with the
473 //adjoining lower edge. [Helpful in the ProcessHorizontal() method.]
474 std::swap(e.Top.x(), e.Bot.x());
475#ifdef CLIPPERLIB_USE_XYZ
476 std::swap(e.Top.z(), e.Bot.z());
477#endif
478}

References ClipperLib::TEdge::Bot, ReverseHorizontal(), and ClipperLib::TEdge::Top.

Referenced by ClipperLib::ClipperBase::AddPathInternal(), ClipperLib::ClipperBase::ProcessBound(), and ReverseHorizontal().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReversePath()

void ClipperLib::ReversePath ( Path p)
3812{
3813 std::reverse(p.begin(), p.end());
3814}

Referenced by ClipperLib::ClipperOffset::FixOrientations(), Minkowski(), and ReversePaths().

+ Here is the caller graph for this function:

◆ ReversePaths()

void ClipperLib::ReversePaths ( Paths p)
3818{
3819 for (Paths::size_type i = 0; i < p.size(); ++i)
3820 ReversePath(p[i]);
3821}

References ReversePath().

+ Here is the call graph for this function:

◆ ReversePolyPtLinks()

void ClipperLib::ReversePolyPtLinks ( OutPt pp)
413{
414 if (!pp) return;
415 OutPt *pp1 = pp;
416 do {
417 OutPt *pp2 = pp1->Next;
418 pp1->Next = pp1->Prev;
419 pp1->Prev = pp2;
420 pp1 = pp2;
421 } while( pp1 != pp );
422}

References ClipperLib::OutPt::Next, ClipperLib::OutPt::Prev, and ReversePolyPtLinks().

Referenced by ClipperLib::Clipper::AppendPolygon(), ClipperLib::Clipper::ExecuteInternal(), ClipperLib::Clipper::JoinCommonEdges(), and ReversePolyPtLinks().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Round()

cInt ClipperLib::Round ( double  val)
inline
88{
89 return static_cast<cInt>((val < 0) ? (val - 0.5) : (val + 0.5));
90}
int32_t cInt
Definition clipper.hpp:91

References Round().

Referenced by ClipperLib::ClipperOffset::DoMiter(), ClipperLib::ClipperOffset::DoOffset(), ClipperLib::ClipperOffset::DoRound(), ClipperLib::ClipperOffset::DoSquare(), IntersectPoint(), ClipperLib::ClipperOffset::OffsetPoint(), Round(), and TopX().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SimplifyPolygon()

Paths ClipperLib::SimplifyPolygon ( const Path in_poly,
PolyFillType  fillType,
bool  strictly_simple 
)
3825{
3826 Clipper c;
3827 c.StrictlySimple(strictly_simple);
3828 c.AddPath(in_poly, ptSubject, true);
3829 Paths out;
3830 c.Execute(ctUnion, out, fillType, fillType);
3831 return out;
3832}

References ctUnion, and ptSubject.

◆ SimplifyPolygons()

template<typename PathsProvider >
Paths ClipperLib::SimplifyPolygons ( PathsProvider &&  in_polys,
PolyFillType  fillType = pftNonZero,
bool  strictly_simple = true 
)
inline
592 {
593 Clipper c;
594 c.StrictlySimple(strictly_simple);
595 c.AddPaths(std::forward<PathsProvider>(in_polys), ptSubject, true);
596 Paths out;
597 c.Execute(ctUnion, out, fillType, fillType);
598 return out;
599}

References ctUnion, ptSubject, and SimplifyPolygons().

Referenced by Slic3r::Arachne::fixSelfIntersections(), Slic3r::Emboss::heal_shape(), Slic3r::simplify_polygon_impl(), and SimplifyPolygons().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SlopesEqual() [1/4]

bool ClipperLib::SlopesEqual ( const cInt  dx1,
const cInt  dy1,
const cInt  dx2,
const cInt  dy2,
bool   
)
inline
296 {
297 return int64_t(dy1) * int64_t(dx2) == int64_t(dx1) * int64_t(dy2);
298}
__int64 int64_t
Definition unistd.h:76

References SlopesEqual().

Referenced by ClipperLib::Clipper::AddLocalMinPoly(), ClipperLib::ClipperBase::AddPathInternal(), ClipperLib::Clipper::FixupOutPolygon(), ClipperLib::Clipper::InsertLocalMinimaIntoAEL(), ClipperLib::Clipper::JoinPoints(), ClipperLib::Clipper::ProcessEdgesAtTopOfScanbeam(), ClipperLib::Clipper::ProcessHorizontal(), SlopesEqual(), SlopesEqual(), SlopesEqual(), and SlopesEqual().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SlopesEqual() [2/4]

bool ClipperLib::SlopesEqual ( const IntPoint pt1,
const IntPoint pt2,
const IntPoint pt3,
bool  UseFullInt64Range 
)
inline
314 { return SlopesEqual(pt1.x()-pt2.x(), pt1.y()-pt2.y(), pt2.x()-pt3.x(), pt2.y()-pt3.y(), UseFullInt64Range); }
bool SlopesEqual(const cInt dx1, const cInt dy1, const cInt dx2, const cInt dy2, bool)
Definition clipper.cpp:296

References SlopesEqual().

+ Here is the call graph for this function:

◆ SlopesEqual() [3/4]

bool ClipperLib::SlopesEqual ( const IntPoint pt1,
const IntPoint pt2,
const IntPoint pt3,
const IntPoint pt4,
bool  UseFullInt64Range 
)
inline
316 { return SlopesEqual(pt1.x()-pt2.x(), pt1.y()-pt2.y(), pt3.x()-pt4.x(), pt3.y()-pt4.y(), UseFullInt64Range); }

References SlopesEqual().

+ Here is the call graph for this function:

◆ SlopesEqual() [4/4]

bool ClipperLib::SlopesEqual ( const TEdge e1,
const TEdge e2,
bool  UseFullInt64Range 
)
inline
312 { return SlopesEqual(e1.Delta.x(), e1.Delta.y(), e2.Delta.x(), e2.Delta.y(), UseFullInt64Range); }

References ClipperLib::TEdge::Delta, and SlopesEqual().

+ Here is the call graph for this function:

◆ SlopesNearCollinear()

bool ClipperLib::SlopesNearCollinear ( const IntPoint pt1,
const IntPoint pt2,
const IntPoint pt3,
double  distSqrd 
)
3863{
3864 //this function is more accurate when the point that's geometrically
3865 //between the other 2 points is the one that's tested for distance.
3866 //ie makes it more likely to pick up 'spikes' ...
3867 if (std::abs(pt1.x() - pt2.x()) > std::abs(pt1.y() - pt2.y()))
3868 {
3869 if ((pt1.x() > pt2.x()) == (pt1.x() < pt3.x()))
3870 return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd;
3871 else if ((pt2.x() > pt1.x()) == (pt2.x() < pt3.x()))
3872 return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd;
3873 else
3874 return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd;
3875 }
3876 else
3877 {
3878 if ((pt1.y() > pt2.y()) == (pt1.y() < pt3.y()))
3879 return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd;
3880 else if ((pt2.y() > pt1.y()) == (pt2.y() < pt3.y()))
3881 return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd;
3882 else
3883 return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd;
3884 }
3885}
double DistanceFromLineSqrd(const IntPoint &pt, const IntPoint &ln1, const IntPoint &ln2)
Definition clipper.cpp:3844

References DistanceFromLineSqrd().

Referenced by CleanPolygon().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ TopX()

cInt ClipperLib::TopX ( TEdge edge,
const cInt  currentY 
)
inline
334{
335 return (currentY == edge.Top.y()) ?
336 edge.Top.x() :
337 edge.Bot.x() + Round(edge.Dx *(currentY - edge.Bot.y()));
338}

References ClipperLib::TEdge::Bot, ClipperLib::TEdge::Dx, Round(), ClipperLib::TEdge::Top, and TopX().

Referenced by ClipperLib::Clipper::AddLocalMinPoly(), ClipperLib::Clipper::BuildIntersectList(), E2InsertsBeforeE1(), IntersectPoint(), ClipperLib::Clipper::ProcessEdgesAtTopOfScanbeam(), and TopX().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ TranslatePath()

void ClipperLib::TranslatePath ( const Path input,
Path output,
const IntPoint delta 
)
4039{
4040 //precondition: input != output
4041 output.resize(input.size());
4042 for (size_t i = 0; i < input.size(); ++i)
4043 output[i] = IntPoint2d(input[i].x() + delta.x(), input[i].y() + delta.y());
4044}
static int input(void)

References input(), and IntPoint2d().

Referenced by MinkowskiSum().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ UpdateOutPtIdxs()

void ClipperLib::UpdateOutPtIdxs ( OutRec outrec)
inline
2862{
2863 OutPt* op = outrec.Pts;
2864 do
2865 {
2866 op->Idx = outrec.Idx;
2867 op = op->Prev;
2868 }
2869 while(op != outrec.Pts);
2870}
int Idx
Definition clipper.hpp:291

References ClipperLib::OutPt::Idx, ClipperLib::OutRec::Idx, ClipperLib::OutPt::Prev, and ClipperLib::OutRec::Pts.

Referenced by ClipperLib::Clipper::DoSimplePolygons(), and ClipperLib::Clipper::JoinCommonEdges().

+ Here is the caller graph for this function:

Variable Documentation

◆ def_arc_tolerance

double const ClipperLib::def_arc_tolerance = 0.25
static

◆ pi

double const ClipperLib::pi = 3.141592653589793238
static

◆ Skip

◆ two_pi

double const ClipperLib::two_pi = pi *2
static

◆ Unassigned