From 80676f358acb062c64e6460dedf3418447e38a1a Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 29 Jul 2013 13:36:22 +0200 Subject: [PATCH] Keep edge lines in rectilinear infill even when the sides are not perfectly straight --- lib/Slic3r/ExPolygon.pm | 6 ++++++ lib/Slic3r/Fill/Rectilinear.pm | 5 ++++- t/fill.t | 22 ++++++++++++++++------ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index bd5ed4e3fb..3db8a7241a 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -84,6 +84,12 @@ sub wkt { join ',', map "($_)", map { join ',', map "$_->[0] $_->[1]", @$_ } @$self; } +sub dump_perl { + my $self = shift; + return sprintf "[%s]", + join ',', map "[$_]", map { join ',', map "[$_->[0],$_->[1]]", @$_ } @$self; +} + sub offset { my $self = shift; return Slic3r::Geometry::Clipper::offset($self, @_); diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index c58b3871a0..50567dc399 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -55,8 +55,11 @@ sub fill_surface { # clip paths against a slightly offsetted expolygon, so that the first and last paths # are kept even if the expolygon has vertical sides + # 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 @paths = @{ Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection( - [ $expolygon->offset_ex(scaled_epsilon) ], + [ $expolygon->offset_ex($line_spacing*0.05) ], [ @vertical_lines ], ) }; diff --git a/t/fill.t b/t/fill.t index 9ffce0ba18..ca064fac3f 100644 --- a/t/fill.t +++ b/t/fill.t @@ -2,7 +2,7 @@ use Test::More; use strict; use warnings; -plan tests => 31; +plan tests => 32; BEGIN { use FindBin; @@ -51,8 +51,8 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } { my $test = sub { - my ($expolygon) = @_; - $expolygon->align_to_origin; + my ($expolygon, $flow_spacing) = @_; + my $filler = Slic3r::Fill::Rectilinear->new( bounding_box => $expolygon->bounding_box, angle => 0, @@ -61,12 +61,17 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } surface_type => S_TYPE_BOTTOM, expolygon => $expolygon, ); - my ($params, @paths) = $filler->fill_surface($surface, flow_spacing => 0.55, density => 1); + my ($params, @paths) = $filler->fill_surface($surface, flow_spacing => $flow_spacing, density => 1); # check whether any part was left uncovered my @grown_paths = map Slic3r::Polyline->new(@$_)->grow(scale $params->{flow_spacing}/2), @paths; my $uncovered = diff_ex([ @$expolygon ], [ @grown_paths ], 1); + + # ignore very small dots + @$uncovered = grep $_->area > (scale $flow_spacing)**2, @$uncovered; + is scalar(@$uncovered), 0, 'solid surface is fully filled'; + if (0 && @$uncovered) { require "Slic3r/SVG.pm"; Slic3r::SVG::output( @@ -84,12 +89,17 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } [3116896, 20327272.01297], [3116896, 9598327.01296997], ]); - $test->($expolygon); + $test->($expolygon, 0.55); for (1..20) { $expolygon->scale(1.05); - $test->($expolygon); + $test->($expolygon, 0.55); } + + $expolygon = Slic3r::ExPolygon->new( + [[59515297,5422499],[59531249,5578697],[59695801,6123186],[59965713,6630228],[60328214,7070685],[60773285,7434379],[61274561,7702115],[61819378,7866770],[62390306,7924789],[62958700,7866744],[63503012,7702244],[64007365,7434357],[64449960,7070398],[64809327,6634999],[65082143,6123325],[65245005,5584454],[65266967,5422499],[66267307,5422499],[66269190,8310081],[66275379,17810072],[66277259,20697500],[65267237,20697500],[65245004,20533538],[65082082,19994444],[64811462,19488579],[64450624,19048208],[64012101,18686514],[63503122,18415781],[62959151,18251378],[62453416,18198442],[62390147,18197355],[62200087,18200576],[61813519,18252990],[61274433,18415918],[60768598,18686517],[60327567,19047892],[59963609,19493297],[59695865,19994587],[59531222,20539379],[59515153,20697500],[58502480,20697500],[58502480,5422499]] + ); + $test->($expolygon, 0.524341649025257); } {