File indexing completed on 2026-06-26 07:46:17
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/BlueprintNode.hpp"
0010
0011 #include "Acts/Geometry/Blueprint.hpp"
0012 #include "Acts/Geometry/ContainerBlueprintNode.hpp"
0013 #include "Acts/Geometry/GeometryIdentifierBlueprintNode.hpp"
0014 #include "Acts/Geometry/LayerBlueprintNode.hpp"
0015 #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp"
0016 #include "Acts/Geometry/PortalDesignatorBlueprintNode.hpp"
0017 #include "Acts/Geometry/StaticBlueprintNode.hpp"
0018 #include "Acts/Navigation/INavigationPolicy.hpp"
0019 #include "Acts/Navigation/TryAllNavigationPolicy.hpp"
0020
0021 #include <ostream>
0022
0023 namespace Acts::Experimental {
0024
0025 namespace {
0026 bool hasDescendent(const BlueprintNode& descendent,
0027 const BlueprintNode& ancestor) {
0028 if (&descendent == &ancestor) {
0029 return true;
0030 }
0031
0032 return std::ranges::any_of(ancestor.children(),
0033 [&](const auto& child) -> bool {
0034 return hasDescendent(descendent, child);
0035 });
0036 }
0037 }
0038
0039 void BlueprintNode::toStream(std::ostream& os) const {
0040 os << "BlueprintNode(" << name() << ")";
0041 }
0042
0043 BlueprintNode& BlueprintNode::addChild(std::shared_ptr<BlueprintNode> child) {
0044 if (!child) {
0045 throw std::invalid_argument("Child is nullptr");
0046 }
0047
0048 if (dynamic_cast<Blueprint*>(child.get()) != nullptr) {
0049 throw std::invalid_argument("Cannot add a Blueprint as a child");
0050 }
0051
0052 if (child->depth() != 0) {
0053 throw std::invalid_argument("Child has already been added to another node");
0054 }
0055
0056 if (hasDescendent(*this, *child)) {
0057 throw std::invalid_argument("Adding child would create a cycle");
0058 }
0059
0060 child->setDepth(m_depth + 1);
0061 m_children.push_back(std::move(child));
0062 return *this;
0063 }
0064
0065 BlueprintNode::MutableChildRange BlueprintNode::children() {
0066 return MutableChildRange{m_children};
0067 }
0068
0069 BlueprintNode::ChildRange BlueprintNode::children() const {
0070 return ChildRange{m_children};
0071 }
0072
0073 std::size_t BlueprintNode::depth() const {
0074 return m_depth;
0075 }
0076
0077 void BlueprintNode::setDepth(std::size_t depth) {
0078 m_depth = depth;
0079 for (auto& child : children()) {
0080 child.setDepth(depth + 1);
0081 }
0082 }
0083
0084 std::string BlueprintNode::indent() const {
0085 return std::string(m_depth * 2, ' ');
0086 }
0087
0088 std::string BlueprintNode::prefix() const {
0089 return indent() + "[" + name() + "]: ";
0090 }
0091
0092 StaticBlueprintNode& BlueprintNode::addStaticVolume(
0093 std::unique_ptr<TrackingVolume> volume,
0094 const std::function<void(StaticBlueprintNode& cylinder)>& callback) {
0095 if (!volume) {
0096 throw std::invalid_argument("Volume is nullptr");
0097 }
0098
0099 auto child = std::make_shared<StaticBlueprintNode>(std::move(volume));
0100 addChild(child);
0101
0102 if (callback) {
0103 callback(*child);
0104 }
0105 return *child;
0106 }
0107
0108 StaticBlueprintNode& BlueprintNode::addStaticVolume(
0109 const Transform3& transform, std::shared_ptr<VolumeBounds> volumeBounds,
0110 const std::string& volumeName,
0111 const std::function<void(StaticBlueprintNode& node)>& callback) {
0112 return addStaticVolume(std::make_unique<TrackingVolume>(
0113 transform, std::move(volumeBounds), volumeName),
0114 callback);
0115 }
0116
0117 CylinderContainerBlueprintNode& BlueprintNode::addCylinderContainer(
0118 const std::string& name, AxisDirection direction,
0119 const std::function<void(CylinderContainerBlueprintNode& cylinder)>&
0120 callback) {
0121 auto cylinder =
0122 std::make_shared<CylinderContainerBlueprintNode>(name, direction);
0123 addChild(cylinder);
0124 if (callback) {
0125 callback(*cylinder);
0126 }
0127 return *cylinder;
0128 }
0129
0130 CuboidContainerBlueprintNode& BlueprintNode::addCuboidContainer(
0131 const std::string& name, AxisDirection direction,
0132 const std::function<void(CuboidContainerBlueprintNode& box)>& callback) {
0133 auto box = std::make_shared<CuboidContainerBlueprintNode>(name, direction);
0134 addChild(box);
0135 if (callback) {
0136 callback(*box);
0137 }
0138 return *box;
0139 }
0140
0141 MaterialDesignatorBlueprintNode& BlueprintNode::addMaterial(
0142 const std::string& name,
0143 const std::function<void(MaterialDesignatorBlueprintNode& material)>&
0144 callback) {
0145 auto material = std::make_shared<MaterialDesignatorBlueprintNode>(name);
0146 addChild(material);
0147 if (callback) {
0148 callback(*material);
0149 }
0150 return *material;
0151 }
0152
0153 PortalDesignatorBlueprintNode& BlueprintNode::addPortalDesignator(
0154 const std::string& name,
0155 const std::function<void(PortalDesignatorBlueprintNode& portals)>&
0156 callback) {
0157 auto portals = std::make_shared<PortalDesignatorBlueprintNode>(name);
0158 addChild(portals);
0159 if (callback) {
0160 callback(*portals);
0161 }
0162 return *portals;
0163 }
0164
0165 LayerBlueprintNode& BlueprintNode::addLayer(
0166 const std::string& name,
0167 const std::function<void(LayerBlueprintNode& layer)>& callback) {
0168 auto layer = std::make_shared<LayerBlueprintNode>(name);
0169 addChild(layer);
0170 if (callback) {
0171 callback(*layer);
0172 }
0173 return *layer;
0174 }
0175
0176 GeometryIdentifierBlueprintNode& BlueprintNode::withGeometryIdentifier(
0177 const std::function<
0178 void(GeometryIdentifierBlueprintNode& geometryIdentifier)>& callback) {
0179 auto geometryIdentifier = std::make_shared<GeometryIdentifierBlueprintNode>();
0180 addChild(geometryIdentifier);
0181 if (callback) {
0182 callback(*geometryIdentifier);
0183 }
0184 return *geometryIdentifier;
0185 }
0186
0187 void BlueprintNode::clearChildren() {
0188 for (auto& child : children()) {
0189 child.setDepth(0);
0190 }
0191 m_children.clear();
0192 }
0193
0194 void BlueprintNode::graphviz(std::ostream& os) const {
0195 os << "digraph BlueprintNode {" << std::endl;
0196 addToGraphviz(os);
0197 os << "}" << std::endl;
0198 }
0199
0200 void BlueprintNode::addToGraphviz(std::ostream& os) const {
0201 for (const auto& child : children()) {
0202 os << indent() << "\"" << name() << "\" -> \"" << child.name() << "\";"
0203 << std::endl;
0204 child.addToGraphviz(os);
0205 }
0206 }
0207
0208 }