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