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