![]() |
|
|||
File indexing completed on 2025-06-05 08:29:29
0001 // This file is part of the Acts project. 0002 // 0003 // Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/. 0008 0009 #pragma once 0010 0011 #include "Acts/Definitions/Algebra.hpp" 0012 #include "Acts/Definitions/Direction.hpp" 0013 #include "Acts/Utilities/BinningType.hpp" 0014 #include "Acts/Utilities/Logger.hpp" 0015 #include "Acts/Utilities/Result.hpp" 0016 0017 #include <memory> 0018 0019 namespace Acts { 0020 0021 class RegularSurface; 0022 class GeometryContext; 0023 class TrackingVolume; 0024 class CylinderSurface; 0025 class PlaneSurface; 0026 class DiscSurface; 0027 class Surface; 0028 0029 class PortalLinkBase; 0030 0031 /// Exception thrown when portals cannot be merged 0032 class PortalMergingException : public std::exception { 0033 const char* what() const noexcept override; 0034 }; 0035 0036 /// Exception thrown when portals cannot be fused 0037 class PortalFusingException : public std::exception { 0038 const char* what() const noexcept override; 0039 }; 0040 0041 /// A portal connects two or more neighboring volumes. Each volume has a set of 0042 /// portals that describes which volumes lie behind the portal in that 0043 /// direction. Portals use associated portal links to perform lookups of target 0044 /// volumes. 0045 /// Each portal has two links, and a corresponding surface. One link is 0046 /// associated with the direction along the surface's normal vector, and one 0047 /// with the opposite direction. 0048 class Portal { 0049 public: 0050 /// Constructor for a portal from a single link 0051 /// @param direction The direction of the link 0052 /// @param link The portal link 0053 Portal(Direction direction, std::unique_ptr<PortalLinkBase> link); 0054 0055 /// Constructor for a portal from a surface and volume, where a trivial portal 0056 /// link is automatically constructed. 0057 /// @param direction The direction of the link 0058 /// @param surface The surface from which to create the portal link 0059 /// @param volume The volume this portal connects to in the @p direction 0060 /// relative to the normal of @p surface. 0061 Portal(Direction direction, std::shared_ptr<RegularSurface> surface, 0062 TrackingVolume& volume); 0063 0064 /// Constructor for a portal from two links. One of the links can be 0065 /// `nullptr`, but at least one of them needs to be set. If both are set, they 0066 /// need to be valid compatible links that can be fused. 0067 /// @param gctx The geometry context 0068 /// @param alongNormal The link along the normal of the surface 0069 /// @param oppositeNormal The link opposite to the normal of the 0070 Portal(const GeometryContext& gctx, 0071 std::unique_ptr<PortalLinkBase> alongNormal, 0072 std::unique_ptr<PortalLinkBase> oppositeNormal); 0073 0074 /// Helper struct for the arguments to the portal constructor below using 0075 /// designated initializers. 0076 struct Arguments { 0077 /// Aggregate over a surface and a volume with optional semantics 0078 struct Link { 0079 Link() = default; 0080 /// Constructor from a surface and a volume 0081 Link(std::shared_ptr<RegularSurface> surfaceIn, TrackingVolume& volumeIn) 0082 : surface(std::move(surfaceIn)), volume(&volumeIn) {} 0083 0084 /// The associated surface 0085 std::shared_ptr<RegularSurface> surface = nullptr; 0086 /// The associated volume 0087 TrackingVolume* volume = nullptr; 0088 }; 0089 0090 /// Entry for the link along normal 0091 /// Entry for the link opposite normal 0092 Link alongNormal{}; 0093 Link oppositeNormal{}; 0094 }; 0095 0096 /// Constructor that takes a geometry context and an rvalue reference to a 0097 /// helper struct from above. This pattern allows you to use designated 0098 /// initializers to construct this object like: 0099 /// ```cpp 0100 /// Portal{gctx, {.oppositeNormal = {cyl1, *vol1}}}; 0101 /// Portal{gctx, {.alongNormal = {cyl2, *vol2}}}; 0102 /// ``` 0103 /// @param gctx The geometry context 0104 /// @param args The struct containing the arguments 0105 Portal(const GeometryContext& gctx, Arguments&& args); 0106 0107 /// Fuse two portals together. Fusing is the combination of two portal links 0108 /// on the same logical surfaces. The actual surface instances can be 0109 /// different, as long as they are geometrically equivalent (within numerical 0110 /// precision). The resulting portal will have one portal along the shared 0111 /// surface's normal vector, and one opposite that vector. 0112 /// 0113 /// portal1 portal2 0114 /// +---+ +---+ 0115 /// | | | | 0116 /// | | | | 0117 /// <----+ | + | +----> 0118 /// | | | | 0119 /// | | | | 0120 /// +---+ +---+ 0121 /// 0122 /// @note The input portals need to have compatible link loadaout, e.g. one 0123 /// portal needs to have the *along normal* slot filled, and the 0124 /// otherone one needs to have the *opposite normal* slot filled. If 0125 /// portals share a filled slot, the function throws an exception. 0126 /// @note This is a destructive operation on the portals involved 0127 /// @param gctx The geometry context 0128 /// @param aPortal The first portal 0129 /// @param bPortal The second portal 0130 /// @param logger The logger to push output to 0131 static Portal fuse(const GeometryContext& gctx, Portal& aPortal, 0132 Portal& bPortal, const Logger& logger = getDummyLogger()); 0133 0134 /// Merge two adjacent portals with each other to produce a new portal that 0135 /// encompasses both inputs. It is the complementary operation to the fusing 0136 /// of portals. To be able to merge portals, the surfaces of their associated 0137 /// links need to be *mergeable*, and the portal links need to be compatible. 0138 /// This means that both portals need to have a link along the portal surface 0139 /// normal, opposite the normal, or both. If the equipped links are opposite 0140 /// relative to one another (e.g. one along one opposite), the function will 0141 /// throw an exception. 0142 /// 0143 /// ^ ^ 0144 /// | | 0145 /// portal1| portal2| 0146 /// +-------+-------+ +-------+-------+ 0147 /// | | + | | 0148 /// +-------+-------+ +-------+-------+ 0149 /// | | 0150 /// | | 0151 /// v v 0152 /// 0153 /// @note This is a destructive operation on both portals, their 0154 /// links will be moved to produce merged links, which can fail 0155 /// if the portal links are not compatible 0156 /// @param gctx The geometry context 0157 /// @param aPortal The first portal 0158 /// @param bPortal The second portal 0159 /// @param direction The direction of the merge (e.g. along z) 0160 /// @param logger The logger to push output to 0161 static Portal merge(const GeometryContext& gctx, Portal& aPortal, 0162 Portal& bPortal, BinningValue direction, 0163 const Logger& logger = getDummyLogger()); 0164 0165 /// Resolve the volume for a 3D position and a direction 0166 /// The @p direction is used to select the right portal link, if it is set. 0167 /// In case no link is found in the specified direction, a `nullptr` is 0168 /// returned. 0169 /// @param gctx The geometry context 0170 /// @param position The 3D position 0171 /// @param direction The direction 0172 /// @return The target volume (can be `nullptr`) 0173 Result<const TrackingVolume*> resolveVolume(const GeometryContext& gctx, 0174 const Vector3& position, 0175 const Vector3& direction) const; 0176 0177 /// Set a link on the portal into the slot specified by the direction. 0178 /// @note The surface associated with @p link must be logically equivalent 0179 /// to the one of the link that's already set on the portal. 0180 /// @param gctx The geometry context 0181 /// @param direction The direction 0182 /// @param link The link to set 0183 void setLink(const GeometryContext& gctx, Direction direction, 0184 std::unique_ptr<PortalLinkBase> link); 0185 0186 /// Helper function create a trivial portal link based on a surface. 0187 /// @param gctx The geometry context 0188 /// @param direction The direction of the link to create 0189 /// @param surface The surface 0190 /// @note The @p surface must be logically equivalent 0191 /// to the one of the link that's already set on the portal. 0192 /// @param volume The target volume 0193 void setLink(const GeometryContext& gctx, Direction direction, 0194 std::shared_ptr<RegularSurface> surface, TrackingVolume& volume); 0195 0196 /// Get the link associated with the @p direction. Can be null if the associated link is unset. 0197 /// @param direction The direction 0198 /// @return The link (can be null) 0199 const PortalLinkBase* getLink(Direction direction) const; 0200 0201 /// Returns true if the portal is valid, that means it has at least one 0202 /// non-null link associated.Portals can be in an invalid state after they get 0203 /// merged or fused with other portals. 0204 /// @return True if the portal is valid 0205 bool isValid() const; 0206 0207 /// Create and attach a trivial portal link to the empty slot of this portal 0208 /// @param volume The target volume to connect to 0209 void fill(TrackingVolume& volume); 0210 0211 /// Access the portal surface that is shared between the two links 0212 /// @return The portal surface 0213 const RegularSurface& surface() const; 0214 0215 private: 0216 /// Helper to check surface equivalence without checking material status. This 0217 /// is needed because we allow fusing portals with surfaces that are 0218 /// equivalent but one of them has material while the other does not. The 0219 /// normal surface comparison would determine these surfaces as not 0220 /// equivalent. 0221 /// @param gctx The geometry context 0222 /// @param a The first surface 0223 /// @param b The second surface 0224 /// @return True if the surfaces are equivalent 0225 static bool isSameSurface(const GeometryContext& gctx, const Surface& a, 0226 const Surface& b); 0227 0228 std::shared_ptr<RegularSurface> m_surface; 0229 0230 std::unique_ptr<PortalLinkBase> m_alongNormal; 0231 std::unique_ptr<PortalLinkBase> m_oppositeNormal; 0232 }; 0233 0234 } // namespace Acts
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |