From 8475968025ebf0dc9c661d557f7fe90ac852cee9 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Wed, 25 Mar 2020 09:09:02 +0100
Subject: [PATCH 01/15] First installation of common gizmo data pool

---
 src/slic3r/CMakeLists.txt                |   2 +
 src/slic3r/GUI/Gizmos/GLGizmoBase.hpp    |   3 +
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp |  53 +++++++
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 191 +++++++++++++++++++++++
 4 files changed, 249 insertions(+)
 create mode 100644 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
 create mode 100644 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp

diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index c8f7e9f1c..f13c6084b 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -34,6 +34,8 @@ set(SLIC3R_GUI_SOURCES
     GUI/Gizmos/GLGizmos.hpp
     GUI/Gizmos/GLGizmosManager.cpp
     GUI/Gizmos/GLGizmosManager.hpp
+    GUI/Gizmos/GLGizmosCommon.cpp
+    GUI/Gizmos/GLGizmosCommon.hpp
     GUI/Gizmos/GLGizmoBase.cpp
     GUI/Gizmos/GLGizmoBase.hpp
     GUI/Gizmos/GLGizmoMove.cpp
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
index 0d19a86af..965f195a9 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
@@ -32,6 +32,7 @@ static const float CONSTRAINED_COLOR[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
 class ImGuiWrapper;
 class GLCanvas3D;
 class ClippingPlane;
+enum class CommonGizmosDataID;
 
 class GLGizmoBase
 {
@@ -128,6 +129,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(); }
 
     unsigned int get_sprite_id() const { return m_sprite_id; }
 
@@ -161,6 +163,7 @@ protected:
     virtual void on_set_hover_id() {}
     virtual bool on_is_activable() const { return true; }
     virtual bool on_is_selectable() const { return true; }
+    virtual CommonGizmosDataID on_get_requirements() const { return CommonGizmosDataID(0); }
     virtual void on_enable_grabber(unsigned int id) {}
     virtual void on_disable_grabber(unsigned int id) {}
     virtual void on_start_dragging() {}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
new file mode 100644
index 000000000..89a671519
--- /dev/null
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -0,0 +1,53 @@
+#include "GLGizmosCommon.hpp"
+
+#include <cassert>
+
+#include "slic3r/GUI/GLCanvas3D.hpp"
+
+namespace Slic3r {
+namespace GUI {
+
+
+CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
+    : m_canvas(canvas)
+{
+    using namespace CommonGizmosDataObjects;
+    using c = CommonGizmosDataID;
+    m_data[c::SelectionInfo].reset(       new SelectionInfo(this));
+    m_data[c::InstancesHider].reset(      new InstancesHider(this));
+    m_data[c::HollowedMesh].reset(        new HollowedMesh(this));
+    m_data[c::ClippingPlaneWrapper].reset(new ClippingPlaneWrapper(this));
+    m_data[c::SupportsClipper].reset(     new SupportsClipper(this));
+    m_data[c::MeshRaycaster].reset(       new Raycaster(this));
+}
+
+void CommonGizmosDataPool::update(CommonGizmosDataID required)
+{
+    assert(check_dependencies(required));
+    for (auto& [id, data] : m_data)
+        data->update(int(required) & int(CommonGizmosDataID(id)));
+}
+
+#ifndef NDEBUG
+bool CommonGizmosDataPool::check_dependencies(CommonGizmosDataID required) const
+{
+    // This should iterate over currently required data. Each of them should
+    // be asked about its dependencies and it must check that all dependencies
+    // are also in required and before the current one.
+    return true;
+}
+#endif // NDEBUG
+
+
+
+
+void CommonGizmosDataObjects::SelectionInfo::update(bool required)
+{
+    Selection selection = m_common->get_canvas()->get_selection();
+
+}
+
+
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
new file mode 100644
index 000000000..6d83179cb
--- /dev/null
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -0,0 +1,191 @@
+#ifndef slic3r_GUI_GLGizmosCommon_hpp_
+#define slic3r_GUI_GLGizmosCommon_hpp_
+
+#include <memory>
+#include <map>
+
+namespace Slic3r {
+
+class ModelObject;
+
+
+namespace GUI {
+
+class GLCanvas3D;
+
+class CommonGizmosDataBase;
+namespace CommonGizmosDataObjects {
+    class SelectionInfo;
+}
+
+// Some of the gizmos use the same data that need to be updated ocassionally.
+// It is also desirable that the data are not recalculated when the gizmos
+// are just switched, but on the other hand, they should be released when
+// they are not in use by any gizmo anymore.
+
+// Enumeration of various data types that the data pool can contain.
+// Each gizmo can tell which of the data it wants to use through
+// on_get_requirements() method.
+enum class CommonGizmosDataID {
+    None                 = 0,
+    SelectionInfo        = 1 << 0,
+    InstancesHider       = 1 << 1,
+    HollowedMesh         = 1 << 2,
+    ClippingPlaneWrapper = 1 << 3,
+    SupportsClipper      = 1 << 4,
+    MeshRaycaster        = 1 << 5,
+};
+
+
+// Following class holds pointers to the common data objects and triggers
+// their updating/releasing. There is just one object of this type (managed
+// by GLGizmoManager, the gizmos keep a pointer to it.
+class CommonGizmosDataPool {
+public:
+    CommonGizmosDataPool(GLCanvas3D* canvas);
+
+    // Update all resources and release what is not used.
+    // Accepts a bitmask of currently required resources.
+    void update(CommonGizmosDataID required = CommonGizmosDataID::None);
+
+    // Getters for the data that need to be accessed from the gizmos directly.
+    CommonGizmosDataObjects::SelectionInfo selection_info();
+
+    GLCanvas3D* get_canvas() const { return m_canvas; }
+
+private:
+    std::map<CommonGizmosDataID, std::unique_ptr<CommonGizmosDataBase>> m_data;
+    GLCanvas3D* m_canvas;
+
+#ifndef NDEBUG
+    bool check_dependencies(CommonGizmosDataID required) const;
+#endif
+};
+
+
+
+
+
+// Base class for a wrapper object managing a single resource.
+// Each of the enum values above (safe None) will have an object of this kind.
+class CommonGizmosDataBase {
+public:
+    // Pass a backpointer to the pool, so the individual
+    // objects can communicate with one another.
+    explicit CommonGizmosDataBase(CommonGizmosDataPool* cgdp)
+        : m_common{cgdp} {}
+
+    // Update the resource. If it is not needed (based on argument value)
+    // any persistent data will be released.
+    virtual void update(bool required) = 0;
+
+    // Returns whether the resource is currently maintained.
+    bool is_valid() const { return m_is_valid; }
+
+protected:
+    CommonGizmosDataPool* m_common = nullptr;
+
+private:
+    bool m_is_valid = false;
+};
+
+
+
+// The specializations of the CommonGizmosDataBase class live in this
+// namespace to avoid clashes in GUI namespace.
+namespace CommonGizmosDataObjects
+{
+
+class SelectionInfo : public CommonGizmosDataBase
+{
+public:
+    explicit SelectionInfo(CommonGizmosDataPool* cgdp) :
+        CommonGizmosDataBase(cgdp) {}
+    void update(bool required) override;
+
+    ModelObject* model_object();
+    int get_active_instance();
+
+private:
+    ModelObject* m_model_object = nullptr;
+    int m_active_inst = -1;
+};
+
+
+class InstancesHider : public CommonGizmosDataBase
+{
+public:
+    explicit InstancesHider(CommonGizmosDataPool* cgdp) :
+        CommonGizmosDataBase(cgdp) {}
+    void update(bool required) override;
+};
+
+
+
+
+
+
+
+class HollowedMesh : public CommonGizmosDataBase
+{
+public:
+    explicit HollowedMesh(CommonGizmosDataPool* cgdp)
+        : CommonGizmosDataBase(cgdp) {}
+    void update(bool required) override;
+};
+
+
+
+
+
+
+
+class ClippingPlaneWrapper : public CommonGizmosDataBase
+{
+public:
+    explicit ClippingPlaneWrapper(CommonGizmosDataPool* cgdp)
+        : CommonGizmosDataBase(cgdp) {}
+    void update(bool required) override;
+};
+
+
+
+
+
+
+
+class SupportsClipper : public CommonGizmosDataBase
+{
+public:
+    explicit SupportsClipper(CommonGizmosDataPool* cgdp)
+        : CommonGizmosDataBase(cgdp) {}
+    void update(bool required) override;
+};
+
+
+
+
+
+
+
+class Raycaster : public CommonGizmosDataBase
+{
+public:
+    explicit Raycaster(CommonGizmosDataPool* cgdp)
+        : CommonGizmosDataBase(cgdp) {}
+    void update(bool required) override;
+};
+
+
+} // namespace CommonGizmosDataObjects
+
+
+
+
+
+
+} // namespace GUI
+} // namespace Slic3r
+
+
+#endif // slic3r_GUI_GLGizmosCommon_hpp_

From 7c4071c541bff2c5ea7337b8f241690ac0ce4404 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Thu, 2 Apr 2020 17:05:23 +0200
Subject: [PATCH 02/15] Disabled the SLA gizmos

---
 src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 379bd48d1..b6cd4858c 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -95,12 +95,12 @@ bool GLGizmosManager::init()
     m_gizmos.emplace_back(new GLGizmoRotate3D(m_parent, "rotate.svg", 2));
     m_gizmos.emplace_back(new GLGizmoFlatten(m_parent, "place.svg", 3));
     m_gizmos.emplace_back(new GLGizmoCut(m_parent, "cut.svg", 4));
-    m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", 5));
-    m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 6));
+    //m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", 5));
+    //m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 6));
 
-    m_common_gizmos_data.reset(new CommonGizmosData());
-    dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->set_common_data_ptr(m_common_gizmos_data.get());
-    dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->set_common_data_ptr(m_common_gizmos_data.get());
+    //m_common_gizmos_data.reset(new CommonGizmosData());
+    //dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->set_common_data_ptr(m_common_gizmos_data.get());
+    //dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->set_common_data_ptr(m_common_gizmos_data.get());
 
     for (auto& gizmo : m_gizmos) {
         if (! gizmo->init()) {
@@ -353,7 +353,7 @@ void GLGizmosManager::set_flattening_data(const ModelObject* model_object)
 
 void GLGizmosManager::set_sla_support_data(ModelObject* model_object)
 {
-    if (! m_enabled
+    /*if (! m_enabled
      || m_gizmos.empty()
      || wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA)
         return;
@@ -367,6 +367,7 @@ void GLGizmosManager::set_sla_support_data(ModelObject* model_object)
     // following lines are thus dependent
     gizmo_supports->set_sla_support_data(model_object, m_parent.get_selection());
     gizmo_hollow->set_sla_support_data(model_object, m_parent.get_selection());
+    */
 }
 
 // Returns true if the gizmo used the event to do something, false otherwise.

From 3b06332999e04592fd2f8f98889458ed436e3d58 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Thu, 2 Apr 2020 17:07:15 +0200
Subject: [PATCH 03/15] Common gizmos data are now handled by the
 CommonGizmosDataPool object

---
 src/slic3r/GUI/AppConfig.hpp              |  2 +-
 src/slic3r/GUI/Gizmos/GLGizmoBase.hpp     |  3 +++
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp  | 10 +++++-----
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp  |  4 ++--
 src/slic3r/GUI/Gizmos/GLGizmosManager.cpp |  4 ++++
 src/slic3r/GUI/Gizmos/GLGizmosManager.hpp |  5 ++++-
 6 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/src/slic3r/GUI/AppConfig.hpp b/src/slic3r/GUI/AppConfig.hpp
index 346d42b21..1e90d32e0 100644
--- a/src/slic3r/GUI/AppConfig.hpp
+++ b/src/slic3r/GUI/AppConfig.hpp
@@ -60,7 +60,7 @@ public:
 		boost::trim_all(key_trimmed);
 		assert(key_trimmed == key);
 		assert(! key_trimmed.empty());
-#endif _NDEBUG
+#endif // _NDEBUG
 		std::string &old = m_storage[section][key];
 		if (old != value) {
 			old = value;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
index 965f195a9..8a2b71976 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
@@ -33,6 +33,7 @@ class ImGuiWrapper;
 class GLCanvas3D;
 class ClippingPlane;
 enum class CommonGizmosDataID;
+class CommonGizmosDataPool;
 
 class GLGizmoBase
 {
@@ -102,6 +103,7 @@ protected:
     ImGuiWrapper* m_imgui;
     bool m_first_input_window_render;
     mutable std::string m_tooltip;
+    CommonGizmosDataPool* m_c;
 
 public:
     GLGizmoBase(GLCanvas3D& parent,
@@ -130,6 +132,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(); }
+    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/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index 89a671519..bcc562d8b 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -14,11 +14,11 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
     using namespace CommonGizmosDataObjects;
     using c = CommonGizmosDataID;
     m_data[c::SelectionInfo].reset(       new SelectionInfo(this));
-    m_data[c::InstancesHider].reset(      new InstancesHider(this));
-    m_data[c::HollowedMesh].reset(        new HollowedMesh(this));
-    m_data[c::ClippingPlaneWrapper].reset(new ClippingPlaneWrapper(this));
-    m_data[c::SupportsClipper].reset(     new SupportsClipper(this));
-    m_data[c::MeshRaycaster].reset(       new Raycaster(this));
+    //m_data[c::InstancesHider].reset(      new InstancesHider(this));
+    //m_data[c::HollowedMesh].reset(        new HollowedMesh(this));
+    //m_data[c::ClippingPlaneWrapper].reset(new ClippingPlaneWrapper(this));
+    //m_data[c::SupportsClipper].reset(     new SupportsClipper(this));
+    //m_data[c::MeshRaycaster].reset(       new Raycaster(this));
 }
 
 void CommonGizmosDataPool::update(CommonGizmosDataID required)
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index 6d83179cb..259de5013 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -111,7 +111,7 @@ private:
     int m_active_inst = -1;
 };
 
-
+/*
 class InstancesHider : public CommonGizmosDataBase
 {
 public:
@@ -175,7 +175,7 @@ public:
         : CommonGizmosDataBase(cgdp) {}
     void update(bool required) override;
 };
-
+*/
 
 } // namespace CommonGizmosDataObjects
 
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index b6cd4858c..9600b3d64 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -102,11 +102,14 @@ bool GLGizmosManager::init()
     //dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->set_common_data_ptr(m_common_gizmos_data.get());
     //dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->set_common_data_ptr(m_common_gizmos_data.get());
 
+    m_common_gizmos_data.reset(new CommonGizmosDataPool(&m_parent));
+
     for (auto& gizmo : m_gizmos) {
         if (! gizmo->init()) {
             m_gizmos.clear();
             return false;
         }
+        gizmo->set_common_data_pool(m_common_gizmos_data.get());
     }
 
     m_current = Undefined;
@@ -1335,5 +1338,6 @@ void CommonGizmosData::build_AABB_if_needed()
     m_schedule_aabb_calculation = false;
 }
 
+
 } // namespace GUI
 } // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
index 7ae1fa661..f01ecfd77 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
@@ -5,6 +5,7 @@
 #include "slic3r/GUI/GLToolbar.hpp"
 #include "libslic3r/ObjectID.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmoBase.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
 
 #include <map>
 
@@ -20,6 +21,7 @@ class GLCanvas3D;
 class ClippingPlane;
 enum class SLAGizmoEventType : unsigned char;
 class CommonGizmosData;
+class CommonGizmosDataPool;
 
 class Rect
 {
@@ -115,7 +117,8 @@ private:
     MouseCapture m_mouse_capture;
     std::string m_tooltip;
     bool m_serializing;
-    std::unique_ptr<CommonGizmosData> m_common_gizmos_data;
+    //std::unique_ptr<CommonGizmosData> m_common_gizmos_data;
+    std::unique_ptr<CommonGizmosDataPool> m_common_gizmos_data;
 
 public:
     explicit GLGizmosManager(GLCanvas3D& parent);

From 593e7a1546ec8a1eaa00be9f1d807aaefeb51a19 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Fri, 3 Apr 2020 13:27:04 +0200
Subject: [PATCH 04/15] Flattening gizmo now uses the new CommonDataPool to
 store pointer to active object

---
 src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp  | 48 +++++++++++------------
 src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp  |  4 +-
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp  | 29 +++++++++++---
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp  | 30 ++++++++------
 src/slic3r/GUI/Gizmos/GLGizmosManager.cpp |  4 ++
 5 files changed, 71 insertions(+), 44 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
index 9fae8893a..7f33916cd 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
@@ -2,6 +2,7 @@
 #include "GLGizmoFlatten.hpp"
 #include "slic3r/GUI/GLCanvas3D.hpp"
 #include "slic3r/GUI/GUI_App.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
 
 #include <numeric>
 
@@ -26,20 +27,15 @@ bool GLGizmoFlatten::on_init()
 
 void GLGizmoFlatten::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
-    m_model_object = nullptr;
-    for (const auto mo : wxGetApp().model().objects) {
-        if (mo->id() == m_model_object_id) {
-            m_model_object = mo;
-            break;
-        }
-    }
-
     if (m_state == On && is_plane_update_necessary())
         update_planes();
 }
 
+CommonGizmosDataID GLGizmoFlatten::on_get_requirements() const
+{
+    return CommonGizmosDataID::SelectionInfo;
+}
+
 std::string GLGizmoFlatten::on_get_name() const
 {
     return (_(L("Place on face")) + " [F]").ToUTF8().data();
@@ -132,18 +128,17 @@ void GLGizmoFlatten::on_render_for_picking() const
 void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object)
 {
     m_starting_center = Vec3d::Zero();
-    if (m_model_object != model_object) {
+    if (model_object != m_old_model_object) {
         m_planes.clear();
         m_planes_valid = false;
     }
-    m_model_object = model_object;
-    m_model_object_id = model_object ? model_object->id() : 0;
 }
 
 void GLGizmoFlatten::update_planes()
 {
+    const ModelObject* mo = m_c->selection_info()->model_object();
     TriangleMesh ch;
-    for (const ModelVolume* vol : m_model_object->volumes)
+    for (const ModelVolume* vol : mo->volumes)
     {
         if (vol->type() != ModelVolumeType::MODEL_PART)
             continue;
@@ -153,7 +148,7 @@ void GLGizmoFlatten::update_planes()
     }
     ch = ch.convex_hull_3d();
     m_planes.clear();
-    const Transform3d& inst_matrix = m_model_object->instances.front()->get_matrix(true);
+    const Transform3d& inst_matrix = mo->instances.front()->get_matrix(true);
 
     // Following constants are used for discarding too small polygons.
     const float minimal_area = 5.f; // in square mm (world coordinates)
@@ -331,12 +326,13 @@ void GLGizmoFlatten::update_planes()
     // Planes are finished - let's save what we calculated it from:
     m_volumes_matrices.clear();
     m_volumes_types.clear();
-    for (const ModelVolume* vol : m_model_object->volumes) {
+    for (const ModelVolume* vol : mo->volumes) {
         m_volumes_matrices.push_back(vol->get_matrix());
         m_volumes_types.push_back(vol->type());
     }
-    m_first_instance_scale = m_model_object->instances.front()->get_scaling_factor();
-    m_first_instance_mirror = m_model_object->instances.front()->get_mirror();
+    m_first_instance_scale = mo->instances.front()->get_scaling_factor();
+    m_first_instance_mirror = mo->instances.front()->get_mirror();
+    m_old_model_object = mo;
 
     m_planes_valid = true;
 }
@@ -344,20 +340,22 @@ void GLGizmoFlatten::update_planes()
 
 bool GLGizmoFlatten::is_plane_update_necessary() const
 {
-    if (m_state != On || !m_model_object || m_model_object->instances.empty())
+    const ModelObject* mo = m_c->selection_info()->model_object();
+    if (m_state != On || ! mo || mo->instances.empty())
         return false;
 
-    if (! m_planes_valid || m_model_object->volumes.size() != m_volumes_matrices.size())
+    if (! m_planes_valid || mo != m_old_model_object
+     || mo->volumes.size() != m_volumes_matrices.size())
         return true;
 
     // We want to recalculate when the scale changes - some planes could (dis)appear.
-    if (! m_model_object->instances.front()->get_scaling_factor().isApprox(m_first_instance_scale)
-     || ! m_model_object->instances.front()->get_mirror().isApprox(m_first_instance_mirror))
+    if (! mo->instances.front()->get_scaling_factor().isApprox(m_first_instance_scale)
+     || ! mo->instances.front()->get_mirror().isApprox(m_first_instance_mirror))
         return true;
 
-    for (unsigned int i=0; i < m_model_object->volumes.size(); ++i)
-        if (! m_model_object->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i])
-         || m_model_object->volumes[i]->type() != m_volumes_types[i])
+    for (unsigned int i=0; i < mo->volumes.size(); ++i)
+        if (! mo->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i])
+         || mo->volumes[i]->type() != m_volumes_types[i])
             return true;
 
     return false;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp
index 9cd2ab6bb..05b4ae4cd 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp
@@ -30,8 +30,7 @@ private:
     std::vector<PlaneData> m_planes;
     bool m_planes_valid = false;
     mutable Vec3d m_starting_center;
-    const ModelObject* m_model_object = nullptr;
-    ObjectID m_model_object_id = 0;
+    const ModelObject* m_old_model_object = nullptr;
     std::vector<const Transform3d*> instances_matrices;
 
     void update_planes();
@@ -51,6 +50,7 @@ protected:
     virtual void on_render() const override;
     virtual void on_render_for_picking() const override;
     virtual void on_set_state() override;
