Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef VECGEOM_SURFACE_TORUSCONVERTER_H_
0002 #define VECGEOM_SURFACE_TORUSCONVERTER_H_
0003 
0004 #include <VecGeom/surfaces/conv/Builder.h>
0005 #include <VecGeom/surfaces/Model.h>
0006 
0007 #include <VecGeom/volumes/Torus2.h>
0008 
0009 namespace vgbrep {
0010 namespace conv {
0011 
0012 /// @brief Converter for Torus
0013 /// @tparam Real_t Precision type
0014 /// @param torus Torus solid to be converted
0015 /// @param logical_id Id of the logical volume
0016 /// @return Conversion success
0017 template <typename Real_t>
0018 bool CreateTorusSurfaces(vecgeom::UnplacedTorus2 const &torus, int logical_id, bool intersection = false)
0019 {
0020   using RingMask_t = RingMask<Real_t>;
0021 
0022   LogicExpressionCPU logic; // top & bottom & [rmin] & rmax & (dphi < 180) ? sphi * ephi : sphi | ephi
0023   auto rmin = torus.rmin();
0024   auto rmax = torus.rmax();
0025   auto rtor = torus.rtor();
0026   auto sphi = torus.sphi();
0027   auto dphi = torus.dphi();
0028   auto ephi = dphi + sphi;
0029 
0030   VECGEOM_ASSERT(rtor - rmin > -vecgeom::kTolerance);
0031 
0032   bool fullCirc  = ApproxEqual(dphi, vecgeom::kTwoPi);
0033   bool smallerPi = dphi < (vecgeom::kPi - vecgeom::kTolerance);
0034 
0035   int isurf;
0036   vecgeom::Precision surfdata[4];
0037 
0038   // We need angles in degrees for transformations
0039   auto sphid = vecgeom::kRadToDeg * sphi;
0040   auto ephid = vecgeom::kRadToDeg * ephi;
0041   vecgeom::Transformation3DMP<Real_t> identity;
0042 
0043   // inner torus
0044   // Note that the torus surface needs to be fully checked already in the surface check.
0045   // Therefore, it does not need a frame and the frames should not be checked, hence the `never_check` flag.
0046   surfdata[0] = rtor;
0047   surfdata[1] = rmin;
0048   surfdata[2] = sphi;
0049   surfdata[3] = ephi;
0050   isurf       = builder::CreateLocalSurface<Real_t>(
0051       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kTorus, surfdata, /*flipped=*/true),
0052       builder::CreateFrame<Real_t>(FrameType::kRing, RingMask_t{rtor - rmin, rtor + rmin, fullCirc, sphi, ephi}),
0053       /*identity transformation*/ identity, /*never_check=*/true);
0054   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0055   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0056   logic.push_back(isurf);
0057 
0058   // outer torus
0059   surfdata[0] = rtor;
0060   surfdata[1] = rmax;
0061   surfdata[2] = sphi;
0062   surfdata[3] = ephi;
0063   isurf       = builder::CreateLocalSurface<Real_t>(
0064       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kTorus, surfdata),
0065       builder::CreateFrame<Real_t>(FrameType::kRing, RingMask_t{rtor - rmax, rtor + rmax, fullCirc, sphi, ephi}),
0066       /*identity transformation*/ identity, /*never_check=*/true);
0067   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0068   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0069   logic.push_back(land);
0070   logic.push_back(isurf);
0071 
0072   if (ApproxEqual(dphi, vecgeom::kTwoPi)) {
0073     builder::AddLogicToShell<Real_t>(logical_id, logic);
0074     return true;
0075   }
0076 
0077   // ring cap at Sphi
0078   isurf = builder::CreateLocalSurface<Real_t>(
0079       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0080       builder::CreateFrame<Real_t>(FrameType::kRing,
0081                                    RingMask_t{rmin, rmax, /*fullcircle=*/true, static_cast<vecgeom::Precision>(0),
0082                                               static_cast<vecgeom::Precision>(360)}),
0083       vecgeom::Transformation3DMP<Precision>(rtor * std::cos(sphi), rtor * std::sin(sphi), 0., sphid, 90., 0.));
0084   if (!smallerPi) builder::GetSurface<Real_t>(isurf).fEmbedding = false;
0085   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0086   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0087   logic.push_back(land);
0088   logic.push_back(lplus); // '('
0089   logic.push_back(isurf);
0090 
0091   // ring cap at Sphi+Dphi
0092   isurf = builder::CreateLocalSurface<Real_t>(
0093       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0094       builder::CreateFrame<Real_t>(FrameType::kRing,
0095                                    RingMask_t{rmin, rmax, /*fullcircle=*/true, static_cast<vecgeom::Precision>(0),
0096                                               static_cast<vecgeom::Precision>(360)}),
0097       vecgeom::Transformation3DMP<Precision>(rtor * std::cos(ephi), rtor * std::sin(ephi), 0., ephid, -90., 0.));
0098   if (!smallerPi) builder::GetSurface<Real_t>(isurf).fEmbedding = false;
0099   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0100   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0101   logic.push_back(smallerPi ? land : lor);
0102   logic.push_back(isurf);
0103   logic.push_back(lminus); // ')'
0104   builder::AddLogicToShell<Real_t>(logical_id, logic);
0105   return true;
0106 }
0107 
0108 } // namespace conv
0109 } // namespace vgbrep
0110 #endif