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 "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;

View file

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

View file

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

View file

@ -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;
};

View file

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