+    virtual CommonGizmosDataID on_get_requirements() const override;
 };
 
 } // namespace GUI
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index bcc562d8b..8022b93f2 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -7,11 +7,11 @@
 namespace Slic3r {
 namespace GUI {
 
+using namespace CommonGizmosDataObjects;
 
 CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
     : m_canvas(canvas)
 {
-    using namespace CommonGizmosDataObjects;
     using c = CommonGizmosDataID;
     m_data[c::SelectionInfo].reset(       new SelectionInfo(this));
     //m_data[c::InstancesHider].reset(      new InstancesHider(this));
@@ -24,8 +24,19 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
 void CommonGizmosDataPool::update(CommonGizmosDataID required)
 {
     assert(check_dependencies(required));
-    for (auto& [id, data] : m_data)
-        data->update(int(required) & int(CommonGizmosDataID(id)));
+    for (auto& [id, data] : m_data) {
+        if (int(required) & int(CommonGizmosDataID(id)))
+            data->update();
+        else if (data->is_valid())
+            data->release();
+    }
+}
+
+
+SelectionInfo* CommonGizmosDataPool::selection_info()
+{
+    SelectionInfo* sel_info = dynamic_cast<SelectionInfo*>(m_data[CommonGizmosDataID::SelectionInfo].get());
+    return sel_info;
 }
 
 #ifndef NDEBUG
@@ -41,13 +52,19 @@ bool CommonGizmosDataPool::check_dependencies(CommonGizmosDataID required) const
 
 
 
-void CommonGizmosDataObjects::SelectionInfo::update(bool required)
+void SelectionInfo::on_update()
 {
     Selection selection = m_common->get_canvas()->get_selection();
-
+    if (selection.is_single_full_instance())
+        m_model_object = selection.get_model()->objects[selection.get_object_idx()];
+    else
+        m_model_object = nullptr;
 }
 
-
+void SelectionInfo::on_release()
+{
+    m_model_object = nullptr;
+}
 
 } // namespace GUI
 } // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index 259de5013..3f3854ffa 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -46,10 +46,10 @@ public:
 
     // Update all resources and release what is not used.
     // Accepts a bitmask of currently required resources.
-    void update(CommonGizmosDataID required = CommonGizmosDataID::None);
+    void update(CommonGizmosDataID required);
 
     // Getters for the data that need to be accessed from the gizmos directly.
-    CommonGizmosDataObjects::SelectionInfo selection_info();
+    CommonGizmosDataObjects::SelectionInfo* selection_info();
 
     GLCanvas3D* get_canvas() const { return m_canvas; }
 
@@ -74,16 +74,21 @@ public:
     // objects can communicate with one another.
     explicit CommonGizmosDataBase(CommonGizmosDataPool* cgdp)
         : m_common{cgdp} {}
+    virtual ~CommonGizmosDataBase() {}
 
-    // Update the resource. If it is not needed (based on argument value)
-    // any persistent data will be released.
-    virtual void update(bool required) = 0;
+    // Update the resource.
+    void update() { on_update(); m_is_valid = true; }
+
+    // Release any data that are stored internally.
+    void release() { on_release(); m_is_valid = false; }
 
     // Returns whether the resource is currently maintained.
     bool is_valid() const { return m_is_valid; }
 
 protected:
     CommonGizmosDataPool* m_common = nullptr;
+    virtual void on_release() = 0;
+    virtual void on_update() = 0;
 
 private:
     bool m_is_valid = false;
@@ -99,13 +104,16 @@ namespace CommonGizmosDataObjects
 class SelectionInfo : public CommonGizmosDataBase
 {
 public:
-    explicit SelectionInfo(CommonGizmosDataPool* cgdp) :
-        CommonGizmosDataBase(cgdp) {}
-    void update(bool required) override;
+    explicit SelectionInfo(CommonGizmosDataPool* cgdp)
+        : CommonGizmosDataBase(cgdp) {}
 
-    ModelObject* model_object();
+    ModelObject* model_object() { return m_model_object; }
     int get_active_instance();
 
+protected:
+    void on_update() override;
+    void on_release() override;
+
 private:
     ModelObject* m_model_object = nullptr;
     int m_active_inst = -1;
@@ -115,8 +123,8 @@ private:
 class InstancesHider : public CommonGizmosDataBase
 {
 public:
-    explicit InstancesHider(CommonGizmosDataPool* cgdp) :
-        CommonGizmosDataBase(cgdp) {}
+    explicit InstancesHider(CommonGizmosDataPool* cgdp)
+        : CommonGizmosDataBase(cgdp) {}
     void update(bool required) override;
 };
 
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 9600b3d64..d5be7cd10 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -201,6 +201,10 @@ void GLGizmosManager::update_data()
         enable_grabber(Scale, i, enable_scale_xyz);
     }
 
+    m_common_gizmos_data->update(get_current()
+                           ? get_current()->get_requirements()
+                           : CommonGizmosDataID(0));
+
     if (selection.is_single_full_instance())
     {
         // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first

From 3db3a6152049bb32f2b37db3af25a55331747aca Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Fri, 3 Apr 2020 18:04:37 +0200
Subject: [PATCH 05/15] InstancesHider implementation

Any gizmo can now ask for hiding all but the active instance by returning proper value from on_get_requirements
---
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp  | 42 ++++++++++++++++++++---
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp  |  8 +++--
 src/slic3r/GUI/Gizmos/GLGizmosManager.cpp |  7 ++--
 3 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index 8022b93f2..3dd604b6b 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -14,7 +14,7 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
 {
     using c = CommonGizmosDataID;
     m_data[c::SelectionInfo].reset(       new SelectionInfo(this));
-    //m_data[c::InstancesHider].reset(      new InstancesHider(this));
+    m_data[c::InstancesHider].reset(      new InstancesHider(this));
     //m_data[c::HollowedMesh].reset(        new HollowedMesh(this));
     //m_data[c::ClippingPlaneWrapper].reset(new ClippingPlaneWrapper(this));
     //m_data[c::SupportsClipper].reset(     new SupportsClipper(this));
@@ -27,8 +27,10 @@ void CommonGizmosDataPool::update(CommonGizmosDataID required)
     for (auto& [id, data] : m_data) {
         if (int(required) & int(CommonGizmosDataID(id)))
             data->update();
-        else if (data->is_valid())
-            data->release();
+        else
+            if (data->is_valid())
+                data->release();
+
     }
 }
 
@@ -36,6 +38,7 @@ void CommonGizmosDataPool::update(CommonGizmosDataID required)
 SelectionInfo* CommonGizmosDataPool::selection_info()
 {
     SelectionInfo* sel_info = dynamic_cast<SelectionInfo*>(m_data[CommonGizmosDataID::SelectionInfo].get());
+    assert(sel_info->is_valid());
     return sel_info;
 }
 
@@ -54,7 +57,7 @@ bool CommonGizmosDataPool::check_dependencies(CommonGizmosDataID required) const
 
 void SelectionInfo::on_update()
 {
-    Selection selection = m_common->get_canvas()->get_selection();
+    const Selection& selection = m_common->get_canvas()->get_selection();
     if (selection.is_single_full_instance())
         m_model_object = selection.get_model()->objects[selection.get_object_idx()];
     else
@@ -66,5 +69,36 @@ void SelectionInfo::on_release()
     m_model_object = nullptr;
 }
 
+int SelectionInfo::get_active_instance()
+{
+    const Selection& selection = m_common->get_canvas()->get_selection();
+    return selection.get_instance_idx();
+}
+
+
+
+
+
+void InstancesHider::on_update()
+{
+    const ModelObject* mo = m_common->selection_info()->model_object();
+    int active_inst = m_common->selection_info()->get_active_instance();
+    GLCanvas3D* canvas = m_common->get_canvas();
+
+    if (mo && active_inst != -1) {
+        canvas->toggle_model_objects_visibility(false);
+        canvas->toggle_model_objects_visibility(true, mo, active_inst);
+    }
+    else
+        canvas->toggle_model_objects_visibility(true);
+}
+
+void InstancesHider::on_release()
+{
+    m_common->get_canvas()->toggle_model_objects_visibility(true);
+}
+
+
+
 } // namespace GUI
 } // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index 3f3854ffa..f1840837f 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -119,19 +119,21 @@ private:
     int m_active_inst = -1;
 };
 
-/*
+
 class InstancesHider : public CommonGizmosDataBase
 {
 public:
     explicit InstancesHider(CommonGizmosDataPool* cgdp)
         : CommonGizmosDataBase(cgdp) {}
-    void update(bool required) override;
+protected:
+    void on_update() override;
+    void on_release() override;
 };
 
 
 
 
-
+/*
 
 
 class HollowedMesh : public CommonGizmosDataBase
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index d5be7cd10..26f42ed34 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -1196,10 +1196,13 @@ void GLGizmosManager::activate_gizmo(EType type)
             return; // gizmo refused to be turned off, do nothing.
     }
 
+    m_current = type;
+    m_common_gizmos_data->update(get_current()
+                           ? get_current()->get_requirements()
+                           : CommonGizmosDataID(0));
+
     if (type != Undefined)
         m_gizmos[type]->set_state(GLGizmoBase::On);
-
-    m_current = type;
 }
 
 

From 7e797eaaf8bc77ba10791593b214c1be7dc6d1e2 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Mon, 6 Apr 2020 08:06:07 +0200
Subject: [PATCH 06/15] Dependencies check in debug mode Some common resources
 can depend on each other - this checks that the requirements are consistent

---
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 25 ++++++++++++++++++------
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 15 +++++++++++++-
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index 3dd604b6b..40ac66c71 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -43,11 +43,24 @@ SelectionInfo* CommonGizmosDataPool::selection_info()
 }
 
 #ifndef NDEBUG
+// Check the required resources one by one and return true if all
+// dependencies are met.
 bool CommonGizmosDataPool::check_dependencies(CommonGizmosDataID required) const
 {
     // This should iterate over currently required data. Each of them should
     // be asked about its dependencies and it must check that all dependencies
     // are also in required and before the current one.
+    for (auto& [id, data] : m_data) {
+        // in case we don't use this, the deps are irrelevant
+        if (! (int(required) & int(CommonGizmosDataID(id))))
+            continue;
+
+
+        CommonGizmosDataID deps = data->get_dependencies();
+        assert(int(deps) == (int(deps) & int(required)));
+    }
+
+
     return true;
 }
 #endif // NDEBUG
@@ -57,7 +70,7 @@ bool CommonGizmosDataPool::check_dependencies(CommonGizmosDataID required) const
 
 void SelectionInfo::on_update()
 {
-    const Selection& selection = m_common->get_canvas()->get_selection();
+    const Selection& selection = get_pool()->get_canvas()->get_selection();
     if (selection.is_single_full_instance())
         m_model_object = selection.get_model()->objects[selection.get_object_idx()];
     else
@@ -71,7 +84,7 @@ void SelectionInfo::on_release()
 
 int SelectionInfo::get_active_instance()
 {
-    const Selection& selection = m_common->get_canvas()->get_selection();
+    const Selection& selection = get_pool()->get_canvas()->get_selection();
     return selection.get_instance_idx();
 }
 
@@ -81,9 +94,9 @@ int SelectionInfo::get_active_instance()
 
 void InstancesHider::on_update()
 {
-    const ModelObject* mo = m_common->selection_info()->model_object();
-    int active_inst = m_common->selection_info()->get_active_instance();
-    GLCanvas3D* canvas = m_common->get_canvas();
+    const ModelObject* mo = get_pool()->selection_info()->model_object();
+    int active_inst = get_pool()->selection_info()->get_active_instance();
+    GLCanvas3D* canvas = get_pool()->get_canvas();
 
     if (mo && active_inst != -1) {
         canvas->toggle_model_objects_visibility(false);
@@ -95,7 +108,7 @@ void InstancesHider::on_update()
 
 void InstancesHider::on_release()
 {
-    m_common->get_canvas()->toggle_model_objects_visibility(true);
+    get_pool()->get_canvas()->toggle_model_objects_visibility(true);
 }
 
 
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index f1840837f..5211ca48f 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -85,13 +85,22 @@ public:
     // Returns whether the resource is currently maintained.
     bool is_valid() const { return m_is_valid; }
 
+#ifndef NDEBUG
+    // Return a bitmask of all resources that this one relies on.
+    // The dependent resource must have higher ID than the one
+    // it depends on.
+    virtual CommonGizmosDataID get_dependencies() const { return CommonGizmosDataID::None; }
+#endif // NDEBUG
+
 protected:
-    CommonGizmosDataPool* m_common = nullptr;
     virtual void on_release() = 0;
     virtual void on_update() = 0;
+    CommonGizmosDataPool* get_pool() const { return m_common; }
+
 
 private:
     bool m_is_valid = false;
+    CommonGizmosDataPool* m_common = nullptr;
 };
 
 
@@ -125,6 +134,10 @@ class InstancesHider : public CommonGizmosDataBase
 public:
     explicit InstancesHider(CommonGizmosDataPool* cgdp)
         : CommonGizmosDataBase(cgdp) {}
+#ifndef NDEBUG
+    CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
+#endif // NDEBUG
+
 protected:
     void on_update() override;
     void on_release() override;

From 81dba7677bd3fc0183c6ccff2537481a8bbb1af5 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Mon, 6 Apr 2020 09:56:00 +0200
Subject: [PATCH 07/15] Hollowed mesh tracker implementation The class tracks
 state of the backend calculation and if there is a hollowed/drilled mesh, it
 can provide a pointer to it

---
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 73 +++++++++++++++++++++++-
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 32 +++++++----
 2 files changed, 92 insertions(+), 13 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index 40ac66c71..783081ed2 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -3,6 +3,7 @@
 #include <cassert>
 
 #include "slic3r/GUI/GLCanvas3D.hpp"
+#include "libslic3r/SLAPrint.hpp"
 
 namespace Slic3r {
 namespace GUI {
@@ -15,7 +16,7 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
     using c = CommonGizmosDataID;
     m_data[c::SelectionInfo].reset(       new SelectionInfo(this));
     m_data[c::InstancesHider].reset(      new InstancesHider(this));
-    //m_data[c::HollowedMesh].reset(        new HollowedMesh(this));
+    m_data[c::HollowedMesh].reset(        new HollowedMesh(this));
     //m_data[c::ClippingPlaneWrapper].reset(new ClippingPlaneWrapper(this));
     //m_data[c::SupportsClipper].reset(     new SupportsClipper(this));
     //m_data[c::MeshRaycaster].reset(       new Raycaster(this));
@@ -38,8 +39,15 @@ void CommonGizmosDataPool::update(CommonGizmosDataID required)
 SelectionInfo* CommonGizmosDataPool::selection_info()
 {
     SelectionInfo* sel_info = dynamic_cast<SelectionInfo*>(m_data[CommonGizmosDataID::SelectionInfo].get());
-    assert(sel_info->is_valid());
-    return sel_info;
+    assert(sel_info);
+    return sel_info->is_valid() ? sel_info : nullptr;
+}
+
+HollowedMesh* CommonGizmosDataPool::hollowed_mesh()
+{
+    HollowedMesh* hol_mesh = dynamic_cast<HollowedMesh*>(m_data[CommonGizmosDataID::HollowedMesh].get());
+    assert(hol_mesh);
+    return hol_mesh->is_valid() ? hol_mesh : nullptr;
 }
 
 #ifndef NDEBUG
@@ -113,5 +121,64 @@ void InstancesHider::on_release()
 
 
 
+void HollowedMesh::on_update()
+{
+    const ModelObject* mo = get_pool()->selection_info()->model_object();
+    if (! mo)
+        return;
+
+    const GLCanvas3D* canvas = get_pool()->get_canvas();
+    const PrintObjects& print_objects = canvas->sla_print()->objects();
+    const SLAPrintObject* print_object = m_print_object_idx != -1
+            ? print_objects[m_print_object_idx]
+            : nullptr;
+
+    // Find the respective SLAPrintObject.
+    if (m_print_object_idx < 0 || m_print_objects_count != int(print_objects.size())) {
+        m_print_objects_count = print_objects.size();
+        m_print_object_idx = -1;
+        for (const SLAPrintObject* po : print_objects) {
+            ++m_print_object_idx;
+            if (po->model_object()->id() == mo->id()) {
+                print_object = po;
+                break;
+            }
+        }
+    }
+
+    // If there is a valid SLAPrintObject, check state of Hollowing step.
+    if (print_object) {
+        if (print_object->is_step_done(slaposDrillHoles) && print_object->has_mesh(slaposDrillHoles)) {
+            size_t timestamp = print_object->step_state_with_timestamp(slaposDrillHoles).timestamp;
+            if (timestamp > m_old_hollowing_timestamp) {
+                const TriangleMesh& backend_mesh = print_object->get_mesh_to_print();
+                m_hollowed_mesh_transformed.reset(new TriangleMesh(backend_mesh));
+                Transform3d trafo_inv = canvas->sla_print()->sla_trafo(*mo).inverse();
+                m_hollowed_mesh_transformed->transform(trafo_inv);
+                m_old_hollowing_timestamp = timestamp;
+            }
+        }
+        else {
+            m_hollowed_mesh_transformed.reset(nullptr);
+            m_old_hollowing_timestamp = 0;
+        }
+    }
+}
+
+
+void HollowedMesh::on_release()
+{
+    m_hollowed_mesh_transformed.reset();
+    m_old_hollowing_timestamp = 0;
+    m_print_object_idx = -1;
+}
+
+
+const TriangleMesh* HollowedMesh::get_hollowed_mesh() const
+{
+    return m_hollowed_mesh_transformed.get();
+}
+
+
 } // namespace GUI
 } // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index 5211ca48f..dcd5f862f 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -7,6 +7,7 @@
 namespace Slic3r {
 
 class ModelObject;
+class TriangleMesh;
 
 
 namespace GUI {
@@ -16,6 +17,8 @@ class GLCanvas3D;
 class CommonGizmosDataBase;
 namespace CommonGizmosDataObjects {
     class SelectionInfo;
+    class InstancesHider;
+    class HollowedMesh;
 }
 
 // Some of the gizmos use the same data that need to be updated ocassionally.
@@ -50,6 +53,8 @@ public:
 
     // Getters for the data that need to be accessed from the gizmos directly.
     CommonGizmosDataObjects::SelectionInfo* selection_info();
+    CommonGizmosDataObjects::HollowedMesh* hollowed_mesh();
+
 
     GLCanvas3D* get_canvas() const { return m_canvas; }
 
@@ -129,6 +134,7 @@ private:
 };
 
 
+
 class InstancesHider : public CommonGizmosDataBase
 {
 public:
@@ -145,23 +151,29 @@ protected:
 
 
 
-
-/*
-
-
 class HollowedMesh : public CommonGizmosDataBase
 {
 public:
     explicit HollowedMesh(CommonGizmosDataPool* cgdp)
         : CommonGizmosDataBase(cgdp) {}
-    void update(bool required) override;
+#ifndef NDEBUG
+    CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
+#endif // NDEBUG
+
+    const TriangleMesh* get_hollowed_mesh() const;
+
+protected:
+    void on_update() override;
+    void on_release() override;
+
+private:
+    std::unique_ptr<TriangleMesh> m_hollowed_mesh_transformed;
+    size_t m_old_hollowing_timestamp = 0;
+    int m_print_object_idx = -1;
+    int m_print_objects_count = 0;
 };
 
-
-
-
-
-
+/*
 
 class ClippingPlaneWrapper : public CommonGizmosDataBase
 {

From bf734c8f689eed87358549520f4fd7febf883e07 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Mon, 6 Apr 2020 12:24:04 +0200
Subject: [PATCH 08/15] Raycaster wrapper The raycaster manages a MeshRaycaster
 object that the gizmo can ask to perform raycasts If the hollowed mesh
 tracker is enabled and the hollowed mesh is newly calculated/invalidated, the
 raycaster automatically updates.

---
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 43 +++++++++++++++++++-
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 51 ++++++++++++++----------
 2 files changed, 71 insertions(+), 23 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index 783081ed2..413d5391b 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -17,9 +17,10 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
     m_data[c::SelectionInfo].reset(       new SelectionInfo(this));
     m_data[c::InstancesHider].reset(      new InstancesHider(this));
     m_data[c::HollowedMesh].reset(        new HollowedMesh(this));
-    //m_data[c::ClippingPlaneWrapper].reset(new ClippingPlaneWrapper(this));
+    m_data[c::Raycaster].reset(           new Raycaster(this));
+    //m_data[c::ObjectClipper].reset(new ClippingPlaneWrapper(this));
     //m_data[c::SupportsClipper].reset(     new SupportsClipper(this));
-    //m_data[c::MeshRaycaster].reset(       new Raycaster(this));
+
 }
 
 void CommonGizmosDataPool::update(CommonGizmosDataID required)
@@ -50,6 +51,13 @@ HollowedMesh* CommonGizmosDataPool::hollowed_mesh()
     return hol_mesh->is_valid() ? hol_mesh : nullptr;
 }
 
+Raycaster* CommonGizmosDataPool::raycaster()
+{
+    Raycaster* rc = dynamic_cast<Raycaster*>(m_data[CommonGizmosDataID::Raycaster].get());
+    assert(rc);
+    return rc->is_valid() ? rc : nullptr;
+}
+
 #ifndef NDEBUG
 // Check the required resources one by one and return true if all
 // dependencies are met.
@@ -180,5 +188,36 @@ const TriangleMesh* HollowedMesh::get_hollowed_mesh() const
 }
 
 
+
+
+
+void Raycaster::on_update()
+{
+    const ModelObject* mo = get_pool()->selection_info()->model_object();
+
+    if (! mo)
+        return;
+
+    const TriangleMesh* mesh = &mo->volumes.front()->mesh();
+    const HollowedMesh* hollowed_mesh_tracker = get_pool()->hollowed_mesh();
+    if (hollowed_mesh_tracker && hollowed_mesh_tracker->get_hollowed_mesh())
+        mesh = hollowed_mesh_tracker->get_hollowed_mesh();
+
+    if (mesh != m_old_mesh) {
+        m_raycaster.reset(new MeshRaycaster(*mesh));
+        m_old_mesh = mesh;
+    }
+}
+
+void Raycaster::on_release()
+{
+    m_raycaster.reset();
+    m_old_mesh = nullptr;
+}
+
+
+
+
+
 } // namespace GUI
 } // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index dcd5f862f..5ebe7fad3 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -4,10 +4,11 @@
 #include <memory>
 #include <map>
 
+#include "slic3r/GUI/MeshUtils.hpp"
+
 namespace Slic3r {
 
 class ModelObject;
-class TriangleMesh;
 
 
 namespace GUI {
@@ -19,6 +20,7 @@ namespace CommonGizmosDataObjects {
     class SelectionInfo;
     class InstancesHider;
     class HollowedMesh;
+    class Raycaster;
 }
 
 // Some of the gizmos use the same data that need to be updated ocassionally.
@@ -34,9 +36,10 @@ enum class CommonGizmosDataID {
     SelectionInfo        = 1 << 0,
     InstancesHider       = 1 << 1,
     HollowedMesh         = 1 << 2,
-    ClippingPlaneWrapper = 1 << 3,
-    SupportsClipper      = 1 << 4,
-    MeshRaycaster        = 1 << 5,
+    Raycaster            = 1 << 3,
+    ObjectClipper        = 1 << 4,
+    SupportsClipper      = 1 << 5,
+
 };
 
 
@@ -54,6 +57,7 @@ public:
     // Getters for the data that need to be accessed from the gizmos directly.
     CommonGizmosDataObjects::SelectionInfo* selection_info();
     CommonGizmosDataObjects::HollowedMesh* hollowed_mesh();
+    CommonGizmosDataObjects::Raycaster* raycaster();
 
 
     GLCanvas3D* get_canvas() const { return m_canvas; }
@@ -173,6 +177,28 @@ private:
     int m_print_objects_count = 0;
 };
 
+
+
+class Raycaster : public CommonGizmosDataBase
+{
+public:
+    explicit Raycaster(CommonGizmosDataPool* cgdp)
+        : CommonGizmosDataBase(cgdp) {}
+#ifndef NDEBUG
+    CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
+#endif // NDEBUG
+
+    const MeshRaycaster* raycaster() const { return m_raycaster.get(); }
+
+protected:
+    void on_update() override;
+    void on_release() override;
+
+private:
+    std::unique_ptr<MeshRaycaster> m_raycaster;
+    const TriangleMesh* m_old_mesh = nullptr;
+};
+
 /*
 
 class ClippingPlaneWrapper : public CommonGizmosDataBase
@@ -185,10 +211,6 @@ public:
 
 
 
-
-
-
-
 class SupportsClipper : public CommonGizmosDataBase
 {
 public:
@@ -197,19 +219,6 @@ public:
     void update(bool required) override;
 };
 
-
-
-
-
-
-
-class Raycaster : public CommonGizmosDataBase
-{
-public:
-    explicit Raycaster(CommonGizmosDataPool* cgdp)
-        : CommonGizmosDataBase(cgdp) {}
-    void update(bool required) override;
-};
 */
 
 } // namespace CommonGizmosDataObjects

From d9e5721cb79f5a75a657470941ddd873103f6a1a Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Mon, 6 Apr 2020 13:59:28 +0200
Subject: [PATCH 09/15] Raycaster can now handle multiple volumes This is
 necessary for future FDM supports gizmo. SLA objects only have one volume, so
 it wasn't needed until now.

---
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 38 ++++++++++++++++++------
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp |  7 +++--
 2 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index 413d5391b..ecbe75165 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -198,21 +198,41 @@ void Raycaster::on_update()
     if (! mo)
         return;
 
