From c03f9f019747ffa25a93a98c3e7d4e0aa61907a1 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 23 Jun 2013 00:05:08 +0200 Subject: [PATCH] Fixed regression causing wrong direction for inwards move in holes. Includes regression test. #1265 --- lib/Slic3r/GCode.pm | 2 -- lib/Slic3r/Layer/Region.pm | 4 ++++ lib/Slic3r/Test.pm | 7 +++++++ t/perimeters.t | 33 ++++++++++++++++++++++++++++++++- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index a8000cba4..37a5f77d8 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -190,8 +190,6 @@ sub extrude_loop { $extrusion_path->intersect_expolygons($self->_layer_overhangs); # reapply the nearest point search for starting point - # (TODO: choose the nearest point not on an overhang - make sure wipe and - # inwards move consider the new actual starting point) @paths = Slic3r::ExtrusionPath::Collection ->new(paths => [@paths]) ->chained_path($last_pos, 1); diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 7a838d65a..3f71bfba9 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -256,7 +256,11 @@ sub make_perimeters { foreach my $polynode (@nodes) { push @loops, $traverse->($polynode->{children}, $depth+1, $is_contour); + # return ccw contours and cw holes + # GCode.pm will convert all of them to ccw, but it needs to know + # what the holes are in order to compute the correct inwards move my $polygon = Slic3r::Polygon->new($polynode->{outer} // [ reverse @{$polynode->{hole}} ]); + $polygon->reverse if !$is_contour; my $role = EXTR_ROLE_PERIMETER; if ($is_contour ? $depth == 0 : !@{ $polynode->{children} }) { diff --git a/lib/Slic3r/Test.pm b/lib/Slic3r/Test.pm index fee73b0dc..a8bcd2426 100644 --- a/lib/Slic3r/Test.pm +++ b/lib/Slic3r/Test.pm @@ -27,6 +27,13 @@ sub model { $facets = [ [0,1,2], [0,2,3], [4,5,6], [4,6,7], [0,4,7], [0,7,1], [1,7,6], [1,6,2], [2,6,5], [2,5,3], [4,0,3], [4,3,5], ], + } elsif ($model_name eq 'cube_with_hole') { + $vertices = [ + [0,0,0],[0,0,10],[0,20,0],[0,20,10],[20,0,0],[20,0,10],[5,5,0],[15,5,0],[5,15,0],[20,20,0],[15,15,0],[20,20,10],[5,5,10],[5,15,10],[15,5,10],[15,15,10] + ]; + $facets = [ + [0,1,2],[2,1,3],[1,0,4],[5,1,4],[6,7,4],[8,2,9],[0,2,8],[10,8,9],[0,8,6],[0,6,4],[4,7,9],[7,10,9],[2,3,9],[9,3,11],[12,1,5],[13,3,12],[14,12,5],[3,1,12],[11,3,13],[11,15,5],[11,13,15],[15,14,5],[5,4,9],[11,5,9],[8,13,12],[6,8,12],[10,15,13],[8,10,13],[15,10,14],[14,10,7],[14,7,12],[12,7,6] + ], } elsif ($model_name eq 'V') { $vertices = [ [-14,0,20],[-14,15,20],[0,0,0],[0,15,0],[-4,0,20],[-4,15,20],[5,0,7.14286],[10,0,0],[24,0,20],[14,0,20],[10,15,0],[5,15,7.14286],[14,15,20],[24,15,20] diff --git a/t/perimeters.t b/t/perimeters.t index de53b6a14..1ce91bd32 100644 --- a/t/perimeters.t +++ b/t/perimeters.t @@ -1,4 +1,4 @@ -use Test::More tests => 3; +use Test::More tests => 5; use strict; use warnings; @@ -41,6 +41,37 @@ use Slic3r::Test; ok !$has_cw_loops, 'all perimeters extruded ccw'; } + { + $config->set('external_perimeter_speed', 68); + my $print = Slic3r::Test::init_print('cube_with_hole', config => $config); + my $has_cw_loops = my $has_outwards_move = 0; + my $cur_loop; + my %external_loops = (); # print_z => count of external loops + Slic3r::GCode::Reader->new(gcode => Slic3r::Test::gcode($print))->parse(sub { + my ($self, $cmd, $args, $info) = @_; + + if ($info->{extruding} && $info->{dist_XY} > 0) { + $cur_loop ||= [ [$self->X, $self->Y] ]; + push @$cur_loop, [ @$info{qw(new_X new_Y)} ]; + } else { + if ($cur_loop) { + $has_cw_loops = 1 if !Slic3r::Geometry::Clipper::is_counter_clockwise($cur_loop); + if ($self->F == $config->external_perimeter_speed*60) { + my $move_dest = [ @$info{qw(new_X new_Y)} ]; + $external_loops{$self->Z}++; + $has_outwards_move = 1 + if !Slic3r::Polygon->new(@$cur_loop)->encloses_point($move_dest) + ? ($external_loops{$self->Z} == 2) # contour should include destination + : ($external_loops{$self->Z} == 1); # hole should not + } + $cur_loop = undef; + } + } + }); + ok !$has_cw_loops, 'all perimeters extruded ccw'; + ok !$has_outwards_move, 'move inwards after completing external loop'; + } + { my $print = Slic3r::Test::init_print('L', config => $config); my $loop_starts_from_convex_point = 0;