File indexing completed on 2025-01-18 10:13:59
0001
0002
0003
0004
0005 #ifndef BOOLEANIMPLEMENTATION_H_
0006 #define BOOLEANIMPLEMENTATION_H_
0007
0008 #include "VecGeom/base/Vector3D.h"
0009 #include "VecGeom/volumes/BooleanStruct.h"
0010 #include <VecCore/VecCore>
0011
0012 namespace vecgeom {
0013
0014 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1v(struct, BooleanImplementation, BooleanOperation, Arg1);
0015
0016 inline namespace VECGEOM_IMPL_NAMESPACE {
0017
0018 template <BooleanOperation Op>
0019 class PlacedBooleanVolume;
0020 template <BooleanOperation Op>
0021 class UnplacedBooleanVolume;
0022
0023 template <BooleanOperation boolOp>
0024 struct BooleanImplementation {
0025 using PlacedShape_t = PlacedBooleanVolume<boolOp>;
0026 using UnplacedVolume_t = UnplacedBooleanVolume<boolOp>;
0027 using UnplacedStruct_t = BooleanStruct;
0028
0029
0030
0031 };
0032
0033
0034
0035
0036
0037
0038
0039 template <>
0040 struct BooleanImplementation<kSubtraction> {
0041 using PlacedShape_t = PlacedBooleanVolume<kSubtraction>;
0042 using UnplacedVolume_t = UnplacedBooleanVolume<kSubtraction>;
0043 using UnplacedStruct_t = BooleanStruct;
0044
0045 VECCORE_ATT_HOST_DEVICE
0046 static void PrintType()
0047 {
0048 }
0049
0050 template <typename Stream>
0051 static void PrintType(Stream &s)
0052 {
0053
0054
0055
0056 }
0057
0058 template <typename Stream>
0059 static void PrintType(Stream &st, int transCodeT = translation::kGeneric, int rotCodeT = rotation::kGeneric)
0060 {
0061 st << "SpecializedBooleanVolume<kSubtraction" << transCodeT << "," << rotCodeT << ">";
0062 }
0063
0064 template <typename Stream>
0065 static void PrintImplementationType(Stream &s)
0066 {
0067
0068
0069
0070
0071 }
0072
0073 template <typename Stream>
0074 static void PrintUnplacedType(Stream &s)
0075 {
0076 s << "BooleanStruct";
0077 }
0078
0079 template <typename Real_v, typename Bool_v>
0080 VECGEOM_FORCE_INLINE
0081 VECCORE_ATT_HOST_DEVICE
0082 static void Contains(BooleanStruct const &unplaced, Vector3D<Real_v> const &point, Bool_v &inside)
0083 {
0084 Vector3D<Real_v> tmp;
0085 inside = unplaced.fLeftVolume->Contains(point);
0086 if (vecCore::MaskEmpty(inside)) return;
0087
0088 auto rightInside = unplaced.fRightVolume->Contains(point);
0089 inside &= !rightInside;
0090 }
0091
0092 template <typename Real_v, typename Inside_t>
0093 VECGEOM_FORCE_INLINE
0094 VECCORE_ATT_HOST_DEVICE
0095 static void Inside(BooleanStruct const &unplaced, Vector3D<Real_v> const &p, Inside_t &inside)
0096 {
0097
0098
0099
0100 VPlacedVolume const *const fPtrSolidA = unplaced.fLeftVolume;
0101 VPlacedVolume const *const fPtrSolidB = unplaced.fRightVolume;
0102
0103 const auto positionA = fPtrSolidA->Inside(p);
0104 if (positionA == EInside::kOutside) {
0105 inside = EInside::kOutside;
0106 return;
0107 }
0108
0109 const auto positionB = fPtrSolidB->Inside(p);
0110
0111 if (positionA == EInside::kInside && positionB == EInside::kOutside) {
0112 inside = EInside::kInside;
0113 return;
0114 } else {
0115 if ((positionA == EInside::kInside && positionB == EInside::kSurface) ||
0116 (positionB == EInside::kOutside && positionA == EInside::kSurface)
0117
0118
0119
0120
0121
0122 ) {
0123 inside = EInside::kSurface;
0124 return;
0125 } else {
0126 inside = EInside::kOutside;
0127 return;
0128 }
0129 }
0130
0131 }
0132
0133 template <typename Real_v>
0134 VECGEOM_FORCE_INLINE
0135 VECCORE_ATT_HOST_DEVICE
0136 static void DistanceToIn(BooleanStruct const &unplaced, Vector3D<Real_v> const &p, Vector3D<Real_v> const &dir,
0137 Real_v const &stepMax, Real_v &distance)
0138 {
0139
0140
0141
0142 Real_v d1, d2, snxt = 0.;
0143 Vector3D<Real_v> hitpoint = p;
0144
0145 auto insideRight = unplaced.fRightVolume->Contains(p);
0146
0147 Precision epsil(kPushTolerance);
0148
0149
0150
0151 while (1) {
0152 if (insideRight) {
0153
0154 d1 = unplaced.fRightVolume->PlacedDistanceToOut(hitpoint, dir, stepMax);
0155 snxt += (d1 >= 0. && d1 < kInfLength) ? (d1 + epsil) : 0.;
0156 hitpoint += (d1 >= 0. && d1 < kInfLength) ? (d1 + epsil) * dir : 0. * dir;
0157
0158
0159
0160 if (unplaced.fLeftVolume->Contains(hitpoint)) {
0161 auto check = unplaced.fLeftVolume->PlacedDistanceToOut(hitpoint, dir);
0162 if (check > epsil) {
0163 distance = snxt;
0164
0165 return;
0166 }
0167 }
0168 }
0169
0170
0171
0172
0173 d2 = unplaced.fLeftVolume->DistanceToIn(hitpoint, dir, stepMax);
0174 d2 = Max(d2, Precision(0.));
0175 if (d2 == kInfLength) {
0176 distance = kInfLength;
0177
0178 return;
0179 }
0180
0181 d1 = unplaced.fRightVolume->DistanceToIn(hitpoint, dir, stepMax);
0182 if (d2 < d1 - kTolerance) {
0183 snxt += d2 + epsil;
0184
0185 distance = snxt;
0186 return;
0187 }
0188
0189
0190 snxt += (d1 >= 0. && d1 < kInfLength) ? d1 + epsil : 0.;
0191 hitpoint += (d1 >= 0. && d1 < kInfLength) ? (d1 + epsil) * dir : epsil * dir;
0192 insideRight = true;
0193 }
0194 }
0195
0196 template <typename Real_v>
0197 VECGEOM_FORCE_INLINE
0198 VECCORE_ATT_HOST_DEVICE
0199 static void DistanceToOut(BooleanStruct const &unplaced, Vector3D<Real_v> const &point,
0200 Vector3D<Real_v> const &direction, Real_v const &stepMax, Real_v &distance)
0201 {
0202 const auto distancel = unplaced.fLeftVolume->PlacedDistanceToOut(point, direction, stepMax);
0203 const Real_v dinright = unplaced.fRightVolume->DistanceToIn(point, direction, stepMax);
0204 distance = Min(distancel, dinright);
0205 return;
0206 }
0207
0208 template <typename Real_v>
0209 VECGEOM_FORCE_INLINE
0210 VECCORE_ATT_HOST_DEVICE
0211 static void SafetyToIn(BooleanStruct const &unplaced, Vector3D<Real_v> const &point, Real_v &safety)
0212 {
0213 VPlacedVolume const *const fPtrSolidA = unplaced.fLeftVolume;
0214 VPlacedVolume const *const fPtrSolidB = unplaced.fRightVolume;
0215
0216
0217 if ((fPtrSolidA->Contains(point)) &&
0218 (fPtrSolidB->Contains(point))) {
0219 safety = fPtrSolidB->SafetyToOut(fPtrSolidB->GetTransformation()->Transform(point));
0220 } else {
0221
0222 safety = fPtrSolidA->SafetyToIn(point);
0223 }
0224 }
0225
0226 template <typename Real_v>
0227 VECGEOM_FORCE_INLINE
0228 VECCORE_ATT_HOST_DEVICE
0229 static void SafetyToOut(BooleanStruct const &unplaced, Vector3D<Real_v> const &point, Real_v &safety)
0230 {
0231 const auto safetyleft = unplaced.fLeftVolume->SafetyToOut(point);
0232 const auto safetyright = unplaced.fRightVolume->SafetyToIn(point);
0233 safety = Min(safetyleft, safetyright);
0234 }
0235
0236 template <typename Real_v, typename Bool_v>
0237 VECGEOM_FORCE_INLINE
0238 VECCORE_ATT_HOST_DEVICE
0239 static void NormalKernel(BooleanStruct const &unplaced, Vector3D<Real_v> const &point, Vector3D<Real_v> &normal,
0240 Bool_v &valid)
0241 {
0242 Vector3D<Real_v> localNorm;
0243 Vector3D<Real_v> localPoint;
0244 valid = false;
0245
0246 VPlacedVolume const *const fPtrSolidA = unplaced.fLeftVolume;
0247 VPlacedVolume const *const fPtrSolidB = unplaced.fRightVolume;
0248
0249
0250 if (fPtrSolidB->Contains(point)) {
0251 fPtrSolidB->GetTransformation()->Transform(point, localPoint);
0252 valid = fPtrSolidB->Normal(localPoint, localNorm);
0253
0254 localNorm *= -1.;
0255 fPtrSolidB->GetTransformation()->InverseTransformDirection(localNorm, normal);
0256 return;
0257 }
0258
0259
0260 if (!fPtrSolidA->Contains(point)) {
0261 fPtrSolidA->GetTransformation()->Transform(point, localPoint);
0262 valid = fPtrSolidA->Normal(localPoint, localNorm);
0263 fPtrSolidA->GetTransformation()->InverseTransformDirection(localNorm, normal);
0264 return;
0265 }
0266
0267
0268 fPtrSolidA->GetTransformation()->Transform(point, localPoint);
0269 Real_v safetyA = fPtrSolidA->SafetyToOut(localPoint);
0270 Real_v safetyB = fPtrSolidB->SafetyToIn(point);
0271 Bool_v onA = safetyA < safetyB;
0272 if (vecCore::MaskFull(onA)) {
0273 valid = fPtrSolidA->Normal(localPoint, localNorm);
0274 fPtrSolidA->GetTransformation()->InverseTransformDirection(localNorm, normal);
0275 return;
0276 } else {
0277
0278 fPtrSolidB->GetTransformation()->Transform(point, localPoint);
0279 valid = fPtrSolidB->Normal(localPoint, localNorm);
0280
0281 localNorm *= -1.;
0282 fPtrSolidB->GetTransformation()->InverseTransformDirection(localNorm, normal);
0283 return;
0284 }
0285
0286
0287 return;
0288 }
0289
0290 };
0291
0292 }
0293
0294 }
0295
0296
0297 #include "BooleanUnionImplementation.h"
0298
0299
0300 #include "BooleanIntersectionImplementation.h"
0301
0302 #endif