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
///