From aba7641fe4fce121df57f2fdce6c351e04165d9c Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Fri, 21 Jun 2013 19:43:15 +0200 Subject: [PATCH] Avoid starting loops on convex vertices and/or overhangs. #296 #135 --- lib/Slic3r/GCode.pm | 22 ++++++++++++++++++++-- lib/Slic3r/Polygon.pm | 10 +++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 14e6521f..a8000cba 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -141,6 +141,25 @@ sub extrude_loop { $loop = $loop->unpack if $loop->isa('Slic3r::ExtrusionLoop::Packed'); my $was_clockwise = $loop->polygon->make_counter_clockwise; + # find candidate starting points + # start looking for concave vertices not being overhangs + my @concave = $loop->polygon->concave_points; + my @candidates = grep Boost::Geometry::Utils::point_covered_by_multi_polygon($_, $self->_layer_overhangs), + @concave; + if (!@candidates) { + # if none, look for any concave vertex + @candidates = @concave; + if (!@candidates) { + # if none, look for any non-overhang vertex + @candidates = grep Boost::Geometry::Utils::point_covered_by_multi_polygon($_, $self->_layer_overhangs), + @{$loop->polygon}; + if (!@candidates) { + # if none, all points are valid candidates + @candidates = @{$loop->polygon}; + } + } + } + # find the point of the loop that is closest to the current extruder position # or randomize if requested my $last_pos = $self->last_pos; @@ -148,10 +167,9 @@ sub extrude_loop { $last_pos = Slic3r::Point->new(scale $self->config->print_center->[X], scale $self->config->bed_size->[Y]); $last_pos->rotate(rand(2*PI), $self->config->print_center); } - my $start_index = $loop->nearest_point_index_to($last_pos); # split the loop at the starting point and make a path - my $extrusion_path = $loop->split_at_index($start_index); + my $extrusion_path = $loop->split_at(Slic3r::Geometry::nearest_point($last_pos, \@candidates)); # clip the path to avoid the extruder to get exactly on the first point of the loop; # if polyline was shorter than the clipping distance we'd get a null polyline, so diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm index 72488798..9cc8fcb1 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -7,7 +7,7 @@ use parent 'Slic3r::Polyline'; use Slic3r::Geometry qw(polygon_lines polygon_remove_parallel_continuous_edges polygon_remove_acute_vertices polygon_segment_having_point point_in_polygon - X1 X2 Y1 Y2); + PI X1 X2 Y1 Y2); use Slic3r::Geometry::Clipper qw(JT_MITER); sub lines { @@ -154,4 +154,12 @@ sub split_at_first_point { return $self->split_at_index(0); } +sub concave_points { + my $self = shift; + + return map $self->[$_], + grep Slic3r::Geometry::angle3points(@$self[$_, $_-1, $_+1]) < PI, + -1 .. ($#$self-1); +} + 1; \ No newline at end of file