File indexing completed on 2025-07-01 07:52:51
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/StaticBlueprintNode.hpp"
0010
0011 #include "Acts/Geometry/CuboidPortalShell.hpp"
0012 #include "Acts/Geometry/CylinderPortalShell.hpp"
0013 #include "Acts/Geometry/GeometryContext.hpp"
0014 #include "Acts/Geometry/TrapezoidPortalShell.hpp"
0015 #include "Acts/Geometry/VolumeBounds.hpp"
0016 #include "Acts/Navigation/INavigationPolicy.hpp"
0017 #include "Acts/Utilities/GraphViz.hpp"
0018 #include "Acts/Visualization/GeometryView3D.hpp"
0019
0020 namespace Acts::Experimental {
0021
0022 StaticBlueprintNode::StaticBlueprintNode(std::unique_ptr<TrackingVolume> volume)
0023 : m_volume(std::move(volume)) {}
0024
0025 Volume& StaticBlueprintNode::build(const BlueprintOptions& options,
0026 const GeometryContext& gctx,
0027 const Logger& logger) {
0028 ACTS_DEBUG(prefix() << "Static build");
0029 if (!m_volume) {
0030 throw std::runtime_error("Volume is not built");
0031 }
0032
0033 ACTS_DEBUG(prefix() << "Building volume (" << name()
0034 << ", id=" << m_volume->geometryId() << ") with "
0035 << children().size() << " children");
0036 for (auto& child : children()) {
0037 child.build(options, gctx, logger);
0038 }
0039
0040 ACTS_DEBUG(prefix() << "-> returning volume " << *m_volume);
0041 return *m_volume;
0042 }
0043
0044 PortalShellBase& StaticBlueprintNode::connect(const BlueprintOptions& options,
0045 const GeometryContext& gctx,
0046 const Logger& logger) {
0047 ACTS_DEBUG(prefix() << "Static connect");
0048 if (m_volume == nullptr) {
0049 throw std::runtime_error("Volume is not present");
0050 }
0051
0052 ACTS_DEBUG(prefix() << "Connecting parent volume (" << name() << ") with "
0053 << children().size() << " children");
0054
0055 for (auto& child : children()) {
0056 auto& shell = child.connect(options, gctx, logger);
0057
0058 shell.fill(*m_volume);
0059 }
0060
0061 VolumeBounds::BoundsType type = m_volume->volumeBounds().type();
0062 if (type == VolumeBounds::eCylinder) {
0063 m_shell = std::make_unique<SingleCylinderPortalShell>(*m_volume);
0064
0065 } else if (type == VolumeBounds::eCuboid) {
0066 m_shell = std::make_unique<SingleCuboidPortalShell>(*m_volume);
0067
0068 } else if (type == VolumeBounds::eTrapezoid) {
0069 m_shell = std::make_unique<SingleTrapezoidPortalShell>(*m_volume);
0070
0071 } else {
0072 throw std::logic_error("Volume type is not supported");
0073 }
0074
0075 assert(m_shell != nullptr &&
0076 "No shell was built at the end of StaticBlueprintNode::connect");
0077 assert(m_shell->isValid() &&
0078 "Shell is not valid at the end of StaticBlueprintNode::connect");
0079 return *m_shell;
0080 }
0081
0082 void StaticBlueprintNode::finalize(const BlueprintOptions& options,
0083 const GeometryContext& gctx,
0084 TrackingVolume& parent,
0085 const Logger& logger) {
0086 ACTS_DEBUG(prefix() << "Finalizing static volume");
0087
0088 if (!m_volume) {
0089 ACTS_ERROR(prefix() << "Volume is not built");
0090 throw std::runtime_error("Volume is not built");
0091 }
0092
0093 if (!m_shell) {
0094 ACTS_ERROR(prefix() << "Shell is not built");
0095 throw std::runtime_error("Shell is not built");
0096 }
0097
0098 for (auto& child : children()) {
0099 child.finalize(options, gctx, *m_volume, logger);
0100 }
0101
0102 ACTS_DEBUG(prefix() << "Registering " << m_shell->size()
0103 << " portals into volume " << m_volume->volumeName());
0104 m_shell->applyToVolume();
0105
0106 ACTS_DEBUG(prefix() << " Adding volume (" << m_volume->volumeName()
0107 << ") to parent volume (" << parent.volumeName() << ")");
0108
0109 const auto* policyFactory = options.defaultNavigationPolicyFactory.get();
0110
0111 if (m_navigationPolicyFactory) {
0112 policyFactory = m_navigationPolicyFactory.get();
0113 }
0114 m_volume->setNavigationPolicy(policyFactory->build(gctx, *m_volume, logger));
0115
0116 parent.addVolume(std::move(m_volume));
0117 }
0118
0119 const std::string& StaticBlueprintNode::name() const {
0120 static const std::string uninitialized = "uninitialized";
0121 if (m_volume == nullptr) {
0122 return uninitialized;
0123 }
0124 return m_volume->volumeName();
0125 }
0126
0127 StaticBlueprintNode& StaticBlueprintNode::setNavigationPolicyFactory(
0128 std::shared_ptr<NavigationPolicyFactory> navigationPolicyFactory) {
0129 m_navigationPolicyFactory = std::move(navigationPolicyFactory);
0130 return *this;
0131 }
0132
0133 const NavigationPolicyFactory* StaticBlueprintNode::navigationPolicyFactory()
0134 const {
0135 return m_navigationPolicyFactory.get();
0136 }
0137
0138 void StaticBlueprintNode::addToGraphviz(std::ostream& os) const {
0139 std::stringstream ss;
0140 ss << "<b>" << name() << "</b>";
0141 ss << "<br/>";
0142 if (m_volume == nullptr) {
0143 throw std::runtime_error("Volume is not built");
0144 }
0145 switch (m_volume->volumeBounds().type()) {
0146 case VolumeBounds::eCylinder:
0147 ss << "Cylinder";
0148 break;
0149 case VolumeBounds::eCuboid:
0150 ss << "Cuboid";
0151 break;
0152 case VolumeBounds::eCone:
0153 ss << "Cone";
0154 break;
0155 case VolumeBounds::eCutoutCylinder:
0156 ss << "CutoutCylinder";
0157 break;
0158 case VolumeBounds::eGenericCuboid:
0159 ss << "GenericCuboid";
0160 break;
0161 case VolumeBounds::eTrapezoid:
0162 ss << "Trapezoid";
0163 break;
0164 default:
0165 ss << "Other";
0166 }
0167
0168 GraphViz::Node node{
0169 .id = name(), .label = ss.str(), .shape = GraphViz::Shape::Rectangle};
0170
0171 os << node;
0172
0173 BlueprintNode::addToGraphviz(os);
0174 }
0175
0176 }