File indexing completed on 2025-01-30 10:26:08
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef NAVIGATION_VOXELLEVELLOCATOR_H_
0009 #define NAVIGATION_VOXELLEVELLOCATOR_H_
0010
0011 #include "VecGeom/navigation/VLevelLocator.h"
0012 #include "VecGeom/volumes/LogicalVolume.h"
0013 #include "VecGeom/volumes/PlacedVolume.h"
0014 #include "VecGeom/management/FlatVoxelManager.h"
0015 #include "VecGeom/volumes/kernel/BoxImplementation.h"
0016 #include "VecGeom/navigation/SimpleLevelLocator.h"
0017 #include "VecGeom/management/ABBoxManager.h"
0018
0019 namespace vecgeom {
0020 inline namespace VECGEOM_IMPL_NAMESPACE {
0021
0022
0023
0024 template <bool IsAssemblyAware = false>
0025 class TVoxelLevelLocator : public VLevelLocator {
0026
0027 private:
0028 FlatVoxelManager &fAccelerationStructure;
0029
0030 TVoxelLevelLocator() : fAccelerationStructure(FlatVoxelManager::Instance()) {}
0031
0032
0033
0034
0035 template <bool ExclV, bool ModifyState>
0036 __attribute__((always_inline)) bool LevelLocateKernel(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0037 Vector3D<Precision> const &localpoint, NavigationState *state,
0038 VPlacedVolume const *&pvol,
0039 Vector3D<Precision> &daughterlocalpoint) const
0040 {
0041 const auto accstructure = fAccelerationStructure.GetStructure(lvol);
0042
0043 const auto locatevoxels = accstructure->fVoxelToLocateCandidates;
0044
0045 Vector3D<float> floatlocalpoint(localpoint.x(), localpoint.y(), localpoint.z());
0046
0047 int numbercandidates{0};
0048 const auto candidateidsptr = locatevoxels->getProperties(floatlocalpoint, numbercandidates);
0049
0050 if (numbercandidates > 0) {
0051
0052 int numberboxes{0};
0053 const auto boxes = ABBoxManager::Instance().GetABBoxes(lvol, numberboxes);
0054
0055 for (int i = 0; i < numbercandidates; ++i) {
0056 const int daughterid = candidateidsptr[i];
0057
0058
0059 VPlacedVolume const *candidate = lvol->GetDaughters()[daughterid];
0060 if (ExclV) {
0061 if (candidate == exclvol) continue;
0062 }
0063
0064
0065 const auto &lower = boxes[2 * daughterid];
0066 const auto &upper = boxes[2 * daughterid + 1];
0067 bool boxcontains{false};
0068 ABBoxImplementation::ABBoxContainsKernel(lower, upper, localpoint, boxcontains);
0069 if (!boxcontains) {
0070 continue;
0071 }
0072
0073
0074 if (CheckCandidateVol<IsAssemblyAware, ModifyState>(candidate, localpoint, state, pvol, daughterlocalpoint)) {
0075 return true;
0076 }
0077 }
0078 }
0079 return false;
0080 }
0081
0082
0083
0084
0085 template <bool ExclV, bool ModifyState>
0086 __attribute__((always_inline)) bool LevelLocateKernelWithDirection(LogicalVolume const *lvol,
0087 VPlacedVolume const *exclvol,
0088 Vector3D<Precision> const &localpoint,
0089 Vector3D<Precision> const &localdir,
0090 NavigationState *state, VPlacedVolume const *&pvol,
0091 Vector3D<Precision> &daughterlocalpoint) const
0092 {
0093 const auto accstructure = fAccelerationStructure.GetStructure(lvol);
0094
0095 const auto locatevoxels = accstructure->fVoxelToLocateCandidates;
0096
0097 Vector3D<float> floatlocalpoint(localpoint.x(), localpoint.y(), localpoint.z());
0098
0099 int numbercandidates{0};
0100 const auto candidateidsptr = locatevoxels->getProperties(floatlocalpoint, numbercandidates);
0101
0102 if (numbercandidates > 0) {
0103
0104 int numberboxes{0};
0105 const auto boxes = ABBoxManager::Instance().GetABBoxes(lvol, numberboxes);
0106
0107 for (int i = 0; i < numbercandidates; ++i) {
0108 const int daughterid = candidateidsptr[i];
0109
0110
0111 VPlacedVolume const *candidate = lvol->GetDaughters()[daughterid];
0112 if (ExclV) {
0113 if (candidate == exclvol) continue;
0114 }
0115
0116
0117 const auto &lower = boxes[2 * daughterid];
0118 const auto &upper = boxes[2 * daughterid + 1];
0119 bool boxcontains{false};
0120 ABBoxImplementation::ABBoxContainsKernel(lower, upper, localpoint, boxcontains);
0121 if (!boxcontains) {
0122 continue;
0123 }
0124
0125
0126 if (CheckCandidateVolWithDirection<IsAssemblyAware, ModifyState>(candidate, localpoint, localdir, state, pvol,
0127 daughterlocalpoint)) {
0128 return true;
0129 }
0130 }
0131 }
0132 return false;
0133 }
0134
0135 public:
0136 static std::string GetClassName() { return "VoxelLevelLocator"; }
0137 std::string GetName() const override { return GetClassName(); }
0138
0139 bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0140 Vector3D<Precision> &daughterlocalpoint) const override
0141 {
0142 return LevelLocateKernel<false, false>(lvol, nullptr, localpoint, nullptr, pvol, daughterlocalpoint);
0143 }
0144
0145 bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, NavigationState &state,
0146 Vector3D<Precision> &daughterlocalpoint) const override
0147 {
0148 VPlacedVolume const *pvol;
0149 return LevelLocateKernel<false, true>(lvol, nullptr, localpoint, &state, pvol, daughterlocalpoint);
0150 }
0151
0152 bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0153 Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0154 Vector3D<Precision> &daughterlocalpoint) const override
0155 {
0156 return LevelLocateKernel<true, false>(lvol, exclvol, localpoint, nullptr, pvol, daughterlocalpoint);
0157 }
0158
0159 bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0160 Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdir,
0161 VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint) const override
0162 {
0163 return LevelLocateKernelWithDirection<true, false>(lvol, exclvol, localpoint, localdir, nullptr, pvol,
0164 daughterlocalpoint);
0165 }
0166
0167 static VLevelLocator const *GetInstance()
0168 {
0169 static TVoxelLevelLocator instance;
0170 return &instance;
0171 }
0172
0173 };
0174
0175 template <>
0176 inline std::string TVoxelLevelLocator<true>::GetClassName()
0177 {
0178 return "AssemblyAwareVoxelLevelLocator";
0179 }
0180 }
0181 }
0182
0183 #endif