diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index bc4216889..0c60a46d8 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -13,6 +13,8 @@ has 'id' => ( required => 1, ); +has 'slicing_errors' => (is => 'rw'); + # collection of spare segments generated by slicing the original geometry; # these need to be merged in continuos (closed) polylines has 'lines' => ( diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index cfba9561d..d2a54c544 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -98,6 +98,48 @@ sub new_from_mesh { $layer->make_surfaces($mesh->make_loops($layer)); } + # detect slicing errors + my $warning_thrown = 0; + for (my $i = 0; $i <= $#{$print->layers}; $i++) { + my $layer = $print->layers->[$i]; + next unless $layer->slicing_errors; + if (!$warning_thrown) { + warn "The model has overlapping or self-intersecting facets. I tried to repair it, " + . "however you might want to check the results or repair the input file and retry.\n"; + $warning_thrown = 1; + } + + # try to repair the layer surfaces by merging all contours and all holes from + # neighbor layers + Slic3r::debugf "Attempting to repair layer %d\n", $i; + + my (@upper_surfaces, @lower_surfaces); + for (my $j = $i+1; $j <= $#{$print->layers}; $j++) { + if (!$print->layers->[$j]->slicing_errors) { + @upper_surfaces = @{$print->layers->[$j]->surfaces}; + last; + } + } + for (my $j = $i-1; $j >= 0; $j--) { + if (!$print->layers->[$j]->slicing_errors) { + @lower_surfaces = @{$print->layers->[$j]->surfaces}; + last; + } + } + + my $union = union_ex([ + map $_->expolygon->contour, @upper_surfaces, @lower_surfaces, + ]); + my $diff = diff_ex( + [ map @$_, @$union ], + [ map $_->expolygon->holes, @upper_surfaces, @lower_surfaces, ], + ); + + @{$layer->surfaces} = map Slic3r::Surface->cast_from_expolygon + ($_, surface_type => 'internal'), + @$diff; + } + return $print; } diff --git a/lib/Slic3r/TriangleMesh.pm b/lib/Slic3r/TriangleMesh.pm index a2120a920..3ef1baf3e 100644 --- a/lib/Slic3r/TriangleMesh.pm +++ b/lib/Slic3r/TriangleMesh.pm @@ -215,6 +215,7 @@ sub make_loops { if (@discarded_lines) { print " Warning: even slow detection algorithm threw errors. Review the output before printing.\n"; + $layer->slicing_errors(1); } }