Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-23 07:48:03

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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   // for most of the binning types it is actually the center,
0038   // just for R-binning types the
0039   if (aDir == AxisDirection::AxisR || aDir == AxisDirection::AxisRPhi) {
0040     // the binning Position for R-type may have an offset
0041     return (center(gctx) + m_volumeBounds->referenceOffset(aDir));
0042   }
0043   // return the center
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   // If the volume is instantiated with a placement, the bounds can be updated
0075   // as long as the portals have not been made. Or the bounds are equivalent
0076   // with the current bounds
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& /*gctx*/,
0088                     std::shared_ptr<VolumeBounds> volbounds,
0089                     std::optional<Transform3> transform,
0090                     const Logger& /*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 }  // namespace Acts