From 4c80d9ed01bc0fdcda9235224f50caeb77d86d77 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 27 Aug 2021 09:04:15 +0200 Subject: [PATCH 1/3] Fix taking entering/leaving snapshots in SLA gizmo: This was broken between 2.2.0 and 2.3.0. The 'entering' snapshot should be taken before the gizmo opens, not after. Otherwise it is in fact the same as the next snapshot. --- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 11 ------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 2 ++ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 34 +++++++++++--------- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 8b033ce732..1c6e00c070 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -135,6 +135,7 @@ public: bool is_activable() const { return on_is_activable(); } bool is_selectable() const { return on_is_selectable(); } CommonGizmosDataID get_requirements() const { return on_get_requirements(); } + virtual bool wants_enter_leave_snapshots() const { return false; } void set_common_data_pool(CommonGizmosDataPool* ptr) { m_c = ptr; } unsigned int get_sprite_id() const { return m_sprite_id; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 8c90d20d31..c7faab3bf5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -901,15 +901,6 @@ void GLGizmoSlaSupports::on_set_state() return; if (m_state == On && m_old_state != On) { // the gizmo was just turned on - if (! m_parent.get_gizmos_manager().is_serializing()) { - // Only take the snapshot when the USER opens the gizmo. Common gizmos - // data are not yet available, the CallAfter will postpone taking the - // snapshot until they are. No, it does not feel right. - wxGetApp().CallAfter([]() { - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Entering SLA gizmo")); - }); - } - // Set default head diameter from config. const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; m_new_point_head_diameter = static_cast(cfg.option("support_head_front_diameter"))->value; @@ -925,8 +916,6 @@ void GLGizmoSlaSupports::on_set_state() else { // we are actually shutting down disable_editing_mode(); // so it is not active next time the gizmo opens - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Leaving SLA gizmo")); - m_normal_cache.clear(); m_old_mo_id = -1; } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index cb60c0e258..8e30aa6b85 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -67,6 +67,8 @@ public: bool has_backend_supports() const; void reslice_SLA_supports(bool postpone_error_messages = false) const; + bool wants_enter_leave_snapshots() const override { return true; } + private: bool on_init() override; void on_update(const UpdateData& data) override; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 6d9a039772..080991859b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -22,6 +22,7 @@ #include "slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp" #include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp" +#include "libslic3r/format.hpp" #include "libslic3r/Model.hpp" #include "libslic3r/PresetBundle.hpp" @@ -1198,26 +1199,29 @@ void GLGizmosManager::activate_gizmo(EType type) if (m_gizmos.empty() || m_current == type) return; - if (m_current != Undefined) { - m_gizmos[m_current]->set_state(GLGizmoBase::Off); - if (m_gizmos[m_current]->get_state() != GLGizmoBase::Off) + GLGizmoBase* old_gizmo = m_current == Undefined ? nullptr : m_gizmos[m_current].get(); + GLGizmoBase* new_gizmo = type == Undefined ? nullptr : m_gizmos[type].get(); + + if (old_gizmo) { + old_gizmo->set_state(GLGizmoBase::Off); + if (old_gizmo->get_state() != GLGizmoBase::Off) return; // gizmo refused to be turned off, do nothing. + + if (! m_parent.get_gizmos_manager().is_serializing() + && old_gizmo->wants_enter_leave_snapshots()) + Plater::TakeSnapshot snapshot(wxGetApp().plater(), + Slic3r::format(_utf8("Leaving %1%"), old_gizmo->get_name())); } + if (new_gizmo && ! m_parent.get_gizmos_manager().is_serializing() + && new_gizmo->wants_enter_leave_snapshots()) + Plater::TakeSnapshot snapshot(wxGetApp().plater(), + Slic3r::format(_utf8("Entering %1%"), new_gizmo->get_name())); + m_current = type; - // Updating common data should be left to the update_data function, which - // is always called after this one. activate_gizmo can be called by undo/redo, - // when selection is not yet deserialized, so the common data would update - // incorrectly (or crash if relying on unempty selection). Undo/redo stack - // will also call update_data, after selection is restored. - - //m_common_gizmos_data->update(get_current() - // ? get_current()->get_requirements() - // : CommonGizmosDataID(0)); - - if (type != Undefined) - m_gizmos[type]->set_state(GLGizmoBase::On); + if (new_gizmo) + new_gizmo->set_state(GLGizmoBase::On); } From a4300b8e6411d42ce73f3ff2cd23785a3f172d8f Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 27 Aug 2021 09:04:33 +0200 Subject: [PATCH 2/3] Naming of the entering/leaving snapshots is now more generic, it uses the actual name of the gizmo. Also, the keyboard shortcut is now appended to the name, instead of being duplicated in it. --- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 14 ++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 4 ++-- 14 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index cc089e26ef..64479a39e2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -232,6 +232,20 @@ void GLGizmoBase::render_input_window(float x, float y, float bottom_limit) } } + + +std::string GLGizmoBase::get_name(bool include_shortcut) const +{ + int key = get_shortcut_key(); + assert( key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z); + std::string out = on_get_name(); + if (include_shortcut) + out += std::string(" [") + char(int('A') + key - int(WXK_CONTROL_A)) + "]"; + return out; +} + + + // Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components // were not interpolated by alpha blending or multi sampling. unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 1c6e00c070..05f6adb5e8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -120,7 +120,7 @@ public: void load(cereal::BinaryInputArchive& ar) { m_state = On; on_load(ar); } void save(cereal::BinaryOutputArchive& ar) const { on_save(ar); } - std::string get_name() const { return on_get_name(); } + std::string get_name(bool include_shortcut = true) const; int get_group_id() const { return m_group_id; } void set_group_id(int id) { m_group_id = id; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 641258ca44..3dcb9e2b10 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -49,7 +49,7 @@ bool GLGizmoCut::on_init() std::string GLGizmoCut::on_get_name() const { - return (_L("Cut") + " [C]").ToUTF8().data(); + return _u8L("Cut"); } void GLGizmoCut::on_set_state() diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 99c010bf1d..1ebba4d11f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -28,7 +28,7 @@ void GLGizmoFdmSupports::on_shutdown() std::string GLGizmoFdmSupports::on_get_name() const { - return (_L("Paint-on supports") + " [L]").ToUTF8().data(); + return _u8L("Paint-on supports"); } @@ -85,7 +85,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l y = std::min(y, bottom_limit - approx_height); m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); - m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->begin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index 3e5c12eec4..b8c7d9f92e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -37,7 +37,7 @@ CommonGizmosDataID GLGizmoFlatten::on_get_requirements() const std::string GLGizmoFlatten::on_get_name() const { - return (_L("Place on face") + " [F]").ToUTF8().data(); + return _u8L("Place on face"); } bool GLGizmoFlatten::on_is_activable() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 05e0be1410..f405f457d1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -505,7 +505,7 @@ RENDER_AGAIN: y = std::min(y, bottom_limit - approx_height); m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); - m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->begin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: const float settings_sliders_left = @@ -773,7 +773,7 @@ bool GLGizmoHollow::on_is_selectable() const std::string GLGizmoHollow::on_get_name() const { - return (_(L("Hollow and drill")) + " [H]").ToUTF8().data(); + return _u8L("Hollow and drill"); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index a30ac377e8..608e7bd1fa 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -42,7 +42,7 @@ void GLGizmoMmuSegmentation::on_shutdown() std::string GLGizmoMmuSegmentation::on_get_name() const { // FIXME Lukas H.: Discuss and change shortcut - return (_L("Multimaterial painting") + " [N]").ToUTF8().data(); + return _u8L("Multimaterial painting"); } bool GLGizmoMmuSegmentation::on_is_selectable() const @@ -239,7 +239,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott y = std::min(y, bottom_limit - approx_height); m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); - m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->begin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 9a056adcb3..e7b6a0ad6e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -52,7 +52,7 @@ bool GLGizmoMove3D::on_init() std::string GLGizmoMove3D::on_get_name() const { - return (_L("Move") + " [M]").ToUTF8().data(); + return _u8L("Move"); } bool GLGizmoMove3D::on_is_activable() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 36759d2eca..54fcfc2c7c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -463,7 +463,7 @@ bool GLGizmoRotate3D::on_init() std::string GLGizmoRotate3D::on_get_name() const { - return (_L("Rotate") + " [R]").ToUTF8().data(); + return _u8L("Rotate"); } bool GLGizmoRotate3D::on_is_activable() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index 894d844d83..b97507166b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -76,7 +76,7 @@ bool GLGizmoScale3D::on_init() std::string GLGizmoScale3D::on_get_name() const { - return (_L("Scale") + " [S]").ToUTF8().data(); + return _u8L("Scale"); } bool GLGizmoScale3D::on_is_activable() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp index 5b84bbaba4..a2ee56d9ae 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -48,7 +48,7 @@ bool GLGizmoSeam::on_init() std::string GLGizmoSeam::on_get_name() const { - return (_L("Seam painting") + " [P]").ToUTF8().data(); + return _u8L("Seam painting"); } @@ -79,7 +79,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) const float approx_height = m_imgui->scaled(14.0f); y = std::min(y, bottom_limit - approx_height); m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); - m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->begin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp index f70e3f93e2..9f49f9734a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp @@ -44,7 +44,7 @@ bool GLGizmoSimplify::on_init() std::string GLGizmoSimplify::on_get_name() const { - return (_L("Simplify")).ToUTF8().data(); + return _u8L("Simplify"); } void GLGizmoSimplify::on_render() {} @@ -97,7 +97,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi int flag = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse; - m_imgui->begin(on_get_name(), flag); + m_imgui->begin(get_name(), flag); size_t triangle_count = m_volume->mesh().its.indices.size(); // already reduced mesh diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index c7faab3bf5..11446d6d78 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -625,7 +625,7 @@ RENDER_AGAIN: //ImGui::SetNextWindowPos(ImVec2(x, y - std::max(0.f, y+window_size.y-bottom_limit) )); //ImGui::SetNextWindowSize(ImVec2(window_size)); - m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->begin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); // adjust window position to avoid overlap the view toolbar float win_h = ImGui::GetWindowHeight(); @@ -863,7 +863,7 @@ bool GLGizmoSlaSupports::on_is_selectable() const std::string GLGizmoSlaSupports::on_get_name() const { - return (_L("SLA Support Points") + " [L]").ToUTF8().data(); + return _u8L("SLA Support Points"); } CommonGizmosDataID GLGizmoSlaSupports::on_get_requirements() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 080991859b..dfe6de746c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -1210,13 +1210,13 @@ void GLGizmosManager::activate_gizmo(EType type) if (! m_parent.get_gizmos_manager().is_serializing() && old_gizmo->wants_enter_leave_snapshots()) Plater::TakeSnapshot snapshot(wxGetApp().plater(), - Slic3r::format(_utf8("Leaving %1%"), old_gizmo->get_name())); + Slic3r::format(_utf8("Leaving %1%"), old_gizmo->get_name(false))); } if (new_gizmo && ! m_parent.get_gizmos_manager().is_serializing() && new_gizmo->wants_enter_leave_snapshots()) Plater::TakeSnapshot snapshot(wxGetApp().plater(), - Slic3r::format(_utf8("Entering %1%"), new_gizmo->get_name())); + Slic3r::format(_utf8("Entering %1%"), new_gizmo->get_name(false))); m_current = type; From 315663980bf1f567e110cdcb72a2f2b694f4c5e5 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 31 Aug 2021 13:48:22 +0200 Subject: [PATCH 3/3] Do not allow 'replace by stl' when a gizmo is active, some of the gizmos might not cope well. ALso avoided code duplication in all such cases (currently fix by Netfabb, simplify, replace by stl). --- src/slic3r/GUI/GUI_ObjectList.cpp | 13 ++++------ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 29 ++++++++++++++++------- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 3 ++- src/slic3r/GUI/Plater.cpp | 11 ++++----- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 096836f23e..c99d9090cb 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -4030,17 +4030,12 @@ void ObjectList::simplify() // Do not simplify when a gizmo is open. There might be issues with updates // and what is worse, the snapshot time would refer to the internal stack. - auto current_type = gizmos_mgr.get_current_type(); - if (current_type == GLGizmosManager::Simplify) { + if (! gizmos_mgr.check_gizmos_closed_except(GLGizmosManager::EType::Simplify)) + return; + + if (gizmos_mgr.get_current_type() == GLGizmosManager::Simplify) { // close first gizmos_mgr.open_gizmo(GLGizmosManager::EType::Simplify); - }else if (current_type != GLGizmosManager::Undefined) { - plater->get_notification_manager()->push_notification( - NotificationType::CustomSupportsAndSeamRemovedAfterRepair, - NotificationManager::NotificationLevel::RegularNotification, - _u8L("ERROR: Please close all manipulators available from " - "the left toolbar before start simplify the mesh.")); - return; } gizmos_mgr.open_gizmo(GLGizmosManager::EType::Simplify); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index dfe6de746c..93eba3042c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -164,10 +164,8 @@ void GLGizmosManager::refresh_on_off_state() return; if (m_current != Undefined - && ! m_gizmos[m_current]->is_activable()) { - activate_gizmo(Undefined); + && ! m_gizmos[m_current]->is_activable() && activate_gizmo(Undefined)) update_data(); - } } void GLGizmosManager::reset_all_states() @@ -182,14 +180,28 @@ void GLGizmosManager::reset_all_states() bool GLGizmosManager::open_gizmo(EType type) { int idx = int(type); - if (m_gizmos[idx]->is_activable()) { - activate_gizmo(m_current == idx ? Undefined : (EType)idx); + if (m_gizmos[idx]->is_activable() + && activate_gizmo(m_current == idx ? Undefined : (EType)idx)) { update_data(); return true; } return false; } + +bool GLGizmosManager::check_gizmos_closed_except(EType type) const +{ + if (get_current_type() != type && get_current_type() != Undefined) { + wxGetApp().plater()->get_notification_manager()->push_notification( + NotificationType::CustomSupportsAndSeamRemovedAfterRepair, + NotificationManager::NotificationLevel::RegularNotification, + _u8L("ERROR: Please close all manipulators available from " + "the left toolbar first")); + return false; + } + return true; +} + void GLGizmosManager::set_hover_id(int id) { if (!m_enabled || m_current == Undefined) @@ -1194,10 +1206,10 @@ std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) return name; } -void GLGizmosManager::activate_gizmo(EType type) +bool GLGizmosManager::activate_gizmo(EType type) { if (m_gizmos.empty() || m_current == type) - return; + return true; GLGizmoBase* old_gizmo = m_current == Undefined ? nullptr : m_gizmos[m_current].get(); GLGizmoBase* new_gizmo = type == Undefined ? nullptr : m_gizmos[type].get(); @@ -1205,7 +1217,7 @@ void GLGizmosManager::activate_gizmo(EType type) if (old_gizmo) { old_gizmo->set_state(GLGizmoBase::Off); if (old_gizmo->get_state() != GLGizmoBase::Off) - return; // gizmo refused to be turned off, do nothing. + return false; // gizmo refused to be turned off, do nothing. if (! m_parent.get_gizmos_manager().is_serializing() && old_gizmo->wants_enter_leave_snapshots()) @@ -1222,6 +1234,7 @@ void GLGizmosManager::activate_gizmo(EType type) if (new_gizmo) new_gizmo->set_state(GLGizmoBase::On); + return true; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 188c9e9141..ed02574dfa 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -104,7 +104,7 @@ private: std::vector get_selectable_idxs() const; size_t get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const; - void activate_gizmo(EType type); + bool activate_gizmo(EType type); struct MouseCapture { @@ -176,6 +176,7 @@ public: void reset_all_states(); bool is_serializing() const { return m_serializing; } bool open_gizmo(EType type); + bool check_gizmos_closed_except(EType) const; void set_hover_id(int id); void enable_grabber(EType type, unsigned int id, bool enable); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 4236ee4501..af8734184f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3186,6 +3186,9 @@ void Plater::priv::update_sla_scene() void Plater::priv::replace_with_stl() { + if (! q->canvas3D()->get_gizmos_manager().check_gizmos_closed_except(GLGizmosManager::EType::Undefined)) + return; + const Selection& selection = get_selection(); if (selection.is_wipe_tower() || get_selection().get_volume_idxs().size() != 1) @@ -3530,14 +3533,8 @@ void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* = // Do not fix anything when a gizmo is open. There might be issues with updates // and what is worse, the snapshot time would refer to the internal stack. - if (q->canvas3D()->get_gizmos_manager().get_current_type() != GLGizmosManager::Undefined) { - notification_manager->push_notification( - NotificationType::CustomSupportsAndSeamRemovedAfterRepair, - NotificationManager::NotificationLevel::RegularNotification, - _u8L("ERROR: Please close all manipulators available from " - "the left toolbar before fixing the mesh.")); + if (! q->canvas3D()->get_gizmos_manager().check_gizmos_closed_except(GLGizmosManager::Undefined)) return; - } // size_t snapshot_time = undo_redo_stack().active_snapshot_time(); Plater::TakeSnapshot snapshot(q, _L("Fix through NetFabb"));