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",
142 rz->
ScaleA( 1/convertRad );
147 Create( phiStart, phiTotal, theNumSide, rz );
165 std::ostringstream message;
166 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
167 <<
" No sides specified !";
168 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
174 Create( phiStart, phiTotal, theNumSide, rz );
196 if (rz->
Amin() < 0.0)
198 std::ostringstream message;
199 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
200 <<
" All R values must be >= 0 !";
201 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
212 std::ostringstream message;
213 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
214 <<
" R/Z cross section is zero or near zero: " << rzArea;
215 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
222 std::ostringstream message;
223 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
224 <<
" Too few unique R/Z values !";
225 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
231 std::ostringstream message;
232 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
233 <<
" R/Z segments cross !";
234 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
248 if ( (phiTotal <= 0) || (phiTotal > twopi*(1-
DBL_EPSILON)) )
278 next->
r = iterRZ.
GetA();
279 next->
z = iterRZ.
GetB();
280 }
while( ++next, iterRZ.
Next() );
307 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
332 }
while( prev=corner, corner=next, corner >
corners );
391 if (
this == &source)
return *
this;
467 std::ostringstream message;
468 message <<
"Solid " <<
GetName() <<
" built using generic construct."
469 <<
G4endl <<
"Not applicable to the generic construct !";
470 G4Exception(
"G4Polyhedra::Reset()",
"GeomSolids1001",
552 G4double rmin = kInfinity, rmax = -kInfinity;
553 G4double zmin = kInfinity, zmax = -kInfinity;
557 if (corner.
r < rmin) rmin = corner.
r;
558 if (corner.
r > rmax) rmax = corner.
r;
559 if (corner.
z < zmin) zmin = corner.
z;
560 if (corner.
z > zmax) zmax = corner.
z;
574 G4double xmin = rmin*cosCur, xmax = xmin;
575 G4double ymin = rmin*sinCur, ymax = ymin;
576 for (
G4int k=0; k<ksteps+1; ++k)
579 if (x < xmin) xmin = x;
580 if (x > xmax) xmax = x;
582 if (y < ymin) ymin = y;
583 if (y > ymax) ymax = y;
587 if (xx < xmin) xmin = xx;
588 if (xx > xmax) xmax = xx;
590 if (yy < ymin) ymin = yy;
591 if (yy > ymax) ymax = yy;
594 sinCur = sinCur*cosStep + cosCur*sinStep;
595 cosCur = cosCur*cosStep - sinTmp*sinStep;
597 pMin.
set(xmin,ymin,zmin);
598 pMax.
set(xmax,ymax,zmax);
602 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
604 std::ostringstream message;
605 message <<
"Bad bounding box (min >= max) for solid: "
607 <<
"\npMin = " << pMin
608 <<
"\npMax = " << pMax;
609 G4Exception(
"G4Polyhedra::BoundingLimits()",
"GeomMgt0001",
634 return exist = (pMin < pMax) ?
true :
false;
643 std::vector<G4int> iout;
655 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
660 std::ostringstream message;
661 message <<
"Triangulation of RZ contour has failed for solid: "
663 <<
"\nExtent has been calculated using boundary box";
681 std::vector<const G4ThreeVectorList *> polygons;
682 polygons.resize(ksteps+1);
683 for (
G4int k=0; k<ksteps+1; ++k)
692 for (
G4int i=0; i<ntria; ++i)
697 for (
G4int k=0; k<ksteps+1; ++k)
700 G4ThreeVectorList::iterator iter = ptr->begin();
701 iter->set(triangles[i3+0].x()*cosCur,
702 triangles[i3+0].x()*sinCur,
703 triangles[i3+0].y());
705 iter->set(triangles[i3+1].x()*cosCur,
706 triangles[i3+1].x()*sinCur,
707 triangles[i3+1].y());
709 iter->set(triangles[i3+2].x()*cosCur,
710 triangles[i3+2].x()*sinCur,
711 triangles[i3+2].y());
714 sinCur = sinCur*cosStep + cosCur*sinStep;
715 cosCur = cosCur*cosStep - sinTmp*sinStep;
721 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
722 if (emin < pMin) pMin = emin;
723 if (emax > pMax) pMax = emax;
724 if (eminlim > pMin && emaxlim < pMax)
break;
727 for (
G4int k=0; k<ksteps+1; ++k) {
delete polygons[k]; polygons[k]=0;}
728 return (pMin < pMax);
758 G4long oldprc = os.precision(16);
759 os <<
"-----------------------------------------------------------\n"
760 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
761 <<
" ===================================================\n"
762 <<
" Solid type: G4Polyhedra\n"
764 <<
" starting phi angle : " <<
startPhi/degree <<
" degrees \n"
765 <<
" ending phi angle : " <<
endPhi/degree <<
" degrees \n"
766 <<
" number of sides : " <<
numSide <<
" \n";
771 os <<
" number of Z planes: " << numPlanes <<
"\n"
773 for (i=0; i<numPlanes; ++i)
775 os <<
" Z plane " << i <<
": "
778 os <<
" Tangent distances to inner surface (Rmin): \n";
779 for (i=0; i<numPlanes; ++i)
781 os <<
" Z plane " << i <<
": "
784 os <<
" Tangent distances to outer surface (Rmax): \n";
785 for (i=0; i<numPlanes; ++i)
787 os <<
" Z plane " << i <<
": "
791 os <<
" number of RZ points: " <<
numCorner <<
"\n"
792 <<
" RZ values (corners): \n";
798 os <<
"-----------------------------------------------------------\n";
799 os.precision(oldprc);
815 for (
G4int i=0; i<nrz; ++i)
818 total += (b.
r*b.
r + b.
r*a.
r + a.
r*a.
r)*(b.
z - a.
z);
840 for (
G4int i=0; i<nrz; ++i)
843 total += a.
r*b.
z - a.
z*b.
r;
846 total = std::abs(total);
852 for (
G4int i=0; i<nrz; ++i)
874 fElements =
new std::vector<G4Polyhedra::surface_element>;
883 for (
G4int ib=0; ib<nrz; ++ib)
891 if (a.
r == 0. && b.
r == 0.)
continue;
916 std::vector<G4int> triangles;
917 for (
G4int i=0; i<nrz; ++i)
924 for (
G4int i=0; i<ntria; i+=3)
927 selem.
i0 = triangles[i];
928 selem.
i1 = triangles[i+1];
929 selem.
i2 = triangles[i+2];
966 ->
G4bool { return x.area < val; });
972 if (u + v > 1.) { u = 1. - u; v = 1. - v; }
988 if (i2 == -1) p1.
set(a.
r*cosa, a.
r*sina, a.
z);
989 p0 += (p1 - p0)*u + (p2 - p0)*v;
993 G4int iside = nside*(select - sprev)/(scurr - sprev);
1002 if (iside == nside) --iside;
1006 x = p0.
x()*cosphi - p0.
y()*sinphi;
1007 y = p0.
x()*sinphi + p0.
y()*cosphi;
1015 if (i0 >= nrz) { i0 -= nrz; }
1020 x = r*std::cos(phi);
1021 y = r*std::sin(phi);
1022 z = (p1.
z - p0.
z)*u + (p2.
z - p0.
z)*v + p0.
z;
1044 G4bool isConvertible =
true;
1050 std::vector<G4double>
Z;
1051 std::vector<G4double> Rmin;
1052 std::vector<G4double> Rmax;
1054 G4int countPlanes=1;
1065 Rmax.push_back (
corners[1].r);icurr=1;
1067 else if (Zprev ==
corners[numPlanes-1].z)
1069 Rmin.push_back(
corners[numPlanes-1].r);
1070 Rmax.push_back (
corners[0].r);
1076 Rmax.push_back (
corners[0].r);
1081 G4int inextr=0, inextl=0;
1082 for (
G4int i=0; i < numPlanes-2; ++i)
1085 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1087 if((
corners[inextr].z >= Zmax) & (
corners[inextl].
z >= Zmax)) {
break; }
1102 Rmin.push_back(
corners[inextl].r);
1103 Rmax.push_back(
corners[icurr].r);
1107 Rmin.push_back(
corners[inextl].r);
1116 Rmin.push_back(
corners[icurl].r);
1117 Rmax.push_back(
corners[icurr].r);
1121 Rmin.push_back(
corners[icurl].r);
1128 isConvertible=
false;
break;
1130 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1138 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1140 Rmin.push_back(
corners[inextl].r);
1141 Rmax.push_back (
corners[inextr].r);
1145 Z.push_back(Zright);
1154 Rmax.push_back(
corners[inextr].r);
1155 Rmin.push_back(
corners[icurr].r);
1159 Rmin.push_back(
corners[icurl].r + (Zright-
corners[icurl].z)/difZl
1161 Rmax.push_back(
corners[inextr].r);
1169 Rmax.push_back(
corners[inextr].r);
1170 Rmin.push_back (
corners[icurr].r);
1174 Rmax.push_back(
corners[inextr].r);
1182 isConvertible=
false;
break;
1192 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1194 Rmax.push_back(
corners[inextr].r);
1195 Rmin.push_back(
corners[inextl].r);
1207 for(
G4int j=0; j < countPlanes; ++j)
1221 std::ostringstream message;
1223 <<
"cannot be converted to Polyhedra with (Rmin,Rmaz,Z) parameters!";
1224 G4Exception(
"G4Polyhedra::SetOriginalParameters()",
1233 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
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
G4ThreeVector GetPointOnSurface() const
G4Polyhedra & operator=(const G4Polyhedra &source)
std::ostream & StreamInfo(std::ostream &os) const
G4PolyhedraHistorical * original_parameters
G4double GetCubicVolume()
G4PolyhedraSideRZ * corners
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4Polyhedra(const G4String &name, G4double phiStart, G4double phiTotal, G4int numSide, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
G4int GetNumRZCorner() const
void CopyStuff(const G4Polyhedra &source)
G4double GetSinStartPhi() const
void Create(G4double phiStart, G4double phiTotal, G4int numSide, G4ReduciblePolygon *rz)
G4GeometryType GetEntityType() const
G4double GetSurfaceArea()
G4double GetEndPhi() const
std::vector< surface_element > * fElements
void SetOriginalParameters(G4PolyhedraHistorical *pars)
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4PolyhedraSideRZ GetCorner(const G4int index) const
G4double GetStartPhi() const
G4EnclosingCylinder * enclosingCylinder
G4double GetCosStartPhi() const
void SetSurfaceElements() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
EInside Inside(const G4ThreeVector &p) const
G4Polyhedron * CreatePolyhedron() const
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4bool RemoveDuplicateVertices(G4double tolerance)
G4int NumVertices() const
G4bool RemoveRedundantVertices(G4double tolerance)
G4bool CrossesItself(G4double tolerance)
void ScaleA(G4double scale)
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
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const