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