54#include "clipper2/clipper.h"
71 static bool to_Paths (
const CSG_Shapes *pShapes, Clipper2Lib::PathsD &Paths)
80 for(
sLong iShape=0, iPath=0; iShape<pShapes->
Get_Count(); iShape++)
82 CSG_Shape &Shape = *pShapes->
Get_Shape(iShape);
90 Paths.resize(1 + iPath);
97 Paths[iPath][iPoint].
x = p.
x;
98 Paths[iPath][iPoint].y = p.
y;
103 return( Paths.size() > 0 );
107 static bool to_Shape (
const Clipper2Lib::PathsD &Paths, CSG_Shapes *pShapes)
113 static bool to_Paths (
const CSG_Shape *pShape, Clipper2Lib::PathsD &Paths,
bool bCheckOrientation =
true)
122 for(
int iPart=0, iPath=0; iPart<pShape->
Get_Part_Count(); iPart++, iPath++)
130 Paths.resize(1 + iPath);
136 Clipper2Lib::PointD Point(p.
x, p.
y);
138 if( iPoint == 0 || Paths[iPath].back() != Point )
140 Paths[iPath].push_back(Point);
146 Paths[iPath].pop_back();
151 return( Paths.size() > 0 );
155 static bool to_Shape (
const Clipper2Lib::PathsD &Paths, CSG_Shape *pShape)
164 for(
size_t iPath=0; iPath<Paths.size(); iPath++)
166 for(
size_t iPoint=0; iPoint<Paths[iPath].size(); iPoint++)
168 pShape->
Add_Point(Paths[iPath][iPoint].x, Paths[iPath][iPoint].y, (
int)iPath);
176 static bool Clip (Clipper2Lib::ClipType ClipType, CSG_Shape *pSubject, CSG_Shape_Polygon *pClip, CSG_Shape *pSolution)
178 Clipper2Lib::PathsD Subject, Clip, Solution;
180 if( to_Paths(pSubject, Subject)
181 && to_Paths(pClip , Clip ) )
183 Clipper2Lib::ClipperD Clipper(m_Precision);
185 Clipper.AddClip(Clip);
189 Clipper.AddSubject(Subject);
191 if( !Clipper.Execute(ClipType, Clipper2Lib::FillRule::NonZero, Solution) )
198 Clipper.AddOpenSubject(Subject);
200 if( !Clipper.Execute(ClipType, Clipper2Lib::FillRule::NonZero, Solution) )
206 return( to_Shape(Solution, pSolution ? pSolution : pSubject) );
213 static bool Dissolve (CSG_Shape *pShape, CSG_Shape *pSolution)
215 Clipper2Lib::PathsD Subject, Solution;
217 if( to_Paths(pShape, Subject,
false) )
219 Clipper2Lib::ClipperD Clipper(m_Precision);
221 Clipper.AddSubject(Subject);
223 if( Clipper.Execute(Clipper2Lib::ClipType::Union, Clipper2Lib::FillRule::NonZero, Solution) )
225 return( to_Shape(Solution, pSolution ? pSolution : pShape) );
235 Clipper2Lib::PathsD Paths, Solution;
237 if( to_Paths(pShape, Paths) )
239 Clipper2Lib::EndType ClipperEndType;
243 ClipperEndType = Clipper2Lib::EndType(EndType);
247 ClipperEndType = Clipper2Lib::EndType::Polygon;
250 double ArcTolerance = std::pow(10., m_Precision) * Delta * (1. - cos(dArc / 2.));
252 Solution = Clipper2Lib::InflatePaths(Paths, Delta, Clipper2Lib::JoinType(JoinType), ClipperEndType, 2., m_Precision, ArcTolerance);
254 return( to_Shape(Solution, pSolution ? pSolution : pShape) );
261 static int Get_Precision (
void) {
return( m_Precision ); }
263 static bool Set_Precision (
int Precision)
265 if( Precision < -8 || Precision > 8 )
270 m_Precision = Precision;
277 static int m_Precision;
281int CSG_Clipper::m_Precision = 4;
300 return( !pSolution || pSolution->
Assign(pShape,
false) );
303 return( !pSolution ? pShape->
Assign(pClip,
false) : pSolution->
Assign(pClip,
false) );
306 return( CSG_Clipper::Clip(Clipper2Lib::ClipType::Intersection, pShape, pClip, pSolution) );
316 return( !pSolution || pSolution->
Assign(pShape,
false) );
324 return( CSG_Clipper::Clip(Clipper2Lib::ClipType::Difference, pShape, pClip, pSolution) );
334 if( pSolution ) { pSolution->
Assign(pShape,
false); }
else { pSolution = pShape; }
348 return( CSG_Clipper::Clip(Clipper2Lib::ClipType::Xor, pShape, pClip, pSolution) );
358 if( pSolution ) { pSolution->
Assign(pShape,
false); }
else { pSolution = pShape; }
368 return( !pSolution || pSolution->
Assign(pShape,
false) );
371 return( !pSolution ? pShape->
Assign(pClip,
false) : pSolution->
Assign(pClip,
false) );
374 return( CSG_Clipper::Clip(Clipper2Lib::ClipType::Union, pShape, pClip, pSolution) );
390 return( CSG_Clipper::Dissolve(pShape, pSolution) );
396 return( CSG_Clipper::Offset(pShape, Size, dArc, pSolution, JoinType, EndType) );
virtual CSG_Shape_Part * Get_Part(int iPart) const
virtual int Get_Part_Count(void) const
bool is_Clockwise(int iPart)
virtual int Get_Point_Count(void) const =0
TSG_Intersection Intersects(CSG_Shape *pShape)
class CSG_Shape_Polygon * asPolygon(void) const
virtual int Add_Part(class CSG_Shape_Part *pPart, bool bRevert=false)
TSG_Shape_Type Get_Type(void) const
virtual int Add_Point(double x, double y, int iPart=0)=0
virtual int Get_Part_Count(void) const =0
virtual TSG_Point Get_Point(int iPoint=0) const =0
virtual int Del_Parts(void)
virtual bool Assign(CSG_Table_Record *pRecord)
virtual CSG_Shape * Add_Shape(CSG_Table_Record *pCopy=NULL, TSG_ADD_Shape_Copy_Mode mCopy=SHAPE_COPY)
virtual bool Del_Shapes(void)
virtual CSG_Shape * Get_Shape(const CSG_Point &Point, double Epsilon=0.)
virtual bool is_Valid(void) const
sLong Get_Count(void) const
bool SG_Shape_Get_ExclusiveOr(CSG_Shape *pShape, CSG_Shape_Polygon *pClip, CSG_Shape *pSolution)
bool SG_Shape_Get_Difference(CSG_Shape *pShape, CSG_Shape_Polygon *pClip, CSG_Shape *pSolution)
bool SG_Shape_Get_Union(CSG_Shape *pShape, CSG_Shape_Polygon *pClip, CSG_Shape *pSolution)
const char * SG_Clipper_Get_Version(void)
bool SG_Shape_Get_Offset(CSG_Shape *pShape, double Size, double dArc, CSG_Shape *pSolution, TSG_Line_JoinType JoinType, TSG_Line_EndType EndType)
bool SG_Shape_Get_Intersection(CSG_Shape *pShape, CSG_Shape_Polygon *pClip, CSG_Shape *pSolution)
bool SG_Shape_Get_Dissolve(CSG_Shape *pShape, CSG_Shape *pSolution)