59 using namespace CLHEP;
75 Create( phiStart, phiTotal, rz );
100 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
101 <<
" All R values must be >= 0 !";
102 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
114 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
115 <<
" R/Z cross section is zero or near zero: " << rzArea;
116 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
124 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
125 <<
" Too few unique R/Z values !";
126 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
133 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
134 <<
" R/Z segments cross !";
135 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
145 if (phiTotal <= 0 || phiTotal >
twopi-1
E-10)
162 endPhi = phiStart+phiTotal;
181 next->
r = iterRZ.
GetA();
182 next->
z = iterRZ.
GetB();
183 }
while( ++next, iterRZ.
Next() );
215 if (corner->
z > next->
z)
232 }
while( prev=corner, corner=next, corner >
corners );
261 :
G4VCSGfaceted(a), startPhi(0.), endPhi(0.), phiIsOpen(false),
262 numCorner(0), corners(0), enclosingCylinder(0)
293 if (
this == &source)
return *
this;
350 message <<
"Solid " <<
GetName() <<
" built using generic construct."
351 <<
G4endl <<
"Not applicable to the generic construct !";
352 G4Exception(
"G4GenericPolycone::Reset()",
"GeomSolids1001",
423 if (corner.
r < rmin) rmin = corner.
r;
424 if (corner.
r > rmax) rmax = corner.
r;
425 if (corner.
z < zmin) zmin = corner.
z;
426 if (corner.
z > zmax) zmax = corner.
z;
436 pMin.
set(vmin.
x(),vmin.
y(),zmin);
437 pMax.
set(vmax.
x(),vmax.
y(),zmax);
441 pMin.
set(-rmax,-rmax, zmin);
442 pMax.
set( rmax, rmax, zmax);
447 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
450 message <<
"Bad bounding box (min >= max) for solid: "
452 <<
"\npMin = " << pMin
453 <<
"\npMax = " << pMax;
454 G4Exception(
"GenericG4Polycone::BoundingLimits()",
"GeomMgt0001",
478 if (
true)
return bbox.
CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
482 return exist = (pMin < pMax) ?
true :
false;
501 if (area < 0.)
std::reverse(contourRZ.begin(),contourRZ.end());
507 message <<
"Triangulation of RZ contour has failed for solid: "
509 <<
"\nExtent has been calculated using boundary box";
510 G4Exception(
"G4GenericPolycone::CalculateExtent()",
516 const G4int NSTEPS = 24;
522 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-
deg)/astep) + 1;
525 G4double sinHalf = std::sin(0.5*ang);
526 G4double cosHalf = std::cos(0.5*ang);
527 G4double sinStep = 2.*sinHalf*cosHalf;
528 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
536 std::vector<const G4ThreeVectorList *> polygons;
537 polygons.resize(ksteps+2);
539 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
540 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
547 G4int ntria = triangles.size()/3;
548 for (
G4int i=0; i<ntria; ++i)
551 for (
G4int k=0; k<3; ++k)
553 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
556 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
557 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
561 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
567 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
568 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
569 for (
G4int j=0; j<6; ++j)
571 pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
573 for (
G4int k=1; k<ksteps+1; ++k)
575 for (
G4int j=0; j<6; ++j)
577 pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
580 sinCur = sinCur*cosStep + cosCur*sinStep;
581 cosCur = cosCur*cosStep - sinTmp*sinStep;
583 for (
G4int j=0; j<6; ++j)
585 pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
591 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
592 if (emin < pMin) pMin = emin;
593 if (emax > pMax) pMax =
emax;
594 if (eminlim > pMin && emaxlim < pMax)
return true;
596 return (pMin < pMax);
614 return G4String(
"G4GenericPolycone");
631 G4int oldprc = os.precision(16);
632 os <<
"-----------------------------------------------------------\n"
633 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
634 <<
" ===================================================\n"
635 <<
" Solid type: G4GenericPolycone\n"
638 <<
" ending phi angle : " <<
endPhi/
degree <<
" degrees \n";
641 os <<
" number of RZ points: " <<
numCorner <<
"\n"
642 <<
" RZ values (corners): \n";
648 os <<
"-----------------------------------------------------------\n";
649 os.precision(oldprc);
692 const G4int numSide =
699 typedef G4int int4[4];
706 std::vector<G4bool> chopped(
numCorner,
false);
707 std::vector<G4int*> triQuads;
710 while (remaining >= 3)
715 G4int iStepper = iStarter;
718 if (A < 0) { A = iStepper; }
719 else if (
B < 0) {
B = iStepper; }
720 else if (
C < 0) {
C = iStepper; }
723 if (++iStepper >=
numCorner) { iStepper = 0; }
725 while (chopped[iStepper]);
727 while (
C < 0 && iStepper != iStarter);
742 triQuads.push_back(tq);
750 if (++iStarter >=
numCorner) { iStarter = 0; }
752 while (chopped[iStarter]);
758 nFaces = numSide *
numCorner + 2 * triQuads.size();
759 faces_vec =
new int4[nFaces];
763 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
765 for (
size_t i = 0; i < triQuads.size(); ++i)
778 a = triQuads[i][0] + addition;
779 b = triQuads[i][2] + addition;
780 c = triQuads[i][1] + addition;
783 G4int bc = std::abs(c - b);
784 G4int ca = std::abs(a - c);
785 faces_vec[iface][0] = (ab == 1 || ab ==
d)? a: -a;
786 faces_vec[iface][1] = (bc == 1 || bc ==
d)? b: -b;
787 faces_vec[iface][2] = (ca == 1 || ca ==
d)? c: -c;
788 faces_vec[iface][3] = 0;
795 xyz =
new double3[nNodes];
799 for (
G4int iSide = 0; iSide < numSide; ++iSide)
803 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
804 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
808 if (iCorner < numCorner - 1)
810 faces_vec[iface][0] = ixyz + 1;
811 faces_vec[iface][1] = -(ixyz + numCorner + 1);
812 faces_vec[iface][2] = ixyz + numCorner + 2;
813 faces_vec[iface][3] = ixyz + 2;
817 faces_vec[iface][0] = ixyz + 1;
818 faces_vec[iface][1] = -(ixyz + numCorner + 1);
819 faces_vec[iface][2] = ixyz + 2;
820 faces_vec[iface][3] = ixyz - numCorner + 2;
823 else if (iSide == numSide - 1)
825 if (iCorner < numCorner - 1)
827 faces_vec[iface][0] = ixyz + 1;
828 faces_vec[iface][1] = ixyz + numCorner + 1;
829 faces_vec[iface][2] = ixyz + numCorner + 2;
830 faces_vec[iface][3] = -(ixyz + 2);
834 faces_vec[iface][0] = ixyz + 1;
835 faces_vec[iface][1] = ixyz + numCorner + 1;
836 faces_vec[iface][2] = ixyz + 2;
837 faces_vec[iface][3] = -(ixyz - numCorner + 2);
842 if (iCorner < numCorner - 1)
844 faces_vec[iface][0] = ixyz + 1;
845 faces_vec[iface][1] = -(ixyz + numCorner + 1);
846 faces_vec[iface][2] = ixyz + numCorner + 2;
847 faces_vec[iface][3] = -(ixyz + 2);
851 faces_vec[iface][0] = ixyz + 1;
852 faces_vec[iface][1] = -(ixyz + numCorner + 1);
853 faces_vec[iface][2] = ixyz + 2;
854 faces_vec[iface][3] = -(ixyz - numCorner + 2);
867 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
868 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
877 xyz =
new double3[nNodes];
878 faces_vec =
new int4[nFaces];
881 G4int ixyz = 0, iface = 0;
882 for (
G4int iSide = 0; iSide < numSide; ++iSide)
886 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
887 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
890 if (iSide < numSide - 1)
892 if (iCorner < numCorner - 1)
894 faces_vec[iface][0] = ixyz + 1;
895 faces_vec[iface][1] = -(ixyz + numCorner + 1);
896 faces_vec[iface][2] = ixyz + numCorner + 2;
897 faces_vec[iface][3] = -(ixyz + 2);
901 faces_vec[iface][0] = ixyz + 1;
902 faces_vec[iface][1] = -(ixyz + numCorner + 1);
903 faces_vec[iface][2] = ixyz + 2;
904 faces_vec[iface][3] = -(ixyz - numCorner + 2);
909 if (iCorner < numCorner - 1)
911 faces_vec[iface][0] = ixyz + 1;
912 faces_vec[iface][1] = -(ixyz + numCorner - nFaces + 1);
913 faces_vec[iface][2] = ixyz + numCorner - nFaces + 2;
914 faces_vec[iface][3] = -(ixyz + 2);
918 faces_vec[iface][0] = ixyz + 1;
919 faces_vec[iface][1] = -(ixyz - nFaces + numCorner + 1);
920 faces_vec[iface][2] = ixyz - nFaces + 2;
921 faces_vec[iface][3] = -(ixyz - numCorner + 2);
937 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
938 G4Exception(
"G4GenericPolycone::CreatePolyhedron()",
"GeomSolids1002",
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
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
G4double GetStartPhi() const
G4double GetEndPhi() const
G4GenericPolycone(const G4String &name, G4double phiStart, G4double phiTotal, G4int numRZ, const G4double r[], const G4double z[])
G4PolyconeSideRZ * corners
CLHEP::Hep2Vector G4TwoVector
G4double GetCosStartPhi() const
void message(RunManager *runmanager)
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
static const G4double emax
G4double GetSinEndPhi() const
G4bool BisectedBy(G4double a1, G4double b1, G4double a2, G4double b2, G4double tolerance)
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
G4Polyhedron * CreatePolyhedron() const
G4double GetSinStartPhi() const
G4bool MustBeOutside(const G4ThreeVector &p) const
virtual EInside Inside(const G4ThreeVector &p) const
G4GeometryType GetEntityType() const
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
std::vector< G4ThreeVector > G4ThreeVectorList
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4GenericPolycone & operator=(const G4GenericPolycone &source)
virtual ~G4GenericPolycone()
G4double GetMinExtent(const EAxis pAxis) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
static constexpr double deg
G4bool RemoveDuplicateVertices(G4double tolerance)
EInside Inside(const G4ThreeVector &p) const
static constexpr double twopi
double A(double temperature)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
std::ostream & StreamInfo(std::ostream &os) const
G4bool CrossesItself(G4double tolerance)
G4PolyconeSideRZ GetCorner(G4int index) const
static G4int GetNumberOfRotationSteps()
void CopyStuff(const G4GenericPolycone &source)
G4ThreeVector GetPointOnSurface() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4int NumVertices() const
G4bool RemoveRedundantVertices(G4double tolerance)
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
G4ThreeVector GetPointOnSurfaceGeneric() const
G4EnclosingCylinder * enclosingCylinder
static constexpr double degree
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
double B(double temperature)
G4bool fRebuildPolyhedron
G4double GetCosEndPhi() const
G4int GetNumRZCorner() const
G4Polyhedron * fpPolyhedron