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