Flattening gizmo now uses the new CommonDataPool to store pointer to active object
This commit is contained in:
parent
3b06332999
commit
593e7a1546
5 changed files with 71 additions and 44 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue