diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index db64f97a7f..4cf4b5caa7 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -1182,19 +1182,27 @@ Transform3d assemble_transform(const Vec3d& translation, const Vec3d& rotation, Vec3d extract_euler_angles(const Eigen::Matrix& rotation_matrix) { #if ENABLE_NEW_EULER_ANGLES - // see: http://www.gregslabaugh.net/publications/euler.pdf + // reference: http://www.gregslabaugh.net/publications/euler.pdf auto is_approx = [](double value, double test_value) -> bool { return std::abs(value - test_value) < EPSILON; }; Vec3d angles1 = Vec3d::Zero(); Vec3d angles2 = Vec3d::Zero(); if (is_approx(std::abs(rotation_matrix(2, 0)), 1.0)) { - // the handling of singular cases deviates from the cited paper - // the following code works better when rotating an object with the gizmo after having - // changed its orientation using the place on bed gizmo angles1(0) = 0.0; - angles1(1) = 0.5 * (double)PI; - angles1(2) = angles1(0) + ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2)); + if (rotation_matrix(2, 0) > 0.0) // == +1.0 + { + angles1(1) = 0.5 * (double)PI; + angles1(2) = angles1(0) + ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2)); + + } + else // == -1.0 + { + angles1(1) = 0.5 * (double)PI; + angles1(2) = -angles1(0) - ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2)); + + } + angles2 = angles1; } else diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f124390632..4a149eea85 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2726,7 +2726,20 @@ void GLCanvas3D::Selection::_synchronize_unselected_instances(bool including_z) if ((v->object_idx() != object_idx) || (v->instance_idx() == instance_idx)) continue; - v->set_instance_rotation(Vec3d(rotation(0), rotation(1), including_z ? rotation(2) : m_cache.volumes_data[j].get_instance_rotation()(2) + rotation(2))); + auto is_approx = [](double value, double test_value) -> bool { return std::abs(value - test_value) < EPSILON; }; + + double z; + if (including_z) + // rotation comes from place on face -> force given z + z = rotation(2); + else if (is_approx(rotation(0), m_cache.volumes_data[j].get_instance_rotation()(0)) && is_approx(rotation(1), m_cache.volumes_data[j].get_instance_rotation()(1))) + // z only rotation -> keep instance z + z = v->get_instance_rotation()(2); + else + // generic rotation -> update instance z + z = m_cache.volumes_data[j].get_instance_rotation()(2) + rotation(2); + + v->set_instance_rotation(Vec3d(rotation(0), rotation(1), z)); v->set_instance_scaling_factor(scaling_factor); v->set_instance_mirror(mirror);