File indexing completed on 2025-01-18 09:11:19
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/CylinderContainerBlueprintNode.hpp"
0013 #include "Acts/Geometry/LayerBlueprintNode.hpp"
0014 #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp"
0015 #include "Acts/Geometry/StaticBlueprintNode.hpp"
0016 #include "Acts/Navigation/INavigationPolicy.hpp"
0017 #include "Acts/Navigation/TryAllNavigationPolicy.hpp"
0018
0019 #include <concepts>
0020 #include <ostream>
0021
0022 namespace Acts {
0023
0024 namespace {
0025 bool hasDescendent(const BlueprintNode& descendent,
0026 const BlueprintNode& ancestor) {
0027 if (&descendent == &ancestor) {
0028 return true;
0029 }
0030
0031 return std::ranges::any_of(ancestor.children(),
0032 [&](const auto& child) -> bool {
0033 return hasDescendent(descendent, child);
0034 });
0035 }
0036 }
0037
0038 void BlueprintNode::toStream(std::ostream& os) const {
0039 os << "BlueprintNode(" << name() << ")";
0040 }
0041
0042 BlueprintNode& BlueprintNode::addChild(std::shared_ptr<BlueprintNode> child) {
0043 if (!child) {
0044 throw std::invalid_argument("Child is nullptr");
0045 }
0046
0047 if (dynamic_cast<Blueprint*>(child.get()) != nullptr) {
0048 throw std::invalid_argument("Cannot add a Blueprint as a child");
0049 }
0050
0051 if (child->depth() != 0) {
0052 throw std::invalid_argument("Child has already been added to another node");
0053 }
0054
0055 if (hasDescendent(*this, *child)) {
0056 throw std::invalid_argument("Adding child would create a cycle");
0057 }
0058
0059 child->setDepth(m_depth + 1);
0060 m_children.push_back(std::move(child));
0061 return *this;
0062 }
0063
0064 BlueprintNode::MutableChildRange BlueprintNode::children() {
0065 return MutableChildRange{m_children};
0066 }
0067
0068 BlueprintNode::ChildRange BlueprintNode::children() const {
0069 return ChildRange{m_children};
0070 }
0071
0072 std::size_t BlueprintNode::depth() const {
0073 return m_depth;
0074 }
0075
0076 void BlueprintNode::setDepth(std::size_t depth) {
0077 m_depth = depth;
0078 for (auto& child : children()) {
0079 child.setDepth(depth + 1);
0080 }
0081 }
0082
0083 std::string BlueprintNode::indent() const {
0084 return std::string(m_depth * 2, ' ');
0085 }
0086
0087 std::string BlueprintNode::prefix() const {
0088 return indent() + "[" + name() + "]: ";
0089 }
0090
0091 StaticBlueprintNode& BlueprintNode::addStaticVolume(
0092 std::unique_ptr<TrackingVolume> volume,
0093 const std::function<void(StaticBlueprintNode& cylinder)>& callback) {
0094 if (!volume) {
0095 throw std::invalid_argument("Volume is nullptr");
0096 }
0097
0098 auto child = std::make_shared<StaticBlueprintNode>(std::move(volume));
0099 addChild(child);
0100
0101 if (callback) {
0102 callback(*child);
0103 }
0104 return *child;
0105 }
0106
0107 StaticBlueprintNode& BlueprintNode::addStaticVolume(
0108 const Transform3& transform, std::shared_ptr<VolumeBounds> volumeBounds,
0109 const std::string& volumeName,
0110 const std::function<void(StaticBlueprintNode& cylinder)>& callback) {
0111 return addStaticVolume(std::make_unique<TrackingVolume>(
0112 transform, std::move(volumeBounds), volumeName),
0113 callback);
0114 }
0115
0116 CylinderContainerBlueprintNode& BlueprintNode::addCylinderContainer(
0117 const std::string& name, AxisDirection direction,
0118 const std::function<void(CylinderContainerBlueprintNode& cylinder)>&
0119 callback) {
0120 auto cylinder =
0121 std::make_shared<CylinderContainerBlueprintNode>(name, direction);
0122 addChild(cylinder);
0123 if (callback) {
0124 callback(*cylinder);
0125 }
0126 return *cylinder;
0127 }
0128
0129 MaterialDesignatorBlueprintNode& BlueprintNode::addMaterial(
0130 const std::string& name,
0131 const std::function<void(MaterialDesignatorBlueprintNode& material)>&
0132 callback) {
0133 auto material = std::make_shared<MaterialDesignatorBlueprintNode>(name);
0134 addChild(material);
0135 if (callback) {
0136 callback(*material);
0137 }
0138 return *material;
0139 }
0140
0141 LayerBlueprintNode& BlueprintNode::addLayer(
0142 const std::string& name,
0143 const std::function<void(LayerBlueprintNode& layer)>& callback) {
0144 auto layer = std::make_shared<LayerBlueprintNode>(name);
0145 addChild(layer);
0146 if (callback) {
0147 callback(*layer);
0148 }
0149 return *layer;
0150 }
0151
0152 void BlueprintNode::clearChildren() {
0153 for (auto& child : children()) {
0154 child.setDepth(0);
0155 }
0156 m_children.clear();
0157 }
0158
0159 void BlueprintNode::graphviz(std::ostream& os) const {
0160 os << "digraph BlueprintNode {" << std::endl;
0161 addToGraphviz(os);
0162 os << "}" << std::endl;
0163 }
0164
0165 void BlueprintNode::addToGraphviz(std::ostream& os) const {
0166 for (const auto& child : children()) {
0167 os << indent() << "\"" << name() << "\" -> \"" << child.name() << "\";"
0168 << std::endl;
0169 child.addToGraphviz(os);
0170 }
0171 }
0172
0173 }