-    const TriangleMesh* mesh = &mo->volumes.front()->mesh();
-    const HollowedMesh* hollowed_mesh_tracker = get_pool()->hollowed_mesh();
-    if (hollowed_mesh_tracker && hollowed_mesh_tracker->get_hollowed_mesh())
-        mesh = hollowed_mesh_tracker->get_hollowed_mesh();
+    std::vector<const TriangleMesh*> meshes;
+    const std::vector<ModelVolume*>& mvs = mo->volumes;
+    if (mvs.size() == 1) {
+        assert(mvs.front()->is_model_part());
+        const HollowedMesh* hollowed_mesh_tracker = get_pool()->hollowed_mesh();
+        if (hollowed_mesh_tracker && hollowed_mesh_tracker->get_hollowed_mesh())
+            meshes.push_back(hollowed_mesh_tracker->get_hollowed_mesh());
+    }
+    if (meshes.empty()) {
+        for (const ModelVolume* mv : mvs) {
+            if (mv->is_model_part())
+                meshes.push_back(&mv->mesh());
+        }
+    }
 
-    if (mesh != m_old_mesh) {
-        m_raycaster.reset(new MeshRaycaster(*mesh));
-        m_old_mesh = mesh;
+    if (meshes != m_old_meshes) {
+        m_raycasters.clear();
+        for (const TriangleMesh* mesh : meshes)
+            m_raycasters.emplace_back(new MeshRaycaster(*mesh));
+        m_old_meshes = meshes;
     }
 }
 
 void Raycaster::on_release()
 {
-    m_raycaster.reset();
-    m_old_mesh = nullptr;
+    m_raycasters.clear();
+    m_old_meshes.clear();
+}
+
+std::vector<const MeshRaycaster*> Raycaster::raycasters() const
+{
+    std::vector<const MeshRaycaster*> mrcs;
+    for (const auto& raycaster_unique_ptr : m_raycasters)
+        mrcs.push_back(raycaster_unique_ptr.get());
+    return mrcs;
 }
 
 
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index 5ebe7fad3..0b327cce8 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -188,15 +188,16 @@ public:
     CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
 #endif // NDEBUG
 
-    const MeshRaycaster* raycaster() const { return m_raycaster.get(); }
+    const MeshRaycaster* raycaster() const { assert(m_raycasters.size() == 1); return m_raycasters.front().get(); }
+    std::vector<const MeshRaycaster*> raycasters() const;
 
 protected:
     void on_update() override;
     void on_release() override;
 
 private:
-    std::unique_ptr<MeshRaycaster> m_raycaster;
-    const TriangleMesh* m_old_mesh = nullptr;
+    std::vector<std::unique_ptr<MeshRaycaster>> m_raycasters;
+    std::vector<const TriangleMesh*> m_old_meshes;
 };
 
 /*

From 5d4014a4a5facca910c0d726306bb5fe8a44977d Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 7 Apr 2020 09:29:34 +0200
Subject: [PATCH 10/15] ObjectClipper implementation, hollowing gizmo reenabled
 ObjectClipper tracks active mesh (incl. possible hollowing), remembers
 clipping plane position and can render the cut on demand Hollowing gizmo uses
 the new infrastructure

---
 src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp   | 275 ++++++++++++----------
 src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp   |   8 +-
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp  | 109 ++++++++-
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp  |  49 +++-
 src/slic3r/GUI/Gizmos/GLGizmosManager.cpp |  13 +-
 5 files changed, 305 insertions(+), 149 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
index 51e6d7458..f27bc2863 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
@@ -2,20 +2,15 @@
 #include "slic3r/GUI/GLCanvas3D.hpp"
 #include "slic3r/GUI/Camera.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmos.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
 
 #include <GL/glew.h>
 
 #include "slic3r/GUI/GUI_App.hpp"
 #include "slic3r/GUI/GUI_ObjectSettings.hpp"
 #include "slic3r/GUI/GUI_ObjectList.hpp"
-#include "slic3r/GUI/MeshUtils.hpp"
 #include "slic3r/GUI/Plater.hpp"
-#if ENABLE_NON_STATIC_CANVAS_MANAGER
-#include "slic3r/GUI/Camera.hpp"
-#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
 #include "slic3r/GUI/PresetBundle.hpp"
-#include "libslic3r/SLAPrint.hpp"
-#include "libslic3r/TriangleMesh.hpp"
 
 
 namespace Slic3r {
@@ -59,7 +54,14 @@ bool GLGizmoHollow::on_init()
 
 void GLGizmoHollow::set_sla_support_data(ModelObject*, const Selection&)
 {
-    if (m_c->recent_update) {
+    const ModelObject* mo = m_c->selection_info()->model_object();
+    if (mo) {
+        reload_cache();
+        if (m_c->hollowed_mesh()->get_hollowed_mesh())
+            m_holes_in_drilled_mesh = mo->sla_drain_holes;
+    }
+
+    /*if (m_c->recent_update) {
 
         if (m_state == On)
             m_c->build_AABB_if_needed();
@@ -85,7 +87,7 @@ void GLGizmoHollow::set_sla_support_data(ModelObject*, const Selection&)
         m_parent.toggle_model_objects_visibility(false);
         m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
         m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, m_c->m_model_object, m_c->m_active_instance);
-    }
+    }*/
 }
 
 
@@ -93,12 +95,12 @@ void GLGizmoHollow::set_sla_support_data(ModelObject*, const Selection&)
 void GLGizmoHollow::on_render() const
 {
     const Selection& selection = m_parent.get_selection();
+    const CommonGizmosDataObjects::SelectionInfo* sel_info = m_c->selection_info();
 
     // If current m_c->m_model_object does not match selection, ask GLCanvas3D to turn us off
     if (m_state == On
-     && (m_c->m_model_object != selection.get_model()->objects[selection.get_object_idx()]
-      || m_c->m_active_instance != selection.get_instance_idx()
-      || m_c->m_model_object_id != m_c->m_model_object->id())) {
+     && (sel_info->model_object() != selection.get_model()->objects[selection.get_object_idx()]
+      || sel_info->get_active_instance() != selection.get_instance_idx())) {
         m_parent.post_event(SimpleEvent(EVT_GLCANVAS_RESETGIZMOS));
         return;
     }
@@ -106,13 +108,14 @@ void GLGizmoHollow::on_render() const
     glsafe(::glEnable(GL_BLEND));
     glsafe(::glEnable(GL_DEPTH_TEST));
 
-    m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
+    //m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
 
     if (m_quadric != nullptr && selection.is_from_single_instance())
         render_points(selection, false);
 
     m_selection_rectangle.render(m_parent);
-    render_clipping_plane(selection);
+    //render_clipping_plane(selection);
+    m_c->object_clipper()->render_cut();
 
     glsafe(::glDisable(GL_BLEND));
 }
@@ -121,6 +124,8 @@ void GLGizmoHollow::on_render() const
 
 void GLGizmoHollow::render_clipping_plane(const Selection& selection) const
 {
+    return;
+/*
     if (m_c->m_clipping_plane_distance == 0.f)
         return;
 
@@ -189,6 +194,7 @@ void GLGizmoHollow::render_clipping_plane(const Selection& selection) const
         ::glEnd();
         ::glPopMatrix();
     }
+*/
 }
 
 
@@ -217,13 +223,14 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
     glsafe(::glMultMatrixd(instance_matrix.data()));
 
     float render_color[4];
-    size_t cache_size = m_c->m_model_object->sla_drain_holes.size();
+    const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
+    size_t cache_size = drain_holes.size();
     for (size_t i = 0; i < cache_size; ++i)
     {
-        const sla::DrainHole& drain_hole = m_c->m_model_object->sla_drain_holes[i];
+        const sla::DrainHole& drain_hole = drain_holes[i];
         const bool& point_selected = m_selected[i];
 
-        if (is_mesh_point_clipped((drain_hole.pos+m_c->HoleStickOutLength*drain_hole.normal).cast<double>()))
+        if (is_mesh_point_clipped((drain_hole.pos+HoleStickOutLength*drain_hole.normal).cast<double>()))
             continue;
 
         // First decide about the color of the point.
@@ -297,12 +304,17 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
 
 bool GLGizmoHollow::is_mesh_point_clipped(const Vec3d& point) const
 {
-    if (m_c->m_clipping_plane_distance == 0.f)
+    if (m_c->object_clipper()->get_position() == 0.)
         return false;
 
-    Vec3d transformed_point = m_c->m_model_object->instances[m_c->m_active_instance]->get_transformation().get_matrix() * point;
-    transformed_point(2) += m_z_shift;
-    return m_c->m_clipping_plane->is_point_clipped(transformed_point);
+    auto sel_info = m_c->selection_info();
+    int active_inst = m_c->selection_info()->get_active_instance();
+    const ModelInstance* mi = sel_info->model_object()->instances[active_inst];
+    const Transform3d& trafo = mi->get_transformation().get_matrix();
+
+    Vec3d transformed_point =  trafo * point;
+    transformed_point(2) += sel_info->get_sla_shift();
+    return m_c->object_clipper()->get_clipping_plane()->is_point_clipped(transformed_point);
 }
 
 
@@ -311,7 +323,7 @@ bool GLGizmoHollow::is_mesh_point_clipped(const Vec3d& point) const
 // Return false if no intersection was found, true otherwise.
 bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal)
 {
-    if (! m_c->m_mesh_raycaster)
+    if (! m_c->raycaster()->raycaster())
         return false;
 
 #if ENABLE_NON_STATIC_CANVAS_MANAGER
@@ -322,20 +334,23 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V
     const Selection& selection = m_parent.get_selection();
     const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
     Geometry::Transformation trafo = volume->get_instance_transformation();
-    trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift));
+    trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
+
+    double clp_dist = m_c->object_clipper()->get_position();
+    const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane();
 
     // The raycaster query
     Vec3f hit;
     Vec3f normal;
-    if (m_c->m_mesh_raycaster->unproject_on_mesh(
+    if (m_c->raycaster()->raycaster()->unproject_on_mesh(
             mouse_pos,
             trafo.get_matrix(),
             camera,
             hit,
             normal,
-            m_c->m_clipping_plane_distance != 0.f ? m_c->m_clipping_plane.get() : nullptr))
+            clp_dist != 0. ? clp : nullptr))
     {
-        if (m_c->has_drilled_mesh()) {
+        if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh()) {
             // in this case the raycaster sees the hollowed and drilled mesh.
             // if the point lies on the surface created by the hole, we want
             // to ignore it.
@@ -362,6 +377,10 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V
 // concludes that the event was not intended for it, it should return false.
 bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down)
 {
+    ModelObject* mo = m_c->selection_info()->model_object();
+    int active_inst = m_c->selection_info()->get_active_instance();
+
+
     // left down with shift - show the selection rectangle:
     if (action == SLAGizmoEventType::LeftDown && (shift_down || alt_down || control_down)) {
         if (m_hover_id == -1) {
@@ -393,15 +412,15 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
             if (unproject_on_mesh(mouse_position, pos_and_normal)) { // we got an intersection
                 Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Add drainage hole")));
 
-                Vec3d scaling = m_c->m_model_object->instances[m_c->m_active_instance]->get_scaling_factor();
+                Vec3d scaling = mo->instances[active_inst]->get_scaling_factor();
                 Vec3f normal_transformed(pos_and_normal.second(0)/scaling(0),
                                          pos_and_normal.second(1)/scaling(1),
                                          pos_and_normal.second(2)/scaling(2));
 
-                m_c->m_model_object->sla_drain_holes.emplace_back(pos_and_normal.first + m_c->HoleStickOutLength * pos_and_normal.second/* normal_transformed.normalized()*/,
+                mo->sla_drain_holes.emplace_back(pos_and_normal.first + HoleStickOutLength * pos_and_normal.second/* normal_transformed.normalized()*/,
                                                              -pos_and_normal.second, m_new_hole_radius, m_new_hole_height);
                 m_selected.push_back(false);
-                assert(m_selected.size() == m_c->m_model_object->sla_drain_holes.size());
+                assert(m_selected.size() == mo->sla_drain_holes.size());
                 m_parent.set_as_dirty();
                 m_wait_for_up_event = true;
             }
@@ -420,11 +439,11 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
         GLSelectionRectangle::EState rectangle_status = m_selection_rectangle.get_state();
 
         // First collect positions of all the points in world coordinates.
-        Geometry::Transformation trafo = m_c->m_model_object->instances[m_c->m_active_instance]->get_transformation();
+        Geometry::Transformation trafo = mo->instances[active_inst]->get_transformation();
         trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift));
         std::vector<Vec3d> points;
-        for (unsigned int i=0; i<m_c->m_model_object->sla_drain_holes.size(); ++i)
-            points.push_back(trafo.get_matrix() * m_c->m_model_object->sla_drain_holes[i].pos.cast<double>());
+        for (unsigned int i=0; i<mo->sla_drain_holes.size(); ++i)
+            points.push_back(trafo.get_matrix() * mo->sla_drain_holes[i].pos.cast<double>());
 
         // Now ask the rectangle which of the points are inside.
         std::vector<Vec3f> points_inside;
@@ -434,7 +453,9 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
 
         // Only select/deselect points that are actually visible
 #if ENABLE_NON_STATIC_CANVAS_MANAGER
-        for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, wxGetApp().plater()->get_camera(), points_inside, m_c->m_clipping_plane.get()))
+        for (size_t idx : m_c->raycaster()->raycaster()->get_unobscured_idxs(
+                 trafo, wxGetApp().plater()->get_camera(), points_inside,
+                 m_c->object_clipper()->get_clipping_plane()))
 #else
         for (size_t idx :  m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_c->m_clipping_plane.get()))
 #endif // ENABLE_NON_STATIC_CANVAS_MANAGER
@@ -491,20 +512,24 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
     }
 
     if (action == SLAGizmoEventType::MouseWheelUp && control_down) {
-        m_c->m_clipping_plane_distance = std::min(1.f, m_c->m_clipping_plane_distance + 0.01f);
-        update_clipping_plane(m_c->m_clipping_plane_was_moved);
-        m_c->m_clipping_plane_was_moved = true;
+        double pos = m_c->object_clipper()->get_position();
+        pos = std::min(1., pos + 0.01);
+        m_c->object_clipper()->set_position(pos, true);
+        //update_clipping_plane(/*m_c->m_clipping_plane_was_moved*/);
+        //m_c->m_clipping_plane_was_moved = true;
         return true;
     }
 
     if (action == SLAGizmoEventType::MouseWheelDown && control_down) {
-        m_c->m_clipping_plane_distance = std::max(0.f, m_c->m_clipping_plane_distance - 0.01f);
-        update_clipping_plane(true);
+        double pos = m_c->object_clipper()->get_position();
+        pos = std::max(0., pos - 0.01);
+        m_c->object_clipper()->set_position(pos, true);
+        //update_clipping_plane(true);
         return true;
     }
 
     if (action == SLAGizmoEventType::ResetClippingPlane) {
-        update_clipping_plane();
+        m_c->object_clipper()->set_position(-1., false);
         return true;
     }
 
