File indexing completed on 2025-10-13 08:16:28
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/Layer.hpp"
0010
0011 #include "Acts/Material/IMaterialDecorator.hpp"
0012 #include "Acts/Propagator/NavigationTarget.hpp"
0013 #include "Acts/Propagator/Navigator.hpp"
0014 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Surfaces/SurfaceArray.hpp"
0017 #include "Acts/Utilities/Enumerate.hpp"
0018 #include "Acts/Utilities/Helpers.hpp"
0019 #include "Acts/Utilities/Intersection.hpp"
0020
0021 #include <algorithm>
0022 #include <vector>
0023
0024 namespace Acts {
0025
0026 Layer::Layer(std::unique_ptr<SurfaceArray> surfaceArray, double thickness,
0027 std::unique_ptr<ApproachDescriptor> ades, LayerType laytyp)
0028 : m_nextLayers(NextLayers(nullptr, nullptr)),
0029 m_surfaceArray(surfaceArray.release()),
0030 m_layerThickness(thickness),
0031 m_approachDescriptor(nullptr),
0032 m_representingVolume(nullptr),
0033 m_layerType(laytyp),
0034 m_ssRepresentingSurface(1) {
0035 if (ades) {
0036 ades->registerLayer(*this);
0037 m_approachDescriptor = std::move(ades);
0038 m_ssApproachSurfaces = 1;
0039 }
0040
0041 if (m_surfaceArray) {
0042 m_ssSensitiveSurfaces = 1;
0043 }
0044 }
0045
0046 Layer::~Layer() noexcept = default;
0047
0048 const ApproachDescriptor* Layer::approachDescriptor() const {
0049 return m_approachDescriptor.get();
0050 }
0051
0052 ApproachDescriptor* Layer::approachDescriptor() {
0053 return const_cast<ApproachDescriptor*>(m_approachDescriptor.get());
0054 }
0055
0056 void Layer::closeGeometry(const IMaterialDecorator* materialDecorator,
0057 const GeometryIdentifier& layerID,
0058 const GeometryIdentifierHook& hook,
0059 const Logger& logger) {
0060
0061 assignGeometryId(layerID);
0062
0063 Surface* rSurface = const_cast<Surface*>(&surfaceRepresentation());
0064 if (materialDecorator != nullptr) {
0065 materialDecorator->decorate(*rSurface);
0066 }
0067 ACTS_DEBUG("layerID: " << layerID);
0068
0069 rSurface->assignGeometryId(layerID);
0070
0071
0072 if (surfaceRepresentation().surfaceMaterial() != nullptr) {
0073 m_ssRepresentingSurface = 2;
0074 }
0075
0076 if (m_approachDescriptor) {
0077
0078 m_ssApproachSurfaces = 1;
0079
0080 GeometryIdentifier::Value iasurface = 0;
0081 for (auto& aSurface : m_approachDescriptor->containedSurfaces()) {
0082 auto asurfaceID = GeometryIdentifier(layerID).withApproach(++iasurface);
0083 auto mutableASurface = const_cast<Surface*>(aSurface);
0084 mutableASurface->assignGeometryId(asurfaceID);
0085 if (materialDecorator != nullptr) {
0086 materialDecorator->decorate(*mutableASurface);
0087 }
0088
0089 if (aSurface->surfaceMaterial() != nullptr) {
0090 m_ssApproachSurfaces = 2;
0091 }
0092 }
0093 }
0094
0095 if (m_surfaceArray) {
0096
0097 m_ssSensitiveSurfaces = 1;
0098
0099 GeometryIdentifier::Value issurface = 0;
0100 for (auto& sSurface : m_surfaceArray->surfaces()) {
0101 auto ssurfaceID = GeometryIdentifier(layerID).withSensitive(++issurface);
0102 ssurfaceID = hook.decorateIdentifier(ssurfaceID, *sSurface);
0103 auto mutableSSurface = const_cast<Surface*>(sSurface);
0104 mutableSSurface->assignGeometryId(ssurfaceID);
0105 if (materialDecorator != nullptr) {
0106 materialDecorator->decorate(*mutableSSurface);
0107 }
0108
0109 if (sSurface->surfaceMaterial() != nullptr) {
0110 m_ssSensitiveSurfaces = 2;
0111 }
0112 }
0113 }
0114 }
0115
0116 boost::container::small_vector<NavigationTarget, 10> Layer::compatibleSurfaces(
0117 const GeometryContext& gctx, const Vector3& position,
0118 const Vector3& direction, const NavigationOptions<Surface>& options) const {
0119
0120 boost::container::small_vector<NavigationTarget, 10> surfaceIntersections;
0121
0122
0123 if (!m_surfaceArray || !m_approachDescriptor) {
0124 return surfaceIntersections;
0125 }
0126
0127 double nearLimit = options.nearLimit;
0128 double farLimit = options.farLimit;
0129
0130 auto isUnique = [&](const NavigationTarget& b) {
0131 return std::ranges::none_of(
0132 surfaceIntersections, [&b](const NavigationTarget& a) {
0133 return &a.surface() == &b.surface() &&
0134 a.intersectionIndex() == b.intersectionIndex();
0135 });
0136 };
0137
0138
0139 auto acceptSurface = [&options](const Surface& sf,
0140 bool sensitive = false) -> bool {
0141
0142 if (sensitive && options.resolveSensitive) {
0143 return true;
0144 }
0145
0146 if (options.resolveMaterial && sf.surfaceMaterial() != nullptr) {
0147 return true;
0148 }
0149
0150 return options.resolvePassive;
0151 };
0152
0153
0154 auto processSurface = [&](const Surface& surface, bool sensitive = false) {
0155
0156 if (options.startObject == &surface) {
0157 return;
0158 }
0159
0160 if (!acceptSurface(surface, sensitive)) {
0161 return;
0162 }
0163 BoundaryTolerance boundaryTolerance = options.boundaryTolerance;
0164 if (rangeContainsValue(options.externalSurfaces, surface.geometryId())) {
0165 boundaryTolerance = BoundaryTolerance::Infinite();
0166 }
0167
0168 auto [intersection, intersectionIndex] =
0169 surface.intersect(gctx, position, direction, boundaryTolerance)
0170 .closestWithIndex();
0171 NavigationTarget surfaceIntersection(intersection, intersectionIndex,
0172 surface, boundaryTolerance);
0173 if (intersection.isValid() &&
0174 detail::checkPathLength(intersection.pathLength(), nearLimit,
0175 farLimit) &&
0176 isUnique(surfaceIntersection)) {
0177 surfaceIntersections.push_back(surfaceIntersection);
0178 }
0179 };
0180
0181
0182
0183
0184
0185
0186 if (m_approachDescriptor &&
0187 (options.resolveMaterial || options.resolvePassive)) {
0188
0189 const std::vector<const Surface*>& approachSurfaces =
0190 m_approachDescriptor->containedSurfaces();
0191
0192
0193
0194 for (auto& aSurface : approachSurfaces) {
0195 processSurface(*aSurface);
0196 }
0197 }
0198
0199
0200
0201
0202 if (m_surfaceArray && (options.resolveMaterial || options.resolvePassive ||
0203 options.resolveSensitive)) {
0204
0205 const std::vector<const Surface*>& sensitiveSurfaces =
0206 m_surfaceArray->neighbors(position, direction);
0207
0208
0209
0210 for (auto& sSurface : sensitiveSurfaces) {
0211 processSurface(*sSurface, true);
0212 }
0213 }
0214
0215
0216
0217
0218 const Surface* layerSurface = &surfaceRepresentation();
0219 processSurface(*layerSurface);
0220
0221 return surfaceIntersections;
0222 }
0223
0224 NavigationTarget Layer::surfaceOnApproach(
0225 const GeometryContext& gctx, const Vector3& position,
0226 const Vector3& direction, const NavigationOptions<Layer>& options) const {
0227
0228
0229
0230
0231
0232 const bool resolvePS = options.resolveSensitive || options.resolvePassive;
0233 const bool resolveMS =
0234 options.resolveMaterial &&
0235 (m_ssSensitiveSurfaces > 1 || m_ssApproachSurfaces > 1 ||
0236 (surfaceRepresentation().surfaceMaterial() != nullptr));
0237
0238
0239 const double nearLimit = options.nearLimit;
0240 const double farLimit = options.farLimit;
0241
0242
0243 if (m_approachDescriptor && (resolvePS || resolveMS)) {
0244 NavigationTarget aSurface = m_approachDescriptor->approachSurface(
0245 gctx, position, direction, options.boundaryTolerance, nearLimit,
0246 farLimit);
0247 return aSurface;
0248 }
0249
0250
0251 const Surface& layerSurface = surfaceRepresentation();
0252 const MultiIntersection3D multiIntersection = layerSurface.intersect(
0253 gctx, position, direction, options.boundaryTolerance);
0254 for (auto [intersectionIndex, intersection] :
0255 Acts::enumerate(multiIntersection)) {
0256 if (intersection.isValid() &&
0257 detail::checkPathLength(intersection.pathLength(), nearLimit,
0258 farLimit)) {
0259 return NavigationTarget(intersection, intersectionIndex, *this,
0260 layerSurface, options.boundaryTolerance);
0261 }
0262 }
0263 return NavigationTarget::None();
0264 }
0265
0266 }