Flattening gizmo now uses the new CommonDataPool to store pointer to active object

This commit is contained in:
Lukas Matena 2020-04-03 13:27:04 +02:00
parent 3b06332999
commit 593e7a1546
5 changed files with 71 additions and 44 deletions

View file

@ -2,6 +2,7 @@
#include "GLGizmoFlatten.hpp" #include "GLGizmoFlatten.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
#include <numeric> #include <numeric>
@ -26,20 +27,15 @@ bool GLGizmoFlatten::on_init()
void GLGizmoFlatten::on_set_state() 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()) if (m_state == On && is_plane_update_necessary())
update_planes(); update_planes();
} }
CommonGizmosDataID GLGizmoFlatten::on_get_requirements() const
{
return CommonGizmosDataID::SelectionInfo;
}
std::string GLGizmoFlatten::on_get_name() const std::string GLGizmoFlatten::on_get_name() const
{ {
return (_(L("Place on face")) + " [F]").ToUTF8().data(); 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) void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object)
{ {
m_starting_center = Vec3d::Zero(); m_starting_center = Vec3d::Zero();
if (m_model_object != model_object) { if (model_object != m_old_model_object) {
m_planes.clear(); m_planes.clear();
m_planes_valid = false; m_planes_valid = false;
} }
m_model_object = model_object;
m_model_object_id = model_object ? model_object->id() : 0;
} }
void GLGizmoFlatten::update_planes() void GLGizmoFlatten::update_planes()
{ {
const ModelObject* mo = m_c->selection_info()->model_object();
TriangleMesh ch; TriangleMesh ch;
for (const ModelVolume* vol : m_model_object->volumes) for (const ModelVolume* vol : mo->volumes)
{ {
if (vol->type() != ModelVolumeType::MODEL_PART) if (vol->type() != ModelVolumeType::MODEL_PART)
continue; continue;
@ -153,7 +148,7 @@ void GLGizmoFlatten::update_planes()
} }
ch = ch.convex_hull_3d(); ch = ch.convex_hull_3d();
m_planes.clear(); 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. // Following constants are used for discarding too small polygons.
const float minimal_area = 5.f; // in square mm (world coordinates) 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: // Planes are finished - let's save what we calculated it from:
m_volumes_matrices.clear(); m_volumes_matrices.clear();
m_volumes_types.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_matrices.push_back(vol->get_matrix());
m_volumes_types.push_back(vol->type()); m_volumes_types.push_back(vol->type());
} }
m_first_instance_scale = m_model_object->instances.front()->get_scaling_factor(); m_first_instance_scale = mo->instances.front()->get_scaling_factor();
m_first_instance_mirror = m_model_object->instances.front()->get_mirror(); m_first_instance_mirror = mo->instances.front()->get_mirror();
m_old_model_object = mo;
m_planes_valid = true; m_planes_valid = true;
} }
@ -344,20 +340,22 @@ void GLGizmoFlatten::update_planes()
bool GLGizmoFlatten::is_plane_update_necessary() const 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; 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; return true;
// We want to recalculate when the scale changes - some planes could (dis)appear. // 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) if (! mo->instances.front()->get_scaling_factor().isApprox(m_first_instance_scale)
|| ! m_model_object->instances.front()->get_mirror().isApprox(m_first_instance_mirror)) || ! mo->instances.front()->get_mirror().isApprox(m_first_instance_mirror))
return true; return true;
for (unsigned int i=0; i < m_model_object->volumes.size(); ++i) for (unsigned int i=0; i < mo->volumes.size(); ++i)
if (! m_model_object->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i]) if (! mo->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i])
|| m_model_object->volumes[i]->type() != m_volumes_types[i]) || mo->volumes[i]->type() != m_volumes_types[i])
return true; return true;
return false; return false;

View file

@ -30,8 +30,7 @@ private:
std::vector<PlaneData> m_planes; std::vector<PlaneData> m_planes;
bool m_planes_valid = false; bool m_planes_valid = false;
mutable Vec3d m_starting_center; mutable Vec3d m_starting_center;
const ModelObject* m_model_object = nullptr; const ModelObject* m_old_model_object = nullptr;
ObjectID m_model_object_id = 0;
std::vector<const Transform3d*> instances_matrices; std::vector<const Transform3d*> instances_matrices;
void update_planes(); void update_planes();
@ -51,6 +50,7 @@ protected:
virtual void on_render() const override; virtual void on_render() const override;
virtual void on_render_for_picking() const override; virtual void on_render_for_picking() const override;
virtual void on_set_state() override; virtual void on_set_state() override;
virtual CommonGizmosDataID on_get_requirements() const override;
}; };
} // namespace GUI } // namespace GUI

