diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index 3fad5fd9f9..0006a31a4e 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -25,18 +25,6 @@ sub safety_offset_ex { @{Math::Clipper::ex_int_offset(_convert($polygons), $factor // (scale 1e-05), 100000, JT_MITER, 2)}; } -sub diff { - my ($subject, $clip, $safety_offset) = @_; - - $clipper->clear; - $clipper->add_subject_polygons(_convert($subject)); - $clipper->add_clip_polygons($safety_offset ? _convert(safety_offset($clip)) : _convert($clip)); - return [ - map Slic3r::Polygon->new(@$_), - @{ $clipper->execute(CT_DIFFERENCE, PFT_NONZERO, PFT_NONZERO) }, - ]; -} - sub union_pt { my ($polygons, $jointype, $safety_offset) = @_; $jointype = PFT_NONZERO unless defined $jointype; @@ -45,18 +33,6 @@ sub union_pt { return $clipper->pt_execute(CT_UNION, $jointype, $jointype); } -sub intersection { - my ($subject, $clip, $jointype, $safety_offset) = @_; - $jointype = PFT_NONZERO unless defined $jointype; - $clipper->clear; - $clipper->add_subject_polygons(_convert($subject)); - $clipper->add_clip_polygons($safety_offset ? _convert(safety_offset($clip)) : _convert($clip)); - return [ - map Slic3r::Polygon->new(@$_), - @{ $clipper->execute(CT_INTERSECTION, $jointype, $jointype) }, - ]; -} - sub collapse_ex { my ($polygons, $width) = @_; return offset2_ex($polygons, -$width/2, +$width/2); diff --git a/xs/src/ClipperUtils.cpp b/xs/src/ClipperUtils.cpp index a18dcb720d..20b20e45ad 100644 --- a/xs/src/ClipperUtils.cpp +++ b/xs/src/ClipperUtils.cpp @@ -192,8 +192,9 @@ offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float d delete output; } -inline void _clipper_ex(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, - Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset) +template +void _clipper_do(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, + Slic3r::Polygons &clip, T &retval, bool safety_offset) { // read input ClipperLib::Polygons* input_subject = new ClipperLib::Polygons(); @@ -220,37 +221,60 @@ inline void _clipper_ex(ClipperLib::ClipType clipType, Slic3r::Polygons &subject clipper.AddPolygons(*input_clip, ClipperLib::ptClip); delete input_clip; + // perform operation + clipper.Execute(clipType, retval, ClipperLib::pftNonZero, ClipperLib::pftNonZero); +} + +void _clipper(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, + Slic3r::Polygons &clip, Slic3r::Polygons &retval, bool safety_offset) +{ + // perform operation + ClipperLib::Polygons* output = new ClipperLib::Polygons(); + _clipper_do(clipType, subject, clip, *output, safety_offset); + + // convert into Polygons + ClipperPolygons_to_Slic3rPolygons(*output, retval); + delete output; +} + +void _clipper(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, + Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset) +{ // perform operation ClipperLib::PolyTree* polytree = new ClipperLib::PolyTree(); - clipper.Execute(clipType, *polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero); + _clipper_do(clipType, subject, clip, *polytree, safety_offset); // convert into ExPolygons PolyTreeToExPolygons(*polytree, retval); delete polytree; } -void -diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset) +template +void diff(Slic3r::Polygons &subject, Slic3r::Polygons &clip, T &retval, bool safety_offset) { - _clipper_ex(ClipperLib::ctDifference, subject, clip, retval, safety_offset); + _clipper(ClipperLib::ctDifference, subject, clip, retval, safety_offset); } +template void diff(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset); +template void diff(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::Polygons &retval, bool safety_offset); -void intersection_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, - bool safety_offset) +template +void intersection(Slic3r::Polygons &subject, Slic3r::Polygons &clip, T &retval, bool safety_offset) { - _clipper_ex(ClipperLib::ctIntersection, subject, clip, retval, safety_offset); + _clipper(ClipperLib::ctIntersection, subject, clip, retval, safety_offset); } +template void intersection(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset); +template void intersection(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::Polygons &retval, bool safety_offset); void xor_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset) { - _clipper_ex(ClipperLib::ctXor, subject, clip, retval, safety_offset); + _clipper(ClipperLib::ctXor, subject, clip, retval, safety_offset); } void union_ex(Slic3r::Polygons &subject, Slic3r::ExPolygons &retval, bool safety_offset) { Slic3r::Polygons p; - _clipper_ex(ClipperLib::ctUnion, subject, p, retval, safety_offset); + _clipper(ClipperLib::ctUnion, subject, p, retval, safety_offset); } } diff --git a/xs/src/ClipperUtils.hpp b/xs/src/ClipperUtils.hpp index 710d35ab53..a40216c614 100644 --- a/xs/src/ClipperUtils.hpp +++ b/xs/src/ClipperUtils.hpp @@ -43,14 +43,23 @@ void offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const fl const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3); -inline void _clipper_ex(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, - Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, - bool safety_offset); -void diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset = false); -void intersection_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, - bool safety_offset = false); +template +void _clipper_do(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, + Slic3r::Polygons &clip, T &retval, bool safety_offset); +void _clipper(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, + Slic3r::Polygons &clip, Slic3r::Polygons &retval, bool safety_offset); +void _clipper(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, + Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset); + +template +void diff(Slic3r::Polygons &subject, Slic3r::Polygons &clip, T &retval, bool safety_offset); + +template +void intersection(Slic3r::Polygons &subject, Slic3r::Polygons &clip, T &retval, bool safety_offset); + void xor_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset = false); + void union_ex(Slic3r::Polygons &subject, Slic3r::ExPolygons &retval, bool safety_offset = false); } diff --git a/xs/xsp/Clipper.xsp b/xs/xsp/Clipper.xsp index 3cdbeae4be..0f996af4e7 100644 --- a/xs/xsp/Clipper.xsp +++ b/xs/xsp/Clipper.xsp @@ -60,13 +60,33 @@ offset2_ex(polygons, delta1, delta2, scale = 100000, joinType = ClipperLib::jtMi OUTPUT: RETVAL +Polygons +diff(subject, clip, safety_offset = false) + Polygons subject + Polygons clip + bool safety_offset + CODE: + diff(subject, clip, RETVAL, safety_offset); + OUTPUT: + RETVAL + ExPolygons diff_ex(subject, clip, safety_offset = false) Polygons subject Polygons clip bool safety_offset CODE: - diff_ex(subject, clip, RETVAL, safety_offset); + diff(subject, clip, RETVAL, safety_offset); + OUTPUT: + RETVAL + +Polygons +intersection(subject, clip, safety_offset = false) + Polygons subject + Polygons clip + bool safety_offset + CODE: + intersection(subject, clip, RETVAL, safety_offset); OUTPUT: RETVAL @@ -76,7 +96,7 @@ intersection_ex(subject, clip, safety_offset = false) Polygons clip bool safety_offset CODE: - intersection_ex(subject, clip, RETVAL, safety_offset); + intersection(subject, clip, RETVAL, safety_offset); OUTPUT: RETVAL