File indexing completed on 2025-01-18 10:13:57
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef NAVIGATION_GLOBALLOCATOR_H_
0009 #define NAVIGATION_GLOBALLOCATOR_H_
0010
0011 #include "VecGeom/base/Global.h"
0012 #include "VecGeom/base/Vector3D.h"
0013 #include "VecGeom/volumes/LogicalVolume.h"
0014 #include "VecGeom/navigation/VLevelLocator.h"
0015 #include "VecGeom/navigation/NavigationState.h"
0016
0017 namespace vecgeom {
0018 inline namespace VECGEOM_IMPL_NAMESPACE {
0019
0020 class LogicalVolume;
0021 class VPlacedVolume;
0022
0023
0024
0025
0026
0027
0028 namespace GlobalLocator {
0029
0030
0031
0032
0033 VECGEOM_FORCE_INLINE
0034 VECCORE_ATT_HOST_DEVICE
0035 VPlacedVolume const *LocateGlobalPoint(VPlacedVolume const *vol, Vector3D<Precision> const &point,
0036 NavigationState &path, bool top)
0037 {
0038 VPlacedVolume const *candvolume = vol;
0039 Vector3D<Precision> currentpoint(point);
0040 if (top) {
0041 assert(vol != nullptr);
0042 candvolume = (vol->UnplacedContains(point)) ? vol : nullptr;
0043 }
0044 if (candvolume) {
0045 path.Push(candvolume);
0046 LogicalVolume const *lvol = candvolume->GetLogicalVolume();
0047 Vector<Daughter> const *daughters = lvol->GetDaughtersp();
0048
0049 bool godeeper = true;
0050 while (daughters->size() > 0 && godeeper) {
0051
0052 VLevelLocator const *locator = lvol->GetLevelLocator();
0053 if (locator != nullptr) {
0054 Vector3D<Precision> transformedpoint;
0055 godeeper = locator->LevelLocate(lvol, currentpoint, path, transformedpoint);
0056 if (godeeper) {
0057 candvolume = path.Top();
0058 lvol = candvolume->GetLogicalVolume();
0059 daughters = lvol->GetDaughtersp();
0060 currentpoint = transformedpoint;
0061 }
0062 } else {
0063
0064 godeeper = true;
0065 for (size_t i = 0; i < daughters->size() && godeeper; ++i) {
0066 VPlacedVolume const *nextvolume = (*daughters)[i];
0067 Vector3D<Precision> transformedpoint;
0068 if (nextvolume->Contains(currentpoint, transformedpoint)) {
0069 path.Push(nextvolume);
0070 currentpoint = transformedpoint;
0071 candvolume = nextvolume;
0072 daughters = candvolume->GetLogicalVolume()->GetDaughtersp();
0073 godeeper = true;
0074 break;
0075 }
0076 }
0077 godeeper = false;
0078 }
0079 }
0080 }
0081 return candvolume ? path.Top() : nullptr;
0082 }
0083
0084
0085
0086 VECGEOM_FORCE_INLINE
0087 VECCORE_ATT_HOST_DEVICE
0088 VPlacedVolume const *LocateGlobalPointExclVolume(VPlacedVolume const *vol, VPlacedVolume const *excludedvolume,
0089 Vector3D<Precision> const &point, NavigationState &path, bool top)
0090 {
0091 VPlacedVolume const *candvolume = vol;
0092 Vector3D<Precision> currentpoint(point);
0093 if (top) {
0094 assert(vol != nullptr);
0095 candvolume = (vol->UnplacedContains(point)) ? vol : nullptr;
0096 }
0097 if (candvolume) {
0098 path.Push(candvolume);
0099 LogicalVolume const *lvol = candvolume->GetLogicalVolume();
0100 Vector<Daughter> const *daughters = lvol->GetDaughtersp();
0101
0102 bool godeeper = true;
0103 while (daughters->size() > 0 && godeeper) {
0104 godeeper = false;
0105
0106 VLevelLocator const *locator = lvol->GetLevelLocator();
0107 if (locator != nullptr) {
0108 Vector3D<Precision> transformedpoint;
0109 godeeper = locator->LevelLocateExclVol(lvol, excludedvolume, currentpoint, candvolume, transformedpoint);
0110 if (godeeper) {
0111 lvol = candvolume->GetLogicalVolume();
0112 daughters = lvol->GetDaughtersp();
0113 currentpoint = transformedpoint;
0114 path.Push(candvolume);
0115 }
0116 } else {
0117 for (size_t i = 0; i < daughters->size(); ++i) {
0118 VPlacedVolume const *nextvolume = (*daughters)[i];
0119 if (nextvolume != excludedvolume) {
0120 Vector3D<Precision> transformedpoint;
0121 if (nextvolume->Contains(currentpoint, transformedpoint)) {
0122 path.Push(nextvolume);
0123 currentpoint = transformedpoint;
0124 candvolume = nextvolume;
0125 daughters = candvolume->GetLogicalVolume()->GetDaughtersp();
0126 godeeper = true;
0127 break;
0128 }
0129 }
0130 }
0131 }
0132 }
0133 }
0134 return candvolume;
0135 }
0136
0137 VECGEOM_FORCE_INLINE
0138 VECCORE_ATT_HOST_DEVICE
0139 static VPlacedVolume const *RelocatePointFromPath(Vector3D<Precision> const &localpoint, NavigationState &path)
0140 {
0141
0142
0143
0144
0145 VPlacedVolume const *currentmother = path.Top();
0146 if (currentmother != nullptr) {
0147 Vector3D<Precision> tmp = localpoint;
0148 while (currentmother) {
0149 if (currentmother->GetLogicalVolume()->GetUnplacedVolume()->IsAssembly() ||
0150 !currentmother->UnplacedContains(tmp)) {
0151 path.Pop();
0152 Vector3D<Precision> pointhigherup = currentmother->GetTransformation()->InverseTransform(tmp);
0153 tmp = pointhigherup;
0154 currentmother = path.Top();
0155 } else {
0156 break;
0157 }
0158 }
0159
0160 if (currentmother) {
0161 path.Pop();
0162 return LocateGlobalPoint(currentmother, tmp, path, false);
0163 }
0164 }
0165 return currentmother;
0166 }
0167
0168
0169 VECGEOM_FORCE_INLINE
0170 VECCORE_ATT_HOST_DEVICE
0171 static VPlacedVolume const *RelocatePointFromPathForceDifferent(Vector3D<Precision> const &localpoint,
0172 NavigationState &path)
0173 {
0174
0175
0176
0177
0178 VPlacedVolume const *currentmother = path.Top();
0179 VPlacedVolume const *entryvol = currentmother;
0180 if (currentmother != nullptr) {
0181 Vector3D<Precision> tmp = localpoint;
0182 while (currentmother) {
0183 if (currentmother == entryvol || currentmother->GetLogicalVolume()->GetUnplacedVolume()->IsAssembly() ||
0184 !currentmother->UnplacedContains(tmp)) {
0185 path.Pop();
0186 Vector3D<Precision> pointhigherup = currentmother->GetTransformation()->InverseTransform(tmp);
0187 tmp = pointhigherup;
0188 currentmother = path.Top();
0189 } else {
0190 break;
0191 }
0192 }
0193
0194 if (currentmother) {
0195 path.Pop();
0196 return LocateGlobalPointExclVolume(currentmother, entryvol, tmp, path, false);
0197 }
0198 }
0199 return currentmother;
0200 }
0201
0202 VECCORE_ATT_HOST_DEVICE
0203 VECGEOM_FORCE_INLINE
0204 bool HasSamePath(Vector3D<Precision> const &globalpoint, Transformation3D const &globaltransf,
0205 NavigationState const ¤tstate, NavigationState &newstate)
0206 {
0207 Vector3D<Precision> localpoint = globaltransf.Transform(globalpoint);
0208 currentstate.CopyTo(&newstate);
0209 RelocatePointFromPath(localpoint, newstate);
0210 return currentstate.HasSamePathAsOther(newstate);
0211 }
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 VECCORE_ATT_HOST_DEVICE
0223 inline bool HasSamePath(Vector3D<Precision> const &globalpoint, NavigationState const ¤tstate,
0224 NavigationState &newstate)
0225 {
0226 Transformation3D m;
0227 currentstate.TopMatrix(m);
0228 return HasSamePath(globalpoint, m, currentstate, newstate);
0229 }
0230
0231 }
0232 }
0233 }
0234
0235 #endif