@@ -514,11 +539,12 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
 void GLGizmoHollow::delete_selected_points()
 {
     Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Delete drainage hole")));
+    sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
 
-    for (unsigned int idx=0; idx<m_c->m_model_object->sla_drain_holes.size(); ++idx) {
+    for (unsigned int idx=0; idx<drain_holes.size(); ++idx) {
         if (m_selected[idx]) {
             m_selected.erase(m_selected.begin()+idx);
-            m_c->m_model_object->sla_drain_holes.erase(m_c->m_model_object->sla_drain_holes.begin() + (idx--));
+            drain_holes.erase(drain_holes.begin() + (idx--));
         }
     }
 
@@ -527,12 +553,14 @@ void GLGizmoHollow::delete_selected_points()
 
 void GLGizmoHollow::on_update(const UpdateData& data)
 {
+    sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
+
     if (m_hover_id != -1) {
         std::pair<Vec3f, Vec3f> pos_and_normal;
         if (! unproject_on_mesh(data.mouse_pos.cast<double>(), pos_and_normal))
             return;
-        m_c->m_model_object->sla_drain_holes[m_hover_id].pos = pos_and_normal.first + m_c->HoleStickOutLength * pos_and_normal.second;
-        m_c->m_model_object->sla_drain_holes[m_hover_id].normal = -pos_and_normal.second;
+        drain_holes[m_hover_id].pos = pos_and_normal.first + HoleStickOutLength * pos_and_normal.second;
+        drain_holes[m_hover_id].normal = -pos_and_normal.second;
     }
 }
 
@@ -540,19 +568,22 @@ void GLGizmoHollow::on_update(const UpdateData& data)
 void GLGizmoHollow::hollow_mesh(bool postpone_error_messages)
 {
     wxGetApp().CallAfter([this, postpone_error_messages]() {
-        wxGetApp().plater()->reslice_SLA_hollowing(*m_c->m_model_object, postpone_error_messages);
+        wxGetApp().plater()->reslice_SLA_hollowing(
+            *m_c->selection_info()->model_object(), postpone_error_messages);
     });
 }
 
 
-std::vector<std::pair<const ConfigOption*, const ConfigOptionDef*>> GLGizmoHollow::get_config_options(const std::vector<std::string>& keys) const
+std::vector<std::pair<const ConfigOption*, const ConfigOptionDef*>>
+GLGizmoHollow::get_config_options(const std::vector<std::string>& keys) const
 {
     std::vector<std::pair<const ConfigOption*, const ConfigOptionDef*>> out;
+    const ModelObject* mo = m_c->selection_info()->model_object();
 
-    if (!m_c->m_model_object)
+    if (! mo)
         return out;
 
-    const DynamicPrintConfig& object_cfg = m_c->m_model_object->config;
+    const DynamicPrintConfig& object_cfg = mo->config;
     const DynamicPrintConfig& print_cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
     std::unique_ptr<DynamicPrintConfig> default_cfg = nullptr;
 
@@ -575,16 +606,21 @@ std::vector<std::pair<const ConfigOption*, const ConfigOptionDef*>> GLGizmoHollo
 
 ClippingPlane GLGizmoHollow::get_sla_clipping_plane() const
 {
-    if (!m_c->m_model_object || m_state == Off || m_c->m_clipping_plane_distance == 0.f)
+    if (! m_c->selection_info()->model_object()
+     || m_state == Off
+     || m_c->object_clipper()->get_position() == 0.)
         return ClippingPlane::ClipsNothing();
-    else
-        return ClippingPlane(-m_c->m_clipping_plane->get_normal(), m_c->m_clipping_plane->get_data()[3]);
+    else {
+        const ClippingPlane& clp = *m_c->object_clipper()->get_clipping_plane();
+        return ClippingPlane(-clp.get_normal(), clp.get_data()[3]);
+    }
 }
 
 
 void GLGizmoHollow::on_render_input_window(float x, float y, float bottom_limit)
 {
-    if (! m_c->m_model_object)
+    ModelObject* mo = m_c->selection_info()->model_object();
+    if (! mo)
         return;
 
     bool first_run = true; // This is a hack to redraw the button when all points are removed,
@@ -650,7 +686,7 @@ RENDER_AGAIN:
         auto opts = get_config_options({"hollowing_enable"});
         m_enable_hollowing = static_cast<const ConfigOptionBool*>(opts[0].first)->value;
         if (m_imgui->checkbox(m_desc["enable"], m_enable_hollowing)) {
-            m_c->m_model_object->config.opt<ConfigOptionBool>("hollowing_enable", true)->value = m_enable_hollowing;
+            mo->config.opt<ConfigOptionBool>("hollowing_enable", true)->value = m_enable_hollowing;
             wxGetApp().obj_list()->update_and_show_object_settings_item();
             config_changed = true;
         }
@@ -712,14 +748,14 @@ RENDER_AGAIN:
     }
     if (slider_edited || slider_released) {
         if (slider_released) {
-            m_c->m_model_object->config.opt<ConfigOptionFloat>("hollowing_min_thickness", true)->value = m_offset_stash;
-            m_c->m_model_object->config.opt<ConfigOptionFloat>("hollowing_quality", true)->value = m_quality_stash;
-            m_c->m_model_object->config.opt<ConfigOptionFloat>("hollowing_closing_distance", true)->value = m_closing_d_stash;
+            mo->config.opt<ConfigOptionFloat>("hollowing_min_thickness", true)->value = m_offset_stash;
+            mo->config.opt<ConfigOptionFloat>("hollowing_quality", true)->value = m_quality_stash;
+            mo->config.opt<ConfigOptionFloat>("hollowing_closing_distance", true)->value = m_closing_d_stash;
             Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Hollowing parameter change")));
         }
-        m_c->m_model_object->config.opt<ConfigOptionFloat>("hollowing_min_thickness", true)->value = offset;
-        m_c->m_model_object->config.opt<ConfigOptionFloat>("hollowing_quality", true)->value = quality;
-        m_c->m_model_object->config.opt<ConfigOptionFloat>("hollowing_closing_distance", true)->value = closing_d;
+        mo->config.opt<ConfigOptionFloat>("hollowing_min_thickness", true)->value = offset;
+        mo->config.opt<ConfigOptionFloat>("hollowing_quality", true)->value = quality;
+        mo->config.opt<ConfigOptionFloat>("hollowing_closing_distance", true)->value = closing_d;
         if (slider_released) {
             wxGetApp().obj_list()->update_and_show_object_settings_item();
             config_changed = true;
@@ -750,9 +786,9 @@ RENDER_AGAIN:
 
     m_imgui->text(m_desc["hole_depth"]);
     ImGui::SameLine(diameter_slider_left);
-    m_new_hole_height -= m_c->HoleStickOutLength;
+    m_new_hole_height -= HoleStickOutLength;
     ImGui::SliderFloat("  ", &m_new_hole_height, 0.f, 10.f, "%.1f mm");
-    m_new_hole_height += m_c->HoleStickOutLength;
+    m_new_hole_height += HoleStickOutLength;
 
     clicked |= ImGui::IsItemClicked();
     edited |= ImGui::IsItemEdited();
@@ -764,19 +800,19 @@ RENDER_AGAIN:
     //  - take correct undo/redo snapshot after the user is done with moving the slider
     if (! m_selection_empty) {
         if (clicked) {
-            m_holes_stash = m_c->m_model_object->sla_drain_holes;
+            m_holes_stash = mo->sla_drain_holes;
         }
         if (edited) {
             for (size_t idx=0; idx<m_selected.size(); ++idx)
                 if (m_selected[idx]) {
-                    m_c->m_model_object->sla_drain_holes[idx].radius = m_new_hole_radius;
-                    m_c->m_model_object->sla_drain_holes[idx].height = m_new_hole_height;
+                    mo->sla_drain_holes[idx].radius = m_new_hole_radius;
+                    mo->sla_drain_holes[idx].height = m_new_hole_height;
                 }
         }
         if (deactivated) {
             // momentarily restore the old value to take snapshot
-            sla::DrainHoles new_holes = m_c->m_model_object->sla_drain_holes;
-            m_c->m_model_object->sla_drain_holes = m_holes_stash;
+            sla::DrainHoles new_holes = mo->sla_drain_holes;
+            mo->sla_drain_holes = m_holes_stash;
             float backup_rad = m_new_hole_radius;
             float backup_hei = m_new_hole_height;
             for (size_t i=0; i<m_holes_stash.size(); ++i) {
@@ -789,7 +825,7 @@ RENDER_AGAIN:
             Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Change drainage hole diameter")));
             m_new_hole_radius = backup_rad;
             m_new_hole_height = backup_hei;
-            m_c->m_model_object->sla_drain_holes = new_holes;
+            mo->sla_drain_holes = new_holes;
         }
     }
 
@@ -797,35 +833,35 @@ RENDER_AGAIN:
     remove_selected = m_imgui->button(m_desc.at("remove_selected"));
     m_imgui->disabled_end();
 
-    m_imgui->disabled_begin(m_c->m_model_object->sla_drain_holes.empty());
+    m_imgui->disabled_begin(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();
-    if (m_c->m_clipping_plane_distance == 0.f)
+    if (m_c->object_clipper()->get_position() == 0.f)
         m_imgui->text(m_desc.at("clipping_of_view"));
     else {
         if (m_imgui->button(m_desc.at("reset_direction"))) {
             wxGetApp().CallAfter([this](){
-                    update_clipping_plane();
+                    m_c->object_clipper()->set_position(-1., false);
                 });
         }
     }
 
     ImGui::SameLine(clipping_slider_left);
     ImGui::PushItemWidth(window_width - clipping_slider_left);
-    if (ImGui::SliderFloat("     ", &m_c->m_clipping_plane_distance, 0.f, 1.f, "%.2f")) {
-        update_clipping_plane(m_c->m_clipping_plane_was_moved);
-        m_c->m_clipping_plane_was_moved = true;
-    }
+    float clp_dist = m_c->object_clipper()->get_position();
+    if (ImGui::SliderFloat("     ", &clp_dist, 0.f, 1.f, "%.2f"))
+        m_c->object_clipper()->set_position(clp_dist, true);
 
     // make sure supports are shown/hidden as appropriate
-    if (m_imgui->checkbox(m_desc["show_supports"], m_show_supports)) {
-        m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, m_c->m_model_object, m_c->m_active_instance);
-        force_refresh = true;
-    }
+    // DODELAT
+    //if (m_imgui->checkbox(m_desc["show_supports"], m_show_supports)) {
+    //    m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, mo, m_c->m_active_instance);
+    //    force_refresh = true;
+    //}
 
     m_imgui->end();
 
@@ -882,18 +918,28 @@ std::string GLGizmoHollow::on_get_name() const
 }
 
 
+CommonGizmosDataID GLGizmoHollow::on_get_requirements() const
+{
+    return CommonGizmosDataID(
+                int(CommonGizmosDataID::SelectionInfo)
+              | int(CommonGizmosDataID::InstancesHider)
+              | int(CommonGizmosDataID::Raycaster)
+              | int(CommonGizmosDataID::HollowedMesh)
+              | int(CommonGizmosDataID::ObjectClipper));
+}
+
 
 void GLGizmoHollow::on_set_state()
 {
     // m_c->m_model_object pointer can be invalid (for instance because of undo/redo action),
     // we should recover it from the object id
-    m_c->m_model_object = nullptr;
+    /*m_c->m_model_object = nullptr;
     for (const auto mo : wxGetApp().model().objects) {
         if (mo->id() == m_c->m_model_object_id) {
             m_c->m_model_object = mo;
             break;
         }
-    }
+    }*/
 
     if (m_state == m_old_state)
         return;
@@ -901,31 +947,31 @@ void GLGizmoHollow::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")));
         //m_c->update_from_backend(m_parent, m_c->m_model_object);
-        m_c->unstash_clipping_plane();
-        update_clipping_plane(m_c->m_clipping_plane_was_moved);
+        //m_c->unstash_clipping_plane();
+        //update_clipping_plane(/*m_c->m_clipping_plane_was_moved*/);
 
-        m_c->build_AABB_if_needed();
+        //m_c->build_AABB_if_needed();
 
         // we'll now reload support points:
-        if (m_c->m_model_object)
+        if (m_c->selection_info()->model_object())
             reload_cache();
 
-        m_parent.toggle_model_objects_visibility(false);
+        /*m_parent.toggle_model_objects_visibility(false);
         if (m_c->m_model_object) {
             m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
             m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, m_c->m_model_object, m_c->m_active_instance);
-        }
+        }*/
     }
     if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
         //Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned off")));
         m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE));
         m_parent.toggle_model_objects_visibility(true);
-        m_c->stash_clipping_plane();
-        m_c->m_clipping_plane_distance = 0.f;
-        update_clipping_plane(true);
+        //m_c->stash_clipping_plane();
+        //m_c->m_clipping_plane_distance = 0.f;
+        //update_clipping_plane(true);
         // Release clippers and the AABB raycaster.
-        m_c->m_object_clipper.reset();
-        m_c->m_supports_clipper.reset();
+        //m_c->m_object_clipper.reset();
+        //m_c->m_supports_clipper.reset();
         //m_c->m_mesh_raycaster.reset();
         //m_c->m_cavity_mesh.reset();
         //m_c->m_volume_with_cavity.reset();
@@ -940,7 +986,7 @@ void GLGizmoHollow::on_start_dragging()
     if (m_hover_id != -1) {
         select_point(NoPoints);
         select_point(m_hover_id);
-        m_hole_before_drag = m_c->m_model_object->sla_drain_holes[m_hover_id].pos;
+        m_hole_before_drag = m_c->selection_info()->model_object()->sla_drain_holes[m_hover_id].pos;
     }
     else
         m_hole_before_drag = Vec3f::Zero();
@@ -949,15 +995,16 @@ void GLGizmoHollow::on_start_dragging()
 
 void GLGizmoHollow::on_stop_dragging()
 {
+    sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
     if (m_hover_id != -1) {
-        Vec3f backup = m_c->m_model_object->sla_drain_holes[m_hover_id].pos;
+        Vec3f backup = drain_holes[m_hover_id].pos;
 
         if (m_hole_before_drag != Vec3f::Zero() // some point was touched
          && backup != m_hole_before_drag) // and it was moved, not just selected
         {
-            m_c->m_model_object->sla_drain_holes[m_hover_id].pos = m_hole_before_drag;
+            drain_holes[m_hover_id].pos = m_hole_before_drag;
             Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Move drainage hole")));
-            m_c->m_model_object->sla_drain_holes[m_hover_id].pos = backup;
+            drain_holes[m_hover_id].pos = backup;
         }
     }
     m_hole_before_drag = Vec3f::Zero();
@@ -967,10 +1014,7 @@ void GLGizmoHollow::on_stop_dragging()
 
 void GLGizmoHollow::on_load(cereal::BinaryInputArchive& ar)
 {
-    ar(m_c->m_clipping_plane_distance,
-       *m_c->m_clipping_plane,
-       m_c->m_model_object_id,
-       m_new_hole_radius,
+    ar(m_new_hole_radius,
        m_new_hole_height,
        m_selected,
        m_selection_empty
@@ -981,10 +1025,7 @@ void GLGizmoHollow::on_load(cereal::BinaryInputArchive& ar)
 
 void GLGizmoHollow::on_save(cereal::BinaryOutputArchive& ar) const
 {
-    ar(m_c->m_clipping_plane_distance,
-       *m_c->m_clipping_plane,
-       m_c->m_model_object_id,
-       m_new_hole_radius,
+    ar(m_new_hole_radius,
        m_new_hole_height,
        m_selected,
        m_selection_empty
@@ -995,13 +1036,15 @@ void GLGizmoHollow::on_save(cereal::BinaryOutputArchive& ar) const
 
 void GLGizmoHollow::select_point(int i)
 {
+    const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
+
     if (i == AllPoints || i == NoPoints) {
         m_selected.assign(m_selected.size(), i == AllPoints);
         m_selection_empty = (i == NoPoints);
 
         if (i == AllPoints) {
-            m_new_hole_radius = m_c->m_model_object->sla_drain_holes[0].radius;
-            m_new_hole_height = m_c->m_model_object->sla_drain_holes[0].height;
+            m_new_hole_radius = drain_holes[0].radius;
+            m_new_hole_height = drain_holes[0].height;
         }
     }
     else {
@@ -1009,8 +1052,8 @@ void GLGizmoHollow::select_point(int i)
             m_selected.push_back(false);
         m_selected[i] = true;
         m_selection_empty = false;
-        m_new_hole_radius = m_c->m_model_object->sla_drain_holes[i].radius;
-        m_new_hole_height = m_c->m_model_object->sla_drain_holes[i].height;
+        m_new_hole_radius = drain_holes[i].radius;
+        m_new_hole_height = drain_holes[i].height;
     }
 }
 
@@ -1030,31 +1073,13 @@ void GLGizmoHollow::unselect_point(int i)
 void GLGizmoHollow::reload_cache()
 {
     m_selected.clear();
-    m_selected.assign(m_c->m_model_object->sla_drain_holes.size(), false);
-}
-
-void GLGizmoHollow::update_clipping_plane(bool keep_normal) const
-{
-    if (! m_c->m_model_object)
-        return;
-#if ENABLE_NON_STATIC_CANVAS_MANAGER
-    Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
-        m_c->m_clipping_plane->get_normal() : -wxGetApp().plater()->get_camera().get_dir_forward());
-#else
-    Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
-                        m_c->m_clipping_plane->get_normal() : -m_parent.get_camera().get_dir_forward());
-#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
-
-    const Vec3d& center = m_c->m_model_object->instances[m_c->m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift);
-    float dist = normal.dot(center);
-    *m_c->m_clipping_plane = ClippingPlane(normal, (dist - (-m_c->m_active_instance_bb_radius) - m_c->m_clipping_plane_distance * 2*m_c->m_active_instance_bb_radius));
-    m_parent.set_as_dirty();
+    m_selected.assign(m_c->selection_info()->model_object()->sla_drain_holes.size(), false);
 }
 
 
 void GLGizmoHollow::on_set_hover_id()
 {
-    if (int(m_c->m_model_object->sla_drain_holes.size()) <= m_hover_id)
+    if (int(m_c->selection_info()->model_object()->sla_drain_holes.size()) <= m_hover_id)
         m_hover_id = -1;
 }
 
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
index 3aafcbf55..a33721519 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
@@ -16,7 +16,7 @@ namespace GUI {
 class ClippingPlane;
 class MeshClipper;
 class MeshRaycaster;
-class CommonGizmosData;
+//class CommonGizmosData;
 enum class SLAGizmoEventType : unsigned char;
 
 class GLGizmoHollow : public GLGizmoBase
@@ -37,8 +37,7 @@ public:
     ClippingPlane get_sla_clipping_plane() const;
     
     bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); }
-    void update_clipping_plane(bool keep_normal = false) const;
-    void set_common_data_ptr(CommonGizmosData* ptr) { m_c = ptr; }
+    //void set_common_data_ptr(CommonGizmosData* ptr) { m_c = ptr; }
 
 private:
     bool on_init() override;
@@ -68,7 +67,7 @@ private:
 
     sla::DrainHoles m_holes_stash;
 
-    CommonGizmosData* m_c = nullptr;
+    //CommonGizmosData* m_c = nullptr;
 
     //std::unique_ptr<ClippingPlane> m_clipping_plane;
     
@@ -101,6 +100,7 @@ protected:
     void on_start_dragging() override;
     void on_stop_dragging() override;
     void on_render_input_window(float x, float y, float bottom_limit) override;
+    virtual CommonGizmosDataID on_get_requirements() const override;
 
     std::string on_get_name() const override;
     bool on_is_activable() const override;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index ecbe75165..792fd0e91 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -4,6 +4,10 @@
 
 #include "slic3r/GUI/GLCanvas3D.hpp"
 #include "libslic3r/SLAPrint.hpp"
+#include "slic3r/GUI/GUI_App.hpp"
+#include "slic3r/GUI/Camera.hpp"
+
+#include <GL/glew.h>
 
 namespace Slic3r {
 namespace GUI {
@@ -18,7 +22,7 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
     m_data[c::InstancesHider].reset(      new InstancesHider(this));
     m_data[c::HollowedMesh].reset(        new HollowedMesh(this));
     m_data[c::Raycaster].reset(           new Raycaster(this));
-    //m_data[c::ObjectClipper].reset(new ClippingPlaneWrapper(this));
+    m_data[c::ObjectClipper].reset(new ObjectClipper(this));
     //m_data[c::SupportsClipper].reset(     new SupportsClipper(this));
 
 }
@@ -37,27 +41,34 @@ void CommonGizmosDataPool::update(CommonGizmosDataID required)
 }
 
 
-SelectionInfo* CommonGizmosDataPool::selection_info()
+SelectionInfo* CommonGizmosDataPool::selection_info() const
 {
-    SelectionInfo* sel_info = dynamic_cast<SelectionInfo*>(m_data[CommonGizmosDataID::SelectionInfo].get());
+    SelectionInfo* sel_info = dynamic_cast<SelectionInfo*>(m_data.at(CommonGizmosDataID::SelectionInfo).get());
     assert(sel_info);
     return sel_info->is_valid() ? sel_info : nullptr;
 }
 
-HollowedMesh* CommonGizmosDataPool::hollowed_mesh()
+HollowedMesh* CommonGizmosDataPool::hollowed_mesh() const
 {
-    HollowedMesh* hol_mesh = dynamic_cast<HollowedMesh*>(m_data[CommonGizmosDataID::HollowedMesh].get());
+    HollowedMesh* hol_mesh = dynamic_cast<HollowedMesh*>(m_data.at(CommonGizmosDataID::HollowedMesh).get());
     assert(hol_mesh);
     return hol_mesh->is_valid() ? hol_mesh : nullptr;
 }
 
-Raycaster* CommonGizmosDataPool::raycaster()
+Raycaster* CommonGizmosDataPool::raycaster() const
 {
-    Raycaster* rc = dynamic_cast<Raycaster*>(m_data[CommonGizmosDataID::Raycaster].get());
+    Raycaster* rc = dynamic_cast<Raycaster*>(m_data.at(CommonGizmosDataID::Raycaster).get());
     assert(rc);
     return rc->is_valid() ? rc : nullptr;
 }
 
+ObjectClipper* CommonGizmosDataPool::object_clipper() const
+{
+    ObjectClipper* oc = dynamic_cast<ObjectClipper*>(m_data.at(CommonGizmosDataID::ObjectClipper).get());
+    assert(oc);
+    return oc->is_valid() ? oc : nullptr;
+}
+
 #ifndef NDEBUG
 // Check the required resources one by one and return true if all
 // dependencies are met.
@@ -87,8 +98,10 @@ bool CommonGizmosDataPool::check_dependencies(CommonGizmosDataID required) const
 void SelectionInfo::on_update()
 {
     const Selection& selection = get_pool()->get_canvas()->get_selection();
-    if (selection.is_single_full_instance())
+    if (selection.is_single_full_instance()) {
         m_model_object = selection.get_model()->objects[selection.get_object_idx()];
+        m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
+    }
     else
         m_model_object = nullptr;
 }
@@ -98,7 +111,7 @@ void SelectionInfo::on_release()
     m_model_object = nullptr;
 }
 
-int SelectionInfo::get_active_instance()
+int SelectionInfo::get_active_instance() const
 {
     const Selection& selection = get_pool()->get_canvas()->get_selection();
     return selection.get_instance_idx();
@@ -239,5 +252,83 @@ std::vector<const MeshRaycaster*> Raycaster::raycasters() const
 
 
 
+void ObjectClipper::on_update()
+{
+    const ModelObject* mo = get_pool()->selection_info()->model_object();
+    if (! mo)
+        return;
+
+    // which mesh should be cut?
+    const TriangleMesh* mesh = &mo->volumes.front()->mesh();
+    bool has_hollowed = get_pool()->hollowed_mesh() && get_pool()->hollowed_mesh()->get_hollowed_mesh();
+    if (has_hollowed)
+        mesh = get_pool()->hollowed_mesh()->get_hollowed_mesh();
+
+    if (mesh != m_old_mesh) {
+        m_clipper.reset(new MeshClipper);
+        m_clipper->set_mesh(*mesh);
+        m_old_mesh = mesh;
+        m_active_inst_bb_radius =
+            mo->instance_bounding_box(get_pool()->selection_info()->get_active_instance()).radius();
+        //if (has_hollowed && m_clp_ratio != 0.)
+        //    m_clp_ratio = 0.25;
+    }
+}
+
+
+void ObjectClipper::on_release()
+{
+    m_clipper.reset();
+    m_old_mesh = nullptr;
+    m_clp.reset();
+
+}
+
+void ObjectClipper::render_cut() const
+{
+    if (m_clp_ratio == 0.)
+        return;
+    const SelectionInfo* sel_info = get_pool()->selection_info();
+    const ModelObject* mo = sel_info->model_object();
+    Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
+    Geometry::Transformation vol_trafo  = mo->volumes.front()->get_transformation();
+    Geometry::Transformation trafo = inst_trafo * vol_trafo;
+    trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
+
+    m_clipper->set_plane(*m_clp);
+    m_clipper->set_transformation(trafo);
+
+    if (! m_clipper->get_triangles().empty()) {
+        ::glPushMatrix();
+        ::glColor3f(1.0f, 0.37f, 0.0f);
+        ::glBegin(GL_TRIANGLES);
+        for (const Vec3f& point : m_clipper->get_triangles())
+            ::glVertex3f(point(0), point(1), point(2));
+        ::glEnd();
+        ::glPopMatrix();
+    }
+}
+
+
+void ObjectClipper::set_position(double pos, bool keep_normal)
+{
+    const ModelObject* mo = get_pool()->selection_info()->model_object();
+    int active_inst = get_pool()->selection_info()->get_active_instance();
+    double z_shift = get_pool()->selection_info()->get_sla_shift();
+
+    Vec3d normal = (keep_normal && m_clp) ? m_clp->get_normal() : -wxGetApp().plater()->get_camera().get_dir_forward();
+    const Vec3d& center = mo->instances[active_inst]->get_offset() + Vec3d(0., 0., z_shift);
+    float dist = normal.dot(center);
+
+    if (pos < 0.)
+        pos = m_clp_ratio;
+
+    m_clp_ratio = pos;
+    m_clp.reset(new ClippingPlane(normal, (dist - (-m_active_inst_bb_radius) - m_clp_ratio * 2*m_active_inst_bb_radius)));
+    get_pool()->get_canvas()->set_as_dirty();
+}
+
+
+
 } // namespace GUI
 } // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index 0b327cce8..7a9cb35b8 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -15,12 +15,17 @@ namespace GUI {
 
 class GLCanvas3D;
 
+static constexpr float HoleStickOutLength = 1.f;
+
+
+
 class CommonGizmosDataBase;
 namespace CommonGizmosDataObjects {
     class SelectionInfo;
     class InstancesHider;
     class HollowedMesh;
     class Raycaster;
+    class ObjectClipper;
 }
 
 // Some of the gizmos use the same data that need to be updated ocassionally.
@@ -55,9 +60,10 @@ public:
     void update(CommonGizmosDataID required);
 
     // Getters for the data that need to be accessed from the gizmos directly.
-    CommonGizmosDataObjects::SelectionInfo* selection_info();
-    CommonGizmosDataObjects::HollowedMesh* hollowed_mesh();
-    CommonGizmosDataObjects::Raycaster* raycaster();
+    CommonGizmosDataObjects::SelectionInfo* selection_info() const;
+    CommonGizmosDataObjects::HollowedMesh* hollowed_mesh() const;
+    CommonGizmosDataObjects::Raycaster* raycaster() const;
+    CommonGizmosDataObjects::ObjectClipper* object_clipper() const;
 
 
     GLCanvas3D* get_canvas() const { return m_canvas; }
@@ -125,8 +131,9 @@ public:
     explicit SelectionInfo(CommonGizmosDataPool* cgdp)
         : CommonGizmosDataBase(cgdp) {}
 
-    ModelObject* model_object() { return m_model_object; }
-    int get_active_instance();
+    ModelObject* model_object() const { return m_model_object; }
+    int get_active_instance() const;
+    float get_sla_shift() const { return m_z_shift; }
 
 protected:
     void on_update() override;
@@ -135,6 +142,7 @@ protected:
 private:
     ModelObject* m_model_object = nullptr;
     int m_active_inst = -1;
+    float m_z_shift = 0.f;
 };
 
 
@@ -200,6 +208,37 @@ private:
     std::vector<const TriangleMesh*> m_old_meshes;
 };
 
+
+
+class ObjectClipper : public CommonGizmosDataBase
+{
+public:
+    explicit ObjectClipper(CommonGizmosDataPool* cgdp)
+        : CommonGizmosDataBase(cgdp) {}
+#ifndef NDEBUG
+    CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
+#endif // NDEBUG
+
+    MeshClipper* get_clipper() const { return m_clipper.get(); }
+    void set_position(double pos, bool keep_normal);
+    double get_position() const { return m_clp_ratio; }
+    ClippingPlane* get_clipping_plane() const { return m_clp.get(); }
+    void render_cut() const;
+
+
+protected:
+    void on_update() override;
+    void on_release() override;
+
+private:
+    const TriangleMesh* m_old_mesh = nullptr;
+    std::unique_ptr<MeshClipper> m_clipper;
+    std::unique_ptr<ClippingPlane> m_clp;
+    double m_clp_ratio = 0.;
+    double m_active_inst_bb_radius = 0.;
+
+};
+
 /*
 
 class ClippingPlaneWrapper : public CommonGizmosDataBase
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 26f42ed34..ed9bd5de3 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -95,7 +95,7 @@ bool GLGizmosManager::init()
     m_gizmos.emplace_back(new GLGizmoRotate3D(m_parent, "rotate.svg", 2));
     m_gizmos.emplace_back(new GLGizmoFlatten(m_parent, "place.svg", 3));
     m_gizmos.emplace_back(new GLGizmoCut(m_parent, "cut.svg", 4));
-    //m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", 5));
+    m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", 5));
     //m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 6));
 
     //m_common_gizmos_data.reset(new CommonGizmosData());
@@ -360,21 +360,22 @@ void GLGizmosManager::set_flattening_data(const ModelObject* model_object)
 
 void GLGizmosManager::set_sla_support_data(ModelObject* model_object)
 {
-    /*if (! m_enabled
+    if (! m_enabled
      || m_gizmos.empty()
      || wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA)
         return;
 
-    m_common_gizmos_data->update_from_backend(m_parent, model_object);
+    /*m_common_gizmos_data->update_from_backend(m_parent, model_object);
 
     auto* gizmo_supports = dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get());
-    auto* gizmo_hollow = dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get());
+
 
     // note: sla support gizmo takes care of updating the common data.
     // following lines are thus dependent
-    gizmo_supports->set_sla_support_data(model_object, m_parent.get_selection());
-    gizmo_hollow->set_sla_support_data(model_object, m_parent.get_selection());
+    //gizmo_supports->set_sla_support_data(model_object, m_parent.get_selection());
     */
+    auto* gizmo_hollow = dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get());
+    gizmo_hollow->set_sla_support_data(model_object, m_parent.get_selection());
 }
 
 // Returns true if the gizmo used the event to do something, false otherwise.

From e82ead0335df913717b7946132c69f725dff35ea Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 7 Apr 2020 11:53:46 +0200
Subject: [PATCH 11/15] InstancesHider allows to show/hide supports on demand

---
 src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp  | 14 +++++++++-----
 src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp  |  2 +-
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 16 ++++++++++++++++
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp |  7 +++++++
 4 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
index f27bc2863..86ad8d0a0 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
@@ -54,6 +54,9 @@ bool GLGizmoHollow::on_init()
 
 void GLGizmoHollow::set_sla_support_data(ModelObject*, const Selection&)
 {
+    if (! m_c->selection_info())
+        return;
+
     const ModelObject* mo = m_c->selection_info()->model_object();
     if (mo) {
         reload_cache();
@@ -857,11 +860,12 @@ RENDER_AGAIN:
         m_c->object_clipper()->set_position(clp_dist, true);
 
     // make sure supports are shown/hidden as appropriate
-    // DODELAT
-    //if (m_imgui->checkbox(m_desc["show_supports"], m_show_supports)) {
-    //    m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, mo, m_c->m_active_instance);
-    //    force_refresh = true;
-    //}
+    bool show_sups = m_c->instances_hider()->are_supports_shown();
+    if (m_imgui->checkbox(m_desc["show_supports"], show_sups)) {
+        //    m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, mo, m_c->m_active_instance);
+        m_c->instances_hider()->show_supports(show_sups);
+        force_refresh = true;
+    }
 
     m_imgui->end();
 
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
index a33721519..178579ba1 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
@@ -50,7 +50,7 @@ private:
     void hollow_mesh(bool postpone_error_messages = false);
     bool unsaved_changes() const;
 
-    bool  m_show_supports = true;
+    // bool  m_show_supports = true;
     float m_new_hole_radius = 2.f;        // Size of a new hole.
     float m_new_hole_height = 6.f;
     mutable std::vector<bool> m_selected; // which holes are currently selected
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index 792fd0e91..a6fbabfa2 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -48,6 +48,14 @@ SelectionInfo* CommonGizmosDataPool::selection_info() const
     return sel_info->is_valid() ? sel_info : nullptr;
 }
 
+
+InstancesHider* CommonGizmosDataPool::instances_hider() const
+{
+    InstancesHider* inst_hider = dynamic_cast<InstancesHider*>(m_data.at(CommonGizmosDataID::InstancesHider).get());
+    assert(inst_hider);
+    return inst_hider->is_valid() ? inst_hider : nullptr;
+}
+
 HollowedMesh* CommonGizmosDataPool::hollowed_mesh() const
 {
     HollowedMesh* hol_mesh = dynamic_cast<HollowedMesh*>(m_data.at(CommonGizmosDataID::HollowedMesh).get());
@@ -130,6 +138,7 @@ void InstancesHider::on_update()
     if (mo && active_inst != -1) {
         canvas->toggle_model_objects_visibility(false);
         canvas->toggle_model_objects_visibility(true, mo, active_inst);
+        canvas->toggle_sla_auxiliaries_visibility(m_show_supports, mo, active_inst);
     }
     else
         canvas->toggle_model_objects_visibility(true);
@@ -140,6 +149,13 @@ void InstancesHider::on_release()
     get_pool()->get_canvas()->toggle_model_objects_visibility(true);
 }
 
+void InstancesHider::show_supports(bool show) {
+    if (m_show_supports != show) {
+        m_show_supports = show;
+        on_update();
+    }
+}
+
 
 
 void HollowedMesh::on_update()
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index 7a9cb35b8..a2fa598c9 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -61,6 +61,7 @@ public:
 
     // Getters for the data that need to be accessed from the gizmos directly.
     CommonGizmosDataObjects::SelectionInfo* selection_info() const;
+    CommonGizmosDataObjects::InstancesHider* instances_hider() const;
     CommonGizmosDataObjects::HollowedMesh* hollowed_mesh() const;
     CommonGizmosDataObjects::Raycaster* raycaster() const;
     CommonGizmosDataObjects::ObjectClipper* object_clipper() const;
@@ -156,9 +157,15 @@ public:
     CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
 #endif // NDEBUG
 
+    void show_supports(bool show);
+    bool are_supports_shown() const { return m_show_supports; }
+
 protected:
     void on_update() override;
     void on_release() override;
+
+private:
+    bool m_show_supports = false;
 };
 
 

From c79e90b921962543f2d6873e9aef1e72d32f5bef Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 7 Apr 2020 13:00:37 +0200
Subject: [PATCH 12/15] SupportsClipper implementation

---
 src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp  |   4 +-
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 112 +++++++++++++++++++++--
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp |  38 +++++---
 3 files changed, 132 insertions(+), 22 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
index 86ad8d0a0..8c705fef8 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
@@ -119,6 +119,7 @@ void GLGizmoHollow::on_render() const
     m_selection_rectangle.render(m_parent);
     //render_clipping_plane(selection);
     m_c->object_clipper()->render_cut();
+    m_c->supports_clipper()->render_cut();
 
     glsafe(::glDisable(GL_BLEND));
 }
