File indexing completed on 2026-06-23 07:48:03
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/Volume.hpp"
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Geometry/VolumeBounds.hpp"
0013
0014 #include <iostream>
0015 #include <utility>
0016
0017 namespace Acts {
0018 Volume::Volume(const Transform3& transform,
0019 std::shared_ptr<VolumeBounds> volbounds) noexcept
0020 : GeometryObject(),
0021 m_transform{std::make_unique<Transform3>(transform)},
0022 m_itransform{std::make_unique<Transform3>(transform.inverse())},
0023 m_volumeBounds(std::move(volbounds)) {}
0024
0025 Volume Volume::shifted(const GeometryContext& gctx,
0026 const Transform3& shift) const {
0027 return Volume(shift * localToGlobalTransform(gctx), m_volumeBounds);
0028 }
0029 Volume::Volume(VolumePlacementBase& positioner,
0030 std::shared_ptr<VolumeBounds> volbounds) noexcept
0031 : GeometryObject{},
0032 m_volumeBounds{std::move(volbounds)},
0033 m_placement{&positioner} {}
0034
0035 Vector3 Volume::referencePosition(const GeometryContext& gctx,
0036 AxisDirection aDir) const {
0037
0038
0039 if (aDir == AxisDirection::AxisR || aDir == AxisDirection::AxisRPhi) {
0040
0041 return (center(gctx) + m_volumeBounds->referenceOffset(aDir));
0042 }
0043
0044 return center(gctx);
0045 }
0046
0047 bool Volume::isAlignable() const {
0048 return m_placement != nullptr;
0049 }
0050
0051 bool Volume::inside(const GeometryContext& gctx, const Vector3& gpos,
0052 double tol) const {
0053 Vector3 posInVolFrame = globalToLocalTransform(gctx) * gpos;
0054 return volumeBounds().inside(posInVolFrame, tol);
0055 }
0056
0057 std::ostream& operator<<(std::ostream& sl, const Volume& vol) {
0058 sl << "Volume with " << vol.volumeBounds() << std::endl;
0059 return sl;
0060 }
0061
0062 Volume::BoundingBox Volume::boundingBox(const Vector3& envelope) const {
0063 return m_volumeBounds->boundingBox(m_transform.get(), envelope, this);
0064 }
0065
0066 Volume::BoundingBox Volume::orientedBoundingBox() const {
0067 using namespace UnitLiterals;
0068 return m_volumeBounds->boundingBox(nullptr, {0.05_mm, 0.05_mm, 0.05_mm},
0069 this);
0070 }
0071
0072 void Volume::assignVolumeBounds(std::shared_ptr<VolumeBounds> volbounds) {
0073 assert(volbounds != nullptr);
0074
0075
0076
0077 if (isAlignable() && volumePlacement()->nPortalPlacements() > 0ul &&
0078 (*m_volumeBounds) != (*volbounds)) {
0079 throw std::runtime_error(
0080 "assignVolumeBounds() - Bounds cannot be overwritten if the associated "
0081 "VolumePlacement has instantiated boundary surfaces");
0082 }
0083
0084 m_volumeBounds = std::move(volbounds);
0085 }
0086
0087 void Volume::update(const GeometryContext& ,
0088 std::shared_ptr<VolumeBounds> volbounds,
0089 std::optional<Transform3> transform,
0090 const Logger& ) {
0091 if (volbounds) {
0092 m_volumeBounds = std::move(volbounds);
0093 }
0094 if (transform.has_value()) {
0095 setTransform(*transform);
0096 }
0097 }
0098
0099 const Transform3& Volume::localToGlobalTransform(
0100 const GeometryContext& gctx) const {
0101 if (isAlignable()) {
0102 return volumePlacement()->localToGlobalTransform(gctx);
0103 }
0104 assert(m_transform != nullptr);
0105 return (*m_transform);
0106 }
0107 const Transform3& Volume::globalToLocalTransform(
0108 const GeometryContext& gctx) const {
0109 if (isAlignable()) {
0110 return volumePlacement()->globalToLocalTransform(gctx);
0111 }
0112 assert(m_itransform != nullptr);
0113 return (*m_itransform);
0114 }
0115
0116 Vector3 Volume::center(const GeometryContext& gctx) const {
0117 return localToGlobalTransform(gctx).translation();
0118 }
0119
0120 const VolumeBounds& Volume::volumeBounds() const {
0121 return *m_volumeBounds;
0122 }
0123
0124 VolumeBounds& Volume::volumeBounds() {
0125 return *m_volumeBounds;
0126 }
0127
0128 std::shared_ptr<const VolumeBounds> Volume::volumeBoundsPtr() const {
0129 return m_volumeBounds;
0130 }
0131
0132 std::shared_ptr<VolumeBounds> Volume::volumeBoundsPtr() {
0133 return m_volumeBounds;
0134 }
0135
0136 VolumePlacementBase* Volume::volumePlacement() {
0137 return m_placement;
0138 }
0139 const VolumePlacementBase* Volume::volumePlacement() const {
0140 return m_placement;
0141 }
0142
0143 void Volume::setTransform(const Transform3& transform) {
0144 if (isAlignable()) {
0145 throw std::runtime_error(
0146 "setTransform() - Transforms of externally aligned volumes cannot "
0147 "be overwritten");
0148 }
0149 m_transform = std::make_unique<Transform3>(transform);
0150 m_itransform = std::make_unique<Transform3>(transform.inverse());
0151 }
0152
0153 bool Volume::operator==(const Volume& other) const {
0154 return ((m_transform != nullptr && other.m_transform != nullptr &&
0155 m_transform->matrix() == other.m_transform->matrix()) ||
0156 (volumePlacement() == other.volumePlacement() && isAlignable())) &&
0157 (*m_volumeBounds == *other.m_volumeBounds);
0158 }
0159
0160 void Volume::visualize(IVisualization3D& helper, const GeometryContext& gctx,
0161 const ViewConfig& viewConfig) const {
0162 auto bSurfaces =
0163 volumeBounds().orientedSurfaces(localToGlobalTransform(gctx));
0164 for (const auto& bs : bSurfaces) {
0165 bs.surface->visualize(helper, gctx, viewConfig);
0166 }
0167 }
0168
0169 }