diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 87b4e223d..5d7b93679 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -1166,4 +1166,21 @@ MedialAxis::retrieve_endpoint(const VD::cell_type* cell) const } } +void assemble_transform(Transform3d& transform, const Vec3d& translation, const Vec3d& rotation, const Vec3d& scale) +{ + transform = Transform3d::Identity(); + transform.translate(translation); + transform.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ())); + transform.rotate(Eigen::AngleAxisd(rotation(1), Vec3d::UnitY())); + transform.rotate(Eigen::AngleAxisd(rotation(0), Vec3d::UnitX())); + transform.scale(scale); +} + +Transform3d assemble_transform(const Vec3d& translation, const Vec3d& rotation, const Vec3d& scale) +{ + Transform3d transform; + assemble_transform(transform, translation, rotation, scale); + return transform; +} + } } diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index 3698b996f..57b9cad02 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -157,6 +157,21 @@ class MedialAxis { const Point& retrieve_endpoint(const VD::cell_type* cell) const; }; +// Sets the given transform by assembling the given transformations in the following order: +// 1) scale +// 2) rotate X +// 3) rotate Y +// 4) rotate Z +// 5) translate +void assemble_transform(Transform3d& transform, const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(), const Vec3d& scale = Vec3d::Ones()); + +// Returns the transform obtained by assembling the given transformations in the following order: +// 1) scale +// 2) rotate X +// 3) rotate Y +// 4) rotate Z +// 5) translate +Transform3d assemble_transform(const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(), const Vec3d& scale = Vec3d::Ones()); } } #endif diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index e0cf14a57..8ced1018d 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1185,22 +1185,14 @@ void ModelInstance::transform_polygon(Polygon* polygon) const Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale) const { +#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM + Vec3d translation = dont_translate ? Vec3d::Zero() : m_offset; + Vec3d rotation = dont_rotate ? Vec3d::Zero() : m_rotation; + Vec3d scale = dont_scale ? Vec3d::Ones() : m_scaling_factor; + return Geometry::assemble_transform(translation, rotation, scale); +#else Transform3d m = Transform3d::Identity(); -#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM - if (!dont_translate) - m.translate(m_offset); - - if (!dont_rotate) - { - m.rotate(Eigen::AngleAxisd(m_rotation(2), Vec3d::UnitZ())); - m.rotate(Eigen::AngleAxisd(m_rotation(1), Vec3d::UnitY())); - m.rotate(Eigen::AngleAxisd(m_rotation(0), Vec3d::UnitX())); - } - - if (!dont_scale) - m.scale(m_scaling_factor); -#else if (!dont_translate) m.translate(Vec3d(offset(0), offset(1), 0.0)); @@ -1209,9 +1201,9 @@ Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, b if (!dont_scale) m.scale(scaling_factor); -#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM return m; +#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM } } diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 92e903911..07f9b0fda 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -389,14 +389,11 @@ const Transform3f& GLVolume::world_matrix() const { if (m_world_matrix_dirty) { +#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM + m_world_matrix = Geometry::assemble_transform(m_offset, m_rotation, m_scaling_factor).cast(); +#else m_world_matrix = Transform3f::Identity(); m_world_matrix.translate(m_offset.cast()); -#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM - m_world_matrix.rotate(Eigen::AngleAxisf((float)m_rotation(2), Vec3f::UnitZ())); - m_world_matrix.rotate(Eigen::AngleAxisf((float)m_rotation(1), Vec3f::UnitY())); - m_world_matrix.rotate(Eigen::AngleAxisf((float)m_rotation(0), Vec3f::UnitX())); - m_world_matrix.scale(m_scaling_factor.cast()); -#else m_world_matrix.rotate(Eigen::AngleAxisf((float)m_rotation, Vec3f::UnitZ())); m_world_matrix.scale((float)m_scaling_factor); #endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a2067bbf3..092548870 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -10,6 +10,7 @@ #include "../../libslic3r/ClipperUtils.hpp" #include "../../libslic3r/PrintConfig.hpp" #include "../../libslic3r/GCode/PreviewData.hpp" +#include "../../libslic3r/Geometry.hpp" #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" #include "GUI_ObjectManipulation.hpp" @@ -1144,17 +1145,14 @@ GLCanvas3D::Selection::VolumeCache::VolumeCache(const Vec3d& position, const Vec , m_rotation(rotation) , m_scaling_factor(scaling_factor) { - m_rotation_matrix = Transform3d::Identity(); - m_rotation_matrix.rotate(Eigen::AngleAxisd(m_rotation(2), Vec3d::UnitZ())); - m_rotation_matrix.rotate(Eigen::AngleAxisd(m_rotation(1), Vec3d::UnitY())); - m_rotation_matrix.rotate(Eigen::AngleAxisd(m_rotation(0), Vec3d::UnitX())); + m_rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), m_rotation); } GLCanvas3D::Selection::Selection() : m_volumes(nullptr) , m_model(nullptr) , m_mode(Instance) - , m_type(Invalid) + , m_type(Empty) , m_valid(false) , m_bounding_box_dirty(true) { @@ -1409,13 +1407,7 @@ void GLCanvas3D::Selection::rotate(const Vec3d& rotation) if (!m_valid) return; - Transform3d m = Transform3d::Identity(); - if (rotation(2) != 0.0f) - m.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ())); - else if (rotation(1) != 0.0f) - m.rotate(Eigen::AngleAxisd(rotation(1), Vec3d::UnitY())); - else if (rotation(0) != 0.0f) - m.rotate(Eigen::AngleAxisd(rotation(0), Vec3d::UnitX())); + Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); bool single_full_instance = is_single_full_instance();