@@ -929,7 +930,8 @@ CommonGizmosDataID GLGizmoHollow::on_get_requirements() const
               | int(CommonGizmosDataID::InstancesHider)
               | int(CommonGizmosDataID::Raycaster)
               | int(CommonGizmosDataID::HollowedMesh)
-              | int(CommonGizmosDataID::ObjectClipper));
+              | int(CommonGizmosDataID::ObjectClipper)
+              | int(CommonGizmosDataID::SupportsClipper));
 }
 
 
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index a6fbabfa2..380aa4e7d 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -18,12 +18,12 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
     : m_canvas(canvas)
 {
     using c = CommonGizmosDataID;
-    m_data[c::SelectionInfo].reset(       new SelectionInfo(this));
-    m_data[c::InstancesHider].reset(      new InstancesHider(this));
-    m_data[c::HollowedMesh].reset(        new HollowedMesh(this));
-    m_data[c::Raycaster].reset(           new Raycaster(this));
-    m_data[c::ObjectClipper].reset(new ObjectClipper(this));
-    //m_data[c::SupportsClipper].reset(     new SupportsClipper(this));
+    m_data[c::SelectionInfo].reset(   new SelectionInfo(this));
+    m_data[c::InstancesHider].reset(  new InstancesHider(this));
+    m_data[c::HollowedMesh].reset(    new HollowedMesh(this));
+    m_data[c::Raycaster].reset(       new Raycaster(this));
+    m_data[c::ObjectClipper].reset(   new ObjectClipper(this));
+    m_data[c::SupportsClipper].reset( new SupportsClipper(this));
 
 }
 
@@ -77,6 +77,13 @@ ObjectClipper* CommonGizmosDataPool::object_clipper() const
     return oc->is_valid() ? oc : nullptr;
 }
 
+SupportsClipper* CommonGizmosDataPool::supports_clipper() const
+{
+    SupportsClipper* sc = dynamic_cast<SupportsClipper*>(m_data.at(CommonGizmosDataID::SupportsClipper).get());
+    assert(sc);
+    return sc->is_valid() ? sc : nullptr;
+}
+
 #ifndef NDEBUG
 // Check the required resources one by one and return true if all
 // dependencies are met.
@@ -346,5 +353,98 @@ void ObjectClipper::set_position(double pos, bool keep_normal)
 
 
 
+void SupportsClipper::on_update()
+{
+    const ModelObject* mo = get_pool()->selection_info()->model_object();
+    if (! mo)
+        return;
+
+    const GLCanvas3D* canvas = get_pool()->get_canvas();
+    const PrintObjects& print_objects = canvas->sla_print()->objects();
+    const SLAPrintObject* print_object = m_print_object_idx != -1
+            ? print_objects[m_print_object_idx]
+            : nullptr;
+
+    // Find the respective SLAPrintObject.
+    if (m_print_object_idx < 0 || m_print_objects_count != int(print_objects.size())) {
+        m_print_objects_count = print_objects.size();
+        m_print_object_idx = -1;
+        for (const SLAPrintObject* po : print_objects) {
+            ++m_print_object_idx;
+            if (po->model_object()->id() == mo->id()) {
+                print_object = po;
+                break;
+            }
+        }
+    }
+
+    if (print_object
+     && print_object->is_step_done(slaposSupportTree)
+     && ! print_object->support_mesh().empty())
+    {
+        // If the supports are already calculated, save the timestamp of the respective step
+        // so we can later tell they were recalculated.
+        size_t timestamp = print_object->step_state_with_timestamp(slaposSupportTree).timestamp;
+        if (! m_clipper || timestamp != m_old_timestamp) {
+            // The timestamp has changed.
+            m_clipper.reset(new MeshClipper);
+            // The mesh should already have the shared vertices calculated.
+            m_clipper->set_mesh(print_object->support_mesh());
+            m_old_timestamp = timestamp;
+        }
+    }
+    else
+        // The supports are not valid. We better dump the cached data.
+        m_clipper.reset();
+}
+
+
+void SupportsClipper::on_release()
+{
+    m_clipper.reset();
+    m_old_timestamp = 0;
+    m_print_object_idx = -1;
+}
+
+void SupportsClipper::render_cut() const
+{
+    const CommonGizmosDataObjects::ObjectClipper* ocl = get_pool()->object_clipper();
+    if (ocl->get_position() == 0.
+     || ! get_pool()->instances_hider()->are_supports_shown()
+     || ! m_clipper)
+        return;
+
+    const SelectionInfo* sel_info = get_pool()->selection_info();
+    const ModelObject* mo = sel_info->model_object();
+    Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
+    Geometry::Transformation vol_trafo  = mo->volumes.front()->get_transformation();
+    Geometry::Transformation trafo = inst_trafo;// * vol_trafo;
+    trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
+
+
+    // Get transformation of supports
+    Geometry::Transformation supports_trafo = trafo;
+    supports_trafo.set_offset(Vec3d(trafo.get_offset()(0), trafo.get_offset()(1), sel_info->get_sla_shift()));
+    supports_trafo.set_rotation(Vec3d(0., 0., trafo.get_rotation()(2)));
+    // I don't know why, but following seems to be correct.
+    supports_trafo.set_mirror(Vec3d(trafo.get_mirror()(0) * trafo.get_mirror()(1) * trafo.get_mirror()(2),
+                                    1,
+                                    1.));
+
+    m_clipper->set_plane(*ocl->get_clipping_plane());
+    m_clipper->set_transformation(supports_trafo);
+
+    if (! m_clipper->get_triangles().empty()) {
+        ::glPushMatrix();
+        ::glColor3f(1.0f, 0.f, 0.37f);
+        ::glBegin(GL_TRIANGLES);
+        for (const Vec3f& point : m_clipper->get_triangles())
+            ::glVertex3f(point(0), point(1), point(2));
+        ::glEnd();
+        ::glPopMatrix();
+    }
+}
+
+
 } // namespace GUI
 } // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index a2fa598c9..54e561f2f 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -26,6 +26,7 @@ namespace CommonGizmosDataObjects {
     class HollowedMesh;
     class Raycaster;
     class ObjectClipper;
+    class SupportsClipper;
 }
 
 // Some of the gizmos use the same data that need to be updated ocassionally.
@@ -65,6 +66,7 @@ public:
     CommonGizmosDataObjects::HollowedMesh* hollowed_mesh() const;
     CommonGizmosDataObjects::Raycaster* raycaster() const;
     CommonGizmosDataObjects::ObjectClipper* object_clipper() const;
+    CommonGizmosDataObjects::SupportsClipper* supports_clipper() const;
 
 
     GLCanvas3D* get_canvas() const { return m_canvas; }
@@ -226,7 +228,6 @@ public:
     CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
 #endif // NDEBUG
 
-    MeshClipper* get_clipper() const { return m_clipper.get(); }
     void set_position(double pos, bool keep_normal);
     double get_position() const { return m_clp_ratio; }
     ClippingPlane* get_clipping_plane() const { return m_clp.get(); }
@@ -243,17 +244,6 @@ private:
     std::unique_ptr<ClippingPlane> m_clp;
     double m_clp_ratio = 0.;
     double m_active_inst_bb_radius = 0.;
-
-};
-
-/*
-
-class ClippingPlaneWrapper : public CommonGizmosDataBase
-{
-public:
-    explicit ClippingPlaneWrapper(CommonGizmosDataPool* cgdp)
-        : CommonGizmosDataBase(cgdp) {}
-    void update(bool required) override;
 };
 
 
@@ -263,10 +253,28 @@ class SupportsClipper : public CommonGizmosDataBase
 public:
     explicit SupportsClipper(CommonGizmosDataPool* cgdp)
         : CommonGizmosDataBase(cgdp) {}
-    void update(bool required) override;
-};
+#ifndef NDEBUG
+    CommonGizmosDataID get_dependencies() const override {
+        return CommonGizmosDataID(
+                    int(CommonGizmosDataID::SelectionInfo)
+                  | int(CommonGizmosDataID::ObjectClipper)
+               );
+    }
+#endif // NDEBUG
 
-*/
+    void render_cut() const;
+
+
+protected:
+    void on_update() override;
+    void on_release() override;
+
+private:
+    size_t m_old_timestamp = 0;
+    int m_print_object_idx = -1;
+    int m_print_objects_count = 0;
+    std::unique_ptr<MeshClipper> m_clipper;
+};
 
 } // namespace CommonGizmosDataObjects
 

From c704849a7a8ccb6c30e718257bda4b73708dbd18 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 7 Apr 2020 15:38:24 +0200
Subject: [PATCH 13/15] SLA supports gizmo is now enabled and uses the new
 infrastructure

---
 src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp      |   2 +-
 src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 261 ++++++++++++-------
 src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp |  14 +-
 src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp     |  18 +-
 src/slic3r/GUI/Gizmos/GLGizmosManager.cpp    |  14 +-
 src/slic3r/GUI/Gizmos/GLGizmosManager.hpp    |  12 +-
 6 files changed, 194 insertions(+), 127 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
index 8c705fef8..46c570c19 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
@@ -971,7 +971,7 @@ void GLGizmoHollow::on_set_state()
     if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
         //Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned off")));
         m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE));
-        m_parent.toggle_model_objects_visibility(true);
+        //m_parent.toggle_model_objects_visibility(true);
         //m_c->stash_clipping_plane();
         //m_c->m_clipping_plane_distance = 0.f;
         //update_clipping_plane(true);
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
index 064302c02..ac65d9313 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
@@ -3,6 +3,7 @@
 #include "slic3r/GUI/GLCanvas3D.hpp"
 #include "slic3r/GUI/Camera.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmos.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
 
 #include <GL/glew.h>
 
@@ -14,9 +15,6 @@
 #include "slic3r/GUI/GUI.hpp"
 #include "slic3r/GUI/GUI_ObjectSettings.hpp"
 #include "slic3r/GUI/GUI_ObjectList.hpp"
-#if ENABLE_NON_STATIC_CANVAS_MANAGER
-#include "slic3r/GUI/Camera.hpp"
-#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
 #include "slic3r/GUI/MeshUtils.hpp"
 #include "slic3r/GUI/Plater.hpp"
 #include "slic3r/GUI/PresetBundle.hpp"
@@ -66,6 +64,19 @@ bool GLGizmoSlaSupports::on_init()
 
 void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const Selection& selection)
 {
+    if (! m_c->selection_info())
+        return;
+
+    ModelObject* mo = m_c->selection_info()->model_object();
+
+    if (mo != m_old_mo) {
+        disable_editing_mode();
+        if (mo)
+            reload_cache();
+        m_old_mo = mo;
+    }
+
+    /*
     if (m_c->recent_update) {
         if (m_state == On)
             m_c->build_AABB_if_needed();
@@ -81,11 +92,11 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S
         m_parent.toggle_model_objects_visibility(false);
         m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
         m_parent.toggle_sla_auxiliaries_visibility(! m_editing_mode, m_c->m_model_object, m_c->m_active_instance);
-    }
+    }*/
 
     // If we triggered autogeneration before, check backend and fetch results if they are there
-    if (m_c->m_model_object) {
-        if (m_c->m_model_object->sla_points_status == sla::PointsStatus::Generating)
+    if (mo) {
+        if (mo->sla_points_status == sla::PointsStatus::Generating)
             get_data_from_backend();
     }
 }
@@ -94,13 +105,14 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S
 
 void GLGizmoSlaSupports::on_render() const
 {
+    ModelObject* mo = m_c->selection_info()->model_object();
     const Selection& selection = m_parent.get_selection();
 
     // If current m_c->m_model_object does not match selection, ask GLCanvas3D to turn us off
     if (m_state == On
-     && (m_c->m_model_object != selection.get_model()->objects[selection.get_object_idx()]
-      || m_c->m_active_instance != selection.get_instance_idx()
-      || m_c->m_model_object_id != m_c->m_model_object->id())) {
+     && (mo != selection.get_model()->objects[selection.get_object_idx()]
+      || m_c->selection_info()->get_active_instance() != selection.get_instance_idx()
+      /*|| m_c->m_model_object_id != m_c->m_model_object->id()*/)) {
         m_parent.post_event(SimpleEvent(EVT_GLCANVAS_RESETGIZMOS));
         return;
     }
@@ -108,20 +120,22 @@ void GLGizmoSlaSupports::on_render() const
     glsafe(::glEnable(GL_BLEND));
     glsafe(::glEnable(GL_DEPTH_TEST));
 
-    m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
+//    m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
 
     if (m_quadric != nullptr && selection.is_from_single_instance())
         render_points(selection, false);
 
     m_selection_rectangle.render(m_parent);
-    render_clipping_plane(selection);
+    m_c->object_clipper()->render_cut();
+    m_c->supports_clipper()->render_cut();
+    //render_clipping_plane(selection);
 
     glsafe(::glDisable(GL_BLEND));
 }
 
 
 
-void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection) const
+/*void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection) const
 {
     if (m_c->m_clipping_plane_distance == 0.f || m_c->m_mesh->empty())
         return;
@@ -205,16 +219,17 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection) const
         ::glEnd();
 		::glPopMatrix();
 	}
-}
+}*/
 
 
 void GLGizmoSlaSupports::on_render_for_picking() const
 {
     const Selection& selection = m_parent.get_selection();
+/*
 #if ENABLE_RENDER_PICKING_PASS
 	m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
 #endif
-
+*/
     glsafe(::glEnable(GL_DEPTH_TEST));
     render_points(selection, true);
 }
@@ -227,9 +242,10 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
     const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
     const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
     const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
+    float z_shift = m_c->selection_info()->get_sla_shift();
 
     glsafe(::glPushMatrix());
-    glsafe(::glTranslated(0.0, 0.0, m_z_shift));
+    glsafe(::glTranslated(0.0, 0.0, z_shift));
     glsafe(::glMultMatrixd(instance_matrix.data()));
 
     float render_color[4];
@@ -285,7 +301,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
         if (m_editing_mode) {
             // in case the normal is not yet cached, find and cache it
             if (m_editing_cache[i].normal == Vec3f::Zero())
-                m_c->m_mesh_raycaster->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal);
+                m_c->raycaster()->raycaster()->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal);
 
             Eigen::Quaterniond q;
             q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast<double>());
@@ -315,14 +331,15 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
     }
 
     // Now render the drain holes:
