From da44618074fdbe7771a234be29b23d462ec7e3c4 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 18 Nov 2019 14:32:41 +0100 Subject: [PATCH] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Fixed adaptive layer height profile and layer height profile smoothing calculations --- src/libslic3r/Slicing.cpp | 85 ++++++++++++++++++++++------------- src/slic3r/GUI/GLCanvas3D.cpp | 2 - 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 42e721744..66e339246 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -257,17 +257,22 @@ std::vector layer_height_profile_adaptive( #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE std::vector layer_height_profile; - layer_height_profile.push_back(0.); + layer_height_profile.push_back(0.0); layer_height_profile.push_back(slicing_params.first_object_layer_height); if (slicing_params.first_object_layer_height_fixed()) { layer_height_profile.push_back(slicing_params.first_object_layer_height); layer_height_profile.push_back(slicing_params.first_object_layer_height); } double slice_z = slicing_params.first_object_layer_height; - double height = slicing_params.first_object_layer_height; int current_facet = 0; +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + while (slice_z <= slicing_params.object_print_z_height()) { + double height = 999.0; +#else + double height = slicing_params.first_object_layer_height; while ((slice_z - height) <= slicing_params.object_print_z_height()) { height = 999.0; +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // Slic3r::debugf "\n Slice layer: %d\n", $id; // determine next layer height double cusp_height = as.cusp_height((float)slice_z, cusp_value, current_facet); @@ -317,15 +322,26 @@ std::vector layer_height_profile_adaptive( layer_height_profile.push_back(slice_z); layer_height_profile.push_back(height); slice_z += height; +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE layer_height_profile.push_back(slice_z); layer_height_profile.push_back(height); +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE } +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + double z_gap = slicing_params.object_print_z_height() - layer_height_profile[layer_height_profile.size() - 2]; + if (z_gap > 0.0) + { + layer_height_profile.push_back(slicing_params.object_print_z_height()); + layer_height_profile.push_back(clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, z_gap)); + } +#else double last = std::max(slicing_params.first_object_layer_height, layer_height_profile[layer_height_profile.size() - 2]); layer_height_profile.push_back(last); layer_height_profile.push_back(slicing_params.first_object_layer_height); layer_height_profile.push_back(slicing_params.object_print_z_height()); layer_height_profile.push_back(slicing_params.first_object_layer_height); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE return layer_height_profile; } @@ -333,7 +349,7 @@ std::vector layer_height_profile_adaptive( std::vector smooth_height_profile(const std::vector& profile, const SlicingParameters& slicing_params, unsigned int radius) { - auto gauss_blur = [] (const std::vector& profile, unsigned int radius) -> std::vector { + auto gauss_blur = [&slicing_params](const std::vector& profile, unsigned int radius) -> std::vector { auto gauss_kernel = [] (unsigned int radius) -> std::vector { unsigned int size = 2 * radius + 1; std::vector ret; @@ -353,48 +369,55 @@ std::vector smooth_height_profile(const std::vector& profile, co return ret; }; + // skip first layer ? + size_t skip_count = slicing_params.first_object_layer_height_fixed() ? 4 : 0; + + // not enough data to smmoth + if ((int)profile.size() - (int)skip_count < 6) + return profile; + + std::vector kernel = gauss_kernel(radius); + int two_radius = 2 * (int)radius; + std::vector ret; size_t size = profile.size(); ret.reserve(size); - std::vector kernel = gauss_kernel(radius); - for (size_t i = 0; i < size; ++i) + // leave first layer untouched + for (size_t i = 0; i < skip_count; ++i) { + ret.push_back(profile[i]); + } + + // smooth the rest of the profile + double max_dz = (double)radius * slicing_params.layer_height; + for (size_t i = skip_count; i < size; i += 2) + { + double z = profile[i]; + ret.push_back(z); ret.push_back(0.0); double& height = ret.back(); - int begin = (int)(i - radius); - int end = (int)(i + radius); - for (int j = begin; j <= end; ++j) + int begin = std::max((int)i - two_radius, (int)skip_count); + int end = std::min((int)i + two_radius, (int)size - 2); + double kernel_total = 0.0; + for (int j = begin; j <= end; j += 2) { - if ((0 <= j) && (j < size)) - height += kernel[j - begin] * profile[j]; + int kernel_id = radius + (j - (int)i) / 2; + double dz = std::abs(z - profile[j]); + if (dz * slicing_params.layer_height <= max_dz) + { + height += kernel[kernel_id] * profile[j + 1]; + kernel_total += kernel[kernel_id]; + } } + + height = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, (kernel_total != 0.0) ? height /= kernel_total : profile[i + 1]); } return ret; }; - std::vector ret = profile; - - std::vector heights; - size_t heights_size = ret.size() / 2; - heights.reserve(heights_size); - // extract heights from profile - for (size_t i = 0; i < heights_size; ++i) - { - heights.push_back(ret[i * 2 + 1]); - } - - // smooth heights - heights = gauss_blur(heights, std::max(radius, (unsigned int)1)); - - // put smoothed heights back into profile - for (size_t i = 0; i < heights_size; ++i) - { - ret[i * 2 + 1] = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, heights[i]); - } - - return ret; + return gauss_blur(profile, std::max(radius, (unsigned int)1)); } void adjust_layer_height_profile( diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5c5fce5c6..7827a9566 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -284,7 +284,6 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::SliderFloat("", &m_adaptive_cusp, 0.0f, (float)m_slicing_parameters->max_layer_height, "%.2f"); ImGui::Separator(); - imgui.disabled_begin(m_layer_height_profile.size() < 10); if (imgui.button(_(L("Smooth")))) wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, m_smooth_radius)); @@ -297,7 +296,6 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const int radius = (int)m_smooth_radius; if (ImGui::SliderInt("##1", &radius, 1, 10)) m_smooth_radius = (unsigned int)radius; - imgui.disabled_end(); ImGui::Separator(); if (imgui.button(_(L("Reset"))))