diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index d098d41f5..e8889b39d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -14,10 +14,11 @@ #include "libslic3r/Model.hpp" - namespace Slic3r { namespace GUI { +static const ColorRGBA DISABLED_COLOR = ColorRGBA::DARK_GRAY(); + GLGizmoHollow::GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) { @@ -508,6 +509,7 @@ void GLGizmoHollow::delete_selected_points() bool GLGizmoHollow::on_mouse(const wxMouseEvent &mouse_event) { + if (!m_input_enabled) return true; if (mouse_event.Moving()) return false; if (use_grabbers(mouse_event)) return true; @@ -644,6 +646,16 @@ void GLGizmoHollow::update_hole_raycasters_for_picking_transform() } #endif // ENABLE_RAYCAST_PICKING +static int last_completed_step(const SLAPrint& sla) +{ + int step = -1; + for (int i = 0; i < (int)SLAPrintObjectStep::slaposCount; ++i) { + if (sla.is_step_done((SLAPrintObjectStep)i)) + ++step; + } + return step; +} + void GLGizmoHollow::update_volumes() { m_volumes.clear(); @@ -657,6 +669,8 @@ void GLGizmoHollow::update_volumes() if (po == nullptr) return; + m_input_enabled = false; + TriangleMesh backend_mesh = po->get_mesh_to_print(); if (!backend_mesh.empty()) { // The backend has generated a valid mesh. Use it @@ -666,8 +680,12 @@ void GLGizmoHollow::update_volumes() new_volume->model.init_from(backend_mesh); new_volume->set_instance_transformation(po->model_object()->instances[m_parent.get_selection().get_instance_idx()]->get_transformation()); new_volume->set_sla_shift_z(po->get_current_elevation()); - new_volume->selected = true; // to set the proper color new_volume->mesh_raycaster = std::make_unique(backend_mesh); + m_input_enabled = last_completed_step(*m_c->selection_info()->print_object()->print()) >= slaposAssembly; + if (m_input_enabled) + new_volume->selected = true; // to set the proper color + else + new_volume->set_color(DISABLED_COLOR); } if (m_volumes.volumes.empty()) { @@ -684,7 +702,7 @@ void GLGizmoHollow::update_volumes() new_volume->set_instance_transformation(v->get_instance_transformation()); new_volume->set_volume_transformation(v->get_volume_transformation()); new_volume->set_sla_shift_z(v->get_sla_shift_z()); - new_volume->selected = true; // to set the proper color + new_volume->set_color(DISABLED_COLOR); new_volume->mesh_raycaster = std::make_unique(mesh); } } @@ -784,6 +802,8 @@ RENDER_AGAIN: float window_width = minimal_slider_width + std::max({settings_sliders_left, clipping_slider_left, diameter_slider_left}); window_width = std::max(window_width, button_preview_width); + m_imgui->disabled_begin(!m_input_enabled); + if (m_imgui->button(m_desc["preview"])) process_mesh(slaposDrillHoles); @@ -801,7 +821,10 @@ RENDER_AGAIN: } } - m_imgui->disabled_begin(! m_enable_hollowing); + m_imgui->disabled_end(); + + m_imgui->disabled_begin(!m_input_enabled || !m_enable_hollowing); + ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("offset")); ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x); @@ -844,7 +867,7 @@ RENDER_AGAIN: mo->config.set("hollowing_min_thickness", m_offset_stash); mo->config.set("hollowing_quality", m_quality_stash); mo->config.set("hollowing_closing_distance", m_closing_d_stash); - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Hollowing parameter change"))); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Hollowing parameter change")); } mo->config.set("hollowing_min_thickness", offset); mo->config.set("hollowing_quality", quality); @@ -867,12 +890,15 @@ RENDER_AGAIN: if (m_new_hole_radius * 2.f > diameter_upper_cap) m_new_hole_radius = diameter_upper_cap / 2.f; ImGui::AlignTextToFramePadding(); + + m_imgui->disabled_begin(!m_input_enabled); + m_imgui->text(m_desc.at("hole_diameter")); ImGui::SameLine(diameter_slider_left, m_imgui->get_item_spacing().x); ImGui::PushItemWidth(window_width - diameter_slider_left); - float diam = 2.f * m_new_hole_radius; m_imgui->slider_float("##hole_diameter", &diam, 1.f, 25.f, "%.1f mm", 1.f, false); + // Let's clamp the value (which could have been entered by keyboard) to a larger range // than the slider. This allows entering off-scale values and still protects against //complete non-sense. @@ -883,9 +909,13 @@ RENDER_AGAIN: bool deactivated = m_imgui->get_last_slider_status().deactivated_after_edit; ImGui::AlignTextToFramePadding(); + m_imgui->text(m_desc["hole_depth"]); ImGui::SameLine(diameter_slider_left, m_imgui->get_item_spacing().x); m_imgui->slider_float("##hole_depth", &m_new_hole_height, 0.f, 10.f, "%.1f mm", 1.f, false); + + m_imgui->disabled_end(); + // Same as above: m_new_hole_height = std::clamp(m_new_hole_height, 0.f, 100.f); @@ -921,24 +951,24 @@ RENDER_AGAIN: break; } } - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Change drainage hole diameter"))); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Change drainage hole diameter")); m_new_hole_radius = backup_rad; m_new_hole_height = backup_hei; mo->sla_drain_holes = new_holes; } } - m_imgui->disabled_begin(m_selection_empty); + m_imgui->disabled_begin(!m_input_enabled || m_selection_empty); remove_selected = m_imgui->button(m_desc.at("remove_selected")); m_imgui->disabled_end(); - m_imgui->disabled_begin(mo->sla_drain_holes.empty()); + m_imgui->disabled_begin(!m_input_enabled || mo->sla_drain_holes.empty()); remove_all = m_imgui->button(m_desc.at("remove_all")); m_imgui->disabled_end(); // Following is rendered in both editing and non-editing mode: - // m_imgui->text(""); ImGui::Separator(); + m_imgui->disabled_begin(!m_input_enabled); if (m_c->object_clipper()->get_position() == 0.f) { ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("clipping_of_view")); @@ -957,6 +987,8 @@ RENDER_AGAIN: if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f")) m_c->object_clipper()->set_position_by_ratio(clp_dist, true); + m_imgui->disabled_end(); + m_imgui->end(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp index e7a324a1e..96f8c6570 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp @@ -81,6 +81,7 @@ private: #endif // ENABLE_RAYCAST_PICKING GLVolumeCollection m_volumes; + bool m_input_enabled{ false }; float m_new_hole_radius = 2.f; // Size of a new hole. float m_new_hole_height = 6.f; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index cc45a8e73..291a8323a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -30,6 +30,8 @@ static const double CONE_HEIGHT = 0.75; namespace Slic3r { namespace GUI { +static const ColorRGBA DISABLED_COLOR = ColorRGBA::DARK_GRAY(); + GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) {} @@ -748,8 +750,7 @@ RENDER_AGAIN: float win_h = ImGui::GetWindowHeight(); y = std::min(y, bottom_limit - win_h); ImGui::SetWindowPos(ImVec2(x, y), ImGuiCond_Always); - if ((last_h != win_h) || (last_y != y)) - { + if (last_h != win_h || last_y != y) { // ask canvas for another frame to render the window in the correct position m_imgui->set_requires_extra_frame(); if (last_h != win_h) @@ -780,6 +781,7 @@ RENDER_AGAIN: if (m_new_point_head_diameter > diameter_upper_cap) m_new_point_head_diameter = diameter_upper_cap; ImGui::AlignTextToFramePadding(); + m_imgui->text(m_desc.at("head_diameter")); ImGui::SameLine(diameter_slider_left); ImGui::PushItemWidth(window_width - diameter_slider_left); @@ -840,6 +842,8 @@ RENDER_AGAIN: } } else { // not in editing mode: + m_imgui->disabled_begin(!m_input_enabled); + ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("minimal_distance")); ImGui::SameLine(settings_sliders_left); @@ -889,7 +893,9 @@ RENDER_AGAIN: if (m_imgui->button(m_desc.at("manual_editing"))) switch_to_editing_mode(); - m_imgui->disabled_begin(m_normal_cache.empty()); + m_imgui->disabled_end(); + + m_imgui->disabled_begin(!m_input_enabled || m_normal_cache.empty()); remove_all = m_imgui->button(m_desc.at("remove_all")); m_imgui->disabled_end(); @@ -902,6 +908,7 @@ RENDER_AGAIN: // Following is rendered in both editing and non-editing mode: + m_imgui->disabled_begin(!m_input_enabled); ImGui::Separator(); if (m_c->object_clipper()->get_position() == 0.f) { ImGui::AlignTextToFramePadding(); @@ -921,7 +928,6 @@ RENDER_AGAIN: if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f")) m_c->object_clipper()->set_position_by_ratio(clp_dist, true); - if (m_imgui->button("?")) { wxGetApp().CallAfter([]() { SlaGizmoHelpDialog help_dlg; @@ -929,6 +935,8 @@ RENDER_AGAIN: }); } + m_imgui->disabled_end(); + m_imgui->end(); if (remove_selected || remove_all) { @@ -1221,7 +1229,9 @@ void GLGizmoSlaSupports::reslice_SLA_supports(bool postpone_error_messages) cons }); } -bool GLGizmoSlaSupports::on_mouse(const wxMouseEvent &mouse_event){ +bool GLGizmoSlaSupports::on_mouse(const wxMouseEvent &mouse_event) +{ + if (!m_input_enabled) return true; if (mouse_event.Moving()) return false; if (!mouse_event.ShiftDown() && !mouse_event.AltDown() && use_grabbers(mouse_event)) return true; @@ -1445,6 +1455,8 @@ void GLGizmoSlaSupports::update_volumes() if (po == nullptr) return; + m_input_enabled = false; + TriangleMesh backend_mesh = po->get_mesh_to_print(); if (!backend_mesh.empty()) { // The backend has generated a valid mesh. Use it @@ -1454,8 +1466,12 @@ void GLGizmoSlaSupports::update_volumes() new_volume->model.init_from(backend_mesh); new_volume->set_instance_transformation(po->model_object()->instances[m_parent.get_selection().get_instance_idx()]->get_transformation()); new_volume->set_sla_shift_z(po->get_current_elevation()); - new_volume->selected = true; // to set the proper color new_volume->mesh_raycaster = std::make_unique(backend_mesh); + m_input_enabled = last_completed_step(*m_c->selection_info()->print_object()->print()) >= slaposDrillHoles; + if (m_input_enabled) + new_volume->selected = true; // to set the proper color + else + new_volume->set_color(DISABLED_COLOR); } if (m_volumes.volumes.empty()) { @@ -1472,7 +1488,7 @@ void GLGizmoSlaSupports::update_volumes() new_volume->set_instance_transformation(v->get_instance_transformation()); new_volume->set_volume_transformation(v->get_volume_transformation()); new_volume->set_sla_shift_z(v->get_sla_shift_z()); - new_volume->selected = true; // to set the proper color + new_volume->set_color(DISABLED_COLOR); new_volume->mesh_raycaster = std::make_unique(mesh); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 6729d6eda..bc5eede66 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -127,6 +127,7 @@ private: #endif // ENABLE_RAYCAST_PICKING GLVolumeCollection m_volumes; + bool m_input_enabled{ false }; // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. @@ -161,8 +162,7 @@ private: protected: void on_set_state() override; - void on_set_hover_id() override - { + void on_set_hover_id() override { if (! m_editing_mode || (int)m_editing_cache.size() <= m_hover_id) m_hover_id = -1; }