From c7b6818ccf6983cb907cb3517bd4459060af6a02 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 17 Jul 2013 00:48:29 +0200 Subject: [PATCH] Ported offset() and offset2() --- lib/Slic3r/ExPolygon.pm | 4 +- lib/Slic3r/Fill.pm | 10 +-- lib/Slic3r/Fill/Concentric.pm | 4 +- lib/Slic3r/GCode/MotionPlanner.pm | 2 +- lib/Slic3r/Geometry/Clipper.pm | 20 ------ lib/Slic3r/Layer/Region.pm | 10 +-- lib/Slic3r/Polygon.pm | 2 +- lib/Slic3r/Polyline.pm | 4 +- lib/Slic3r/Print.pm | 8 +-- lib/Slic3r/Print/Object.pm | 18 ++--- lib/Slic3r/Surface.pm | 2 +- lib/Slic3r/TriangleMesh.pm | 2 +- xs/src/ClipperUtils.cpp | 107 ++++++++++++++++++++++-------- xs/src/ClipperUtils.hpp | 15 ++++- xs/xsp/Clipper.xsp | 25 +++++++ 15 files changed, 152 insertions(+), 81 deletions(-) diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index ffb585bf7..39f876508 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -35,7 +35,7 @@ sub is_printable { # try to get an inwards offset # for a distance equal to half of the extrusion width; # if no offset is possible, then expolygon is not printable. - return Slic3r::Geometry::Clipper::offset($self, -$width / 2) ? 1 : 0; + return @{Slic3r::Geometry::Clipper::offset($self, -$width / 2)} ? 1 : 0; } sub wkt { @@ -46,7 +46,7 @@ sub wkt { sub offset { my $self = shift; - return Slic3r::Geometry::Clipper::offset($self, @_); + return Slic3r::Geometry::Clipper::offset(\@$self, @_); } sub offset_ex { diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index edc5bfe72..f1144c38f 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -105,17 +105,17 @@ sub make_fill { { my $collapsed = diff( [ map @{$_->expolygon}, @surfaces ], - [ offset( - [ offset([ map @{$_->expolygon}, @surfaces ], -$distance_between_surfaces/2) ], + offset( + offset([ map @{$_->expolygon}, @surfaces ], -$distance_between_surfaces/2), +$distance_between_surfaces/2 - ) ], + ), 1, ); push @surfaces, map Slic3r::Surface->new( expolygon => $_, surface_type => S_TYPE_INTERNALSOLID, ), @{intersection_ex( - [ offset($collapsed, $distance_between_surfaces) ], + offset($collapsed, $distance_between_surfaces), [ (map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces), (@$collapsed), @@ -125,7 +125,7 @@ sub make_fill { } # add spacing between surfaces - @surfaces = map $_->offset(-$distance_between_surfaces / 2 * &Slic3r::INFILL_OVERLAP_OVER_SPACING), @surfaces; + @surfaces = map @{$_->offset(-$distance_between_surfaces / 2 * &Slic3r::INFILL_OVERLAP_OVER_SPACING)}, @surfaces; my @fills = (); my @fills_ordering_points = (); diff --git a/lib/Slic3r/Fill/Concentric.pm b/lib/Slic3r/Fill/Concentric.pm index b18352be9..3c47de489 100644 --- a/lib/Slic3r/Fill/Concentric.pm +++ b/lib/Slic3r/Fill/Concentric.pm @@ -29,9 +29,9 @@ sub fill_surface { # compensate the overlap which is good for rectilinear but harmful for concentric # where the perimeter/infill spacing should be equal to any other loop spacing - my @loops = my @last = offset($expolygon, -&Slic3r::INFILL_OVERLAP_OVER_SPACING * $min_spacing / 2); + my @loops = my @last = @{offset($expolygon, -&Slic3r::INFILL_OVERLAP_OVER_SPACING * $min_spacing / 2)}; while (@last) { - push @loops, @last = offset2(\@last, -1.5*$distance, +0.5*$distance); + push @loops, @last = @{offset2(\@last, -1.5*$distance, +0.5*$distance)}; } # generate paths from the outermost to the innermost, to avoid diff --git a/lib/Slic3r/GCode/MotionPlanner.pm b/lib/Slic3r/GCode/MotionPlanner.pm index c001a302e..a51e1bcbe 100644 --- a/lib/Slic3r/GCode/MotionPlanner.pm +++ b/lib/Slic3r/GCode/MotionPlanner.pm @@ -52,7 +52,7 @@ sub BUILD { : $self->islands->[$i]->offset_ex(-$self->_inner_margin); # offset the island outwards to make the boundaries for external movements - $self->_outer->[$i] = [ offset([ $self->islands->[$i]->contour], $self->_outer_margin) ]; + $self->_outer->[$i] = offset([ $self->islands->[$i]->contour], $self->_outer_margin); # if internal motion is enabled, build a set of utility expolygons representing # the outer boundaries (as contours) and the inner boundaries (as holes). whenever diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index 772ca2089..3fad5fd9f 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -25,26 +25,6 @@ sub safety_offset_ex { @{Math::Clipper::ex_int_offset(_convert($polygons), $factor // (scale 1e-05), 100000, JT_MITER, 2)}; } -sub offset { - my ($polygons, $distance, $scale, $joinType, $miterLimit) = @_; - $scale ||= 100000; - $joinType //= JT_MITER; - $miterLimit //= 3; - - my $offsets = Math::Clipper::int_offset(_convert($polygons), $distance, $scale, $joinType, $miterLimit); - return @$offsets; -} - -sub offset2 { - my ($polygons, $distance1, $distance2, $scale, $joinType, $miterLimit) = @_; - $scale ||= 100000; - $joinType //= JT_MITER; - $miterLimit //= 3; - - my $offsets = Math::Clipper::int_offset2(_convert($polygons), $distance1, $distance2, $scale, $joinType, $miterLimit); - return @$offsets; -} - sub diff { my ($subject, $clip, $safety_offset) = @_; diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index ec8da4e3d..0751838ae 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -96,7 +96,7 @@ sub make_surfaces { my $width = $self->perimeter_flow->scaled_width; my $diff = diff_ex( [ map $_->p, @{$self->slices} ], - [ offset2([ map @$_, map $_->expolygon, @{$self->slices} ], -$width, +$width) ], + offset2([ map @$_, map $_->expolygon, @{$self->slices} ], -$width, +$width), 1, ); @@ -189,10 +189,10 @@ sub make_perimeters { # and we can extract the gap for later processing if ($Slic3r::Config->gap_fill_speed > 0 && $Slic3r::Config->fill_density > 0) { my $diff = diff_ex( - [ offset(\@last, -0.5*$spacing) ], + offset(\@last, -0.5*$spacing), # +2 on the offset here makes sure that Clipper float truncation # won't shrink the clip polygon to be smaller than intended. - [ offset(\@offsets, +0.5*$spacing + 2) ], + offset(\@offsets, +0.5*$spacing + 2), ); push @gaps, grep $_->area >= $gap_area_threshold, @$diff; } @@ -416,12 +416,12 @@ sub process_external_surfaces { # offset them and intersect the results with the actual fill boundaries my $margin = scale 3; # TODO: ensure this is greater than the total thickness of the perimeters @top = @{intersection_ex( - [ Slic3r::Geometry::Clipper::offset([ map $_->p, @top ], +$margin) ], + Slic3r::Geometry::Clipper::offset([ map $_->p, @top ], +$margin), [ map $_->p, @fill_boundaries ], 1, # to ensure adjacent expolygons are unified )}; @bottom = @{intersection_ex( - [ Slic3r::Geometry::Clipper::offset([ map $_->p, @bottom ], +$margin) ], + Slic3r::Geometry::Clipper::offset([ map $_->p, @bottom ], +$margin), [ map $_->p, @fill_boundaries ], 1, # to ensure adjacent expolygons are unified )}; diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm index 36b3dbe9b..27abd2c4e 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -86,7 +86,7 @@ sub is_printable { # detect them and we would be discarding them. my $p = $self->clone; $p->make_counter_clockwise; - return Slic3r::Geometry::Clipper::offset([$p], -$width / 2) ? 1 : 0; + return @{Slic3r::Geometry::Clipper::offset([$p], -$width / 2)} ? 1 : 0; } sub is_valid { diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm index e98fbc8d2..be37f8149 100644 --- a/lib/Slic3r/Polyline.pm +++ b/lib/Slic3r/Polyline.pm @@ -47,10 +47,10 @@ sub grow { my @points = @$self; return map Slic3r::Polygon->new(@$_), - Slic3r::Geometry::Clipper::offset( + @{Slic3r::Geometry::Clipper::offset( [ Slic3r::Polygon->new(@points, CORE::reverse @points[1..($#points-1)]) ], $distance, $scale, $joinType, $miterLimit, - ); + )}; } sub nearest_point_to { diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 68a6eda93..23a7099d9 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -172,8 +172,8 @@ sub validate { my @points = map [ @$_[X,Y] ], map @{$_->vertices}, @{$self->objects->[$obj_idx]->meshes}; my $convex_hull = Slic3r::Polygon->new(@{convex_hull(\@points)}); ($clearance) = map Slic3r::Polygon->new(@$_), - Slic3r::Geometry::Clipper::offset( - [$convex_hull], scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND); + @{Slic3r::Geometry::Clipper::offset( + [$convex_hull], scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND)}; } for my $copy (@{$self->objects->[$obj_idx]->copies}) { my $copy_clearance = $clearance->clone; @@ -610,7 +610,7 @@ sub make_skirt { my $distance = scale $Slic3r::Config->skirt_distance; for (my $i = $Slic3r::Config->skirts; $i > 0; $i--) { $distance += scale $spacing; - my ($loop) = Slic3r::Geometry::Clipper::offset([$convex_hull], $distance, 0.0001, JT_ROUND); + my $loop = Slic3r::Geometry::Clipper::offset([$convex_hull], $distance, 0.0001, JT_ROUND)->[0]; push @{$self->skirt}, Slic3r::ExtrusionLoop->new( polygon => Slic3r::Polygon->new(@$loop), role => EXTR_ROLE_SKIRT, @@ -666,7 +666,7 @@ sub make_brim { # JT_SQUARE ensures no vertex is outside the given offset distance # -0.5 because islands are not represented by their centerlines # TODO: we need the offset inwards/offset outwards logic to avoid overlapping extrusions - push @loops, offset2(\@islands, ($i - 1.5) * $flow->scaled_spacing, +1.0 * $flow->scaled_spacing, undef, JT_SQUARE); + push @loops, @{offset2(\@islands, ($i - 1.5) * $flow->scaled_spacing, +1.0 * $flow->scaled_spacing, undef, JT_SQUARE)}; } @{$self->brim} = map Slic3r::ExtrusionLoop->new( diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 9e33dca7f..7b76ba7da 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -274,15 +274,15 @@ sub make_perimeters { my $overlap = $perimeter_spacing; # one perimeter my $diff = diff( - [ offset([ map @{$_->expolygon}, @{$layerm->slices} ], -($Slic3r::Config->perimeters * $perimeter_spacing)) ], - [ offset([ map @{$_->expolygon}, @{$upper_layerm->slices} ], -$overlap) ], + offset([ map @{$_->expolygon}, @{$layerm->slices} ], -($Slic3r::Config->perimeters * $perimeter_spacing)), + offset([ map @{$_->expolygon}, @{$upper_layerm->slices} ], -$overlap), ); next if !@$diff; # if we need more perimeters, $diff should contain a narrow region that we can collapse $diff = diff( $diff, - [ offset2($diff, -$perimeter_spacing, +$perimeter_spacing) ], + offset2($diff, -$perimeter_spacing, +$perimeter_spacing), 1, ); next if !@$diff; @@ -295,8 +295,8 @@ sub make_perimeters { # of our slice $extra_perimeters++; my $hypothetical_perimeter = diff( - [ offset($slice->expolygon->arrayref, -($perimeter_spacing * ($Slic3r::Config->perimeters + $extra_perimeters-1))) ], - [ offset($slice->expolygon->arrayref, -($perimeter_spacing * ($Slic3r::Config->perimeters + $extra_perimeters))) ], + offset($slice->expolygon->arrayref, -($perimeter_spacing * ($Slic3r::Config->perimeters + $extra_perimeters-1))), + offset($slice->expolygon->arrayref, -($perimeter_spacing * ($Slic3r::Config->perimeters + $extra_perimeters))), ); last CYCLE if !@$hypothetical_perimeter; # no extra perimeter is possible @@ -620,7 +620,7 @@ sub discover_horizontal_shells { my $margin = 3 * $layerm->solid_infill_flow->scaled_width; # require at least this size my $too_narrow = diff_ex( [ map @$_, @$new_internal_solid ], - [ offset([ offset([ map @$_, @$new_internal_solid ], -$margin) ], +$margin) ], + offset(offset([ map @$_, @$new_internal_solid ], -$margin), +$margin), 1, ); @@ -634,7 +634,7 @@ sub discover_horizontal_shells { # make sure our grown surfaces don't exceed the fill area my @grown = map @$_, @{intersection_ex( - [ offset([ map @$_, @$too_narrow ], +$margin) ], + offset([ map @$_, @$too_narrow ], +$margin), [ map $_->p, @fill_boundaries ], )}; $new_internal_solid = union_ex([ @grown, (map @$_, @$new_internal_solid) ]); @@ -745,7 +745,7 @@ sub combine_infill { # $intersection now contains the regions that can be combined across the full amount of layers # so let's remove those areas from all layers - my @intersection_with_clearance = map $_->offset( + my @intersection_with_clearance = map @{$_->offset( $layerms[-1]->solid_infill_flow->scaled_width / 2 + $layerms[-1]->perimeter_flow->scaled_width / 2 # Because fill areas for rectilinear and honeycomb are grown @@ -753,7 +753,7 @@ sub combine_infill { + (($type == S_TYPE_INTERNALSOLID || $Slic3r::Config->fill_pattern =~ /(rectilinear|honeycomb)/) ? $layerms[-1]->solid_infill_flow->scaled_width * &Slic3r::INFILL_OVERLAP_OVER_SPACING : 0) - ), @$intersection; + )}, @$intersection; foreach my $layerm (@layerms) { diff --git a/lib/Slic3r/Surface.pm b/lib/Slic3r/Surface.pm index 27a10a17d..a1f4e1466 100644 --- a/lib/Slic3r/Surface.pm +++ b/lib/Slic3r/Surface.pm @@ -35,7 +35,7 @@ sub group { sub offset { my $self = shift; - return map $self->clone(expolygon => $_), @{$self->expolygon->offset_ex(@_)}; + return [ map $self->clone(expolygon => $_), @{$self->expolygon->offset_ex(@_)} ]; } sub simplify { diff --git a/lib/Slic3r/TriangleMesh.pm b/lib/Slic3r/TriangleMesh.pm index f97edabbe..c2dccabd7 100644 --- a/lib/Slic3r/TriangleMesh.pm +++ b/lib/Slic3r/TriangleMesh.pm @@ -550,7 +550,7 @@ sub horizontal_projection { my $scale_vector = Math::Clipper::integerize_coordinate_sets({ bits => 32 }, @f); $_->make_counter_clockwise for @f; # do this after scaling, as winding order might change while doing that - my $union = union_ex([ Slic3r::Geometry::Clipper::offset(\@f, 10000) ]); + my $union = union_ex(Slic3r::Geometry::Clipper::offset(\@f, 10000)); $union = [ map $_->arrayref, @$union ]; Math::Clipper::unscale_coordinate_sets($scale_vector, $_) for @$union; return $union; diff --git a/xs/src/ClipperUtils.cpp b/xs/src/ClipperUtils.cpp index 15cd87c0c..a18dcb720 100644 --- a/xs/src/ClipperUtils.cpp +++ b/xs/src/ClipperUtils.cpp @@ -2,15 +2,6 @@ namespace Slic3r { -void -ClipperPolygon_to_Slic3rPolygon(ClipperLib::Polygon &input, Slic3r::Polygon &output) -{ - output.points.clear(); - for (ClipperLib::Polygon::iterator pit = input.begin(); pit != input.end(); ++pit) { - output.points.push_back(Slic3r::Point( (*pit).X, (*pit).Y )); - } -} - //----------------------------------------------------------- // legacy code from Clipper documentation void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons& expolygons) @@ -37,21 +28,21 @@ void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& ex //----------------------------------------------------------- void -Slic3rPolygon_to_ClipperPolygon(Slic3r::Polygon &input, ClipperLib::Polygon &output) +ClipperPolygon_to_Slic3rPolygon(ClipperLib::Polygon &input, Slic3r::Polygon &output) { - output.clear(); - for (Slic3r::Points::iterator pit = input.points.begin(); pit != input.points.end(); ++pit) { - output.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y )); + output.points.clear(); + for (ClipperLib::Polygon::iterator pit = input.begin(); pit != input.end(); ++pit) { + output.points.push_back(Slic3r::Point( (*pit).X, (*pit).Y )); } } void -Slic3rPolygons_to_ClipperPolygons(Slic3r::Polygons &input, ClipperLib::Polygons &output) +ClipperPolygons_to_Slic3rPolygons(ClipperLib::Polygons &input, Slic3r::Polygons &output) { output.clear(); - for (Slic3r::Polygons::iterator it = input.begin(); it != input.end(); ++it) { - ClipperLib::Polygon p; - Slic3rPolygon_to_ClipperPolygon(*it, p); + for (ClipperLib::Polygons::iterator it = input.begin(); it != input.end(); ++it) { + Slic3r::Polygon p; + ClipperPolygon_to_Slic3rPolygon(*it, p); output.push_back(p); } } @@ -75,6 +66,26 @@ ClipperPolygons_to_Slic3rExPolygons(ClipperLib::Polygons &input, Slic3r::ExPolyg delete polytree; } +void +Slic3rPolygon_to_ClipperPolygon(Slic3r::Polygon &input, ClipperLib::Polygon &output) +{ + output.clear(); + for (Slic3r::Points::iterator pit = input.points.begin(); pit != input.points.end(); ++pit) { + output.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y )); + } +} + +void +Slic3rPolygons_to_ClipperPolygons(Slic3r::Polygons &input, ClipperLib::Polygons &output) +{ + output.clear(); + for (Slic3r::Polygons::iterator it = input.begin(); it != input.end(); ++it) { + ClipperLib::Polygon p; + Slic3rPolygon_to_ClipperPolygon(*it, p); + output.push_back(p); + } +} + void scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale) { @@ -87,7 +98,7 @@ scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale) } void -offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta, +offset(Slic3r::Polygons &polygons, ClipperLib::Polygons &retval, const float delta, double scale, ClipperLib::JoinType joinType, double miterLimit) { // read input @@ -98,12 +109,33 @@ offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float de scaleClipperPolygons(*input, scale); // perform offset - ClipperLib::Polygons* output = new ClipperLib::Polygons(); - ClipperLib::OffsetPolygons(*input, *output, (delta*scale), joinType, miterLimit); + ClipperLib::OffsetPolygons(*input, retval, (delta*scale), joinType, miterLimit); delete input; // unscale output - scaleClipperPolygons(*output, 1/scale); + scaleClipperPolygons(retval, 1/scale); +} + +void +offset(Slic3r::Polygons &polygons, Slic3r::Polygons &retval, const float delta, + double scale, ClipperLib::JoinType joinType, double miterLimit) +{ + // perform offset + ClipperLib::Polygons* output = new ClipperLib::Polygons(); + offset(polygons, *output, delta, scale, joinType, miterLimit); + + // convert into ExPolygons + ClipperPolygons_to_Slic3rPolygons(*output, retval); + delete output; +} + +void +offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta, + double scale, ClipperLib::JoinType joinType, double miterLimit) +{ + // perform offset + ClipperLib::Polygons* output = new ClipperLib::Polygons(); + offset(polygons, *output, delta, scale, joinType, miterLimit); // convert into ExPolygons ClipperPolygons_to_Slic3rExPolygons(*output, retval); @@ -111,7 +143,7 @@ offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float de } void -offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta1, +offset2(Slic3r::Polygons &polygons, ClipperLib::Polygons &retval, const float delta1, const float delta2, double scale, ClipperLib::JoinType joinType, double miterLimit) { // read input @@ -127,16 +159,37 @@ offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float d delete input; // perform second offset - ClipperLib::Polygons* output2 = new ClipperLib::Polygons(); - ClipperLib::OffsetPolygons(*output1, *output2, (delta2*scale), joinType, miterLimit); + ClipperLib::OffsetPolygons(*output1, retval, (delta2*scale), joinType, miterLimit); delete output1; // unscale output - scaleClipperPolygons(*output2, 1/scale); + scaleClipperPolygons(retval, 1/scale); +} + +void +offset2(Slic3r::Polygons &polygons, Slic3r::Polygons &retval, const float delta1, + const float delta2, double scale, ClipperLib::JoinType joinType, double miterLimit) +{ + // perform offset + ClipperLib::Polygons* output = new ClipperLib::Polygons(); + offset2(polygons, *output, delta1, delta2, scale, joinType, miterLimit); // convert into ExPolygons - ClipperPolygons_to_Slic3rExPolygons(*output2, retval); - delete output2; + ClipperPolygons_to_Slic3rPolygons(*output, retval); + delete output; +} + +void +offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta1, + const float delta2, double scale, ClipperLib::JoinType joinType, double miterLimit) +{ + // perform offset + ClipperLib::Polygons* output = new ClipperLib::Polygons(); + offset2(polygons, *output, delta1, delta2, scale, joinType, miterLimit); + + // convert into ExPolygons + ClipperPolygons_to_Slic3rExPolygons(*output, retval); + delete output; } inline void _clipper_ex(ClipperLib::ClipType clipType, Slic3r::Polygons &subject, diff --git a/xs/src/ClipperUtils.hpp b/xs/src/ClipperUtils.hpp index f2f4a3b72..710d35ab5 100644 --- a/xs/src/ClipperUtils.hpp +++ b/xs/src/ClipperUtils.hpp @@ -8,7 +8,6 @@ namespace Slic3r { -void ClipperPolygon_to_Slic3rPolygon(ClipperLib::Polygon &input, Slic3r::Polygon &output); //----------------------------------------------------------- // legacy code from Clipper documentation @@ -18,14 +17,28 @@ void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& ex void Slic3rPolygon_to_ClipperPolygon(Slic3r::Polygon &input, ClipperLib::Polygon &output); void Slic3rPolygons_to_ClipperPolygons(Slic3r::Polygons &input, ClipperLib::Polygons &output); +void ClipperPolygon_to_Slic3rPolygon(ClipperLib::Polygon &input, Slic3r::Polygon &output); +void ClipperPolygons_to_Slic3rPolygons(ClipperLib::Polygons &input, Slic3r::Polygons &output); void ClipperPolygons_to_Slic3rExPolygons(ClipperLib::Polygons &input, Slic3r::ExPolygons &output); void scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale); +void offset(Slic3r::Polygons &polygons, ClipperLib::Polygons &retval, const float delta, + double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, + double miterLimit = 3); +void offset(Slic3r::Polygons &polygons, Slic3r::Polygons &retval, const float delta, + double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, + double miterLimit = 3); void offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3); +void offset2(Slic3r::Polygons &polygons, ClipperLib::Polygons &retval, const float delta1, + const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, + double miterLimit = 3); +void offset2(Slic3r::Polygons &polygons, Slic3r::Polygons &retval, const float delta1, + const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, + double miterLimit = 3); void offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta1, const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3); diff --git a/xs/xsp/Clipper.xsp b/xs/xsp/Clipper.xsp index 3907cd10c..3cdbeae4b 100644 --- a/xs/xsp/Clipper.xsp +++ b/xs/xsp/Clipper.xsp @@ -10,6 +10,18 @@ %{ +Polygons +offset(polygons, delta, scale = 100000, joinType = ClipperLib::jtMiter, miterLimit = 3) + Polygons polygons + const float delta + double scale + ClipperLib::JoinType joinType + double miterLimit + CODE: + offset(polygons, RETVAL, delta, scale, joinType, miterLimit); + OUTPUT: + RETVAL + ExPolygons offset_ex(polygons, delta, scale = 100000, joinType = ClipperLib::jtMiter, miterLimit = 3) Polygons polygons @@ -22,6 +34,19 @@ offset_ex(polygons, delta, scale = 100000, joinType = ClipperLib::jtMiter, miter OUTPUT: RETVAL +Polygons +offset2(polygons, delta1, delta2, scale = 100000, joinType = ClipperLib::jtMiter, miterLimit = 3) + Polygons polygons + const float delta1 + const float delta2 + double scale + ClipperLib::JoinType joinType + double miterLimit + CODE: + offset2(polygons, RETVAL, delta1, delta2, scale, joinType, miterLimit); + OUTPUT: + RETVAL + ExPolygons offset2_ex(polygons, delta1, delta2, scale = 100000, joinType = ClipperLib::jtMiter, miterLimit = 3) Polygons polygons