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