From a9ce511304312a19887c8ef7ef8c6da778780268 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 15 Feb 2023 12:48:41 +0100 Subject: [PATCH] Follow-up of e3cc3be9ab6a047503d0956f76cabffe7f167ffd - Fixes some extra use case where volumes were not rotated as rigid body --- src/slic3r/GUI/GLCanvas3D.cpp | 6 +++--- src/slic3r/GUI/Selection.cpp | 29 ++++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f2a5f3a789..a76fbb764b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3947,8 +3947,8 @@ void GLCanvas3D::update_sequential_clearance() // the results are then cached for following displacements if (m_sequential_print_clearance_first_displacement) { m_sequential_print_clearance.m_hull_2d_cache.clear(); - float shrink_factor = static_cast(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value - EPSILON)); - double mitter_limit = scale_(0.1); + const float shrink_factor = static_cast(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value - EPSILON)); + const double mitter_limit = scale_(0.1); m_sequential_print_clearance.m_hull_2d_cache.reserve(m_model->objects.size()); for (size_t i = 0; i < m_model->objects.size(); ++i) { ModelObject* model_object = m_model->objects[i]; @@ -3956,7 +3956,7 @@ void GLCanvas3D::update_sequential_clearance() #if ENABLE_WORLD_COORDINATE Geometry::Transformation trafo = model_instance0->get_transformation(); trafo.set_offset({ 0.0, 0.0, model_instance0->get_offset().z() }); - Polygon hull_2d = offset(model_object->convex_hull_2d(trafo.get_matrix()), + const Polygon hull_2d = offset(model_object->convex_hull_2d(trafo.get_matrix()), // Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. shrink_factor, diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 4f051dffe1..fd0a5ec595 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1024,18 +1024,37 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ } else { if (transformation_type.instance()) { - // ensure that the volume rotates as a rigid body const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform(); - const Transform3d cached_vol_rotation_matrix = vol_trafo.get_rotation_matrix(); - if ((inst_trafo * vol_trafo).is_left_handed() && !rotation.normalized().isApprox(Vec3d::UnitX())) + const Geometry::Transformation world_trafo = inst_trafo * vol_trafo; + // ensure proper sign of rotation for mirrored objects + if (world_trafo.is_left_handed() && !rotation.normalized().isApprox(Vec3d::UnitX())) rotation_matrix = rotation_matrix.inverse(); - v.set_volume_transformation(vol_trafo.get_matrix() * cached_vol_rotation_matrix.inverse() * rotation_matrix * cached_vol_rotation_matrix); + + // ensure that the volume rotates as a rigid body + const Geometry::TransformationSVD world_svd(world_trafo); + if (world_svd.anisotropic_scale) { + const Transform3d vol_scale_matrix = vol_trafo.get_scaling_factor_matrix(); + rotation_matrix = vol_scale_matrix.inverse() * rotation_matrix * vol_scale_matrix; + } + const Transform3d vol_rotation_matrix = vol_trafo.get_rotation_matrix(); + rotation_matrix = vol_rotation_matrix.inverse() * rotation_matrix * vol_rotation_matrix; + + v.set_volume_transformation(vol_trafo.get_matrix() * rotation_matrix); } else { if (transformation_type.local()) { const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform(); - if ((inst_trafo * vol_trafo).is_left_handed() && !rotation.normalized().isApprox(Vec3d::UnitX())) + const Geometry::Transformation world_trafo = inst_trafo * vol_trafo; + // ensure proper sign of rotation for mirrored objects + if (world_trafo.is_left_handed() && !rotation.normalized().isApprox(Vec3d::UnitX())) rotation_matrix = rotation_matrix.inverse(); + + // ensure that the volume rotates as a rigid body + const Geometry::TransformationSVD svd(world_trafo); + if (svd.anisotropic_scale) { + const Transform3d vol_scale_matrix = vol_trafo.get_scaling_factor_matrix(); + rotation_matrix = vol_scale_matrix.inverse() * rotation_matrix * vol_scale_matrix; + } } transform_volume_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center); }