Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-17 08:35:37

0001 #ifndef VECGEOM_SURFDATA_H_
0002 #define VECGEOM_SURFDATA_H_
0003 
0004 #include <VecGeom/surfaces/Model.h>
0005 #include <VecGeom/base/BVH.h>
0006 #include <VecGeom/base/BVH.h>
0007 
0008 namespace vgbrep {
0009 
0010 /*
0011  * The main surface storage utility, providing access by index to:
0012  *    * global and local transformations applied to surfaces
0013  *    * surface data per surface type
0014  *    * mask data per mask type
0015  *    * imprint data (list of masks)
0016  */
0017 template <typename Real_t>
0018 struct SurfData {
0019 
0020   // BVH internal precision
0021 #ifdef VECGEOM_BVH_SINGLE
0022   using Real_b = float;
0023 #else
0024   using Real_b = double;
0025 #endif
0026   using EllipData_t    = EllipData<Real_t>;
0027   using TorusData_t    = TorusData<Real_t>;
0028   using Arb4Data_t     = Arb4Data<Real_t>;
0029   using WindowMask_t   = WindowMask<Real_t>;
0030   using RingMask_t     = RingMask<Real_t>;
0031   using ZPhiMask_t     = ZPhiMask<Real_t>;
0032   using TriangleMask_t = TriangleMask<Real_t>;
0033   using QuadMask_t     = QuadrilateralMask<Real_t>;
0034   using SideDivision_t = SideDivision<Real_t>;
0035 
0036   int fNscenes{0};
0037 
0038   int fNvolTrans{0};
0039   int fNlocalSurf{0};
0040   int fNExitingSurfaces{0};
0041   int fNEnteringSurfaces{0};
0042   int fNglobalSurf{0};
0043   int fNellip{0};
0044   int fNtorus{0};
0045   int fNarb4{0};
0046   int fNcommonSurf{0};
0047   int fNsides{0};
0048   int fNStates{0};
0049   int fSizeCandList{0};
0050   int fNshells{0};
0051   int fNlogic{0};
0052   int fNrange{0};
0053   int fNwindows{0};
0054   int fNrings{0};
0055   int fNzphis{0};
0056   int fNtriangs{0};
0057   int fNquads{0};
0058   int fNsideDivisions{0};
0059   int fNslices{0};
0060   int fNsliceCandidates{0};
0061   int fNPlacedVolumes{0};
0062 
0063   int *fSceneStartIndex{nullptr}; ///< Start indices for data indexed by state id (per scene)
0064   int *fSceneTouchables{nullptr}; ///< Number of touchables (per scene)
0065 
0066   /// Transformations.
0067   TransformationMP<Real_t> *fPVolTrans{nullptr}; ///< Transformations to placed volumes
0068 
0069   /// Volume shells, indexed by the logical volume id
0070   VolumeShell *fShells{nullptr}; ///< volume shells
0071 
0072   // Local and global framed surfaces
0073   FramedSurface<Real_t, TransformationMP<Real_t>> *fLocalSurf{nullptr};             ///< local surfaces
0074   FramedSurface<Real_t, vecgeom::Transformation2DMP<Real_t>> *fFramedSurf{nullptr}; ///< global surfaces
0075 
0076   EllipData_t *fEllipData{nullptr}; ///< Elliptical data
0077   TorusData_t *fTorusData{nullptr}; ///< Torus data
0078   Arb4Data_t *fArb4Data{nullptr};   ///< Arb4 data
0079 
0080   // Frame data
0081   WindowMask_t *fWindowMasks{nullptr};             ///< rectangular masks
0082   RingMask_t *fRingMasks{nullptr};                 ///< ring masks
0083   ZPhiMask_t *fZPhiMasks{nullptr};                 ///< cylindrical masks
0084   TriangleMask_t *fTriangleMasks{nullptr};         ///< triangular masks
0085   QuadMask_t *fQuadMasks{nullptr};                 ///< quadrilateral masks
0086   CommonSurface<Real_t> *fCommonSurfaces{nullptr}; ///< common surfaces
0087   Candidates *fCandidates;                         ///< candidate surfaces per navigation state
0088   int *fSides{nullptr};                            ///< side surface indices
0089   SideDivision_t *fSideDivisions{nullptr};         ///< [fNsideDivisions] side division helpers
0090   SliceCand *fSlices{nullptr};                     ///< [fNslices] slice candidates
0091   int *fSliceCandidates{nullptr};                  ///< [fNsliceCandidates] frame indices for all slice candidates
0092   int *fSurfShellList{nullptr};                    ///< indices of local surfaces used in shells
0093   logic_int *fLogicList{nullptr};                  ///< list of logic expressions per volume
0094   int *fCandList{nullptr};                         ///< global list of candidate indices
0095   int *fShellExitingSurfaceList{nullptr};          ///< List of surfaces of a volume, having a frame
0096   int *fShellEnteringSurfaceList{nullptr};         ///< List of surfaces of the daughters of a volume, having a frame
0097   int *fShellEnteringSurfacePvolList{nullptr};     ///< Id of the PlacedVolume each entering surface belongs to
0098   int *fShellEnteringSurfacePvolTransList{
0099       nullptr};                                  ///< Id of the volume transformation each entering surface belongs to
0100   int *fShellEnteringSurfaceLvolIdList{nullptr}; ///< Id of the logical volume each entering surface belongs to
0101   int *fShellDaughterPvolIdList{nullptr};        ///< Global PV Ids of the daughter PVs of each Volume
0102   int *fShellDaughterPvolTransList{nullptr};     ///< Transformations of the daughter PVs of each Volume
0103   vecgeom::BVH<Real_b> *fBVH{
0104       nullptr}; ///< BVH per volume shell, built from the AABBs of its entering and exiting surfaces
0105   vecgeom::BVH<Real_b> *fBVHSolids{nullptr}; ///< BVH per volume shell, built from the AABBs of the daughter volumes
0106 
0107   SurfData() = default;
0108 
0109   VECCORE_ATT_HOST_DEVICE
0110   VECGEOM_FORCE_INLINE
0111   static SurfData<Real_t> &Instance()
0112   {
0113 #ifdef VECCORE_CUDA_DEVICE_COMPILATION
0114     return *globaldevicesurfdata::gSurfDataDevice<Real_t>;
0115 #else
0116     static SurfData<Real_t> gSurfData;
0117     return gSurfData;
0118 #endif
0119   }
0120 
0121   VECCORE_ATT_HOST_DEVICE
0122   void Clear()
0123   {
0124     delete[] fWindowMasks;
0125     fWindowMasks = nullptr;
0126     delete[] fRingMasks;
0127     fRingMasks = nullptr;
0128     delete[] fZPhiMasks;
0129     fZPhiMasks = nullptr;
0130     delete[] fQuadMasks;
0131     fQuadMasks = nullptr;
0132     delete[] fTriangleMasks;
0133     fTriangleMasks = nullptr;
0134     delete[] fEllipData;
0135     fEllipData = nullptr;
0136     delete[] fTorusData;
0137     fTorusData = nullptr;
0138     delete[] fArb4Data;
0139     fArb4Data = nullptr;
0140     delete[] fFramedSurf;
0141     fFramedSurf = nullptr;
0142     delete[] fSides;
0143     fSides = nullptr;
0144     delete[] fSideDivisions;
0145     fSideDivisions = nullptr;
0146     delete[] fSlices;
0147     fSlices = nullptr;
0148     delete[] fSliceCandidates;
0149     fSliceCandidates = nullptr;
0150     delete[] fCommonSurfaces;
0151     fCommonSurfaces = nullptr;
0152     delete[] fCandList;
0153     fCandList = nullptr;
0154     delete[] fCandidates;
0155     fCandidates = nullptr;
0156     delete[] fLocalSurf;
0157     fLocalSurf = nullptr;
0158     delete[] fShells;
0159     fShells = nullptr;
0160     delete[] fSurfShellList;
0161     fSurfShellList = nullptr;
0162     delete[] fLogicList;
0163     fLogicList = nullptr;
0164     delete[] fShellExitingSurfaceList;
0165     fShellExitingSurfaceList = nullptr;
0166     delete[] fShellEnteringSurfaceList;
0167     fShellEnteringSurfaceList = nullptr;
0168     delete[] fShellEnteringSurfacePvolList;
0169     fShellEnteringSurfacePvolList = nullptr;
0170     delete[] fShellEnteringSurfacePvolTransList;
0171     fShellEnteringSurfacePvolTransList = nullptr;
0172     delete[] fShellEnteringSurfaceLvolIdList;
0173     fShellEnteringSurfaceLvolIdList = nullptr;
0174     delete[] fShellDaughterPvolIdList;
0175     fShellDaughterPvolIdList = nullptr;
0176     delete[] fBVH;
0177     fBVH = nullptr;
0178   }
0179 
0180   VECCORE_ATT_HOST_DEVICE
0181   VECGEOM_FORCE_INLINE
0182   Candidates const &GetCandidates(int scene_id, int state_id) const
0183   {
0184     return fCandidates[fSceneStartIndex[scene_id] + state_id];
0185   }
0186 
0187   /// Surface data accessors by component id
0188   VECCORE_ATT_HOST_DEVICE
0189   VECGEOM_FORCE_INLINE
0190   EllipData_t const &GetEllipData(int id) const { return fEllipData[id]; }
0191   VECCORE_ATT_HOST_DEVICE
0192   VECGEOM_FORCE_INLINE
0193   TorusData_t const &GetTorusData(int id) const { return fTorusData[id]; }
0194   VECCORE_ATT_HOST_DEVICE
0195   VECGEOM_FORCE_INLINE
0196   Arb4Data_t const &GetArb4Data(int id) const { return fArb4Data[id]; }
0197   VECCORE_ATT_HOST_DEVICE
0198   VECGEOM_FORCE_INLINE
0199   WindowMask_t const &GetWindowMask(int id) const { return fWindowMasks[id]; }
0200   VECCORE_ATT_HOST_DEVICE
0201   VECGEOM_FORCE_INLINE
0202   RingMask_t const &GetRingMask(int id) const { return fRingMasks[id]; }
0203   VECCORE_ATT_HOST_DEVICE
0204   VECGEOM_FORCE_INLINE
0205   ZPhiMask_t const &GetZPhiMask(int id) const { return fZPhiMasks[id]; }
0206   VECCORE_ATT_HOST_DEVICE
0207   VECGEOM_FORCE_INLINE
0208   TriangleMask_t const &GetTriangleMask(int id) const { return fTriangleMasks[id]; }
0209   VECCORE_ATT_HOST_DEVICE
0210   VECGEOM_FORCE_INLINE
0211   QuadMask_t const &GetQuadMask(int id) const { return fQuadMasks[id]; }
0212 
0213   // Accessors by common surface id
0214   VECCORE_ATT_HOST_DEVICE
0215   VECGEOM_FORCE_INLINE
0216   UnplacedSurface<Real_t> const &GetUnplaced(int isurf, bool &flipped) const
0217   {
0218     FramedSurface<Real_t, vecgeom::Transformation2DMP<Real_t>> const &framedsurf =
0219         fFramedSurf[fCommonSurfaces[isurf].fLeftSide.fSurfaces[0]];
0220     flipped = fCommonSurfaces[isurf].fFlipped;
0221     return framedsurf.fSurface;
0222   }
0223 
0224   // Accessors by FSlocator
0225 
0226   /// @brief Get framed surface pointed by a locator
0227   /// @param locator Frame locator
0228   /// @return Frame pointed by the locator
0229   VECCORE_ATT_HOST_DEVICE
0230   VECGEOM_FORCE_INLINE
0231   FramedSurface<Real_t, vecgeom::Transformation2DMP<Real_t>> const &GetFramedSurface(FSlocator const &locator) const
0232   {
0233     auto const &surf = fCommonSurfaces[locator.GetCSindex()];
0234     auto const &side = locator.IsLeftSide() ? surf.fLeftSide : surf.fRightSide;
0235     VECGEOM_ASSERT(locator.GetCSindex() == 0 ||
0236                    (locator.frame_id >= 0 && locator.frame_id < side.fNsurf)); // Wrong locator
0237     return fFramedSurf[side.fSurfaces[locator.frame_id]];
0238   }
0239 
0240   /// @brief Deduce overlap of framed surface from a locator
0241   /// @param locator Frame locator
0242   /// @return Frame pointed by the locator
0243   VECCORE_ATT_HOST_DEVICE
0244   VECGEOM_FORCE_INLINE
0245   bool IsFSOverlapping(FSlocator const &locator) const
0246   {
0247     // frame surf id -1 indicates an extruding overlap, nonetheless, we must return false here,
0248     // so the overlap can be detected properly and the true position can be found. // fixme maybe we can improve the
0249     // logic in testRaytracing.cpp
0250     if (locator.GetFSindex() == -1) return false;
0251     auto const &framedsurf = GetFramedSurface(locator);
0252     return framedsurf.fOverlapping;
0253   }
0254 
0255   /// @brief Deduce state of framed surface from a locator
0256   /// @param locator Frame locator
0257   /// @return Frame pointed by the locator
0258   VECCORE_ATT_HOST_DEVICE
0259   VECGEOM_FORCE_INLINE
0260   int FramedSurfaceState(FSlocator const &locator) const
0261   {
0262     auto const &framedsurf = GetFramedSurface(locator);
0263     return framedsurf.fState;
0264   }
0265 
0266   /// @brief Deduce LogicId of framed surface from a locator
0267   /// @param locator Frame locator
0268   /// @return Frame pointed by the locator
0269   VECCORE_ATT_HOST_DEVICE
0270   VECGEOM_FORCE_INLINE
0271   int FramedSurfaceLogicId(FSlocator const &locator) const
0272   {
0273     if (locator.GetFSindex() == -1) return 0;
0274     auto const &framedsurf = GetFramedSurface(locator);
0275     return framedsurf.fLogicId;
0276   }
0277 
0278   /// @brief Check if framed surface from a locator is embedded
0279   /// @param locator Frame locator
0280   /// @return Frame pointed by the locator
0281   VECCORE_ATT_HOST_DEVICE
0282   VECGEOM_FORCE_INLINE
0283   bool IsFramedSurfaceEmbedded(FSlocator const &locator) const
0284   {
0285     auto const &framedsurf = GetFramedSurface(locator);
0286     return framedsurf.fEmbedded;
0287   }
0288 
0289   /// @brief Check if framed surface from a locator is embedded
0290   /// @param locator Frame locator
0291   /// @return Frame pointed by the locator
0292   VECCORE_ATT_HOST_DEVICE
0293   VECGEOM_FORCE_INLINE
0294   int FramedSurfaceParentInd(FSlocator const &locator) const
0295   {
0296     auto const &framedsurf = GetFramedSurface(locator);
0297     return framedsurf.fParent;
0298   }
0299 
0300   /// @brief Get common surface pointed by a locator
0301   /// @param locator Frame locator
0302   /// @return CS pointed by the locator
0303   VECCORE_ATT_HOST_DEVICE
0304   VECGEOM_FORCE_INLINE
0305   CommonSurface<Real_t> const &GetCommonSurface(FSlocator const &locator) const
0306   {
0307     return fCommonSurfaces[locator.GetCSindex()];
0308   }
0309 
0310   /// @brief Get side on common surface pointed by a locator
0311   /// @param locator Frame locator
0312   /// @return Side pointed by the locator
0313   VECCORE_ATT_HOST_DEVICE
0314   VECGEOM_FORCE_INLINE
0315   Side const &GetSide(FSlocator const &locator) const
0316   {
0317     auto const &surf = fCommonSurfaces[locator.GetCSindex()];
0318     return locator.IsLeftSide() ? surf.fLeftSide : surf.fRightSide;
0319   }
0320 
0321   /// @brief Get opposite side on common surface pointed by a locator
0322   /// @param locator Frame locator
0323   /// @return Side opposite to the one pointed by the locator
0324   VECCORE_ATT_HOST_DEVICE
0325   VECGEOM_FORCE_INLINE
0326   Side const &GetOppositeSide(FSlocator const &locator) const
0327   {
0328     auto const &surf = fCommonSurfaces[locator.GetCSindex()];
0329     return locator.IsLeftSide() ? surf.fRightSide : surf.fLeftSide;
0330   }
0331 
0332   /// @brief Get scene FSlocator from a touchable one
0333   /// @param ltouchable Locator for the touchable framed surface
0334   /// @param lscene Locator for the scene framed surface
0335   VECCORE_ATT_HOST_DEVICE
0336   VECGEOM_FORCE_INLINE
0337   void TouchableToSceneLocator(FSlocator const &ltouchable, FSlocator &lscene) const
0338   {
0339     auto const &framedsurf = GetFramedSurface(ltouchable);
0340     VECGEOM_VALIDATE(framedsurf.fSceneCS > 0, << "Touchable locator not on a scene surface");
0341     lscene.common_id = framedsurf.fSceneCS * (1 - 2 * int(framedsurf.fSceneCSind < 0));
0342     lscene.frame_id  = vecCore::math::Abs(framedsurf.fSceneCSind) - 1;
0343   }
0344 
0345   /// @brief Get touchable FSlocator from a scene one
0346   /// @param scene_state Global state for the scene surface in the parent scene
0347   /// @param surf_index Local surface index for the touchable
0348   /// @param ltouchable Locator for the touchable framed surface
0349   VECCORE_ATT_HOST_DEVICE
0350   VECGEOM_FORCE_INLINE
0351   void SceneToTouchableLocator(vecgeom::NavigationState const &scene_state, int surf_index, FSlocator &ltouchable) const
0352   {
0353     constexpr char kLside          = 1;
0354     unsigned short parent_scene_id = 0, dummy_id = 0;
0355     scene_state.GetSceneId(parent_scene_id, dummy_id);
0356     auto parent_state_id = scene_state.GetId();
0357     // Get parent scene common surface and side from the exiting candidates (ordered by the surf_index of
0358     // the scene volume surface)
0359     auto const &cand_scene = GetCandidates(parent_scene_id, parent_state_id);
0360     ltouchable.common_id   = cand_scene[surf_index] * (1 - 2 * int((cand_scene.fSides[surf_index] & kLside) == 0));
0361     ltouchable.frame_id    = cand_scene.fFrameInd[surf_index];
0362   }
0363 };
0364 } // namespace vgbrep
0365 #endif