Cut WIP: Undo/Redo implementation
This commit is contained in:
parent
73469ffa21
commit
94f3aaacd4
@ -17,16 +17,21 @@ src/slic3r/GUI/GalleryDialog.cpp
|
||||
src/slic3r/GUI/GCodeViewer.cpp
|
||||
src/slic3r/GUI/GLCanvas3D.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoCut.hpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
|
||||
src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp
|
||||
src/slic3r/GUI/GUI.cpp
|
||||
|
@ -584,7 +584,8 @@ private:
|
||||
Internal::StaticSerializationWrapper<LayerHeightProfile> layer_heigth_profile_wrapper(layer_height_profile);
|
||||
ar(name, input_file, instances, volumes, config_wrapper, layer_config_ranges, layer_heigth_profile_wrapper,
|
||||
sla_support_points, sla_points_status, sla_drain_holes, printable, origin_translation,
|
||||
m_bounding_box, m_bounding_box_valid, m_raw_bounding_box, m_raw_bounding_box_valid, m_raw_mesh_bounding_box, m_raw_mesh_bounding_box_valid);
|
||||
m_bounding_box, m_bounding_box_valid, m_raw_bounding_box, m_raw_bounding_box_valid, m_raw_mesh_bounding_box, m_raw_mesh_bounding_box_valid,
|
||||
cut_connectors, cut_id);
|
||||
}
|
||||
|
||||
// Called by Print::validate() from the UI thread.
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/TriangleMeshSlicer.hpp"
|
||||
@ -88,6 +89,8 @@ bool GLGizmoCut3D::on_mouse(const wxMouseEvent &mouse_event)
|
||||
return false;
|
||||
|
||||
if (m_rotation_gizmo.on_mouse(mouse_event)) {
|
||||
if (mouse_event.LeftUp())
|
||||
on_stop_dragging();
|
||||
update_clipper();
|
||||
return true;
|
||||
}
|
||||
@ -221,7 +224,7 @@ void GLGizmoCut3D::update_clipper()
|
||||
void GLGizmoCut3D::update_clipper_on_render()
|
||||
{
|
||||
update_clipper();
|
||||
suppress_update_clipper_on_render = true;
|
||||
force_update_clipper_on_render = false;
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::set_center(const Vec3d& center)
|
||||
@ -595,6 +598,27 @@ bool GLGizmoCut3D::on_init()
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::on_load(cereal::BinaryInputArchive& ar)
|
||||
{
|
||||
ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, //m_selected,
|
||||
m_connector_depth_ratio, m_connector_size, m_connector_mode, m_connector_type, m_connector_style, m_connector_shape_id,
|
||||
m_ar_plane_center, m_ar_rotations);
|
||||
|
||||
set_center_pos(m_ar_plane_center);
|
||||
m_rotation_gizmo.set_center(m_ar_plane_center);
|
||||
m_rotation_gizmo.set_rotation(m_ar_rotations);
|
||||
force_update_clipper_on_render = true;
|
||||
|
||||
m_parent.request_extra_frame();
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::on_save(cereal::BinaryOutputArchive& ar) const
|
||||
{
|
||||
ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, //m_selected,
|
||||
m_connector_depth_ratio, m_connector_size, m_connector_mode, m_connector_type, m_connector_style, m_connector_shape_id,
|
||||
m_ar_plane_center, m_ar_rotations);
|
||||
}
|
||||
|
||||
std::string GLGizmoCut3D::on_get_name() const
|
||||
{
|
||||
return _u8L("Cut");
|
||||
@ -602,13 +626,22 @@ std::string GLGizmoCut3D::on_get_name() const
|
||||
|
||||
void GLGizmoCut3D::on_set_state()
|
||||
{
|
||||
if (get_state() == On)
|
||||
if (m_state == On) {
|
||||
update_bb();
|
||||
|
||||
// initiate archived values
|
||||
m_ar_plane_center = m_plane_center;
|
||||
m_ar_rotations = m_rotation_gizmo.get_rotation();
|
||||
|
||||
m_parent.request_extra_frame();
|
||||
}
|
||||
else
|
||||
m_c->object_clipper()->release();
|
||||
|
||||
m_rotation_gizmo.set_center(m_plane_center);
|
||||
m_rotation_gizmo.set_state(m_state);
|
||||
|
||||
suppress_update_clipper_on_render = m_state != On;
|
||||
force_update_clipper_on_render = m_state == On;
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::on_set_hover_id()
|
||||
@ -674,6 +707,24 @@ void GLGizmoCut3D::on_dragging(const UpdateData& data)
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::on_start_dragging()
|
||||
{
|
||||
if (m_hover_id > m_group_id && m_connector_mode == CutConnectorMode::Manual)
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Move connector"), UndoRedo::SnapshotType::GizmoAction);
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::on_stop_dragging()
|
||||
{
|
||||
if (m_hover_id < m_group_id) {
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Rotate cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||
m_ar_rotations = m_rotation_gizmo.get_rotation();
|
||||
}
|
||||
else if (m_hover_id == m_group_id) {
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Move cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||
m_ar_plane_center = m_plane_center;
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos)
|
||||
{
|
||||
m_plane_center = center_pos;
|
||||
@ -778,6 +829,9 @@ void GLGizmoCut3D::on_render()
|
||||
if (!m_sphere.is_initialized())
|
||||
m_sphere.init_from(its_make_sphere(1.0, double(PI) / 12.0));
|
||||
|
||||
if (force_update_clipper_on_render)
|
||||
update_clipper_on_render();
|
||||
|
||||
render_connectors(false);
|
||||
|
||||
m_c->object_clipper()->render_cut();
|
||||
@ -790,9 +844,6 @@ void GLGizmoCut3D::on_render()
|
||||
m_rotation_gizmo.render();
|
||||
}
|
||||
}
|
||||
|
||||
if (!suppress_update_clipper_on_render)
|
||||
update_clipper_on_render();
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::on_render_for_picking()
|
||||
@ -963,7 +1014,7 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit)
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
m_imgui->disabled_begin((!m_keep_upper && !m_keep_lower) || !can_perform_cut());
|
||||
m_imgui->disabled_begin(!can_perform_cut());
|
||||
const bool cut_clicked = m_imgui->button(_L("Perform cut"));
|
||||
m_imgui->disabled_end();
|
||||
|
||||
@ -1024,13 +1075,16 @@ void GLGizmoCut3D::render_connectors(bool picking)
|
||||
{
|
||||
m_has_invalid_connector = false;
|
||||
|
||||
if (m_connector_mode == CutConnectorMode::Auto)
|
||||
if (m_connector_mode == CutConnectorMode::Auto || !m_c->selection_info())
|
||||
return;
|
||||
|
||||
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||
const CutConnectors& connectors = mo->cut_connectors;
|
||||
if (connectors.size() != m_selected.size())
|
||||
return;
|
||||
if (connectors.size() != m_selected.size()) {
|
||||
// #ysFIXME
|
||||
m_selected.clear();
|
||||
m_selected.resize(connectors.size(), false);
|
||||
}
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat") : wxGetApp().get_shader("gouraud_light");
|
||||
@ -1145,7 +1199,7 @@ void GLGizmoCut3D::render_connectors(bool picking)
|
||||
|
||||
bool GLGizmoCut3D::can_perform_cut() const
|
||||
{
|
||||
if (m_has_invalid_connector)
|
||||
if (m_has_invalid_connector || (!m_keep_upper && !m_keep_lower))
|
||||
return false;
|
||||
|
||||
BoundingBoxf3 box = bounding_box();
|
||||
@ -1172,9 +1226,16 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
Vec3d cut_center_offset = m_plane_center - instance_offset;
|
||||
cut_center_offset[Z] -= first_glvolume->get_sla_shift_z();
|
||||
|
||||
Plater* plater = wxGetApp().plater();
|
||||
|
||||
bool create_dowels_as_separate_object = false;
|
||||
if (0.0 < object_cut_z && can_perform_cut()) {
|
||||
ModelObject* mo = wxGetApp().plater()->model().objects[object_idx];
|
||||
ModelObject* mo = plater->model().objects[object_idx];
|
||||
if(!mo)
|
||||
return;
|
||||
|
||||
Plater::TakeSnapshot snapshot(plater, _L("Cut by Plane"));
|
||||
|
||||
const bool has_connectors = !mo->cut_connectors.empty();
|
||||
// update connectors pos as offset of its center before cut performing
|
||||
if (has_connectors && m_connector_mode == CutConnectorMode::Manual) {
|
||||
@ -1198,7 +1259,7 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
create_dowels_as_separate_object = true;
|
||||
}
|
||||
|
||||
wxGetApp().plater()->cut(object_idx, instance_idx, cut_center_offset, m_rotation_gizmo.get_rotation(),
|
||||
plater->cut(object_idx, instance_idx, cut_center_offset, m_rotation_gizmo.get_rotation(),
|
||||
only_if(has_connectors ? true : m_keep_upper, ModelObjectCutAttribute::KeepUpper) |
|
||||
only_if(has_connectors ? true : m_keep_lower, ModelObjectCutAttribute::KeepLower) |
|
||||
only_if(m_rotate_upper, ModelObjectCutAttribute::FlipUpper) |
|
||||
@ -1306,7 +1367,7 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi
|
||||
const Vec3d& normal = pos_and_normal.second;
|
||||
// The clipping plane was clicked, hit containts coordinates of the hit in world coords.
|
||||
std::cout << hit.x() << "\t" << hit.y() << "\t" << hit.z() << std::endl;
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Add connector"));
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Add connector"), UndoRedo::SnapshotType::GizmoAction);
|
||||
|
||||
connectors.emplace_back(hit, m_rotation_gizmo.get_rotation(), float(m_connector_size * 0.5), float(m_connector_depth_ratio));
|
||||
update_model_object();
|
||||
@ -1326,7 +1387,7 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi
|
||||
if (m_hover_id < m_connectors_group_id)
|
||||
return false;
|
||||
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Delete connector"));
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Delete connector"), UndoRedo::SnapshotType::GizmoAction);
|
||||
|
||||
size_t connector_id = m_hover_id - m_connectors_group_id;
|
||||
connectors.erase(connectors.begin() + connector_id);
|
||||
|
@ -24,6 +24,10 @@ class GLGizmoCut3D : public GLGizmoBase
|
||||
double m_snap_step{ 1.0 };
|
||||
int m_connectors_group_id;
|
||||
|
||||
// archived values
|
||||
Vec3d m_ar_plane_center { Vec3d::Zero() };
|
||||
Vec3d m_ar_rotations { Vec3d::Zero() };
|
||||
|
||||
Vec3d m_plane_center{ Vec3d::Zero() };
|
||||
// data to check position of the cut palne center on gizmo activation
|
||||
Vec3d m_min_pos{ Vec3d::Zero() };
|
||||
@ -38,7 +42,7 @@ class GLGizmoCut3D : public GLGizmoBase
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
GLModel m_plane;
|
||||
GLModel m_grabber_connection;
|
||||
// GLModel m_grabber_connection;
|
||||
GLModel m_cone;
|
||||
GLModel m_sphere;
|
||||
Vec3d m_old_center;
|
||||
@ -57,7 +61,7 @@ class GLGizmoCut3D : public GLGizmoBase
|
||||
float m_label_width{ 150.0 };
|
||||
float m_control_width{ 200.0 };
|
||||
bool m_imperial_units{ false };
|
||||
bool suppress_update_clipper_on_render{false};
|
||||
bool force_update_clipper_on_render{false};
|
||||
|
||||
mutable std::vector<bool> m_selected; // which pins are currently selected
|
||||
bool m_selection_empty = true;
|
||||
@ -123,18 +127,24 @@ public:
|
||||
|
||||
protected:
|
||||
bool on_init() override;
|
||||
void on_load(cereal::BinaryInputArchive& ar) override { ar(m_keep_upper, m_keep_lower, m_rotate_lower); }
|
||||
void on_save(cereal::BinaryOutputArchive& ar) const override { ar(m_keep_upper, m_keep_lower, m_rotate_lower); }
|
||||
void on_load(cereal::BinaryInputArchive& ar) override;
|
||||
void on_save(cereal::BinaryOutputArchive& ar) const override;
|
||||
std::string on_get_name() const override;
|
||||
void on_set_state() override;
|
||||
CommonGizmosDataID on_get_requirements() const override;
|
||||
void on_set_hover_id() override;
|
||||
bool on_is_activable() const override;
|
||||
void on_dragging(const UpdateData& data) override;
|
||||
void on_start_dragging() override;
|
||||
void on_stop_dragging() override;
|
||||
void on_render() override;
|
||||
void on_render_for_picking() override;
|
||||
void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||
|
||||
bool wants_enter_leave_snapshots() const override { return true; }
|
||||
std::string get_gizmo_entering_text() const override { return _u8L("Entering Cut gizmo"); }
|
||||
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Cut gizmo"); }
|
||||
std::string get_action_snapshot_name() override { return _u8L("Cut gizmo editing"); }
|
||||
|
||||
private:
|
||||
void set_center(const Vec3d& center);
|
||||
|
@ -836,7 +836,8 @@ void GLGizmoRotate3D::on_start_dragging()
|
||||
void GLGizmoRotate3D::on_stop_dragging()
|
||||
{
|
||||
assert(0 <= m_hover_id && m_hover_id < 3);
|
||||
m_parent.do_rotate(L("Gizmo-Rotate"));
|
||||
if (!m_use_only_grabbers)
|
||||
m_parent.do_rotate(L("Gizmo-Rotate"));
|
||||
m_gizmos[m_hover_id].stop_dragging();
|
||||
}
|
||||
|
||||
|
@ -5915,10 +5915,7 @@ void Slic3r::GUI::Plater::cut(size_t obj_idx, size_t instance_idx, const Vec3d&
|
||||
|
||||
wxCHECK_RET(instance_idx < object->instances.size(), "instance_idx out of bounds");
|
||||
|
||||
if (!attributes.has(ModelObjectCutAttribute::KeepUpper) && !attributes.has(ModelObjectCutAttribute::KeepLower))
|
||||
return;
|
||||
|
||||
Plater::TakeSnapshot snapshot(this, _L("Cut by Plane"));
|
||||
//Plater::TakeSnapshot snapshot(this, _L("Cut by Plane"));
|
||||
wxBusyCursor wait;
|
||||
|
||||
const auto new_objects = object->cut(instance_idx, cut_center, cut_rotation, attributes);
|
||||
|
Loading…
Reference in New Issue
Block a user