Merge pull request 'fix(assembly): enforce drag quaternion continuity + short-arc validation (#338)' (#342) from fix/drag-quat-continuity into main
All checks were successful
Build and Test / build (push) Successful in 29m40s

Reviewed-on: #342
This commit was merged in pull request #342.
This commit is contained in:
2026-02-27 16:41:57 +00:00

View File

@@ -659,19 +659,26 @@ bool AssemblyObject::validateNewPlacements()
// Get the relative rotation: how much did the part rotate? // Get the relative rotation: how much did the part rotate?
Base::Rotation relativeRot = newRot * oldRot.inverse(); Base::Rotation relativeRot = newRot * oldRot.inverse();
// Get the angle of this rotation // Ensure we measure the short-arc angle. Rotation stores
// angle = 2*acos(w) which gives [0, 2*pi]. When the
// quaternion w component is negative (opposite hemisphere),
// the angle exceeds pi even though q and -q represent the
// same rotation. Map to [0, pi] for a correct comparison.
Base::Vector3d axis; Base::Vector3d axis;
double angle; double angle;
relativeRot.getRawValue(axis, angle); relativeRot.getRawValue(axis, angle);
if (angle > M_PI) {
angle = 2.0 * M_PI - angle;
}
// If the part rotated more than 90 degrees, consider it a flip // If the part rotated more than 90 degrees, consider it a flip
// Use 91 degrees to allow for small numerical errors // Use 91 degrees to allow for small numerical errors
constexpr double maxAngle = 91.0 * M_PI / 180.0; constexpr double maxAngle = 91.0 * M_PI / 180.0;
if (std::abs(angle) > maxAngle) { if (angle > maxAngle) {
Base::Console().warning( Base::Console().warning(
"Assembly : Ignoring bad solve, part (%s) flipped orientation (%.1f degrees).\n", "Assembly : Ignoring bad solve, part (%s) flipped orientation (%.1f degrees).\n",
obj->getFullLabel(), obj->getFullLabel(),
std::abs(angle) * 180.0 / M_PI angle * 180.0 / M_PI
); );
return false; return false;
} }