diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 25db3cce0..7bab0ed7a 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -877,8 +877,7 @@ double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) const Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to)); const Vec3d& axis = angle_axis.axis(); const double angle = angle_axis.angle(); -#if 0 -//#ifndef NDEBUG +#ifndef NDEBUG if (std::abs(angle) > 1e-8) { assert(std::abs(axis.x()) < 1e-8); assert(std::abs(axis.y()) < 1e-8); @@ -887,4 +886,15 @@ double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) return (axis.z() < 0) ? -angle : angle; } +double rotation_diff_z(const Transform3d &trafo_from, const Transform3d &trafo_to) +{ + auto m = trafo_to.linear() * trafo_from.linear().inverse(); + assert(std::abs(m.determinant() - 1)); + Vec3d vx = m * Vec3d(1., 0., 0); + // Verify that the linear part of rotation from trafo_from to trafo_to rotates around Z and is unity. + assert(std::abs(std::hypot(vx.x(), vx.y()) - 1.) < 1e-5); + assert(std::abs(vx.z()) < 1e-5); + return atan2(vx.y(), vx.x()); +} + }} // namespace Slic3r::Geometry diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index acaad6af3..d7cf32611 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -547,6 +547,7 @@ extern Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec // Rotation by Z to align rot_xyz_from to rot_xyz_to. // This should only be called if it is known, that the two rotations only differ in rotation around the Z axis. extern double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to); +extern double rotation_diff_z(const Transform3d &trafo_from, const Transform3d &trafo_to); // Is the angle close to a multiple of 90 degrees? inline bool is_rotation_ninety_degrees(double a) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index e7305234f..eff0bcd45 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -404,7 +404,7 @@ bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Poly } // Make a copy, so it may be rotated for instances. Polygon convex_hull0 = it_convex_hull->second; - const double z_diff = Geometry::rotation_diff_z(model_instance0->get_rotation(), print_object->instances().front().model_instance->get_rotation()); + const double z_diff = Geometry::rotation_diff_z(model_instance0->get_matrix(), print_object->instances().front().model_instance->get_matrix()); if (std::abs(z_diff) > EPSILON) convex_hull0.rotate(z_diff); // Now we check that no instance of convex_hull intersects any of the previously checked object instances. diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index d4023f64d..dc5e2b519 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -190,14 +190,13 @@ static std::vector sla_instances(const ModelObject &mo std::vector instances; assert(! model_object.instances.empty()); if (! model_object.instances.empty()) { - Vec3d rotation0 = model_object.instances.front()->get_rotation(); - rotation0(2) = 0.; + const Transform3d& trafo0 = model_object.instances.front()->get_matrix(); for (ModelInstance *model_instance : model_object.instances) if (model_instance->is_printable()) { instances.emplace_back( model_instance->id(), Point::new_scale(model_instance->get_offset(X), model_instance->get_offset(Y)), - float(Geometry::rotation_diff_z(rotation0, model_instance->get_rotation()))); + float(Geometry::rotation_diff_z(trafo0, model_instance->get_matrix()))); } } return instances;