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