diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index b31032c9d9..edc5bfe72f 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -70,7 +70,7 @@ sub make_fill { @groups = sort { defined $a->[0]->bridge_angle ? -1 : 0 } @groups; foreach my $group (@groups) { - my $union = union_ex([ map $_->p, @$group ], undef, 1); + my $union = union_ex([ map $_->p, @$group ], 1); # subtract surfaces having a defined bridge_angle from any other if (@surfaces_with_bridge_angle && !defined $group->[0]->bridge_angle) { @@ -120,7 +120,6 @@ sub make_fill { (map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces), (@$collapsed), ], - undef, 1, )}; } diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 0b601fc2a3..3e11db93bd 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -105,7 +105,7 @@ sub change_layer { ); if ($self->config->avoid_crossing_perimeters) { $self->layer_mp(Slic3r::GCode::MotionPlanner->new( - islands => union_ex([ map @$_, @{$layer->slices} ], undef, 1), + islands => union_ex([ map @$_, @{$layer->slices} ], 1), )); } diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index 164d5fc3e0..772ca2089b 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -57,18 +57,6 @@ sub diff { ]; } -sub union_ex { - my ($polygons, $jointype, $safety_offset) = @_; - $jointype = PFT_NONZERO unless defined $jointype; - $clipper->clear; - $polygons = $polygons->arrayref if ref $polygons eq 'Slic3r::ExPolygon'; - $clipper->add_subject_polygons($safety_offset ? _convert(safety_offset($polygons)) : _convert($polygons)); - return [ - map Slic3r::ExPolygon->new($_->{outer}, @{$_->{holes}}), - @{ $clipper->ex_execute(CT_UNION, $jointype, $jointype) }, - ]; -} - sub union_pt { my ($polygons, $jointype, $safety_offset) = @_; $jointype = PFT_NONZERO unless defined $jointype; @@ -77,18 +65,6 @@ sub union_pt { return $clipper->pt_execute(CT_UNION, $jointype, $jointype); } -sub intersection_ex { - 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::ExPolygon->new($_->{outer}, @{$_->{holes}}), - @{ $clipper->ex_execute(CT_INTERSECTION, $jointype, $jointype) }, - ]; -} - sub intersection { my ($subject, $clip, $jointype, $safety_offset) = @_; $jointype = PFT_NONZERO unless defined $jointype; @@ -101,18 +77,6 @@ sub intersection { ]; } -sub xor_ex { - my ($subject, $clip, $jointype) = @_; - $jointype = PFT_NONZERO unless defined $jointype; - $clipper->clear; - $clipper->add_subject_polygons(_convert($subject)); - $clipper->add_clip_polygons(_convert($clip)); - return [ - map Slic3r::ExPolygon->new($_->{outer}, @{$_->{holes}}), - @{ $clipper->ex_execute(CT_XOR, $jointype, $jointype) }, - ]; -} - sub collapse_ex { my ($polygons, $width) = @_; return offset2_ex($polygons, -$width/2, +$width/2); diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 4ef1f2ac15..ec8da4e3d2 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -418,13 +418,11 @@ sub process_external_surfaces { @top = @{intersection_ex( [ Slic3r::Geometry::Clipper::offset([ map $_->p, @top ], +$margin) ], [ map $_->p, @fill_boundaries ], - undef, 1, # to ensure adjacent expolygons are unified )}; @bottom = @{intersection_ex( [ Slic3r::Geometry::Clipper::offset([ map $_->p, @bottom ], +$margin) ], [ map $_->p, @fill_boundaries ], - undef, 1, # to ensure adjacent expolygons are unified )}; @@ -526,7 +524,6 @@ sub _detect_bridges { my $anchors = intersection_ex( [ $surface->p ], [ map @$_, @lower ], - undef, 1, # safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some @edges ); diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index c78518aa01..9e33dca7f9 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -610,7 +610,7 @@ sub discover_horizontal_shells { my $new_internal_solid = intersection_ex( [ map @$_, @$solid ], [ map $_->p, grep { ($_->surface_type == S_TYPE_INTERNAL) || ($_->surface_type == S_TYPE_INTERNALSOLID) } @neighbor_fill_surfaces ], - undef, 1, + 1, ); next if !@$new_internal_solid; diff --git a/xs/src/ClipperUtils.cpp b/xs/src/ClipperUtils.cpp index 82e12e06d7..15cd87c0cf 100644 --- a/xs/src/ClipperUtils.cpp +++ b/xs/src/ClipperUtils.cpp @@ -139,8 +139,8 @@ offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float d delete output2; } -void -diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset) +inline void _clipper_ex(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, + Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset) { // read input ClipperLib::Polygons* input_subject = new ClipperLib::Polygons(); @@ -150,7 +150,11 @@ diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &r // perform safety offset if (safety_offset) { - // SafetyOffset(*input_clip); + if (clipType == ClipperLib::ctUnion) { + // SafetyOffset(*input_subject); + } else { + // SafetyOffset(*input_clip); + } } // init Clipper @@ -165,13 +169,35 @@ diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &r // perform operation ClipperLib::PolyTree* polytree = new ClipperLib::PolyTree(); - clipper.Execute(ClipperLib::ctDifference, *polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero); + clipper.Execute(clipType, *polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero); // convert into ExPolygons PolyTreeToExPolygons(*polytree, retval); delete polytree; } +void +diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset) +{ + _clipper_ex(ClipperLib::ctDifference, subject, clip, retval, safety_offset); +} +void intersection_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, + bool safety_offset) +{ + _clipper_ex(ClipperLib::ctIntersection, subject, clip, retval, 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); +} + +void union_ex(Slic3r::Polygons &subject, Slic3r::ExPolygons &retval, bool safety_offset) +{ + Slic3r::Polygons p; + _clipper_ex(ClipperLib::ctUnion, subject, p, retval, safety_offset); +} } diff --git a/xs/src/ClipperUtils.hpp b/xs/src/ClipperUtils.hpp index 37012591df..f2f4a3b72b 100644 --- a/xs/src/ClipperUtils.hpp +++ b/xs/src/ClipperUtils.hpp @@ -30,7 +30,15 @@ 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); -void diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset); +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); +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 08fdfa3d72..3907cd10cb 100644 --- a/xs/xsp/Clipper.xsp +++ b/xs/xsp/Clipper.xsp @@ -45,4 +45,33 @@ diff_ex(subject, clip, safety_offset = false) OUTPUT: RETVAL +ExPolygons +intersection_ex(subject, clip, safety_offset = false) + Polygons subject + Polygons clip + bool safety_offset + CODE: + intersection_ex(subject, clip, RETVAL, safety_offset); + OUTPUT: + RETVAL + +ExPolygons +xor_ex(subject, clip, safety_offset = false) + Polygons subject + Polygons clip + bool safety_offset + CODE: + xor_ex(subject, clip, RETVAL, safety_offset); + OUTPUT: + RETVAL + +ExPolygons +union_ex(subject, safety_offset = false) + Polygons subject + bool safety_offset + CODE: + union_ex(subject, RETVAL, safety_offset); + OUTPUT: + RETVAL + %} diff --git a/xs/xsp/my.map b/xs/xsp/my.map index 81950a13d4..d26060ede1 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -14,6 +14,7 @@ SurfaceCollection* O_OBJECT ExtrusionRole T_UV SurfaceType T_UV ClipperLib::JoinType T_UV +ClipperLib::PolyFillType T_UV Lines T_ARRAYREF Polygons T_ARRAYREF