From 15628a90ed994083a02be45b7411e3b00fe96e48 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Fri, 18 Apr 2014 17:30:35 +0200 Subject: [PATCH] Regression test for numerical issues causing thin gaps between perimeters and infill. #1803 --- lib/Slic3r/Layer/Region.pm | 8 +++--- t/perimeters.t | 57 +++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 28df15c51..14347b183 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -83,7 +83,6 @@ sub make_perimeters { my @contours = (); # array of Polygons with ccw orientation my @holes = (); # array of Polygons with cw orientation my @thin_walls = (); # array of ExPolygons - my @gaps = (); # array of ExPolygons # we need to process each island separately because we might have different # extra perimeters for each one @@ -92,7 +91,7 @@ sub make_perimeters { my $loop_number = $self->config->perimeters + ($surface->extra_perimeters || 0); my @last = @{$surface->expolygon}; - my @last_gaps = (); + my @gaps = (); # array of ExPolygons if ($loop_number > 0) { # we loop one time more than needed in order to find gaps after the last perimeter was applied for my $i (1 .. ($loop_number+1)) { # outer loop is 1 @@ -131,7 +130,7 @@ sub make_perimeters { offset(\@last, -0.5*$pspacing), offset(\@offsets, +0.5*$pspacing + 10), # safety offset ); - push @gaps, @last_gaps = grep abs($_->area) >= $gap_area_threshold, @$diff; + push @gaps, grep abs($_->area) >= $gap_area_threshold, @$diff; } } @@ -149,7 +148,7 @@ sub make_perimeters { } } } - + # fill gaps if (@gaps) { if (0) { @@ -201,6 +200,7 @@ sub make_perimeters { ); } + # process thin walls by collapsing slices to single passes my @thin_wall_polylines = (); if (@thin_walls) { diff --git a/t/perimeters.t b/t/perimeters.t index 9490b6959..ca9ed9ac0 100644 --- a/t/perimeters.t +++ b/t/perimeters.t @@ -1,4 +1,4 @@ -use Test::More tests => 6; +use Test::More tests => 7; use strict; use warnings; @@ -7,6 +7,7 @@ BEGIN { use lib "$FindBin::Bin/../lib"; } +use List::Util qw(first); use Slic3r; use Slic3r::Flow ':roles'; use Slic3r::Geometry qw(PI scale unscale); @@ -181,4 +182,58 @@ use Slic3r::Test; ok !(grep { $_ % $config->perimeters } values %perimeters), 'no superfluous extra perimeters'; } +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('nozzle_diameter', [0.4]); + $config->set('perimeters', 2); + $config->set('perimeter_extrusion_width', 0.4); + $config->set('infill_extrusion_width', 0.53); + $config->set('solid_infill_extrusion_width', 0.53); + + # we just need a pre-filled Print object + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + $print->init_extruders; + + # override a layer's slices + my $expolygon = Slic3r::ExPolygon->new([[-71974463,-139999376],[-71731792,-139987456],[-71706544,-139985616],[-71682119,-139982639],[-71441248,-139946912],[-71417487,-139942895],[-71379384,-139933984],[-71141800,-139874480],[-71105247,-139862895],[-70873544,-139779984],[-70838592,-139765856],[-70614943,-139660064],[-70581783,-139643567],[-70368368,-139515680],[-70323751,-139487872],[-70122160,-139338352],[-70082399,-139306639],[-69894800,-139136624],[-69878679,-139121327],[-69707992,-138933008],[-69668575,-138887343],[-69518775,-138685359],[-69484336,-138631632],[-69356423,-138418207],[-69250040,-138193296],[-69220920,-138128976],[-69137992,-137897168],[-69126095,-137860255],[-69066568,-137622608],[-69057104,-137582511],[-69053079,-137558751],[-69017352,-137317872],[-69014392,-137293456],[-69012543,-137268207],[-68999369,-137000000],[-63999999,-137000000],[-63705947,-136985551],[-63654984,-136977984],[-63414731,-136942351],[-63364756,-136929840],[-63129151,-136870815],[-62851950,-136771631],[-62585807,-136645743],[-62377483,-136520895],[-62333291,-136494415],[-62291908,-136463728],[-62096819,-136319023],[-62058644,-136284432],[-61878676,-136121328],[-61680968,-135903184],[-61650275,-135861807],[-61505591,-135666719],[-61354239,-135414191],[-61332211,-135367615],[-61228359,-135148063],[-61129179,-134870847],[-61057639,-134585262],[-61014451,-134294047],[-61000000,-134000000],[-61000000,-107999999],[-61014451,-107705944],[-61057639,-107414736],[-61129179,-107129152],[-61228359,-106851953],[-61354239,-106585808],[-61505591,-106333288],[-61680967,-106096816],[-61878675,-105878680],[-62096820,-105680967],[-62138204,-105650279],[-62333292,-105505591],[-62585808,-105354239],[-62632384,-105332207],[-62851951,-105228360],[-62900463,-105211008],[-63129152,-105129183],[-63414731,-105057640],[-63705947,-105014448],[-63999999,-105000000],[-68999369,-105000000],[-69012543,-104731792],[-69014392,-104706544],[-69017352,-104682119],[-69053079,-104441248],[-69057104,-104417487],[-69066008,-104379383],[-69125528,-104141799],[-69137111,-104105248],[-69220007,-103873544],[-69234136,-103838591],[-69339920,-103614943],[-69356415,-103581784],[-69484328,-103368367],[-69512143,-103323752],[-69661647,-103122160],[-69693352,-103082399],[-69863383,-102894800],[-69878680,-102878679],[-70066999,-102707992],[-70112656,-102668576],[-70314648,-102518775],[-70368367,-102484336],[-70581783,-102356424],[-70806711,-102250040],[-70871040,-102220919],[-71102823,-102137992],[-71139752,-102126095],[-71377383,-102066568],[-71417487,-102057104],[-71441248,-102053079],[-71682119,-102017352],[-71706535,-102014392],[-71731784,-102012543],[-71974456,-102000624],[-71999999,-102000000],[-104000000,-102000000],[-104025536,-102000624],[-104268207,-102012543],[-104293455,-102014392],[-104317880,-102017352],[-104558751,-102053079],[-104582512,-102057104],[-104620616,-102066008],[-104858200,-102125528],[-104894751,-102137111],[-105126455,-102220007],[-105161408,-102234136],[-105385056,-102339920],[-105418215,-102356415],[-105631632,-102484328],[-105676247,-102512143],[-105877839,-102661647],[-105917600,-102693352],[-106105199,-102863383],[-106121320,-102878680],[-106292007,-103066999],[-106331424,-103112656],[-106481224,-103314648],[-106515663,-103368367],[-106643575,-103581783],[-106749959,-103806711],[-106779080,-103871040],[-106862007,-104102823],[-106873904,-104139752],[-106933431,-104377383],[-106942896,-104417487],[-106946920,-104441248],[-106982648,-104682119],[-106985607,-104706535],[-106987456,-104731784],[-107000630,-105000000],[-112000000,-105000000],[-112294056,-105014448],[-112585264,-105057640],[-112870848,-105129184],[-112919359,-105146535],[-113148048,-105228360],[-113194624,-105250392],[-113414191,-105354239],[-113666711,-105505591],[-113708095,-105536279],[-113903183,-105680967],[-114121320,-105878679],[-114319032,-106096816],[-114349720,-106138200],[-114494408,-106333288],[-114645760,-106585808],[-114667792,-106632384],[-114771640,-106851952],[-114788991,-106900463],[-114870815,-107129151],[-114942359,-107414735],[-114985551,-107705943],[-115000000,-107999999],[-115000000,-134000000],[-114985551,-134294048],[-114942359,-134585263],[-114870816,-134870847],[-114853464,-134919359],[-114771639,-135148064],[-114645759,-135414192],[-114494407,-135666720],[-114319031,-135903184],[-114121320,-136121327],[-114083144,-136155919],[-113903184,-136319023],[-113861799,-136349712],[-113666711,-136494416],[-113458383,-136619264],[-113414192,-136645743],[-113148049,-136771631],[-112870848,-136870815],[-112820872,-136883327],[-112585264,-136942351],[-112534303,-136949920],[-112294056,-136985551],[-112000000,-137000000],[-107000630,-137000000],[-106987456,-137268207],[-106985608,-137293440],[-106982647,-137317872],[-106946920,-137558751],[-106942896,-137582511],[-106933991,-137620624],[-106874471,-137858208],[-106862888,-137894751],[-106779992,-138126463],[-106765863,-138161424],[-106660080,-138385055],[-106643584,-138418223],[-106515671,-138631648],[-106487855,-138676256],[-106338352,-138877839],[-106306647,-138917600],[-106136616,-139105199],[-106121320,-139121328],[-105933000,-139291999],[-105887344,-139331407],[-105685351,-139481232],[-105631632,-139515663],[-105418216,-139643567],[-105193288,-139749951],[-105128959,-139779072],[-104897175,-139862016],[-104860247,-139873904],[-104622616,-139933423],[-104582511,-139942896],[-104558751,-139946912],[-104317880,-139982656],[-104293463,-139985616],[-104268216,-139987456],[-104025544,-139999376],[-104000000,-140000000],[-71999999,-140000000]],[[-105000000,-138000000],[-105000000,-104000000],[-71000000,-104000000],[-71000000,-138000000]],[[-69000000,-132000000],[-69000000,-110000000],[-64991180,-110000000],[-64991180,-132000000]],[[-111008824,-132000000],[-111008824,-110000000],[-107000000,-110000000],[-107000000,-132000000]]); + my $object = $print->objects->[0]; + $object->slice; + my $layer = $object->layers->[1]; + my $layerm = $layer->regions->[0]; + $layerm->slices->clear; + $layerm->slices->append(Slic3r::Surface->new(surface_type => S_TYPE_INTERNAL, expolygon => $expolygon)); + + # make perimeters + $layer->make_perimeters; + + # compute the covered area + my $pflow = $layerm->flow(FLOW_ROLE_PERIMETER); + my $covered_by_perimeters = union_ex([ + (map @{$_->polygon->split_at_first_point->grow($pflow->scaled_width/2)}, @{$layerm->perimeters}), + ]); + my $covered_by_infill = union_ex([ + (map $_->p, @{$layerm->fill_surfaces}), + (map @{$_->polyline->grow($pflow->scaled_width/2)}, @{$layerm->thin_fills}), + ]); + + # compute the non covered area + my $non_covered = diff( + [ map @{$_->expolygon}, @{$layerm->slices} ], + [ map @$_, (@$covered_by_perimeters, @$covered_by_infill) ], + ); + + if (0) { + printf "max non covered = %f\n", List::Util::max(map unscale unscale $_->area, @$non_covered); + require "Slic3r/SVG.pm"; + Slic3r::SVG::output( + "gaps.svg", + expolygons => [ map $_->expolygon, @{$layerm->slices} ], + red_expolygons => union_ex([ map @$_, (@$covered_by_perimeters, @$covered_by_infill) ]), + green_expolygons => union_ex($non_covered), + ); + } + + ok !(defined first { $_->area > ($pflow->scaled_width**2) } @$non_covered), 'no gap between perimeters and infill'; +} + __END__