Ported offset() and offset2()

This commit is contained in:
Alessandro Ranellucci 2013-07-17 00:48:29 +02:00
parent bf8c799685
commit c7b6818ccf
15 changed files with 152 additions and 81 deletions

View file

@ -35,7 +35,7 @@ sub is_printable {
# try to get an inwards offset # try to get an inwards offset
# for a distance equal to half of the extrusion width; # for a distance equal to half of the extrusion width;
# if no offset is possible, then expolygon is not printable. # 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 { sub wkt {
@ -46,7 +46,7 @@ sub wkt {
sub offset { sub offset {
my $self = shift; my $self = shift;
return Slic3r::Geometry::Clipper::offset($self, @_); return Slic3r::Geometry::Clipper::offset(\@$self, @_);
} }
sub offset_ex { sub offset_ex {

View file

@ -105,17 +105,17 @@ sub make_fill {
{ {
my $collapsed = diff( my $collapsed = diff(
[ map @{$_->expolygon}, @surfaces ], [ map @{$_->expolygon}, @surfaces ],
[ offset( offset(
[ offset([ map @{$_->expolygon}, @surfaces ], -$distance_between_surfaces/2) ], offset([ map @{$_->expolygon}, @surfaces ], -$distance_between_surfaces/2),
+$distance_between_surfaces/2 +$distance_between_surfaces/2
) ], ),
1, 1,
); );
push @surfaces, map Slic3r::Surface->new( push @surfaces, map Slic3r::Surface->new(
expolygon => $_, expolygon => $_,
surface_type => S_TYPE_INTERNALSOLID, surface_type => S_TYPE_INTERNALSOLID,
), @{intersection_ex( ), @{intersection_ex(
[ offset($collapsed, $distance_between_surfaces) ], offset($collapsed, $distance_between_surfaces),
[ [
(map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces), (map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces),
(@$collapsed), (@$collapsed),
@ -125,7 +125,7 @@ sub make_fill {
} }
# add spacing between surfaces # 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 = ();
my @fills_ordering_points = (); my @fills_ordering_points = ();

View file

@ -29,9 +29,9 @@ sub fill_surface {
# compensate the overlap which is good for rectilinear but harmful for concentric # 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 # 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) { 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 # generate paths from the outermost to the innermost, to avoid

View file

@ -52,7 +52,7 @@ sub BUILD {
: $self->islands->[$i]->offset_ex(-$self->_inner_margin); : $self->islands->[$i]->offset_ex(-$self->_inner_margin);
# offset the island outwards to make the boundaries for external movements # 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 # if internal motion is enabled, build a set of utility expolygons representing
# the outer boundaries (as contours) and the inner boundaries (as holes). whenever # the outer boundaries (as contours) and the inner boundaries (as holes). whenever

View file

@ -25,26 +25,6 @@ sub safety_offset_ex {
@{Math::Clipper::ex_int_offset(_convert($polygons), $factor // (scale 1e-05), 100000, JT_MITER, 2)}; @{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 { sub diff {
my ($subject, $clip, $safety_offset) = @_; my ($subject, $clip, $safety_offset) = @_;

View file

@ -96,7 +96,7 @@ sub make_surfaces {
my $width = $self->perimeter_flow->scaled_width; my $width = $self->perimeter_flow->scaled_width;
my $diff = diff_ex( my $diff = diff_ex(
[ map $_->p, @{$self->slices} ], [ map $_->p, @{$self->slices} ],
[ offset2([ map @$_, map $_->expolygon, @{$self->slices} ], -$width, +$width) ], offset2([ map @$_, map $_->expolygon, @{$self->slices} ], -$width, +$width),
1, 1,
); );
@ -189,10 +189,10 @@ sub make_perimeters {
# and we can extract the gap for later processing # and we can extract the gap for later processing
if ($Slic3r::Config->gap_fill_speed > 0 && $Slic3r::Config->fill_density > 0) { if ($Slic3r::Config->gap_fill_speed > 0 && $Slic3r::Config->fill_density > 0) {
my $diff = diff_ex( 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 # +2 on the offset here makes sure that Clipper float truncation
# won't shrink the clip polygon to be smaller than intended. # 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; 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 # 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 my $margin = scale 3; # TODO: ensure this is greater than the total thickness of the perimeters
@top = @{intersection_ex( @top = @{intersection_ex(
[ Slic3r::Geometry::Clipper::offset([ map $_->p, @top ], +$margin) ], Slic3r::Geometry::Clipper::offset([ map $_->p, @top ], +$margin),
[ map $_->p, @fill_boundaries ], [ map $_->p, @fill_boundaries ],
1, # to ensure adjacent expolygons are unified 1, # to ensure adjacent expolygons are unified
)}; )};
@bottom = @{intersection_ex( @bottom = @{intersection_ex(
[ Slic3r::Geometry::Clipper::offset([ map $_->p, @bottom ], +$margin) ], Slic3r::Geometry::Clipper::offset([ map $_->p, @bottom ], +$margin),
[ map $_->p, @fill_boundaries ], [ map $_->p, @fill_boundaries ],
1, # to ensure adjacent expolygons are unified 1, # to ensure adjacent expolygons are unified
)}; )};

View file

@ -86,7 +86,7 @@ sub is_printable {
# detect them and we would be discarding them. # detect them and we would be discarding them.
my $p = $self->clone; my $p = $self->clone;
$p->make_counter_clockwise; $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 { sub is_valid {

View file

@ -47,10 +47,10 @@ sub grow {
my @points = @$self; my @points = @$self;
return map Slic3r::Polygon->new(@$_), return map Slic3r::Polygon->new(@$_),
Slic3r::Geometry::Clipper::offset( @{Slic3r::Geometry::Clipper::offset(
[ Slic3r::Polygon->new(@points, CORE::reverse @points[1..($#points-1)]) ], [ Slic3r::Polygon->new(@points, CORE::reverse @points[1..($#points-1)]) ],
$distance, $scale, $joinType, $miterLimit, $distance, $scale, $joinType, $miterLimit,
); )};
} }
sub nearest_point_to { sub nearest_point_to {

View file

@ -172,8 +172,8 @@ sub validate {
my @points = map [ @$_[X,Y] ], map @{$_->vertices}, @{$self->objects->[$obj_idx]->meshes}; my @points = map [ @$_[X,Y] ], map @{$_->vertices}, @{$self->objects->[$obj_idx]->meshes};
my $convex_hull = Slic3r::Polygon->new(@{convex_hull(\@points)}); my $convex_hull = Slic3r::Polygon->new(@{convex_hull(\@points)});
($clearance) = map Slic3r::Polygon->new(@$_), ($clearance) = map Slic3r::Polygon->new(@$_),
Slic3r::Geometry::Clipper::offset( @{Slic3r::Geometry::Clipper::offset(
[$convex_hull], scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND); [$convex_hull], scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND)};
} }
for my $copy (@{$self->objects->[$obj_idx]->copies}) { for my $copy (@{$self->objects->[$obj_idx]->copies}) {
my $copy_clearance = $clearance->clone; my $copy_clearance = $clearance->clone;
@ -610,7 +610,7 @@ sub make_skirt {
my $distance = scale $Slic3r::Config->skirt_distance; my $distance = scale $Slic3r::Config->skirt_distance;
for (my $i = $Slic3r::Config->skirts; $i > 0; $i--) { for (my $i = $Slic3r::Config->skirts; $i > 0; $i--) {
$distance += scale $spacing; $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( push @{$self->skirt}, Slic3r::ExtrusionLoop->new(
polygon => Slic3r::Polygon->new(@$loop), polygon => Slic3r::Polygon->new(@$loop),
role => EXTR_ROLE_SKIRT, role => EXTR_ROLE_SKIRT,
@ -666,7 +666,7 @@ sub make_brim {
# JT_SQUARE ensures no vertex is outside the given offset distance # JT_SQUARE ensures no vertex is outside the given offset distance
# -0.5 because islands are not represented by their centerlines # -0.5 because islands are not represented by their centerlines
# TODO: we need the offset inwards/offset outwards logic to avoid overlapping extrusions # 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( @{$self->brim} = map Slic3r::ExtrusionLoop->new(

View file

@ -274,15 +274,15 @@ sub make_perimeters {
my $overlap = $perimeter_spacing; # one perimeter my $overlap = $perimeter_spacing; # one perimeter
my $diff = diff( my $diff = diff(
[ offset([ map @{$_->expolygon}, @{$layerm->slices} ], -($Slic3r::Config->perimeters * $perimeter_spacing)) ], offset([ map @{$_->expolygon}, @{$layerm->slices} ], -($Slic3r::Config->perimeters * $perimeter_spacing)),
[ offset([ map @{$_->expolygon}, @{$upper_layerm->slices} ], -$overlap) ], offset([ map @{$_->expolygon}, @{$upper_layerm->slices} ], -$overlap),
); );
next if !@$diff; next if !@$diff;
# if we need more perimeters, $diff should contain a narrow region that we can collapse # if we need more perimeters, $diff should contain a narrow region that we can collapse
$diff = diff( $diff = diff(
$diff, $diff,
[ offset2($diff, -$perimeter_spacing, +$perimeter_spacing) ], offset2($diff, -$perimeter_spacing, +$perimeter_spacing),
1, 1,
); );
next if !@$diff; next if !@$diff;
@ -295,8 +295,8 @@ sub make_perimeters {
# of our slice # of our slice
$extra_perimeters++; $extra_perimeters++;
my $hypothetical_perimeter = diff( 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-1))),
[ offset($slice->expolygon->arrayref, -($perimeter_spacing * ($Slic3r::Config->perimeters + $extra_perimeters))) ], offset($slice->expolygon->arrayref, -($perimeter_spacing * ($Slic3r::Config->perimeters + $extra_perimeters))),
); );
last CYCLE if !@$hypothetical_perimeter; # no extra perimeter is possible 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 $margin = 3 * $layerm->solid_infill_flow->scaled_width; # require at least this size
my $too_narrow = diff_ex( my $too_narrow = diff_ex(
[ map @$_, @$new_internal_solid ], [ map @$_, @$new_internal_solid ],
[ offset([ offset([ map @$_, @$new_internal_solid ], -$margin) ], +$margin) ], offset(offset([ map @$_, @$new_internal_solid ], -$margin), +$margin),
1, 1,
); );
@ -634,7 +634,7 @@ sub discover_horizontal_shells {
# make sure our grown surfaces don't exceed the fill area # make sure our grown surfaces don't exceed the fill area
my @grown = map @$_, @{intersection_ex( my @grown = map @$_, @{intersection_ex(
[ offset([ map @$_, @$too_narrow ], +$margin) ], offset([ map @$_, @$too_narrow ], +$margin),
[ map $_->p, @fill_boundaries ], [ map $_->p, @fill_boundaries ],
)}; )};
$new_internal_solid = union_ex([ @grown, (map @$_, @$new_internal_solid) ]); $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 # $intersection now contains the regions that can be combined across the full amount of layers
# so let's remove those areas from all 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]->solid_infill_flow->scaled_width / 2
+ $layerms[-1]->perimeter_flow->scaled_width / 2 + $layerms[-1]->perimeter_flow->scaled_width / 2
# Because fill areas for rectilinear and honeycomb are grown # 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)/) + (($type == S_TYPE_INTERNALSOLID || $Slic3r::Config->fill_pattern =~ /(rectilinear|honeycomb)/)
? $layerms[-1]->solid_infill_flow->scaled_width * &Slic3r::INFILL_OVERLAP_OVER_SPACING ? $layerms[-1]->solid_infill_flow->scaled_width * &Slic3r::INFILL_OVERLAP_OVER_SPACING
: 0) : 0)
), @$intersection; )}, @$intersection;
foreach my $layerm (@layerms) { foreach my $layerm (@layerms) {

View file

@ -35,7 +35,7 @@ sub group {
sub offset { sub offset {
my $self = shift; my $self = shift;
return map $self->clone(expolygon => $_), @{$self->expolygon->offset_ex(@_)}; return [ map $self->clone(expolygon => $_), @{$self->expolygon->offset_ex(@_)} ];
} }
sub simplify { sub simplify {

View file

@ -550,7 +550,7 @@ sub horizontal_projection {
my $scale_vector = Math::Clipper::integerize_coordinate_sets({ bits => 32 }, @f); 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 $_->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 ]; $union = [ map $_->arrayref, @$union ];
Math::Clipper::unscale_coordinate_sets($scale_vector, $_) for @$union; Math::Clipper::unscale_coordinate_sets($scale_vector, $_) for @$union;
return $union; return $union;

View file

@ -2,15 +2,6 @@
namespace Slic3r { 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 // legacy code from Clipper documentation
void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons& expolygons) void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons& expolygons)
@ -37,21 +28,21 @@ void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& ex
//----------------------------------------------------------- //-----------------------------------------------------------
void void
Slic3rPolygon_to_ClipperPolygon(Slic3r::Polygon &input, ClipperLib::Polygon &output) ClipperPolygon_to_Slic3rPolygon(ClipperLib::Polygon &input, Slic3r::Polygon &output)
{ {
output.clear(); output.points.clear();
for (Slic3r::Points::iterator pit = input.points.begin(); pit != input.points.end(); ++pit) { for (ClipperLib::Polygon::iterator pit = input.begin(); pit != input.end(); ++pit) {
output.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y )); output.points.push_back(Slic3r::Point( (*pit).X, (*pit).Y ));
} }
} }
void void
Slic3rPolygons_to_ClipperPolygons(Slic3r::Polygons &input, ClipperLib::Polygons &output) ClipperPolygons_to_Slic3rPolygons(ClipperLib::Polygons &input, Slic3r::Polygons &output)
{ {
output.clear(); output.clear();
for (Slic3r::Polygons::iterator it = input.begin(); it != input.end(); ++it) { for (ClipperLib::Polygons::iterator it = input.begin(); it != input.end(); ++it) {
ClipperLib::Polygon p; Slic3r::Polygon p;
Slic3rPolygon_to_ClipperPolygon(*it, p); ClipperPolygon_to_Slic3rPolygon(*it, p);
output.push_back(p); output.push_back(p);
} }
} }
@ -75,6 +66,26 @@ ClipperPolygons_to_Slic3rExPolygons(ClipperLib::Polygons &input, Slic3r::ExPolyg
delete polytree; 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 void
scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale) scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale)
{ {
@ -87,7 +98,7 @@ scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale)
} }
void 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) double scale, ClipperLib::JoinType joinType, double miterLimit)
{ {
// read input // read input
@ -98,12 +109,33 @@ offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float de
scaleClipperPolygons(*input, scale); scaleClipperPolygons(*input, scale);
// perform offset // perform offset
ClipperLib::Polygons* output = new ClipperLib::Polygons(); ClipperLib::OffsetPolygons(*input, retval, (delta*scale), joinType, miterLimit);
ClipperLib::OffsetPolygons(*input, *output, (delta*scale), joinType, miterLimit);
delete input; delete input;
// unscale output // 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 // convert into ExPolygons
ClipperPolygons_to_Slic3rExPolygons(*output, retval); ClipperPolygons_to_Slic3rExPolygons(*output, retval);
@ -111,7 +143,7 @@ offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float de
} }
void 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) const float delta2, double scale, ClipperLib::JoinType joinType, double miterLimit)
{ {
// read input // read input
@ -127,16 +159,37 @@ offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float d
delete input; delete input;
// perform second offset // perform second offset
ClipperLib::Polygons* output2 = new ClipperLib::Polygons(); ClipperLib::OffsetPolygons(*output1, retval, (delta2*scale), joinType, miterLimit);
ClipperLib::OffsetPolygons(*output1, *output2, (delta2*scale), joinType, miterLimit);
delete output1; delete output1;
// unscale output // 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 // convert into ExPolygons
ClipperPolygons_to_Slic3rExPolygons(*output2, retval); ClipperPolygons_to_Slic3rPolygons(*output, retval);
delete output2; 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, inline void _clipper_ex(ClipperLib::ClipType clipType, Slic3r::Polygons &subject,

View file

@ -8,7 +8,6 @@
namespace Slic3r { namespace Slic3r {
void ClipperPolygon_to_Slic3rPolygon(ClipperLib::Polygon &input, Slic3r::Polygon &output);
//----------------------------------------------------------- //-----------------------------------------------------------
// legacy code from Clipper documentation // 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 Slic3rPolygon_to_ClipperPolygon(Slic3r::Polygon &input, ClipperLib::Polygon &output);
void Slic3rPolygons_to_ClipperPolygons(Slic3r::Polygons &input, ClipperLib::Polygons &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 ClipperPolygons_to_Slic3rExPolygons(ClipperLib::Polygons &input, Slic3r::ExPolygons &output);
void scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale); 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, void offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta,
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); 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, void offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta1,
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);

View file

@ -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 ExPolygons
offset_ex(polygons, delta, scale = 100000, joinType = ClipperLib::jtMiter, miterLimit = 3) offset_ex(polygons, delta, scale = 100000, joinType = ClipperLib::jtMiter, miterLimit = 3)
Polygons polygons Polygons polygons
@ -22,6 +34,19 @@ offset_ex(polygons, delta, scale = 100000, joinType = ClipperLib::jtMiter, miter
OUTPUT: OUTPUT:
RETVAL 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 ExPolygons
offset2_ex(polygons, delta1, delta2, scale = 100000, joinType = ClipperLib::jtMiter, miterLimit = 3) offset2_ex(polygons, delta1, delta2, scale = 100000, joinType = ClipperLib::jtMiter, miterLimit = 3)
Polygons polygons Polygons polygons