-    if (! m_c->has_drilled_mesh()) {
+    //if (! m_c->has_drilled_mesh()) {
+    if (! m_c->hollowed_mesh()->get_hollowed_mesh()) {
         render_color[0] = 0.7f;
         render_color[1] = 0.7f;
         render_color[2] = 0.7f;
         render_color[3] = 0.7f;
         glsafe(::glColor4fv(render_color));
-        for (const sla::DrainHole& drain_hole : m_c->m_model_object->sla_drain_holes) {
-            if (is_mesh_point_clipped((drain_hole.pos+m_c->HoleStickOutLength*drain_hole.normal).cast<double>()))
+        for (const sla::DrainHole& drain_hole : m_c->selection_info()->model_object()->sla_drain_holes) {
+            if (is_mesh_point_clipped((drain_hole.pos+HoleStickOutLength*drain_hole.normal).cast<double>()))
                 continue;
 
             // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
@@ -365,12 +382,17 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
 
 bool GLGizmoSlaSupports::is_mesh_point_clipped(const Vec3d& point) const
 {
-    if (m_c->m_clipping_plane_distance == 0.f)
+    if (m_c->object_clipper()->get_position() == 0.)
         return false;
 
-    Vec3d transformed_point = m_c->m_model_object->instances[m_c->m_active_instance]->get_transformation().get_matrix() * point;
-    transformed_point(2) += m_z_shift;
-    return m_c->m_clipping_plane->is_point_clipped(transformed_point);
+    auto sel_info = m_c->selection_info();
+    int active_inst = m_c->selection_info()->get_active_instance();
+    const ModelInstance* mi = sel_info->model_object()->instances[active_inst];
+    const Transform3d& trafo = mi->get_transformation().get_matrix();
+
+    Vec3d transformed_point =  trafo * point;
+    transformed_point(2) += sel_info->get_sla_shift();
+    return m_c->object_clipper()->get_clipping_plane()->is_point_clipped(transformed_point);
 }
 
 
@@ -379,7 +401,7 @@ bool GLGizmoSlaSupports::is_mesh_point_clipped(const Vec3d& point) const
 // Return false if no intersection was found, true otherwise.
 bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal)
 {
-    if (! m_c->m_mesh_raycaster)
+    if (! m_c->raycaster()->raycaster())
         return false;
 
 #if ENABLE_NON_STATIC_CANVAS_MANAGER
@@ -390,26 +412,30 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
     const Selection& selection = m_parent.get_selection();
     const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
     Geometry::Transformation trafo = volume->get_instance_transformation();
-    trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift));
+    trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
+
+    double clp_dist = m_c->object_clipper()->get_position();
+    const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane();
 
     // The raycaster query
     Vec3f hit;
     Vec3f normal;
-    if (m_c->m_mesh_raycaster->unproject_on_mesh(
+    if (m_c->raycaster()->raycaster()->unproject_on_mesh(
             mouse_pos,
             trafo.get_matrix(),
             camera,
             hit,
             normal,
-            m_c->m_clipping_plane_distance != 0.f ? m_c->m_clipping_plane.get() : nullptr))
+            clp_dist != 0. ? clp : nullptr))
     {
         // Check whether the hit is in a hole
         bool in_hole = false;
         // In case the hollowed and drilled mesh is available, we can allow
         // placing points in holes, because they should never end up
         // on surface that's been drilled away.
-        if (! m_c->has_drilled_mesh()) {
-            for (const sla::DrainHole& hole : m_c->m_model_object->sla_drain_holes) {
+        if (! m_c->hollowed_mesh()->get_hollowed_mesh()) {
+            sla::DrainHoles drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
+            for (const sla::DrainHole& hole : drain_holes) {
                 if (hole.is_inside(hit)) {
                     in_hole = true;
                     break;
@@ -432,6 +458,9 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
 // concludes that the event was not intended for it, it should return false.
 bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down)
 {
+    ModelObject* mo = m_c->selection_info()->model_object();
+    int active_inst = m_c->selection_info()->get_active_instance();
+
     if (m_editing_mode) {
 
         // left down with shift - show the selection rectangle:
@@ -483,8 +512,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
             GLSelectionRectangle::EState rectangle_status = m_selection_rectangle.get_state();
 
             // First collect positions of all the points in world coordinates.
-            Geometry::Transformation trafo = m_c->m_model_object->instances[m_c->m_active_instance]->get_transformation();
-            trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift));
+            Geometry::Transformation trafo = mo->instances[active_inst]->get_transformation();
+            trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
             std::vector<Vec3d> points;
             for (unsigned int i=0; i<m_editing_cache.size(); ++i)
                 points.push_back(trafo.get_matrix() * m_editing_cache[i].support_point.pos.cast<double>());
@@ -496,11 +525,9 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
                 points_inside.push_back(points[idx].cast<float>());
 
             // Only select/deselect points that are actually visible
-#if ENABLE_NON_STATIC_CANVAS_MANAGER
-            for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, wxGetApp().plater()->get_camera(), points_inside, m_c->m_clipping_plane.get()))
-#else
-            for (size_t idx :  m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_c->m_clipping_plane.get()))
-#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
+            for (size_t idx : m_c->raycaster()->raycaster()->get_unobscured_idxs(
+                     trafo, wxGetApp().plater()->get_camera(), points_inside,
+                     m_c->object_clipper()->get_clipping_plane()))
             {
                 if (rectangle_status == GLSelectionRectangle::Deselect)
                     unselect_point(points_idxs[idx]);
@@ -577,20 +604,25 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
     }
 
     if (action == SLAGizmoEventType::MouseWheelUp && control_down) {
-        m_c->m_clipping_plane_distance = std::min(1.f, m_c->m_clipping_plane_distance + 0.01f);
-        update_clipping_plane(m_c->m_clipping_plane_was_moved);
-        m_c->m_clipping_plane_was_moved = true;
+        double pos = m_c->object_clipper()->get_position();
+        pos = std::min(1., pos + 0.01);
+        m_c->object_clipper()->set_position(pos, true);
+        //update_clipping_plane(/*m_c->m_clipping_plane_was_moved*/);
+        //m_c->m_clipping_plane_was_moved = true;
         return true;
     }
 
     if (action == SLAGizmoEventType::MouseWheelDown && control_down) {
-        m_c->m_clipping_plane_distance = std::max(0.f, m_c->m_clipping_plane_distance - 0.01f);
-        update_clipping_plane(true);
+        double pos = m_c->object_clipper()->get_position();
+        pos = std::max(0., pos - 0.01);
+        m_c->object_clipper()->set_position(pos, true);
+        //update_clipping_plane(true);
         return true;
     }
 
     if (action == SLAGizmoEventType::ResetClippingPlane) {
-        update_clipping_plane();
+        //update_clipping_plane();
+        m_c->object_clipper()->set_position(-1., false);
         return true;
     }
 
@@ -634,11 +666,12 @@ void GLGizmoSlaSupports::on_update(const UpdateData& data)
 std::vector<const ConfigOption*> GLGizmoSlaSupports::get_config_options(const std::vector<std::string>& keys) const
 {
     std::vector<const ConfigOption*> out;
+    const ModelObject* mo = m_c->selection_info()->model_object();
 
-    if (!m_c->m_model_object)
+    if (! mo)
         return out;
 
-    const DynamicPrintConfig& object_cfg = m_c->m_model_object->config;
+    const DynamicPrintConfig& object_cfg = mo->config;
     const DynamicPrintConfig& print_cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
     std::unique_ptr<DynamicPrintConfig> default_cfg = nullptr;
 
@@ -661,10 +694,18 @@ std::vector<const ConfigOption*> GLGizmoSlaSupports::get_config_options(const st
 
 ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
 {
-    if (!m_c->m_model_object || m_state == Off || m_c->m_clipping_plane_distance == 0.f)
+    //if (!m_c->m_model_object || m_state == Off || m_c->m_clipping_plane_distance == 0.f)
+    //    return ClippingPlane::ClipsNothing();
+    //else
+    //    return ClippingPlane(-m_c->m_clipping_plane->get_normal(), m_c->m_clipping_plane->get_data()[3]);
+    if (! m_c->selection_info()->model_object()
+     || m_state == Off
+     || m_c->object_clipper()->get_position() == 0.)
         return ClippingPlane::ClipsNothing();
-    else
-        return ClippingPlane(-m_c->m_clipping_plane->get_normal(), m_c->m_clipping_plane->get_data()[3]);
+    else {
+        const ClippingPlane& clp = *m_c->object_clipper()->get_clipping_plane();
+        return ClippingPlane(-clp.get_normal(), clp.get_data()[3]);
+    }
 }
 
 
@@ -714,7 +755,9 @@ void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_l
     static float last_y = 0.0f;
     static float last_h = 0.0f;
 
-    if (! m_c->m_model_object)
+    ModelObject* mo = m_c->selection_info()->model_object();
+
+    if (! mo)
         return;
 
     bool first_run = true; // This is a hack to redraw the button when all points are removed,
@@ -851,15 +894,15 @@ RENDER_AGAIN:
             m_density_stash = density;
         }
         if (slider_edited) {
-            m_c->m_model_object->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = minimal_point_distance;
-            m_c->m_model_object->config.opt<ConfigOptionInt>("support_points_density_relative", true)->value = (int)density;
+            mo->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = minimal_point_distance;
+            mo->config.opt<ConfigOptionInt>("support_points_density_relative", true)->value = (int)density;
         }
         if (slider_released) {
-            m_c->m_model_object->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = m_minimal_point_distance_stash;
-            m_c->m_model_object->config.opt<ConfigOptionInt>("support_points_density_relative", true)->value = (int)m_density_stash;
+            mo->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = m_minimal_point_distance_stash;
+            mo->config.opt<ConfigOptionInt>("support_points_density_relative", true)->value = (int)m_density_stash;
             Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Support parameter change")));
-            m_c->m_model_object->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = minimal_point_distance;
-            m_c->m_model_object->config.opt<ConfigOptionInt>("support_points_density_relative", true)->value = (int)density;
+            mo->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = minimal_point_distance;
+            mo->config.opt<ConfigOptionInt>("support_points_density_relative", true)->value = (int)density;
             wxGetApp().obj_list()->update_and_show_object_settings_item();
         }
 
@@ -886,7 +929,7 @@ RENDER_AGAIN:
 
     // Following is rendered in both editing and non-editing mode:
     ImGui::Separator();
-    if (m_c->m_clipping_plane_distance == 0.f)
+    if (m_c->object_clipper()->get_position() == 0.f)
     {
         ImGui::AlignTextToFramePadding();
         m_imgui->text(m_desc.at("clipping_of_view"));
@@ -894,17 +937,17 @@ RENDER_AGAIN:
     else {
         if (m_imgui->button(m_desc.at("reset_direction"))) {
             wxGetApp().CallAfter([this](){
-                    update_clipping_plane();
+                    //update_clipping_plane();
+                    m_c->object_clipper()->set_position(-1., false);
                 });
         }
     }
 
     ImGui::SameLine(clipping_slider_left);
     ImGui::PushItemWidth(window_width - clipping_slider_left);
-    if (ImGui::SliderFloat("  ", &m_c->m_clipping_plane_distance, 0.f, 1.f, "%.2f")) {
-        update_clipping_plane(m_c->m_clipping_plane_was_moved);
-        m_c->m_clipping_plane_was_moved = true;
-    }
+    float clp_dist = m_c->object_clipper()->get_position();
+    if (ImGui::SliderFloat("  ", &clp_dist, 0.f, 1.f, "%.2f"))
+        m_c->object_clipper()->set_position(clp_dist, true);
 
 
     if (m_imgui->button("?")) {
@@ -969,18 +1012,31 @@ std::string GLGizmoSlaSupports::on_get_name() const
 }
 
 
+CommonGizmosDataID GLGizmoSlaSupports::on_get_requirements() const
+{
+    return CommonGizmosDataID(
+                int(CommonGizmosDataID::SelectionInfo)
+              | int(CommonGizmosDataID::InstancesHider)
+              | int(CommonGizmosDataID::Raycaster)
+              | int(CommonGizmosDataID::HollowedMesh)
+              | int(CommonGizmosDataID::ObjectClipper)
+              | int(CommonGizmosDataID::SupportsClipper));
+}
+
+
 
 void GLGizmoSlaSupports::on_set_state()
 {
+    const ModelObject* mo = m_c->selection_info()->model_object();
     // m_c->m_model_object pointer can be invalid (for instance because of undo/redo action),
     // we should recover it from the object id
-    m_c->m_model_object = nullptr;
+    /*m_c->m_model_object = nullptr;
     for (const auto mo : wxGetApp().model().objects) {
         if (mo->id() == m_c->m_model_object_id) {
             m_c->m_model_object = mo;
             break;
         }
-    }
+    }*/
 
     if (m_state == m_old_state)
         return;
@@ -988,28 +1044,28 @@ 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")));
 
-        m_c->unstash_clipping_plane();
-        update_clipping_plane(m_c->m_clipping_plane_was_moved);
+        //m_c->unstash_clipping_plane();
+        //update_clipping_plane(m_c->m_clipping_plane_was_moved);
 
-        m_c->build_AABB_if_needed();
+        //m_c->build_AABB_if_needed();
 
 
         // we'll now reload support points:
-        if (m_c->m_model_object)
+        if (mo)
             reload_cache();
 
-        m_parent.toggle_model_objects_visibility(false);
+        /*m_parent.toggle_model_objects_visibility(false);
         if (m_c->m_model_object)  {
             m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
             m_parent.toggle_sla_auxiliaries_visibility(! m_editing_mode, m_c->m_model_object, m_c->m_active_instance);
-        }
+        }*/
 
         // 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<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value;
     }
     if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
-        bool will_ask = m_c->m_model_object && m_editing_mode && unsaved_changes();
+        bool will_ask = mo && m_editing_mode && unsaved_changes();
         if (will_ask) {
             wxGetApp().CallAfter([this]() {
                 // Following is called through CallAfter, because otherwise there was a problem
@@ -1028,15 +1084,15 @@ void GLGizmoSlaSupports::on_set_state()
             // we are actually shutting down
             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_parent.toggle_model_objects_visibility(true);
             m_normal_cache.clear();
-            m_c->stash_clipping_plane();
-            m_c->m_clipping_plane_distance = 0.f;
-            update_clipping_plane(true);
+            //m_c->stash_clipping_plane();
+            //m_c->m_clipping_plane_distance = 0.f;
+            //update_clipping_plane(true);
             // Release clippers and the AABB raycaster.
-            m_its = nullptr;
-            m_c->m_object_clipper.reset();
-            m_c->m_supports_clipper.reset();
+            //m_its = nullptr;
+            //m_c->m_object_clipper.reset();
+            //m_c->m_supports_clipper.reset();
             //m_c->m_mesh_raycaster.reset();
         }
     }
@@ -1077,10 +1133,7 @@ void GLGizmoSlaSupports::on_stop_dragging()
 
 void GLGizmoSlaSupports::on_load(cereal::BinaryInputArchive& ar)
 {
-    ar(m_c->m_clipping_plane_distance,
-       *m_c->m_clipping_plane,
-       m_c->m_model_object_id,
-       m_new_point_head_diameter,
+    ar(m_new_point_head_diameter,
        m_normal_cache,
        m_editing_cache,
        m_selection_empty
@@ -1091,10 +1144,7 @@ void GLGizmoSlaSupports::on_load(cereal::BinaryInputArchive& ar)
 
 void GLGizmoSlaSupports::on_save(cereal::BinaryOutputArchive& ar) const
 {
-    ar(m_c->m_clipping_plane_distance,
-       *m_c->m_clipping_plane,
-       m_c->m_model_object_id,
-       m_new_point_head_diameter,
+    ar(m_new_point_head_diameter,
        m_normal_cache,
        m_editing_cache,
        m_selection_empty
@@ -1171,9 +1221,10 @@ void GLGizmoSlaSupports::editing_mode_apply_changes()
         for (const CacheEntry& ce : m_editing_cache)
             m_normal_cache.push_back(ce.support_point);
 
-        m_c->m_model_object->sla_points_status = sla::PointsStatus::UserModified;
-        m_c->m_model_object->sla_support_points.clear();
-        m_c->m_model_object->sla_support_points = m_normal_cache;
+        ModelObject* mo = m_c->selection_info()->model_object();
+        mo->sla_points_status = sla::PointsStatus::UserModified;
+        mo->sla_support_points.clear();
+        mo->sla_support_points = m_normal_cache;
 
         reslice_SLA_supports();
     }
@@ -1183,23 +1234,25 @@ void GLGizmoSlaSupports::editing_mode_apply_changes()
 
 void GLGizmoSlaSupports::reload_cache()
 {
+    const ModelObject* mo = m_c->selection_info()->model_object();
     m_normal_cache.clear();
-    if (m_c->m_model_object->sla_points_status == sla::PointsStatus::AutoGenerated || m_c->m_model_object->sla_points_status == sla::PointsStatus::Generating)
+    if (mo->sla_points_status == sla::PointsStatus::AutoGenerated || mo->sla_points_status == sla::PointsStatus::Generating)
         get_data_from_backend();
     else
-        for (const sla::SupportPoint& point : m_c->m_model_object->sla_support_points)
+        for (const sla::SupportPoint& point : mo->sla_support_points)
             m_normal_cache.emplace_back(point);
 }
 
 
 bool GLGizmoSlaSupports::has_backend_supports() const
 {
-    if (! m_c->m_model_object)
+    const ModelObject* mo = m_c->selection_info()->model_object();
+    if (! mo)
         return false;
 
     // find SlaPrintObject with this ID
     for (const SLAPrintObject* po : m_parent.sla_print()->objects()) {
-        if (po->model_object()->id() == m_c->m_model_object->id())
+        if (po->model_object()->id() == mo->id())
         	return po->is_step_done(slaposSupportPoints);
     }
     return false;
@@ -1207,24 +1260,28 @@ bool GLGizmoSlaSupports::has_backend_supports() const
 
 void GLGizmoSlaSupports::reslice_SLA_supports(bool postpone_error_messages) const
 {
-    wxGetApp().CallAfter([this, postpone_error_messages]() { wxGetApp().plater()->reslice_SLA_supports(*m_c->m_model_object, postpone_error_messages); });
+    wxGetApp().CallAfter([this, postpone_error_messages]() {
+        wxGetApp().plater()->reslice_SLA_supports(
+            *m_c->selection_info()->model_object(), postpone_error_messages);
+    });
 }
 
 void GLGizmoSlaSupports::get_data_from_backend()
 {
     if (! has_backend_supports())
         return;
+    ModelObject* mo = m_c->selection_info()->model_object();
 
     // 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_c->m_model_object->id()) {
+        if (po->model_object()->id() == mo->id()) {
             m_normal_cache.clear();
             const std::vector<sla::SupportPoint>& points = po->get_support_points();
             auto mat = po->trafo().inverse().cast<float>();
             for (unsigned int i=0; i<points.size();++i)
                 m_normal_cache.emplace_back(sla::SupportPoint(mat * points[i].pos, points[i].head_front_radius, points[i].is_new_island));
 
-            m_c->m_model_object->sla_points_status = sla::PointsStatus::AutoGenerated;
+            mo->sla_points_status = sla::PointsStatus::AutoGenerated;
             break;
         }
     }
@@ -1241,10 +1298,12 @@ void GLGizmoSlaSupports::auto_generate()
                         _(L("Are you sure you want to do it?")) + "\n",
                         _(L("Warning")), wxICON_WARNING | wxYES | wxNO);
 
-    if (m_c->m_model_object->sla_points_status != sla::PointsStatus::UserModified || m_normal_cache.empty() || dlg.ShowModal() == wxID_YES) {
+    ModelObject* mo = m_c->selection_info()->model_object();
+
+    if (mo->sla_points_status != sla::PointsStatus::UserModified || m_normal_cache.empty() || dlg.ShowModal() == wxID_YES) {
         Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Autogenerate support points")));
         wxGetApp().CallAfter([this]() { reslice_SLA_supports(); });
-        m_c->m_model_object->sla_points_status = sla::PointsStatus::Generating;
+        mo->sla_points_status = sla::PointsStatus::Generating;
     }
 }
 
@@ -1259,7 +1318,8 @@ void GLGizmoSlaSupports::switch_to_editing_mode()
         m_editing_cache.emplace_back(sp);
     select_point(NoPoints);
 
-    m_parent.toggle_sla_auxiliaries_visibility(false, m_c->m_model_object, m_c->m_active_instance);
+    //m_parent.toggle_sla_auxiliaries_visibility(false, m_c->m_model_object, m_c->m_active_instance);
+    m_c->instances_hider()->show_supports(false);
     m_parent.set_as_dirty();
 }
 
@@ -1269,7 +1329,8 @@ void GLGizmoSlaSupports::disable_editing_mode()
     if (m_editing_mode) {
         m_editing_mode = false;
         wxGetApp().plater()->leave_gizmos_stack();
-        m_parent.toggle_sla_auxiliaries_visibility(true, m_c->m_model_object, m_c->m_active_instance);
+        //m_parent.toggle_sla_auxiliaries_visibility(true, m_c->m_model_object, m_c->m_active_instance);
+        m_c->instances_hider()->show_supports(true);
         m_parent.set_as_dirty();
     }
 }
@@ -1288,7 +1349,7 @@ bool GLGizmoSlaSupports::unsaved_changes() const
     return false;
 }
 
-
+/*
 void GLGizmoSlaSupports::update_clipping_plane(bool keep_normal) const
 {
     if (! m_c->m_model_object)
@@ -1306,7 +1367,7 @@ void GLGizmoSlaSupports::update_clipping_plane(bool keep_normal) const
     float dist = normal.dot(center);
     *m_c->m_clipping_plane = ClippingPlane(normal, (dist - (-m_c->m_active_instance_bb_radius) - m_c->m_clipping_plane_distance * 2*m_c->m_active_instance_bb_radius));
     m_parent.set_as_dirty();
-}
+}*/
 
 SlaGizmoHelpDialog::SlaGizmoHelpDialog()
 : wxDialog(nullptr, wxID_ANY, _(L("SLA gizmo keyboard shortcuts")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
index bd48ecd65..81b347204 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
@@ -16,7 +16,7 @@ namespace GUI {
 class ClippingPlane;
 class MeshClipper;
 class MeshRaycaster;
-class CommonGizmosData;
+//class CommonGizmosData;
 enum class SLAGizmoEventType : unsigned char;
 
 class GLGizmoSlaSupports : public GLGizmoBase
@@ -26,7 +26,7 @@ private:
     //ObjectID m_model_object_id = 0;
     //int m_active_instance = -1;
     //float m_active_instance_bb_radius; // to cache the bb
-    mutable double m_z_shift = 0.f;
+    //mutable double m_z_shift = 0.f;
     bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
 
     const float RenderPointScale = 1.f;
@@ -81,8 +81,8 @@ public:
     bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); }
     bool has_backend_supports() const;
     void reslice_SLA_supports(bool postpone_error_messages = false) const;
-    void update_clipping_plane(bool keep_normal = false) const;
-    void set_common_data_ptr(CommonGizmosData* ptr) { m_c = ptr; }
+    //void update_clipping_plane(bool keep_normal = false) const;
+    //void set_common_data_ptr(CommonGizmosData* ptr) { m_c = ptr; }
 
 private:
     bool on_init() override;
@@ -92,7 +92,7 @@ private:
 
     //void render_selection_rectangle() const;
     void render_points(const Selection& selection, bool picking = false) const;
-    void render_clipping_plane(const Selection& selection) const;
+    //void render_clipping_plane(const Selection& selection) const;
     bool unsaved_changes() const;
 
     bool m_lock_unique_islands = false;
@@ -104,6 +104,7 @@ private:
     float m_density_stash = 0.f;                // and again
     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
+    const ModelObject* m_old_mo = nullptr;
 
     //std::unique_ptr<ClippingPlane> m_clipping_plane;
 
@@ -117,7 +118,7 @@ private:
     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)
 
-    CommonGizmosData* m_c = nullptr;
+    //CommonGizmosData* m_c = nullptr;
 
     //mutable std::unique_ptr<MeshClipper> m_object_clipper;
     //mutable std::unique_ptr<MeshClipper> m_supports_clipper;
@@ -159,6 +160,7 @@ protected:
     std::string on_get_name() const override;
     bool on_is_activable() const override;
     bool on_is_selectable() const override;
+    virtual CommonGizmosDataID on_get_requirements() const override;
     void on_load(cereal::BinaryInputArchive& ar) override;
     void on_save(cereal::BinaryOutputArchive& ar) const override;
 };
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index 380aa4e7d..a8e1801d7 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -196,16 +196,18 @@ void HollowedMesh::on_update()
             size_t timestamp = print_object->step_state_with_timestamp(slaposDrillHoles).timestamp;
             if (timestamp > m_old_hollowing_timestamp) {
                 const TriangleMesh& backend_mesh = print_object->get_mesh_to_print();
-                m_hollowed_mesh_transformed.reset(new TriangleMesh(backend_mesh));
-                Transform3d trafo_inv = canvas->sla_print()->sla_trafo(*mo).inverse();
-                m_hollowed_mesh_transformed->transform(trafo_inv);
-                m_old_hollowing_timestamp = timestamp;
+                if (! backend_mesh.empty()) {
+                    m_hollowed_mesh_transformed.reset(new TriangleMesh(backend_mesh));
+                    Transform3d trafo_inv = canvas->sla_print()->sla_trafo(*mo).inverse();
+                    m_hollowed_mesh_transformed->transform(trafo_inv);
+                    m_old_hollowing_timestamp = timestamp;
+                }
+                else
+                    m_hollowed_mesh_transformed.reset(nullptr);
             }
         }
-        else {
+        else
             m_hollowed_mesh_transformed.reset(nullptr);
-            m_old_hollowing_timestamp = 0;
-        }
     }
 }
 
@@ -417,7 +419,7 @@ void SupportsClipper::render_cut() const
     const SelectionInfo* sel_info = get_pool()->selection_info();
     const ModelObject* mo = sel_info->model_object();
     Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
-    Geometry::Transformation vol_trafo  = mo->volumes.front()->get_transformation();
+    //Geometry::Transformation vol_trafo  = mo->volumes.front()->get_transformation();
     Geometry::Transformation trafo = inst_trafo;// * vol_trafo;
     trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
 
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index ed9bd5de3..884d63b4c 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -9,10 +9,10 @@
 #include "slic3r/GUI/GUI_ObjectManipulation.hpp"
 #include "slic3r/GUI/PresetBundle.hpp"
 #include "slic3r/Utils/UndoRedo.hpp"
-#include "libslic3r/SLAPrint.hpp"
-#include "slic3r/GUI/MeshUtils.hpp"
+//#include "libslic3r/SLAPrint.hpp"
+//#include "slic3r/GUI/MeshUtils.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmos.hpp"
-#include "slic3r/GUI/Camera.hpp"
+//#include "slic3r/GUI/Camera.hpp"
 
 #include <wx/glcanvas.h>
 
@@ -96,7 +96,7 @@ bool GLGizmosManager::init()
     m_gizmos.emplace_back(new GLGizmoFlatten(m_parent, "place.svg", 3));
     m_gizmos.emplace_back(new GLGizmoCut(m_parent, "cut.svg", 4));
     m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", 5));
-    //m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 6));
+    m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 6));
 
     //m_common_gizmos_data.reset(new CommonGizmosData());
     //dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->set_common_data_ptr(m_common_gizmos_data.get());
@@ -375,7 +375,9 @@ void GLGizmosManager::set_sla_support_data(ModelObject* model_object)
     //gizmo_supports->set_sla_support_data(model_object, m_parent.get_selection());
     */
     auto* gizmo_hollow = dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get());
+    auto* gizmo_supports = dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get());
     gizmo_hollow->set_sla_support_data(model_object, m_parent.get_selection());
+    gizmo_supports->set_sla_support_data(model_object, m_parent.get_selection());
 }
 
 // Returns true if the gizmo used the event to do something, false otherwise.
@@ -1217,7 +1219,7 @@ bool GLGizmosManager::grabber_contains_mouse() const
 }
 
 
-
+/*
 CommonGizmosData::CommonGizmosData()
 {
     m_clipping_plane.reset(new ClippingPlane(Vec3d::Zero(), 0.));
@@ -1344,7 +1346,7 @@ void CommonGizmosData::build_AABB_if_needed()
     m_supports_clipper.reset();
     m_old_mesh = m_mesh;
     m_schedule_aabb_calculation = false;
-}
+}*/
 
 
 } // namespace GUI
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
index f01ecfd77..81fd991b7 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
@@ -3,7 +3,7 @@
 
 #include "slic3r/GUI/GLTexture.hpp"
 #include "slic3r/GUI/GLToolbar.hpp"
-#include "libslic3r/ObjectID.hpp"
+//#include "libslic3r/ObjectID.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmoBase.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
 
