From 8dc6eca03fe39bc399e6bf0a53a2ef8a0e7d8d1d Mon Sep 17 00:00:00 2001 From: platsch Date: Wed, 9 May 2018 02:39:36 +0200 Subject: [PATCH] Match object top (#4321) * Fix: don't render layers in spline preview if they are outside the printable / visible region * Try to reduce / thicken top layer in adaptive slicing mode to better match top of object --- lib/Slic3r/GUI/Plater/SplineControl.pm | 10 +++++-- xs/src/libslic3r/PrintObject.cpp | 38 ++++++++++++++++++-------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/Slic3r/GUI/Plater/SplineControl.pm b/lib/Slic3r/GUI/Plater/SplineControl.pm index 92918d435..f47a91af2 100644 --- a/lib/Slic3r/GUI/Plater/SplineControl.pm +++ b/lib/Slic3r/GUI/Plater/SplineControl.pm @@ -336,9 +336,13 @@ sub _draw_layers_as_lines { my $last_z = 0.0; foreach my $z (@$layers) { my $layer_h = $z - $last_z; - my $pl = $self->point_to_pixel(0, $z); - my $pr = $self->point_to_pixel($layer_h, $z); - $dc->DrawLine($pl->x, $pl->y, $pr->x, $pr->y); + # only draw layers up to object height. The spline might contain one more layer due to + # print_z / slice_z effects + if($z le $self->{object_height}) { + my $pl = $self->point_to_pixel(0, $z); + my $pr = $self->point_to_pixel($layer_h, $z); + $dc->DrawLine($pl->x, $pl->y, $pr->x, $pr->y); + } $last_z = $z; } } diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index 6d60f3c6f..9700057b0 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -603,7 +603,7 @@ std::vector PrintObject::generate_object_layers(coordf_t first_layer_h } // loop until we have at least one layer and the max slice_z reaches the object height - while (print_z < unscale(this->size.z)) { + while ((scale_(print_z + EPSILON)) < this->size.z) { if (this->config.adaptive_slicing.value) { height = 999; @@ -652,36 +652,50 @@ std::vector PrintObject::generate_object_layers(coordf_t first_layer_h result.push_back(print_z); } + // Store layer vector for interactive manipulation + this->layer_height_spline.setLayers(result); + if (this->config.adaptive_slicing.value) { + // smoothing after adaptive algorithm + result = this->layer_height_spline.getInterpolatedLayers(); + // remove top layer if empty + coordf_t slice_z = result.back() - (result[result.size()-1] - result[result.size()-2])/2.0; + if(slice_z > unscale(this->size.z)) { + result.pop_back(); + } + } + // Reduce or thicken the top layer in order to match the original object size. // This is not actually related to z_steps_per_mm but we only enable it in case // user provided that value, as it means they really care about the layer height // accuracy and we don't provide unexpected result for people noticing the last // layer has a different layer height. - if (this->_print->config.z_steps_per_mm > 0 && result.size() > 1 && !this->config.adaptive_slicing.value) { + if ((this->_print->config.z_steps_per_mm > 0 || this->config.adaptive_slicing.value) && result.size() > 1) { coordf_t diff = result.back() - unscale(this->size.z); int last_layer = result.size()-1; if (diff < 0) { // we need to thicken last layer coordf_t new_h = result[last_layer] - result[last_layer-1]; - new_h = std::min(min_nozzle_diameter, new_h - diff); // add (negativ) diff value + if(this->config.adaptive_slicing.value) { // use min/max layer_height values from adaptive algo. + new_h = std::min(max_layer_height, new_h - diff); // add (negativ) diff value + }else{ + new_h = std::min(min_nozzle_diameter, new_h - diff); // add (negativ) diff value + } result[last_layer] = result[last_layer-1] + new_h; } else { // we need to reduce last layer coordf_t new_h = result[last_layer] - result[last_layer-1]; - if(min_nozzle_diameter/2 < new_h) { //prevent generation of a too small layer - new_h = std::max(min_nozzle_diameter/2, new_h - diff); // subtract (positive) diff value - result[last_layer] = result[last_layer-1] + new_h; + if(this->config.adaptive_slicing.value) { // use min/max layer_height values from adaptive algo. + new_h = std::max(min_layer_height, new_h - diff); // subtract (positive) diff value + }else{ + if(min_nozzle_diameter/2 < new_h) { //prevent generation of a too small layer + new_h = std::max(min_nozzle_diameter/2, new_h - diff); // subtract (positive) diff value + } } + result[last_layer] = result[last_layer-1] + new_h; } } - // Store layer vector for interactive manipulation - this->layer_height_spline.setLayers(result); - if (this->config.adaptive_slicing.value) { // smoothing after adaptive algorithm - result = this->layer_height_spline.getInterpolatedLayers(); - } - this->state.set_done(posLayers); }