File indexing completed on 2025-01-18 09:11:27
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Navigation/NavigationStream.hpp"
0010
0011 #include "Acts/Detector/Portal.hpp"
0012 #include "Acts/Surfaces/Surface.hpp"
0013
0014 #include <algorithm>
0015
0016 namespace Acts {
0017
0018 bool NavigationStream::initialize(const GeometryContext& gctx,
0019 const QueryPoint& queryPoint,
0020 const BoundaryTolerance& cTolerance,
0021 double onSurfaceTolerance) {
0022
0023 const Vector3& position = queryPoint.position;
0024 const Vector3& direction = queryPoint.direction;
0025
0026
0027
0028 std::ranges::sort(m_candidates, [](const Candidate& a, const Candidate& b) {
0029 return (&a.surface()) < (&b.surface());
0030 });
0031
0032 m_candidates.erase(std::unique(m_candidates.begin(), m_candidates.end(),
0033 [](const Candidate& a, const Candidate& b) {
0034 return (&a.surface()) == (&b.surface());
0035 }),
0036 m_candidates.end());
0037
0038
0039
0040 std::vector<Candidate> additionalCandidates = {};
0041 for (auto& [sIntersection, gen2Portal, portal, bTolerance] : m_candidates) {
0042
0043 const Surface* surface = sIntersection.object();
0044
0045 auto multiIntersection = surface->intersect(gctx, position, direction,
0046 cTolerance, onSurfaceTolerance);
0047
0048
0049
0050 bool originalCandidateUpdated = false;
0051 for (const auto& rsIntersection : multiIntersection.split()) {
0052
0053 if (rsIntersection.pathLength() < -onSurfaceTolerance) {
0054 continue;
0055 }
0056
0057 if (rsIntersection.isValid()) {
0058 if (!originalCandidateUpdated) {
0059 sIntersection = rsIntersection;
0060 originalCandidateUpdated = true;
0061 } else {
0062 additionalCandidates.emplace_back(
0063 Candidate{.intersection = rsIntersection,
0064 .gen2Portal = gen2Portal,
0065 .portal = portal,
0066 .bTolerance = bTolerance});
0067 }
0068 }
0069 }
0070 }
0071
0072
0073 m_candidates.insert(m_candidates.end(), additionalCandidates.begin(),
0074 additionalCandidates.end());
0075
0076
0077 std::ranges::sort(m_candidates, Candidate::pathLengthOrder);
0078
0079
0080 auto firstInvalid =
0081 std::ranges::find_if(m_candidates, [](const Candidate& a) {
0082 const auto& [aIntersection, aGen2Portal, aPortal, aTolerance] = a;
0083 return !aIntersection.isValid();
0084 });
0085
0086
0087 m_candidates.resize(std::distance(m_candidates.begin(), firstInvalid));
0088
0089 m_currentIndex = 0;
0090 if (m_candidates.empty()) {
0091 return false;
0092 }
0093 return true;
0094 }
0095
0096 bool NavigationStream::update(const GeometryContext& gctx,
0097 const QueryPoint& queryPoint,
0098 double onSurfaceTolerance) {
0099
0100 for (; m_currentIndex < m_candidates.size(); ++m_currentIndex) {
0101
0102 Candidate& candidate = currentCandidate();
0103
0104 const Surface* surface = candidate.intersection.object();
0105
0106 auto multiIntersection =
0107 surface->intersect(gctx, queryPoint.position, queryPoint.direction,
0108 candidate.bTolerance, onSurfaceTolerance);
0109
0110 for (const auto& rsIntersection : multiIntersection.split()) {
0111
0112 if (rsIntersection.index() != candidate.intersection.index()) {
0113 continue;
0114 }
0115
0116 if (rsIntersection.isValid()) {
0117 candidate.intersection = rsIntersection;
0118 return true;
0119 }
0120 }
0121 }
0122
0123 return false;
0124 }
0125
0126 void NavigationStream::addSurfaceCandidate(
0127 const Surface& surface, const BoundaryTolerance& bTolerance) {
0128 m_candidates.emplace_back(
0129 Candidate{.intersection = ObjectIntersection<Surface>::invalid(&surface),
0130 .bTolerance = bTolerance});
0131 }
0132
0133 void NavigationStream::addSurfaceCandidates(
0134 std::span<const Surface*> surfaces, const BoundaryTolerance& bTolerance) {
0135 std::ranges::for_each(surfaces, [&](const auto* surface) {
0136 m_candidates.emplace_back(
0137 Candidate{.intersection = ObjectIntersection<Surface>::invalid(surface),
0138 .bTolerance = bTolerance});
0139 });
0140 }
0141
0142 void NavigationStream::addPortalCandidate(const Experimental::Portal& portal) {
0143 m_candidates.emplace_back(Candidate{
0144 .intersection = ObjectIntersection<Surface>::invalid(&portal.surface()),
0145 .gen2Portal = &portal,
0146 .bTolerance = BoundaryTolerance::None()});
0147 }
0148
0149 void NavigationStream::addPortalCandidate(const Portal& portal) {
0150 m_candidates.emplace_back(Candidate{
0151 .intersection = ObjectIntersection<Surface>::invalid(&portal.surface()),
0152 .portal = &portal,
0153 .bTolerance = BoundaryTolerance::None()});
0154 }
0155
0156 void NavigationStream::addPortalCandidates(
0157 std::span<const Experimental::Portal*> portals) {
0158 std::ranges::for_each(portals, [&](const auto& portal) {
0159 m_candidates.emplace_back(Candidate{
0160 .intersection =
0161 ObjectIntersection<Surface>::invalid(&(portal->surface())),
0162 .gen2Portal = portal,
0163 .bTolerance = BoundaryTolerance::None()});
0164 });
0165 }
0166
0167 AppendOnlyNavigationStream::AppendOnlyNavigationStream(NavigationStream& stream)
0168 : m_stream{&stream} {}
0169
0170 void AppendOnlyNavigationStream::addPortalCandidate(const Portal& portal) {
0171 m_stream->addPortalCandidate(portal);
0172 }
0173
0174 void AppendOnlyNavigationStream::addSurfaceCandidate(
0175 const Surface& surface, const BoundaryTolerance& bTolerance) {
0176 m_stream->addSurfaceCandidate(surface, bTolerance);
0177 }
0178
0179 }