|
||||
File indexing completed on 2025-01-18 09:10:52
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, 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 /// ``` 0114 /// portal1 portal2 0115 /// +---+ +---+ 0116 /// | | | | 0117 /// | | | | 0118 /// <----+ | + | +----> 0119 /// | | | | 0120 /// | | | | 0121 /// +---+ +---+ 0122 /// ``` 0123 /// 0124 /// @note The input portals need to have compatible link loadaout, e.g. one 0125 /// portal needs to have the *along normal* slot filled, and the 0126 /// otherone one needs to have the *opposite normal* slot filled. If 0127 /// portals share a filled slot, the function throws an exception. 0128 /// @note This is a destructive operation on the portals involved 0129 /// @param gctx The geometry context 0130 /// @param aPortal The first portal 0131 /// @param bPortal The second portal 0132 /// @param logger The logger to push output to 0133 static Portal fuse(const GeometryContext& gctx, Portal& aPortal, 0134 Portal& bPortal, const Logger& logger = getDummyLogger()); 0135 0136 /// Merge two adjacent portals with each other to produce a new portal that 0137 /// encompasses both inputs. It is the complementary operation to the fusing 0138 /// of portals. To be able to merge portals, the surfaces of their associated 0139 /// links need to be *mergeable*, and the portal links need to be compatible. 0140 /// This means that both portals need to have a link along the portal surface 0141 /// normal, opposite the normal, or both. If the equipped links are opposite 0142 /// relative to one another (e.g. one along one opposite), the function will 0143 /// throw an exception. 0144 /// 0145 /// ``` 0146 /// ^ ^ 0147 /// | | 0148 /// portal1| portal2| 0149 /// +-------+-------+ +-------+-------+ 0150 /// | | + | | 0151 /// +-------+-------+ +-------+-------+ 0152 /// | | 0153 /// | | 0154 /// v v 0155 /// ``` 0156 /// 0157 /// @note This is a destructive operation on both portals, their 0158 /// links will be moved to produce merged links, which can fail 0159 /// if the portal links are not compatible 0160 /// @param gctx The geometry context 0161 /// @param aPortal The first portal 0162 /// @param bPortal The second portal 0163 /// @param direction The direction of the merge (e.g. along z) 0164 /// @param logger The logger to push output to 0165 static Portal merge(const GeometryContext& gctx, Portal& aPortal, 0166 Portal& bPortal, AxisDirection direction, 0167 const Logger& logger = getDummyLogger()); 0168 0169 /// Resolve the volume for a 3D position and a direction 0170 /// The @p direction is used to select the right portal link, if it is set. 0171 /// In case no link is found in the specified direction, a `nullptr` is 0172 /// returned. 0173 /// @param gctx The geometry context 0174 /// @param position The 3D position 0175 /// @param direction The direction 0176 /// @return The target volume (can be `nullptr`) 0177 Result<const TrackingVolume*> resolveVolume(const GeometryContext& gctx, 0178 const Vector3& position, 0179 const Vector3& direction) const; 0180 0181 /// Set a link on the portal into the slot specified by the direction. 0182 /// @note The surface associated with @p link must be logically equivalent 0183 /// to the one of the link that's already set on the portal. 0184 /// @param gctx The geometry context 0185 /// @param direction The direction 0186 /// @param link The link to set 0187 void setLink(const GeometryContext& gctx, Direction direction, 0188 std::unique_ptr<PortalLinkBase> link); 0189 0190 /// Helper function create a trivial portal link based on a surface. 0191 /// @param gctx The geometry context 0192 /// @param direction The direction of the link to create 0193 /// @param surface The surface 0194 /// @note The @p surface must be logically equivalent 0195 /// to the one of the link that's already set on the portal. 0196 /// @param volume The target volume 0197 void setLink(const GeometryContext& gctx, Direction direction, 0198 std::shared_ptr<RegularSurface> surface, TrackingVolume& volume); 0199 0200 /// Get the link associated with the @p direction. Can be null if the associated link is unset. 0201 /// @param direction The direction 0202 /// @return The link (can be null) 0203 const PortalLinkBase* getLink(Direction direction) const; 0204 0205 /// Returns true if the portal is valid, that means it has at least one 0206 /// non-null link associated.Portals can be in an invalid state after they get 0207 /// merged or fused with other portals. 0208 /// @return True if the portal is valid 0209 bool isValid() const; 0210 0211 /// Create and attach a trivial portal link to the empty slot of this portal 0212 /// @param volume The target volume to connect to 0213 void fill(TrackingVolume& volume); 0214 0215 /// Access the portal surface that is shared between the two links 0216 /// @return The portal surface 0217 const RegularSurface& surface() const; 0218 0219 /// Access the portal surface that is shared between the two links 0220 /// @return The portal surface 0221 RegularSurface& surface(); 0222 0223 private: 0224 /// Helper to check surface equivalence without checking material status. This 0225 /// is needed because we allow fusing portals with surfaces that are 0226 /// equivalent but one of them has material while the other does not. The 0227 /// normal surface comparison would determine these surfaces as not 0228 /// equivalent. 0229 /// @param gctx The geometry context 0230 /// @param a The first surface 0231 /// @param b The second surface 0232 /// @return True if the surfaces are equivalent 0233 static bool isSameSurface(const GeometryContext& gctx, const Surface& a, 0234 const Surface& b); 0235 0236 std::shared_ptr<RegularSurface> m_surface; 0237 0238 std::unique_ptr<PortalLinkBase> m_alongNormal; 0239 std::unique_ptr<PortalLinkBase> m_oppositeNormal; 0240 }; 0241 0242 } // 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 |