diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index c8f7e9f1c9..f13c6084b3 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 0d19a86afe..965f195a91 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 0000000000..89a6715190 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -0,0 +1,53 @@ +#include "GLGizmosCommon.hpp" + +#include + +#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 0000000000..6d83179cb6 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -0,0 +1,191 @@ +#ifndef slic3r_GUI_GLGizmosCommon_hpp_ +#define slic3r_GUI_GLGizmosCommon_hpp_ + +#include +#include + +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> 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_