From f7923ec83eff563fd3d51ca7b0f72003cb6852b4 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Thu, 14 Sep 2023 15:06:00 +0200 Subject: [PATCH] Fix rotation by slider in emboss dialog --- src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp | 87 +++++++++++++++++++++------- src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp | 2 +- 2 files changed, 67 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp index e9b3f4e8c9..eed0236d8b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp @@ -40,7 +40,6 @@ using namespace Slic3r::GUI::Emboss; GLGizmoSVG::GLGizmoSVG(GLCanvas3D &parent) : GLGizmoBase(parent, M_ICON_FILENAME, -3) - , m_gui_cfg(nullptr) , m_rotate_gizmo(parent, GLGizmoRotate::Axis::Z) // grab id = 2 (Z axis) { m_rotate_gizmo.set_group_id(0); @@ -233,6 +232,17 @@ 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) @@ -250,7 +260,10 @@ bool GLGizmoSVG::on_mouse_for_rotation(const wxMouseEvent &mouse_event) // temporary rotation Selection &selection = m_parent.get_selection(); - selection.rotate(Vec3d(0., 0., angle), get_transformation_type(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); angle += *m_rotate_start_angle; // move to range <-M_PI, M_PI> @@ -265,6 +278,29 @@ bool GLGizmoSVG::on_mouse_for_rotation(const wxMouseEvent &mouse_event) return used; } +namespace{ +std::optional calculate_angle(const Selection& selection) +{ + const GLVolume *gl_volume = selection.get_first_volume(); + assert(gl_volume != nullptr); + if (gl_volume == nullptr) + return {}; + + Transform3d to_world = gl_volume->world_matrix(); + const ModelVolume* volume = get_model_volume(*gl_volume, selection.get_model()->objects); + assert(volume != nullptr); + assert(volume->emboss_shape.has_value()); + if (volume == nullptr || + !volume->emboss_shape.has_value() || + !volume->emboss_shape->fix_3mf_tr) + return calc_up(to_world, Slic3r::GUI::up_limit); + + // exist fix matrix and must be applied before calculation + to_world = to_world * volume->emboss_shape->fix_3mf_tr->inverse(); + return calc_up(to_world, Slic3r::GUI::up_limit); +} +} + bool GLGizmoSVG::on_mouse_for_translate(const wxMouseEvent &mouse_event) { // exist selected volume? @@ -308,11 +344,8 @@ bool GLGizmoSVG::on_mouse_for_translate(const wxMouseEvent &mouse_event) calculate_scale(); // Recalculate angle for GUI - if (!m_keep_up) { - const GLVolume *gl_volume = get_selected_gl_volume(m_parent.get_selection()); - assert(gl_volume != nullptr); - m_angle = calc_up(gl_volume->world_matrix(), Slic3r::GUI::up_limit); - } + if (!m_keep_up) + m_angle = calculate_angle(m_parent.get_selection()); } return res; } @@ -1082,7 +1115,7 @@ void GLGizmoSVG::set_volume_by_selection() m_shape_warnings = create_shape_warnings(*es.svg_file.image, get_scale_for_tolerance()); // Calculate current angle of up vector - m_angle = calc_up(gl_volume->world_matrix(), Slic3r::GUI::up_limit); + m_angle = calculate_angle(selection); m_distance = calc_distance(*gl_volume, m_raycast_manager, m_parent); m_shape_bb = get_extents(m_volume_shape.shapes_with_ids); @@ -1665,13 +1698,13 @@ void GLGizmoSVG::draw_size() if (new_relative_scale.has_value()){ Selection &selection = m_parent.get_selection(); selection.setup_cache(); - TransformationType type = m_volume->is_the_only_one_part() ? - TransformationType::Instance_Relative_Independent : - TransformationType::Local_Relative_Independent; - auto seloection_scale_fnc = [&selection, rel_scale = *new_relative_scale, type]() - { selection.scale(rel_scale, type); }; - + auto seloection_scale_fnc = [&selection, rel_scale = *new_relative_scale]() { + TransformationType type = selection.is_single_volume() ? + TransformationType::Local_Relative_Independent: + TransformationType::Instance_Relative_Independent; + selection.scale(rel_scale, type); + }; selection_transform(selection, seloection_scale_fnc, *m_volume); m_parent.do_scale(L("Resize")); @@ -1772,11 +1805,23 @@ void GLGizmoSVG::draw_rotation() Geometry::to_range_pi_pi(angle_rad); double diff_angle = angle_rad - angle; - do_local_z_rotate(m_parent, diff_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); + + std::string snapshot_name; // empty meand no store undo / redo + m_parent.do_rotate(snapshot_name); // calc angle after rotation - const GLVolume *gl_volume = get_selected_gl_volume(m_parent.get_selection()); - m_angle = calc_up(gl_volume->world_matrix(), Slic3r::GUI::up_limit); + m_angle = calculate_angle(selection); // recalculate for surface cut if (m_volume->emboss_shape->projection.use_surface) @@ -1833,10 +1878,10 @@ void GLGizmoSVG::draw_mirroring() Selection &selection = m_parent.get_selection(); selection.setup_cache(); - auto selection_mirror_fnc = [&selection, &axis, &volume = *m_volume]() - { - TransformationType type = volume.is_the_only_one_part()? - TransformationType::Instance : TransformationType::Local; + auto selection_mirror_fnc = [&selection, &axis, &volume = *m_volume](){ + TransformationType type = selection.is_single_volume()? + TransformationType::Local: + TransformationType::Instance; selection.mirror(axis, type); }; selection_transform(selection, selection_mirror_fnc, *m_volume); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp index 95e44f6230..eab7353948 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp @@ -132,7 +132,7 @@ private: bool on_mouse_for_translate(const wxMouseEvent &mouse_event); struct GuiCfg; - std::unique_ptr m_gui_cfg; + std::unique_ptr m_gui_cfg = nullptr; // actual selected only one volume - with emboss data ModelVolume *m_volume = nullptr;