42 #if !defined(G4GEOM_USE_UGENERICPOLYCONE)
59 using namespace CLHEP;
75 Create( phiStart, phiTotal, rz );
99 std::ostringstream message;
100 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
101 <<
" All R values must be >= 0 !";
102 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
113 std::ostringstream message;
114 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
115 <<
" R/Z cross section is zero or near zero: " << rzArea;
116 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
123 std::ostringstream message;
124 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
125 <<
" Too few unique R/Z values !";
126 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
132 std::ostringstream message;
133 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
134 <<
" R/Z segments cross !";
135 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
145 if (phiTotal <= 0 || phiTotal >
twopi-1E-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;
349 std::ostringstream message;
350 message <<
"Solid " <<
GetName() <<
" built using generic construct."
351 <<
G4endl <<
"Not applicable to the generic construct !";
352 G4Exception(
"G4GenericPolycone::Reset()",
"GeomSolids1001",
422 if (corner.
r < rmin) rmin = corner.
r;
423 if (corner.
r > rmax) rmax = corner.
r;
424 if (corner.
z < zmin) zmin = corner.
z;
425 if (corner.
z > zmax) zmax = corner.
z;
435 pMin.
set(vmin.
x(),vmin.
y(),zmin);
436 pMax.
set(vmax.
x(),vmax.
y(),zmax);
440 pMin.
set(-rmax,-rmax, zmin);
441 pMax.
set( rmax, rmax, zmax);
446 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
448 std::ostringstream message;
449 message <<
"Bad bounding box (min >= max) for solid: "
451 <<
"\npMin = " << pMin
452 <<
"\npMax = " << pMax;
453 G4Exception(
"GenericG4Polycone::Extent()",
"GeomMgt0001",
477 if (
true)
return bbox.
CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
481 return exist = (pMin < pMax) ?
true :
false;
500 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
505 std::ostringstream message;
506 message <<
"Triangulation of RZ contour has failed for solid: "
508 <<
"\nExtent has been calculated using boundary box";
509 G4Exception(
"G4GenericPolycone::CalculateExtent()",
515 const G4int NSTEPS = 24;
521 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-
deg)/astep) + 1;
524 G4double sinHalf = std::sin(0.5*ang);
525 G4double cosHalf = std::cos(0.5*ang);
526 G4double sinStep = 2.*sinHalf*cosHalf;
527 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
535 std::vector<const G4ThreeVectorList *> polygons;
536 polygons.resize(ksteps+2);
538 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
539 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
546 G4int ntria = triangles.size()/3;
547 for (
G4int i=0; i<ntria; ++i)
550 for (
G4int k=0; k<3; ++k)
552 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
555 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
556 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
560 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
566 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
567 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
568 for (
G4int j=0; j<6; ++j)
570 pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
572 for (
G4int k=1; k<ksteps+1; ++k)
574 for (
G4int j=0; j<6; ++j)
576 pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
579 sinCur = sinCur*cosStep + cosCur*sinStep;
580 cosCur = cosCur*cosStep - sinTmp*sinStep;
582 for (
G4int j=0; j<6; ++j)
584 pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
590 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
591 if (emin < pMin) pMin = emin;
592 if (emax > pMax) pMax =
emax;
593 if (eminlim > pMin && emaxlim < pMax)
return true;
595 return (pMin < pMax);
613 return G4String(
"G4GenericPolycone");
630 G4int oldprc = os.precision(16);
631 os <<
"-----------------------------------------------------------\n"
632 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
633 <<
" ===================================================\n"
634 <<
" Solid type: G4GenericPolycone\n"
637 <<
" ending phi angle : " <<
endPhi/
degree <<
" degrees \n";
640 os <<
" number of RZ points: " <<
numCorner <<
"\n"
641 <<
" RZ values (corners): \n";
647 os <<
"-----------------------------------------------------------\n";
648 os.precision(oldprc);
691 const G4int numSide =
698 typedef G4int int4[4];
705 std::vector<G4bool> chopped(
numCorner,
false);
706 std::vector<G4int*> triQuads;
709 while (remaining >= 3)
714 G4int iStepper = iStarter;
717 if (A < 0) { A = iStepper; }
718 else if (
B < 0) {
B = iStepper; }
719 else if (
C < 0) {
C = iStepper; }
722 if (++iStepper >=
numCorner) { iStepper = 0; }
724 while (chopped[iStepper]);
726 while (
C < 0 && iStepper != iStarter);
741 triQuads.push_back(tq);
749 if (++iStarter >=
numCorner) { iStarter = 0; }
751 while (chopped[iStarter]);
757 nFaces = numSide *
numCorner + 2 * triQuads.size();
758 faces_vec =
new int4[nFaces];
762 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
764 for (
size_t i = 0; i < triQuads.size(); ++i)
777 a = triQuads[i][0] + addition;
778 b = triQuads[i][2] + addition;
779 c = triQuads[i][1] + addition;
782 G4int bc = std::abs(c - b);
783 G4int ca = std::abs(a - c);
784 faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
785 faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
786 faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
787 faces_vec[iface][3] = 0;
794 xyz =
new double3[nNodes];
798 for (
G4int iSide = 0; iSide < numSide; ++iSide)
802 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
803 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
807 if (iCorner < numCorner - 1)
809 faces_vec[iface][0] = ixyz + 1;
810 faces_vec[iface][1] = -(ixyz + numCorner + 1);
811 faces_vec[iface][2] = ixyz + numCorner + 2;
812 faces_vec[iface][3] = ixyz + 2;
816 faces_vec[iface][0] = ixyz + 1;
817 faces_vec[iface][1] = -(ixyz + numCorner + 1);
818 faces_vec[iface][2] = ixyz + 2;
819 faces_vec[iface][3] = ixyz - numCorner + 2;
822 else if (iSide == numSide - 1)
824 if (iCorner < numCorner - 1)
826 faces_vec[iface][0] = ixyz + 1;
827 faces_vec[iface][1] = ixyz + numCorner + 1;
828 faces_vec[iface][2] = ixyz + numCorner + 2;
829 faces_vec[iface][3] = -(ixyz + 2);
833 faces_vec[iface][0] = ixyz + 1;
834 faces_vec[iface][1] = ixyz + numCorner + 1;
835 faces_vec[iface][2] = ixyz + 2;
836 faces_vec[iface][3] = -(ixyz - numCorner + 2);
841 if (iCorner < numCorner - 1)
843 faces_vec[iface][0] = ixyz + 1;
844 faces_vec[iface][1] = -(ixyz + numCorner + 1);
845 faces_vec[iface][2] = ixyz + numCorner + 2;
846 faces_vec[iface][3] = -(ixyz + 2);
850 faces_vec[iface][0] = ixyz + 1;
851 faces_vec[iface][1] = -(ixyz + numCorner + 1);
852 faces_vec[iface][2] = ixyz + 2;
853 faces_vec[iface][3] = -(ixyz - numCorner + 2);
866 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
867 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
876 xyz =
new double3[nNodes];
877 faces_vec =
new int4[nFaces];
880 G4int ixyz = 0, iface = 0;
881 for (
G4int iSide = 0; iSide < numSide; ++iSide)
885 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
886 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
889 if (iSide < numSide - 1)
891 if (iCorner < numCorner - 1)
893 faces_vec[iface][0] = ixyz + 1;
894 faces_vec[iface][1] = -(ixyz + numCorner + 1);
895 faces_vec[iface][2] = ixyz + numCorner + 2;
896 faces_vec[iface][3] = -(ixyz + 2);
900 faces_vec[iface][0] = ixyz + 1;
901 faces_vec[iface][1] = -(ixyz + numCorner + 1);
902 faces_vec[iface][2] = ixyz + 2;
903 faces_vec[iface][3] = -(ixyz - numCorner + 2);
908 if (iCorner < numCorner - 1)
910 faces_vec[iface][0] = ixyz + 1;
911 faces_vec[iface][1] = -(ixyz + numCorner - nFaces + 1);
912 faces_vec[iface][2] = ixyz + numCorner - nFaces + 2;
913 faces_vec[iface][3] = -(ixyz + 2);
917 faces_vec[iface][0] = ixyz + 1;
918 faces_vec[iface][1] = -(ixyz - nFaces + numCorner + 1);
919 faces_vec[iface][2] = ixyz - nFaces + 2;
920 faces_vec[iface][3] = -(ixyz - numCorner + 2);
935 std::ostringstream message;
936 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
937 G4Exception(
"G4GenericPolycone::CreatePolyhedron()",
"GeomSolids1002",
void set(double x, double y, double z)
G4PolyconeSideRZ GetCorner(G4int index) const
G4bool CrossesItself(G4double tolerance)
G4double GetCosStartPhi() const
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
G4bool fRebuildPolyhedron
G4Polyhedron * fpPolyhedron
static const G4double kInfinity
G4PolyconeSideRZ * corners
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4double GetCosEndPhi() const
G4bool MustBeOutside(const G4ThreeVector &p) const
double B(double temperature)
G4double GetSinStartPhi() const
G4GenericPolycone(const G4String &name, G4double phiStart, G4double phiTotal, G4int numRZ, const G4double r[], const G4double z[])
static constexpr double twopi
G4double GetEndPhi() const
G4GeometryType GetEntityType() const
G4Polyhedron * CreatePolyhedron() const
G4bool RemoveDuplicateVertices(G4double tolerance)
G4ThreeVector GetPointOnSurface() const
G4EnclosingCylinder * enclosingCylinder
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
G4bool RemoveRedundantVertices(G4double tolerance)
G4ThreeVector GetPointOnSurfaceGeneric() const
double A(double temperature)
G4int NumVertices() const
void CopyStuff(const G4GenericPolycone &source)
static constexpr double degree
std::ostream & StreamInfo(std::ostream &os) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
void Extent(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4double GetStartPhi() const
G4double GetSinEndPhi() const
std::vector< G4ThreeVector > G4ThreeVectorList
virtual ~G4GenericPolycone()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static const G4double emax
G4GenericPolycone & operator=(const G4GenericPolycone &source)
EInside Inside(const G4ThreeVector &p) const
static G4int GetNumberOfRotationSteps()
G4bool BisectedBy(G4double a1, G4double b1, G4double a2, G4double b2, G4double tolerance)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
CLHEP::Hep2Vector G4TwoVector
static constexpr double deg
G4double GetMaxExtent(const EAxis pAxis) const
virtual EInside Inside(const G4ThreeVector &p) const
G4int GetNumRZCorner() const
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
G4double GetMinExtent(const EAxis pAxis) const