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++)
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);
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) );
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) );
233 static bool Offset (
CSG_Shape *pShape,
double Delta,
double dArc,
CSG_Shape *pSolution)
235 Clipper2Lib::PathsD Paths, Solution;
237 if( to_Paths(pShape, Paths) )
239 Clipper2Lib::EndType EndType;
245 EndType = Clipper2Lib::EndType::Round;
249 EndType = Clipper2Lib::EndType::Polygon;
252 double ArcTolerance = std::pow(10., m_Precision) * Delta * (1. - cos(dArc / 2.));
254 Solution = Clipper2Lib::InflatePaths(Paths, Delta, Clipper2Lib::JoinType::Round, EndType, 2., m_Precision, ArcTolerance);
256 return( to_Shape(Solution, pSolution ? pSolution : pShape) );
263 static int Get_Precision (
void) {
return( m_Precision ); }
265 static bool Set_Precision (
int Precision)
267 if( Precision < -8 || Precision > 8 )
272 m_Precision = Precision;
279 static int m_Precision;
283 int CSG_Clipper::m_Precision = 4;
302 return( !pSolution || pSolution->
Assign(pShape,
false) );
305 return( !pSolution ? pShape->
Assign(pClip,
false) : pSolution->
Assign(pClip,
false) );
308 return( CSG_Clipper::Clip(Clipper2Lib::ClipType::Intersection, pShape, pClip, pSolution) );
318 return( !pSolution || pSolution->
Assign(pShape,
false) );
326 return( CSG_Clipper::Clip(Clipper2Lib::ClipType::Difference, pShape, pClip, pSolution) );
336 if( pSolution ) { pSolution->
Assign(pShape,
false); }
else { pSolution = pShape; }
350 return( CSG_Clipper::Clip(Clipper2Lib::ClipType::Xor, pShape, pClip, pSolution) );
360 if( pSolution ) { pSolution->
Assign(pShape,
false); }
else { pSolution = pShape; }
370 return( !pSolution || pSolution->
Assign(pShape,
false) );
373 return( !pSolution ? pShape->
Assign(pClip,
false) : pSolution->
Assign(pClip,
false) );
376 return( CSG_Clipper::Clip(Clipper2Lib::ClipType::Union, pShape, pClip, pSolution) );
392 return( CSG_Clipper::Dissolve(pShape, pSolution) );
398 return( CSG_Clipper::Offset(pShape, Size, dArc, pSolution) );