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] 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