refactor!: Move Transform2/Transform3 from Affine to Isometry - #6040
refactor!: Move Transform2/Transform3 from Affine to Isometry#6040andiwand wants to merge 2 commits into
Conversation
The geometry, navigation and propagation code has always assumed the linear part of a transform is orthogonal: `Surface::freeToBoundJacobian` uses `referenceFrame().transpose()` as its inverse, and `referenceFrame` is typed `RotationMatrix3`. A scaled or sheared transform therefore produces a silently wrong Jacobian rather than an error. Make the assumption part of the type, so that is a compile error instead. `AffineTransform2`/`AffineTransform3` name the unconstrained form for the external geometry that legitimately needs it, and `makeTransform3(rotation, translation)` replaces the `Translation3 * RotationMatrix3` idiom, which Eigen types as affine. Picks up acts-project#4055 by @pbutti. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01DGXsyXAdFts7z7YYqCar43 Co-Authored-By: Pierfrancesco Butti <pierfrancesco.butti@gmail.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DGXsyXAdFts7z7YYqCar43
Why
Exactly one place in the repo ever violated it: the beveled endcap disc in What changed vs #4055
Not a perf PR. The isolated Review guide25 files, but only the first is a design decision:
What breaks for usersFour compile-error classes, all loud, ~23 sites in this repo: building from Notes for maintainers
Verified: Core + DD4hep/Geant4/GeoModel/Json/Root/ActSVG/EDM4hep + Examples + python bindings build clean, 375/375 ctest with assertions forced on. |
Public API surface diffNo change to the public API surface. ✅ |
Add Acts::isOrthogonal next to makeTransform3 so the assert and the two deserialization boundaries share one rule, and make GeoModel placement conversion and Transform3 from_json throw rather than silently truncate a scaled or sheared matrix. That check found two transforms built from uninitialized Eigen storage via prerotate/pretranslate, in the Python Transform3 binding and in GridJsonConverterTests, both of which produced a garbage linear part. Route the five remaining hand-built transforms through makeTransform3, add a beveled-disc test for CylinderVolumeBounds::orientedSurfaces, and drop the unused AffineTransform2. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3yeUHxMX9pyWarxGRCWVc
|



The geometry, navigation and propagation code has always assumed the
linear part of a transform is orthogonal:
Surface::freeToBoundJacobianuses
referenceFrame().transpose()as its inverse, andreferenceFrameis typed
RotationMatrix3. A scaled or sheared transform thereforeproduces a silently wrong Jacobian rather than an error. Make the
assumption part of the type, so that is a compile error instead.
AffineTransform2/AffineTransform3name the unconstrained form for theexternal geometry that legitimately needs it, and
makeTransform3(rotation, translation)replaces theTranslation3 * RotationMatrix3idiom, which Eigen types as affine.Picks up #4055 by pbutti.
Co-Authored-By: Pierfrancesco Butti pierfrancesco.butti@gmail.com
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com