View file

@ -7,11 +7,11 @@
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
using namespace CommonGizmosDataObjects;
CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas) CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
: m_canvas(canvas) : m_canvas(canvas)
{ {
using namespace CommonGizmosDataObjects;
using c = CommonGizmosDataID; using c = CommonGizmosDataID;
m_data[c::SelectionInfo].reset( new SelectionInfo(this)); m_data[c::SelectionInfo].reset( new SelectionInfo(this));
//m_data[c::InstancesHider].reset( new InstancesHider(this)); //m_data[c::InstancesHider].reset( new InstancesHider(this));
@ -24,8 +24,19 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
void CommonGizmosDataPool::update(CommonGizmosDataID required) void CommonGizmosDataPool::update(CommonGizmosDataID required)
{ {
assert(check_dependencies(required)); assert(check_dependencies(required));
for (auto& [id, data] : m_data) for (auto& [id, data] : m_data) {
data->update(int(required) & int(CommonGizmosDataID(id))); 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 #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(); 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 GUI
} // namespace Slic3r } // namespace Slic3r

View file

@ -46,10 +46,10 @@ public:
// Update all resources and release what is not used. // Update all resources and release what is not used.
// Accepts a bitmask of currently required resources. // 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. // 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; } GLCanvas3D* get_canvas() const { return m_canvas; }
@ -74,16 +74,21 @@ public:
// objects can communicate with one another. // objects can communicate with one another.
explicit CommonGizmosDataBase(CommonGizmosDataPool* cgdp) explicit CommonGizmosDataBase(CommonGizmosDataPool* cgdp)
: m_common{cgdp} {} : m_common{cgdp} {}
virtual ~CommonGizmosDataBase() {}
// Update the resource. If it is not needed (based on argument value) // Update the resource.
// any persistent data will be released. void update() { on_update(); m_is_valid = true; }
virtual void update(bool required) = 0;
// Release any data that are stored internally.
void release() { on_release(); m_is_valid = false; }
// Returns whether the resource is currently maintained. // Returns whether the resource is currently maintained.
bool is_valid() const { return m_is_valid; } bool is_valid() const { return m_is_valid; }
protected: protected:
CommonGizmosDataPool* m_common = nullptr; CommonGizmosDataPool* m_common = nullptr;
virtual void on_release() = 0;
virtual void on_update() = 0;
private: private:
bool m_is_valid = false; bool m_is_valid = false;
@ -99,13 +104,16 @@ namespace CommonGizmosDataObjects
class SelectionInfo : public CommonGizmosDataBase class SelectionInfo : public CommonGizmosDataBase
{ {
public: public:
explicit SelectionInfo(CommonGizmosDataPool* cgdp) : explicit SelectionInfo(CommonGizmosDataPool* cgdp)
CommonGizmosDataBase(cgdp) {} : CommonGizmosDataBase(cgdp) {}
void update(bool required) override;
ModelObject* model_object(); ModelObject* model_object() { return m_model_object; }
int get_active_instance(); int get_active_instance();
protected:
void on_update() override;
void on_release() override;
private: private:
ModelObject* m_model_object = nullptr; ModelObject* m_model_object = nullptr;
int m_active_inst = -1; int m_active_inst = -1;
@ -115,8 +123,8 @@ private:
class InstancesHider : public CommonGizmosDataBase class InstancesHider : public CommonGizmosDataBase
{ {
public: public:
explicit InstancesHider(CommonGizmosDataPool* cgdp) : explicit InstancesHider(CommonGizmosDataPool* cgdp)
CommonGizmosDataBase(cgdp) {} : CommonGizmosDataBase(cgdp) {}
void update(bool required) override; void update(bool required) override;
}; };

View file

@ -201,6 +201,10 @@ void GLGizmosManager::update_data()
enable_grabber(Scale, i, enable_scale_xyz); 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()) 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 // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first