mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 01:15:55 +08:00
Cut WIP: Fix for Undo/Redo
This commit is contained in:
parent
d6f46bedeb
commit
496481e972
@ -651,7 +651,7 @@ void GLGizmoCut3D::on_load(cereal::BinaryInputArchive& ar)
|
|||||||
m_connector_depth_ratio, m_connector_size, m_connector_mode, m_connector_type, m_connector_style, m_connector_shape_id,
|
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);
|
m_ar_plane_center, m_ar_rotations);
|
||||||
|
|
||||||
set_center_pos(m_ar_plane_center);
|
set_center_pos(m_ar_plane_center, true);
|
||||||
m_rotation_gizmo.set_center(m_ar_plane_center);
|
m_rotation_gizmo.set_center(m_ar_plane_center);
|
||||||
m_rotation_gizmo.set_rotation(m_ar_rotations);
|
m_rotation_gizmo.set_rotation(m_ar_rotations);
|
||||||
force_update_clipper_on_render = true;
|
force_update_clipper_on_render = true;
|
||||||
@ -771,21 +771,12 @@ void GLGizmoCut3D::on_stop_dragging()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos)
|
void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos, bool force/* = false*/)
|
||||||
{
|
{
|
||||||
const BoundingBoxf3 tbb = transformed_bounding_box(true);
|
if (force || transformed_bounding_box(true).contains(center_pos)) {
|
||||||
if (!tbb.contains(center_pos))
|
m_plane_center = center_pos;
|
||||||
return;
|
m_center_offset = m_plane_center - m_bb_center;
|
||||||
|
}
|
||||||
m_plane_center = center_pos;
|
|
||||||
|
|
||||||
// !!! ysFIXME add smart clamp calculation
|
|
||||||
// Clamp the center position of the cut plane to the object's bounding box
|
|
||||||
//m_plane_center = Vec3d(std::clamp(center_pos.x(), m_min_pos.x(), m_max_pos.x()),
|
|
||||||
// std::clamp(center_pos.y(), m_min_pos.y(), m_max_pos.y()),
|
|
||||||
// std::clamp(center_pos.z(), m_min_pos.z(), m_max_pos.z()));
|
|
||||||
|
|
||||||
m_center_offset = m_plane_center - m_bb_center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBoxf3 GLGizmoCut3D::bounding_box() const
|
BoundingBoxf3 GLGizmoCut3D::bounding_box() const
|
||||||
@ -806,18 +797,18 @@ BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(bool revert_move /*= false*
|
|||||||
{
|
{
|
||||||
// #ysFIXME !!!
|
// #ysFIXME !!!
|
||||||
BoundingBoxf3 ret;
|
BoundingBoxf3 ret;
|
||||||
const Selection& selection = m_parent.get_selection();
|
|
||||||
const Selection::IndicesList& idxs = selection.get_volume_idxs();
|
|
||||||
|
|
||||||
const int instance_idx = selection.get_instance_idx();
|
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||||
const int object_idx = selection.get_object_idx();
|
if (!mo)
|
||||||
if (instance_idx < 0 || object_idx < 0)
|
|
||||||
return ret;
|
return ret;
|
||||||
|
const int instance_idx = m_c->selection_info()->get_active_instance();
|
||||||
|
if (instance_idx < 0)
|
||||||
|
return ret;
|
||||||
|
const ModelInstance* mi = mo->instances[instance_idx];
|
||||||
|
|
||||||
const Vec3d& instance_offset = wxGetApp().plater()->model().objects[object_idx]->instances[instance_idx]->get_offset();
|
const Vec3d& instance_offset = mi->get_offset();
|
||||||
|
|
||||||
Vec3d cut_center_offset = m_plane_center - instance_offset;
|
Vec3d cut_center_offset = m_plane_center - instance_offset;
|
||||||
cut_center_offset[Z] -= selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
|
cut_center_offset[Z] -= m_c->selection_info()->get_sla_shift();
|
||||||
|
|
||||||
const Vec3d& rotation = m_rotation_gizmo.get_rotation();
|
const Vec3d& rotation = m_rotation_gizmo.get_rotation();
|
||||||
const auto move = Geometry::assemble_transform(-cut_center_offset);
|
const auto move = Geometry::assemble_transform(-cut_center_offset);
|
||||||
@ -828,6 +819,8 @@ BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(bool revert_move /*= false*
|
|||||||
|
|
||||||
const auto cut_matrix = (revert_move ? move2 : Transform3d::Identity()) * rot_x * rot_y * rot_z * move;
|
const auto cut_matrix = (revert_move ? move2 : Transform3d::Identity()) * rot_x * rot_y * rot_z * move;
|
||||||
|
|
||||||
|
const Selection& selection = m_parent.get_selection();
|
||||||
|
const Selection::IndicesList& idxs = selection.get_volume_idxs();
|
||||||
for (unsigned int i : idxs) {
|
for (unsigned int i : idxs) {
|
||||||
const GLVolume* volume = selection.get_volume(i);
|
const GLVolume* volume = selection.get_volume(i);
|
||||||
// respect just to the solid parts for FFF and ignore pad and supports for SLA
|
// respect just to the solid parts for FFF and ignore pad and supports for SLA
|
||||||
@ -853,7 +846,7 @@ bool GLGizmoCut3D::update_bb()
|
|||||||
m_max_pos = box.max;
|
m_max_pos = box.max;
|
||||||
m_min_pos = box.min;
|
m_min_pos = box.min;
|
||||||
m_bb_center = box.center();
|
m_bb_center = box.center();
|
||||||
set_center_pos(m_bb_center + m_center_offset);
|
set_center_pos(m_bb_center + m_center_offset, true);
|
||||||
|
|
||||||
m_plane.reset();
|
m_plane.reset();
|
||||||
m_cone.reset();
|
m_cone.reset();
|
||||||
@ -1270,9 +1263,9 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
|||||||
|
|
||||||
const bool has_connectors = !mo->cut_connectors.empty();
|
const bool has_connectors = !mo->cut_connectors.empty();
|
||||||
{
|
{
|
||||||
Plater::TakeSnapshot snapshot(plater, _L("Cut by Plane"));
|
|
||||||
// update connectors pos as offset of its center before cut performing
|
// update connectors pos as offset of its center before cut performing
|
||||||
if (has_connectors && m_connector_mode == CutConnectorMode::Manual) {
|
if (has_connectors && m_connector_mode == CutConnectorMode::Manual) {
|
||||||
|
Plater::TakeSnapshot snapshot(plater, _L("Cut by Plane"));
|
||||||
for (CutConnector& connector : mo->cut_connectors) {
|
for (CutConnector& connector : mo->cut_connectors) {
|
||||||
connector.rotation = m_rotation_gizmo.get_rotation();
|
connector.rotation = m_rotation_gizmo.get_rotation();
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ private:
|
|||||||
void render_cut_center_graber();
|
void render_cut_center_graber();
|
||||||
void render_cut_line();
|
void render_cut_line();
|
||||||
void perform_cut(const Selection& selection);
|
void perform_cut(const Selection& selection);
|
||||||
void set_center_pos(const Vec3d& center_pos);
|
void set_center_pos(const Vec3d& center_pos, bool force = false);
|
||||||
bool update_bb();
|
bool update_bb();
|
||||||
void reset_connectors();
|
void reset_connectors();
|
||||||
void update_connector_shape();
|
void update_connector_shape();
|
||||||
|
@ -414,8 +414,11 @@ void ObjectClipper::render_cut() const
|
|||||||
if (m_clp_ratio == 0.)
|
if (m_clp_ratio == 0.)
|
||||||
return;
|
return;
|
||||||
const SelectionInfo* sel_info = get_pool()->selection_info();
|
const SelectionInfo* sel_info = get_pool()->selection_info();
|
||||||
|
int sel_instance_idx = sel_info->get_active_instance();
|
||||||
|
if (sel_instance_idx < 0)
|
||||||
|
return;
|
||||||
const ModelObject* mo = sel_info->model_object();
|
const ModelObject* mo = sel_info->model_object();
|
||||||
const Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
|
const Geometry::Transformation inst_trafo = mo->instances[sel_instance_idx]->get_transformation();
|
||||||
|
|
||||||
size_t clipper_id = 0;
|
size_t clipper_id = 0;
|
||||||
for (const ModelVolume* mv : mo->volumes) {
|
for (const ModelVolume* mv : mo->volumes) {
|
||||||
|
@ -1780,7 +1780,7 @@ struct Plater::priv
|
|||||||
std::string get_config(const std::string &key) const;
|
std::string get_config(const std::string &key) const;
|
||||||
|
|
||||||
std::vector<size_t> load_files(const std::vector<fs::path>& input_files, bool load_model, bool load_config, bool used_inches = false);
|
std::vector<size_t> load_files(const std::vector<fs::path>& input_files, bool load_model, bool load_config, bool used_inches = false);
|
||||||
std::vector<size_t> load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z = false);
|
std::vector<size_t> load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z = false, bool call_selection_changed = true);
|
||||||
|
|
||||||
fs::path get_export_file_path(GUI::FileType file_type);
|
fs::path get_export_file_path(GUI::FileType file_type);
|
||||||
wxString get_export_file(GUI::FileType file_type);
|
wxString get_export_file(GUI::FileType file_type);
|
||||||
@ -2691,7 +2691,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||||||
|
|
||||||
// #define AUTOPLACEMENT_ON_LOAD
|
// #define AUTOPLACEMENT_ON_LOAD
|
||||||
|
|
||||||
std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z)
|
std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z, bool call_selection_changed /*= true*/)
|
||||||
{
|
{
|
||||||
const Vec3d bed_size = Slic3r::to_3d(this->bed.build_volume().bounding_volume2d().size(), 1.0) - 2.0 * Vec3d::Ones();
|
const Vec3d bed_size = Slic3r::to_3d(this->bed.build_volume().bounding_volume2d().size(), 1.0) - 2.0 * Vec3d::Ones();
|
||||||
|
|
||||||
@ -2774,17 +2774,18 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
|
|||||||
|
|
||||||
notification_manager->close_notification_of_type(NotificationType::UpdatedItemsInfo);
|
notification_manager->close_notification_of_type(NotificationType::UpdatedItemsInfo);
|
||||||
for (const size_t idx : obj_idxs) {
|
for (const size_t idx : obj_idxs) {
|
||||||
wxGetApp().obj_list()->add_object_to_list(idx);
|
wxGetApp().obj_list()->add_object_to_list(idx, call_selection_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
if (call_selection_changed) {
|
||||||
// Update InfoItems in ObjectList after update() to use of a correct value of the GLCanvas3D::is_sinking(),
|
update();
|
||||||
// which is updated after a view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH) call
|
// Update InfoItems in ObjectList after update() to use of a correct value of the GLCanvas3D::is_sinking(),
|
||||||
for (const size_t idx : obj_idxs)
|
// which is updated after a view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH) call
|
||||||
wxGetApp().obj_list()->update_info_items(idx);
|
for (const size_t idx : obj_idxs)
|
||||||
|
wxGetApp().obj_list()->update_info_items(idx);
|
||||||
object_list_changed();
|
|
||||||
|
|
||||||
|
object_list_changed();
|
||||||
|
}
|
||||||
this->schedule_background_process();
|
this->schedule_background_process();
|
||||||
|
|
||||||
return obj_idxs;
|
return obj_idxs;
|
||||||
@ -5919,18 +5920,29 @@ 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");
|
wxCHECK_RET(instance_idx < object->instances.size(), "instance_idx out of bounds");
|
||||||
|
|
||||||
//Plater::TakeSnapshot snapshot(this, _L("Cut by Plane"));
|
this->suppress_snapshots();
|
||||||
wxBusyCursor wait;
|
wxBusyCursor wait;
|
||||||
|
|
||||||
const auto new_objects = object->cut(instance_idx, cut_center, cut_rotation, attributes);
|
const auto new_objects = object->cut(instance_idx, cut_center, cut_rotation, attributes);
|
||||||
|
|
||||||
remove(obj_idx);
|
model().delete_object(obj_idx);
|
||||||
p->load_model_objects(new_objects);
|
sidebar().obj_list()->delete_object_from_list(obj_idx);
|
||||||
|
|
||||||
|
// suppress to call selection update for Object List to avoid call of early Gizmos on/off update
|
||||||
|
p->load_model_objects(new_objects, false, false);
|
||||||
|
|
||||||
Selection& selection = p->get_selection();
|
Selection& selection = p->get_selection();
|
||||||
size_t last_id = p->model.objects.size() - 1;
|
size_t last_id = p->model.objects.size() - 1;
|
||||||
for (size_t i = 0; i < new_objects.size(); ++i)
|
for (size_t i = 0; i < new_objects.size(); ++i)
|
||||||
selection.add_object((unsigned int)(last_id - i), i == 0);
|
selection.add_object((unsigned int)(last_id - i), i == 0);
|
||||||
|
this->allow_snapshots();
|
||||||
|
|
||||||
|
// now process all updates of the 3d scene
|
||||||
|
update();
|
||||||
|
// Update InfoItems in ObjectList after update() to use of a correct value of the GLCanvas3D::is_sinking(),
|
||||||
|
// which is updated after a view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH) call
|
||||||
|
for (size_t idx = 0; idx < p->model.objects.size(); idx++)
|
||||||
|
wxGetApp().obj_list()->update_info_items(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::export_gcode(bool prefer_removable)
|
void Plater::export_gcode(bool prefer_removable)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user