SLA support points edits are now pushed onto undo/redo stack

This commit is contained in:
Lukas Matena 2019-07-17 15:38:19 +02:00
parent f97a61cdcf
commit 81dde630ea
2 changed files with 110 additions and 45 deletions

View File

@ -106,6 +106,9 @@ void GLGizmoSlaSupports::on_render() const
return; return;
} }
if (! m_its || ! m_mesh)
const_cast<GLGizmoSlaSupports*>(this)->update_mesh();
glsafe(::glEnable(GL_BLEND)); glsafe(::glEnable(GL_BLEND));
glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glEnable(GL_DEPTH_TEST));
@ -387,20 +390,28 @@ bool GLGizmoSlaSupports::is_mesh_update_necessary() const
void GLGizmoSlaSupports::update_mesh() void GLGizmoSlaSupports::update_mesh()
{ {
if (! m_model_object)
return;
wxBusyCursor wait; wxBusyCursor wait;
// this way we can use that mesh directly. // this way we can use that mesh directly.
// This mesh does not account for the possible Z up SLA offset. // This mesh does not account for the possible Z up SLA offset.
m_mesh = &m_model_object->volumes.front()->mesh(); m_mesh = &m_model_object->volumes.front()->mesh();
m_its = &m_mesh->its; m_its = &m_mesh->its;
m_current_mesh_object_id = m_model_object->id();
m_editing_mode = false;
// If this is different mesh than last time or if the AABB tree is uninitialized, recalculate it.
if (m_current_mesh_object_id != m_model_object->id() || (m_AABB.m_left == NULL && m_AABB.m_right == NULL))
{
m_AABB.deinit(); m_AABB.deinit();
m_AABB.init( m_AABB.init(
MapMatrixXfUnaligned(m_its->vertices.front().data(), m_its->vertices.size(), 3), MapMatrixXfUnaligned(m_its->vertices.front().data(), m_its->vertices.size(), 3),
MapMatrixXiUnaligned(m_its->indices.front().data(), m_its->indices.size(), 3)); MapMatrixXiUnaligned(m_its->indices.front().data(), m_its->indices.size(), 3));
} }
m_current_mesh_object_id = m_model_object->id();
m_editing_mode = false;
}
// Unprojects the mouse position on the mesh and return the hit point and normal of the facet. // Unprojects the mouse position on the mesh and return the hit point and normal of the facet.
// The function throws if no intersection if found. // The function throws if no intersection if found.
std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos) std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
@ -1034,6 +1045,25 @@ std::string GLGizmoSlaSupports::on_get_name() const
void GLGizmoSlaSupports::on_set_state() void GLGizmoSlaSupports::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
const ModelObject* old_model_object = m_model_object;
m_model_object = nullptr;
for (const auto mo : *wxGetApp().model_objects()) {
if (mo->id() == m_current_mesh_object_id) {
m_model_object = mo;
break;
}
}
// If ModelObject pointer really changed, invalidate mesh and do everything
// as if the gizmo was switched from Off state
if (m_model_object == nullptr || old_model_object != m_model_object) {
m_mesh = nullptr;
m_its = nullptr;
m_old_state = Off;
}
if (m_state == On && m_old_state != On) { // the gizmo was just turned on if (m_state == On && m_old_state != On) { // the gizmo was just turned on
if (is_mesh_update_necessary()) if (is_mesh_update_necessary())
update_mesh(); update_mesh();
@ -1090,6 +1120,26 @@ void GLGizmoSlaSupports::on_start_dragging()
void GLGizmoSlaSupports::on_load(cereal::BinaryInputArchive& ar)
{
ar(m_clipping_plane_distance,
m_clipping_plane_normal,
m_current_mesh_object_id
);
}
void GLGizmoSlaSupports::on_save(cereal::BinaryOutputArchive& ar) const
{
ar(m_clipping_plane_distance,
m_clipping_plane_normal,
m_current_mesh_object_id
);
}
void GLGizmoSlaSupports::select_point(int i) void GLGizmoSlaSupports::select_point(int i)
{ {
if (i == AllPoints || i == NoPoints) { if (i == AllPoints || i == NoPoints) {
@ -1146,6 +1196,7 @@ void GLGizmoSlaSupports::editing_mode_apply_changes()
// If there are no changes, don't touch the front-end. The data in the cache could have been // If there are no changes, don't touch the front-end. The data in the cache could have been
// taken from the backend and copying them to ModelObject would needlessly invalidate them. // taken from the backend and copying them to ModelObject would needlessly invalidate them.
if (m_unsaved_changes) { if (m_unsaved_changes) {
wxGetApp().plater()->take_snapshot(_(L("Support points edit")));
m_model_object->sla_points_status = sla::PointsStatus::UserModified; m_model_object->sla_points_status = sla::PointsStatus::UserModified;
m_model_object->sla_support_points.clear(); m_model_object->sla_support_points.clear();
for (const CacheEntry& cache_entry : m_editing_mode_cache) for (const CacheEntry& cache_entry : m_editing_mode_cache)
@ -1204,6 +1255,7 @@ void GLGizmoSlaSupports::auto_generate()
)), _(L("Warning")), wxICON_WARNING | wxYES | wxNO); )), _(L("Warning")), wxICON_WARNING | wxYES | wxNO);
if (m_model_object->sla_points_status != sla::PointsStatus::UserModified || m_editing_mode_cache.empty() || dlg.ShowModal() == wxID_YES) { if (m_model_object->sla_points_status != sla::PointsStatus::UserModified || m_editing_mode_cache.empty() || dlg.ShowModal() == wxID_YES) {
wxGetApp().plater()->take_snapshot(_(L("Autogenerate support points")));
m_model_object->sla_support_points.clear(); m_model_object->sla_support_points.clear();
m_model_object->sla_points_status = sla::PointsStatus::Generating; m_model_object->sla_points_status = sla::PointsStatus::Generating;
m_editing_mode_cache.clear(); m_editing_mode_cache.clear();

View File

@ -14,6 +14,8 @@
#include "libslic3r/SLAPrint.hpp" #include "libslic3r/SLAPrint.hpp"
#include <wx/dialog.h> #include <wx/dialog.h>
#include <cereal/types/vector.hpp>
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -49,12 +51,21 @@ private:
class CacheEntry { class CacheEntry {
public: public:
CacheEntry() :
support_point(sla::SupportPoint()), selected(false), normal(Vec3f::Zero()) {}
CacheEntry(const sla::SupportPoint& point, bool sel, const Vec3f& norm = Vec3f::Zero()) : CacheEntry(const sla::SupportPoint& point, bool sel, const Vec3f& norm = Vec3f::Zero()) :
support_point(point), selected(sel), normal(norm) {} support_point(point), selected(sel), normal(norm) {}
sla::SupportPoint support_point; sla::SupportPoint support_point;
bool selected; // whether the point is selected bool selected; // whether the point is selected
Vec3f normal; Vec3f normal;
template<class Archive>
void serialize(Archive & ar)
{
ar(support_point, selected, normal);
}
}; };
public: public:
@ -139,6 +150,8 @@ protected:
virtual std::string on_get_name() const; virtual std::string on_get_name() const;
virtual bool on_is_activable() const; virtual bool on_is_activable() const;
virtual bool on_is_selectable() const; virtual bool on_is_selectable() const;
virtual void on_load(cereal::BinaryInputArchive& ar) override;
virtual void on_save(cereal::BinaryOutputArchive& ar) const override;
}; };