diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index bb00782599..b92b931ded 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -424,7 +424,7 @@ bool GLGizmoEmboss::do_mirror(size_t axis) selection.setup_cache(); auto selection_mirror_fnc = [&selection, &axis]() { selection.mirror((Axis) axis, get_drag_transformation_type(selection)); }; - selection_transform(selection, selection_mirror_fnc, m_volume); + selection_transform(selection, selection_mirror_fnc); m_parent.do_mirror(L("Set Mirror")); wxGetApp().obj_manipul()->UpdateAndShow(true); @@ -500,34 +500,13 @@ bool GLGizmoEmboss::on_mouse_for_rotation(const wxMouseEvent &mouse_event) if (!m_dragging) return used; if (mouse_event.Dragging()) { - if (!m_rotate_start_angle.has_value()) { - // when m_rotate_start_angle is not set mean it is not Dragging - // when angle_opt is not set than angle is Zero - const std::optional &angle_opt = m_style_manager.get_style().angle; - m_rotate_start_angle = angle_opt.value_or(0.f); - } - - double angle = m_rotate_gizmo.get_angle(); - angle -= PI / 2; // Grabber is upward - - // temporary rotation - Selection& selection = m_parent.get_selection(); - selection.rotate(Vec3d(0., 0., angle), get_drag_transformation_type(selection)); - - angle += *m_rotate_start_angle; - // move to range <-M_PI, M_PI> - Geometry::to_range_pi_pi(angle); - - // set into activ style + // check that style is activ assert(m_style_manager.is_active_font()); - if (m_style_manager.is_active_font()) { - std::optional angle_opt; - if (!is_approx(angle, 0.)) - angle_opt = angle; - m_style_manager.get_style().angle = angle_opt; - } + if (!m_style_manager.is_active_font()) + return used; - volume_transformation_changing(); + std::optional &angle_opt = m_style_manager.get_style().angle; + dragging_rotate_gizmo(m_rotate_gizmo.get_angle(), angle_opt, m_rotate_start_angle, m_parent.get_selection()); } return used; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp index 48f191389c..437dd04d4d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp @@ -239,39 +239,9 @@ bool GLGizmoSVG::on_mouse_for_rotation(const wxMouseEvent &mouse_event) bool used = use_grabbers(mouse_event); if (!m_dragging) return used; - if (mouse_event.Dragging()) { - if (!m_rotate_start_angle.has_value()) - m_rotate_start_angle = m_angle.value_or(0.f); - double angle = m_rotate_gizmo.get_angle(); - angle -= PI / 2; // Grabber is upward - - double new_angle = angle + *m_rotate_start_angle; - - bool is_volume_mirrored = has_reflection(m_volume->get_matrix()); - bool is_instance_mirrored = has_reflection(m_parent.get_selection().get_first_volume()->get_instance_transformation().get_matrix()); - if (is_volume_mirrored != is_instance_mirrored) - new_angle = -angle + *m_rotate_start_angle; - - // move to range <-M_PI, M_PI> - Geometry::to_range_pi_pi(new_angle); - - double z_rotation = m_volume->emboss_shape->fix_3mf_tr.has_value()? - (new_angle - m_angle.value_or(0.f)) : // relative angle - angle; // relativity is keep by selection cache - - Selection &selection = m_parent.get_selection(); - auto selection_rotate_fnc = [z_rotation, &selection]() { - selection.rotate(Vec3d(0., 0., z_rotation), get_drag_transformation_type(selection)); - }; - selection_transform(selection, selection_rotate_fnc, m_volume); - - // propagate angle into property - m_angle = static_cast(new_angle); - - // do not store zero - if (is_approx(*m_angle, 0.f)) - m_angle.reset(); - } + if (mouse_event.Dragging()) + dragging_rotate_gizmo(m_rotate_gizmo.get_angle(), m_angle, m_rotate_start_angle, m_parent.get_selection()); + return used; } @@ -1790,7 +1760,7 @@ void GLGizmoSVG::draw_size() auto selection_scale_fnc = [&selection, rel_scale = *new_relative_scale]() { selection.scale(rel_scale, get_drag_transformation_type(selection)); }; - selection_transform(selection, selection_scale_fnc, m_volume); + selection_transform(selection, selection_scale_fnc); m_parent.do_scale(L("Resize")); wxGetApp().obj_manipul()->set_dirty(); @@ -1952,7 +1922,7 @@ void GLGizmoSVG::draw_mirroring() auto selection_mirror_fnc = [&selection, &axis](){ selection.mirror(axis, get_drag_transformation_type(selection)); }; - selection_transform(selection, selection_mirror_fnc, m_volume); + selection_transform(selection, selection_mirror_fnc); m_parent.do_mirror(L("Set Mirror")); // Mirror is ignoring keep up !! diff --git a/src/slic3r/GUI/SurfaceDrag.cpp b/src/slic3r/GUI/SurfaceDrag.cpp index a25569d61a..39573dbf96 100644 --- a/src/slic3r/GUI/SurfaceDrag.cpp +++ b/src/slic3r/GUI/SurfaceDrag.cpp @@ -61,6 +61,14 @@ Transform3d get_volume_transformation( // distinguish between transformation of volume inside object // and object(single full instance with one volume) bool is_embossed_object(const Selection &selection); + +/// +/// Get fix transformation for selected volume +/// Fix after store to 3mf +/// +/// Select only wanted volume +/// Pointer on fix transformation from ModelVolume when exists otherwise nullptr +const Transform3d *get_fix_transformation(const Selection &selection); } namespace Slic3r::GUI { @@ -278,27 +286,11 @@ 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()); - auto get_fix = [&selection, &volume, &gl_volume]() -> const Transform3d * { - if (gl_volume == nullptr) - return nullptr; - - if (volume == nullptr) { - volume = get_model_volume(*gl_volume, selection.get_model()->objects); - if (volume == nullptr) - return nullptr; - } - const std::optional &es = volume->emboss_shape; - if (!volume->emboss_shape.has_value()) - return nullptr; - if (!es->fix_3mf_tr.has_value()) - return nullptr; - return &(*es->fix_3mf_tr); - }; - - if (const Transform3d *fix = get_fix(); fix != nullptr) { +void selection_transform(Selection &selection, const std::function &selection_transformation_fnc) +{ + if (const Transform3d *fix = get_fix_transformation(selection); fix != nullptr) { + // NOTE: need editable gl volume .. can't use selection.get_first_volume() + 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->inverse()); selection.setup_cache(); @@ -460,6 +452,47 @@ TransformationType get_drag_transformation_type(const Selection &selection) TransformationType::Instance_Relative_Joint : TransformationType::Local_Relative_Joint; } + +void dragging_rotate_gizmo(double gizmo_angle, std::optional& current_angle, std::optional &start_angle, Selection &selection) +{ + if (!start_angle.has_value()) + // create cache for initial angle + start_angle = current_angle.value_or(0.f); + + gizmo_angle -= PI / 2; // Grabber is upward + + double new_angle = gizmo_angle + *start_angle; + + const GLVolume *gl_volume = selection.get_first_volume(); + assert(gl_volume != nullptr); + if (gl_volume == nullptr) + return; + + bool is_volume_mirrored = has_reflection(gl_volume->get_volume_transformation().get_matrix()); + bool is_instance_mirrored = has_reflection(gl_volume->get_instance_transformation().get_matrix()); + if (is_volume_mirrored != is_instance_mirrored) + new_angle = -gizmo_angle + *start_angle; + + // move to range <-M_PI, M_PI> + Geometry::to_range_pi_pi(new_angle); + + const Transform3d* fix = get_fix_transformation(selection); + double z_rotation = (fix!=nullptr) ? (new_angle - current_angle.value_or(0.f)) : // relative angle + gizmo_angle; // relativity is keep by selection cache + + auto selection_rotate_fnc = [z_rotation, &selection]() { + selection.rotate(Vec3d(0., 0., z_rotation), get_drag_transformation_type(selection)); + }; + selection_transform(selection, selection_rotate_fnc); + + // propagate angle into property + current_angle = static_cast(new_angle); + + // do not store zero + if (is_approx(*current_angle, 0.f)) + current_angle.reset(); +} + } // namespace Slic3r::GUI // private implementation @@ -677,4 +710,23 @@ bool is_embossed_object(const Selection &selection) return selection.is_single_full_object() || selection.is_single_full_instance(); } +const Transform3d *get_fix_transformation(const Selection &selection) { + const GLVolume *gl_volume = get_selected_gl_volume(selection); + assert(gl_volume != nullptr); + if (gl_volume == nullptr) + return nullptr; + + const ModelVolume *volume = get_model_volume(*gl_volume, selection.get_model()->objects); + assert(volume != nullptr); + if (volume == nullptr) + return nullptr; + + const std::optional &es = volume->emboss_shape; + if (!volume->emboss_shape.has_value()) + return nullptr; + if (!es->fix_3mf_tr.has_value()) + return nullptr; + return &(*es->fix_3mf_tr); +} + } // namespace diff --git a/src/slic3r/GUI/SurfaceDrag.hpp b/src/slic3r/GUI/SurfaceDrag.hpp index aaf506582d..9f1c0e3c07 100644 --- a/src/slic3r/GUI/SurfaceDrag.hpp +++ b/src/slic3r/GUI/SurfaceDrag.hpp @@ -122,9 +122,7 @@ Transform3d world_matrix_fixed(const Selection &selection); /// /// 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); +void selection_transform(Selection &selection, const std::function& selection_transformation_fnc); /// /// Apply camera direction for emboss direction @@ -150,11 +148,22 @@ void do_local_z_rotate(GLCanvas3D &canvas, double relative_angle); void do_local_z_move(GLCanvas3D &canvas, double relative_move); /// -/// +/// Distiguish between object and volume +/// Differ in possible transformation type /// -/// -/// +/// Contain selected volume/object +/// Transformation to use TransformationType get_drag_transformation_type(const Selection &selection); +/// +/// On dragging rotate gizmo func +/// Transform GLVolume from selection +/// +/// GLGizmoRotate::get_angle() +/// In/Out current angle visible in UI +/// Cache for start dragging angle +/// Selected only Actual embossed volume +void dragging_rotate_gizmo(double gizmo_angle, std::optional& current_angle, std::optional &start_angle, Selection &selection); + } // namespace Slic3r::GUI #endif // slic3r_SurfaceDrag_hpp_ \ No newline at end of file