From 6c106212cb356a20fcba38302e397782843cdb04 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Thu, 14 Sep 2023 18:03:44 +0200 Subject: [PATCH] Fix distance from surface and generalize rotation fix --- src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp | 85 ++++++++-------------------- src/slic3r/GUI/SurfaceDrag.cpp | 48 ++++++++++++++-- src/slic3r/GUI/SurfaceDrag.hpp | 12 ++++ 3 files changed, 80 insertions(+), 65 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp index eed0236d8b..252bf96dac 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp @@ -232,17 +232,6 @@ TransformationType get_transformation_type(const Selection &selection) TransformationType::Local_Relative_Joint : TransformationType::Instance_Relative_Joint; // object } - -/// -/// Wrap function around selection transformation to apply fix transformation -/// Fix transformation is needed because of (store/load) volume (to/from) 3mf -/// -/// Selection to be modified -/// Function modified Selection transformation -/// Volume which may(or may not) contain fix matrix -template -void selection_transform(Selection &selection, Fnc selection_transformation_fnc, const ModelVolume &volume); - } // namespace bool GLGizmoSVG::on_mouse_for_rotation(const wxMouseEvent &mouse_event) @@ -260,17 +249,35 @@ bool GLGizmoSVG::on_mouse_for_rotation(const wxMouseEvent &mouse_event) // temporary rotation Selection &selection = m_parent.get_selection(); - //auto selection_rotate_fnc = [&angle, &selection](){ + auto selection_rotate_fnc = [&angle, &selection](){ selection.rotate(Vec3d(0., 0., angle), get_transformation_type(selection)); - //}; - //selection_transform(selection, selection_rotate_fnc, *m_volume); + }; + selection_transform(selection, selection_rotate_fnc, m_volume); angle += *m_rotate_start_angle; // move to range <-M_PI, M_PI> Geometry::to_range_pi_pi(angle); + + //{ // Slow alternative to valid rotation + // Selection &selection = m_parent.get_selection(); + // selection.setup_cache(); + // double diff_angle = angle - m_angle.value_or(0.f); + // auto selection_rotate_fnc = [&selection, &diff_angle]() { + // TransformationType transformation_type = selection.is_single_volume() ? + // TransformationType::Local_Relative_Joint : + // TransformationType::Instance_Relative_Joint; + // selection.rotate(Vec3d(0., 0., diff_angle), transformation_type); + // }; + // selection_transform(selection, selection_rotate_fnc, m_volume); + + // std::string snapshot_name; // empty meand no store undo / redo + // m_parent.do_rotate(snapshot_name); + //} + // propagate angle into property m_angle = static_cast(angle); + // do not store zero if (is_approx(*m_angle, 0.f)) m_angle.reset(); @@ -1567,36 +1574,6 @@ void GLGizmoSVG::draw_depth() ImGui::SetTooltip("%s", _u8L("Size in emboss direction.").c_str()); } -namespace{ - -/// -/// Wrap function around selection transformation to apply fix transformation after load volume from 3mf -/// -/// -/// Volume which may contain fix matrix -template -void selection_transform(Selection &selection, Fnc selection_transformation_fnc, const ModelVolume& volume) -{ - if (!volume.emboss_shape.has_value()) - return selection_transformation_fnc(); - - const std::optional &fix_tr = volume.emboss_shape->fix_3mf_tr; - if (!fix_tr.has_value()) - return selection_transformation_fnc(); - - GLVolume* gl_volume = selection.get_volume(*selection.get_volume_idxs().begin()); - Transform3d volume_tr = gl_volume->get_volume_transformation().get_matrix(); - gl_volume->set_volume_transformation(volume_tr * fix_tr->inverse()); - selection.setup_cache(); - - selection_transformation_fnc(); - - volume_tr = gl_volume->get_volume_transformation().get_matrix(); - gl_volume->set_volume_transformation(volume_tr * (*fix_tr)); - selection.setup_cache(); -} -} - void GLGizmoSVG::draw_size() { ImGuiWrapper::text(m_gui_cfg->translations.size); @@ -1705,7 +1682,7 @@ void GLGizmoSVG::draw_size() TransformationType::Instance_Relative_Independent; selection.scale(rel_scale, type); }; - selection_transform(selection, seloection_scale_fnc, *m_volume); + selection_transform(selection, seloection_scale_fnc, m_volume); m_parent.do_scale(L("Resize")); wxGetApp().obj_manipul()->set_dirty(); @@ -1806,22 +1783,10 @@ void GLGizmoSVG::draw_rotation() double diff_angle = angle_rad - angle; - //do_local_z_rotate(m_parent, diff_angle); - Selection& selection = m_parent.get_selection(); - selection.setup_cache(); - auto selection_rotate_fnc = [&selection, &diff_angle]() { - TransformationType transformation_type = selection.is_single_volume() ? - TransformationType::Local_Relative_Joint : - TransformationType::Instance_Relative_Joint; - selection.rotate(Vec3d(0., 0., diff_angle), transformation_type); - }; - selection_transform(selection, selection_rotate_fnc, *m_volume); + do_local_z_rotate(m_parent, diff_angle); - std::string snapshot_name; // empty meand no store undo / redo - m_parent.do_rotate(snapshot_name); - // calc angle after rotation - m_angle = calculate_angle(selection); + m_angle = calculate_angle(m_parent.get_selection()); // recalculate for surface cut if (m_volume->emboss_shape->projection.use_surface) @@ -1884,7 +1849,7 @@ void GLGizmoSVG::draw_mirroring() TransformationType::Instance; selection.mirror(axis, type); }; - selection_transform(selection, selection_mirror_fnc, *m_volume); + selection_transform(selection, selection_mirror_fnc, m_volume); m_parent.do_mirror(L("Set Mirror")); wxGetApp().obj_manipul()->UpdateAndShow(true); diff --git a/src/slic3r/GUI/SurfaceDrag.cpp b/src/slic3r/GUI/SurfaceDrag.cpp index bda7877397..fb491e99ca 100644 --- a/src/slic3r/GUI/SurfaceDrag.cpp +++ b/src/slic3r/GUI/SurfaceDrag.cpp @@ -257,6 +257,36 @@ Transform3d world_matrix_fixed(const Selection &selection) return world_matrix_fixed(*gl_volume, selection.get_model()->objects); } +void selection_transform(Selection &selection, const std::function &selection_transformation_fnc, const ModelVolume *volume) +{ + GLVolume *gl_volume = selection.get_volume(*selection.get_volume_idxs().begin()); + if (gl_volume == nullptr) + return selection_transformation_fnc(); + + if (volume == nullptr) { + volume = get_model_volume(*gl_volume, selection.get_model()->objects); + if (volume == nullptr) + return selection_transformation_fnc(); + } + + if (!volume->emboss_shape.has_value()) + return selection_transformation_fnc(); + + const std::optional &fix_tr = volume->emboss_shape->fix_3mf_tr; + if (!fix_tr.has_value()) + return selection_transformation_fnc(); + + Transform3d volume_tr = gl_volume->get_volume_transformation().get_matrix(); + gl_volume->set_volume_transformation(volume_tr * fix_tr->inverse()); + selection.setup_cache(); + + selection_transformation_fnc(); + + volume_tr = gl_volume->get_volume_transformation().get_matrix(); + gl_volume->set_volume_transformation(volume_tr * (*fix_tr)); + selection.setup_cache(); +} + bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas) { const Vec3d &cam_dir = camera.get_dir_forward(); @@ -312,9 +342,14 @@ void do_local_z_rotate(GLCanvas3D &canvas, double relative_angle) if (!selection.is_single_full_object() && !selection.is_single_volume()) return; selection.setup_cache(); - TransformationType transformation_type = selection.is_single_volume() ? - TransformationType::Local_Relative_Joint : TransformationType::Instance_Relative_Joint; - selection.rotate(Vec3d(0., 0., relative_angle), transformation_type); + + auto selection_rotate_fnc = [&selection, &relative_angle](){ + TransformationType transformation_type = selection.is_single_volume() ? + TransformationType::Local_Relative_Joint : + TransformationType::Instance_Relative_Joint; + selection.rotate(Vec3d(0., 0., relative_angle), transformation_type); + }; + selection_transform(selection, selection_rotate_fnc); std::string snapshot_name; // empty meand no store undo / redo // NOTE: it use L instead of _L macro because prefix _ is appended @@ -330,8 +365,11 @@ void do_local_z_move(GLCanvas3D &canvas, double relative_move) { if (selection.is_empty()) return; selection.setup_cache(); - Vec3d translate = Vec3d::UnitZ() * relative_move; - selection.translate(translate, TransformationType::Local); + auto selection_translate_fnc = [&selection, relative_move]() { + Vec3d translate = Vec3d::UnitZ() * relative_move; + selection.translate(translate, TransformationType::Local); + }; + selection_transform(selection, selection_translate_fnc); std::string snapshot_name; // empty mean no store undo / redo // NOTE: it use L instead of _L macro because prefix _ is appended inside diff --git a/src/slic3r/GUI/SurfaceDrag.hpp b/src/slic3r/GUI/SurfaceDrag.hpp index b23eaafbe0..d1b154a945 100644 --- a/src/slic3r/GUI/SurfaceDrag.hpp +++ b/src/slic3r/GUI/SurfaceDrag.hpp @@ -5,9 +5,11 @@ #include "libslic3r/Point.hpp" // Vec2d, Transform3d #include "slic3r/Utils/RaycastManager.hpp" #include "wx/event.h" // wxMouseEvent +#include namespace Slic3r { class GLVolume; +class ModelVolume; } // namespace Slic3r namespace Slic3r::GUI { @@ -106,6 +108,16 @@ Transform3d world_matrix_fixed(const GLVolume &gl_volume, const ModelObjectPtrs& /// Fixed Transformation of selected volume in selection Transform3d world_matrix_fixed(const Selection &selection); +/// +/// Wrap function around selection transformation to apply fix transformation +/// Fix transformation is needed because of (store/load) volume (to/from) 3mf +/// +/// Selected gl volume will be modified +/// Function modified Selection transformation +/// Same as selected GLVolume, volume may(or may not) contain fix matrix, +/// when nullptr it is gathered from selection +void selection_transform(Selection &selection, const std::function& selection_transformation_fnc, const ModelVolume *volume = nullptr); + /// /// Apply camera direction for emboss direction ///