From d9f5fdae72fc83a841b323725a77101de803560c Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 15 Jul 2014 19:07:38 +0200 Subject: [PATCH] Bugfix: make_perimeters() was not truly idempotent because prepare_infill() split ->slices into typed surfaces --- lib/Slic3r/Layer.pm | 5 +++++ lib/Slic3r/Layer/Region.pm | 11 +++++++++++ lib/Slic3r/Print/Object.pm | 11 ++++++++++- xs/src/Print.cpp | 3 ++- xs/src/Print.hpp | 4 ++++ xs/xsp/Print.xsp | 7 ++++++- 6 files changed, 38 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index 094ae0b2c..f6fc9f342 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -57,6 +57,11 @@ sub make_slices { $self->slices->append(@$slices); } +sub merge_slices { + my ($self) = @_; + $_->merge_slices for @{$self->regions}; +} + sub make_perimeters { my $self = shift; Slic3r::debugf "Making perimeters for layer %d\n", $self->id; diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 25c840490..0b52e6f0d 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -40,6 +40,17 @@ sub flow { ); } +sub merge_slices { + my ($self) = @_; + + my $expolygons = union_ex([ map $_->p, @{$self->slices} ]); + $self->slices->clear; + $self->slices->append(Slic3r::Surface->new( + expolygon => $_, + surface_type => S_TYPE_INTERNAL, + )) for @$expolygons; +} + sub make_perimeters { my ($self, $slices, $fill_surfaces) = @_; diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index ace1d7afb..182e21998 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -366,6 +366,7 @@ sub slice { die "No layers were detected. You might want to repair your STL file(s) or check their size and retry.\n" if !@{$self->layers}; + $self->set_typed_slices(0); $self->set_step_done(STEP_SLICE); } @@ -412,6 +413,13 @@ sub make_perimeters { $self->set_step_started(STEP_PERIMETERS); $self->print->status_cb->(20, "Generating perimeters"); + # merge slices if they were split into types + if ($self->typed_slices) { + $_->merge_slices for @{$self->layers}; + $self->set_typed_slices(0); + $self->invalidate_step(STEP_PREPARE_INFILL); + } + # compare each layer to the one below, and mark those slices needing # one additional inner perimeter, like the top of domed objects- @@ -509,7 +517,8 @@ sub prepare_infill { # and transform $layerm->fill_surfaces from expolygon # to typed top/bottom/internal surfaces; $self->detect_surfaces_type; - + $self->set_typed_slices(1); + # decide what surfaces are to be filled $_->prepare_fill_surfaces for map @{$_->regions}, @{$self->layers}; diff --git a/xs/src/Print.cpp b/xs/src/Print.cpp index 43b168fa1..3e447685c 100644 --- a/xs/src/Print.cpp +++ b/xs/src/Print.cpp @@ -66,7 +66,8 @@ REGISTER_CLASS(PrintRegion, "Print::Region"); PrintObject::PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox) : _print(print), - _model_object(model_object) + _model_object(model_object), + typed_slices(false) { region_volumes.resize(this->_print->regions.size()); diff --git a/xs/src/Print.hpp b/xs/src/Print.hpp index 7b1734be9..9bd0d8212 100644 --- a/xs/src/Print.hpp +++ b/xs/src/Print.hpp @@ -70,6 +70,10 @@ class PrintObject Points copies; // Slic3r::Point objects in scaled G-code coordinates PrintObjectConfig config; t_layer_height_ranges layer_height_ranges; + + // this is set to true when LayerRegion->slices is split in top/internal/bottom + // so that next call to make_perimeters() performs a union() before computing loops + bool typed_slices; Point3 size; // XYZ in scaled coordinates diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index d246dbfe5..c104eaf30 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -61,7 +61,12 @@ _constant() %code%{ RETVAL = &THIS->size; %}; Ref _copies_shift() %code%{ RETVAL = &THIS->_copies_shift; %}; - + + bool typed_slices() + %code%{ RETVAL = THIS->typed_slices; %}; + void set_typed_slices(bool value) + %code%{ THIS->typed_slices = value; %}; + Points _shifted_copies() %code%{ RETVAL = THIS->_shifted_copies; %}; void set_shifted_copies(Points value)