33#if !defined(G4GEOM_USE_UGENERICPOLYCONE)
70 Create( phiStart, phiTotal, rz );
93 std::ostringstream message;
94 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
95 <<
" All R values must be >= 0 !";
96 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
107 std::ostringstream message;
108 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
109 <<
" R/Z cross section is zero or near zero: " << rzArea;
110 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
117 std::ostringstream message;
118 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
119 <<
" Too few unique R/Z values !";
120 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
126 std::ostringstream message;
127 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
128 <<
" R/Z segments cross !";
129 G4Exception(
"G4GenericPolycone::Create()",
"GeomSolids0002",
139 if (phiTotal <= 0 || phiTotal > twopi-1E-10)
156 endPhi = phiStart+phiTotal;
175 next->
r = iterRZ.
GetA();
176 next->
z = iterRZ.
GetB();
177 }
while( ++next, iterRZ.
Next() );
201 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
209 if (corner->
z > next->
z)
226 }
while( prev=corner, corner=next, corner >
corners );
284 if (
this == &source)
return *
this;
344 std::ostringstream message;
345 message <<
"Solid " <<
GetName() <<
" built using generic construct."
346 <<
G4endl <<
"Not applicable to the generic construct !";
347 G4Exception(
"G4GenericPolycone::Reset()",
"GeomSolids1001",
405 G4double rmin = kInfinity, rmax = -kInfinity;
406 G4double zmin = kInfinity, zmax = -kInfinity;
411 if (corner.
r < rmin) rmin = corner.
r;
412 if (corner.
r > rmax) rmax = corner.
r;
413 if (corner.
z < zmin) zmin = corner.
z;
414 if (corner.
z > zmax) zmax = corner.
z;
424 pMin.
set(vmin.
x(),vmin.
y(),zmin);
425 pMax.
set(vmax.
x(),vmax.
y(),zmax);
429 pMin.
set(-rmax,-rmax, zmin);
430 pMax.
set( rmax, rmax, zmax);
435 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
437 std::ostringstream message;
438 message <<
"Bad bounding box (min >= max) for solid: "
440 <<
"\npMin = " << pMin
441 <<
"\npMax = " << pMax;
442 G4Exception(
"GenericG4Polycone::BoundingLimits()",
"GeomMgt0001",
470 return exist = (pMin < pMax) ?
true :
false;
489 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
494 std::ostringstream message;
495 message <<
"Triangulation of RZ contour has failed for solid: "
497 <<
"\nExtent has been calculated using boundary box";
498 G4Exception(
"G4GenericPolycone::CalculateExtent()",
504 const G4int NSTEPS = 24;
510 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-deg)/astep) + 1;
513 G4double sinHalf = std::sin(0.5*ang);
514 G4double cosHalf = std::cos(0.5*ang);
515 G4double sinStep = 2.*sinHalf*cosHalf;
516 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
524 std::vector<const G4ThreeVectorList *> polygons;
525 polygons.resize(ksteps+2);
527 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
528 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
535 G4int ntria = triangles.size()/3;
536 for (
G4int i=0; i<ntria; ++i)
539 for (
G4int k=0; k<3; ++k)
541 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
544 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
545 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
549 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
555 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
556 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
557 for (
G4int j=0; j<6; ++j)
559 pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
561 for (
G4int k=1; k<ksteps+1; ++k)
563 for (
G4int j=0; j<6; ++j)
565 pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
568 sinCur = sinCur*cosStep + cosCur*sinStep;
569 cosCur = cosCur*cosStep - sinTmp*sinStep;
571 for (
G4int j=0; j<6; ++j)
573 pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
579 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
580 if (emin < pMin) pMin = emin;
581 if (emax > pMax) pMax = emax;
582 if (eminlim > pMin && emaxlim < pMax)
return true;
584 return (pMin < pMax);
591 return G4String(
"G4GenericPolycone");
609 G4int oldprc = os.precision(16);
610 os <<
"-----------------------------------------------------------\n"
611 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
612 <<
" ===================================================\n"
613 <<
" Solid type: G4GenericPolycone\n"
615 <<
" starting phi angle : " <<
startPhi/degree <<
" degrees \n"
616 <<
" ending phi angle : " <<
endPhi/degree <<
" degrees \n";
619 os <<
" number of RZ points: " <<
numCorner <<
"\n"
620 <<
" RZ values (corners): \n";
626 os <<
"-----------------------------------------------------------\n";
627 os.precision(oldprc);
643 for (
G4int i=0; i<nrz; ++i)
646 total += (b.
r*b.
r + b.
r*a.
r + a.
r*a.
r)*(b.
z - a.
z);
668 for (
G4int i=0; i<nrz; ++i)
671 scut += a.
r*b.
z - a.
z*b.
r;
674 scut = std::abs(scut);
679 for (
G4int i=0; i<nrz; ++i)
683 slat += (b.
r + a.
r)*h;
699 fElements =
new std::vector<G4GenericPolycone::surface_element>;
706 for (
G4int ib=0; ib<nrz; ++ib)
715 if (a.
r == 0. && b.
r == 0.)
continue;
717 sarea += 0.5*dphi*(b.
r + a.
r)*h;
726 std::vector<G4int> triangles;
727 for (
G4int i=0; i<nrz; ++i)
733 G4int ntria = triangles.size();
734 for (
G4int i=0; i<ntria; i+=3)
737 selem.
i0 = triangles[i];
738 selem.
i1 = triangles[i+1];
739 selem.
i2 = triangles[i+2];
776 ->
G4bool { return x.area < val; });
796 r = (p1.
r - p0.
r)*u + p0.
r;
797 z = (p1.
z - p0.
z)*u + p0.
z;
801 r = std::sqrt(p1.
r*p1.
r*u + p0.
r*p0.
r*(1. - u));
802 z = p0.
z + (p1.
z - p0.
z)*(r - p0.
r)/(p1.
r - p0.
r);
810 if (i0 >= nrz) { i0 -= nrz; }
814 if (u + v > 1.) { u = 1. - u; v = 1. - v; }
815 r = (p1.
r - p0.
r)*u + (p2.
r - p0.
r)*v + p0.
r;
816 z = (p1.
z - p0.
z)*u + (p2.
z - p0.
z)*v + p0.
z;
849 const G4int numSide =
856 typedef G4int int4[4];
863 std::vector<G4bool> chopped(
numCorner,
false);
864 std::vector<G4int*> triQuads;
867 while (remaining >= 3)
872 G4int iStepper = iStarter;
875 if (
A < 0) {
A = iStepper; }
876 else if (
B < 0) {
B = iStepper; }
877 else if (
C < 0) {
C = iStepper; }
880 if (++iStepper >=
numCorner) { iStepper = 0; }
882 while (chopped[iStepper]);
884 while (
C < 0 && iStepper != iStarter);
899 triQuads.push_back(tq);
907 if (++iStarter >=
numCorner) { iStarter = 0; }
909 while (chopped[iStarter]);
915 nFaces = numSide *
numCorner + 2 * triQuads.size();
916 faces_vec =
new int4[nFaces];
920 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
922 for (
size_t i = 0; i < triQuads.size(); ++i)
935 a = triQuads[i][0] + addition;
936 b = triQuads[i][2] + addition;
937 c = triQuads[i][1] + addition;
939 G4int ab = std::abs(b - a);
940 G4int bc = std::abs(c - b);
941 G4int ca = std::abs(a - c);
942 faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
943 faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
944 faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
945 faces_vec[iface][3] = 0;
952 xyz =
new double3[nNodes];
956 for (
G4int iSide = 0; iSide < numSide; ++iSide)
960 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
961 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
967 faces_vec[iface][0] = ixyz + 1;
968 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
969 faces_vec[iface][2] = ixyz +
numCorner + 2;
970 faces_vec[iface][3] = ixyz + 2;
974 faces_vec[iface][0] = ixyz + 1;
975 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
976 faces_vec[iface][2] = ixyz + 2;
977 faces_vec[iface][3] = ixyz -
numCorner + 2;
980 else if (iSide == numSide - 1)
984 faces_vec[iface][0] = ixyz + 1;
985 faces_vec[iface][1] = ixyz +
numCorner + 1;
986 faces_vec[iface][2] = ixyz +
numCorner + 2;
987 faces_vec[iface][3] = -(ixyz + 2);
991 faces_vec[iface][0] = ixyz + 1;
992 faces_vec[iface][1] = ixyz +
numCorner + 1;
993 faces_vec[iface][2] = ixyz + 2;
994 faces_vec[iface][3] = -(ixyz -
numCorner + 2);
1001 faces_vec[iface][0] = ixyz + 1;
1002 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1003 faces_vec[iface][2] = ixyz +
numCorner + 2;
1004 faces_vec[iface][3] = -(ixyz + 2);
1008 faces_vec[iface][0] = ixyz + 1;
1009 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1010 faces_vec[iface][2] = ixyz + 2;
1011 faces_vec[iface][3] = -(ixyz -
numCorner + 2);
1024 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1025 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1034 xyz =
new double3[nNodes];
1035 faces_vec =
new int4[nFaces];
1038 G4int ixyz = 0, iface = 0;
1039 for (
G4int iSide = 0; iSide < numSide; ++iSide)
1043 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1044 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1047 if (iSide < numSide - 1)
1051 faces_vec[iface][0] = ixyz + 1;
1052 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1053 faces_vec[iface][2] = ixyz +
numCorner + 2;
1054 faces_vec[iface][3] = -(ixyz + 2);
1058 faces_vec[iface][0] = ixyz + 1;
1059 faces_vec[iface][1] = -(ixyz +
numCorner + 1);
1060 faces_vec[iface][2] = ixyz + 2;
1061 faces_vec[iface][3] = -(ixyz -
numCorner + 2);
1068 faces_vec[iface][0] = ixyz + 1;
1069 faces_vec[iface][1] = -(ixyz +
numCorner - nFaces + 1);
1070 faces_vec[iface][2] = ixyz +
numCorner - nFaces + 2;
1071 faces_vec[iface][3] = -(ixyz + 2);
1075 faces_vec[iface][0] = ixyz + 1;
1076 faces_vec[iface][1] = -(ixyz - nFaces +
numCorner + 1);
1077 faces_vec[iface][2] = ixyz - nFaces + 2;
1078 faces_vec[iface][3] = -(ixyz -
numCorner + 2);
1089 delete [] faces_vec;
1093 std::ostringstream message;
1094 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
1095 G4Exception(
"G4GenericPolycone::CreatePolyhedron()",
"GeomSolids1002",
std::vector< G4ThreeVector > G4ThreeVectorList
double B(double temperature)
double A(double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
CLHEP::Hep2Vector G4TwoVector
void set(double x, double y, double z)
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool MustBeOutside(const G4ThreeVector &p) const
G4double GetSurfaceArea()
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
void SetSurfaceElements() const
G4PolyconeSideRZ * corners
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4EnclosingCylinder * enclosingCylinder
G4double GetStartPhi() const
void CopyStuff(const G4GenericPolycone &source)
G4GenericPolycone & operator=(const G4GenericPolycone &source)
G4double GetCubicVolume()
G4double GetEndPhi() const
G4int GetNumRZCorner() const
G4GeometryType GetEntityType() const
G4double GetCosEndPhi() const
G4double GetSinStartPhi() const
G4PolyconeSideRZ GetCorner(G4int index) const
G4ThreeVector GetPointOnSurface() const
G4double GetSinEndPhi() const
std::ostream & StreamInfo(std::ostream &os) const
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
G4GenericPolycone(const G4String &name, G4double phiStart, G4double phiTotal, G4int numRZ, const G4double r[], const G4double z[])
G4Polyhedron * CreatePolyhedron() const
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4double GetCosStartPhi() const
std::vector< surface_element > * fElements
EInside Inside(const G4ThreeVector &p) const
virtual ~G4GenericPolycone()
G4bool BisectedBy(G4double a1, G4double b1, G4double a2, G4double b2, G4double tolerance)
G4bool RemoveDuplicateVertices(G4double tolerance)
G4int NumVertices() const
G4bool RemoveRedundantVertices(G4double tolerance)
G4bool CrossesItself(G4double tolerance)
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
virtual EInside Inside(const G4ThreeVector &p) const
G4Polyhedron * fpPolyhedron
G4bool fRebuildPolyhedron
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const
static G4int GetNumberOfRotationSteps()
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])