From 07608a80cdeed4a99669f0ac291855ecf647f7d9 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Mon, 29 Jul 2019 15:08:59 +0200
Subject: [PATCH] SLA gizmo - making sure the cone direction is correctly
 undone/redone

---
 src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 50 +++++++++-----------
 src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp |  6 +--
 2 files changed, 25 insertions(+), 31 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
index 1daa57614..267c4f899 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
@@ -64,7 +64,7 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S
         return;
     }
 
-    if (m_model_object != model_object) {
+    if (m_model_object != model_object || m_model_object_id != model_object->id()) {
         m_model_object = model_object;
         m_print_object_idx = -1;
     }
@@ -105,7 +105,8 @@ void GLGizmoSlaSupports::on_render() const
     // If current m_model_object does not match selection, ask GLCanvas3D to turn us off
     if (m_state == On
      && (m_model_object != selection.get_model()->objects[selection.get_object_idx()]
-      || m_active_instance != selection.get_instance_idx())) {
+      || m_active_instance != selection.get_instance_idx()
+      || m_model_object_id != m_model_object->id())) {
         m_parent.post_event(SimpleEvent(EVT_GLCANVAS_RESETGIZMOS));
         return;
     }
@@ -390,7 +391,7 @@ bool GLGizmoSlaSupports::is_point_clipped(const Vec3d& point) const
 bool GLGizmoSlaSupports::is_mesh_update_necessary() const
 {
     return ((m_state == On) && (m_model_object != nullptr) && !m_model_object->instances.empty())
-        && ((m_model_object->id() != m_current_mesh_object_id) || m_its == nullptr);
+        && ((m_model_object->id() != m_model_object_id) || m_its == nullptr);
 }
 
 
@@ -407,7 +408,7 @@ void GLGizmoSlaSupports::update_mesh()
     m_its = &m_mesh->its;
 
     // If this is different mesh than last time or if the AABB tree is uninitialized, recalculate it.
-    if (m_current_mesh_object_id != m_model_object->id() || (m_AABB.m_left == NULL && m_AABB.m_right == NULL))
+    if (m_model_object_id != m_model_object->id() || (m_AABB.m_left == NULL && m_AABB.m_right == NULL))
     {
         m_AABB.deinit();
         m_AABB.init(
@@ -415,7 +416,7 @@ void GLGizmoSlaSupports::update_mesh()
             MapMatrixXiUnaligned(m_its->indices.front().data(), m_its->indices.size(), 3));
     }
 
-    m_current_mesh_object_id = m_model_object->id();
+    m_model_object_id = m_model_object->id();
     disable_editing_mode();
 }
 
@@ -1080,25 +1081,14 @@ void GLGizmoSlaSupports::on_set_state()
 {
     // m_model_object pointer can be invalid (for instance because of undo/redo action),
     // we should recover it from the object id
-    const ModelObject* old_model_object = m_model_object;
     m_model_object = nullptr;
     for (const auto mo : wxGetApp().model().objects) {
-        if (mo->id() == m_current_mesh_object_id) {
+        if (mo->id() == m_model_object_id) {
             m_model_object = mo;
             break;
         }
     }
 
-
-    // If ModelObject pointer really changed, invalidate mesh and do everything
-    // as if the gizmo was switched from Off state
-    /*if (m_model_object == nullptr || old_model_object != m_model_object) {
-        m_mesh = nullptr;
-        m_its = nullptr;
-        if (m_state == On)
-            m_old_state = Off;
-    }*/
-
     if (m_state == On && m_old_state != On) { // the gizmo was just turned on
         if (is_mesh_update_necessary())
             update_mesh();
@@ -1150,23 +1140,27 @@ void GLGizmoSlaSupports::on_start_dragging()
     if (m_hover_id != -1) {
         select_point(NoPoints);
         select_point(m_hover_id);
-        m_dragged_point_initial_pos = m_editing_cache[m_hover_id].support_point.pos;
+        m_point_before_drag = m_editing_cache[m_hover_id];
     }
+    else
+        m_point_before_drag = CacheEntry();
 }
 
 
 void GLGizmoSlaSupports::on_stop_dragging()
 {
-    Vec3f backup = m_editing_cache[m_hover_id].support_point.pos;
+    if (m_hover_id != -1) {
+        CacheEntry backup = m_editing_cache[m_hover_id];
 
-    if (backup != Vec3f::Zero() // some point was touched
-     && backup != m_dragged_point_initial_pos) // and it was moved, not just selected
-    {
-        m_editing_cache[m_hover_id].support_point.pos = m_dragged_point_initial_pos;
-        wxGetApp().plater()->take_snapshot(_(L("Move support point")));
-        m_editing_cache[m_hover_id].support_point.pos = backup;
-        m_dragged_point_initial_pos = Vec3f::Zero();
+        if (m_point_before_drag.support_point.pos != Vec3f::Zero() // some point was touched
+         && 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")));
+            m_editing_cache[m_hover_id] = backup;
+        }
     }
+    m_point_before_drag = CacheEntry();
 }
 
 
@@ -1175,7 +1169,7 @@ void GLGizmoSlaSupports::on_load(cereal::BinaryInputArchive& ar)
 {
     ar(m_clipping_plane_distance,
        m_clipping_plane_normal,
-       m_current_mesh_object_id,
+       m_model_object_id,
        m_new_point_head_diameter,
        m_normal_cache,
        m_editing_cache
@@ -1188,7 +1182,7 @@ void GLGizmoSlaSupports::on_save(cereal::BinaryOutputArchive& ar) const
 {
     ar(m_clipping_plane_distance,
        m_clipping_plane_normal,
-       m_current_mesh_object_id,
+       m_model_object_id,
        m_new_point_head_diameter,
        m_normal_cache,
        m_editing_cache
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
index 889ddf064..99184a90d 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
@@ -28,7 +28,7 @@ class GLGizmoSlaSupports : public GLGizmoBase
 {
 private:
     ModelObject* m_model_object = nullptr;
-    ObjectID m_current_mesh_object_id = 0;
+    ObjectID m_model_object_id = 0;
     int m_active_instance = -1;
     float m_active_instance_bb_radius; // to cache the bb
     mutable float m_z_shift = 0.f;
@@ -105,8 +105,8 @@ private:
     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).
     float m_new_point_head_diameter;        // Size of a new point.
-    Vec3f m_dragged_point_initial_pos = Vec3f::Zero(); //undo/redo
-    float m_old_point_head_diameter = 0.f; // undo/redo
+    CacheEntry m_point_before_drag;         // undo/redo - so we know what state was edited
+    float m_old_point_head_diameter = 0.;   // the same
     float m_minimal_point_distance = 20.f;
     mutable std::vector<CacheEntry> m_editing_cache; // a support point and whether it is currently selected
     std::vector<sla::SupportPoint> m_normal_cache; // to restore after discarding changes or undo/redo