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 "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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue