mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 06:22:03 +08:00
Cut bug fixing: SPE-1511 and SPE-1525
* Fixed Cut by line * Added missed snapshots for Undo/Redo * Fix for set new position do the cut plane * Fixed update_clipper()
This commit is contained in:
parent
575422c7b7
commit
923f7cf8d7
@ -365,7 +365,9 @@ void GLGizmoCut3D::shift_cut(double delta)
|
|||||||
Vec3d starting_vec = m_rotation_m * Vec3d::UnitZ();
|
Vec3d starting_vec = m_rotation_m * Vec3d::UnitZ();
|
||||||
if (starting_vec.norm() != 0.0)
|
if (starting_vec.norm() != 0.0)
|
||||||
starting_vec.normalize();
|
starting_vec.normalize();
|
||||||
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Move cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||||
set_center(m_plane_center + starting_vec * delta, true);
|
set_center(m_plane_center + starting_vec * delta, true);
|
||||||
|
m_ar_plane_center = m_plane_center;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::rotate_vec3d_around_plane_center(Vec3d&vec)
|
void GLGizmoCut3D::rotate_vec3d_around_plane_center(Vec3d&vec)
|
||||||
@ -402,12 +404,10 @@ bool GLGizmoCut3D::is_looking_forward() const
|
|||||||
|
|
||||||
void GLGizmoCut3D::update_clipper()
|
void GLGizmoCut3D::update_clipper()
|
||||||
{
|
{
|
||||||
BoundingBoxf3 box = m_bounding_box;
|
|
||||||
|
|
||||||
// update cut_normal
|
// update cut_normal
|
||||||
Vec3d beg, end = beg = m_plane_center;
|
Vec3d beg, end = beg = m_bb_center;
|
||||||
beg[Z] = box.center().z() - m_radius;
|
beg[Z] -= m_radius;
|
||||||
end[Z] = box.center().z() + m_radius;
|
end[Z] += m_radius;
|
||||||
|
|
||||||
rotate_vec3d_around_plane_center(beg);
|
rotate_vec3d_around_plane_center(beg);
|
||||||
rotate_vec3d_around_plane_center(end);
|
rotate_vec3d_around_plane_center(end);
|
||||||
@ -416,19 +416,18 @@ void GLGizmoCut3D::update_clipper()
|
|||||||
Vec3d normal = m_cut_normal = end - beg;
|
Vec3d normal = m_cut_normal = end - beg;
|
||||||
|
|
||||||
// calculate normal and offset for clipping plane
|
// calculate normal and offset for clipping plane
|
||||||
double dist = (m_plane_center - beg).norm();
|
|
||||||
dist = std::clamp(dist, 0.0001, normal.norm());
|
|
||||||
normal.normalize();
|
normal.normalize();
|
||||||
m_clp_normal = normal;
|
m_clp_normal = normal;
|
||||||
double offset = normal.dot(beg) + dist;
|
double offset = normal.dot(m_plane_center);
|
||||||
|
double dist = normal.dot(beg);
|
||||||
|
|
||||||
m_parent.set_color_clip_plane(normal, offset);
|
m_parent.set_color_clip_plane(normal, offset);
|
||||||
|
|
||||||
if (!is_looking_forward()) {
|
if (!is_looking_forward()) {
|
||||||
// recalculate normal and offset for clipping plane, if camera is looking downward to cut plane
|
// recalculate normal and offset for clipping plane, if camera is looking downward to cut plane
|
||||||
end = beg = m_plane_center;
|
end = beg = m_bb_center;
|
||||||
beg[Z] = box.center().z() + m_radius;
|
beg[Z] += m_radius;
|
||||||
end[Z] = box.center().z() - m_radius;
|
end[Z] -= m_radius;
|
||||||
|
|
||||||
rotate_vec3d_around_plane_center(beg);
|
rotate_vec3d_around_plane_center(beg);
|
||||||
rotate_vec3d_around_plane_center(end);
|
rotate_vec3d_around_plane_center(end);
|
||||||
@ -436,12 +435,10 @@ void GLGizmoCut3D::update_clipper()
|
|||||||
normal = end - beg;
|
normal = end - beg;
|
||||||
if (normal == Vec3d::Zero())
|
if (normal == Vec3d::Zero())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dist = (m_plane_center - beg).norm();
|
|
||||||
dist = std::clamp(dist, 0.0001, normal.norm());
|
|
||||||
normal.normalize();
|
normal.normalize();
|
||||||
m_clp_normal = normal;
|
m_clp_normal = normal;
|
||||||
offset = normal.dot(beg) + dist;
|
offset = normal.dot(m_plane_center);
|
||||||
|
dist = normal.dot(beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_c->object_clipper()->set_range_and_pos(normal, offset, dist);
|
m_c->object_clipper()->set_range_and_pos(normal, offset, dist);
|
||||||
@ -579,7 +576,9 @@ void GLGizmoCut3D::render_move_center_input(int axis)
|
|||||||
|
|
||||||
if (in_val != val) {
|
if (in_val != val) {
|
||||||
move[axis] = val;
|
move[axis] = val;
|
||||||
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Move cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||||
set_center(move, true);
|
set_center(move, true);
|
||||||
|
m_ar_plane_center = m_plane_center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -886,7 +885,8 @@ 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_connectors_editing,
|
ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing,
|
||||||
m_ar_plane_center, m_rotation_m);
|
m_ar_plane_center, m_rotation_m);
|
||||||
|
|
||||||
set_center_pos(m_ar_plane_center, true);
|
m_transformed_bounding_box = transformed_bounding_box(m_ar_plane_center, m_rotation_m);
|
||||||
|
set_center_pos(m_ar_plane_center);
|
||||||
|
|
||||||
m_parent.request_extra_frame();
|
m_parent.request_extra_frame();
|
||||||
}
|
}
|
||||||
@ -910,11 +910,11 @@ void GLGizmoCut3D::on_set_state()
|
|||||||
|
|
||||||
update_bb();
|
update_bb();
|
||||||
m_connectors_editing = !m_selected.empty();
|
m_connectors_editing = !m_selected.empty();
|
||||||
|
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
||||||
|
|
||||||
// initiate archived values
|
// initiate archived values
|
||||||
m_ar_plane_center = m_plane_center;
|
m_ar_plane_center = m_plane_center;
|
||||||
m_start_dragging_m = m_rotation_m;
|
m_start_dragging_m = m_rotation_m;
|
||||||
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
|
||||||
|
|
||||||
m_parent.request_extra_frame();
|
m_parent.request_extra_frame();
|
||||||
}
|
}
|
||||||
@ -1179,7 +1179,7 @@ void GLGizmoCut3D::dragging_grabber_xy(const GLGizmoBase::UpdateData &data)
|
|||||||
const bool update_tbb = m_rotation_m.rotation() != rotation_tmp.rotation();
|
const bool update_tbb = m_rotation_m.rotation() != rotation_tmp.rotation();
|
||||||
m_rotation_m = rotation_tmp;
|
m_rotation_m = rotation_tmp;
|
||||||
if (update_tbb)
|
if (update_tbb)
|
||||||
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
m_transformed_bounding_box = transformed_bounding_box(m_plane_center, m_rotation_m);
|
||||||
|
|
||||||
m_angle = theta;
|
m_angle = theta;
|
||||||
while (m_angle > two_pi)
|
while (m_angle > two_pi)
|
||||||
@ -1246,11 +1246,9 @@ void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos, bool update_tbb /*=fa
|
|||||||
Vec3d normal = m_rotation_m.inverse() * Vec3d(m_plane_center - center_pos);
|
Vec3d normal = m_rotation_m.inverse() * Vec3d(m_plane_center - center_pos);
|
||||||
tbb.translate(normal.z() * Vec3d::UnitZ());
|
tbb.translate(normal.z() * Vec3d::UnitZ());
|
||||||
}
|
}
|
||||||
const Vec3d& instance_offset = m_parent.get_selection().get_first_volume()->get_instance_offset();
|
|
||||||
const Vec3d trans_center_pos = (m_rotation_m.inverse() * (center_pos - instance_offset)) + tbb.center();
|
|
||||||
|
|
||||||
bool can_set_center_pos = tbb.contains(trans_center_pos);
|
bool can_set_center_pos = false;
|
||||||
if (!can_set_center_pos) {
|
{
|
||||||
if (tbb.max.z() > -.5 && tbb.min.z() < .5)
|
if (tbb.max.z() > -.5 && tbb.min.z() < .5)
|
||||||
can_set_center_pos = true;
|
can_set_center_pos = true;
|
||||||
else {
|
else {
|
||||||
@ -1283,12 +1281,12 @@ BoundingBoxf3 GLGizmoCut3D::bounding_box() const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(const Vec3d& plane_center) const
|
BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(const Vec3d& plane_center, const Transform3d& rotation_m/* = Transform3d::Identity()*/) const
|
||||||
{
|
{
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
|
|
||||||
const Vec3d& instance_offset = selection.get_first_volume()->get_instance_offset();
|
const Vec3d& instance_offset = selection.get_first_volume()->get_instance_offset();
|
||||||
const auto cut_matrix = Transform3d::Identity() * m_rotation_m.inverse() * translation_transform(instance_offset - plane_center);
|
const auto cut_matrix = Transform3d::Identity() * rotation_m.inverse() * translation_transform(instance_offset - plane_center);
|
||||||
|
|
||||||
const Selection::IndicesList& idxs = selection.get_volume_idxs();
|
const Selection::IndicesList& idxs = selection.get_volume_idxs();
|
||||||
BoundingBoxf3 ret;
|
BoundingBoxf3 ret;
|
||||||
@ -1544,8 +1542,11 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
|
|||||||
|
|
||||||
m_imgui->disabled_begin(connectors.empty());
|
m_imgui->disabled_begin(connectors.empty());
|
||||||
ImGui::SameLine(m_label_width);
|
ImGui::SameLine(m_label_width);
|
||||||
if (render_reset_button("connectors", _u8L("Remove connectors")))
|
const wxString act_name = _L("Remove connectors");
|
||||||
|
if (render_reset_button("connectors", into_u8(act_name))) {
|
||||||
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), act_name, UndoRedo::SnapshotType::GizmoAction);
|
||||||
reset_connectors();
|
reset_connectors();
|
||||||
|
}
|
||||||
m_imgui->disabled_end();
|
m_imgui->disabled_end();
|
||||||
|
|
||||||
render_flip_plane_button(m_connectors_editing && connectors.empty());
|
render_flip_plane_button(m_connectors_editing && connectors.empty());
|
||||||
@ -1617,10 +1618,11 @@ void GLGizmoCut3D::render_build_size()
|
|||||||
|
|
||||||
void GLGizmoCut3D::reset_cut_plane()
|
void GLGizmoCut3D::reset_cut_plane()
|
||||||
{
|
{
|
||||||
m_rotation_m = Transform3d::Identity();
|
|
||||||
m_angle_arc.reset();
|
m_angle_arc.reset();
|
||||||
m_transformed_bounding_box = transformed_bounding_box(m_bb_center);
|
m_transformed_bounding_box = transformed_bounding_box(m_bb_center);
|
||||||
set_center(m_bb_center);
|
set_center(m_bb_center);
|
||||||
|
m_start_dragging_m = m_rotation_m = Transform3d::Identity();
|
||||||
|
m_ar_plane_center = m_plane_center;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::invalidate_cut_plane()
|
void GLGizmoCut3D::invalidate_cut_plane()
|
||||||
@ -1649,7 +1651,7 @@ void GLGizmoCut3D::set_connectors_editing(bool connectors_editing)
|
|||||||
void GLGizmoCut3D::flip_cut_plane()
|
void GLGizmoCut3D::flip_cut_plane()
|
||||||
{
|
{
|
||||||
m_rotation_m = m_rotation_m * rotation_transform(PI * Vec3d::UnitX());
|
m_rotation_m = m_rotation_m * rotation_transform(PI * Vec3d::UnitX());
|
||||||
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
m_transformed_bounding_box = transformed_bounding_box(m_plane_center, m_rotation_m);
|
||||||
|
|
||||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Flip cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Flip cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||||
m_start_dragging_m = m_rotation_m;
|
m_start_dragging_m = m_rotation_m;
|
||||||
@ -1724,8 +1726,11 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors)
|
|||||||
|
|
||||||
const bool is_cut_plane_init = m_rotation_m.isApprox(Transform3d::Identity()) && m_bb_center == m_plane_center;
|
const bool is_cut_plane_init = m_rotation_m.isApprox(Transform3d::Identity()) && m_bb_center == m_plane_center;
|
||||||
m_imgui->disabled_begin(is_cut_plane_init);
|
m_imgui->disabled_begin(is_cut_plane_init);
|
||||||
if (render_reset_button("cut_plane", _u8L("Reset cutting plane")))
|
wxString act_name = _L("Reset cutting plane");
|
||||||
|
if (render_reset_button("cut_plane", into_u8(act_name))) {
|
||||||
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), act_name, UndoRedo::SnapshotType::GizmoAction);
|
||||||
reset_cut_plane();
|
reset_cut_plane();
|
||||||
|
}
|
||||||
m_imgui->disabled_end();
|
m_imgui->disabled_end();
|
||||||
|
|
||||||
// render_flip_plane_button();
|
// render_flip_plane_button();
|
||||||
@ -1740,7 +1745,9 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors)
|
|||||||
ImGui::SameLine(2.5f * m_label_width);
|
ImGui::SameLine(2.5f * m_label_width);
|
||||||
|
|
||||||
m_imgui->disabled_begin(is_cut_plane_init && !has_connectors);
|
m_imgui->disabled_begin(is_cut_plane_init && !has_connectors);
|
||||||
if (m_imgui->button(_L("Reset cut"), _L("Reset cutting plane and remove connectors"))) {
|
act_name = _L("Reset cut");
|
||||||
|
if (m_imgui->button(act_name, _L("Reset cutting plane and remove connectors"))) {
|
||||||
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), act_name, UndoRedo::SnapshotType::GizmoAction);
|
||||||
reset_cut_plane();
|
reset_cut_plane();
|
||||||
reset_connectors();
|
reset_connectors();
|
||||||
}
|
}
|
||||||
@ -2299,20 +2306,26 @@ bool GLGizmoCut3D::process_cut_line(SLAGizmoEventType action, const Vec2d& mouse
|
|||||||
Vec3d line_dir = m_line_end - m_line_beg;
|
Vec3d line_dir = m_line_end - m_line_beg;
|
||||||
if (line_dir.norm() < 3.0)
|
if (line_dir.norm() < 3.0)
|
||||||
return true;
|
return true;
|
||||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Cut by line"), UndoRedo::SnapshotType::GizmoAction);
|
|
||||||
|
|
||||||
Vec3d cross_dir = line_dir.cross(dir).normalized();
|
Vec3d cross_dir = line_dir.cross(dir).normalized();
|
||||||
Eigen::Quaterniond q;
|
Eigen::Quaterniond q;
|
||||||
Transform3d m = Transform3d::Identity();
|
Transform3d m = Transform3d::Identity();
|
||||||
m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3d::UnitZ(), cross_dir).toRotationMatrix();
|
m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3d::UnitZ(), cross_dir).toRotationMatrix();
|
||||||
|
|
||||||
m_rotation_m = m;
|
const Vec3d new_plane_center = m_bb_center + cross_dir * cross_dir.dot(pt - m_bb_center);
|
||||||
// update transformed bb
|
// update transformed bb
|
||||||
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
const auto new_tbb = transformed_bounding_box(new_plane_center, m);
|
||||||
|
const Vec3d& instance_offset = m_parent.get_selection().get_first_volume()->get_instance_offset();
|
||||||
|
const Vec3d trans_center_pos = m.inverse() * (new_plane_center - instance_offset) + new_tbb.center();
|
||||||
|
if (new_tbb.contains(trans_center_pos)) {
|
||||||
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Cut by line"), UndoRedo::SnapshotType::GizmoAction);
|
||||||
|
m_transformed_bounding_box = new_tbb;
|
||||||
|
set_center(new_plane_center);
|
||||||
|
m_start_dragging_m = m_rotation_m = m;
|
||||||
|
m_ar_plane_center = m_plane_center;
|
||||||
|
}
|
||||||
|
|
||||||
m_angle_arc.reset();
|
m_angle_arc.reset();
|
||||||
|
|
||||||
set_center(m_plane_center + cross_dir * (cross_dir.dot(pt - m_plane_center)), true);
|
|
||||||
|
|
||||||
discard_cut_line_processing();
|
discard_cut_line_processing();
|
||||||
}
|
}
|
||||||
else if (action == SLAGizmoEventType::Moving)
|
else if (action == SLAGizmoEventType::Moving)
|
||||||
|
@ -35,6 +35,7 @@ class GLGizmoCut3D : public GLGizmoBase
|
|||||||
|
|
||||||
// archived values
|
// archived values
|
||||||
Vec3d m_ar_plane_center { Vec3d::Zero() };
|
Vec3d m_ar_plane_center { Vec3d::Zero() };
|
||||||
|
Transform3d m_start_dragging_m{ Transform3d::Identity() };
|
||||||
|
|
||||||
Vec3d m_plane_center{ Vec3d::Zero() };
|
Vec3d m_plane_center{ Vec3d::Zero() };
|
||||||
// data to check position of the cut palne center on gizmo activation
|
// data to check position of the cut palne center on gizmo activation
|
||||||
@ -57,7 +58,6 @@ class GLGizmoCut3D : public GLGizmoBase
|
|||||||
double m_snap_fine_out_radius{ 0.0 };
|
double m_snap_fine_out_radius{ 0.0 };
|
||||||
|
|
||||||
// dragging angel in hovered axes
|
// dragging angel in hovered axes
|
||||||
Transform3d m_start_dragging_m{ Transform3d::Identity() };
|
|
||||||
double m_angle{ 0.0 };
|
double m_angle{ 0.0 };
|
||||||
|
|
||||||
TriangleMesh m_connector_mesh;
|
TriangleMesh m_connector_mesh;
|
||||||
@ -194,7 +194,7 @@ public:
|
|||||||
void invalidate_cut_plane();
|
void invalidate_cut_plane();
|
||||||
|
|
||||||
BoundingBoxf3 bounding_box() const;
|
BoundingBoxf3 bounding_box() const;
|
||||||
BoundingBoxf3 transformed_bounding_box(const Vec3d& plane_center) const;
|
BoundingBoxf3 transformed_bounding_box(const Vec3d& plane_center, const Transform3d& rotation_m = Transform3d::Identity()) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool on_init() override;
|
bool on_init() override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user