37 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
46 using namespace CLHEP;
52 G4UGenericPolycone::G4UGenericPolycone(
const G4String&
name,
58 : G4USolid(name, new UGenericPolycone(name, phiStart, phiTotal, numRZ, r, z))
68 G4UGenericPolycone::G4UGenericPolycone(__void__&
a)
78 G4UGenericPolycone::~G4UGenericPolycone()
87 G4UGenericPolycone::G4UGenericPolycone(
const G4UGenericPolycone &source)
98 G4UGenericPolycone::operator=(
const G4UGenericPolycone &source)
100 if (
this == &source)
return *
this;
102 G4USolid::operator=( source );
107 G4double G4UGenericPolycone::GetStartPhi()
const
109 return GetShape()->GetStartPhi();
111 G4double G4UGenericPolycone::GetEndPhi()
const
113 return GetShape()->GetEndPhi();
115 G4double G4UGenericPolycone::GetSinStartPhi()
const
117 if (!GetShape()->IsOpen())
return 0;
118 G4double phi = GetShape()->GetStartPhi();
119 return std::sin(phi);
121 G4double G4UGenericPolycone::GetCosStartPhi()
const
123 if (!GetShape()->IsOpen())
return 1;
124 G4double phi = GetShape()->GetStartPhi();
125 return std::cos(phi);
127 G4double G4UGenericPolycone::GetSinEndPhi()
const
129 if (!GetShape()->IsOpen())
return 0;
130 G4double phi = GetShape()->GetEndPhi();
131 return std::sin(phi);
133 G4double G4UGenericPolycone::GetCosEndPhi()
const
135 if (!GetShape()->IsOpen())
return 1;
136 G4double phi = GetShape()->GetEndPhi();
137 return std::cos(phi);
139 G4bool G4UGenericPolycone::IsOpen()
const
141 return GetShape()->IsOpen();
143 G4int G4UGenericPolycone::GetNumRZCorner()
const
145 return GetShape()->GetNumRZCorner();
149 UPolyconeSideRZ pside = GetShape()->GetCorner(index);
166 for (
G4int i=0; i<GetNumRZCorner(); ++i)
169 if (corner.
r < rmin) rmin = corner.
r;
170 if (corner.
r > rmax) rmax = corner.
r;
171 if (corner.
z < zmin) zmin = corner.
z;
172 if (corner.
z > zmax) zmax = corner.
z;
179 GetSinStartPhi(),GetCosStartPhi(),
180 GetSinEndPhi(),GetCosEndPhi(),
182 pMin.
set(vmin.
x(),vmin.
y(),zmin);
183 pMax.
set(vmax.
x(),vmax.
y(),zmax);
187 pMin.
set(-rmax,-rmax, zmin);
188 pMax.
set( rmax, rmax, zmax);
193 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
196 message <<
"Bad bounding box (min >= max) for solid: "
198 <<
"\npMin = " << pMin
199 <<
"\npMax = " << pMax;
200 G4Exception(
"G4UGenericPolycone::BoundingLimits()",
"GeomMgt0001",
211 G4UGenericPolycone::CalculateExtent(
const EAxis pAxis,
221 BoundingLimits(bmin,bmax);
224 if (
true)
return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
226 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
228 return exist = (pMin < pMax) ?
true :
false;
241 for (
G4int i=0; i<GetNumRZCorner(); ++i)
247 if (area < 0.)
std::reverse(contourRZ.begin(),contourRZ.end());
253 message <<
"Triangulation of RZ contour has failed for solid: "
255 <<
"\nExtent has been calculated using boundary box";
256 G4Exception(
"G4UGenericPolycone::CalculateExtent()",
258 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
262 const G4int NSTEPS = 24;
268 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-
deg)/astep) + 1;
271 G4double sinHalf = std::sin(0.5*ang);
272 G4double cosHalf = std::cos(0.5*ang);
273 G4double sinStep = 2.*sinHalf*cosHalf;
274 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
276 G4double sinStart = GetSinStartPhi();
277 G4double cosStart = GetCosStartPhi();
282 std::vector<const G4ThreeVectorList *> polygons;
283 polygons.resize(ksteps+2);
285 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
286 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
293 G4int ntria = triangles.size()/3;
294 for (
G4int i=0; i<ntria; ++i)
297 for (
G4int k=0; k<3; ++k)
299 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
302 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
303 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
307 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
313 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
314 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
315 for (
G4int j=0; j<6; ++j)
317 pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
319 for (
G4int k=1; k<ksteps+1; ++k)
321 for (
G4int j=0; j<6; ++j)
323 pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
326 sinCur = sinCur*cosStep + cosCur*sinStep;
327 cosCur = cosCur*cosStep - sinTmp*sinStep;
329 for (
G4int j=0; j<6; ++j)
331 pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
337 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
338 if (emin < pMin) pMin = emin;
339 if (emax > pMax) pMax =
emax;
340 if (eminlim > pMin && emaxlim < pMax)
return true;
342 return (pMin < pMax);
349 G4Polyhedron* G4UGenericPolycone::CreatePolyhedron()
const
375 const G4int numSide =
377 * (GetEndPhi() - GetStartPhi()) /
twopi) + 1;
382 typedef G4int int4[4];
389 std::vector<G4bool> chopped(GetNumRZCorner(),
false);
390 std::vector<G4int*> triQuads;
391 G4int remaining = GetNumRZCorner();
393 while (remaining >= 3)
398 G4int iStepper = iStarter;
401 if (A < 0) { A = iStepper; }
402 else if (
B < 0) {
B = iStepper; }
403 else if (
C < 0) {
C = iStepper; }
406 if (++iStepper >= GetNumRZCorner()) { iStepper = 0; }
408 while (chopped[iStepper]);
410 while (
C < 0 && iStepper != iStarter);
415 G4double BAr = GetCorner(A).r - GetCorner(
B).r;
416 G4double BAz = GetCorner(A).z - GetCorner(
B).z;
417 G4double BCr = GetCorner(
C).r - GetCorner(
B).r;
418 G4double BCz = GetCorner(
C).z - GetCorner(
B).z;
425 triQuads.push_back(tq);
433 if (++iStarter >= GetNumRZCorner()) { iStarter = 0; }
435 while (chopped[iStarter]);
440 nNodes = (numSide + 1) * GetNumRZCorner();
441 nFaces = numSide * GetNumRZCorner() + 2 * triQuads.size();
442 faces_vec =
new int4[nFaces];
444 G4int addition = GetNumRZCorner() * numSide;
445 G4int d = GetNumRZCorner() - 1;
446 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
448 for (
size_t i = 0; i < triQuads.size(); ++i)
461 a = triQuads[i][0] + addition;
462 b = triQuads[i][2] + addition;
463 c = triQuads[i][1] + addition;
466 G4int bc = std::abs(c - b);
467 G4int ca = std::abs(a - c);
468 faces_vec[iface][0] = (ab == 1 || ab ==
d)? a: -a;
469 faces_vec[iface][1] = (bc == 1 || bc ==
d)? b: -b;
470 faces_vec[iface][2] = (ca == 1 || ca ==
d)? c: -c;
471 faces_vec[iface][3] = 0;
478 xyz =
new double3[nNodes];
479 const G4double dPhi = (GetEndPhi() - GetStartPhi()) / numSide;
482 for (
G4int iSide = 0; iSide < numSide; ++iSide)
484 for (
G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
486 xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
487 xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
488 xyz[ixyz][2] = GetCorner(iCorner).z;
491 if (iCorner < GetNumRZCorner() - 1)
493 faces_vec[iface][0] = ixyz + 1;
494 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
495 faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
496 faces_vec[iface][3] = ixyz + 2;
500 faces_vec[iface][0] = ixyz + 1;
501 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
502 faces_vec[iface][2] = ixyz + 2;
503 faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
506 else if (iSide == numSide - 1)
508 if (iCorner < GetNumRZCorner() - 1)
510 faces_vec[iface][0] = ixyz + 1;
511 faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
512 faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
513 faces_vec[iface][3] = -(ixyz + 2);
517 faces_vec[iface][0] = ixyz + 1;
518 faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
519 faces_vec[iface][2] = ixyz + 2;
520 faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
525 if (iCorner < GetNumRZCorner() - 1)
527 faces_vec[iface][0] = ixyz + 1;
528 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
529 faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
530 faces_vec[iface][3] = -(ixyz + 2);
534 faces_vec[iface][0] = ixyz + 1;
535 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
536 faces_vec[iface][2] = ixyz + 2;
537 faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
548 for (
G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
550 xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
551 xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
552 xyz[ixyz][2] = GetCorner(iCorner).z;
558 nNodes = numSide * GetNumRZCorner();
559 nFaces = numSide * GetNumRZCorner();;
560 xyz =
new double3[nNodes];
561 faces_vec =
new int4[nFaces];
562 const G4double dPhi = (GetEndPhi() - GetStartPhi()) / numSide;
564 G4int ixyz = 0, iface = 0;
565 for (
G4int iSide = 0; iSide < numSide; ++iSide)
567 for (
G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
569 xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
570 xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
571 xyz[ixyz][2] = GetCorner(iCorner).z;
573 if (iSide < numSide - 1)
575 if (iCorner < GetNumRZCorner() - 1)
577 faces_vec[iface][0] = ixyz + 1;
578 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
579 faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
580 faces_vec[iface][3] = -(ixyz + 2);
584 faces_vec[iface][0] = ixyz + 1;
585 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
586 faces_vec[iface][2] = ixyz + 2;
587 faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
592 if (iCorner < GetNumRZCorner() - 1)
594 faces_vec[iface][0] = ixyz + 1;
595 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() - nFaces + 1);
596 faces_vec[iface][2] = ixyz + GetNumRZCorner() - nFaces + 2;
597 faces_vec[iface][3] = -(ixyz + 2);
601 faces_vec[iface][0] = ixyz + 1;
602 faces_vec[iface][1] = -(ixyz - nFaces + GetNumRZCorner() + 1);
603 faces_vec[iface][2] = ixyz - nFaces + 2;
604 faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
620 message <<
"Problem creating G4Polyhedron for: " << GetName();
621 G4Exception(
"G4GenericPolycone::CreatePolyhedron()",
"GeomSolids1002",
632 #endif // G4GEOM_USE_USOLIDS
void set(double x, double y, double z)
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
G4double GetMaxExtent(const EAxis pAxis) const
std::vector< ExP01TrackerHit * > a
static const G4double kInfinity
CLHEP::Hep2Vector G4TwoVector
void message(RunManager *runmanager)
static const G4double emax
const G4double kCarTolerance
std::vector< G4ThreeVector > G4ThreeVectorList
G4double GetMinExtent(const EAxis pAxis) const
static constexpr double deg
static constexpr double twopi
double A(double temperature)
static G4int GetNumberOfRotationSteps()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4GLOB_DLL std::ostream G4cout
double B(double temperature)