From 625baaefeee0e58cb37a0a68375b03b39c2abf8a Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 15 Dec 2022 16:02:33 +0100 Subject: [PATCH] Follow-up to previous commit (wipe tower rotation) --- src/slic3r/GUI/GLCanvas3D.cpp | 54 ++--------------------------------- 1 file changed, 3 insertions(+), 51 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index cdb893a7b..de912a134 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3627,56 +3627,6 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) m_dirty = true; } -#if ENABLE_WORLD_COORDINATE -// This function is a replacement for function Vec3d Geometry::extract_rotation(const Transform3d& transform) -// which is returning wrong values for the call made in the following method GLCanvas3D::do_rotate() when rotating the wipe tower -Vec3d extract_rotation(const Transform3d& transform) -{ - // use only the non-translational part of the transform - Eigen::Matrix rotation_matrix = transform.matrix().block(0, 0, 3, 3); - // remove scale - rotation_matrix.col(0).normalize(); - rotation_matrix.col(1).normalize(); - rotation_matrix.col(2).normalize(); - - // reference: http://eecs.qmul.ac.uk/~gslabaugh/publications/euler.pdf - Vec3d angles1 = Vec3d::Zero(); - Vec3d angles2 = Vec3d::Zero(); - if (std::abs(std::abs(rotation_matrix(2, 0)) - 1.0) < 1e-5) { - angles1.z() = 0.0; - if (rotation_matrix(2, 0) < 0.0) { // == -1.0 - angles1.y() = 0.5 * double(PI); - angles1.x() = angles1.z() + ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2)); - } - else { // == 1.0 - angles1.y() = -0.5 * double(PI); - angles1.x() = -angles1.y() + ::atan2(-rotation_matrix(0, 1), -rotation_matrix(0, 2)); - } - angles2 = angles1; - } - else { - angles1.y() = -::asin(rotation_matrix(2, 0)); - const double inv_cos1 = 1.0 / ::cos(angles1.y()); - angles1.x() = ::atan2(rotation_matrix(2, 1) * inv_cos1, rotation_matrix(2, 2) * inv_cos1); - angles1.z() = ::atan2(rotation_matrix(1, 0) * inv_cos1, rotation_matrix(0, 0) * inv_cos1); - - angles2.y() = double(PI) - angles1.y(); - const double inv_cos2 = 1.0 / ::cos(angles2.y()); - angles2.x() = ::atan2(rotation_matrix(2, 1) * inv_cos2, rotation_matrix(2, 2) * inv_cos2); - angles2.z() = ::atan2(rotation_matrix(1, 0) * inv_cos2, rotation_matrix(0, 0) * inv_cos2); - } - - // The following euristic is the best found up to now (in the sense that it works fine with the greatest number of edge use-cases) - // but there are other use-cases were it does not - // We need to improve it - const double min_1 = angles1.cwiseAbs().minCoeff(); - const double min_2 = angles2.cwiseAbs().minCoeff(); - const bool use_1 = (min_1 < min_2) || (is_approx(min_1, min_2) && (angles1.norm() <= angles2.norm())); - - return use_1 ? angles1 : angles2; -} -#endif // ENABLE_WORLD_COORDINATE - void GLCanvas3D::do_rotate(const std::string& snapshot_type) { if (m_model == nullptr) @@ -3710,7 +3660,9 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) if (v->is_wipe_tower) { const Vec3d offset = v->get_volume_offset(); #if ENABLE_WORLD_COORDINATE - post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), extract_rotation(v->get_volume_transformation().get_matrix()).z()))); + Vec3d rot_unit_x = v->get_volume_transformation().get_matrix().linear() * Vec3d::UnitX(); + double z_rot = std::atan2(rot_unit_x.y(), rot_unit_x.x()); + post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), z_rot))); #else post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), v->get_volume_rotation().z()))); #endif // ENABLE_WORLD_COORDINATE