@@ -20,7 +20,7 @@ namespace GUI {
 class GLCanvas3D;
 class ClippingPlane;
 enum class SLAGizmoEventType : unsigned char;
-class CommonGizmosData;
+//class CommonGizmosData;
 class CommonGizmosDataPool;
 
 class Rect
@@ -234,13 +234,13 @@ private:
 
 
 
-class MeshRaycaster;
-class MeshClipper;
+//class MeshRaycaster;
+//class MeshClipper;
 
 // This class is only for sharing SLA related data between SLA gizmos
 // and its synchronization with backend data. It should not be misused
 // for anything else.
-class CommonGizmosData {
+/*class CommonGizmosData {
 public:
     CommonGizmosData();
     const TriangleMesh* mesh() const {
@@ -290,7 +290,7 @@ private:
     bool m_has_drilled_mesh = false;
     bool m_schedule_aabb_calculation = false;
 };
-
+*/
 } // namespace GUI
 } // namespace Slic3r
 

From 535a27de65decbf0b16f85ff8004dc8935d86775 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 7 Apr 2020 15:55:54 +0200
Subject: [PATCH 14/15] Fixed crash related to ClippingPlane and incorrect
 handling of sla z shift in hollowing gizmo

---
 src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp      |  8 ++++----
 src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp      |  4 ++--
 src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp |  4 ++--
 src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp |  2 +-
 src/slic3r/GUI/Gizmos/GLGizmosManager.cpp    | 13 +++++++++++--
 5 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
index 46c570c19..3c82806ca 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
@@ -223,7 +223,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
     const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
 
     glsafe(::glPushMatrix());
-    glsafe(::glTranslated(0.0, 0.0, m_z_shift));
+    glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift()));
     glsafe(::glMultMatrixd(instance_matrix.data()));
 
     float render_color[4];
@@ -444,7 +444,7 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
 
         // First collect positions of all the points in world coordinates.
         Geometry::Transformation trafo = mo->instances[active_inst]->get_transformation();
-        trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift));
+        trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
         std::vector<Vec3d> points;
         for (unsigned int i=0; i<mo->sla_drain_holes.size(); ++i)
             points.push_back(trafo.get_matrix() * mo->sla_drain_holes[i].pos.cast<double>());
@@ -607,7 +607,7 @@ GLGizmoHollow::get_config_options(const std::vector<std::string>& keys) const
     return out;
 }
 
-
+/*
 ClippingPlane GLGizmoHollow::get_sla_clipping_plane() const
 {
     if (! m_c->selection_info()->model_object()
@@ -619,7 +619,7 @@ ClippingPlane GLGizmoHollow::get_sla_clipping_plane() const
         return ClippingPlane(-clp.get_normal(), clp.get_data()[3]);
     }
 }
-
+*/
 
 void GLGizmoHollow::on_render_input_window(float x, float y, float bottom_limit)
 {
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
index 178579ba1..73d26b2da 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
@@ -22,7 +22,7 @@ enum class SLAGizmoEventType : unsigned char;
 class GLGizmoHollow : public GLGizmoBase
 {
 private:
-    mutable double m_z_shift = 0.;
+    //mutable double m_z_shift = 0.;
     bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
 
     GLUquadricObj* m_quadric;
@@ -34,7 +34,7 @@ public:
     void set_sla_support_data(ModelObject* model_object, const Selection& selection);
     bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
     void delete_selected_points();
-    ClippingPlane get_sla_clipping_plane() const;
+    //ClippingPlane get_sla_clipping_plane() const;
     
     bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); }
     //void set_common_data_ptr(CommonGizmosData* ptr) { m_c = ptr; }
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
index ac65d9313..16ac6ec3c 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
@@ -691,7 +691,7 @@ std::vector<const ConfigOption*> GLGizmoSlaSupports::get_config_options(const st
     return out;
 }
 
-
+/*
 ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
 {
     //if (!m_c->m_model_object || m_state == Off || m_c->m_clipping_plane_distance == 0.f)
@@ -707,7 +707,7 @@ ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
         return ClippingPlane(-clp.get_normal(), clp.get_data()[3]);
     }
 }
-
+*/
 
 /*
 void GLGizmoSlaSupports::find_intersecting_facets(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<unsigned int>& idxs) const
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
index 81b347204..2b7b1ae78 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
@@ -75,7 +75,7 @@ public:
     void set_sla_support_data(ModelObject* model_object, const Selection& selection);
     bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
     void delete_selected_points(bool force = false);
-    ClippingPlane get_sla_clipping_plane() const;
+    //ClippingPlane get_sla_clipping_plane() const;
 
     bool is_in_editing_mode() const { return m_editing_mode; }
     bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); }
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 884d63b4c..61d0bd5f4 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -395,13 +395,22 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
 
 ClippingPlane GLGizmosManager::get_sla_clipping_plane() const
 {
-    if (!m_enabled || (m_current != SlaSupports && m_current != Hollow) || m_gizmos.empty())
+    if (! m_common_gizmos_data->object_clipper()
+       || m_common_gizmos_data->object_clipper()->get_position() == 0.)
+        return ClippingPlane::ClipsNothing();
+    else {
+        const ClippingPlane& clp = *m_common_gizmos_data->object_clipper()->get_clipping_plane();
+        return ClippingPlane(-clp.get_normal(), clp.get_data()[3]);
+    }
+
+
+    /*if (!m_enabled || (m_current != SlaSupports && m_current != Hollow) || m_gizmos.empty())
         return ClippingPlane::ClipsNothing();
 
     if (m_current == SlaSupports)
         return dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->get_sla_clipping_plane();
     else
-        return dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->get_sla_clipping_plane();
+        return dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->get_sla_clipping_plane();*/
 }
 
 bool GLGizmosManager::wants_reslice_supports_on_undo() const

From 1d65ce760b8b9a7fc401d873379c3f0bb1c89603 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 7 Apr 2020 16:19:53 +0200
Subject: [PATCH 15/15] Removed obsolete code Got rid of dummy header
 GLGizmos.hpp

---
 src/slic3r/CMakeLists.txt                    |   1 -
 src/slic3r/GUI/GLCanvas3D.cpp                |   1 -
 src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp      | 168 +---------------
 src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp      |  19 +-
 src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 200 +------------------
 src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp |  28 +--
 src/slic3r/GUI/Gizmos/GLGizmos.hpp           |  37 ----
 src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp     |  18 ++
 src/slic3r/GUI/Gizmos/GLGizmosManager.cpp    | 152 +-------------
 src/slic3r/GUI/Gizmos/GLGizmosManager.hpp    |  59 ------
 10 files changed, 35 insertions(+), 648 deletions(-)
 delete mode 100644 src/slic3r/GUI/Gizmos/GLGizmos.hpp

diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index f13c6084b..02275aeda 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -31,7 +31,6 @@ set(SLIC3R_GUI_SOURCES
     GUI/GLCanvas3DManager.cpp
     GUI/Selection.hpp
     GUI/Selection.cpp    
-    GUI/Gizmos/GLGizmos.hpp
     GUI/Gizmos/GLGizmosManager.cpp
     GUI/Gizmos/GLGizmosManager.hpp
     GUI/Gizmos/GLGizmosCommon.cpp
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 74abbebdd..064f01cf2 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -1,5 +1,4 @@
 #include "libslic3r/libslic3r.h"
-#include "slic3r/GUI/Gizmos/GLGizmos.hpp"
 #include "GLCanvas3D.hpp"
 
 #include "admesh/stl.h"
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
index 3c82806ca..3c7e7a236 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
@@ -1,7 +1,6 @@
 #include "GLGizmoHollow.hpp"
 #include "slic3r/GUI/GLCanvas3D.hpp"
 #include "slic3r/GUI/Camera.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmos.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
 
 #include <GL/glew.h>
@@ -63,34 +62,6 @@ void GLGizmoHollow::set_sla_support_data(ModelObject*, const Selection&)
         if (m_c->hollowed_mesh()->get_hollowed_mesh())
             m_holes_in_drilled_mesh = mo->sla_drain_holes;
     }
-
-    /*if (m_c->recent_update) {
-
-        if (m_state == On)
-            m_c->build_AABB_if_needed();
-
-        update_clipping_plane(m_c->m_clipping_plane_was_moved);
-
-        // This is a temporary and not very nice hack, to make sure that
-        // if the cp was moved by the data returned by backend, it will
-        // remember its direction. FIXME: Refactor this mess and make
-        // the clipping plane itself part of the shared data.
-        if (! m_c->m_clipping_plane_was_moved && m_c->m_clipping_plane_distance == 0.25f)
-            m_c->m_clipping_plane_was_moved = true;
-
-
-        if (m_c->m_model_object) {
-            reload_cache();
-            if (m_c->has_drilled_mesh())
-                m_holes_in_drilled_mesh = m_c->m_model_object->sla_drain_holes;
-        }
-    }
-
-    if (m_state == On) {
-        m_parent.toggle_model_objects_visibility(false);
-        m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
-        m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, m_c->m_model_object, m_c->m_active_instance);
-    }*/
 }
 
 
@@ -111,13 +82,10 @@ void GLGizmoHollow::on_render() const
     glsafe(::glEnable(GL_BLEND));
     glsafe(::glEnable(GL_DEPTH_TEST));
 
-    //m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
-
     if (m_quadric != nullptr && selection.is_from_single_instance())
         render_points(selection, false);
 
     m_selection_rectangle.render(m_parent);
-    //render_clipping_plane(selection);
     m_c->object_clipper()->render_cut();
     m_c->supports_clipper()->render_cut();
 
@@ -125,83 +93,6 @@ void GLGizmoHollow::on_render() const
 }
 
 
-
-void GLGizmoHollow::render_clipping_plane(const Selection& selection) const
-{
-    return;
-/*
-    if (m_c->m_clipping_plane_distance == 0.f)
-        return;
-
-    // Get transformation of the instance
-    const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
-    Geometry::Transformation trafo = vol->get_instance_transformation();
-    trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift));
-
-    // Get transformation of supports
-    Geometry::Transformation supports_trafo;
-    supports_trafo.set_offset(Vec3d(trafo.get_offset()(0), trafo.get_offset()(1), vol->get_sla_shift_z()));
-    supports_trafo.set_rotation(Vec3d(0., 0., trafo.get_rotation()(2)));
-    // I don't know why, but following seems to be correct.
-    supports_trafo.set_mirror(Vec3d(trafo.get_mirror()(0) * trafo.get_mirror()(1) * trafo.get_mirror()(2),
-                                    1,
-                                    1.));
-
-    // Now initialize the TMS for the object, perform the cut and save the result.
-    if (! m_c->m_object_clipper) {
-        m_c->m_object_clipper.reset(new MeshClipper);
-        m_c->m_object_clipper->set_mesh(*m_c->mesh());
-    }
-    m_c->m_object_clipper->set_plane(*m_c->m_clipping_plane);
-    m_c->m_object_clipper->set_transformation(trafo);
-
-    if (m_c->m_print_object_idx >= 0) {
-        const SLAPrintObject* print_object = m_parent.sla_print()->objects()[m_c->m_print_object_idx];
-
-        if (print_object->is_step_done(slaposSupportTree) && !print_object->get_mesh(slaposSupportTree).empty()) {
-            // If the supports are already calculated, save the timestamp of the respective step
-            // so we can later tell they were recalculated.
-            size_t timestamp = print_object->step_state_with_timestamp(slaposSupportTree).timestamp;
-
-            if (! m_c->m_supports_clipper || (int)timestamp != m_c->m_old_timestamp) {
-                // The timestamp has changed.
-                m_c->m_supports_clipper.reset(new MeshClipper);
-                // The mesh should already have the shared vertices calculated.
-                m_c->m_supports_clipper->set_mesh(print_object->support_mesh());
-                m_c->m_old_timestamp = timestamp;
-            }
-            m_c->m_supports_clipper->set_plane(*m_c->m_clipping_plane);
-            m_c->m_supports_clipper->set_transformation(supports_trafo);
-        }
-        else
-            // The supports are not valid. We better dump the cached data.
-            m_c->m_supports_clipper.reset();
-    }
-
-    // At this point we have the triangulated cuts for both the object and supports - let's render.
-    if (! m_c->m_object_clipper->get_triangles().empty()) {
-        ::glPushMatrix();
-        ::glColor3f(1.0f, 0.37f, 0.0f);
-        ::glBegin(GL_TRIANGLES);
-        for (const Vec3f& point : m_c->m_object_clipper->get_triangles())
-            ::glVertex3f(point(0), point(1), point(2));
-        ::glEnd();
-        ::glPopMatrix();
-    }
-
-    if (m_show_supports && m_c->m_supports_clipper && ! m_c->m_supports_clipper->get_triangles().empty()) {
-        ::glPushMatrix();
-        ::glColor3f(1.0f, 0.f, 0.37f);
-        ::glBegin(GL_TRIANGLES);
-        for (const Vec3f& point : m_c->m_supports_clipper->get_triangles())
-            ::glVertex3f(point(0), point(1), point(2));
-        ::glEnd();
-        ::glPopMatrix();
-    }
-*/
-}
-
-
 void GLGizmoHollow::on_render_for_picking() const
 {
     const Selection& selection = m_parent.get_selection();
@@ -272,7 +163,6 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
             glFrontFace(GL_CW);
 
         // Matrices set, we can render the point mark now.
-
         Eigen::Quaterniond q;
         q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * (-drain_hole.normal).cast<double>());
         Eigen::AngleAxisd aa(q);
@@ -456,13 +346,9 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
             points_inside.push_back(points[idx].cast<float>());
 
         // Only select/deselect points that are actually visible
-#if ENABLE_NON_STATIC_CANVAS_MANAGER
         for (size_t idx : m_c->raycaster()->raycaster()->get_unobscured_idxs(
                  trafo, wxGetApp().plater()->get_camera(), points_inside,
                  m_c->object_clipper()->get_clipping_plane()))
-#else
-        for (size_t idx :  m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_c->m_clipping_plane.get()))
-#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
         {
             if (rectangle_status == GLSelectionRectangle::Deselect)
                 unselect_point(points_idxs[idx]);
@@ -519,8 +405,6 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
         double pos = m_c->object_clipper()->get_position();
         pos = std::min(1., pos + 0.01);
         m_c->object_clipper()->set_position(pos, true);
-        //update_clipping_plane(/*m_c->m_clipping_plane_was_moved*/);
-        //m_c->m_clipping_plane_was_moved = true;
         return true;
     }
 
@@ -528,7 +412,6 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
         double pos = m_c->object_clipper()->get_position();
         pos = std::max(0., pos - 0.01);
         m_c->object_clipper()->set_position(pos, true);
-        //update_clipping_plane(true);
         return true;
     }
 
@@ -607,19 +490,6 @@ GLGizmoHollow::get_config_options(const std::vector<std::string>& keys) const
     return out;
 }
 
-/*
-ClippingPlane GLGizmoHollow::get_sla_clipping_plane() const
-{
-    if (! m_c->selection_info()->model_object()
-     || m_state == Off
-     || m_c->object_clipper()->get_position() == 0.)
-        return ClippingPlane::ClipsNothing();
-    else {
-        const ClippingPlane& clp = *m_c->object_clipper()->get_clipping_plane();
-        return ClippingPlane(-clp.get_normal(), clp.get_data()[3]);
-    }
-}
-*/
 
 void GLGizmoHollow::on_render_input_window(float x, float y, float bottom_limit)
 {
@@ -863,7 +733,6 @@ RENDER_AGAIN:
     // make sure supports are shown/hidden as appropriate
     bool show_sups = m_c->instances_hider()->are_supports_shown();
     if (m_imgui->checkbox(m_desc["show_supports"], show_sups)) {
-        //    m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, mo, m_c->m_active_instance);
         m_c->instances_hider()->show_supports(show_sups);
         force_refresh = true;
     }
@@ -937,51 +806,16 @@ CommonGizmosDataID GLGizmoHollow::on_get_requirements() const
 
 void GLGizmoHollow::on_set_state()
 {
-    // m_c->m_model_object pointer can be invalid (for instance because of undo/redo action),
-    // we should recover it from the object id
-    /*m_c->m_model_object = nullptr;
-    for (const auto mo : wxGetApp().model().objects) {
-        if (mo->id() == m_c->m_model_object_id) {
-            m_c->m_model_object = mo;
-            break;
-        }
-    }*/
-
     if (m_state == m_old_state)
         return;
 
     if (m_state == On && m_old_state != On) { // the gizmo was just turned on
-        //Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned on")));
-        //m_c->update_from_backend(m_parent, m_c->m_model_object);
-        //m_c->unstash_clipping_plane();
-        //update_clipping_plane(/*m_c->m_clipping_plane_was_moved*/);
-
-        //m_c->build_AABB_if_needed();
-
         // we'll now reload support points:
         if (m_c->selection_info()->model_object())
             reload_cache();
-
-        /*m_parent.toggle_model_objects_visibility(false);
-        if (m_c->m_model_object) {
-            m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
-            m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, m_c->m_model_object, m_c->m_active_instance);
-        }*/
     }
-    if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
-        //Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned off")));
+    if (m_state == Off && m_old_state != Off) // the gizmo was just turned Off
         m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE));
-        //m_parent.toggle_model_objects_visibility(true);
-        //m_c->stash_clipping_plane();
-        //m_c->m_clipping_plane_distance = 0.f;
-        //update_clipping_plane(true);
-        // Release clippers and the AABB raycaster.
-        //m_c->m_object_clipper.reset();
-        //m_c->m_supports_clipper.reset();
-        //m_c->m_mesh_raycaster.reset();
-        //m_c->m_cavity_mesh.reset();
-        //m_c->m_volume_with_cavity.reset();
-    }
     m_old_state = m_state;
 }
 
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
index 73d26b2da..3ee83c345 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp
@@ -13,16 +13,11 @@
 namespace Slic3r {
 namespace GUI {
 
-class ClippingPlane;
-class MeshClipper;
-class MeshRaycaster;
-//class CommonGizmosData;
 enum class SLAGizmoEventType : unsigned char;
 
 class GLGizmoHollow : public GLGizmoBase
 {
 private:
-    //mutable double m_z_shift = 0.;
     bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
 
     GLUquadricObj* m_quadric;
@@ -33,11 +28,10 @@ public:
     ~GLGizmoHollow() override;
     void set_sla_support_data(ModelObject* model_object, const Selection& selection);
     bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
-    void delete_selected_points();
-    //ClippingPlane get_sla_clipping_plane() const;
-    
-    bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); }
-    //void set_common_data_ptr(CommonGizmosData* ptr) { m_c = ptr; }
+    void delete_selected_points();    
+    bool is_selection_rectangle_dragging() const {
+        return m_selection_rectangle.is_dragging();
+    }
 
 private:
     bool on_init() override;
@@ -46,7 +40,6 @@ private:
     void on_render_for_picking() const override;
 
     void render_points(const Selection& selection, bool picking = false) const;
-    void render_clipping_plane(const Selection& selection) const;
     void hollow_mesh(bool postpone_error_messages = false);
     bool unsaved_changes() const;
 
@@ -66,10 +59,6 @@ private:
     sla::DrainHoles m_holes_in_drilled_mesh;
 
     sla::DrainHoles m_holes_stash;
-
-    //CommonGizmosData* m_c = nullptr;
-
-    //std::unique_ptr<ClippingPlane> m_clipping_plane;
     
     // 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.
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
index 16ac6ec3c..496568d51 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
@@ -2,7 +2,6 @@
 #include "GLGizmoSlaSupports.hpp"
 #include "slic3r/GUI/GLCanvas3D.hpp"
 #include "slic3r/GUI/Camera.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmos.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
 
 #include <GL/glew.h>
@@ -15,7 +14,6 @@
 #include "slic3r/GUI/GUI.hpp"
 #include "slic3r/GUI/GUI_ObjectSettings.hpp"
 #include "slic3r/GUI/GUI_ObjectList.hpp"
-#include "slic3r/GUI/MeshUtils.hpp"
 #include "slic3r/GUI/Plater.hpp"
 #include "slic3r/GUI/PresetBundle.hpp"
 #include "libslic3r/SLAPrint.hpp"
@@ -27,7 +25,6 @@ namespace GUI {
 GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
     : GLGizmoBase(parent, icon_filename, sprite_id)
     , m_quadric(nullptr)
-    , m_its(nullptr)
 {    
     m_quadric = ::gluNewQuadric();
     if (m_quadric != nullptr)
@@ -76,24 +73,6 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S
         m_old_mo = mo;
     }
 
-    /*
-    if (m_c->recent_update) {
-        if (m_state == On)
-            m_c->build_AABB_if_needed();
-
-        update_clipping_plane(m_c->m_clipping_plane_was_moved);
-
-        disable_editing_mode();
-        if (m_c->m_model_object)
-            reload_cache();
-    }
-
-    if (m_state == On) {
-        m_parent.toggle_model_objects_visibility(false);
-        m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
-        m_parent.toggle_sla_auxiliaries_visibility(! m_editing_mode, m_c->m_model_object, m_c->m_active_instance);
-    }*/
-
     // If we triggered autogeneration before, check backend and fetch results if they are there
     if (mo) {
         if (mo->sla_points_status == sla::PointsStatus::Generating)
@@ -111,8 +90,7 @@ void GLGizmoSlaSupports::on_render() const
     // If current m_c->m_model_object does not match selection, ask GLCanvas3D to turn us off
     if (m_state == On
      && (mo != selection.get_model()->objects[selection.get_object_idx()]
-      || m_c->selection_info()->get_active_instance() != selection.get_instance_idx()
-      /*|| m_c->m_model_object_id != m_c->m_model_object->id()*/)) {
+      || m_c->selection_info()->get_active_instance() != selection.get_instance_idx())) {
         m_parent.post_event(SimpleEvent(EVT_GLCANVAS_RESETGIZMOS));
         return;
     }
@@ -120,116 +98,20 @@ void GLGizmoSlaSupports::on_render() const
     glsafe(::glEnable(GL_BLEND));
     glsafe(::glEnable(GL_DEPTH_TEST));
 
-//    m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
-
     if (m_quadric != nullptr && selection.is_from_single_instance())
         render_points(selection, false);
 
     m_selection_rectangle.render(m_parent);
     m_c->object_clipper()->render_cut();
     m_c->supports_clipper()->render_cut();
-    //render_clipping_plane(selection);
 
     glsafe(::glDisable(GL_BLEND));
 }
 
 
-
-/*void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection) const
-{
-    if (m_c->m_clipping_plane_distance == 0.f || m_c->m_mesh->empty())
-        return;
-
-    // Get transformation of the instance
-    const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
-    Geometry::Transformation trafo = vol->get_instance_transformation();
-    trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift));
-
-    // Get transformation of supports
-    Geometry::Transformation supports_trafo;
-    supports_trafo.set_offset(Vec3d(trafo.get_offset()(0), trafo.get_offset()(1), vol->get_sla_shift_z()));
-    supports_trafo.set_rotation(Vec3d(0., 0., trafo.get_rotation()(2)));
-    // I don't know why, but following seems to be correct.
-    supports_trafo.set_mirror(Vec3d(trafo.get_mirror()(0) * trafo.get_mirror()(1) * trafo.get_mirror()(2),
-                                    1,
-                                    1.));
-
-    // Now initialize the TMS for the object, perform the cut and save the result.
-    if (! m_c->m_object_clipper) {
-        m_c->m_object_clipper.reset(new MeshClipper);
-        m_c->m_object_clipper->set_mesh(*m_c->mesh());
-    }
-    m_c->m_object_clipper->set_plane(*m_c->m_clipping_plane);
-    m_c->m_object_clipper->set_transformation(trafo);
-
-
-    // Next, ask the backend if supports are already calculated. If so, we are gonna cut them too.
-    // First we need a pointer to the respective SLAPrintObject. The index into objects vector is
-    // cached so we don't have todo it on each render. We only search for the po if needed:
-    if (m_c->m_print_object_idx < 0 || (int)m_parent.sla_print()->objects().size() != m_c->m_print_objects_count) {
-        m_c->m_print_objects_count = m_parent.sla_print()->objects().size();
-        m_c->m_print_object_idx = -1;
-        for (const SLAPrintObject* po : m_parent.sla_print()->objects()) {
-            ++m_c->m_print_object_idx;
-            if (po->model_object()->id() == m_c->m_model_object->id())
-                break;
-        }
-    }
-    if (m_c->m_print_object_idx >= 0) {
-        const SLAPrintObject* print_object = m_parent.sla_print()->objects()[m_c->m_print_object_idx];
-
-        if (print_object->is_step_done(slaposSupportTree) && !print_object->get_mesh(slaposSupportTree).empty()) {
-            // If the supports are already calculated, save the timestamp of the respective step
-            // so we can later tell they were recalculated.
-            size_t timestamp = print_object->step_state_with_timestamp(slaposSupportTree).timestamp;
-
-            if (! m_c->m_supports_clipper || (int)timestamp != m_c->m_old_timestamp) {
-                // The timestamp has changed.
-                m_c->m_supports_clipper.reset(new MeshClipper);
-                // The mesh should already have the shared vertices calculated.
-                m_c->m_supports_clipper->set_mesh(print_object->support_mesh());
-                m_c->m_old_timestamp = timestamp;
-            }
-            m_c->m_supports_clipper->set_plane(*m_c->m_clipping_plane);
-            m_c->m_supports_clipper->set_transformation(supports_trafo);
-        }
-        else
-            // The supports are not valid. We better dump the cached data.
-            m_c->m_supports_clipper.reset();
-    }
-
-    // At this point we have the triangulated cuts for both the object and supports - let's render.
-    if (! m_c->m_object_clipper->get_triangles().empty()) {
-		::glPushMatrix();
-        ::glColor3f(1.0f, 0.37f, 0.0f);
-        ::glBegin(GL_TRIANGLES);
-        for (const Vec3f& point : m_c->m_object_clipper->get_triangles())
-            ::glVertex3f(point(0), point(1), point(2));
-        ::glEnd();
-		::glPopMatrix();
-	}
-
-    if (m_c->m_supports_clipper && ! m_c->m_supports_clipper->get_triangles().empty() && !m_editing_mode) {
-        // The supports are hidden in the editing mode, so it makes no sense to render the cuts.
-        ::glPushMatrix();
-        ::glColor3f(1.0f, 0.f, 0.37f);
-        ::glBegin(GL_TRIANGLES);
-        for (const Vec3f& point : m_c->m_supports_clipper->get_triangles())
-            ::glVertex3f(point(0), point(1), point(2));
-        ::glEnd();
-		::glPopMatrix();
-	}
-}*/
-
-
 void GLGizmoSlaSupports::on_render_for_picking() const
 {
     const Selection& selection = m_parent.get_selection();
-/*
-#if ENABLE_RENDER_PICKING_PASS
-	m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
-#endif
-*/
     glsafe(::glEnable(GL_DEPTH_TEST));
     render_points(selection, true);
 }
@@ -404,11 +286,7 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
     if (! m_c->raycaster()->raycaster())
         return false;
 
-#if ENABLE_NON_STATIC_CANVAS_MANAGER
     const Camera& camera = wxGetApp().plater()->get_camera();
-#else
-    const Camera& camera = m_parent.get_camera();
-#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
     const Selection& selection = m_parent.get_selection();
     const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
     Geometry::Transformation trafo = volume->get_instance_transformation();
@@ -607,8 +485,6 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
         double pos = m_c->object_clipper()->get_position();
         pos = std::min(1., pos + 0.01);
         m_c->object_clipper()->set_position(pos, true);
-        //update_clipping_plane(/*m_c->m_clipping_plane_was_moved*/);
-        //m_c->m_clipping_plane_was_moved = true;
         return true;
     }
 
