From 6e4060569a833a61c257166d7906ce028d02a06d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 7 Nov 2019 15:55:45 +0100 Subject: [PATCH 01/16] 1) Added new tech ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE 2) Imgui dialog replaces texture for reset button and tooltip when layer editing is active --- src/libslic3r/PrintObject.cpp | 9 ++- src/libslic3r/Technologies.hpp | 3 + src/slic3r/GUI/GLCanvas3D.cpp | 102 +++++++++++++++++++++++++++++++-- src/slic3r/GUI/GLCanvas3D.hpp | 27 ++++++++- src/slic3r/GUI/Plater.cpp | 3 + 5 files changed, 132 insertions(+), 12 deletions(-) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index c4ca46a8c..7819b8313 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1522,9 +1522,12 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c layer_height_profile.clear(); if (layer_height_profile.empty()) { - //layer_height_profile = layer_height_profile_adaptive(slicing_parameters, model_object.layer_config_ranges, model_object.volumes); - layer_height_profile = layer_height_profile_from_ranges(slicing_parameters, model_object.layer_config_ranges); - updated = true; +//#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +// layer_height_profile = layer_height_profile_adaptive(slicing_parameters, model_object.layer_config_ranges, model_object.volumes); +//#else + layer_height_profile = layer_height_profile_from_ranges(slicing_parameters, model_object.layer_config_ranges); +//#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + updated = true; } return updated; } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 5d0a7592c..f8db1b7b3 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -42,4 +42,7 @@ #define ENABLE_THUMBNAIL_GENERATOR_DEBUG (0 && ENABLE_THUMBNAIL_GENERATOR) #define ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE (1 && ENABLE_THUMBNAIL_GENERATOR) +// Enable adaptive layer height profile +#define ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE (1 && ENABLE_2_2_0_ALPHA1) + #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 99f61e51e..18ac3b10a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -150,7 +150,9 @@ GLCanvas3D::LayersEditing::~LayersEditing() } const float GLCanvas3D::LayersEditing::THICKNESS_BAR_WIDTH = 70.0f; +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE const float GLCanvas3D::LayersEditing::THICKNESS_RESET_BUTTON_HEIGHT = 22.0f; +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename) { @@ -217,13 +219,70 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const if (!m_enabled) return; +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + static const ImVec4 orange(0.757f, 0.404f, 0.216f, 1.0f); + + const Size& cnv_size = canvas.get_canvas_size(); + float canvas_w = (float)cnv_size.get_width(); + float canvas_h = (float)cnv_size.get_height(); + + + ImGuiWrapper& imgui = *wxGetApp().imgui(); + imgui.set_next_window_pos(canvas_w - THICKNESS_BAR_WIDTH, canvas_h, ImGuiCond_Always, 1.0f, 1.0f); + imgui.set_next_window_bg_alpha(0.5f); + + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + + imgui.begin(_(L("Layer height profile")), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); + + ImGui::PushStyleColor(ImGuiCol_Text, orange); + imgui.text(_(L("Left mouse button:"))); + ImGui::PopStyleColor(); + ImGui::SameLine(); + imgui.text(_(L("Add detail"))); + + ImGui::PushStyleColor(ImGuiCol_Text, orange); + imgui.text(_(L("Right mouse button:"))); + ImGui::PopStyleColor(); + ImGui::SameLine(); + imgui.text(_(L("Remove detail"))); + + ImGui::PushStyleColor(ImGuiCol_Text, orange); + imgui.text(_(L("Shift + Left mouse button:"))); + ImGui::PopStyleColor(); + ImGui::SameLine(); + imgui.text(_(L("Reset to base"))); + + ImGui::PushStyleColor(ImGuiCol_Text, orange); + imgui.text(_(L("Shift + Right mouse button:"))); + ImGui::PopStyleColor(); + ImGui::SameLine(); + imgui.text(_(L("Smoothing"))); + + ImGui::PushStyleColor(ImGuiCol_Text, orange); + imgui.text(_(L("Mouse wheel:"))); + ImGui::PopStyleColor(); + ImGui::SameLine(); + imgui.text(_(L("Increase/decrease edit area"))); + + ImGui::Separator(); + if (imgui.button(_(L("Reset")))) + wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); + + imgui.end(); + + ImGui::PopStyleVar(); + + const Rect& bar_rect = get_bar_rect_viewport(canvas); +#else const Rect& bar_rect = get_bar_rect_viewport(canvas); const Rect& reset_rect = get_reset_rect_viewport(canvas); _render_tooltip_texture(canvas, bar_rect, reset_rect); _render_reset_texture(reset_rect); - _render_active_object_annotations(canvas, bar_rect); - _render_profile(bar_rect); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + render_active_object_annotations(canvas, bar_rect); + render_profile(bar_rect); } float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas) @@ -248,11 +307,13 @@ bool GLCanvas3D::LayersEditing::bar_rect_contains(const GLCanvas3D& canvas, floa return (rect.get_left() <= x) && (x <= rect.get_right()) && (rect.get_top() <= y) && (y <= rect.get_bottom()); } +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool GLCanvas3D::LayersEditing::reset_rect_contains(const GLCanvas3D& canvas, float x, float y) { const Rect& rect = get_reset_rect_screen(canvas); return (rect.get_left() <= x) && (x <= rect.get_right()) && (rect.get_top() <= y) && (y <= rect.get_bottom()); } +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas) { @@ -260,9 +321,14 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas) float w = (float)cnv_size.get_width(); float h = (float)cnv_size.get_height(); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + return Rect(w - thickness_bar_width(canvas), 0.0f, w, h); +#else return Rect(w - thickness_bar_width(canvas), 0.0f, w, h - reset_button_height(canvas)); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE } +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE Rect GLCanvas3D::LayersEditing::get_reset_rect_screen(const GLCanvas3D& canvas) { const Size& cnv_size = canvas.get_canvas_size(); @@ -271,6 +337,7 @@ Rect GLCanvas3D::LayersEditing::get_reset_rect_screen(const GLCanvas3D& canvas) return Rect(w - thickness_bar_width(canvas), h - reset_button_height(canvas), w, h); } +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) { @@ -281,9 +348,14 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) float zoom = (float)canvas.get_camera().get_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); +#else return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE } +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas) { const Size& cnv_size = canvas.get_canvas_size(); @@ -295,13 +367,14 @@ Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); } +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - -bool GLCanvas3D::LayersEditing::_is_initialized() const +bool GLCanvas3D::LayersEditing::is_initialized() const { return m_shader.is_initialized(); } +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const { // TODO: do this with ImGui @@ -347,8 +420,9 @@ void GLCanvas3D::LayersEditing::_render_reset_texture(const Rect& reset_rect) co GLTexture::render_texture(m_reset_texture.get_id(), reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top()); } +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const +void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const { m_shader.start_using(); @@ -379,7 +453,7 @@ void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas m_shader.stop_using(); } -void GLCanvas3D::LayersEditing::_render_profile(const Rect& bar_rect) const +void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) const { //FIXME show some kind of legend. @@ -557,6 +631,7 @@ float GLCanvas3D::LayersEditing::thickness_bar_width(const GLCanvas3D &canvas) * THICKNESS_BAR_WIDTH; } +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE float GLCanvas3D::LayersEditing::reset_button_height(const GLCanvas3D &canvas) { return @@ -567,6 +642,7 @@ float GLCanvas3D::LayersEditing::reset_button_height(const GLCanvas3D &canvas) #endif * THICKNESS_RESET_BUTTON_HEIGHT; } +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE const Point GLCanvas3D::Mouse::Drag::Invalid_2D_Point(INT_MAX, INT_MAX); @@ -1118,6 +1194,9 @@ wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent); wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #if ENABLE_THUMBNAIL_GENERATOR const double GLCanvas3D::DefaultCameraZoomToBoxMarginFactor = 1.25; @@ -1420,6 +1499,15 @@ bool GLCanvas3D::is_layers_editing_allowed() const return m_layers_editing.is_allowed(); } +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +void GLCanvas3D::reset_layer_height_profile() +{ + m_layers_editing.reset_layer_height_profile(*this); + m_layers_editing.state = LayersEditing::Completed; + m_dirty = true; +} +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + bool GLCanvas3D::is_reload_delayed() const { return m_reload_delayed; @@ -2814,6 +2902,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_layers_editing.state = LayersEditing::Editing; _perform_layer_editing_action(&evt); } +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE else if ((layer_editing_object_idx != -1) && m_layers_editing.reset_rect_contains(*this, pos(0), pos(1))) { if (evt.LeftDown()) @@ -2826,6 +2915,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } } +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE else if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) { if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 8c2e6e9a5..da55210a8 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -104,6 +104,9 @@ wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent); wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class GLCanvas3D { @@ -153,13 +156,17 @@ private: private: static const float THICKNESS_BAR_WIDTH; +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static const float THICKNESS_RESET_BUTTON_HEIGHT; +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool m_enabled; Shader m_shader; unsigned int m_z_texture_id; +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE mutable GLTexture m_tooltip_texture; mutable GLTexture m_reset_texture; +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // Not owned by LayersEditing. const DynamicPrintConfig *m_config; // ModelObject for the currently selected object (Model::objects[last_object_id]). @@ -220,25 +227,35 @@ private: static float get_cursor_z_relative(const GLCanvas3D& canvas); static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y); +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static bool reset_rect_contains(const GLCanvas3D& canvas, float x, float y); +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static Rect get_bar_rect_screen(const GLCanvas3D& canvas); +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static Rect get_reset_rect_screen(const GLCanvas3D& canvas); +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static Rect get_bar_rect_viewport(const GLCanvas3D& canvas); +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static Rect get_reset_rect_viewport(const GLCanvas3D& canvas); +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE float object_max_z() const { return m_object_max_z; } private: - bool _is_initialized() const; + bool is_initialized() const; void generate_layer_height_texture(); +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void _render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const; void _render_reset_texture(const Rect& reset_rect) const; - void _render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const; - void _render_profile(const Rect& bar_rect) const; +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const; + void render_profile(const Rect& bar_rect) const; void update_slicing_parameters(); static float thickness_bar_width(const GLCanvas3D &canvas); +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static float reset_button_height(const GLCanvas3D &canvas); +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE }; struct Mouse @@ -500,6 +517,10 @@ public: bool is_layers_editing_enabled() const; bool is_layers_editing_allowed() const; +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void reset_layer_height_profile(); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + bool is_reload_delayed() const; void enable_layers_editing(bool enable); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cdd35b720..44de82861 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2070,6 +2070,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); }); view3D_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); }); view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); }); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 3DScene/Toolbar: view3D_canvas->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this); From b77ba32bb2171ae55254d5ac50f08d7f11911192 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 12 Nov 2019 14:18:43 +0100 Subject: [PATCH 02/16] Adaptive layer height profile -> Added Adaptive button to imgui dialog --- src/libslic3r/PrintObject.cpp | 5 +---- src/libslic3r/Slicing.cpp | 6 +++++- src/slic3r/GUI/GLCanvas3D.cpp | 22 ++++++++++++++++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 5 +++++ src/slic3r/GUI/Plater.cpp | 1 + 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 7819b8313..bf97baaf6 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1522,11 +1522,8 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c layer_height_profile.clear(); if (layer_height_profile.empty()) { -//#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -// layer_height_profile = layer_height_profile_adaptive(slicing_parameters, model_object.layer_config_ranges, model_object.volumes); -//#else + //layer_height_profile = layer_height_profile_adaptive(slicing_parameters, model_object.layer_config_ranges, model_object.volumes); layer_height_profile = layer_height_profile_from_ranges(slicing_parameters, model_object.layer_config_ranges); -//#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE updated = true; } return updated; diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index c62736ffe..1c1a1159f 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -609,7 +609,11 @@ int generate_layer_height_texture( const Vec3crd &color1 = palette_raw[idx1]; const Vec3crd &color2 = palette_raw[idx2]; coordf_t z = cell_to_z * coordf_t(cell); - assert(z >= lo && z <= hi); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + assert((lo - EPSILON <= z) && (z <= hi + EPSILON)); +#else + assert(z >= lo && z <= hi); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // Intensity profile to visualize the layers. coordf_t intensity = cos(M_PI * 0.7 * (mid - z) / h); // Color mapping from layer height to RGB. diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index fb01726b0..7b1dfb89a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -269,6 +269,10 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const if (imgui.button(_(L("Reset")))) wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); + ImGui::SameLine(); + if (imgui.button(_(L("Adaptive")))) + wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE)); + imgui.end(); ImGui::PopStyleVar(); @@ -570,6 +574,16 @@ void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas) canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas) +{ + const_cast(m_model_object)->layer_height_profile.clear(); + m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, m_model_object->layer_config_ranges, m_model_object->volumes); + m_layers_texture.valid = false; + canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); +} +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void GLCanvas3D::LayersEditing::generate_layer_height_texture() { this->update_slicing_parameters(); @@ -1196,6 +1210,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); +wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, SimpleEvent); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #if ENABLE_THUMBNAIL_GENERATOR @@ -1506,6 +1521,13 @@ void GLCanvas3D::reset_layer_height_profile() m_layers_editing.state = LayersEditing::Completed; m_dirty = true; } + +void GLCanvas3D::adaptive_layer_height_profile() +{ + m_layers_editing.adaptive_layer_height_profile(*this); + m_layers_editing.state = LayersEditing::Completed; + m_dirty = true; +} #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool GLCanvas3D::is_reload_delayed() const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index da55210a8..d17174628 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -106,6 +106,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, SimpleEvent); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class GLCanvas3D @@ -224,6 +225,9 @@ private: void adjust_layer_height_profile(); void accept_changes(GLCanvas3D& canvas); void reset_layer_height_profile(GLCanvas3D& canvas); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void adaptive_layer_height_profile(GLCanvas3D& canvas); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static float get_cursor_z_relative(const GLCanvas3D& canvas); static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y); @@ -519,6 +523,7 @@ public: #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void reset_layer_height_profile(); + void adaptive_layer_height_profile(); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool is_reload_delayed() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 084d821ba..ac9c5cc4b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2091,6 +2091,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); }); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); + view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(); }); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 3DScene/Toolbar: From 0001ce3dab749d130fc2ead976aed3ba753d9b7f Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 13 Nov 2019 13:53:02 +0100 Subject: [PATCH 03/16] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Refactoring of SlicingAdaptive to account for volumes' transformation --- src/libslic3r/Slicing.cpp | 24 ++++++++--- src/libslic3r/Slicing.hpp | 11 +++++- src/libslic3r/SlicingAdaptive.cpp | 66 ++++++++++++++++++++----------- src/libslic3r/SlicingAdaptive.hpp | 32 +++++++++++---- src/slic3r/GUI/GLCanvas3D.cpp | 12 +++--- 5 files changed, 104 insertions(+), 41 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 1c1a1159f..a82bbc72a 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -224,24 +224,38 @@ std::vector layer_height_profile_from_ranges( // Based on the work of @platsch // Fill layer_height_profile by heights ensuring a prescribed maximum cusp height. +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +std::vector layer_height_profile_adaptive( + const SlicingParameters& slicing_params, + const ModelObject& object) +#else std::vector layer_height_profile_adaptive( const SlicingParameters &slicing_params, const t_layer_config_ranges & /* layer_config_ranges */, const ModelVolumePtrs &volumes) +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE { +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 1) Initialize the SlicingAdaptive class with the object meshes. SlicingAdaptive as; as.set_slicing_parameters(slicing_params); - for (const ModelVolume *volume : volumes) + as.set_object(object); +#else + // 1) Initialize the SlicingAdaptive class with the object meshes. + SlicingAdaptive as; + as.set_slicing_parameters(slicing_params); + for (const ModelVolume* volume : volumes) if (volume->is_model_part()) as.add_mesh(&volume->mesh()); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + as.prepare(); // 2) Generate layers using the algorithm of @platsch // loop until we have at least one layer and the max slice_z reaches the object height //FIXME make it configurable // Cusp value: A maximum allowed distance from a corner of a rectangular extrusion to a chrodal line, in mm. - const coordf_t cusp_value = 0.2; // $self->config->get_value('cusp_value'); + const double cusp_value = 0.2; // $self->config->get_value('cusp_value'); std::vector layer_height_profile; layer_height_profile.push_back(0.); @@ -250,14 +264,14 @@ std::vector layer_height_profile_adaptive( layer_height_profile.push_back(slicing_params.first_object_layer_height); layer_height_profile.push_back(slicing_params.first_object_layer_height); } - coordf_t slice_z = slicing_params.first_object_layer_height; - coordf_t height = 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; while ((slice_z - height) <= slicing_params.object_print_z_height()) { height = 999; // Slic3r::debugf "\n Slice layer: %d\n", $id; // determine next layer height - coordf_t cusp_height = as.cusp_height(slice_z, cusp_value, current_facet); + double cusp_height = as.cusp_height((float)slice_z, (float)cusp_value, current_facet); // check for horizontal features and object size /* if($self->config->get_value('match_horizontal_surfaces')) { diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index 064363ec2..250d7baeb 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -18,8 +18,12 @@ namespace Slic3r class PrintConfig; class PrintObjectConfig; +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +class ModelObject; +#else class ModelVolume; typedef std::vector ModelVolumePtrs; +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // Parameters to guide object slicing and support generation. // The slicing parameters account for a raft and whether the 1st object layer is printed with a normal or a bridging flow @@ -138,11 +142,16 @@ extern std::vector layer_height_profile_from_ranges( const SlicingParameters &slicing_params, const t_layer_config_ranges &layer_config_ranges); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +extern std::vector layer_height_profile_adaptive( + const SlicingParameters& slicing_params, + const ModelObject& object); +#else extern std::vector layer_height_profile_adaptive( const SlicingParameters &slicing_params, const t_layer_config_ranges &layer_config_ranges, const ModelVolumePtrs &volumes); - +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE enum LayerHeightEditActionType : unsigned int { LAYER_HEIGHT_EDIT_ACTION_INCREASE = 0, diff --git a/src/libslic3r/SlicingAdaptive.cpp b/src/libslic3r/SlicingAdaptive.cpp index ad03b550b..a38752fbc 100644 --- a/src/libslic3r/SlicingAdaptive.cpp +++ b/src/libslic3r/SlicingAdaptive.cpp @@ -1,16 +1,22 @@ #include "libslic3r.h" +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +#include "Model.hpp" +#else #include "TriangleMesh.hpp" +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #include "SlicingAdaptive.hpp" namespace Slic3r { +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void SlicingAdaptive::clear() { - m_meshes.clear(); + m_meshes.clear(); m_faces.clear(); m_face_normal_z.clear(); } +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE std::pair face_z_span(const stl_facet *f) { @@ -21,21 +27,38 @@ std::pair face_z_span(const stl_facet *f) void SlicingAdaptive::prepare() { - // 1) Collect faces of all meshes. - int nfaces_total = 0; - for (std::vector::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + if (m_object == nullptr) + return; + + m_faces.clear(); + m_face_normal_z.clear(); + + m_mesh = m_object->raw_mesh(); + const ModelInstance* first_instance = m_object->instances.front(); + m_mesh.transform(first_instance->get_matrix(), first_instance->is_left_handed()); + + // 1) Collect faces from mesh. + m_faces.reserve(m_mesh.stl.stats.number_of_facets); + for (const stl_facet& face : m_mesh.stl.facet_start) + m_faces.emplace_back(&face); +#else + // 1) Collect faces of all meshes. + int nfaces_total = 0; + for (std::vector::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) nfaces_total += (*it_mesh)->stl.stats.number_of_facets; - m_faces.reserve(nfaces_total); - for (std::vector::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) - for (const stl_facet &face : (*it_mesh)->stl.facet_start) - m_faces.emplace_back(&face); + m_faces.reserve(nfaces_total); + for (std::vector::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) + for (const stl_facet& face : (*it_mesh)->stl.facet_start) + m_faces.emplace_back(&face); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 2) Sort faces lexicographically by their Z span. std::sort(m_faces.begin(), m_faces.end(), [](const stl_facet *f1, const stl_facet *f2) { - std::pair span1 = face_z_span(f1); + std::pair span1 = face_z_span(f1); std::pair span2 = face_z_span(f2); - return span1 < span2; - }); + return span1 < span2; + }); // 3) Generate Z components of the facet normals. m_face_normal_z.assign(m_faces.size(), 0.f); @@ -45,14 +68,14 @@ void SlicingAdaptive::prepare() float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet) { - float height = m_slicing_params.max_layer_height; + float height = (float)m_slicing_params.max_layer_height; bool first_hit = false; // find all facets intersecting the slice-layer int ordered_id = current_facet; for (; ordered_id < int(m_faces.size()); ++ ordered_id) { - std::pair zspan = face_z_span(m_faces[ordered_id]); - // facet's minimum is higher than slice_z -> end loop + std::pair zspan = face_z_span(m_faces[ordered_id]); + // facet's minimum is higher than slice_z -> end loop if (zspan.first >= z) break; // facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point @@ -77,8 +100,8 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet // check for sloped facets inside the determined layer and correct height if necessary if (height > m_slicing_params.min_layer_height) { for (; ordered_id < int(m_faces.size()); ++ ordered_id) { - std::pair zspan = face_z_span(m_faces[ordered_id]); - // facet's minimum is higher than slice_z + height -> end loop + std::pair zspan = face_z_span(m_faces[ordered_id]); + // facet's minimum is higher than slice_z + height -> end loop if (zspan.first >= z + height) break; @@ -122,19 +145,18 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet float SlicingAdaptive::horizontal_facet_distance(float z) { for (size_t i = 0; i < m_faces.size(); ++ i) { - std::pair zspan = face_z_span(m_faces[i]); - // facet's minimum is higher than max forward distance -> end loop + std::pair zspan = face_z_span(m_faces[i]); + // facet's minimum is higher than max forward distance -> end loop if (zspan.first > z + m_slicing_params.max_layer_height) break; // min_z == max_z -> horizontal facet - if (zspan.first > z && zspan.first == zspan.second) + if ((zspan.first > z) && (zspan.first == zspan.second)) return zspan.first - z; } // objects maximum? - return (z + m_slicing_params.max_layer_height > m_slicing_params.object_print_z_height()) ? - std::max(m_slicing_params.object_print_z_height() - z, 0.f) : - m_slicing_params.max_layer_height; + return (z + (float)m_slicing_params.max_layer_height > (float)m_slicing_params.object_print_z_height()) ? + std::max((float)m_slicing_params.object_print_z_height() - z, 0.f) : (float)m_slicing_params.max_layer_height; } }; // namespace Slic3r diff --git a/src/libslic3r/SlicingAdaptive.hpp b/src/libslic3r/SlicingAdaptive.hpp index bfd081d81..eccb298d0 100644 --- a/src/libslic3r/SlicingAdaptive.hpp +++ b/src/libslic3r/SlicingAdaptive.hpp @@ -5,29 +5,47 @@ #include "Slicing.hpp" #include "admesh/stl.h" +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +#include "TriangleMesh.hpp" +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE namespace Slic3r { +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +class ModelVolume; +#else class TriangleMesh; +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class SlicingAdaptive { public: - void clear(); - void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; } - void add_mesh(const TriangleMesh *mesh) { m_meshes.push_back(mesh); } - void prepare(); +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void clear(); +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; } +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void set_object(const ModelObject& object) { m_object = &object; } +#else + void add_mesh(const TriangleMesh* mesh) { m_meshes.push_back(mesh); } +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void prepare(); float cusp_height(float z, float cusp_value, int ¤t_facet); float horizontal_facet_distance(float z); protected: SlicingParameters m_slicing_params; - std::vector m_meshes; - // Collected faces of all meshes, sorted by raising Z of the bottom most face. +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + const ModelObject* m_object; + TriangleMesh m_mesh; +#else + std::vector m_meshes; +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + // Collected faces of all meshes, sorted by raising Z of the bottom most face. std::vector m_faces; - // Z component of face normals, normalized. + // Z component of face normals, normalized. std::vector m_face_normal_z; }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7b1dfb89a..9647d252a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -266,13 +266,13 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const imgui.text(_(L("Increase/decrease edit area"))); ImGui::Separator(); - if (imgui.button(_(L("Reset")))) - wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); - - ImGui::SameLine(); if (imgui.button(_(L("Adaptive")))) wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE)); + ImGui::SameLine(); + if (imgui.button(_(L("Reset")))) + wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); + imgui.end(); ImGui::PopStyleVar(); @@ -577,8 +577,8 @@ void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas) #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas) { - const_cast(m_model_object)->layer_height_profile.clear(); - m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, m_model_object->layer_config_ranges, m_model_object->volumes); + m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, *m_model_object); + const_cast(m_model_object)->layer_height_profile = m_layer_height_profile; m_layers_texture.valid = false; canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } From 6eee31bf5a28264a48982eb32bfd428e7469af3d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 13 Nov 2019 15:06:17 +0100 Subject: [PATCH 04/16] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Disabled unused code --- src/libslic3r/SlicingAdaptive.cpp | 2 ++ src/libslic3r/SlicingAdaptive.hpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/SlicingAdaptive.cpp b/src/libslic3r/SlicingAdaptive.cpp index a38752fbc..e64012553 100644 --- a/src/libslic3r/SlicingAdaptive.cpp +++ b/src/libslic3r/SlicingAdaptive.cpp @@ -140,6 +140,7 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet return height; } +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // Returns the distance to the next horizontal facet in Z-dir // to consider horizontal object features in slice thickness float SlicingAdaptive::horizontal_facet_distance(float z) @@ -158,5 +159,6 @@ float SlicingAdaptive::horizontal_facet_distance(float z) return (z + (float)m_slicing_params.max_layer_height > (float)m_slicing_params.object_print_z_height()) ? std::max((float)m_slicing_params.object_print_z_height() - z, 0.f) : (float)m_slicing_params.max_layer_height; } +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE }; // namespace Slic3r diff --git a/src/libslic3r/SlicingAdaptive.hpp b/src/libslic3r/SlicingAdaptive.hpp index eccb298d0..1d2996986 100644 --- a/src/libslic3r/SlicingAdaptive.hpp +++ b/src/libslic3r/SlicingAdaptive.hpp @@ -32,7 +32,9 @@ public: #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void prepare(); float cusp_height(float z, float cusp_value, int ¤t_facet); - float horizontal_facet_distance(float z); +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + float horizontal_facet_distance(float z); +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE protected: SlicingParameters m_slicing_params; From 5baffdb9c20f55d5bc95b48a5e6355258a080ce9 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 14 Nov 2019 10:22:48 +0100 Subject: [PATCH 05/16] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Customizable cusp value --- src/libslic3r/Slicing.cpp | 13 +++++-------- src/libslic3r/Slicing.hpp | 4 ++-- src/slic3r/GUI/GLCanvas3D.cpp | 20 ++++++++++++++------ src/slic3r/GUI/GLCanvas3D.hpp | 8 +++++--- src/slic3r/GUI/Plater.cpp | 2 +- 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index a82bbc72a..b7816fd04 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -225,9 +225,8 @@ std::vector layer_height_profile_from_ranges( // Based on the work of @platsch // Fill layer_height_profile by heights ensuring a prescribed maximum cusp height. #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -std::vector layer_height_profile_adaptive( - const SlicingParameters& slicing_params, - const ModelObject& object) +std::vector layer_height_profile_adaptive(const SlicingParameters& slicing_params, + const ModelObject& object, float cusp_value) #else std::vector layer_height_profile_adaptive( const SlicingParameters &slicing_params, @@ -253,11 +252,8 @@ std::vector layer_height_profile_adaptive( // 2) Generate layers using the algorithm of @platsch // loop until we have at least one layer and the max slice_z reaches the object height - //FIXME make it configurable - // Cusp value: A maximum allowed distance from a corner of a rectangular extrusion to a chrodal line, in mm. - const double cusp_value = 0.2; // $self->config->get_value('cusp_value'); - std::vector layer_height_profile; + std::vector layer_height_profile; layer_height_profile.push_back(0.); layer_height_profile.push_back(slicing_params.first_object_layer_height); if (slicing_params.first_object_layer_height_fixed()) { @@ -271,7 +267,8 @@ std::vector layer_height_profile_adaptive( height = 999; // Slic3r::debugf "\n Slice layer: %d\n", $id; // determine next layer height - double cusp_height = as.cusp_height((float)slice_z, (float)cusp_value, current_facet); + double cusp_height = as.cusp_height((float)slice_z, cusp_value, current_facet); + // check for horizontal features and object size /* if($self->config->get_value('match_horizontal_surfaces')) { diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index 250d7baeb..e25cbd326 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -143,9 +143,9 @@ extern std::vector layer_height_profile_from_ranges( const t_layer_config_ranges &layer_config_ranges); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -extern std::vector layer_height_profile_adaptive( +extern std::vector layer_height_profile_adaptive( const SlicingParameters& slicing_params, - const ModelObject& object); + const ModelObject& object, float cusp_value); #else extern std::vector layer_height_profile_adaptive( const SlicingParameters &slicing_params, diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9647d252a..8ef0eaa13 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -130,6 +130,7 @@ GLCanvas3D::LayersEditing::LayersEditing() , m_object_max_z(0.f) , m_slicing_parameters(nullptr) , m_layer_height_profile_modified(false) + , m_adaptive_cusp(0.2f) , state(Unknown) , band_width(2.0f) , strength(0.005f) @@ -267,9 +268,16 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::Separator(); if (imgui.button(_(L("Adaptive")))) - wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE)); + wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, m_adaptive_cusp)); ImGui::SameLine(); + imgui.text(_(L("Cusp (mm)"))); + ImGui::SameLine(); + ImGui::PushItemWidth(100.0f); + m_adaptive_cusp = std::min(m_adaptive_cusp, (float)m_slicing_parameters->max_layer_height); + ImGui::SliderFloat("", &m_adaptive_cusp, 0.0f, (float)m_slicing_parameters->max_layer_height, "%.2f"); + + ImGui::Separator(); if (imgui.button(_(L("Reset")))) wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); @@ -575,9 +583,9 @@ void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas) } #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas) +void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp) { - m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, *m_model_object); + m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, *m_model_object, cusp); const_cast(m_model_object)->layer_height_profile = m_layer_height_profile; m_layers_texture.valid = false; canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); @@ -1210,7 +1218,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); -wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, SimpleEvent); +wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #if ENABLE_THUMBNAIL_GENERATOR @@ -1522,9 +1530,9 @@ void GLCanvas3D::reset_layer_height_profile() m_dirty = true; } -void GLCanvas3D::adaptive_layer_height_profile() +void GLCanvas3D::adaptive_layer_height_profile(float cusp) { - m_layers_editing.adaptive_layer_height_profile(*this); + m_layers_editing.adaptive_layer_height_profile(*this, cusp); m_layers_editing.state = LayersEditing::Completed; m_dirty = true; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d17174628..d1369d086 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -106,7 +106,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); -wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, SimpleEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class GLCanvas3D @@ -179,6 +179,8 @@ private: std::vector m_layer_height_profile; bool m_layer_height_profile_modified; + mutable float m_adaptive_cusp; + class LayersTexture { public: @@ -226,7 +228,7 @@ private: void accept_changes(GLCanvas3D& canvas); void reset_layer_height_profile(GLCanvas3D& canvas); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void adaptive_layer_height_profile(GLCanvas3D& canvas); + void adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static float get_cursor_z_relative(const GLCanvas3D& canvas); @@ -523,7 +525,7 @@ public: #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void reset_layer_height_profile(); - void adaptive_layer_height_profile(); + void adaptive_layer_height_profile(float cusp); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool is_reload_delayed() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ac9c5cc4b..e2b15602c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2091,7 +2091,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); }); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); - view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(); }); + view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); }); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 3DScene/Toolbar: From f548a4d7d6fe328cf16f8b901758d60b8d94c2e3 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 15 Nov 2019 15:49:07 +0100 Subject: [PATCH 06/16] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Profile smoothing using gaussian blur --- src/libslic3r/Slicing.cpp | 74 +++++++++++++++++++++++++++++++++- src/libslic3r/Slicing.hpp | 5 +++ src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GLCanvas3D.cpp | 52 +++++++++++++++++++++++- src/slic3r/GUI/GLCanvas3D.hpp | 14 +++++++ src/slic3r/GUI/Plater.cpp | 3 ++ 6 files changed, 145 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index b7816fd04..0d3b3af38 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -252,6 +252,9 @@ std::vector layer_height_profile_adaptive( // 2) Generate layers using the algorithm of @platsch // loop until we have at least one layer and the max slice_z reaches the object height +#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + double cusp_value = 0.2; +#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE std::vector layer_height_profile; layer_height_profile.push_back(0.); @@ -264,7 +267,7 @@ std::vector layer_height_profile_adaptive( double height = slicing_params.first_object_layer_height; int current_facet = 0; while ((slice_z - height) <= slicing_params.object_print_z_height()) { - height = 999; + height = 999.0; // 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); @@ -318,7 +321,7 @@ std::vector layer_height_profile_adaptive( layer_height_profile.push_back(height); } - coordf_t last = std::max(slicing_params.first_object_layer_height, layer_height_profile[layer_height_profile.size() - 2]); + 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()); @@ -327,6 +330,73 @@ std::vector layer_height_profile_adaptive( return layer_height_profile; } +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING +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_kernel = [] (unsigned int radius) -> std::vector { + unsigned int size = 2 * radius + 1; + std::vector ret; + ret.reserve(size); + + // Reworked from static inline int getGaussianKernelSize(float sigma) taken from opencv-4.1.2\modules\features2d\src\kaze\AKAZEFeatures.cpp + double sigma = 0.3 * (double)(radius - 1) + 0.8; + double two_sq_sigma = 2.0 * sigma * sigma; + double inv_root_two_pi_sq_sigma = 1.0 / ::sqrt(M_PI * two_sq_sigma); + + for (unsigned int i = 0; i < size; ++i) + { + double x = (double)i - (double)radius; + ret.push_back(inv_root_two_pi_sq_sigma * ::exp(-x * x / two_sq_sigma)); + } + + return ret; + }; + + 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) + { + unsigned int id = 0; + double value = 0.0; + for (int j = (int)(i - radius); j <= (int)(i + radius); ++j) + { + if ((0 <= j) && (j < size)) + value += kernel[id] * profile[j]; + + ++id; + } + ret.push_back(value); + } + + return ret; + }; + + std::vector ret = profile; + + std::vector heights; + size_t heights_size = ret.size() / 2; + heights.reserve(heights_size); + for (size_t i = 0; i < heights_size; ++i) + { + heights.push_back(ret[i * 2 + 1]); + } + + heights = gauss_blur(heights, std::max(radius, (unsigned int)1)); + + 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; +} +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + void adjust_layer_height_profile( const SlicingParameters &slicing_params, std::vector &layer_height_profile, diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index e25cbd326..545857216 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -146,6 +146,11 @@ extern std::vector layer_height_profile_from_ranges( extern std::vector layer_height_profile_adaptive( const SlicingParameters& slicing_params, const ModelObject& object, float cusp_value); + +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING +extern std::vector smooth_height_profile(const std::vector& profile, const SlicingParameters& slicing_params, + unsigned int radius); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #else extern std::vector layer_height_profile_adaptive( const SlicingParameters &slicing_params, diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index f8db1b7b3..465f5dd33 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -44,5 +44,6 @@ // Enable adaptive layer height profile #define ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE (1 && ENABLE_2_2_0_ALPHA1) +#define ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING (1 && ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8ef0eaa13..d0cd1fbeb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -130,7 +130,12 @@ GLCanvas3D::LayersEditing::LayersEditing() , m_object_max_z(0.f) , m_slicing_parameters(nullptr) , m_layer_height_profile_modified(false) +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE , m_adaptive_cusp(0.2f) +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + , m_smooth_radius(5) +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE , state(Unknown) , band_width(2.0f) , strength(0.005f) @@ -227,9 +232,10 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const float canvas_w = (float)cnv_size.get_width(); float canvas_h = (float)cnv_size.get_height(); + const float scale_gl = wxGetApp().mainframe->scale_factor(); ImGuiWrapper& imgui = *wxGetApp().imgui(); - imgui.set_next_window_pos(canvas_w - THICKNESS_BAR_WIDTH, canvas_h, ImGuiCond_Always, 1.0f, 1.0f); + imgui.set_next_window_pos(canvas_w - scale_gl * THICKNESS_BAR_WIDTH, canvas_h, ImGuiCond_Always, 1.0f, 1.0f); imgui.set_next_window_bg_alpha(0.5f); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); @@ -271,12 +277,30 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, m_adaptive_cusp)); ImGui::SameLine(); + float text_align = ImGui::GetCursorPosX(); imgui.text(_(L("Cusp (mm)"))); ImGui::SameLine(); - ImGui::PushItemWidth(100.0f); + float widget_align = ImGui::GetCursorPosX(); + ImGui::PushItemWidth(120.0f); m_adaptive_cusp = std::min(m_adaptive_cusp, (float)m_slicing_parameters->max_layer_height); ImGui::SliderFloat("", &m_adaptive_cusp, 0.0f, (float)m_slicing_parameters->max_layer_height, "%.2f"); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + ImGui::Separator(); + if (imgui.button(_(L("Smooth")))) + wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, m_smooth_radius)); + + ImGui::SameLine(); + ImGui::SetCursorPosX(text_align); + imgui.text(_(L("Radius"))); + ImGui::SameLine(); + ImGui::PushItemWidth(120.0f); + ImGui::SetCursorPosX(widget_align); + int radius = (int)m_smooth_radius; + if (ImGui::SliderInt("##1", &radius, 1, 10)) + m_smooth_radius = (unsigned int)radius; +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + ImGui::Separator(); if (imgui.button(_(L("Reset")))) wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); @@ -590,6 +614,17 @@ void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas m_layers_texture.valid = false; canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } + +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING +void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, unsigned int radius) +{ + m_layer_height_profile = smooth_height_profile(m_layer_height_profile, *m_slicing_parameters, radius); + const_cast(m_model_object)->layer_height_profile = m_layer_height_profile; + m_layers_texture.valid = false; + canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); +} +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void GLCanvas3D::LayersEditing::generate_layer_height_texture() @@ -1219,6 +1254,9 @@ wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING +wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, Event); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #if ENABLE_THUMBNAIL_GENERATOR @@ -1536,6 +1574,16 @@ void GLCanvas3D::adaptive_layer_height_profile(float cusp) m_layers_editing.state = LayersEditing::Completed; m_dirty = true; } + +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING +void GLCanvas3D::smooth_layer_height_profile(unsigned int radius) +{ + m_layers_editing.smooth_layer_height_profile(*this, radius); + m_layers_editing.state = LayersEditing::Completed; + m_dirty = true; +} +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool GLCanvas3D::is_reload_delayed() const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d1369d086..d57a5c8d6 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -107,6 +107,9 @@ wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING +wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, Event); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class GLCanvas3D @@ -179,7 +182,12 @@ private: std::vector m_layer_height_profile; bool m_layer_height_profile_modified; +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE mutable float m_adaptive_cusp; +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + mutable unsigned int m_smooth_radius; +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class LayersTexture { @@ -229,6 +237,9 @@ private: void reset_layer_height_profile(GLCanvas3D& canvas); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + void smooth_layer_height_profile(GLCanvas3D& canvas, unsigned int radius); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static float get_cursor_z_relative(const GLCanvas3D& canvas); @@ -526,6 +537,9 @@ public: #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void reset_layer_height_profile(); void adaptive_layer_height_profile(float cusp); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + void smooth_layer_height_profile(unsigned int radius); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool is_reload_delayed() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e2b15602c..3c93486d8 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2092,6 +2092,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); }); +#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING + view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](Event& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); }); +#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 3DScene/Toolbar: From 68a9980a5e7fb25a411c5b4deed2c09c4c6bd4c8 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 18 Nov 2019 10:17:44 +0100 Subject: [PATCH 07/16] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Small refactoring to improve performances --- src/libslic3r/Slicing.cpp | 16 +++++++++------- src/slic3r/GUI/GLCanvas3D.cpp | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 0d3b3af38..9fb2e00f4 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -361,16 +361,15 @@ std::vector smooth_height_profile(const std::vector& profile, co for (size_t i = 0; i < size; ++i) { - unsigned int id = 0; - double value = 0.0; - for (int j = (int)(i - radius); j <= (int)(i + radius); ++j) + 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) { if ((0 <= j) && (j < size)) - value += kernel[id] * profile[j]; - - ++id; + height += kernel[j - begin] * profile[j]; } - ret.push_back(value); } return ret; @@ -381,13 +380,16 @@ std::vector smooth_height_profile(const std::vector& profile, co 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]); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d0cd1fbeb..d9746bd05 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -287,6 +287,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING 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)); @@ -299,6 +300,7 @@ 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(); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING ImGui::Separator(); From 28dedd65f0bd2149f8af9c3280be9b2fb2f54ac4 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 18 Nov 2019 10:25:23 +0100 Subject: [PATCH 08/16] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Code cleanup --- src/libslic3r/Slicing.cpp | 2 -- src/libslic3r/Slicing.hpp | 6 +++--- src/libslic3r/Technologies.hpp | 1 - src/slic3r/GUI/GLCanvas3D.cpp | 12 ------------ src/slic3r/GUI/GLCanvas3D.hpp | 8 -------- src/slic3r/GUI/Plater.cpp | 2 -- 6 files changed, 3 insertions(+), 28 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 9fb2e00f4..42e721744 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -330,7 +330,6 @@ std::vector layer_height_profile_adaptive( return layer_height_profile; } -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING std::vector smooth_height_profile(const std::vector& profile, const SlicingParameters& slicing_params, unsigned int radius) { @@ -397,7 +396,6 @@ std::vector smooth_height_profile(const std::vector& profile, co return ret; } -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING void adjust_layer_height_profile( const SlicingParameters &slicing_params, diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index 545857216..8dc0b47e9 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -147,10 +147,10 @@ extern std::vector layer_height_profile_adaptive( const SlicingParameters& slicing_params, const ModelObject& object, float cusp_value); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING -extern std::vector smooth_height_profile(const std::vector& profile, const SlicingParameters& slicing_params, +extern std::vector smooth_height_profile( + const std::vector& profile, + const SlicingParameters& slicing_params, unsigned int radius); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #else extern std::vector layer_height_profile_adaptive( const SlicingParameters &slicing_params, diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 465f5dd33..f8db1b7b3 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -44,6 +44,5 @@ // Enable adaptive layer height profile #define ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE (1 && ENABLE_2_2_0_ALPHA1) -#define ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING (1 && ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d9746bd05..5c5fce5c6 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -132,9 +132,7 @@ GLCanvas3D::LayersEditing::LayersEditing() , m_layer_height_profile_modified(false) #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE , m_adaptive_cusp(0.2f) -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING , m_smooth_radius(5) -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE , state(Unknown) , band_width(2.0f) @@ -285,7 +283,6 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const m_adaptive_cusp = std::min(m_adaptive_cusp, (float)m_slicing_parameters->max_layer_height); ImGui::SliderFloat("", &m_adaptive_cusp, 0.0f, (float)m_slicing_parameters->max_layer_height, "%.2f"); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING ImGui::Separator(); imgui.disabled_begin(m_layer_height_profile.size() < 10); if (imgui.button(_(L("Smooth")))) @@ -301,7 +298,6 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const if (ImGui::SliderInt("##1", &radius, 1, 10)) m_smooth_radius = (unsigned int)radius; imgui.disabled_end(); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING ImGui::Separator(); if (imgui.button(_(L("Reset")))) @@ -617,7 +613,6 @@ void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, unsigned int radius) { m_layer_height_profile = smooth_height_profile(m_layer_height_profile, *m_slicing_parameters, radius); @@ -625,8 +620,6 @@ void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, m_layers_texture.valid = false; canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING - #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void GLCanvas3D::LayersEditing::generate_layer_height_texture() @@ -1256,9 +1249,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, Event); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #if ENABLE_THUMBNAIL_GENERATOR @@ -1577,15 +1568,12 @@ void GLCanvas3D::adaptive_layer_height_profile(float cusp) m_dirty = true; } -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING void GLCanvas3D::smooth_layer_height_profile(unsigned int radius) { m_layers_editing.smooth_layer_height_profile(*this, radius); m_layers_editing.state = LayersEditing::Completed; m_dirty = true; } -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING - #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool GLCanvas3D::is_reload_delayed() const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d57a5c8d6..4a1859d54 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -107,9 +107,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, Event); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class GLCanvas3D @@ -184,9 +182,7 @@ private: #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE mutable float m_adaptive_cusp; -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING mutable unsigned int m_smooth_radius; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class LayersTexture @@ -237,9 +233,7 @@ private: void reset_layer_height_profile(GLCanvas3D& canvas); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING void smooth_layer_height_profile(GLCanvas3D& canvas, unsigned int radius); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static float get_cursor_z_relative(const GLCanvas3D& canvas); @@ -537,9 +531,7 @@ public: #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void reset_layer_height_profile(); void adaptive_layer_height_profile(float cusp); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING void smooth_layer_height_profile(unsigned int radius); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool is_reload_delayed() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2750af7df..faf7a3d69 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2090,9 +2090,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); }); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](Event& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); }); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE_SMOOTHING #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 3DScene/Toolbar: From da44618074fdbe7771a234be29b23d462ec7e3c4 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 18 Nov 2019 14:32:41 +0100 Subject: [PATCH 09/16] 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")))) From 25ab9e8d5d2f9e061b453528a7cf80a0ac66e9d2 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 19 Nov 2019 11:43:20 +0100 Subject: [PATCH 10/16] Fixed normals transformation in functions stl_transform() --- src/admesh/stl.h | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/admesh/stl.h b/src/admesh/stl.h index fa0edec2b..9224b0459 100644 --- a/src/admesh/stl.h +++ b/src/admesh/stl.h @@ -184,10 +184,21 @@ extern void stl_mirror_xz(stl_file *stl); extern void stl_get_size(stl_file *stl); +// the following function is not used +/* template extern void stl_transform(stl_file *stl, T *trafo3x4) { - for (uint32_t i_face = 0; i_face < stl->stats.number_of_facets; ++ i_face) { + Eigen::Matrix trafo3x3; + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + trafo3x3(i, j) = (i * 4) + j; + } + } + Eigen::Matrix r = trafo3x3.inverse().transpose(); + for (uint32_t i_face = 0; i_face < stl->stats.number_of_facets; ++ i_face) { stl_facet &face = stl->facet_start[i_face]; for (int i_vertex = 0; i_vertex < 3; ++ i_vertex) { stl_vertex &v_dst = face.vertex[i_vertex]; @@ -196,21 +207,18 @@ extern void stl_transform(stl_file *stl, T *trafo3x4) v_dst(1) = T(trafo3x4[4] * v_src(0) + trafo3x4[5] * v_src(1) + trafo3x4[6] * v_src(2) + trafo3x4[7]); v_dst(2) = T(trafo3x4[8] * v_src(0) + trafo3x4[9] * v_src(1) + trafo3x4[10] * v_src(2) + trafo3x4[11]); } - stl_vertex &v_dst = face.normal; - stl_vertex v_src = v_dst; - v_dst(0) = T(trafo3x4[0] * v_src(0) + trafo3x4[1] * v_src(1) + trafo3x4[2] * v_src(2)); - v_dst(1) = T(trafo3x4[4] * v_src(0) + trafo3x4[5] * v_src(1) + trafo3x4[6] * v_src(2)); - v_dst(2) = T(trafo3x4[8] * v_src(0) + trafo3x4[9] * v_src(1) + trafo3x4[10] * v_src(2)); - } + face.normal = (r * face.normal.template cast()).template cast().eval(); + } stl_get_size(stl); } +*/ template inline void stl_transform(stl_file *stl, const Eigen::Transform& t) { - const Eigen::Matrix r = t.matrix().template block<3, 3>(0, 0); - for (size_t i = 0; i < stl->stats.number_of_facets; ++ i) { + const Eigen::Matrix r = t.matrix().template block<3, 3>(0, 0).inverse().transpose(); + for (size_t i = 0; i < stl->stats.number_of_facets; ++ i) { stl_facet &f = stl->facet_start[i]; for (size_t j = 0; j < 3; ++j) f.vertex[j] = (t * f.vertex[j].template cast()).template cast().eval(); @@ -223,12 +231,13 @@ inline void stl_transform(stl_file *stl, const Eigen::Transform inline void stl_transform(stl_file *stl, const Eigen::Matrix& m) { - for (size_t i = 0; i < stl->stats.number_of_facets; ++ i) { + const Eigen::Matrix r = m.inverse().transpose(); + for (size_t i = 0; i < stl->stats.number_of_facets; ++ i) { stl_facet &f = stl->facet_start[i]; for (size_t j = 0; j < 3; ++j) f.vertex[j] = (m * f.vertex[j].template cast()).template cast().eval(); - f.normal = (m * f.normal.template cast()).template cast().eval(); - } + f.normal = (r * f.normal.template cast()).template cast().eval(); + } stl_get_size(stl); } From 3b084c50cdb3c0f4e52b3a320374db2807a4929a Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 19 Nov 2019 14:44:42 +0100 Subject: [PATCH 11/16] Revert to older texture for mini printer printbed --- resources/icons/bed/mini.svg | 145 +++++++++++++---------------------- 1 file changed, 53 insertions(+), 92 deletions(-) diff --git a/resources/icons/bed/mini.svg b/resources/icons/bed/mini.svg index 1b9476ef8..93c3437bd 100644 --- a/resources/icons/bed/mini.svg +++ b/resources/icons/bed/mini.svg @@ -1,109 +1,70 @@ - - bed_texture_denser - - - - - - - - - - + + MINI_bed_texture + + + + + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 79d516ca7f9b14c3083c1048937448c4d76a926f Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 19 Nov 2019 14:58:27 +0100 Subject: [PATCH 12/16] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Smoothing algorithm modified to give more weight close to height limits --- src/libslic3r/Slicing.cpp | 27 ++++++++++++++++----------- src/libslic3r/SlicingAdaptive.cpp | 4 ++++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 66e339246..1badd9b14 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -346,8 +346,7 @@ std::vector layer_height_profile_adaptive( return layer_height_profile; } -std::vector smooth_height_profile(const std::vector& profile, const SlicingParameters& slicing_params, - unsigned int radius) +std::vector smooth_height_profile(const std::vector& profile, const SlicingParameters& slicing_params, unsigned int radius) { auto gauss_blur = [&slicing_params](const std::vector& profile, unsigned int radius) -> std::vector { auto gauss_kernel = [] (unsigned int radius) -> std::vector { @@ -390,28 +389,34 @@ std::vector smooth_height_profile(const std::vector& profile, co } // smooth the rest of the profile - double max_dz = (double)radius * slicing_params.layer_height; + double med_h = 0.5 * (slicing_params.min_layer_height + slicing_params.max_layer_height); + double half_delta_h = 0.5 * (slicing_params.max_layer_height - slicing_params.min_layer_height); + double inv_half_delta_h = (half_delta_h > 0.0) ? 1.0 / half_delta_h : 1.0; + + double max_dz_band = (double)radius * slicing_params.layer_height; for (size_t i = skip_count; i < size; i += 2) { - double z = profile[i]; - ret.push_back(z); + double zi = profile[i]; + ret.push_back(zi); ret.push_back(0.0); double& height = ret.back(); 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; + double weight_total = 0.0; for (int j = begin; j <= end; j += 2) { int kernel_id = radius + (j - (int)i) / 2; - double dz = std::abs(z - profile[j]); - if (dz * slicing_params.layer_height <= max_dz) + double dz = std::abs(zi - profile[j]); + if (dz * slicing_params.layer_height <= max_dz_band) { - height += kernel[kernel_id] * profile[j + 1]; - kernel_total += kernel[kernel_id]; + double dh = std::abs(profile[j + 1] - med_h); + double weight = kernel[kernel_id] * dh * inv_half_delta_h; + height += weight * profile[j + 1]; + weight_total += weight; } } - height = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, (kernel_total != 0.0) ? height /= kernel_total : profile[i + 1]); + height = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, (weight_total != 0.0) ? height /= weight_total : profile[i + 1]); } return ret; diff --git a/src/libslic3r/SlicingAdaptive.cpp b/src/libslic3r/SlicingAdaptive.cpp index e64012553..bc02a89c1 100644 --- a/src/libslic3r/SlicingAdaptive.cpp +++ b/src/libslic3r/SlicingAdaptive.cpp @@ -37,6 +37,10 @@ void SlicingAdaptive::prepare() m_mesh = m_object->raw_mesh(); const ModelInstance* first_instance = m_object->instances.front(); m_mesh.transform(first_instance->get_matrix(), first_instance->is_left_handed()); + for (stl_facet& facet : m_mesh.stl.facet_start) + { + facet.normal.normalize(); + } // 1) Collect faces from mesh. m_faces.reserve(m_mesh.stl.stats.number_of_facets); From 4982e177a26ccfdd93b875da7bb6fa635c56fe3c Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 19 Nov 2019 15:39:49 +0100 Subject: [PATCH 13/16] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Attempt to fix imgui dialog position on Mac --- src/slic3r/GUI/GLCanvas3D.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7827a9566..4721901f4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -230,7 +230,11 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const float canvas_w = (float)cnv_size.get_width(); float canvas_h = (float)cnv_size.get_height(); +#if ENABLE_RETINA_GL + const float scale_gl = m_retina_helper->get_scale_factor(); +#else const float scale_gl = wxGetApp().mainframe->scale_factor(); +#endif // ENABLE_RETINA_GL ImGuiWrapper& imgui = *wxGetApp().imgui(); imgui.set_next_window_pos(canvas_w - scale_gl * THICKNESS_BAR_WIDTH, canvas_h, ImGuiCond_Always, 1.0f, 1.0f); From 955439b3baf8ed03fa541e11325ec98a2083e061 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 20 Nov 2019 10:57:56 +0100 Subject: [PATCH 14/16] Fixed build on Mac --- src/slic3r/GUI/GLCanvas3D.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4721901f4..818c2ae63 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -230,14 +230,8 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const float canvas_w = (float)cnv_size.get_width(); float canvas_h = (float)cnv_size.get_height(); -#if ENABLE_RETINA_GL - const float scale_gl = m_retina_helper->get_scale_factor(); -#else - const float scale_gl = wxGetApp().mainframe->scale_factor(); -#endif // ENABLE_RETINA_GL - ImGuiWrapper& imgui = *wxGetApp().imgui(); - imgui.set_next_window_pos(canvas_w - scale_gl * THICKNESS_BAR_WIDTH, canvas_h, ImGuiCond_Always, 1.0f, 1.0f); + imgui.set_next_window_pos(canvas_w - imgui.get_style_scaling() * THICKNESS_BAR_WIDTH, canvas_h, ImGuiCond_Always, 1.0f, 1.0f); imgui.set_next_window_bg_alpha(0.5f); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); From aea32ffe7272186ca20e30c3edea8ff92c1048b7 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 20 Nov 2019 14:06:30 +0100 Subject: [PATCH 15/16] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Added 'keep min' option to smoothing algorithm --- src/libslic3r/Slicing.cpp | 26 +++++++++++++++----------- src/libslic3r/Slicing.hpp | 14 +++++++++++--- src/slic3r/GUI/GLCanvas3D.cpp | 24 +++++++++++++++--------- src/slic3r/GUI/GLCanvas3D.hpp | 10 ++++++---- src/slic3r/GUI/Plater.cpp | 2 +- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 1badd9b14..81e9bf0c5 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -346,9 +346,9 @@ std::vector layer_height_profile_adaptive( return layer_height_profile; } -std::vector smooth_height_profile(const std::vector& profile, const SlicingParameters& slicing_params, unsigned int radius) +std::vector smooth_height_profile(const std::vector& profile, const SlicingParameters& slicing_params, const HeightProfileSmoothingParams& smoothing_params) { - auto gauss_blur = [&slicing_params](const std::vector& profile, unsigned int radius) -> std::vector { + auto gauss_blur = [&slicing_params](const std::vector& profile, const HeightProfileSmoothingParams& smoothing_params) -> std::vector { auto gauss_kernel = [] (unsigned int radius) -> std::vector { unsigned int size = 2 * radius + 1; std::vector ret; @@ -374,7 +374,8 @@ std::vector smooth_height_profile(const std::vector& profile, co // not enough data to smmoth if ((int)profile.size() - (int)skip_count < 6) return profile; - + + unsigned int radius = std::max(smoothing_params.radius, (unsigned int)1); std::vector kernel = gauss_kernel(radius); int two_radius = 2 * (int)radius; @@ -388,15 +389,16 @@ std::vector smooth_height_profile(const std::vector& profile, co ret.push_back(profile[i]); } - // smooth the rest of the profile - double med_h = 0.5 * (slicing_params.min_layer_height + slicing_params.max_layer_height); - double half_delta_h = 0.5 * (slicing_params.max_layer_height - slicing_params.min_layer_height); - double inv_half_delta_h = (half_delta_h > 0.0) ? 1.0 / half_delta_h : 1.0; + // smooth the rest of the profile by biasing a gaussian blur + // the bias moves the smoothed profile closer to the min_layer_height + double delta_h = slicing_params.max_layer_height - slicing_params.min_layer_height; + double inv_delta_h = (delta_h != 0.0) ? 1.0 / delta_h : 1.0; double max_dz_band = (double)radius * slicing_params.layer_height; for (size_t i = skip_count; i < size; i += 2) { double zi = profile[i]; + double hi = profile[i + 1]; ret.push_back(zi); ret.push_back(0.0); double& height = ret.back(); @@ -409,20 +411,22 @@ std::vector smooth_height_profile(const std::vector& profile, co double dz = std::abs(zi - profile[j]); if (dz * slicing_params.layer_height <= max_dz_band) { - double dh = std::abs(profile[j + 1] - med_h); - double weight = kernel[kernel_id] * dh * inv_half_delta_h; + double dh = std::abs(slicing_params.max_layer_height - profile[j + 1]); + double weight = kernel[kernel_id] * sqrt(dh * inv_delta_h); height += weight * profile[j + 1]; weight_total += weight; } } - height = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, (weight_total != 0.0) ? height /= weight_total : profile[i + 1]); + height = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, (weight_total != 0.0) ? height /= weight_total : hi); + if (smoothing_params.keep_min) + height = std::min(height, hi); } return ret; }; - return gauss_blur(profile, std::max(radius, (unsigned int)1)); + return gauss_blur(profile, smoothing_params); } void adjust_layer_height_profile( diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index 8dc0b47e9..03ef7e67d 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -147,10 +147,18 @@ extern std::vector layer_height_profile_adaptive( const SlicingParameters& slicing_params, const ModelObject& object, float cusp_value); +struct HeightProfileSmoothingParams +{ + unsigned int radius; + bool keep_min; + + HeightProfileSmoothingParams() : radius(5), keep_min(false) {} + HeightProfileSmoothingParams(unsigned int radius, bool keep_min) : radius(radius), keep_min(keep_min) {} +}; + extern std::vector smooth_height_profile( - const std::vector& profile, - const SlicingParameters& slicing_params, - unsigned int radius); + const std::vector& profile, const SlicingParameters& slicing_params, + const HeightProfileSmoothingParams& smoothing_params); #else extern std::vector layer_height_profile_adaptive( const SlicingParameters &slicing_params, diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 818c2ae63..a459a3ec8 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -132,7 +132,6 @@ GLCanvas3D::LayersEditing::LayersEditing() , m_layer_height_profile_modified(false) #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE , m_adaptive_cusp(0.2f) - , m_smooth_radius(5) #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE , state(Unknown) , band_width(2.0f) @@ -283,7 +282,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::Separator(); if (imgui.button(_(L("Smooth")))) - wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, m_smooth_radius)); + wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), HeightProfileSmoothEvent(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, m_smooth_params )); ImGui::SameLine(); ImGui::SetCursorPosX(text_align); @@ -291,9 +290,16 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::SameLine(); ImGui::PushItemWidth(120.0f); ImGui::SetCursorPosX(widget_align); - int radius = (int)m_smooth_radius; + int radius = (int)m_smooth_params.radius; if (ImGui::SliderInt("##1", &radius, 1, 10)) - m_smooth_radius = (unsigned int)radius; + m_smooth_params.radius = (unsigned int)radius; + + ImGui::SetCursorPosX(text_align); + imgui.text(_(L("Keep min"))); + ImGui::SameLine(); + ImGui::PushItemWidth(120.0f); + ImGui::SetCursorPosX(widget_align); + imgui.checkbox("##2", m_smooth_params.keep_min); ImGui::Separator(); if (imgui.button(_(L("Reset")))) @@ -609,9 +615,9 @@ void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } -void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, unsigned int radius) +void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_params) { - m_layer_height_profile = smooth_height_profile(m_layer_height_profile, *m_slicing_parameters, radius); + m_layer_height_profile = smooth_height_profile(m_layer_height_profile, *m_slicing_parameters, smoothing_params); const_cast(m_model_object)->layer_height_profile = m_layer_height_profile; m_layers_texture.valid = false; canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); @@ -1245,7 +1251,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event); -wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, Event); +wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #if ENABLE_THUMBNAIL_GENERATOR @@ -1564,9 +1570,9 @@ void GLCanvas3D::adaptive_layer_height_profile(float cusp) m_dirty = true; } -void GLCanvas3D::smooth_layer_height_profile(unsigned int radius) +void GLCanvas3D::smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params) { - m_layers_editing.smooth_layer_height_profile(*this, radius); + m_layers_editing.smooth_layer_height_profile(*this, smoothing_params); m_layers_editing.state = LayersEditing::Completed; m_dirty = true; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 4a1859d54..ad35f3909 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -81,6 +81,8 @@ template using Vec2dsEvent = ArrayEvent; using Vec3dEvent = Event; template using Vec3dsEvent = ArrayEvent; +using HeightProfileSmoothEvent = Event; + wxDECLARE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent); @@ -107,7 +109,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event); -wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, Event); +wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class GLCanvas3D @@ -182,7 +184,7 @@ private: #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE mutable float m_adaptive_cusp; - mutable unsigned int m_smooth_radius; + mutable HeightProfileSmoothingParams m_smooth_params; #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class LayersTexture @@ -233,7 +235,7 @@ private: void reset_layer_height_profile(GLCanvas3D& canvas); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp); - void smooth_layer_height_profile(GLCanvas3D& canvas, unsigned int radius); + void smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_paramsn); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static float get_cursor_z_relative(const GLCanvas3D& canvas); @@ -531,7 +533,7 @@ public: #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void reset_layer_height_profile(); void adaptive_layer_height_profile(float cusp); - void smooth_layer_height_profile(unsigned int radius); + void smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE bool is_reload_delayed() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index faf7a3d69..563bb5133 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2090,7 +2090,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); }); - view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](Event& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); }); + view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](HeightProfileSmoothEvent& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); }); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 3DScene/Toolbar: From 6df506e4824ee26b68379cb4760c1e22a509385e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 22 Nov 2019 12:39:03 +0100 Subject: [PATCH 16/16] ENABLE_THUMBNAIL_GENERATOR -> Thumbnails generated using a callback function --- src/libslic3r/GCode.cpp | 113 ++++++++++---------- src/libslic3r/GCode.hpp | 10 +- src/libslic3r/GCode/ThumbnailData.hpp | 4 + src/libslic3r/Print.cpp | 4 +- src/libslic3r/Print.hpp | 8 +- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 19 ++-- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 9 +- src/slic3r/GUI/Plater.cpp | 77 ++++--------- 8 files changed, 108 insertions(+), 136 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 56a94b28c..28bcdf50c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -6,9 +6,6 @@ #include "Geometry.hpp" #include "GCode/PrintExtents.hpp" #include "GCode/WipeTower.hpp" -#if ENABLE_THUMBNAIL_GENERATOR -#include "GCode/ThumbnailData.hpp" -#endif // ENABLE_THUMBNAIL_GENERATOR #include "ShortestPath.hpp" #include "Utils.hpp" @@ -695,7 +692,7 @@ std::vector>> GCode::collec } #if ENABLE_THUMBNAIL_GENERATOR -void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const std::vector* thumbnail_data) +void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) #else void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) #endif // ENABLE_THUMBNAIL_GENERATOR @@ -725,7 +722,7 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ try { m_placeholder_parser_failed_templates.clear(); #if ENABLE_THUMBNAIL_GENERATOR - this->_do_export(*print, file, thumbnail_data); + this->_do_export(*print, file, thumbnail_cb); #else this->_do_export(*print, file); #endif // ENABLE_THUMBNAIL_GENERATOR @@ -793,9 +790,9 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ } #if ENABLE_THUMBNAIL_GENERATOR -void GCode::_do_export(Print& print, FILE* file, const std::vector* thumbnail_data) +void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thumbnail_cb) #else -void GCode::_do_export(Print &print, FILE *file) +void GCode::_do_export(Print& print, FILE* file) #endif // ENABLE_THUMBNAIL_GENERATOR { PROFILE_FUNC(); @@ -812,46 +809,46 @@ void GCode::_do_export(Print &print, FILE *file) // shall be adjusted as well to produce a G-code block compatible with the particular firmware flavor. if (print.config().gcode_flavor.value == gcfMarlin) { m_normal_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values[0]); - m_normal_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values[0]); - m_normal_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values[0]); - m_normal_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values[0]); - m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values[0]); - m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values[0]); - m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values[0]); - m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values[0]); - m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values[0]); - m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values[0]); - m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values[0]); - m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values[0]); - m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values[0]); - m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values[0]); - m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values[0]); - m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values[0]); + m_normal_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values[0]); + m_normal_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values[0]); + m_normal_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values[0]); + m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values[0]); + m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values[0]); + m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values[0]); if (m_silent_time_estimator_enabled) { m_silent_time_estimator.reset(); m_silent_time_estimator.set_dialect(print.config().gcode_flavor); - /* "Stealth mode" values can be just a copy of "normal mode" values + /* "Stealth mode" values can be just a copy of "normal mode" values * (when they aren't input for a printer preset). * Thus, use back value from values, instead of second one, which could be absent */ - m_silent_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values.back()); - m_silent_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values.back()); - m_silent_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values.back()); - m_silent_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values.back()); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values.back()); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values.back()); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values.back()); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values.back()); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values.back()); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values.back()); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values.back()); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values.back()); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values.back()); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values.back()); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values.back()); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values.back()); + m_silent_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values.back()); + m_silent_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values.back()); + m_silent_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values.back()); + m_silent_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values.back()); if (print.config().single_extruder_multi_material) { // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they // are considered to be active for the single extruder multi-material printers only. @@ -909,7 +906,8 @@ void GCode::_do_export(Print &print, FILE *file) std::sort(zs.begin(), zs.end()); m_layer_count += (unsigned int)(object->copies().size() * (std::unique(zs.begin(), zs.end()) - zs.begin())); } - } else { + } + else { // Print all objects with the same print_z together. std::vector zs; for (auto object : print.objects()) { @@ -927,7 +925,7 @@ void GCode::_do_export(Print &print, FILE *file) m_enable_cooling_markers = true; this->apply_print_config(print.config()); this->set_extruders(print.extruders()); - + // Initialize colorprint. m_colorprint_heights = cast(print.config().colorprint_heights.values); @@ -936,31 +934,31 @@ void GCode::_do_export(Print &print, FILE *file) // get the minimum cross-section used in the print std::vector mm3_per_mm; for (auto object : print.objects()) { - for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) { + for (size_t region_id = 0; region_id < object->region_volumes.size(); ++region_id) { const PrintRegion* region = print.regions()[region_id]; for (auto layer : object->layers()) { const LayerRegion* layerm = layer->regions()[region_id]; - if (region->config().get_abs_value("perimeter_speed" ) == 0 || - region->config().get_abs_value("small_perimeter_speed" ) == 0 || - region->config().get_abs_value("external_perimeter_speed" ) == 0 || - region->config().get_abs_value("bridge_speed" ) == 0) + if (region->config().get_abs_value("perimeter_speed") == 0 || + region->config().get_abs_value("small_perimeter_speed") == 0 || + region->config().get_abs_value("external_perimeter_speed") == 0 || + region->config().get_abs_value("bridge_speed") == 0) mm3_per_mm.push_back(layerm->perimeters.min_mm3_per_mm()); - if (region->config().get_abs_value("infill_speed" ) == 0 || - region->config().get_abs_value("solid_infill_speed" ) == 0 || - region->config().get_abs_value("top_solid_infill_speed" ) == 0 || - region->config().get_abs_value("bridge_speed" ) == 0) + if (region->config().get_abs_value("infill_speed") == 0 || + region->config().get_abs_value("solid_infill_speed") == 0 || + region->config().get_abs_value("top_solid_infill_speed") == 0 || + region->config().get_abs_value("bridge_speed") == 0) mm3_per_mm.push_back(layerm->fills.min_mm3_per_mm()); } } - if (object->config().get_abs_value("support_material_speed" ) == 0 || - object->config().get_abs_value("support_material_interface_speed" ) == 0) + if (object->config().get_abs_value("support_material_speed") == 0 || + object->config().get_abs_value("support_material_interface_speed") == 0) for (auto layer : object->support_layers()) mm3_per_mm.push_back(layer->support_fills.min_mm3_per_mm()); } print.throw_if_canceled(); // filter out 0-width segments mm3_per_mm.erase(std::remove_if(mm3_per_mm.begin(), mm3_per_mm.end(), [](double v) { return v < 0.000001; }), mm3_per_mm.end()); - if (! mm3_per_mm.empty()) { + if (!mm3_per_mm.empty()) { // In order to honor max_print_speed we need to find a target volumetric // speed that we can use throughout the print. So we define this target // volumetric speed as the volumetric speed produced by printing the @@ -973,7 +971,7 @@ void GCode::_do_export(Print &print, FILE *file) } } print.throw_if_canceled(); - + m_cooling_buffer = make_unique(*this); if (print.config().spiral_vase.value) m_spiral_vase = make_unique(print.config()); @@ -991,11 +989,12 @@ void GCode::_do_export(Print &print, FILE *file) #if ENABLE_THUMBNAIL_GENERATOR // Write thumbnails using base64 encoding - if (thumbnail_data != nullptr) + if (thumbnail_cb != nullptr) { const size_t max_row_length = 78; - - for (const ThumbnailData& data : *thumbnail_data) + ThumbnailsList thumbnails; + thumbnail_cb(thumbnails, print.full_print_config().option("thumbnails")->values, true, true, false); + for (const ThumbnailData& data : thumbnails) { if (data.is_valid()) { diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 19ec5be3c..40794986a 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -17,6 +17,9 @@ #include "GCodeTimeEstimator.hpp" #include "EdgeGrid.hpp" #include "GCode/Analyzer.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR #include #include @@ -30,9 +33,6 @@ namespace Slic3r { // Forward declarations. class GCode; class GCodePreviewData; -#if ENABLE_THUMBNAIL_GENERATOR -struct ThumbnailData; -#endif // ENABLE_THUMBNAIL_GENERATOR class AvoidCrossingPerimeters { public: @@ -167,7 +167,7 @@ public: // throws std::runtime_exception on error, // throws CanceledException through print->throw_if_canceled(). #if ENABLE_THUMBNAIL_GENERATOR - void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, const std::vector* thumbnail_data = nullptr); + void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #else void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); #endif // ENABLE_THUMBNAIL_GENERATOR @@ -199,7 +199,7 @@ public: protected: #if ENABLE_THUMBNAIL_GENERATOR - void _do_export(Print& print, FILE* file, const std::vector* thumbnail_data); + void _do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thumbnail_cb); #else void _do_export(Print &print, FILE *file); #endif //ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/GCode/ThumbnailData.hpp b/src/libslic3r/GCode/ThumbnailData.hpp index 9823ffd31..efe875e15 100644 --- a/src/libslic3r/GCode/ThumbnailData.hpp +++ b/src/libslic3r/GCode/ThumbnailData.hpp @@ -4,6 +4,7 @@ #if ENABLE_THUMBNAIL_GENERATOR #include +#include "libslic3r/Point.hpp" namespace Slic3r { @@ -20,6 +21,9 @@ struct ThumbnailData bool is_valid() const; }; +typedef std::vector ThumbnailsList; +typedef std::function ThumbnailsGeneratorCallback; + } // namespace Slic3r #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 78a09c511..8b79f5367 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1538,7 +1538,7 @@ void Print::process() // write error into the G-code, cannot execute post-processing scripts). // It is up to the caller to show an error message. #if ENABLE_THUMBNAIL_GENERATOR -std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const std::vector* thumbnail_data) +std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) #else std::string Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data) #endif // ENABLE_THUMBNAIL_GENERATOR @@ -1559,7 +1559,7 @@ std::string Print::export_gcode(const std::string &path_template, GCodePreviewDa // The following line may die for multiple reasons. GCode gcode; #if ENABLE_THUMBNAIL_GENERATOR - gcode.do_export(this, path.c_str(), preview_data, thumbnail_data); + gcode.do_export(this, path.c_str(), preview_data, thumbnail_cb); #else gcode.do_export(this, path.c_str(), preview_data); #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 4fcd67166..1649f3c04 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -11,6 +11,9 @@ #include "Slicing.hpp" #include "GCode/ToolOrdering.hpp" #include "GCode/WipeTower.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR namespace Slic3r { @@ -19,9 +22,6 @@ class PrintObject; class ModelObject; class GCode; class GCodePreviewData; -#if ENABLE_THUMBNAIL_GENERATOR -struct ThumbnailData; -#endif // ENABLE_THUMBNAIL_GENERATOR // Print step IDs for keeping track of the print state. enum PrintStep { @@ -311,7 +311,7 @@ public: // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file. // If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r). #if ENABLE_THUMBNAIL_GENERATOR - std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const std::vector* thumbnail_data = nullptr); + std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #else std::string export_gcode(const std::string &path_template, GCodePreviewData *preview_data); #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 5ab65f340..570841a45 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -20,9 +20,6 @@ #include "libslic3r/Utils.hpp" #include "libslic3r/GCode/PostProcessor.hpp" #include "libslic3r/GCode/PreviewData.hpp" -#if ENABLE_THUMBNAIL_GENERATOR -#include "libslic3r/GCode/ThumbnailData.hpp" -#endif // ENABLE_THUMBNAIL_GENERATOR #include "libslic3r/libslic3r.h" #include @@ -91,7 +88,7 @@ void BackgroundSlicingProcess::process_fff() m_print->process(); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id)); #if ENABLE_THUMBNAIL_GENERATOR - m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_data); + m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_cb); #else m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); #endif // ENABLE_THUMBNAIL_GENERATOR @@ -139,9 +136,12 @@ void BackgroundSlicingProcess::process_sla() m_sla_print->export_raster(zipper); #if ENABLE_THUMBNAIL_GENERATOR - if (m_thumbnail_data != nullptr) + if (m_thumbnail_cb != nullptr) { - for (const ThumbnailData& data : *m_thumbnail_data) + ThumbnailsList thumbnails; + m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, true, false); +// m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, false, false); // renders also supports and pad + for (const ThumbnailData& data : thumbnails) { if (data.is_valid()) write_thumbnail(zipper, data); @@ -461,9 +461,12 @@ void BackgroundSlicingProcess::prepare_upload() Zipper zipper{source_path.string()}; m_sla_print->export_raster(zipper, m_upload_job.upload_data.upload_path.string()); #if ENABLE_THUMBNAIL_GENERATOR - if (m_thumbnail_data != nullptr) + if (m_thumbnail_cb != nullptr) { - for (const ThumbnailData& data : *m_thumbnail_data) + ThumbnailsList thumbnails; + m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, true, false); +// m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, false, false); // renders also supports and pad + for (const ThumbnailData& data : thumbnails) { if (data.is_valid()) write_thumbnail(zipper, data); diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index a603d52ac..984686e35 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -17,9 +17,6 @@ namespace Slic3r { class DynamicPrintConfig; class GCodePreviewData; -#if ENABLE_THUMBNAIL_GENERATOR -struct ThumbnailData; -#endif // ENABLE_THUMBNAIL_GENERATOR class Model; class SLAPrint; @@ -53,7 +50,7 @@ public: void set_sla_print(SLAPrint *print) { m_sla_print = print; } void set_gcode_preview_data(GCodePreviewData *gpd) { m_gcode_preview_data = gpd; } #if ENABLE_THUMBNAIL_GENERATOR - void set_thumbnail_data(const std::vector* data) { m_thumbnail_data = data; } + void set_thumbnail_cb(ThumbnailsGeneratorCallback cb) { m_thumbnail_cb = cb; } #endif // ENABLE_THUMBNAIL_GENERATOR // The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished @@ -159,8 +156,8 @@ private: // Data structure, to which the G-code export writes its annotations. GCodePreviewData *m_gcode_preview_data = nullptr; #if ENABLE_THUMBNAIL_GENERATOR - // Data structures, used to write thumbnails into gcode. - const std::vector* m_thumbnail_data = nullptr; + // Callback function, used to write thumbnails into gcode. + ThumbnailsGeneratorCallback m_thumbnail_cb = nullptr; #endif // ENABLE_THUMBNAIL_GENERATOR // Temporary G-code, there is one defined for the BackgroundSlicingProcess, differentiated from the other processes by a process ID. std::string m_temp_output_path; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f04e1e17f..6f1c776fd 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1387,9 +1387,6 @@ struct Plater::priv Slic3r::Model model; PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; -#if ENABLE_THUMBNAIL_GENERATOR - std::vector thumbnail_data; -#endif // ENABLE_THUMBNAIL_GENERATOR // GUI elements wxSizer* panel_sizer{ nullptr }; @@ -1946,6 +1943,7 @@ struct Plater::priv #if ENABLE_THUMBNAIL_GENERATOR void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); + void generate_thumbnails(ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR void msw_rescale_object_menu(); @@ -2016,7 +2014,15 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) background_process.set_sla_print(&sla_print); background_process.set_gcode_preview_data(&gcode_preview_data); #if ENABLE_THUMBNAIL_GENERATOR - background_process.set_thumbnail_data(&thumbnail_data); + background_process.set_thumbnail_cb([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool transparent_background) + { + std::packaged_task task([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool transparent_background) { + generate_thumbnails(thumbnails, sizes, printable_only, parts_only, transparent_background); + }); + std::future result = task.get_future(); + wxTheApp->CallAfter([&]() { task(thumbnails, sizes, printable_only, parts_only, transparent_background); }); + result.wait(); + }); #endif // ENABLE_THUMBNAIL_GENERATOR background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); @@ -3062,37 +3068,6 @@ bool Plater::priv::restart_background_process(unsigned int state) ( ((state & UPDATE_BACKGROUND_PROCESS_FORCE_RESTART) != 0 && ! this->background_process.finished()) || (state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) != 0 || (state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ) ) { -#if ENABLE_THUMBNAIL_GENERATOR - if (((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) && - (this->background_process.state() != BackgroundSlicingProcess::STATE_RUNNING)) - { - // update thumbnail data - const std::vector &thumbnail_sizes = this->background_process.current_print()->full_print_config().option("thumbnails")->values; - if (this->printer_technology == ptFFF) - { - // for ptFFF we need to generate the thumbnails before the export of gcode starts - this->thumbnail_data.clear(); - for (const Vec2d &sized : thumbnail_sizes) - { - this->thumbnail_data.push_back(ThumbnailData()); - Point size(sized); // round to ints - generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, true, false); - } - } - else if (this->printer_technology == ptSLA) - { - // for ptSLA generate thumbnails without supports and pad (not yet calculated) - // to render also supports and pad see on_slicing_update() - this->thumbnail_data.clear(); - for (const Vec2d &sized : thumbnail_sizes) - { - this->thumbnail_data.push_back(ThumbnailData()); - Point size(sized); // round to ints - generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, true, false); - } - } - } -#endif // ENABLE_THUMBNAIL_GENERATOR // The print is valid and it can be started. if (this->background_process.start()) { this->statusbar()->set_cancel_callback([this]() { @@ -3430,25 +3405,6 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) } else if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_PREVIEW) { // Update the SLA preview. Only called if not RELOAD_SLA_SUPPORT_POINTS, as the block above will refresh the preview anyways. this->preview->reload_print(); - - // uncomment the following lines if you want to render into the thumbnail also supports and pad for SLA printer -/* -#if ENABLE_THUMBNAIL_GENERATOR - // update thumbnail data - // for ptSLA generate the thumbnail after supports and pad have been calculated to have them rendered - if ((this->printer_technology == ptSLA) && (evt.status.percent == -3)) - { - const std::vector& thumbnail_sizes = this->background_process.current_print()->full_print_config().option("thumbnails")->values; - this->thumbnail_data.clear(); - for (const Vec2d &sized : thumbnail_sizes) - { - this->thumbnail_data.push_back(ThumbnailData()); - Point size(sized); // round to ints - generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, false, false); - } - } -#endif // ENABLE_THUMBNAIL_GENERATOR -*/ } } @@ -3679,6 +3635,19 @@ void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsig { view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only, transparent_background); } + +void Plater::priv::generate_thumbnails(ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool transparent_background) +{ + thumbnails.clear(); + for (const Vec2d& size : sizes) + { + thumbnails.push_back(ThumbnailData()); + Point isize(size); // round to ints + generate_thumbnail(thumbnails.back(), isize.x(), isize.y(), printable_only, parts_only, transparent_background); + if (!thumbnails.back().is_valid()) + thumbnails.pop_back(); + } +} #endif // ENABLE_THUMBNAIL_GENERATOR void Plater::priv::msw_rescale_object_menu()