File indexing completed on 2026-04-17 08:35:33
0001 #ifndef VECGEOM_SURFACE_CONECONVERTER_H_
0002 #define VECGEOM_SURFACE_CONECONVERTER_H_
0003
0004 #include <VecGeom/surfaces/conv/Builder.h>
0005 #include <VecGeom/surfaces/Model.h>
0006
0007 #include <VecGeom/volumes/Cone.h>
0008
0009 namespace vgbrep {
0010 namespace conv {
0011
0012
0013
0014
0015
0016
0017 template <typename Real_t>
0018 bool CreateConeSurfaces(vecgeom::UnplacedCone const &cone, int logical_id, bool intersection = false)
0019 {
0020 using RingMask_t = RingMask<Real_t>;
0021 using ZPhiMask_t = ZPhiMask<Real_t>;
0022 using Vector3D = vecgeom::Vector3D<vecgeom::Precision>;
0023
0024 LogicExpressionCPU logic;
0025 auto rmin1 = cone.GetRmin1();
0026 auto rmax1 = cone.GetRmax1();
0027 auto rmin2 = cone.GetRmin2();
0028 auto rmax2 = cone.GetRmax2();
0029 auto dz = cone.GetDz();
0030 auto sphi = cone.GetSPhi();
0031 auto dphi = cone.GetDPhi();
0032 auto ephi = dphi + sphi;
0033
0034 VECGEOM_ASSERT(dphi > vecgeom::kTolerance);
0035 VECGEOM_ASSERT(rmax1 - rmin1 > -vecgeom::kTolerance);
0036 VECGEOM_ASSERT(rmax2 - rmin2 > -vecgeom::kTolerance);
0037
0038
0039
0040 if (rmax1 - rmin1 == vecgeom::kConeTolerance) rmax1 = rmin1 + vecgeom::kToleranceCone<Real_t>;
0041 if (rmax2 - rmin2 == vecgeom::kConeTolerance) rmax2 = rmin2 + vecgeom::kToleranceCone<Real_t>;
0042
0043 bool fullCirc = ApproxEqual(dphi, vecgeom::kTwoPi);
0044 bool smallerPi = dphi < (vecgeom::kPi - vecgeom::kTolerance);
0045
0046 int isurf;
0047 vecgeom::Precision surfdata[2];
0048
0049
0050 auto sphid = vecgeom::kRadToDeg * sphi;
0051 auto ephid = vecgeom::kRadToDeg * ephi;
0052 vecgeom::Transformation3DMP<Real_t> identity;
0053
0054
0055 isurf = builder::CreateLocalSurface<Real_t>(
0056 builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0057 builder::CreateFrame<Real_t>(FrameType::kRing, RingMask_t{rmin2, rmax2, fullCirc, sphi, ephi}),
0058 vecgeom::Transformation3DMP<Precision>(0., 0., dz, 0., 0., 0.));
0059 builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0060 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0061 logic.push_back(isurf);
0062
0063 isurf = builder::CreateLocalSurface<Real_t>(
0064 builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0065 builder::CreateFrame<Real_t>(FrameType::kRing, RingMask_t{rmin1, rmax1, fullCirc, sphi, ephi}),
0066 vecgeom::Transformation3DMP<Precision>(0., 0., -dz, 0., 180., -sphid - ephid));
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 (rmin2 > vecgeom::kTolerance || rmin1 > vecgeom::kTolerance) {
0073 surfdata[0] = 0.5 * (rmin1 + rmin2);
0074 surfdata[1] = 0.5 * (rmin2 - rmin1) / dz;
0075 auto stype = std::abs(surfdata[1]) > vecgeom::kTolerance ? SurfaceType::kConical : SurfaceType::kCylindrical;
0076 isurf = builder::CreateLocalSurface<Real_t>(
0077 builder::CreateUnplacedSurface<Real_t>(stype, surfdata, true),
0078 builder::CreateFrame<Real_t>(FrameType::kZPhi, ZPhiMask_t{-dz, dz, fullCirc, rmin1, rmin2, sphi, ephi}),
0079 identity);
0080 builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0081 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0082 logic.push_back(land);
0083 logic.push_back(isurf);
0084 }
0085
0086 surfdata[0] = 0.5 * (rmax1 + rmax2);
0087 surfdata[1] = 0.5 * (rmax2 - rmax1) / dz;
0088 auto stype = std::abs(surfdata[1]) > vecgeom::kTolerance ? SurfaceType::kConical : SurfaceType::kCylindrical;
0089 isurf = builder::CreateLocalSurface<Real_t>(
0090 builder::CreateUnplacedSurface<Real_t>(stype, surfdata),
0091 builder::CreateFrame<Real_t>(FrameType::kZPhi, ZPhiMask_t{-dz, dz, fullCirc, rmax1, rmax2, sphi, ephi}),
0092 identity);
0093 builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0094 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0095 logic.push_back(land);
0096 logic.push_back(isurf);
0097
0098 if (ApproxEqual(dphi, vecgeom::kTwoPi)) {
0099 builder::AddLogicToShell<Real_t>(logical_id, logic);
0100 return true;
0101 }
0102
0103 vecgeom::Transformation3D transformation;
0104 std::vector<Vector3D> vert;
0105 auto csphi = std::cos(sphi);
0106 auto ssphi = std::sin(sphi);
0107 auto cephi = std::cos(ephi);
0108 auto sephi = std::sin(ephi);
0109
0110
0111 std::vector<Vector3D> corners = {{rmin1 * csphi, rmin1 * ssphi, -dz}, {rmax1 * csphi, rmax1 * ssphi, -dz},
0112 {rmax2 * csphi, rmax2 * ssphi, dz}, {rmin2 * csphi, rmin2 * ssphi, dz},
0113 {rmax1 * cephi, rmax1 * sephi, -dz}, {rmin1 * cephi, rmin1 * sephi, -dz},
0114 {rmin2 * cephi, rmin2 * sephi, dz}, {rmax2 * cephi, rmax2 * sephi, dz}};
0115
0116
0117 vert = {corners[0], corners[1], corners[2], corners[3]};
0118 isurf = builder::CreateLocalSurfaceFromVertices<Real_t>(vert, logical_id);
0119 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0120 if (isurf >= 0) {
0121 if (!smallerPi) builder::GetSurface<Real_t>(isurf).fEmbedding = false;
0122 logic.push_back(land);
0123 logic.push_back(lplus);
0124 logic.push_back(isurf);
0125 }
0126
0127
0128 vert = {corners[4], corners[5], corners[6], corners[7]};
0129 isurf = builder::CreateLocalSurfaceFromVertices<Real_t>(vert, logical_id);
0130 if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0131 if (isurf >= 0) {
0132 if (!smallerPi) builder::GetSurface<Real_t>(isurf).fEmbedding = false;
0133 logic.push_back(smallerPi ? land : lor);
0134 logic.push_back(isurf);
0135 logic.push_back(lminus);
0136 }
0137
0138 builder::AddLogicToShell<Real_t>(logical_id, logic);
0139 return true;
0140 }
0141
0142 }
0143 }
0144 #endif