From 5281b101f9bac65a03eb35aa93eaff0fa4aa6895 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Fri, 24 Aug 2012 18:59:23 +0200 Subject: [PATCH] Some infill paths were still disconnected, causing unnecessary retractions --- lib/Slic3r/ExPolygon.pm | 12 ++++++++---- lib/Slic3r/Fill/Rectilinear.pm | 10 ++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index 70371855..5f9d2357 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -6,7 +6,7 @@ use warnings; use Boost::Geometry::Utils; use Math::Geometry::Voronoi; -use Slic3r::Geometry qw(X Y A B point_in_polygon same_line); +use Slic3r::Geometry qw(X Y A B point_in_polygon same_line line_length); use Slic3r::Geometry::Clipper qw(union_ex JT_MITER); # the constructor accepts an array of polygons @@ -110,10 +110,14 @@ sub encloses_point_quick { sub encloses_line { my $self = shift; - my ($line) = @_; - + my ($line, $tolerance) = @_; my $clip = $self->clip_line($line); - return @$clip == 1 && same_line($clip->[0], $line); + if (!defined $tolerance) { + # optimization + return @$clip == 1 && same_line($clip->[0], $line); + } else { + return @$clip == 1 && abs(line_length($clip->[0]) - $line->length) < $tolerance; + } } sub point_on_segment { diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index ebfa316e..2de7872a 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -14,9 +14,8 @@ sub fill_surface { my $rotate_vector = $self->infill_direction($surface); $self->rotate_points($expolygon, $rotate_vector); - my ($expolygon_off) = $expolygon->offset_ex(scale 0.3); + my ($expolygon_off) = $expolygon->offset_ex(scale $params{flow_spacing}/2); return {} if !$expolygon_off; # skip some very small polygons (which shouldn't arrive here) - my ($expolygon_epsilon_off) = $expolygon->offset_ex(scale epsilon); my $bounding_box = [ $expolygon->bounding_box ]; my $min_spacing = scale $params{flow_spacing}; @@ -46,8 +45,11 @@ sub fill_surface { push @vertical_lines, $vertical_line; $x += $distance_between_lines; } + + # clip paths against a slightly offsetted expolygon, so that the first and last paths + # are kept even if the expolygon has vertical sides my @paths = @{ Boost::Geometry::Utils::polygon_linestring_intersection( - $expolygon_epsilon_off->boost_polygon, + +($expolygon->offset_ex(scale epsilon))[0]->boost_polygon, # TODO: we should use all the resulting expolygons and clip the linestrings to a multipolygon object Boost::Geometry::Utils::linestring(@vertical_lines), ) }; for (@paths) { @@ -78,7 +80,7 @@ sub fill_surface { # TODO: we should also check that both points are on a fill_boundary to avoid # connecting paths on the boundaries of internal regions if ($can_connect->(@distance, $paths[-1][-1], $path->points->[0]) - && $expolygon_off->encloses_line(Slic3r::Line->new($paths[-1][-1], $path->points->[0]))) { + && $expolygon_off->encloses_line(Slic3r::Line->new($paths[-1][-1], $path->points->[0]), $tolerance)) { push @{$paths[-1]}, @{$path->points}; next; }