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