34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
43 using namespace CLHEP;
49 G4UGenericPolycone::G4UGenericPolycone(
const G4String&
name,
55 : Base_t(name, phiStart, phiTotal, numRZ, r, z)
57 wrStart = phiStart;
while (wrStart < 0) wrStart +=
twopi;
65 for (
G4int i=0; i<numRZ; ++i)
69 std::vector<G4int> iout;
79 G4UGenericPolycone::G4UGenericPolycone(__void__&
a)
89 G4UGenericPolycone::~G4UGenericPolycone()
98 G4UGenericPolycone::G4UGenericPolycone(
const G4UGenericPolycone& source)
101 wrStart = source.wrStart;
102 wrDelta = source.wrDelta;
103 rzcorners = source.rzcorners;
112 G4UGenericPolycone::operator=(
const G4UGenericPolycone& source)
114 if (
this == &source)
return *
this;
116 Base_t::operator=( source );
117 wrStart = source.wrStart;
118 wrDelta = source.wrDelta;
119 rzcorners = source.rzcorners;
124 G4double G4UGenericPolycone::GetStartPhi()
const
128 G4double G4UGenericPolycone::GetEndPhi()
const
130 return (wrStart + wrDelta);
132 G4double G4UGenericPolycone::GetSinStartPhi()
const
134 if (IsOpen())
return 0.;
136 return std::sin(phi);
138 G4double G4UGenericPolycone::GetCosStartPhi()
const
140 if (IsOpen())
return 1.;
142 return std::cos(phi);
144 G4double G4UGenericPolycone::GetSinEndPhi()
const
146 if (IsOpen())
return 0.;
148 return std::sin(phi);
150 G4double G4UGenericPolycone::GetCosEndPhi()
const
152 if (IsOpen())
return 1.;
154 return std::cos(phi);
156 G4bool G4UGenericPolycone::IsOpen()
const
158 return (wrDelta <
twopi);
160 G4int G4UGenericPolycone::GetNumRZCorner()
const
162 return rzcorners.size();
176 G4VSolid* G4UGenericPolycone::Clone()
const
178 return new G4UGenericPolycone(*
this);
192 for (
G4int i=0; i<GetNumRZCorner(); ++i)
195 if (corner.
r < rmin) rmin = corner.
r;
196 if (corner.
r > rmax) rmax = corner.
r;
197 if (corner.
z < zmin) zmin = corner.
z;
198 if (corner.
z > zmax) zmax = corner.
z;
205 GetSinStartPhi(),GetCosStartPhi(),
206 GetSinEndPhi(),GetCosEndPhi(),
208 pMin.
set(vmin.
x(),vmin.
y(),zmin);
209 pMax.
set(vmax.
x(),vmax.
y(),zmax);
213 pMin.
set(-rmax,-rmax, zmin);
214 pMax.
set( rmax, rmax, zmax);
219 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
222 message <<
"Bad bounding box (min >= max) for solid: "
224 <<
"\npMin = " << pMin
225 <<
"\npMax = " <<
pMax;
226 G4Exception(
"G4UGenericPolycone::BoundingLimits()",
"GeomMgt0001",
237 G4UGenericPolycone::CalculateExtent(
const EAxis pAxis,
247 BoundingLimits(bmin,bmax);
250 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
252 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
254 return exist = (pMin <
pMax) ?
true :
false;
267 for (
G4int i=0; i<GetNumRZCorner(); ++i)
273 if (area < 0.)
std::reverse(contourRZ.begin(),contourRZ.end());
279 message <<
"Triangulation of RZ contour has failed for solid: "
281 <<
"\nExtent has been calculated using boundary box";
282 G4Exception(
"G4UGenericPolycone::CalculateExtent()",
284 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
288 const G4int NSTEPS = 24;
294 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-
deg)/astep) + 1;
297 G4double sinHalf = std::sin(0.5*ang);
298 G4double cosHalf = std::cos(0.5*ang);
299 G4double sinStep = 2.*sinHalf*cosHalf;
300 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
302 G4double sinStart = GetSinStartPhi();
303 G4double cosStart = GetCosStartPhi();
308 std::vector<const G4ThreeVectorList *> polygons;
309 polygons.resize(ksteps+2);
311 for (
G4int k=0;
k<ksteps+2; ++
k) pols[
k].resize(6);
312 for (
G4int k=0;
k<ksteps+2; ++
k) polygons[
k] = &pols[
k];
319 G4int ntria = triangles.size()/3;
320 for (
G4int i=0; i<ntria; ++i)
325 G4int e0 = i3+
k,
e1 = (k<2) ? e0+1 : i3;
328 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
329 r0[k2+1] = triangles[
e1].x(); z0[k2+1] = triangles[
e1].y();
333 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
339 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
340 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
341 for (
G4int j=0; j<6; ++j)
343 pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
345 for (
G4int k=1; k<ksteps+1; ++
k)
347 for (
G4int j=0; j<6; ++j)
349 pols[
k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
352 sinCur = sinCur*cosStep + cosCur*sinStep;
353 cosCur = cosCur*cosStep - sinTmp*sinStep;
355 for (
G4int j=0; j<6; ++j)
357 pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
363 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
364 if (emin < pMin) pMin =
emin;
365 if (emax > pMax) pMax =
emax;
366 if (eminlim > pMin && emaxlim < pMax)
return true;
368 return (pMin < pMax);
375 G4Polyhedron* G4UGenericPolycone::CreatePolyhedron()
const
403 * (GetEndPhi() - GetStartPhi()) /
twopi) + 1;
408 typedef G4int int4[4];
415 std::vector<G4bool> chopped(GetNumRZCorner(),
false);
416 std::vector<G4int*> triQuads;
417 G4int remaining = GetNumRZCorner();
419 while (remaining >= 3)
424 G4int iStepper = iStarter;
427 if (A < 0) { A = iStepper; }
428 else if (
B < 0) {
B = iStepper; }
429 else if (
C < 0) {
C = iStepper; }
432 if (++iStepper >= GetNumRZCorner()) { iStepper = 0; }
434 while (chopped[iStepper]);
436 while (
C < 0 && iStepper != iStarter);
441 G4double BAr = GetCorner(A).r - GetCorner(
B).r;
442 G4double BAz = GetCorner(A).z - GetCorner(
B).z;
443 G4double BCr = GetCorner(
C).r - GetCorner(
B).r;
444 G4double BCz = GetCorner(
C).z - GetCorner(
B).z;
451 triQuads.push_back(tq);
459 if (++iStarter >= GetNumRZCorner()) { iStarter = 0; }
461 while (chopped[iStarter]);
466 nNodes = (numSide + 1) * GetNumRZCorner();
467 nFaces = numSide * GetNumRZCorner() + 2 * triQuads.size();
468 faces_vec =
new int4[nFaces];
471 G4int d = GetNumRZCorner() - 1;
472 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
474 for (
size_t i = 0; i < triQuads.size(); ++i)
487 a = triQuads[i][0] + addition;
488 b = triQuads[i][2] + addition;
489 c = triQuads[i][1] + addition;
494 faces_vec[iface][0] = (ab == 1 || ab ==
d)? a: -a;
495 faces_vec[iface][1] = (bc == 1 || bc ==
d)? b: -b;
496 faces_vec[iface][2] = (ca == 1 || ca ==
d)? c: -c;
497 faces_vec[iface][3] = 0;
504 xyz =
new double3[nNodes];
505 const G4double dPhi = (GetEndPhi() - GetStartPhi()) / numSide;
510 for (
G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
512 xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
513 xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
514 xyz[ixyz][2] = GetCorner(iCorner).z;
517 if (iCorner < GetNumRZCorner() - 1)
519 faces_vec[iface][0] = ixyz + 1;
520 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
521 faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
522 faces_vec[iface][3] = ixyz + 2;
526 faces_vec[iface][0] = ixyz + 1;
527 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
528 faces_vec[iface][2] = ixyz + 2;
529 faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
532 else if (iSide == numSide - 1)
534 if (iCorner < GetNumRZCorner() - 1)
536 faces_vec[iface][0] = ixyz + 1;
537 faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
538 faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
539 faces_vec[iface][3] = -(ixyz + 2);
543 faces_vec[iface][0] = ixyz + 1;
544 faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
545 faces_vec[iface][2] = ixyz + 2;
546 faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
551 if (iCorner < GetNumRZCorner() - 1)
553 faces_vec[iface][0] = ixyz + 1;
554 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
555 faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
556 faces_vec[iface][3] = -(ixyz + 2);
560 faces_vec[iface][0] = ixyz + 1;
561 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
562 faces_vec[iface][2] = ixyz + 2;
563 faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
574 for (
G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
576 xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
577 xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
578 xyz[ixyz][2] = GetCorner(iCorner).z;
584 nNodes = numSide * GetNumRZCorner();
585 nFaces = numSide * GetNumRZCorner();;
586 xyz =
new double3[nNodes];
587 faces_vec =
new int4[nFaces];
588 const G4double dPhi = (GetEndPhi() - GetStartPhi()) / numSide;
590 G4int ixyz = 0, iface = 0;
593 for (
G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
595 xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
596 xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
597 xyz[ixyz][2] = GetCorner(iCorner).z;
599 if (iSide < numSide - 1)
601 if (iCorner < GetNumRZCorner() - 1)
603 faces_vec[iface][0] = ixyz + 1;
604 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
605 faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
606 faces_vec[iface][3] = -(ixyz + 2);
610 faces_vec[iface][0] = ixyz + 1;
611 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() + 1);
612 faces_vec[iface][2] = ixyz + 2;
613 faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
618 if (iCorner < GetNumRZCorner() - 1)
620 faces_vec[iface][0] = ixyz + 1;
621 faces_vec[iface][1] = -(ixyz + GetNumRZCorner() - nFaces + 1);
622 faces_vec[iface][2] = ixyz + GetNumRZCorner() - nFaces + 2;
623 faces_vec[iface][3] = -(ixyz + 2);
627 faces_vec[iface][0] = ixyz + 1;
628 faces_vec[iface][1] = -(ixyz - nFaces + GetNumRZCorner() + 1);
629 faces_vec[iface][2] = ixyz - nFaces + 2;
630 faces_vec[iface][3] = -(ixyz - GetNumRZCorner() + 2);
646 message <<
"Problem creating G4Polyhedron for: " << GetName();
647 G4Exception(
"G4GenericPolycone::CreatePolyhedron()",
"GeomSolids1002",
658 #endif // G4GEOM_USE_USOLIDS