From 04aa240265ea35d881dd5d395255bf9db23fcb52 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 13 Jan 2015 20:51:31 +0100 Subject: [PATCH] Only apply perimeter/infill overlap to the endpoints of rectilinear infill (and do that in a more proper way) --- lib/Slic3r/Fill.pm | 2 +- lib/Slic3r/Fill/Concentric.pm | 4 +--- lib/Slic3r/Fill/Rectilinear.pm | 13 ++++++++++++- lib/Slic3r/Print/Object.pm | 2 +- xs/xsp/Point.xsp | 4 ++++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 1881d461b..e3acbe551 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -142,7 +142,7 @@ sub make_fill { # we are going to grow such regions by overlapping them with the void (if any) # TODO: detect and investigate whether there could be narrow regions without # any void neighbors - my $distance_between_surfaces = $infill_flow->scaled_spacing * &Slic3r::INFILL_OVERLAP_OVER_SPACING; + my $distance_between_surfaces = $infill_flow->scaled_spacing; { my $collapsed = diff( [ map @{$_->expolygon}, @surfaces ], diff --git a/lib/Slic3r/Fill/Concentric.pm b/lib/Slic3r/Fill/Concentric.pm index 17f3fa225..1bc9b79f9 100644 --- a/lib/Slic3r/Fill/Concentric.pm +++ b/lib/Slic3r/Fill/Concentric.pm @@ -26,9 +26,7 @@ sub fill_surface { $self->spacing(unscale $distance); } - # 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 - my @loops = my @last = @{offset(\@$expolygon, -&Slic3r::INFILL_OVERLAP_OVER_SPACING * $min_spacing / 2)}; + my @loops = my @last = map $_->clone, @$expolygon; while (@last) { push @loops, @last = @{offset2(\@last, -($distance + 0.5*$min_spacing), +0.5*$min_spacing)}; } diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index a50e12b09..b16b0bb0c 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -54,10 +54,21 @@ sub fill_surface { # the minimum offset for preventing edge lines from being clipped is scaled_epsilon; # however we use a larger offset to support expolygons with slightly skewed sides and # not perfectly straight - my @polylines = @{intersection_pl(\@vertical_lines, $expolygon->offset(scale 0.02))}; + my @polylines = @{intersection_pl(\@vertical_lines, $expolygon->offset(+scale 0.02))}; + + my $extra = $self->_min_spacing * &Slic3r::INFILL_OVERLAP_OVER_SPACING; + foreach my $polyline (@polylines) { + my ($first_point, $last_point) = @$polyline[0,-1]; + if ($first_point->y > $last_point->y) { #> + ($first_point, $last_point) = ($last_point, $first_point); + } + $first_point->set_y($first_point->y - $extra); #-- + $last_point->set_y($last_point->y + $extra); #++ + } # connect lines unless ($params{dont_connect} || !@polylines) { # prevent calling leftmost_point() on empty collections + # offset the expolygon by max(min_spacing/2, extra) my ($expolygon_off) = @{$expolygon->offset_ex($self->_min_spacing/2)}; my $collection = Slic3r::Polyline::Collection->new(@polylines); @polylines = (); diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 93b69a0fa..4475e880f 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -1009,7 +1009,7 @@ sub combine_infill { # Because fill areas for rectilinear and honeycomb are grown # later to overlap perimeters, we need to counteract that too. + (($type == S_TYPE_INTERNALSOLID || $region->config->fill_pattern =~ /(rectilinear|honeycomb)/) - ? $layerms[-1]->flow(FLOW_ROLE_SOLID_INFILL)->scaled_width * &Slic3r::INFILL_OVERLAP_OVER_SPACING + ? $layerms[-1]->flow(FLOW_ROLE_SOLID_INFILL)->scaled_width : 0) )}, @$intersection; diff --git a/xs/xsp/Point.xsp b/xs/xsp/Point.xsp index 871911239..8386b146b 100644 --- a/xs/xsp/Point.xsp +++ b/xs/xsp/Point.xsp @@ -22,6 +22,10 @@ %code{% RETVAL = THIS->x; %}; long y() %code{% RETVAL = THIS->y; %}; + void set_x(long val) + %code{% THIS->x = val; %}; + void set_y(long val) + %code{% THIS->y = val; %}; int nearest_point_index(Points points); Point* nearest_point(Points points) %code{% RETVAL = new Point(); THIS->nearest_point(points, RETVAL); %};