The _enforce_quat_continuity function previously skipped dragged parts,
assuming the GUI directly controls their placement. However, Newton
re-solves all free params (including the dragged part's) to satisfy
constraints, and can converge to an equivalent but distinct quaternion
branch. The C++ validateNewPlacements() then sees a >91 degree rotation
and rejects the step.
Two-level fix:
1. Remove the dragged_ids skip — apply continuity to ALL non-grounded
bodies, including the dragged part.
2. Add rotation angle check beyond simple hemisphere negation: compute
the relative quaternion angle using the same formula as the C++
validator (2*acos(w)). If it exceeds 91 degrees, reset to the
previous step's quaternion. This catches branch jumps where the
solver finds a geometrically different but constraint-satisfying
orientation (e.g. Cylindrical + Planar with 180-degree ambiguity).
Verified: all 291 solver tests pass.