![]() |
|
|||
File indexing completed on 2025-07-01 07:52:24
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/Geometry/BlueprintOptions.hpp" 0013 #include "Acts/Geometry/CuboidVolumeBounds.hpp" 0014 #include "Acts/Geometry/CylinderVolumeBounds.hpp" 0015 #include "Acts/Geometry/GeometryContext.hpp" 0016 #include "Acts/Geometry/NavigationPolicyFactory.hpp" 0017 #include "Acts/Utilities/AxisDefinitions.hpp" 0018 #include "Acts/Utilities/Logger.hpp" 0019 #include "Acts/Utilities/TransformRange.hpp" 0020 0021 #include <iosfwd> 0022 #include <memory> 0023 #include <string> 0024 #include <vector> 0025 0026 namespace Acts { 0027 0028 class Volume; 0029 class TrackingVolume; 0030 class VolumeBounds; 0031 class PortalShellBase; 0032 0033 namespace Experimental { 0034 0035 class MaterialDesignatorBlueprintNode; 0036 class StaticBlueprintNode; 0037 class LayerBlueprintNode; 0038 class GeometryIdentifierBlueprintNode; 0039 0040 class CylinderContainerBlueprintNode; 0041 class CuboidContainerBlueprintNode; 0042 0043 /// Base class for all nodes in the blueprint tree. This class defines the 0044 /// three-phase construction process. The three phases are 0045 /// 0046 /// -# **Build**: Construct volume representation + compute final sizing 0047 /// -# **Connect**: Create and connect portals at volume boundaries 0048 /// -# **Finalize**: Register portals with volumes + create acceleration 0049 /// structures 0050 /// 0051 /// During the *build* phase, the `build` method of all nodes in the tree are 0052 /// called recursively. Some nodes, like @ref Acts::Experimental::ContainerBlueprintNode, 0053 /// will take action on the volumes returns from its children, and perform 0054 /// sizing to connect them. See the @ref Acts::Experimental::ContainerBlueprintNode 0055 /// and @ref Acts::CylinderVolumeStack documentation for details on how the 0056 /// sizing is carried out. 0057 class BlueprintNode { 0058 public: 0059 /// Virtual destructor to ensure correct cleanup 0060 virtual ~BlueprintNode() = default; 0061 0062 /// Get the name of this node 0063 virtual const std::string& name() const = 0; 0064 0065 /// @anchor construction 0066 /// @name Construction methods 0067 /// These methods constitute the primary interface of the node that 0068 /// participates in the geometry construction. 0069 /// @{ 0070 0071 /// This method is called during the *build* phase of the blueprint tree 0072 /// construction. It returns a single @ref Acts::Volume which represents transform 0073 /// and bounds of the entire subtree. This does not have to correspond to the 0074 /// final @ref Acts::TrackingVolume, some node types will produce temporary volume 0075 /// representations. Lifetime of the returned volume is managed by the source 0076 /// node! 0077 /// Nodes higher in the hierarchy will issue resizes down the tree hierarchy. 0078 /// This is not done through a direct hierarchy, but coordinated by the 0079 /// respective node type, by internally consulting its children. 0080 /// 0081 /// @note Generally, you should not need to to call this method directly. 0082 /// The construction should usually be done through the special 0083 /// @ref Acts::Experimental::Blueprint class. 0084 /// 0085 /// @param options The global construction options 0086 /// @param gctx The geometry context for construction (usually nominal) 0087 /// @param logger The logger to use for output during construction 0088 /// @return The volume used for communicating transform and size up the hierarchy 0089 virtual Volume& build(const BlueprintOptions& options, 0090 const GeometryContext& gctx, 0091 const Logger& logger = Acts::getDummyLogger()) = 0; 0092 0093 /// This method is called during the *connect* phase. This phase handles the 0094 /// creation and connection of *portals* (instances of @ref Acts::PortalLinkBase). 0095 /// After the build-phase has completed, the volume sizes are **final**. Each 0096 /// node will consult its fully sized volume to produce *boundary surfaces*. 0097 /// Each boundary surface is then turned into a @ref Acts::TrivialPortalLink, which 0098 /// in turn produces a one-sided portal (see @ref Acts::Portal documentation) 0099 /// 0100 /// Some nodes (like @ref Acts::Experimental::ContainerBlueprintNode) will take action on 0101 /// their children, and unify the connected portals. 0102 /// 0103 /// After a node's processing has completed, it returns a reference to a @ref 0104 /// Acts::PortalShellBase, which represents a set of portals in a specific 0105 /// geometry arrangement. The returned object lifetime is managed by the 0106 /// returning node. 0107 /// 0108 /// @param options The global construction options 0109 /// @param gctx The geometry context for construction (usually nominal) 0110 /// @param logger The logger to use for output during construction 0111 virtual PortalShellBase& connect( 0112 const BlueprintOptions& options, const GeometryContext& gctx, 0113 const Logger& logger = Acts::getDummyLogger()) = 0; 0114 0115 /// This method is called during the *finalize* phase. This phase handles: 0116 /// 0117 /// - Registering portals into their final volumes 0118 /// - Registering volumes into their parents 0119 /// - Creating navigation policies 0120 /// - (In future) Handle geometry identification assignment 0121 /// 0122 /// At the end of this phase, each node will have transferred any temporary 0123 /// resources created during the build, that need to be retained, into the 0124 /// final @ref Acts::TrackingGeometry, and can be safely destroyed. 0125 /// 0126 /// @note The @p parent for volumes, portals, etc to be registered in is passed in **as an 0127 /// argument**, rather than being implicitly determined from the 0128 /// **parent node**. This is done so that nodes can remove themselves 0129 /// from the final volume hierarchy, like container nodes or the 0130 /// @ref Acts::Experimental::MaterialDesignatorBlueprintNode. 0131 /// 0132 /// @param options The global construction options 0133 /// @param gctx The geometry context for construction (usually nominal) 0134 /// @param parent The parent volume to register in 0135 /// @param logger The logger to use for output during construction 0136 virtual void finalize(const BlueprintOptions& options, 0137 const GeometryContext& gctx, TrackingVolume& parent, 0138 const Logger& logger = Acts::getDummyLogger()) = 0; 0139 0140 /// @} 0141 0142 /// @anchor convenience 0143 /// @name Convenience methods 0144 /// These methods are meant to make the construction of a blueprint tree in 0145 /// code more ergonomic. 0146 /// They usually take an optional `callback` parameter. The primary use for 0147 /// this parameter is structural, as it facilitates introducing scopes to 0148 /// indicate in code that objects are nested. 0149 /// 0150 /// ```cpp 0151 /// Blueprint::Config cfg; 0152 /// auto root = std::make_unique<Blueprint>(cfg); 0153 /// root->addStaticVolume( 0154 /// base, std::make_shared<CylinderVolumeBounds>(50_mm, 400_mm, 1000_mm), 0155 /// "PixelWrapper", [&](auto& wrapper) { 0156 /// // This scope can be used to equip `wrapper` 0157 /// }); 0158 /// ``` 0159 /// 0160 /// Alternatively, they can also be used without a callback, as the newly 0161 /// created node is also returned by reference: 0162 /// 0163 /// ``` 0164 /// auto& wrapper = root->addStaticVolume( 0165 /// base, std::make_shared<CylinderVolumeBounds>(50_mm, 400_mm, 1000_mm), 0166 /// "PixelWrapper"); 0167 /// ``` 0168 /// 0169 /// In both cases, it's not necessary to register the newly created node 0170 /// with a parent node. 0171 /// 0172 /// @{ 0173 0174 /// This method creates a new @ref Acts::Experimental::StaticBlueprintNode wrapping @p 0175 /// volume and adds it to this node as a child. 0176 /// @param volume The volume to add 0177 /// @param callback An optional callback that receives the node as an argument 0178 /// @return A reference to the created node 0179 StaticBlueprintNode& addStaticVolume( 0180 std::unique_ptr<TrackingVolume> volume, 0181 const std::function<void(StaticBlueprintNode& cylinder)>& callback = {}); 0182 0183 /// Alternative overload for creating a @ref Acts::Experimental::StaticBlueprintNode. This 0184 /// overload will invoke the constructor of @ref Acts::TrackingVolume and use 0185 /// that volume to create the node. 0186 /// @param transform The transform of the volume 0187 /// @param volumeBounds The bounds of the volume 0188 /// @param volumeName The name of the volume 0189 /// @param callback An optional callback that receives the node as an argument 0190 StaticBlueprintNode& addStaticVolume( 0191 const Transform3& transform, std::shared_ptr<VolumeBounds> volumeBounds, 0192 const std::string& volumeName = "undefined", 0193 const std::function<void(StaticBlueprintNode& cylinder)>& callback = {}); 0194 0195 /// Convenience method for creating a cylinder specialization of @ref Acts::Experimental::ContainerBlueprintNode. 0196 /// @param name The name of the container node. This name is only reflected 0197 /// in the node tree for debugging, as no extra volumes is created 0198 /// for the container. 0199 /// @param direction The direction of the stack configuration. See 0200 /// @ref Acts::CylinderVolumeStack for details. 0201 /// @param callback An optional callback that receives the node as an argument 0202 CylinderContainerBlueprintNode& addCylinderContainer( 0203 const std::string& name, AxisDirection direction, 0204 const std::function<void(CylinderContainerBlueprintNode& cylinder)>& 0205 callback = {}); 0206 0207 /// Convenience method for creating a cuboid specialization of @ref Acts::Experimental::ContainerBlueprintNode. 0208 /// @param name The name of the container node. This name is only reflected 0209 /// in the node tree for debugging, as no extra volumes is created 0210 /// for the container. 0211 /// @param direction The direction of the stack configuration. See 0212 /// @ref Acts::CuboidVolumeStack for details. 0213 /// @param callback An optional callback that receives the node as an argument 0214 CuboidContainerBlueprintNode& addCuboidContainer( 0215 const std::string& name, AxisDirection direction, 0216 const std::function<void(CuboidContainerBlueprintNode& cylinder)>& 0217 callback = {}); 0218 0219 /// Convenience method for creating a @ref Acts::Experimental::MaterialDesignatorBlueprintNode. 0220 /// @param name The name of the material designator node. Used for debugging 0221 /// the node tree only. 0222 /// @param callback An optional callback that receives the node as an argument 0223 MaterialDesignatorBlueprintNode& addMaterial( 0224 const std::string& name, 0225 const std::function<void(MaterialDesignatorBlueprintNode& material)>& 0226 callback = {}); 0227 0228 /// Convenience method for creating a @ref Acts::Experimental::LayerBlueprintNode. 0229 /// @param name The name of the layer node. 0230 /// @param callback An optional callback that receives the node as an argument 0231 LayerBlueprintNode& addLayer( 0232 const std::string& name, 0233 const std::function<void(LayerBlueprintNode& layer)>& callback = {}); 0234 0235 /// Convenience method for creating a @ref Acts::Experimental::GeometryIdentifierBlueprintNode. 0236 /// @param callback An optional callback that receives the node as an argument 0237 GeometryIdentifierBlueprintNode& withGeometryIdentifier( 0238 const std::function<void( 0239 GeometryIdentifierBlueprintNode& geometryIdentifier)>& callback = {}); 0240 0241 /// @} 0242 0243 /// Register a @p child to this node. 0244 /// @warning This method throws if adding the child would create a 0245 /// cycle in the blueprint tree! 0246 /// @param child The child node to add 0247 /// @return A reference this node (not the child!) 0248 BlueprintNode& addChild(std::shared_ptr<BlueprintNode> child); 0249 0250 /// A range-like object that allows range based for loops and index access. 0251 /// This type's iterators and accessors return mutable references when 0252 /// dereferenced. 0253 using MutableChildRange = 0254 detail::TransformRange<detail::Dereference, 0255 std::vector<std::shared_ptr<BlueprintNode>>>; 0256 0257 /// A range-like object that allows range based for loops and index access. 0258 /// This type's iterators and accessors return const references when 0259 /// dereferenced. 0260 using ChildRange = 0261 detail::TransformRange<detail::ConstDereference, 0262 const std::vector<std::shared_ptr<BlueprintNode>>>; 0263 0264 /// Return a @ref MutableChildRange to the children of this node. 0265 /// @return A range-like object to the children 0266 MutableChildRange children(); 0267 0268 /// Return a @ref ChildRange to the children of this node. 0269 /// @return A range-like object to the children 0270 ChildRange children() const; 0271 0272 /// Remove all children from this node 0273 void clearChildren(); 0274 0275 /// Return the depth of this node in the blueprint tree. A depth of zero means 0276 /// this node does not have a parent. 0277 /// @return The depth of this node 0278 std::size_t depth() const; 0279 0280 /// Print the node tree starting from this node to graphviz format 0281 /// @param os The stream to print to 0282 void graphviz(std::ostream& os) const; 0283 0284 /// Method that writes a representatiohn of **this node only** to graphviz. 0285 /// This should generally not be called on its own, but through the @ref 0286 /// BlueprintNode::graphviz method. 0287 /// @param os The stream to print to 0288 virtual void addToGraphviz(std::ostream& os) const; 0289 0290 /// Print a representation of this node to the stream 0291 /// @param os The stream to print to 0292 /// @param node The node to print 0293 /// @return The output stream 0294 friend std::ostream& operator<<(std::ostream& os, const BlueprintNode& node) { 0295 node.toStream(os); 0296 return os; 0297 } 0298 0299 protected: 0300 /// Virtual method to determine stream representation. 0301 /// @note This method is called by the stream operator. 0302 virtual void toStream(std::ostream& os) const; 0303 0304 /// Set the depth to @p depth and update children recursively 0305 void setDepth(std::size_t depth); 0306 0307 /// Printing helper returning a prefix including an indent depending on the 0308 /// depth. 0309 /// @return The prefix string 0310 std::string prefix() const; 0311 0312 /// An indentation depending on the depth of this node. 0313 /// @return The indentation string 0314 std::string indent() const; 0315 0316 private: 0317 std::size_t m_depth{0}; 0318 std::vector<std::shared_ptr<BlueprintNode>> m_children{}; 0319 }; 0320 0321 } // namespace Experimental 0322 } // 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 |
![]() ![]() |