From 24b9c926c676f9caecbf11dad3d174cfebd1918b Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 22 Aug 2019 16:58:51 +0200 Subject: [PATCH 1/6] GLGizmoManager.cpp: Initial work on the possibility of a gizmo refusing to close --- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 61 ++++++++++++++++------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 38af63464..99a2f229f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -1065,34 +1065,57 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) float scaled_stride_y = scaled_icons_size + scaled_gap_y; float top_y = 0.5f * (cnv_h - height) + scaled_border; - for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + auto inside = [scaled_border, scaled_icons_size, &mouse_pos](float top_y) { + return (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); + }; + + bool could_activate = true; + for (std::pair &type_and_gizmo : m_gizmos) { - if ((it->second == nullptr) || !it->second->is_selectable()) + GLGizmoBase *gizmo = type_and_gizmo.second; + if ((gizmo == nullptr) || !gizmo->is_selectable()) continue; - bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); - if (it->second->is_activable() && inside) - { - if ((it->second->get_state() == GLGizmoBase::On)) - { - it->second->set_state(GLGizmoBase::Hover); - m_current = Undefined; - } - else if ((it->second->get_state() == GLGizmoBase::Hover)) - { - it->second->set_state(GLGizmoBase::On); - m_current = it->first; + if (! (gizmo->is_activable() && inside(top_y))) { + gizmo->set_state(GLGizmoBase::Off); + if (gizmo->get_state() != GLGizmoBase::Off) { + // Gizmo refused to leave it's active state. Don't try to select + could_activate = false; } } - else - it->second->set_state(GLGizmoBase::Off); top_y += scaled_stride_y; } - GizmosMap::iterator it = m_gizmos.find(m_current); - if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) - it->second->set_state(GLGizmoBase::On); + top_y = 0.5f * (cnv_h - height) + scaled_border; + for (std::pair &type_and_gizmo : m_gizmos) + { + GLGizmoBase *gizmo = type_and_gizmo.second; + if ((gizmo == nullptr) || !gizmo->is_selectable()) + continue; + + if (gizmo->is_activable() && inside(top_y)) + { + if ((gizmo->get_state() == GLGizmoBase::On)) + { + gizmo->set_state(GLGizmoBase::Hover); + m_current = Undefined; + } + else if ((gizmo->get_state() == GLGizmoBase::Hover) && could_activate) + { + gizmo->set_state(GLGizmoBase::On); + m_current = type_and_gizmo.first; + } + } + + top_y += scaled_stride_y; + } + + if (could_activate) { + GizmosMap::iterator it = m_gizmos.find(m_current); + if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) + it->second->set_state(GLGizmoBase::On); + } } std::string GLGizmosManager::update_hover_state(const Vec2d& mouse_pos) From c736b657d402ccbad9a602e54f6a4a71b544758c Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 23 Aug 2019 01:08:14 +0200 Subject: [PATCH 2/6] SLA gizmo now refuses to close with unsaved changes in editing mode --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 24 +++++++------ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 38 +++++++++++++------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 4976520fa..32a43e78c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -1127,19 +1127,23 @@ void GLGizmoSlaSupports::on_set_state() m_new_point_head_diameter = static_cast(cfg.option("support_head_front_diameter"))->value; } if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off - wxGetApp().CallAfter([this]() { - // Following is called through CallAfter, because otherwise there was a problem - // on OSX with the wxMessageDialog being shown several times when clicked into. - if (m_model_object) { - if (m_editing_mode && unsaved_changes()) { - wxMessageDialog dlg(GUI::wxGetApp().mainframe, _(L("Do you want to save your manually edited support points?")) + "\n", - _(L("Save changes?")), wxICON_QUESTION | wxYES | wxNO); + bool will_ask = m_model_object && m_editing_mode && unsaved_changes(); + if (will_ask) { + wxGetApp().CallAfter([this]() { + // Following is called through CallAfter, because otherwise there was a problem + // on OSX with the wxMessageDialog being shown several times when clicked into. + wxMessageDialog dlg(GUI::wxGetApp().mainframe, _(L("Do you want to save your manually " + "edited support points?")) + "\n",_(L("Save changes?")), wxICON_QUESTION | wxYES | wxNO); if (dlg.ShowModal() == wxID_YES) editing_mode_apply_changes(); else editing_mode_discard_changes(); - } - } + }); + // refuse to be turned off so the gizmo is active when the CallAfter is executed + m_state = m_old_state; + } + else { + // we are actually shutting down m_parent.toggle_model_objects_visibility(true); disable_editing_mode(); // so it is not active next time the gizmo opens m_normal_cache.clear(); @@ -1149,7 +1153,7 @@ void GLGizmoSlaSupports::on_set_state() m_its = nullptr; m_tms.reset(); m_supports_tms.reset(); - }); + } } m_old_state = m_state; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 99a2f229f..bd176b231 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -280,8 +280,8 @@ bool GLGizmosManager::handle_shortcut(int key) if (m_parent.get_selection().is_empty()) return false; - EType old_current = m_current; bool handled = false; + for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second == nullptr) || !it->second->is_selectable()) @@ -294,25 +294,34 @@ bool GLGizmosManager::handle_shortcut(int key) if ((it->second->get_state() == GLGizmoBase::On)) { it->second->set_state(GLGizmoBase::Off); - m_current = Undefined; + if (it->second->get_state() == GLGizmoBase::Off) { + m_current = Undefined; + } handled = true; } else if ((it->second->get_state() == GLGizmoBase::Off)) { - it->second->set_state(GLGizmoBase::On); - m_current = it->first; + // Before turning anything on, turn everything else off to see if + // nobody refuses. Only then activate the gizmo. + bool can_open = true; + for (GizmosMap::iterator i = m_gizmos.begin(); i != m_gizmos.end(); ++i) { + if (i->first != it->first) { + if (m_current == i->first && i->second->get_state() != GLGizmoBase::Off ) { + i->second->set_state(GLGizmoBase::Off); + if (i->second->get_state() != GLGizmoBase::Off) + can_open = false; + } + } + } + if (can_open) { + it->second->set_state(GLGizmoBase::On); + m_current = it->first; + } handled = true; } } } - if (handled && (old_current != Undefined) && (old_current != m_current)) - { - GizmosMap::const_iterator it = m_gizmos.find(old_current); - if (it != m_gizmos.end()) - it->second->set_state(GLGizmoBase::Off); - } - return handled; } @@ -1098,8 +1107,11 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) { if ((gizmo->get_state() == GLGizmoBase::On)) { - gizmo->set_state(GLGizmoBase::Hover); - m_current = Undefined; + gizmo->set_state(GLGizmoBase::Off); + if (gizmo->get_state() == GLGizmoBase::Off) { + gizmo->set_state(GLGizmoBase::Hover); + m_current = Undefined; + } } else if ((gizmo->get_state() == GLGizmoBase::Hover) && could_activate) { From b55a140ad41ab0b317c99d7b0996724c687dffbd Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 23 Aug 2019 01:36:56 +0200 Subject: [PATCH 3/6] SLA gizmo takes snapshots on opening and closing --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 7 ++++++- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 2 ++ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 9 +++++++-- src/slic3r/GUI/Plater.cpp | 3 +++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 32a43e78c..8236410bd 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -1100,6 +1100,9 @@ std::string GLGizmoSlaSupports::on_get_name() const void GLGizmoSlaSupports::on_set_state() { + if (m_state == Hover) + return; + // m_model_object pointer can be invalid (for instance because of undo/redo action), // we should recover it from the object id m_model_object = nullptr; @@ -1111,6 +1114,7 @@ void GLGizmoSlaSupports::on_set_state() } if (m_state == On && m_old_state != On) { // the gizmo was just turned on + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned on"))); if (is_mesh_update_necessary()) update_mesh(); @@ -1144,8 +1148,9 @@ void GLGizmoSlaSupports::on_set_state() } else { // we are actually shutting down - m_parent.toggle_model_objects_visibility(true); disable_editing_mode(); // so it is not active next time the gizmo opens + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned off"))); + m_parent.toggle_model_objects_visibility(true); m_normal_cache.clear(); m_clipping_plane_distance = 0.f; // Release triangle mesh slicer and the AABB spatial search structure. diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index fa3facf4b..2f6e9ccf3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -101,6 +101,8 @@ private: void update_cache_entry_normal(unsigned int i) const; bool unsaved_changes() const; + EState m_no_hover_state = Off; + EState m_no_hover_old_state = Off; bool m_lock_unique_islands = false; bool m_editing_mode = false; // Is editing mode active? bool m_old_editing_state = false; // To keep track of whether the user toggled between the modes (needed for imgui refreshes). diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index bd176b231..236a0a27c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -1096,6 +1096,10 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) top_y += scaled_stride_y; } + // We may change m_current soon. If we did it during following loop, gizmos that take undo/redo snapshots + // in their on_set_state function could snapshot a state with the new gizmo already active. + // Therefore, just remember what needs to be done and actually change m_current afterwards. + EType new_current = m_current; top_y = 0.5f * (cnv_h - height) + scaled_border; for (std::pair &type_and_gizmo : m_gizmos) { @@ -1110,18 +1114,19 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) gizmo->set_state(GLGizmoBase::Off); if (gizmo->get_state() == GLGizmoBase::Off) { gizmo->set_state(GLGizmoBase::Hover); - m_current = Undefined; + new_current = Undefined; } } else if ((gizmo->get_state() == GLGizmoBase::Hover) && could_activate) { gizmo->set_state(GLGizmoBase::On); - m_current = type_and_gizmo.first; + new_current = type_and_gizmo.first; } } top_y += scaled_stride_y; } + m_current = new_current; if (could_activate) { GizmosMap::iterator it = m_gizmos.find(m_current); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index bb6c1e2f6..3e733aef5 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3863,6 +3863,9 @@ void Plater::priv::undo_redo_to(size_t time_to_load) void Plater::priv::undo_redo_to(std::vector::const_iterator it_snapshot) { + // Make sure that no updating function calls take_snapshot until we are done. + SuppressSnapshots snapshot_supressor(q); + bool temp_snapshot_was_taken = this->undo_redo_stack().temp_snapshot_active(); PrinterTechnology new_printer_technology = it_snapshot->snapshot_data.printer_technology; bool printer_technology_changed = this->printer_technology != new_printer_technology; From 52933d1babc1b1f6f8c5a771bfa5daebf63c9b3d Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 22 Aug 2019 16:44:49 +0200 Subject: [PATCH 4/6] Recalculate SLA supports after undo/redo in case SLA gizmo was active and had supports when the snapshot was taken --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 47 +++++++++++++++----- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 4 ++ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 11 ++++- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 8 +++- src/slic3r/GUI/Plater.cpp | 19 ++++++-- src/slic3r/Utils/UndoRedo.hpp | 1 + 6 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 8236410bd..9aa46f1e7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -528,7 +528,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous if (m_selection_empty) { std::pair pos_and_normal; if (unproject_on_mesh(mouse_position, pos_and_normal)) { // we got an intersection - wxGetApp().plater()->take_snapshot(_(L("Add support point"))); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Add support point"))); m_editing_cache.emplace_back(sla::SupportPoint(pos_and_normal.first, m_new_point_head_diameter/2.f, false), false, pos_and_normal.second); m_parent.set_as_dirty(); m_wait_for_up_event = true; @@ -716,14 +716,12 @@ void GLGizmoSlaSupports::delete_selected_points(bool force) std::abort(); } - wxGetApp().plater()->take_snapshot(_(L("Delete support point"))); + Plater::TakeSnapshot(wxGetApp().plater(), _(L("Delete support point"))); for (unsigned int idx=0; idxreslice_SLA_supports(*m_model_object); } select_point(NoPoints); @@ -919,7 +917,7 @@ RENDER_AGAIN: cache_entry.support_point.head_front_radius = m_old_point_head_diameter / 2.f; float backup = m_new_point_head_diameter; m_new_point_head_diameter = m_old_point_head_diameter; - wxGetApp().plater()->take_snapshot(_(L("Change point head diameter"))); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Change point head diameter"))); m_new_point_head_diameter = backup; for (auto& cache_entry : m_editing_cache) if (cache_entry.selected) @@ -985,7 +983,7 @@ RENDER_AGAIN: if (slider_released) { m_model_object->config.opt("support_points_minimal_distance", true)->value = m_minimal_point_distance_stash; m_model_object->config.opt("support_points_density_relative", true)->value = (int)m_density_stash; - wxGetApp().plater()->take_snapshot(_(L("Support parameter change"))); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Support parameter change"))); m_model_object->config.opt("support_points_minimal_distance", true)->value = minimal_point_distance; m_model_object->config.opt("support_points_density_relative", true)->value = (int)density; wxGetApp().obj_list()->update_and_show_object_settings_item(); @@ -1186,7 +1184,7 @@ void GLGizmoSlaSupports::on_stop_dragging() && backup.support_point.pos != m_point_before_drag.support_point.pos) // and it was moved, not just selected { m_editing_cache[m_hover_id] = m_point_before_drag; - wxGetApp().plater()->take_snapshot(_(L("Move support point"))); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Move support point"))); m_editing_cache[m_hover_id] = backup; } } @@ -1285,7 +1283,7 @@ void GLGizmoSlaSupports::editing_mode_apply_changes() disable_editing_mode(); // this leaves the editing mode undo/redo stack and must be done before the snapshot is taken if (unsaved_changes()) { - wxGetApp().plater()->take_snapshot(_(L("Support points edit"))); + take_snapshot_internal(_(L("Support points edit"))); m_normal_cache.clear(); for (const CacheEntry& ce : m_editing_cache) @@ -1295,7 +1293,7 @@ void GLGizmoSlaSupports::editing_mode_apply_changes() m_model_object->sla_support_points.clear(); m_model_object->sla_support_points = m_normal_cache; - wxGetApp().CallAfter([this]() { wxGetApp().plater()->reslice_SLA_supports(*m_model_object); }); + reslice_SLA_supports(); } } @@ -1312,11 +1310,29 @@ void GLGizmoSlaSupports::reload_cache() } +bool GLGizmoSlaSupports::has_backend_supports() const +{ + // find SlaPrintObject with this ID + for (const SLAPrintObject* po : m_parent.sla_print()->objects()) { + if (po->model_object()->id() == m_model_object->id() && po->is_step_done(slaposSupportPoints)) + return true; + } + return false; +} + +void GLGizmoSlaSupports::reslice_SLA_supports() const +{ + wxGetApp().CallAfter([this]() { wxGetApp().plater()->reslice_SLA_supports(*m_model_object); }); +} void GLGizmoSlaSupports::get_data_from_backend() { + if (! has_backend_supports()) + return; + + // find the respective SLAPrintObject, we need a pointer to it for (const SLAPrintObject* po : m_parent.sla_print()->objects()) { - if (po->model_object()->id() == m_model_object->id() && po->is_step_done(slaposSupportPoints)) { + if (po->model_object()->id() == m_model_object->id()) { m_normal_cache.clear(); const std::vector& points = po->get_support_points(); auto mat = po->trafo().inverse().cast(); @@ -1331,6 +1347,13 @@ void GLGizmoSlaSupports::get_data_from_backend() // We don't copy the data into ModelObject, as this would stop the background processing. } +void GLGizmoSlaSupports::take_snapshot_internal(const wxString& desc) +{ + m_internal_snapshot = true; + Plater::TakeSnapshot snapshot(wxGetApp().plater(), desc); + m_internal_snapshot = false; +} + void GLGizmoSlaSupports::auto_generate() @@ -1341,8 +1364,8 @@ void GLGizmoSlaSupports::auto_generate() )), _(L("Warning")), wxICON_WARNING | wxYES | wxNO); if (m_model_object->sla_points_status != sla::PointsStatus::UserModified || m_normal_cache.empty() || dlg.ShowModal() == wxID_YES) { - wxGetApp().plater()->take_snapshot(_(L("Autogenerate support points"))); - wxGetApp().CallAfter([this]() { wxGetApp().plater()->reslice_SLA_supports(*m_model_object); }); + take_snapshot_internal(_(L("Autogenerate support points"))); + wxGetApp().CallAfter([this]() { reslice_SLA_supports(); }); m_model_object->sla_points_status = sla::PointsStatus::Generating; } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 2f6e9ccf3..a184582c4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -86,6 +86,8 @@ public: bool is_in_editing_mode() const { return m_editing_mode; } bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); } + bool has_backend_supports() const; + void reslice_SLA_supports() const; private: bool on_init(); @@ -100,6 +102,7 @@ private: void update_mesh(); void update_cache_entry_normal(unsigned int i) const; bool unsaved_changes() const; + void take_snapshot_internal(const wxString& desc); EState m_no_hover_state = Off; EState m_no_hover_old_state = Off; @@ -128,6 +131,7 @@ private: bool m_wait_for_up_event = false; bool m_selection_empty = true; EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state) + bool m_internal_snapshot = false; mutable std::unique_ptr m_tms; mutable std::unique_ptr m_supports_tms; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 236a0a27c..c21af45f0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -5,6 +5,7 @@ #include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_ObjectManipulation.hpp" #include "slic3r/GUI/PresetBundle.hpp" +#include "slic3r/Utils/UndoRedo.hpp" #include #include @@ -464,6 +465,11 @@ ClippingPlane GLGizmosManager::get_sla_clipping_plane() const return ClippingPlane::ClipsNothing(); } +bool GLGizmosManager::wants_reslice_supports_on_undo() const +{ + return (m_current == SlaSupports + && dynamic_cast(m_gizmos.at(SlaSupports))->has_backend_supports()); +} void GLGizmosManager::render_current_gizmo() const { @@ -870,10 +876,13 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt) return processed; } -void GLGizmosManager::update_after_undo_redo() +void GLGizmosManager::update_after_undo_redo(const UndoRedo::Snapshot& snapshot) { update_data(); m_serializing = false; + if (m_current == SlaSupports + && snapshot.snapshot_data.flags & UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS) + dynamic_cast(m_gizmos[SlaSupports])->reslice_SLA_supports(); } void GLGizmosManager::reset() diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index b1c000ceb..8b744c74f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -9,6 +9,11 @@ #include namespace Slic3r { + +namespace UndoRedo { +class Snapshot; +} + namespace GUI { class GLCanvas3D; @@ -173,6 +178,7 @@ public: void set_sla_support_data(ModelObject* model_object); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false); ClippingPlane get_sla_clipping_plane() const; + bool wants_reslice_supports_on_undo() const; void render_current_gizmo() const; void render_current_gizmo_for_picking_pass() const; @@ -186,7 +192,7 @@ public: bool on_char(wxKeyEvent& evt); bool on_key(wxKeyEvent& evt); - void update_after_undo_redo(); + void update_after_undo_redo(const UndoRedo::Snapshot& snapshot); private: void reset(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3e733aef5..6f7adc01b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1908,7 +1908,7 @@ private: void update_fff_scene(); void update_sla_scene(); void undo_redo_to(std::vector::const_iterator it_snapshot); - void update_after_undo_redo(bool temp_snapshot_was_taken = false); + void update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool temp_snapshot_was_taken = false); // path to project file stored with no extension wxString m_project_filename; @@ -3823,6 +3823,12 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name) } else if (this->sidebar->obj_list()->is_selected(itLayerRoot)) snapshot_data.flags |= UndoRedo::SnapshotData::SELECTED_LAYERROOT_ON_SIDEBAR; + + // If SLA gizmo is active, ask it if it wants to trigger support generation + // on loading this snapshot. + if (view3D->get_canvas3d()->get_gizmos_manager().wants_reslice_supports_on_undo()) + snapshot_data.flags |= UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS; + //FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config. // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config. if (this->printer_technology == ptFFF) { @@ -3908,9 +3914,14 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator bool new_selected_layer_on_sidebar = (new_flags & UndoRedo::SnapshotData::SELECTED_LAYER_ON_SIDEBAR) != 0; bool new_selected_layerroot_on_sidebar = (new_flags & UndoRedo::SnapshotData::SELECTED_LAYERROOT_ON_SIDEBAR) != 0; + if (this->view3D->get_canvas3d()->get_gizmos_manager().wants_reslice_supports_on_undo()) + top_snapshot_data.flags |= UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS; + // Disable layer editing before the Undo / Redo jump. if (!new_variable_layer_editing_active && view3D->is_layers_editing_enabled()) view3D->get_canvas3d()->force_main_toolbar_left_action(view3D->get_canvas3d()->get_main_toolbar_item_id("layersediting")); + // Make a copy of the snapshot, undo/redo could invalidate the iterator + const UndoRedo::Snapshot snapshot_copy = *it_snapshot; // Do the jump in time. if (it_snapshot->timestamp < this->undo_redo_stack().active_snapshot_time() ? this->undo_redo_stack().undo(model, this->view3D->get_canvas3d()->get_selection(), this->view3D->get_canvas3d()->get_gizmos_manager(), top_snapshot_data, it_snapshot->timestamp) : @@ -3948,14 +3959,14 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator if (new_selected_settings_on_sidebar || new_selected_layer_on_sidebar) this->sidebar->obj_list()->set_selected_layers_range_idx(layer_range_idx); - this->update_after_undo_redo(temp_snapshot_was_taken); + this->update_after_undo_redo(snapshot_copy, temp_snapshot_was_taken); // Enable layer editing after the Undo / Redo jump. if (! view3D->is_layers_editing_enabled() && this->layers_height_allowed() && new_variable_layer_editing_active) view3D->get_canvas3d()->force_main_toolbar_left_action(view3D->get_canvas3d()->get_main_toolbar_item_id("layersediting")); } } -void Plater::priv::update_after_undo_redo(bool /* temp_snapshot_was_taken */) +void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool /* temp_snapshot_was_taken */) { this->view3D->get_canvas3d()->get_selection().clear(); // Update volumes from the deserializd model, always stop / update the background processing (for both the SLA and FFF technologies). @@ -3967,7 +3978,7 @@ void Plater::priv::update_after_undo_redo(bool /* temp_snapshot_was_taken */) this->undo_redo_stack().release_least_recently_used(); //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time) this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances); - this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(); + this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot); wxGetApp().obj_list()->update_after_undo_redo(); diff --git a/src/slic3r/Utils/UndoRedo.hpp b/src/slic3r/Utils/UndoRedo.hpp index 558449003..2901eaceb 100644 --- a/src/slic3r/Utils/UndoRedo.hpp +++ b/src/slic3r/Utils/UndoRedo.hpp @@ -45,6 +45,7 @@ struct SnapshotData SELECTED_SETTINGS_ON_SIDEBAR = 2, SELECTED_LAYERROOT_ON_SIDEBAR = 4, SELECTED_LAYER_ON_SIDEBAR = 8, + RECALCULATE_SLA_SUPPORTS = 16 }; }; From bf232e1ade20ebf0a9bb7b0eb9f476933871c564 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 23 Aug 2019 10:34:16 +0200 Subject: [PATCH 5/6] Fixed forward declaration of struct Slic3r::UndoRedo::Snapshot so MSVC does not complain --- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 8b744c74f..c0adeb957 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -11,7 +11,7 @@ namespace Slic3r { namespace UndoRedo { -class Snapshot; +struct Snapshot; } namespace GUI { From 1d8e060b75d3370b513c4cb18dfc5dddb161bd81 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 23 Aug 2019 12:11:45 +0200 Subject: [PATCH 6/6] Followup of previous commits - removing some unnecessary code --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 13 +++---------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 2 -- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 9aa46f1e7..69d57857b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -716,7 +716,7 @@ void GLGizmoSlaSupports::delete_selected_points(bool force) std::abort(); } - Plater::TakeSnapshot(wxGetApp().plater(), _(L("Delete support point"))); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Delete support point"))); for (unsigned int idx=0; idxsla_points_status != sla::PointsStatus::UserModified || m_normal_cache.empty() || dlg.ShowModal() == wxID_YES) { - take_snapshot_internal(_(L("Autogenerate support points"))); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Autogenerate support points"))); wxGetApp().CallAfter([this]() { reslice_SLA_supports(); }); m_model_object->sla_points_status = sla::PointsStatus::Generating; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index a184582c4..e331cef53 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -102,7 +102,6 @@ private: void update_mesh(); void update_cache_entry_normal(unsigned int i) const; bool unsaved_changes() const; - void take_snapshot_internal(const wxString& desc); EState m_no_hover_state = Off; EState m_no_hover_old_state = Off; @@ -131,7 +130,6 @@ private: bool m_wait_for_up_event = false; bool m_selection_empty = true; EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state) - bool m_internal_snapshot = false; mutable std::unique_ptr m_tms; mutable std::unique_ptr m_supports_tms;