44#if !defined(G4GEOM_USE_UPOLYHEDRA)
83 std::ostringstream message;
84 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
85 <<
" No sides specified !";
86 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
94 if ( (phiTotal <=0) || (phiTotal >= twopi*(1-
DBL_EPSILON)) )
96 G4double convertRad = std::cos(0.5*phiTotal/theNumSide);
111 for (
G4int i=0; i<numZPlanes; ++i)
113 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
115 if( (rInner[i] > rOuter[i+1])
116 ||(rInner[i+1] > rOuter[i]) )
119 std::ostringstream message;
120 message <<
"Cannot create a Polyhedra with no contiguous segments."
122 <<
" Segments are not contiguous !" <<
G4endl
123 <<
" rMin[" << i <<
"] = " << rInner[i]
124 <<
" -- rMax[" << i+1 <<
"] = " << rOuter[i+1] <<
G4endl
125 <<
" rMin[" << i+1 <<
"] = " << rInner[i+1]
126 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
127 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
141 rz->ScaleA( 1/convertRad );
146 Create( phiStart, phiTotal, theNumSide, rz );
164 std::ostringstream message;
165 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
166 <<
" No sides specified !";
167 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
173 Create( phiStart, phiTotal, theNumSide, rz );
195 if (rz->
Amin() < 0.0)
197 std::ostringstream message;
198 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
199 <<
" All R values must be >= 0 !";
200 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
211 std::ostringstream message;
212 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
213 <<
" R/Z cross section is zero or near zero: " << rzArea;
214 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
221 std::ostringstream message;
222 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
223 <<
" Too few unique R/Z values !";
224 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
230 std::ostringstream message;
231 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
232 <<
" R/Z segments cross !";
233 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
247 if ( (phiTotal <= 0) || (phiTotal > twopi*(1-
DBL_EPSILON)) )
277 next->
r = iterRZ.
GetA();
278 next->
z = iterRZ.
GetB();
279 }
while( ++next, iterRZ.
Next() );
306 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
331 }
while( prev=corner, corner=next, corner >
corners );
390 if (
this == &source)
return *
this;
466 std::ostringstream message;
467 message <<
"Solid " <<
GetName() <<
" built using generic construct."
468 <<
G4endl <<
"Not applicable to the generic construct !";
469 G4Exception(
"G4Polyhedra::Reset()",
"GeomSolids1001",
550 G4double rmin = kInfinity, rmax = -kInfinity;
551 G4double zmin = kInfinity, zmax = -kInfinity;
555 if (corner.
r < rmin) rmin = corner.
r;
556 if (corner.
r > rmax) rmax = corner.
r;
557 if (corner.
z < zmin) zmin = corner.
z;
558 if (corner.
z > zmax) zmax = corner.
z;
572 G4double xmin = rmin*cosCur, xmax = xmin;
573 G4double ymin = rmin*sinCur, ymax = ymin;
574 for (
G4int k=0; k<ksteps+1; ++k)
577 if (x < xmin) xmin = x;
578 if (x > xmax) xmax = x;
580 if (y < ymin) ymin = y;
581 if (y > ymax) ymax = y;
585 if (xx < xmin) xmin = xx;
586 if (xx > xmax) xmax = xx;
588 if (yy < ymin) ymin = yy;
589 if (yy > ymax) ymax = yy;
592 sinCur = sinCur*cosStep + cosCur*sinStep;
593 cosCur = cosCur*cosStep - sinTmp*sinStep;
595 pMin.
set(xmin,ymin,zmin);
596 pMax.
set(xmax,ymax,zmax);
600 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
602 std::ostringstream message;
603 message <<
"Bad bounding box (min >= max) for solid: "
605 <<
"\npMin = " << pMin
606 <<
"\npMax = " << pMax;
607 G4Exception(
"G4Polyhedra::BoundingLimits()",
"GeomMgt0001",
632 return exist = pMin < pMax;
641 std::vector<G4int> iout;
649 contourRZ.emplace_back(corner.
r,corner.
z);
653 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
658 std::ostringstream message;
659 message <<
"Triangulation of RZ contour has failed for solid: "
661 <<
"\nExtent has been calculated using boundary box";
679 std::vector<const G4ThreeVectorList *> polygons;
680 polygons.resize(ksteps+1);
681 for (
G4int k=0; k<ksteps+1; ++k)
690 for (
G4int i=0; i<ntria; ++i)
695 for (
G4int k=0; k<ksteps+1; ++k)
698 auto iter = ptr->begin();
699 iter->set(triangles[i3+0].x()*cosCur,
700 triangles[i3+0].x()*sinCur,
701 triangles[i3+0].y());
703 iter->set(triangles[i3+1].x()*cosCur,
704 triangles[i3+1].x()*sinCur,
705 triangles[i3+1].y());
707 iter->set(triangles[i3+2].x()*cosCur,
708 triangles[i3+2].x()*sinCur,
709 triangles[i3+2].y());
712 sinCur = sinCur*cosStep + cosCur*sinStep;
713 cosCur = cosCur*cosStep - sinTmp*sinStep;
719 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
720 if (emin < pMin) pMin = emin;
721 if (emax > pMax) pMax = emax;
722 if (eminlim > pMin && emaxlim < pMax)
break;
725 for (
G4int k=0; k<ksteps+1; ++k) {
delete polygons[k]; polygons[k]=
nullptr;}
726 return (pMin < pMax);
742 return {
"G4Polyhedra"};
756 G4long oldprc = os.precision(16);
757 os <<
"-----------------------------------------------------------\n"
758 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
759 <<
" ===================================================\n"
760 <<
" Solid type: G4Polyhedra\n"
762 <<
" starting phi angle : " <<
startPhi/degree <<
" degrees \n"
763 <<
" ending phi angle : " <<
endPhi/degree <<
" degrees \n"
764 <<
" number of sides : " <<
numSide <<
" \n";
769 os <<
" number of Z planes: " << numPlanes <<
"\n"
771 for (i=0; i<numPlanes; ++i)
773 os <<
" Z plane " << i <<
": "
776 os <<
" Tangent distances to inner surface (Rmin): \n";
777 for (i=0; i<numPlanes; ++i)
779 os <<
" Z plane " << i <<
": "
782 os <<
" Tangent distances to outer surface (Rmax): \n";
783 for (i=0; i<numPlanes; ++i)
785 os <<
" Z plane " << i <<
": "
789 os <<
" number of RZ points: " <<
numCorner <<
"\n"
790 <<
" RZ values (corners): \n";
796 os <<
"-----------------------------------------------------------\n";
797 os.precision(oldprc);
813 for (
G4int i=0; i<nrz; ++i)
816 total += (b.
r*b.
r + b.
r*a.
r + a.
r*a.
r)*(b.
z - a.
z);
838 for (
G4int i=0; i<nrz; ++i)
841 total += a.
r*b.
z - a.
z*b.
r;
844 total = std::abs(total);
850 for (
G4int i=0; i<nrz; ++i)
872 fElements =
new std::vector<G4Polyhedra::surface_element>;
881 for (
G4int ib=0; ib<nrz; ++ib)
889 if (a.
r == 0. && b.
r == 0.)
continue;
914 std::vector<G4int> triangles;
915 for (
G4int i=0; i<nrz; ++i)
918 contourRZ.emplace_back(corner.
r, corner.
z);
921 auto ntria = (
G4int)triangles.size();
922 for (
G4int i=0; i<ntria; i+=3)
925 selem.
i0 = triangles[i];
926 selem.
i1 = triangles[i+1];
927 selem.
i2 = triangles[i+2];
964 ->
G4bool { return x.area < val; });
970 if (u + v > 1.) { u = 1. - u; v = 1. - v; }
986 if (i2 == -1) p1.
set(a.
r*cosa, a.
r*sina, a.
z);
987 p0 += (p1 - p0)*u + (p2 - p0)*v;
991 G4int iside = nside*(select - sprev)/(scurr - sprev);
1000 if (iside == nside) --iside;
1004 x = p0.
x()*cosphi - p0.
y()*sinphi;
1005 y = p0.
x()*sinphi + p0.
y()*cosphi;
1013 if (i0 >= nrz) { i0 -= nrz; }
1018 x = r*std::cos(phi);
1019 y = r*std::sin(phi);
1020 z = (p1.
z - p0.
z)*u + (p2.
z - p0.
z)*v + p0.
z;
1042 G4bool isConvertible =
true;
1048 std::vector<G4double> Z;
1049 std::vector<G4double> Rmin;
1050 std::vector<G4double> Rmax;
1052 G4int countPlanes=1;
1063 Rmax.push_back (
corners[1].r);icurr=1;
1065 else if (Zprev ==
corners[numPlanes-1].z)
1067 Rmin.push_back(
corners[numPlanes-1].r);
1068 Rmax.push_back (
corners[0].r);
1074 Rmax.push_back (
corners[0].r);
1079 G4int inextr=0, inextl=0;
1080 for (
G4int i=0; i < numPlanes-2; ++i)
1083 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1085 if((
corners[inextr].z >= Zmax) & (
corners[inextl].z >= Zmax)) {
break; }
1100 Rmin.push_back(
corners[inextl].r);
1101 Rmax.push_back(
corners[icurr].r);
1105 Rmin.push_back(
corners[inextl].r);
1114 Rmin.push_back(
corners[icurl].r);
1115 Rmax.push_back(
corners[icurr].r);
1119 Rmin.push_back(
corners[icurl].r);
1126 isConvertible=
false;
break;
1128 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1136 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1138 Rmin.push_back(
corners[inextl].r);
1139 Rmax.push_back (
corners[inextr].r);
1143 Z.push_back(Zright);
1152 Rmax.push_back(
corners[inextr].r);
1153 Rmin.push_back(
corners[icurr].r);
1157 Rmin.push_back(
corners[icurl].r + (Zright-
corners[icurl].z)/difZl
1159 Rmax.push_back(
corners[inextr].r);
1167 Rmax.push_back(
corners[inextr].r);
1168 Rmin.push_back (
corners[icurr].r);
1172 Rmax.push_back(
corners[inextr].r);
1180 isConvertible=
false;
break;
1190 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1192 Rmax.push_back(
corners[inextr].r);
1193 Rmin.push_back(
corners[inextl].r);
1205 for(
G4int j=0; j < countPlanes; ++j)
1219 std::ostringstream message;
1221 <<
"cannot be converted to Polyhedra with (Rmin,Rmaz,Z) parameters!";
1222 G4Exception(
"G4Polyhedra::SetOriginalParameters()",
1231 for(
G4int j=0; j < numPlanes; ++j)
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
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
EInside Inside(const G4ThreeVector &p) const override
G4Polyhedra & operator=(const G4Polyhedra &source)
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep) override
G4GeometryType GetEntityType() const override
G4PolyhedraHistorical * original_parameters
G4double GetSurfaceArea() override
G4PolyhedraSideRZ * corners
G4Polyhedra(const G4String &name, G4double phiStart, G4double phiTotal, G4int numSide, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
G4int GetNumRZCorner() const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const override
G4ThreeVector GetPointOnSurface() const override
void CopyStuff(const G4Polyhedra &source)
G4double GetSinStartPhi() const
void Create(G4double phiStart, G4double phiTotal, G4int numSide, G4ReduciblePolygon *rz)
G4double GetEndPhi() const
std::vector< surface_element > * fElements
void SetOriginalParameters(G4PolyhedraHistorical *pars)
G4VSolid * Clone() const override
G4Polyhedron * CreatePolyhedron() const override
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
G4PolyhedraSideRZ GetCorner(const G4int index) const
std::ostream & StreamInfo(std::ostream &os) const override
G4double GetStartPhi() const
G4EnclosingCylinder * enclosingCylinder
G4double GetCosStartPhi() const
void SetSurfaceElements() const
G4double GetCubicVolume() override
G4bool RemoveDuplicateVertices(G4double tolerance)
G4int NumVertices() const
G4bool RemoveRedundantVertices(G4double tolerance)
G4bool CrossesItself(G4double tolerance)
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
EInside Inside(const G4ThreeVector &p) const override
G4Polyhedron * fpPolyhedron
G4bool fRebuildPolyhedron
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const