diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 52d12dc1b5..fe4a52121a 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -259,9 +259,12 @@ sub make_perimeters { next if !@$diff; # if we need more perimeters, $diff should contain a narrow region that we can collapse + # we use a higher miterLimit here to handle areas with acute angles + # in those cases, the default miterLimit would cut the corner and we'd + # get a triangle that would trigger a non-needed extra perimeter $diff = diff( $diff, - offset2($diff, -$perimeter_spacing, +$perimeter_spacing), + offset2($diff, -$perimeter_spacing, +$perimeter_spacing, CLIPPER_OFFSET_SCALE, JT_MITER, 5), 1, ); next if !@$diff; diff --git a/lib/Slic3r/Test.pm b/lib/Slic3r/Test.pm index a5bb27127b..811d14a2b0 100644 --- a/lib/Slic3r/Test.pm +++ b/lib/Slic3r/Test.pm @@ -69,6 +69,13 @@ sub model { $facets = [ [0,1,2],[2,1,3],[1,0,4],[5,1,4],[6,2,7],[0,2,8],[0,8,9],[0,9,10],[0,10,11],[0,11,12],[0,12,13],[0,13,4],[13,14,4],[15,4,16],[17,4,15],[18,4,17],[19,4,20],[18,20,4],[21,2,22],[4,19,23],[4,23,7],[23,24,7],[22,2,25],[26,2,27],[28,29,7],[25,2,30],[29,31,7],[30,2,26],[31,32,7],[27,2,6],[32,6,7],[28,7,24],[33,2,21],[34,2,33],[35,2,34],[36,2,35],[8,2,36],[16,4,14],[2,3,7],[7,3,37],[38,1,5],[3,1,39],[3,39,40],[3,40,41],[42,38,5],[3,41,43],[3,43,44],[37,3,45],[37,45,46],[37,46,47],[48,49,5],[37,47,50],[49,42,5],[37,50,51],[37,51,52],[37,52,53],[37,53,54],[55,56,5],[37,54,57],[37,57,58],[59,60,5],[37,58,61],[37,62,5],[37,61,62],[62,59,5],[60,55,5],[63,1,38],[64,1,63],[65,1,64],[66,1,65],[67,1,66],[39,1,67],[44,45,3],[56,48,5],[5,4,7],[37,5,7],[41,40,36],[36,40,8],[39,9,40],[40,9,8],[43,41,35],[35,41,36],[44,43,34],[34,43,35],[33,45,44],[34,33,44],[21,46,45],[33,21,45],[22,47,46],[21,22,46],[25,50,47],[22,25,47],[30,51,50],[25,30,50],[26,52,51],[30,26,51],[27,53,52],[26,27,52],[6,54,53],[27,6,53],[32,57,54],[6,32,54],[31,58,57],[32,31,57],[29,61,58],[31,29,58],[28,62,61],[29,28,61],[59,62,28],[24,59,28],[60,59,24],[23,60,24],[55,60,23],[19,55,23],[55,19,56],[56,19,20],[56,20,48],[48,20,18],[48,18,49],[49,18,17],[49,17,42],[42,17,15],[42,15,38],[38,15,16],[38,16,63],[63,16,14],[63,14,64],[64,14,13],[64,13,65],[65,13,12],[65,12,66],[66,12,11],[66,11,67],[67,11,10],[67,10,39],[39,10,9] ], + } elsif ($model_name eq 'ipadstand') { + $vertices = [ + [17.4344673156738,-2.69879599481136e-16,9.5],[14.2814798355103,10,9.5],[0,0,9.5],[31.7159481048584,10,9.5],[62.2344741821289,2.06667568800577e-16,20],[31.7159481048584,10,20],[17.4344673156738,-2.69879599481136e-16,20],[62.2344741821289,10,20],[98.2079696655273,10,0],[98.2079696655273,8.56525380796383e-16,10],[98.2079696655273,0,0],[98.2079696655273,10,20],[98.2079696655273,0,20],[81.6609649658203,-4.39753856997999e-16,10],[90.0549850463867,10,10],[78.5079803466797,10,10],[93.2079696655273,8.56525380796383e-16,10],[14.2814798355103,10,20],[0,0,20],[87.4344711303711,2.81343962782118e-15,20],[84.2814788818359,10,20],[0,10,20],[0,0,0],[0,10,0],[62.2344741821289,2.06667568800577e-16,30],[66.9609756469727,10,30],[62.2344741821289,10,30],[70.1139602661133,8.5525763717214e-16,30],[67.7053375244141,10,28.7107200622559],[71.6787109375,1.24046736339707e-15,27.2897701263428] + ]; + $facets = [ + [0,1,2],[1,0,3],[4,5,6],[5,4,7],[8,9,10],[9,11,12],[11,9,8],[13,14,15],[14,13,16],[17,2,1],[2,17,18],[19,11,20],[11,19,12],[17,21,18],[21,2,18],[2,21,22],[22,21,23],[8,22,23],[22,8,10],[24,25,26],[25,24,27],[23,1,8],[1,23,21],[1,21,17],[5,15,3],[15,5,7],[15,7,28],[28,7,26],[28,26,25],[8,14,11],[14,8,3],[3,8,1],[14,3,15],[11,14,20],[26,4,24],[4,26,7],[12,16,9],[16,12,19],[29,4,13],[4,29,24],[24,29,27],[9,22,10],[22,9,0],[0,9,16],[0,16,13],[0,13,6],[6,13,4],[2,22,0],[19,14,16],[14,19,20],[15,29,13],[29,25,27],[25,29,15],[25,15,28],[6,3,0],[3,6,5] + ]; } else { return undef; } diff --git a/t/perimeters.t b/t/perimeters.t index 95db7c923d..eeb0b40477 100644 --- a/t/perimeters.t +++ b/t/perimeters.t @@ -1,4 +1,4 @@ -use Test::More tests => 5; +use Test::More tests => 6; use strict; use warnings; @@ -139,4 +139,33 @@ use Slic3r::Test; } } +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('skirts', 0); + $config->set('perimeters', 3); + $config->set('layer_height', 0.4); + $config->set('first_layer_height', 0.35); + $config->set('extra_perimeters', 1); + $config->set('cooling', 0); # to prevent speeds from being altered + $config->set('first_layer_speed', '100%'); # to prevent speeds from being altered + $config->set('perimeter_speed', 99); + $config->set('external_perimeter_speed', 99); + $config->set('small_perimeter_speed', 99); + + my $print = Slic3r::Test::init_print('ipadstand', config => $config); + my %perimeters = (); # z => number of loops + my $in_loop = 0; + Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { + my ($self, $cmd, $args, $info) = @_; + + if ($info->{extruding} && $info->{dist_XY} > 0 && ($args->{F} // $self->F) == $config->perimeter_speed*60) { + $perimeters{$self->Z}++ if !$in_loop; + $in_loop = 1; + } else { + $in_loop = 0; + } + }); + ok !(grep { $_ % $config->perimeters } values %perimeters), 'no superfluous extra perimeters'; +} + __END__