File indexing completed on 2026-04-17 08:35:34
0001 #ifndef VECGEOM_SURFACE_TUBECONVERTER_H_
0002 #define VECGEOM_SURFACE_TUBECONVERTER_H_
0003
0004 #include <VecGeom/surfaces/conv/Builder.h>
0005 #include <VecGeom/surfaces/Model.h>
0006
0007 #include <VecGeom/volumes/Tube.h>
0008
0009 namespace vgbrep {
0010 namespace conv {
0011
0012
0013
0014
0015
0016
0017 template <typename Real_t>
0018 bool CreateTubeSurfaces(vecgeom::UnplacedTube const &tube, int logical_id, bool intersection = false)
0019 {
0020 using RingMask_t = RingMask<Real_t>;
0021 using ZPhiMask_t = ZPhiMask<Real_t>;
0022 using WindowMask_t = WindowMask<Real_t>;
0023
0024 LogicExpressionCPU logic;
0025 auto sphi = tube.sphi();
0026 auto dphi = tube.dphi();
0027 auto ephi = tube.sphi() + tube.dphi();
0028
0029 VECGEOM_ASSERT(dphi > vecgeom::kTolerance);
0030
0031 auto Rmean = (tube.rmin() + tube.rmax()) / 2;
0032 auto Rdiff = (tube.rmax() - tube.rmin()) / 2;
0033
0034 VECGEOM_ASSERT(Rdiff > 0);
0035
0036 bool fullCirc = ApproxEqual(dphi, vecgeom::kTwoPi);
0037 bool smallerPi = dphi < (vecgeom::kPi - vecgeom::kTolerance);
0038
0039 int isurf;
0040 vecgeom::Precision surfdata[2];
0041
0042
0043 auto sphid = vecgeom::kRadToDeg * sphi;
0044 auto ephid = vecgeom::kRadToDeg * ephi;
0045 vecgeom::Transformation3DMP<Real_t> identity;
0046
0047
0048 isurf = builder::CreateLocalSurface<Real_t>(
0049 builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0050 builder::CreateFrame<Real_t>(FrameType::kRing, RingMask_t{tube.rmin(), tube.rmax(), fullCirc, sphi, ephi}),
0051 vecgeom::Transformation3DMP<Precision>(0., 0., tube.z(), 0., 0., 0.));
0052 builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0053 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0054 logic.push_back(isurf);
0055
0056 isurf = builder::CreateLocalSurface<Real_t>(
0057 builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0058 builder::CreateFrame<Real_t>(FrameType::kRing, RingMask_t{tube.rmin(), tube.rmax(), fullCirc, sphi, ephi}),
0059 vecgeom::Transformation3DMP<Precision>(0., 0., -tube.z(), 0., 180., -sphid - ephid));
0060 builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0061 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0062 logic.push_back(land);
0063 logic.push_back(isurf);
0064
0065 if (tube.rmin() > vecgeom::kTolerance) {
0066 surfdata[0] = tube.rmin();
0067 isurf = builder::CreateLocalSurface<Real_t>(
0068 builder::CreateUnplacedSurface<Real_t>(SurfaceType::kCylindrical, surfdata, true),
0069 builder::CreateFrame<Real_t>(FrameType::kZPhi,
0070 ZPhiMask_t{-tube.z(), tube.z(), fullCirc, tube.rmin(), tube.rmin(), sphi, ephi}),
0071 identity);
0072 builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0073 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0074 logic.push_back(land);
0075 logic.push_back(isurf);
0076 }
0077
0078 surfdata[0] = tube.rmax();
0079 isurf = builder::CreateLocalSurface<Real_t>(
0080 builder::CreateUnplacedSurface<Real_t>(SurfaceType::kCylindrical, surfdata),
0081 builder::CreateFrame<Real_t>(FrameType::kZPhi,
0082 ZPhiMask_t{-tube.z(), tube.z(), fullCirc, tube.rmax(), tube.rmax(), sphi, ephi}),
0083 identity);
0084 builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0085 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0086 logic.push_back(land);
0087 logic.push_back(isurf);
0088
0089 if (ApproxEqual(dphi, vecgeom::kTwoPi)) {
0090 builder::AddLogicToShell<Real_t>(logical_id, logic);
0091 return true;
0092 }
0093
0094 isurf = builder::CreateLocalSurface<Real_t>(
0095 builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0096 builder::CreateFrame<Real_t>(FrameType::kWindow, WindowMask_t{Rdiff, tube.z()}),
0097 vecgeom::Transformation3DMP<Precision>(Rmean * std::cos(sphi), Rmean * std::sin(sphi), 0., sphid, 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(land);
0102 logic.push_back(lplus);
0103 logic.push_back(isurf);
0104
0105
0106 isurf = builder::CreateLocalSurface<Real_t>(
0107 builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0108 builder::CreateFrame<Real_t>(FrameType::kWindow, WindowMask_t{Rdiff, tube.z()}),
0109 vecgeom::Transformation3DMP<Precision>(Rmean * std::cos(ephi), Rmean * std::sin(ephi), 0., ephid, -90., 0.));
0110 if (!smallerPi) builder::GetSurface<Real_t>(isurf).fEmbedding = false;
0111 builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0112 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0113 logic.push_back(smallerPi ? land : lor);
0114 logic.push_back(isurf);
0115 logic.push_back(lminus);
0116 builder::AddLogicToShell<Real_t>(logical_id, logic);
0117 return true;
0118 }
0119
0120 }
0121 }
0122 #endif