From 9f503b95e8494d31e4c05fb0c8b48167650bdd8b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 4 May 2022 10:28:59 +0200 Subject: [PATCH] Tech ENABLE_TRANSFORMATIONS_BY_MATRICES - Reworked method void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type) to use matrix multiplication Fixed conflicts during rebase with master --- src/libslic3r/Geometry.cpp | 12 ++ src/libslic3r/Geometry.hpp | 21 ++- src/slic3r/GUI/GLCanvas3D.cpp | 33 +++-- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 12 +- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 63 ++++++--- src/slic3r/GUI/Selection.cpp | 163 ++++++++++++++++++------ src/slic3r/GUI/Selection.hpp | 29 +++-- 7 files changed, 256 insertions(+), 77 deletions(-) diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 44e68a9d8..031e489f7 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -314,6 +314,18 @@ Transform3d assemble_transform(const Vec3d& translation, const Vec3d& rotation, } #if ENABLE_TRANSFORMATIONS_BY_MATRICES +void assemble_transform(Transform3d& transform, const Transform3d& translation, const Transform3d& rotation, const Transform3d& scale, const Transform3d& mirror) +{ + transform = translation * rotation * scale * mirror; +} + +Transform3d assemble_transform(const Transform3d& translation, const Transform3d& rotation, const Transform3d& scale, const Transform3d& mirror) +{ + Transform3d transform; + assemble_transform(transform, translation, rotation, scale, mirror); + return transform; +} + void rotation_transform(Transform3d& transform, const Vec3d& rotation) { transform = Transform3d::Identity(); diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index d0548f765..c55867023 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -323,7 +323,8 @@ bool arrange( // 4) rotate Y // 5) rotate Z // 6) translate -void assemble_transform(Transform3d& transform, const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(), const Vec3d& scale = Vec3d::Ones(), const Vec3d& mirror = Vec3d::Ones()); +void assemble_transform(Transform3d& transform, const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(), + const Vec3d& scale = Vec3d::Ones(), const Vec3d& mirror = Vec3d::Ones()); // Returns the transform obtained by assembling the given transformations in the following order: // 1) mirror @@ -332,9 +333,21 @@ void assemble_transform(Transform3d& transform, const Vec3d& translation = Vec3d // 4) rotate Y // 5) rotate Z // 6) translate -Transform3d assemble_transform(const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(), const Vec3d& scale = Vec3d::Ones(), const Vec3d& mirror = Vec3d::Ones()); +Transform3d assemble_transform(const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(), + const Vec3d& scale = Vec3d::Ones(), const Vec3d& mirror = Vec3d::Ones()); #if ENABLE_TRANSFORMATIONS_BY_MATRICES +// Sets the given transform by multiplying the given transformations in the following order: +// T = translation * rotation * scale * mirror +void assemble_transform(Transform3d& transform, const Transform3d& translation = Transform3d::Identity(), + const Transform3d& rotation = Transform3d::Identity(), const Transform3d& scale = Transform3d::Identity(), + const Transform3d& mirror = Transform3d::Identity()); + +// Returns the transform obtained by multiplying the given transformations in the following order: +// T = translation * rotation * scale * mirror +Transform3d assemble_transform(const Transform3d& translation = Transform3d::Identity(), const Transform3d& rotation = Transform3d::Identity(), + const Transform3d& scale = Transform3d::Identity(), const Transform3d& mirror = Transform3d::Identity()); + // Sets the given transform by assembling the given rotations in the following order: // 1) rotate X // 2) rotate Y @@ -391,10 +404,10 @@ class Transformation public: #if ENABLE_TRANSFORMATIONS_BY_MATRICES Transformation() = default; - explicit Transformation(const Transform3d & transform) : m_matrix(transform) {} + explicit Transformation(const Transform3d& transform) : m_matrix(transform) {} #else Transformation(); - explicit Transformation(const Transform3d & transform); + explicit Transformation(const Transform3d& transform); #endif // ENABLE_TRANSFORMATIONS_BY_MATRICES #if ENABLE_TRANSFORMATIONS_BY_MATRICES diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index adab374f5..f3ba04c50 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3825,9 +3825,17 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) ModelObject* model_object = m_model->objects[object_idx]; if (model_object != nullptr) { if (selection_mode == Selection::Instance) +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); +#else model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES else if (selection_mode == Selection::Volume) +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); +#else model_object->volumes[volume_idx]->set_offset(v->get_volume_offset()); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES object_moved = true; model_object->invalidate_bounding_box(); @@ -3907,8 +3915,8 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) int object_idx = v->object_idx(); if (object_idx == 1000) { // the wipe tower #endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL - Vec3d offset = v->get_volume_offset(); - post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset(0), offset(1), v->get_volume_rotation()(2)))); + const Vec3d offset = v->get_volume_offset(); + post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), v->get_volume_rotation().z()))); } #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL int object_idx = v->object_idx(); @@ -3916,8 +3924,8 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) if (object_idx < 0 || (int)m_model->objects.size() <= object_idx) continue; - int instance_idx = v->instance_idx(); - int volume_idx = v->volume_idx(); + const int instance_idx = v->instance_idx(); + const int volume_idx = v->volume_idx(); done.insert(std::pair(object_idx, instance_idx)); @@ -3925,12 +3933,20 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) ModelObject* model_object = m_model->objects[object_idx]; if (model_object != nullptr) { if (selection_mode == Selection::Instance) { +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); +#else model_object->instances[instance_idx]->set_rotation(v->get_instance_rotation()); model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES } else if (selection_mode == Selection::Volume) { +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); +#else model_object->volumes[volume_idx]->set_rotation(v->get_volume_rotation()); model_object->volumes[volume_idx]->set_offset(v->get_volume_offset()); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES } model_object->invalidate_bounding_box(); } @@ -7347,13 +7363,11 @@ bool GLCanvas3D::_is_any_volume_outside() const void GLCanvas3D::_update_selection_from_hover() { bool ctrl_pressed = wxGetKeyState(WXK_CONTROL); - bool selection_changed = false; - if (m_hover_volume_idxs.empty()) { - if (!ctrl_pressed && m_rectangle_selection.get_state() == GLSelectionRectangle::EState::Select) { - selection_changed = ! m_selection.is_empty(); + if (!ctrl_pressed && m_rectangle_selection.get_state() == GLSelectionRectangle::EState::Select) m_selection.remove_all(); - } + + return; } GLSelectionRectangle::EState state = m_rectangle_selection.get_state(); @@ -7366,6 +7380,7 @@ void GLCanvas3D::_update_selection_from_hover() } } + bool selection_changed = false; #if ENABLE_NEW_RECTANGLE_SELECTION if (!m_rectangle_selection.is_empty()) { #endif // ENABLE_NEW_RECTANGLE_SELECTION diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 52dd207e9..42fe796a4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -54,9 +54,7 @@ bool GLGizmoMove3D::on_mouse(const wxMouseEvent &mouse_event) { } void GLGizmoMove3D::data_changed() { - const Selection &selection = m_parent.get_selection(); - bool is_wipe_tower = selection.is_wipe_tower(); - m_grabbers[2].enabled = !is_wipe_tower; + m_grabbers[2].enabled = !m_parent.get_selection().is_wipe_tower(); } bool GLGizmoMove3D::on_init() @@ -100,11 +98,19 @@ void GLGizmoMove3D::on_start_dragging() m_starting_drag_position = m_center + m_grabbers[m_hover_id].center; else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) { const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin()); +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + m_starting_drag_position = m_center + v.get_instance_transformation().get_rotation_matrix() * v.get_volume_transformation().get_rotation_matrix() * m_grabbers[m_hover_id].center; +#else m_starting_drag_position = m_center + Geometry::assemble_transform(Vec3d::Zero(), v.get_instance_rotation()) * Geometry::assemble_transform(Vec3d::Zero(), v.get_volume_rotation()) * m_grabbers[m_hover_id].center; +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES } else { const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin()); +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + m_starting_drag_position = m_center + v.get_instance_transformation().get_rotation_matrix() * m_grabbers[m_hover_id].center; +#else m_starting_drag_position = m_center + Geometry::assemble_transform(Vec3d::Zero(), v.get_instance_rotation()) * m_grabbers[m_hover_id].center; +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES } m_starting_box_center = m_center; m_starting_box_bottom_center = m_center; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 6579a1431..51d089873 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -287,7 +287,15 @@ void GLGizmoRotate::on_render_for_picking() #if ENABLE_WORLD_COORDINATE void GLGizmoRotate::init_data_from_selection(const Selection& selection) { +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + ECoordinatesType coordinates_type; + if (selection.is_wipe_tower()) + coordinates_type = ECoordinatesType::Local; + else + coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); +#else const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES if (coordinates_type == ECoordinatesType::World) { m_bounding_box = selection.get_bounding_box(); m_center = m_bounding_box.center(); @@ -326,7 +334,11 @@ void GLGizmoRotate::init_data_from_selection(const Selection& selection) if (coordinates_type == ECoordinatesType::World) m_orient_matrix = Transform3d::Identity(); +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + else if (coordinates_type == ECoordinatesType::Local && (selection.is_wipe_tower() || selection.is_single_volume_or_modifier())) { +#else else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) { +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin()); #if ENABLE_TRANSFORMATIONS_BY_MATRICES m_orient_matrix = v.get_instance_transformation().get_rotation_matrix() * v.get_volume_transformation().get_rotation_matrix(); @@ -749,12 +761,20 @@ Transform3d GLGizmoRotate::local_transform(const Selection& selection) const { case X: { +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + ret = Geometry::rotation_transform(0.5 * PI * Vec3d::UnitY()) * Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitZ()); +#else ret = Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY()) * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ()); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES break; } case Y: { +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + ret = Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitZ()) * Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitY()); +#else ret = Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ()) * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitY()); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES break; } default: @@ -868,13 +888,21 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event) // Apply new temporary rotations #if ENABLE_WORLD_COORDINATE TransformationType transformation_type; - switch (wxGetApp().obj_manipul()->get_coordinates_type()) - { - default: - case ECoordinatesType::World: { transformation_type = TransformationType::World_Relative_Joint; break; } - case ECoordinatesType::Instance: { transformation_type = TransformationType::Instance_Relative_Joint; break; } - case ECoordinatesType::Local: { transformation_type = TransformationType::Local_Relative_Joint; break; } +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + if (m_parent.get_selection().is_wipe_tower()) + transformation_type = TransformationType::Instance_Relative_Joint; + else { +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES + switch (wxGetApp().obj_manipul()->get_coordinates_type()) + { + default: + case ECoordinatesType::World: { transformation_type = TransformationType::World_Relative_Joint; break; } + case ECoordinatesType::Instance: { transformation_type = TransformationType::Instance_Relative_Joint; break; } + case ECoordinatesType::Local: { transformation_type = TransformationType::Local_Relative_Joint; break; } + } +#if ENABLE_TRANSFORMATIONS_BY_MATRICES } +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES #else TransformationType transformation_type(TransformationType::World_Relative_Joint); #endif // ENABLE_WORLD_COORDINATE @@ -885,22 +913,27 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event) } void GLGizmoRotate3D::data_changed() { - const Selection &selection = m_parent.get_selection(); - bool is_wipe_tower = selection.is_wipe_tower(); - if (is_wipe_tower) { - DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config; - float wipe_tower_rotation_angle = - dynamic_cast( - config.option("wipe_tower_rotation_angle")) - ->value; + if (m_parent.get_selection().is_wipe_tower()) { +#if !ENABLE_TRANSFORMATIONS_BY_MATRICES + const DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + const float wipe_tower_rotation_angle = + dynamic_cast( + config.option("wipe_tower_rotation_angle"))->value; set_rotation(Vec3d(0., 0., (M_PI / 180.) * wipe_tower_rotation_angle)); +#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES m_gizmos[0].disable_grabber(); m_gizmos[1].disable_grabber(); - } else { + } + else { +#if !ENABLE_TRANSFORMATIONS_BY_MATRICES set_rotation(Vec3d::Zero()); +#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES m_gizmos[0].enable_grabber(); m_gizmos[1].enable_grabber(); } +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + set_rotation(Vec3d::Zero()); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES } bool GLGizmoRotate3D::on_init() diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 7bc3ce91a..c96e8efc7 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -35,29 +35,25 @@ static const Slic3r::ColorRGBA TRANSPARENT_PLANE_COLOR = { 0.8f, 0.8f, 0.8f, 0.5 namespace Slic3r { namespace GUI { -Selection::VolumeCache::TransformCache::TransformCache() - : position(Vec3d::Zero()) - , rotation(Vec3d::Zero()) - , scaling_factor(Vec3d::Ones()) - , mirror(Vec3d::Ones()) - , rotation_matrix(Transform3d::Identity()) - , scale_matrix(Transform3d::Identity()) - , mirror_matrix(Transform3d::Identity()) - , full_matrix(Transform3d::Identity()) -{ -} - -Selection::VolumeCache::TransformCache::TransformCache(const Geometry::Transformation& transform) - : position(transform.get_offset()) - , rotation(transform.get_rotation()) - , scaling_factor(transform.get_scaling_factor()) - , mirror(transform.get_mirror()) - , full_matrix(transform.get_matrix()) -{ - rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), rotation); - scale_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scaling_factor); - mirror_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d::Ones(), mirror); -} + Selection::VolumeCache::TransformCache::TransformCache(const Geometry::Transformation& transform) + : position(transform.get_offset()) + , rotation(transform.get_rotation()) + , scaling_factor(transform.get_scaling_factor()) + , mirror(transform.get_mirror()) + , full_matrix(transform.get_matrix()) +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + , transform(transform) + , rotation_matrix(transform.get_rotation_matrix()) + , scale_matrix(transform.get_scaling_factor_matrix()) + , mirror_matrix(transform.get_mirror_matrix()) +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES + { +#if !ENABLE_TRANSFORMATIONS_BY_MATRICES + rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), rotation); + scale_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scaling_factor); + mirror_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d::Ones(), mirror); +#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES + } Selection::VolumeCache::VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform) : m_volume(volume_transform) @@ -772,27 +768,19 @@ void Selection::translate(const Vec3d& displacement, ECoordinatesType type) for (unsigned int i : m_list) { GLVolume& v = *(*m_volumes)[i]; const VolumeCache& volume_data = m_cache.volumes_data[i]; - if (m_mode == Instance && !v.is_wipe_tower) { + if (m_mode == Instance && !is_wipe_tower()) { + assert(is_from_fully_selected_instance(i)); switch (type) { case ECoordinatesType::World: { - if (is_from_fully_selected_instance(i)) - v.set_instance_transformation(Geometry::assemble_transform(displacement) * volume_data.get_instance_full_matrix()); - else - assert(false); - + v.set_instance_transformation(Geometry::assemble_transform(displacement) * volume_data.get_instance_full_matrix()); break; } case ECoordinatesType::Local: { - if (is_from_fully_selected_instance(i)) { - const Vec3d world_displacemet = volume_data.get_instance_rotation_matrix() * displacement; - v.set_instance_transformation(Geometry::assemble_transform(world_displacemet) * volume_data.get_instance_full_matrix()); - } - else - assert(false); - + const Vec3d world_displacemet = volume_data.get_instance_rotation_matrix() * displacement; + v.set_instance_transformation(Geometry::assemble_transform(world_displacemet) * volume_data.get_instance_full_matrix()); break; } default: { assert(false); break; } @@ -913,6 +901,88 @@ void Selection::translate(const Vec3d& displacement, bool local) #endif // ENABLE_TRANSFORMATIONS_BY_MATRICES // Rotate an object around one of the axes. Only one rotation component is expected to be changing. +#if ENABLE_TRANSFORMATIONS_BY_MATRICES +void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type) +{ + if (!m_valid) + return; + + assert(transformation_type.relative() || (transformation_type.absolute() && transformation_type.local())); + + const Transform3d rotation_matrix = Geometry::rotation_transform(rotation); + + for (unsigned int i : m_list) { + GLVolume& v = *(*m_volumes)[i]; + const VolumeCache& volume_data = m_cache.volumes_data[i]; + if (m_mode == Instance && !is_wipe_tower()) { + assert(is_from_fully_selected_instance(i)); + const Geometry::Transformation& old_trafo = volume_data.get_instance_transform(); + Transform3d new_rotation_matrix = Transform3d::Identity(); + if (transformation_type.absolute()) + new_rotation_matrix = rotation_matrix; + else { + if (transformation_type.world()) + new_rotation_matrix = rotation_matrix * old_trafo.get_rotation_matrix(); + else if (transformation_type.local()) + new_rotation_matrix = old_trafo.get_rotation_matrix() * rotation_matrix; + else + assert(false); + } + + const Vec3d new_offset = transformation_type.independent() ? old_trafo.get_offset() : + m_cache.dragging_center + new_rotation_matrix * old_trafo.get_rotation_matrix().inverse() * + (old_trafo.get_offset() - m_cache.dragging_center); + v.set_instance_transformation(Geometry::assemble_transform(Geometry::assemble_transform(new_offset), new_rotation_matrix, + old_trafo.get_scaling_factor_matrix(), old_trafo.get_mirror_matrix())); + } + else { + const Geometry::Transformation& old_trafo = volume_data.get_volume_transform(); + Transform3d new_rotation_matrix = Transform3d::Identity(); + + if (transformation_type.absolute()) + new_rotation_matrix = rotation_matrix; + else { + if (transformation_type.world()) { + const Transform3d inst_rotation_matrix = volume_data.get_instance_transform().get_rotation_matrix(); + new_rotation_matrix = inst_rotation_matrix.inverse() * rotation_matrix * inst_rotation_matrix * old_trafo.get_rotation_matrix(); + } + else if (transformation_type.instance()) + new_rotation_matrix = rotation_matrix * old_trafo.get_rotation_matrix(); + else if (transformation_type.local()) + new_rotation_matrix = old_trafo.get_rotation_matrix() * rotation_matrix; + else + assert(false); + } + + const Vec3d new_offset = !is_wipe_tower() ? old_trafo.get_offset() : + m_cache.dragging_center + new_rotation_matrix * old_trafo.get_rotation_matrix().inverse() * + (old_trafo.get_offset() - m_cache.dragging_center); + v.set_volume_transformation(Geometry::assemble_transform(Geometry::assemble_transform(new_offset), new_rotation_matrix, + old_trafo.get_scaling_factor_matrix(), old_trafo.get_mirror_matrix())); + } + } + +#if !DISABLE_INSTANCES_SYNCH + if (m_mode == Instance) { + int rot_axis_max = 0; + rotation.cwiseAbs().maxCoeff(&rot_axis_max); + SyncRotationType synch; + if (transformation_type.world() && rot_axis_max == 2) + synch = SyncRotationType::NONE; + else if (transformation_type.local()) + synch = SyncRotationType::FULL; + else + synch = SyncRotationType::GENERAL; + synchronize_unselected_instances(synch); + } + else if (m_mode == Volume) + synchronize_unselected_volumes(); +#endif // !DISABLE_INSTANCES_SYNCH + + set_bounding_boxes_dirty(); + wxGetApp().plater()->canvas3D()->requires_check_outside_state(); +} +#else void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type) { if (!m_valid) @@ -1073,6 +1143,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ set_bounding_boxes_dirty(); wxGetApp().plater()->canvas3D()->requires_check_outside_state(); } +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES void Selection::flattening_rotate(const Vec3d& normal) { @@ -2975,7 +3046,13 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_ if (v->object_idx() != object_idx || v->instance_idx() == instance_idx) continue; +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + const Vec3d inst_rotation_i = m_cache.volumes_data[i].get_instance_transform().get_rotation(); + const Vec3d inst_rotation_j = m_cache.volumes_data[j].get_instance_transform().get_rotation(); + assert(is_rotation_xy_synchronized(inst_rotation_i, inst_rotation_j)); +#else assert(is_rotation_xy_synchronized(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation())); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES switch (sync_rotation_type) { case SyncRotationType::NONE: { // z only rotation -> synch instance z @@ -2987,17 +3064,29 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_ } case SyncRotationType::GENERAL: { // generic rotation -> update instance z with the delta of the rotation. +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + const double z_diff = Geometry::rotation_diff_z(inst_rotation_i, inst_rotation_j); +#else const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation()); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES v->set_instance_rotation({ rotation.x(), rotation.y(), rotation.z() + z_diff }); break; } #if ENABLE_WORLD_COORDINATE case SyncRotationType::FULL: { // generic rotation -> update instance z with the delta of the rotation. +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + const Eigen::AngleAxisd angle_axis(Geometry::rotation_xyz_diff(rotation, inst_rotation_j)); +#else const Eigen::AngleAxisd angle_axis(Geometry::rotation_xyz_diff(rotation, m_cache.volumes_data[j].get_instance_rotation())); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES const Vec3d& axis = angle_axis.axis(); const double z_diff = (std::abs(axis.x()) > EPSILON || std::abs(axis.y()) > EPSILON) ? - angle_axis.angle() * axis.z() : Geometry::rotation_diff_z(rotation, m_cache.volumes_data[j].get_instance_rotation()); +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + angle_axis.angle() * axis.z() : Geometry::rotation_diff_z(rotation, inst_rotation_j); +#else + angle_axis.angle()* axis.z() : Geometry::rotation_diff_z(rotation, m_cache.volumes_data[j].get_instance_rotation()); +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES v->set_instance_rotation({ rotation.x(), rotation.y(), rotation.z() + z_diff }); break; diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 012fb0e4d..47a40877c 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -121,16 +121,19 @@ private: private: struct TransformCache { - Vec3d position; - Vec3d rotation; - Vec3d scaling_factor; - Vec3d mirror; - Transform3d rotation_matrix; - Transform3d scale_matrix; - Transform3d mirror_matrix; - Transform3d full_matrix; + Vec3d position{ Vec3d::Zero() }; + Vec3d rotation{ Vec3d::Zero() }; + Vec3d scaling_factor{ Vec3d::Ones() }; + Vec3d mirror{ Vec3d::Ones() }; + Transform3d rotation_matrix{ Transform3d::Identity() }; + Transform3d scale_matrix{ Transform3d::Identity() }; + Transform3d mirror_matrix{ Transform3d::Identity() }; + Transform3d full_matrix{ Transform3d::Identity() }; +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + Geometry::Transformation transform; +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES - TransformCache(); + TransformCache() = default; explicit TransformCache(const Geometry::Transformation& transform); }; @@ -142,13 +145,18 @@ private: VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform); const Vec3d& get_volume_position() const { return m_volume.position; } +#if !ENABLE_TRANSFORMATIONS_BY_MATRICES const Vec3d& get_volume_rotation() const { return m_volume.rotation; } const Vec3d& get_volume_scaling_factor() const { return m_volume.scaling_factor; } const Vec3d& get_volume_mirror() const { return m_volume.mirror; } +#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES const Transform3d& get_volume_rotation_matrix() const { return m_volume.rotation_matrix; } const Transform3d& get_volume_scale_matrix() const { return m_volume.scale_matrix; } const Transform3d& get_volume_mirror_matrix() const { return m_volume.mirror_matrix; } const Transform3d& get_volume_full_matrix() const { return m_volume.full_matrix; } +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + const Geometry::Transformation& get_volume_transform() const { return m_volume.transform; } +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES const Vec3d& get_instance_position() const { return m_instance.position; } const Vec3d& get_instance_rotation() const { return m_instance.rotation; } @@ -158,6 +166,9 @@ private: const Transform3d& get_instance_scale_matrix() const { return m_instance.scale_matrix; } const Transform3d& get_instance_mirror_matrix() const { return m_instance.mirror_matrix; } const Transform3d& get_instance_full_matrix() const { return m_instance.full_matrix; } +#if ENABLE_TRANSFORMATIONS_BY_MATRICES + const Geometry::Transformation& get_instance_transform() const { return m_instance.transform; } +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES }; public: