diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index fba1b2378..44e68a9d8 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -712,7 +712,7 @@ Transformation Transformation::volume_to_bed_transformation(const Transformation // No need to run the non-linear least squares fitting for uniform scaling. // Just set the inverse. #if ENABLE_TRANSFORMATIONS_BY_MATRICES - out = instance_transformation.get_matrix_no_offset().inverse(); + out.set_matrix(instance_transformation.get_matrix_no_offset().inverse()); #else out.set_from_transform(instance_transformation.get_matrix(true).inverse()); #endif // ENABLE_TRANSFORMATIONS_BY_MATRICES diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index ffe96cd3a..d0548f765 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -398,8 +398,6 @@ public: #endif // ENABLE_TRANSFORMATIONS_BY_MATRICES #if ENABLE_TRANSFORMATIONS_BY_MATRICES - Transformation& operator = (const Transform3d& transform) { m_matrix = transform; return *this; } - Vec3d get_offset() const { return m_matrix.translation(); } double get_offset(Axis axis) const { return get_offset()[axis]; } @@ -481,6 +479,8 @@ public: const Transform3d& get_matrix() const { return m_matrix; } Transform3d get_matrix_no_offset() const; Transform3d get_matrix_no_scaling_factor() const; + + void set_matrix(const Transform3d& transform) { m_matrix = transform; } #else const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const; #endif // ENABLE_TRANSFORMATIONS_BY_MATRICES diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index f2844abcb..016689a46 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -692,7 +692,7 @@ public: const Geometry::Transformation& get_transformation() const { return m_transformation; } void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; } #if ENABLE_TRANSFORMATIONS_BY_MATRICES - void set_transformation(const Transform3d& trafo) { m_transformation = trafo; } + void set_transformation(const Transform3d& trafo) { m_transformation.set_matrix(trafo); } #else void set_transformation(const Transform3d &trafo) { m_transformation.set_from_transform(trafo); } #endif // ENABLE_TRANSFORMATIONS_BY_MATRICES diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 263d8af08..9fb5a6965 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -432,8 +432,9 @@ public: const Geometry::Transformation& get_instance_transformation() const { return m_instance_transformation; } void set_instance_transformation(const Geometry::Transformation& transformation) { m_instance_transformation = transformation; set_bounding_boxes_as_dirty(); } - #if ENABLE_TRANSFORMATIONS_BY_MATRICES + void set_instance_transformation(const Transform3d& transform) { m_instance_transformation.set_matrix(transform); set_bounding_boxes_as_dirty(); } + Vec3d get_instance_offset() const { return m_instance_transformation.get_offset(); } #else const Vec3d& get_instance_offset() const { return m_instance_transformation.get_offset(); } @@ -471,8 +472,9 @@ public: const Geometry::Transformation& get_volume_transformation() const { return m_volume_transformation; } void set_volume_transformation(const Geometry::Transformation& transformation) { m_volume_transformation = transformation; set_bounding_boxes_as_dirty(); } - #if ENABLE_TRANSFORMATIONS_BY_MATRICES + void set_volume_transformation(const Transform3d& transform) { m_volume_transformation.set_matrix(transform); set_bounding_boxes_as_dirty(); } + Vec3d get_volume_offset() const { return m_volume_transformation.get_offset(); } #else const Vec3d& get_volume_offset() const { return m_volume_transformation.get_offset(); } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 45d80a145..1f0e77e16 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -763,6 +763,81 @@ void Selection::setup_cache() set_caches(); } +#if ENABLE_TRANSFORMATIONS_BY_MATRICES +void Selection::translate(const Vec3d& displacement, ECoordinatesType type) +{ + if (!m_valid) + return; + + 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) { + 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); + + 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); + + break; + } + default: { assert(false); break; } + } + } + else { + switch (type) + { + case ECoordinatesType::World: + { + const Transform3d inst_matrix_no_offset = volume_data.get_instance_rotation_matrix() * volume_data.get_instance_scale_matrix(); + const Vec3d inst_displacement = inst_matrix_no_offset.inverse() * displacement; + v.set_volume_transformation(Geometry::assemble_transform(inst_displacement) * volume_data.get_volume_full_matrix()); + break; + } + case ECoordinatesType::Instance: + { + const Vec3d inst_displacement = volume_data.get_instance_scale_matrix().inverse() * displacement; + v.set_volume_transformation(Geometry::assemble_transform(inst_displacement) * volume_data.get_volume_full_matrix()); + break; + } + case ECoordinatesType::Local: + { + const Vec3d inst_displacement = volume_data.get_instance_scale_matrix().inverse() * + volume_data.get_volume_rotation_matrix() * displacement; + v.set_volume_transformation(Geometry::assemble_transform(inst_displacement) * volume_data.get_volume_full_matrix()); + break; + } + default: { assert(false); break; } + } + } + } + +#if !DISABLE_INSTANCES_SYNCH + if (m_mode == Instance) + synchronize_unselected_instances(SyncRotationType::NONE); + else if (m_mode == Volume) + synchronize_unselected_volumes(); +#endif // !DISABLE_INSTANCES_SYNCH + + ensure_not_below_bed(); + set_bounding_boxes_dirty(); + wxGetApp().plater()->canvas3D()->requires_check_outside_state(); +} +#else #if ENABLE_WORLD_COORDINATE void Selection::translate(const Vec3d& displacement, ECoordinatesType type) #else @@ -835,6 +910,7 @@ void Selection::translate(const Vec3d& displacement, bool local) set_bounding_boxes_dirty(); wxGetApp().plater()->canvas3D()->requires_check_outside_state(); } +#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES // Rotate an object around one of the axes. Only one rotation component is expected to be changing. void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type) @@ -1491,9 +1567,8 @@ void Selection::render(float scale_factor) else if (coordinates_type == ECoordinatesType::Local && is_single_volume_or_modifier()) { const GLVolume& v = *get_volume(*get_volume_idxs().begin()); #if ENABLE_TRANSFORMATIONS_BY_MATRICES - box = v.transformed_convex_hull_bounding_box( - v.get_instance_transformation().get_scaling_factor_matrix() * v.get_volume_transformation().get_scaling_factor_matrix()); - trafo = v.get_instance_transformation().get_matrix_no_scaling_factor() * v.get_volume_transformation().get_matrix_no_scaling_factor(); + box = v.transformed_convex_hull_bounding_box(v.get_volume_transformation().get_scaling_factor_matrix()); + trafo = v.get_instance_transformation().get_matrix() * v.get_volume_transformation().get_matrix_no_scaling_factor(); #else box = v.transformed_convex_hull_bounding_box(v.get_instance_transformation().get_matrix(true, true, false, true) * v.get_volume_transformation().get_matrix(true, true, false, true)); trafo = v.get_instance_transformation().get_matrix(false, false, true, false) * v.get_volume_transformation().get_matrix(false, false, true, false);