File indexing completed on 2026-09-26 09:15:48
0001
0002
0003
0004
0005
0006 #ifndef VECGEOM_VOLUMES_KERNEL_EXTRUDEDIMPLEMENTATION_H_
0007 #define VECGEOM_VOLUMES_KERNEL_EXTRUDEDIMPLEMENTATION_H_
0008
0009 #include <cstdio>
0010 #include <VecCore/VecCore>
0011 #include "VecGeom/base/Config.h"
0012 #include "VecGeom/volumes/kernel/GenericKernels.h"
0013 #include "VecGeom/base/Vector3D.h"
0014
0015 #include "TessellatedImplementation.h"
0016 #include "SExtruImplementation.h"
0017
0018 namespace vecgeom {
0019
0020 VECGEOM_DEVICE_FORWARD_DECLARE(struct ExtrudedImplementation;);
0021 VECGEOM_DEVICE_DECLARE_CONV(struct, ExtrudedImplementation);
0022
0023 inline namespace VECGEOM_IMPL_NAMESPACE {
0024
0025 class PlacedExtruded;
0026 class ExtrudedStruct;
0027 class UnplacedExtruded;
0028
0029 struct ExtrudedImplementation {
0030
0031 using PlacedShape_t = PlacedExtruded;
0032 using UnplacedStruct_t = ExtrudedStruct;
0033 using UnplacedVolume_t = UnplacedExtruded;
0034
0035 template <typename Real_v, typename Bool_v>
0036 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Contains(UnplacedStruct_t const &extruded,
0037 Vector3D<Real_v> const &point, Bool_v &inside)
0038 {
0039 inside = false;
0040 if (extruded.fIsSxtru) {
0041 SExtruImplementation::Contains<Real_v, Bool_v>(extruded.fSxtruHelper, point, inside);
0042 return;
0043 }
0044
0045 #ifndef VECGEOM_ENABLE_CUDA
0046 if (extruded.fUseTslSections) {
0047
0048 int zIndex = extruded.FindZSegment(point[2]);
0049 if ((zIndex < 0) || (zIndex >= (int)extruded.GetNSegments())) return;
0050 inside = extruded.fTslSections[zIndex]->Contains(point);
0051 return;
0052 }
0053 #endif
0054 TessellatedImplementation::Contains<Real_v, Bool_v>(extruded.fTslHelper, point, inside);
0055 }
0056
0057 template <typename Real_v, typename Inside_v>
0058 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Inside(UnplacedStruct_t const &extruded,
0059 Vector3D<Real_v> const &point, Inside_v &inside)
0060 {
0061 inside = EInside::kOutside;
0062
0063 if (extruded.fIsSxtru) {
0064 SExtruImplementation::Inside<Real_v, Inside_v>(extruded.fSxtruHelper, point, inside);
0065 return;
0066 }
0067
0068 #ifndef VECGEOM_ENABLE_CUDA
0069 if (extruded.fUseTslSections) {
0070 const int nseg = (int)extruded.GetNSegments();
0071 int zIndex = extruded.FindZSegment(point[2]);
0072 if ((zIndex < 0) || (zIndex > nseg)) return;
0073 inside = extruded.fTslSections[Min(zIndex, nseg - 1)]->Inside(point);
0074 if (inside == EInside::kOutside) return;
0075 if (inside == EInside::kInside) {
0076
0077 if (((zIndex == 0) || (zIndex == nseg)) &&
0078 vecCore::math::Abs(point[2] - extruded.fZPlanes[zIndex]) < kTolerance) {
0079 inside = EInside::kSurface;
0080 }
0081 } else {
0082 inside = EInside::kSurface;
0083 }
0084 return;
0085 }
0086 #endif
0087 TessellatedImplementation::Inside<Real_v, Inside_v>(extruded.fTslHelper, point, inside);
0088 }
0089
0090 template <typename Real_v>
0091 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToIn(UnplacedStruct_t const &extruded,
0092 Vector3D<Real_v> const &point,
0093 Vector3D<Real_v> const &direction,
0094 Real_v const &stepMax, Real_v &distance)
0095 {
0096
0097 #ifdef EFFICIENT_TSL_DISTANCETOIN
0098 if (extruded.fUseTslSections) {
0099
0100 const Vector3D<Real_v> invdir(Real_v(1.0) / NonZero(direction.x()), Real_v(1.0) / NonZero(direction.y()),
0101 Real_v(1.0) / NonZero(direction.z()));
0102 Vector3D<int> sign;
0103 sign[0] = invdir.x() < 0;
0104 sign[1] = invdir.y() < 0;
0105 sign[2] = invdir.z() < 0;
0106 distance = BoxImplementation::IntersectCachedKernel2<Real_v, Real_v>(&extruded.fTslHelper.fMinExtent, point,
0107 invdir, sign.x(), sign.y(), sign.z(),
0108 -kTolerance, InfinityLength<Real_v>());
0109 if (distance >= stepMax) return;
0110
0111
0112
0113
0114
0115
0116 int zIndex = extruded.FindZSegment(point[2]);
0117 const int zMax = extruded.GetNSegments();
0118
0119
0120 bool fromOutZ =
0121 (point[2] < extruded.fZPlanes[0] + kTolerance) || (point[2] > extruded.fZPlanes[zMax] - kTolerance);
0122 zIndex = zIndex < 0 ? 0 : (zIndex >= zMax ? zMax - 1 : zIndex);
0123
0124
0125 bool goingRight = direction[2] >= 0;
0126
0127 distance = InfinityLength<Real_v>();
0128 if (goingRight) {
0129 for (int zSegCount = zMax; zIndex < zSegCount; ++zIndex) {
0130 bool skipZ = fromOutZ && (zSegCount == 0);
0131 if (skipZ)
0132 distance = extruded.fTslSections[zIndex]->DistanceToIn<true>(point, direction, invdir.z(), stepMax);
0133 else
0134 distance = extruded.fTslSections[zIndex]->DistanceToIn<false>(point, direction, invdir.z(), stepMax);
0135
0136
0137 if (distance >= -kTolerance && distance < InfinityLength<Precision>()) break;
0138 }
0139 } else {
0140
0141 for (; zIndex >= 0; --zIndex) {
0142 bool skipZ = fromOutZ && (zIndex == zMax);
0143 if (skipZ)
0144 distance = extruded.fTslSections[zIndex]->DistanceToIn<true>(point, direction, invdir.z(), stepMax);
0145 else
0146 distance = extruded.fTslSections[zIndex]->DistanceToIn<false>(point, direction, invdir.z(), stepMax);
0147
0148
0149 if (distance >= -kTolerance && distance < InfinityLength<Precision>()) break;
0150 }
0151 }
0152 }
0153 #endif
0154 if (extruded.fIsSxtru)
0155 SExtruImplementation::DistanceToIn<Real_v>(extruded.fSxtruHelper, point, direction, stepMax, distance);
0156 else
0157 TessellatedImplementation::DistanceToIn<Real_v>(extruded.fTslHelper, point, direction, stepMax, distance);
0158 }
0159
0160 template <typename Real_v>
0161 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToOut(UnplacedStruct_t const &extruded,
0162 Vector3D<Real_v> const &point,
0163 Vector3D<Real_v> const &direction,
0164 Real_v const &stepMax, Real_v &distance)
0165 {
0166 if (extruded.fIsSxtru)
0167 SExtruImplementation::DistanceToOut<Real_v>(extruded.fSxtruHelper, point, direction, stepMax, distance);
0168 else
0169 TessellatedImplementation::DistanceToOut<Real_v>(extruded.fTslHelper, point, direction, stepMax, distance);
0170 }
0171
0172 template <typename Real_v>
0173 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToIn(UnplacedStruct_t const &extruded,
0174 Vector3D<Real_v> const &point, Real_v &safety)
0175 {
0176 if (extruded.fIsSxtru)
0177 SExtruImplementation::SafetyToIn<Real_v>(extruded.fSxtruHelper, point, safety);
0178 else
0179 TessellatedImplementation::SafetyToIn<Real_v>(extruded.fTslHelper, point, safety);
0180 }
0181
0182 template <typename Real_v>
0183 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToOut(UnplacedStruct_t const &extruded,
0184 Vector3D<Real_v> const &point, Real_v &safety)
0185 {
0186 if (extruded.fIsSxtru)
0187 SExtruImplementation::SafetyToOut<Real_v>(extruded.fSxtruHelper, point, safety);
0188 else
0189 TessellatedImplementation::SafetyToOut<Real_v>(extruded.fTslHelper, point, safety);
0190 }
0191
0192 template <typename Real_v>
0193 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Vector3D<Real_v> NormalKernel(
0194 UnplacedStruct_t const &extruded, Vector3D<Real_v> const &point, typename vecCore::Mask_v<Real_v> &valid)
0195 {
0196
0197 if (extruded.fIsSxtru) return SExtruImplementation::NormalKernel<Real_v>(extruded.fSxtruHelper, point, valid);
0198 return TessellatedImplementation::NormalKernel<Real_v>(extruded.fTslHelper, point, valid);
0199 }
0200
0201 };
0202
0203 }
0204 }
0205
0206 #endif