@@ -616,12 +492,10 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
         double pos = m_c->object_clipper()->get_position();
         pos = std::max(0., pos - 0.01);
         m_c->object_clipper()->set_position(pos, true);
-        //update_clipping_plane(true);
         return true;
     }
 
     if (action == SLAGizmoEventType::ResetClippingPlane) {
-        //update_clipping_plane();
         m_c->object_clipper()->set_position(-1., false);
         return true;
     }
@@ -691,23 +565,7 @@ std::vector<const ConfigOption*> GLGizmoSlaSupports::get_config_options(const st
     return out;
 }
 
-/*
-ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
-{
-    //if (!m_c->m_model_object || m_state == Off || m_c->m_clipping_plane_distance == 0.f)
-    //    return ClippingPlane::ClipsNothing();
-    //else
-    //    return ClippingPlane(-m_c->m_clipping_plane->get_normal(), m_c->m_clipping_plane->get_data()[3]);
-    if (! m_c->selection_info()->model_object()
-     || m_state == Off
-     || m_c->object_clipper()->get_position() == 0.)
-        return ClippingPlane::ClipsNothing();
-    else {
-        const ClippingPlane& clp = *m_c->object_clipper()->get_clipping_plane();
-        return ClippingPlane(-clp.get_normal(), clp.get_data()[3]);
-    }
-}
-*/
+
 
 /*
 void GLGizmoSlaSupports::find_intersecting_facets(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<unsigned int>& idxs) const
@@ -937,7 +795,6 @@ RENDER_AGAIN:
     else {
         if (m_imgui->button(m_desc.at("reset_direction"))) {
             wxGetApp().CallAfter([this](){
-                    //update_clipping_plane();
                     m_c->object_clipper()->set_position(-1., false);
                 });
         }
@@ -1028,15 +885,6 @@ CommonGizmosDataID GLGizmoSlaSupports::on_get_requirements() const
 void GLGizmoSlaSupports::on_set_state()
 {
     const ModelObject* mo = m_c->selection_info()->model_object();
-    // m_c->m_model_object pointer can be invalid (for instance because of undo/redo action),
-    // we should recover it from the object id
-    /*m_c->m_model_object = nullptr;
-    for (const auto mo : wxGetApp().model().objects) {
-        if (mo->id() == m_c->m_model_object_id) {
-            m_c->m_model_object = mo;
-            break;
-        }
-    }*/
 
     if (m_state == m_old_state)
         return;
@@ -1044,22 +892,10 @@ 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")));
 
-        //m_c->unstash_clipping_plane();
-        //update_clipping_plane(m_c->m_clipping_plane_was_moved);
-
-        //m_c->build_AABB_if_needed();
-
-
         // we'll now reload support points:
         if (mo)
             reload_cache();
 
-        /*m_parent.toggle_model_objects_visibility(false);
-        if (m_c->m_model_object)  {
-            m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
-            m_parent.toggle_sla_auxiliaries_visibility(! m_editing_mode, m_c->m_model_object, m_c->m_active_instance);
-        }*/
-
         // 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<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value;
@@ -1084,16 +920,8 @@ void GLGizmoSlaSupports::on_set_state()
             // we are actually shutting down
             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_c->stash_clipping_plane();
-            //m_c->m_clipping_plane_distance = 0.f;
-            //update_clipping_plane(true);
-            // Release clippers and the AABB raycaster.
-            //m_its = nullptr;
-            //m_c->m_object_clipper.reset();
-            //m_c->m_supports_clipper.reset();
-            //m_c->m_mesh_raycaster.reset();
+
         }
     }
     m_old_state = m_state;
@@ -1318,7 +1146,6 @@ void GLGizmoSlaSupports::switch_to_editing_mode()
         m_editing_cache.emplace_back(sp);
     select_point(NoPoints);
 
-    //m_parent.toggle_sla_auxiliaries_visibility(false, m_c->m_model_object, m_c->m_active_instance);
     m_c->instances_hider()->show_supports(false);
     m_parent.set_as_dirty();
 }
@@ -1329,7 +1156,6 @@ void GLGizmoSlaSupports::disable_editing_mode()
     if (m_editing_mode) {
         m_editing_mode = false;
         wxGetApp().plater()->leave_gizmos_stack();
-        //m_parent.toggle_sla_auxiliaries_visibility(true, m_c->m_model_object, m_c->m_active_instance);
         m_c->instances_hider()->show_supports(true);
         m_parent.set_as_dirty();
     }
@@ -1349,26 +1175,6 @@ bool GLGizmoSlaSupports::unsaved_changes() const
     return false;
 }
 
-/*
-void GLGizmoSlaSupports::update_clipping_plane(bool keep_normal) const
-{
-    if (! m_c->m_model_object)
-        return;
-
-#if ENABLE_NON_STATIC_CANVAS_MANAGER
-    Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
-        m_c->m_clipping_plane->get_normal() : -wxGetApp().plater()->get_camera().get_dir_forward());
-#else
-    Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
-        m_c->m_clipping_plane->get_normal() : -m_parent.get_camera().get_dir_forward());
-#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
-
-    const Vec3d& center = m_c->m_model_object->instances[m_c->m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift);
-    float dist = normal.dot(center);
-    *m_c->m_clipping_plane = ClippingPlane(normal, (dist - (-m_c->m_active_instance_bb_radius) - m_c->m_clipping_plane_distance * 2*m_c->m_active_instance_bb_radius));
-    m_parent.set_as_dirty();
-}*/
-
 SlaGizmoHelpDialog::SlaGizmoHelpDialog()
 : wxDialog(nullptr, wxID_ANY, _(L("SLA gizmo keyboard shortcuts")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
 {
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
index 2b7b1ae78..43454609a 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
@@ -13,20 +13,12 @@
 namespace Slic3r {
 namespace GUI {
 
-class ClippingPlane;
-class MeshClipper;
-class MeshRaycaster;
-//class CommonGizmosData;
 enum class SLAGizmoEventType : unsigned char;
 
 class GLGizmoSlaSupports : public GLGizmoBase
 {
 private:
-    //ModelObject* m_model_object = nullptr;
-    //ObjectID m_model_object_id = 0;
-    //int m_active_instance = -1;
-    //float m_active_instance_bb_radius; // to cache the bb
-    //mutable double m_z_shift = 0.f;
+
     bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
 
     const float RenderPointScale = 1.f;
@@ -35,13 +27,6 @@ private:
     typedef Eigen::Map<const Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor | Eigen::DontAlign>> MapMatrixXfUnaligned;
     typedef Eigen::Map<const Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor | Eigen::DontAlign>> MapMatrixXiUnaligned;
 
-    //std::unique_ptr<MeshRaycaster> m_mesh_raycaster;
-    //const TriangleMesh* m_mesh;
-    const indexed_triangle_set* m_its;
-    //mutable int m_old_timestamp = -1;
-    //mutable int m_print_object_idx = -1;
-    //mutable int m_print_objects_count = -1;
-
     class CacheEntry {
     public:
         CacheEntry() :
@@ -81,8 +66,6 @@ public:
     bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); }
     bool has_backend_supports() const;
     void reslice_SLA_supports(bool postpone_error_messages = false) const;
-    //void update_clipping_plane(bool keep_normal = false) const;
-    //void set_common_data_ptr(CommonGizmosData* ptr) { m_c = ptr; }
 
 private:
     bool on_init() override;
@@ -90,9 +73,7 @@ private:
     void on_render() const override;
     void on_render_for_picking() const override;
 
-    //void render_selection_rectangle() const;
     void render_points(const Selection& selection, bool picking = false) const;
-    //void render_clipping_plane(const Selection& selection) const;
     bool unsaved_changes() const;
 
     bool m_lock_unique_islands = false;
@@ -106,8 +87,6 @@ private:
     std::vector<sla::SupportPoint> m_normal_cache; // to restore after discarding changes or undo/redo
     const ModelObject* m_old_mo = nullptr;
 
-    //std::unique_ptr<ClippingPlane> m_clipping_plane;
-
     // 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.
     std::map<std::string, wxString> m_desc;
@@ -118,11 +97,6 @@ private:
     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)
 
-    //CommonGizmosData* m_c = nullptr;
-
-    //mutable std::unique_ptr<MeshClipper> m_object_clipper;
-    //mutable std::unique_ptr<MeshClipper> m_supports_clipper;
-
     std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const;
     bool is_mesh_point_clipped(const Vec3d& point) const;
     bool is_point_in_hole(const Vec3f& pt) const;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmos.hpp b/src/slic3r/GUI/Gizmos/GLGizmos.hpp
deleted file mode 100644
index 9f97c42b4..000000000
--- a/src/slic3r/GUI/Gizmos/GLGizmos.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef slic3r_GLGizmos_hpp_
-#define slic3r_GLGizmos_hpp_
-
-// this describes events being passed from GLCanvas3D to SlaSupport gizmo
-namespace Slic3r {
-namespace GUI {
-
-enum class SLAGizmoEventType : unsigned char {
-    LeftDown = 1,
-    LeftUp,
-    RightDown,
-    Dragging,
-    Delete,
-    SelectAll,
-    ShiftUp,
-    AltUp,
-    ApplyChanges,
-    DiscardChanges,
-    AutomaticGeneration,
-    ManualEditing,
-    MouseWheelUp,
-    MouseWheelDown,
-    ResetClippingPlane
-};
-
-} // namespace GUI
-} // namespace Slic3r
-
-#include "slic3r/GUI/Gizmos/GLGizmoMove.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmoScale.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmoRotate.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmoFlatten.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmoCut.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmoHollow.hpp"
-
-#endif //slic3r_GLGizmos_hpp_
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
index 54e561f2f..ba0c310bf 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp
@@ -17,6 +17,24 @@ class GLCanvas3D;
 
 static constexpr float HoleStickOutLength = 1.f;
 
+enum class SLAGizmoEventType : unsigned char {
+    LeftDown = 1,
+    LeftUp,
+    RightDown,
+    Dragging,
+    Delete,
+    SelectAll,
+    ShiftUp,
+    AltUp,
+    ApplyChanges,
+    DiscardChanges,
+    AutomaticGeneration,
+    ManualEditing,
+    MouseWheelUp,
+    MouseWheelDown,
+    ResetClippingPlane
+};
+
 
 
 class CommonGizmosDataBase;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 61d0bd5f4..f9d832bb1 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -9,10 +9,14 @@
 #include "slic3r/GUI/GUI_ObjectManipulation.hpp"
 #include "slic3r/GUI/PresetBundle.hpp"
 #include "slic3r/Utils/UndoRedo.hpp"
-//#include "libslic3r/SLAPrint.hpp"
-//#include "slic3r/GUI/MeshUtils.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmos.hpp"
-//#include "slic3r/GUI/Camera.hpp"
+
+#include "slic3r/GUI/Gizmos/GLGizmoMove.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmoScale.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmoRotate.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmoFlatten.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmoCut.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmoHollow.hpp"
 
 #include <wx/glcanvas.h>
 
@@ -402,15 +406,6 @@ ClippingPlane GLGizmosManager::get_sla_clipping_plane() const
         const ClippingPlane& clp = *m_common_gizmos_data->object_clipper()->get_clipping_plane();
         return ClippingPlane(-clp.get_normal(), clp.get_data()[3]);
     }
-
-
-    /*if (!m_enabled || (m_current != SlaSupports && m_current != Hollow) || m_gizmos.empty())
-        return ClippingPlane::ClipsNothing();
-
-    if (m_current == SlaSupports)
-        return dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->get_sla_clipping_plane();
-    else
-        return dynamic_cast<GLGizmoHollow*>(m_gizmos[Hollow].get())->get_sla_clipping_plane();*/
 }
 
 bool GLGizmosManager::wants_reslice_supports_on_undo() const
@@ -1227,136 +1222,5 @@ bool GLGizmosManager::grabber_contains_mouse() const
     return (curr != nullptr) ? (curr->get_hover_id() != -1) : false;
 }
 
-
-/*
-CommonGizmosData::CommonGizmosData()
-{
-    m_clipping_plane.reset(new ClippingPlane(Vec3d::Zero(), 0.));
-}
-
-
-
-bool CommonGizmosData::update_from_backend(GLCanvas3D& canvas, ModelObject* model_object)
-{
-    recent_update = false;
-    bool object_changed = false;
-
-    if (m_model_object != model_object
-    || (model_object && m_model_object_id != model_object->id())) {
-        m_model_object = model_object;
-        m_print_object_idx = -1;
-        m_mesh_raycaster.reset();
-        m_object_clipper.reset();
-        m_supports_clipper.reset();
-        m_old_mesh = nullptr;
-        m_mesh = nullptr;
-        m_backend_mesh_transformed.clear();
-
-        object_changed = true;
-        recent_update = true;
-    }
-
-    if (m_model_object) {
-        int active_inst = canvas.get_selection().get_instance_idx();
-        if (m_active_instance != active_inst) {
-            m_active_instance = active_inst;
-            m_active_instance_bb_radius = m_model_object->instance_bounding_box(m_active_instance).radius();
-            recent_update = true;
-        }
-    }
-
-
-    if (! m_model_object || ! canvas.get_selection().is_from_single_instance())
-        return false;
-
-    int old_po_idx = m_print_object_idx;
-
-    // First we need a pointer to the respective SLAPrintObject. The index into objects vector is
-    // cached so we don't have todo it on each render. We only search for the po if needed:
-    if (m_print_object_idx < 0 || (int)canvas.sla_print()->objects().size() != m_print_objects_count) {
-        m_print_objects_count = canvas.sla_print()->objects().size();
-        m_print_object_idx = -1;
-        for (const SLAPrintObject* po : canvas.sla_print()->objects()) {
-            ++m_print_object_idx;
-            if (po->model_object()->id() == m_model_object->id())
-                break;
-        }
-    }
-
-    bool mesh_exchanged = false;
-    m_mesh = nullptr;
-    // Load either the model_object mesh, or one provided by the backend
-    // This mesh does not account for the possible Z up SLA offset.
-    // The backend mesh needs to be transformed and because a pointer to it is
-    // saved, a copy is stored as a member (FIXME)
-    if (m_print_object_idx >=0) {
-        const SLAPrintObject* po = canvas.sla_print()->objects()[m_print_object_idx];
-        if (po->is_step_done(slaposDrillHoles)) {
-            m_backend_mesh_transformed = po->get_mesh_to_print();
-            m_backend_mesh_transformed.transform(canvas.sla_print()->sla_trafo(*m_model_object).inverse());
-            m_mesh = &m_backend_mesh_transformed;
-            m_has_drilled_mesh = true;
-            mesh_exchanged = true;
-        }
-    }
-
-    if (! m_mesh) {
-        m_mesh = &m_model_object->volumes.front()->mesh();
-        m_backend_mesh_transformed.clear();
-        m_has_drilled_mesh = false;
-    }
-
-    m_model_object_id = m_model_object->id();
-
-    if (m_mesh != m_old_mesh) {
-        // Update clipping plane position.
-        float new_clp_pos = m_clipping_plane_distance;
-        if (object_changed) {
-            new_clp_pos = 0.f;
-            m_clipping_plane_was_moved = false;
-        } else {
-            // After we got a drilled mesh, move the cp to 25%. This only applies when
-            // the hollowing gizmo is active and hollowing is enabled
-            if (m_clipping_plane_distance == 0.f && mesh_exchanged && m_has_drilled_mesh) {
-                const DynamicPrintConfig& cfg =
-                    (m_model_object && m_model_object->config.has("hollowing_enable"))
-                    ? m_model_object->config
-                    : wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
-
-                if (cfg.has("hollowing_enable") && cfg.opt_bool("hollowing_enable")
-                 && canvas.get_gizmos_manager().get_current_type() == GLGizmosManager::Hollow) {
-                   new_clp_pos = 0.25f;
-                   m_clipping_plane_was_moved = false; // so it uses current camera direction
-                }
-            }
-        }
-        m_clipping_plane_distance = new_clp_pos;
-        m_clipping_plane_distance_stash = new_clp_pos;
-
-        m_schedule_aabb_calculation = true;
-        recent_update = true;
-        return true;
-    }
-    if (! recent_update)
-        recent_update = m_print_object_idx < 0 && old_po_idx >= 0;
-
-    return recent_update;
-}
-
-
-void CommonGizmosData::build_AABB_if_needed()
-{
-    if (! m_schedule_aabb_calculation)
-        return;
-
-    wxBusyCursor wait;
-    m_mesh_raycaster.reset(new MeshRaycaster(*m_mesh));
-    m_object_clipper.reset();
-    m_supports_clipper.reset();
-    m_old_mesh = m_mesh;
-    m_schedule_aabb_calculation = false;
-}*/
-
-
 } // namespace GUI
 } // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
index 81fd991b7..a31a96a26 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
@@ -3,7 +3,6 @@
 
 #include "slic3r/GUI/GLTexture.hpp"
 #include "slic3r/GUI/GLToolbar.hpp"
-//#include "libslic3r/ObjectID.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmoBase.hpp"
 #include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
 
@@ -20,7 +19,6 @@ namespace GUI {
 class GLCanvas3D;
 class ClippingPlane;
 enum class SLAGizmoEventType : unsigned char;
-//class CommonGizmosData;
 class CommonGizmosDataPool;
 
 class Rect
@@ -234,63 +232,6 @@ private:
 
 
 
-//class MeshRaycaster;
-//class MeshClipper;
-
-// This class is only for sharing SLA related data between SLA gizmos
-// and its synchronization with backend data. It should not be misused
-// for anything else.
-/*class CommonGizmosData {
-public:
-    CommonGizmosData();
-    const TriangleMesh* mesh() const {
-        return (! m_mesh ? nullptr : m_mesh); //(m_cavity_mesh ? m_cavity_mesh.get() : m_mesh));
-    }
-
-    bool update_from_backend(GLCanvas3D& canvas, ModelObject* model_object);
-    bool recent_update = false;
-    static constexpr float HoleStickOutLength = 1.f;
-
-    ModelObject* m_model_object = nullptr;
-    const TriangleMesh* m_mesh;
-    std::unique_ptr<MeshRaycaster> m_mesh_raycaster;
-    std::unique_ptr<MeshClipper> m_object_clipper;
-    std::unique_ptr<MeshClipper> m_supports_clipper;
-
-    //std::unique_ptr<TriangleMesh> m_cavity_mesh;
-    //std::unique_ptr<GLVolume> m_volume_with_cavity;
-
-    int m_active_instance = -1;
-    float m_active_instance_bb_radius = 0;
-    ObjectID m_model_object_id = 0;
-    int m_print_object_idx = -1;
-    int m_print_objects_count = -1;
-    int m_old_timestamp = -1;
-
-    float m_clipping_plane_distance = 0.f;
-    std::unique_ptr<ClippingPlane> m_clipping_plane;
-    bool m_clipping_plane_was_moved = false;
-
-    void stash_clipping_plane() {
-        m_clipping_plane_distance_stash = m_clipping_plane_distance;
-    }
-
-    void unstash_clipping_plane() {
-        m_clipping_plane_distance = m_clipping_plane_distance_stash;
-    }
-
-    bool has_drilled_mesh() const { return m_has_drilled_mesh; }
-
-    void build_AABB_if_needed();
-
-private:
-    const TriangleMesh* m_old_mesh;
-    TriangleMesh m_backend_mesh_transformed;
-    float m_clipping_plane_distance_stash = 0.f;
-    bool m_has_drilled_mesh = false;
-    bool m_schedule_aabb_calculation = false;
-};
-*/
 } // namespace GUI
 } // namespace Slic3r