|
|
|||
File indexing completed on 2025-11-07 09:15:06
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 #pragma once 0010 0011 #include "Acts/Definitions/Algebra.hpp" 0012 #include "Acts/Definitions/Direction.hpp" 0013 #include "Acts/Utilities/AxisDefinitions.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 (at least one non-null), and a corresponding 0046 /// surface. One link is associated with the direction along the surface's 0047 /// normal vector, and one 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 /// @param surfaceIn Surface to associate with this link 0082 /// @param volumeIn Volume to associate with this link 0083 Link(std::shared_ptr<RegularSurface> surfaceIn, TrackingVolume& volumeIn) 0084 : surface(std::move(surfaceIn)), volume(&volumeIn) {} 0085 0086 /// The associated surface 0087 std::shared_ptr<RegularSurface> surface = nullptr; 0088 /// The associated volume 0089 TrackingVolume* volume = nullptr; 0090 }; 0091 0092 /// Entry for the link along normal 0093 Link alongNormal{}; 0094 /// Entry for the link opposite normal 0095 Link oppositeNormal{}; 0096 }; 0097 0098 /// Constructor that takes a geometry context and an rvalue reference to a 0099 /// helper struct from above. This pattern allows you to use designated 0100 /// initializers to construct this object like: 0101 /// ```cpp 0102 /// Portal{gctx, {.oppositeNormal = {cyl1, *vol1}}}; 0103 /// Portal{gctx, {.alongNormal = {cyl2, *vol2}}}; 0104 /// ``` 0105 /// @param gctx The geometry context 0106 /// @param args The struct containing the arguments 0107 Portal(const GeometryContext& gctx, Arguments&& args); 0108 0109 /// Fuse two portals together. Fusing is the combination of two portal links 0110 /// on the same logical surfaces. The actual surface instances can be 0111 /// different, as long as they are geometrically equivalent (within numerical 0112 /// precision). The resulting portal will have one portal along the shared 0113 /// surface's normal vector, and one opposite that vector. 0114 /// 0115 /// ``` 0116 /// portal1 portal2 0117 /// +---+ +---+ 0118 /// | | | | 0119 /// | | | | 0120 /// <----+ | + | +----> 0121 /// | | | | 0122 /// | | | | 0123 /// +---+ +---+ 0124 /// ``` 0125 /// 0126 /// @note The input portals need to have compatible link loadaout, e.g. one 0127 /// portal needs to have the *along normal* slot filled, and the 0128 /// otherone one needs to have the *opposite normal* slot filled. If 0129 /// portals share a filled slot, the function throws an exception. 0130 /// @note This is a destructive operation on the portals involved 0131 /// @param gctx The geometry context 0132 /// @param aPortal The first portal 0133 /// @param bPortal The second portal 0134 /// @param logger The logger to push output to 0135 /// @return A new portal that combines both input portals 0136 static Portal fuse(const GeometryContext& gctx, Portal& aPortal, 0137 Portal& bPortal, const Logger& logger = getDummyLogger()); 0138 0139 /// Merge two adjacent portals with each other to produce a new portal that 0140 /// encompasses both inputs. It is the complementary operation to the fusing 0141 /// of portals. To be able to merge portals, the surfaces of their associated 0142 /// links need to be *mergeable*, and the portal links need to be compatible. 0143 /// This means that both portals need to have a link along the portal surface 0144 /// normal, opposite the normal, or both. If the equipped links are opposite 0145 /// relative to one another (e.g. one along one opposite), the function will 0146 /// throw an exception. 0147 /// 0148 /// ``` 0149 /// ^ ^ 0150 /// | | 0151 /// portal1| portal2| 0152 /// +-------+-------+ +-------+-------+ 0153 /// | | + | | 0154 /// +-------+-------+ +-------+-------+ 0155 /// | | 0156 /// | | 0157 /// v v 0158 /// ``` 0159 /// 0160 /// @note This is a destructive operation on both portals, their 0161 /// links will be moved to produce merged links, which can fail 0162 /// if the portal links are not compatible 0163 /// @param gctx The geometry context 0164 /// @param aPortal The first portal 0165 /// @param bPortal The second portal 0166 /// @param direction The direction of the merge (e.g. along z) 0167 /// @param logger The logger to push output to 0168 /// @return A new merged portal that encompasses both input portals 0169 static Portal merge(const GeometryContext& gctx, Portal& aPortal, 0170 Portal& bPortal, AxisDirection direction, 0171 const Logger& logger = getDummyLogger()); 0172 0173 /// Resolve the volume for a 3D position and a direction 0174 /// The @p direction is used to select the right portal link, if it is set. 0175 /// In case no link is found in the specified direction, a `nullptr` is 0176 /// returned. 0177 /// @param gctx The geometry context 0178 /// @param position The 3D position 0179 /// @param direction The direction 0180 /// @return The target volume (can be `nullptr`) 0181 Result<const TrackingVolume*> resolveVolume(const GeometryContext& gctx, 0182 const Vector3& position, 0183 const Vector3& direction) const; 0184 0185 /// Set a link on the portal into the slot specified by the direction. 0186 /// @note The surface associated with @p link must be logically equivalent 0187 /// to the one of the link that's already set on the portal. 0188 /// @param gctx The geometry context 0189 /// @param direction The direction 0190 /// @param link The link to set 0191 void setLink(const GeometryContext& gctx, Direction direction, 0192 std::unique_ptr<PortalLinkBase> link); 0193 0194 /// Helper function create a trivial portal link based on a surface. 0195 /// @param gctx The geometry context 0196 /// @param direction The direction of the link to create 0197 /// @param surface The surface 0198 /// @note The @p surface must be logically equivalent 0199 /// to the one of the link that's already set on the portal. 0200 /// @param volume The target volume 0201 void setLink(const GeometryContext& gctx, Direction direction, 0202 std::shared_ptr<RegularSurface> surface, TrackingVolume& volume); 0203 0204 /// Get the link associated with the @p direction. Can be null if the associated link is unset. 0205 /// @param direction The direction 0206 /// @return The link (can be null) 0207 const PortalLinkBase* getLink(Direction direction) const; 0208 0209 /// Returns true if the portal is valid, that means it has at least one 0210 /// non-null link associated.Portals can be in an invalid state after they get 0211 /// merged or fused with other portals. 0212 /// @return True if the portal is valid 0213 bool isValid() const; 0214 0215 /// Create and attach a trivial portal link to the empty slot of this portal 0216 /// @param volume The target volume to connect to 0217 void fill(TrackingVolume& volume); 0218 0219 /// Access the portal surface that is shared between the two links 0220 /// @return The portal surface 0221 const RegularSurface& surface() const; 0222 0223 /// Access the portal surface that is shared between the two links 0224 /// @return The portal surface 0225 RegularSurface& surface(); 0226 0227 private: 0228 /// Helper to check surface equivalence without checking material status. This 0229 /// is needed because we allow fusing portals with surfaces that are 0230 /// equivalent but one of them has material while the other does not. The 0231 /// normal surface comparison would determine these surfaces as not 0232 /// equivalent. 0233 /// @param gctx The geometry context 0234 /// @param a The first surface 0235 /// @param b The second surface 0236 /// @return True if the surfaces are equivalent 0237 static bool isSameSurface(const GeometryContext& gctx, const Surface& a, 0238 const Surface& b); 0239 0240 std::shared_ptr<RegularSurface> m_surface; 0241 0242 std::unique_ptr<PortalLinkBase> m_alongNormal; 0243 std::unique_ptr<PortalLinkBase> m_oppositeNormal; 0244 }; 0245 0246 } // 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 |
|