59 #if !defined(G4GEOM_USE_UPOLYHEDRA)
77 using namespace CLHEP;
96 std::ostringstream message;
97 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
98 <<
" No sides specified !";
99 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
108 { phiTotal =
twopi; }
109 G4double convertRad = std::cos(0.5*phiTotal/theNumSide);
125 for (i=0; i<numZPlanes; i++)
127 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
129 if( (rInner[i] > rOuter[i+1])
130 ||(rInner[i+1] > rOuter[i]) )
133 std::ostringstream message;
134 message <<
"Cannot create a Polyhedra with no contiguous segments."
136 <<
" Segments are not contiguous !" <<
G4endl
137 <<
" rMin[" << i <<
"] = " << rInner[i]
138 <<
" -- rMax[" << i+1 <<
"] = " << rOuter[i+1] <<
G4endl
139 <<
" rMin[" << i+1 <<
"] = " << rInner[i+1]
140 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
141 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
156 rz->
ScaleA( 1/convertRad );
161 Create( phiStart, phiTotal, theNumSide, rz );
181 std::ostringstream message;
182 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
183 <<
" No sides specified !";
184 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
190 Create( phiStart, phiTotal, theNumSide, rz );
214 if (rz->
Amin() < 0.0)
216 std::ostringstream message;
217 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
218 <<
" All R values must be >= 0 !";
219 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
230 std::ostringstream message;
231 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
232 <<
" R/Z cross section is zero or near zero: " << rzArea;
233 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
240 std::ostringstream message;
241 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
242 <<
" Too few unique R/Z values !";
243 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
249 std::ostringstream message;
250 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
251 <<
" R/Z segments cross !";
252 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
278 endPhi = phiStart+phiTotal;
302 next->
r = iterRZ.
GetA();
303 next->
z = iterRZ.
GetB();
304 }
while( ++next, iterRZ.
Next() );
356 }
while( prev=corner, corner=next, corner >
corners );
386 phiIsOpen(false), genericPgon(false), numCorner(0), corners(0),
387 original_parameters(0), enclosingCylinder(0)
419 if (
this == &source)
return *
this;
490 std::ostringstream message;
491 message <<
"Solid " <<
GetName() <<
" built using generic construct."
492 <<
G4endl <<
"Not applicable to the generic construct !";
493 G4Exception(
"G4Polyhedra::Reset()",
"GeomSolids1001",
583 if (corner.
r < rmin) rmin = corner.
r;
584 if (corner.
r > rmax) rmax = corner.
r;
585 if (corner.
z < zmin) zmin = corner.
z;
586 if (corner.
z > zmax) zmax = corner.
z;
600 G4double xmin = rmin*cosCur, xmax = xmin;
601 G4double ymin = rmin*sinCur, ymax = ymin;
602 for (
G4int k=0; k<ksteps+1; ++k)
605 if (x < xmin) xmin = x;
606 if (x > xmax) xmax = x;
608 if (y < ymin) ymin = y;
609 if (y > ymax) ymax = y;
613 if (xx < xmin) xmin = xx;
614 if (xx > xmax) xmax = xx;
616 if (yy < ymin) ymin = yy;
617 if (yy > ymax) ymax = yy;
620 sinCur = sinCur*cosStep + cosCur*sinStep;
621 cosCur = cosCur*cosStep - sinTmp*sinStep;
623 pMin.
set(xmin,ymin,zmin);
624 pMax.
set(xmax,ymax,zmax);
628 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
630 std::ostringstream message;
631 message <<
"Bad bounding box (min >= max) for solid: "
633 <<
"\npMin = " << pMin
634 <<
"\npMax = " << pMax;
657 if (
true)
return bbox.
CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
661 return exist = (pMin < pMax) ?
true :
false;
670 std::vector<G4int> iout;
682 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
687 std::ostringstream message;
688 message <<
"Triangulation of RZ contour has failed for solid: "
690 <<
"\nExtent has been calculated using boundary box";
708 std::vector<const G4ThreeVectorList *> polygons;
709 polygons.resize(ksteps+1);
710 for (
G4int k=0; k<ksteps+1; ++k) {
717 G4int ntria = triangles.size()/3;
718 for (
G4int i=0; i<ntria; ++i)
723 for (
G4int k=0; k<ksteps+1; ++k)
726 G4ThreeVectorList::iterator iter = ptr->begin();
727 iter->set(triangles[i3+0].x()*cosCur,
728 triangles[i3+0].x()*sinCur,
729 triangles[i3+0].y());
731 iter->set(triangles[i3+1].x()*cosCur,
732 triangles[i3+1].x()*sinCur,
733 triangles[i3+1].y());
735 iter->set(triangles[i3+2].x()*cosCur,
736 triangles[i3+2].x()*sinCur,
737 triangles[i3+2].y());
740 sinCur = sinCur*cosStep + cosCur*sinStep;
741 cosCur = cosCur*cosStep - sinTmp*sinStep;
747 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
748 if (emin < pMin) pMin = emin;
749 if (emax > pMax) pMax =
emax;
750 if (eminlim > pMin && emaxlim < pMax)
break;
753 for (
G4int k=0; k<ksteps+1; ++k) {
delete polygons[k]; polygons[k]=0;}
754 return (pMin < pMax);
791 G4int oldprc = os.precision(16);
792 os <<
"-----------------------------------------------------------\n"
793 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
794 <<
" ===================================================\n"
795 <<
" Solid type: G4Polyhedra\n"
798 <<
" ending phi angle : " <<
endPhi/
degree <<
" degrees \n"
799 <<
" number of sides : " <<
numSide <<
" \n";
804 os <<
" number of Z planes: " << numPlanes <<
"\n"
806 for (i=0; i<numPlanes; i++)
808 os <<
" Z plane " << i <<
": "
811 os <<
" Tangent distances to inner surface (Rmin): \n";
812 for (i=0; i<numPlanes; i++)
814 os <<
" Z plane " << i <<
": "
817 os <<
" Tangent distances to outer surface (Rmax): \n";
818 for (i=0; i<numPlanes; i++)
820 os <<
" Z plane " << i <<
": "
824 os <<
" number of RZ points: " <<
numCorner <<
"\n"
825 <<
" RZ values (corners): \n";
831 os <<
"-----------------------------------------------------------\n";
832 os.precision(oldprc);
847 G4double lambda1, lambda2, chose,aOne,aTwo;
858 if( (chose>=0.) && (chose < aOne) )
862 return (p2+lambda1*v+lambda2*w);
867 return (p0+lambda1*t+lambda2*u);
886 return (p2 + lambda1*w + lambda2*v);
898 G4double chose, totArea=0., Achose1, Achose2,
899 rad1, rad2, sinphi1, sinphi2, cosphi1, cosphi2;
900 G4double a, b, l2, rang, totalPhi, ksi,
901 area, aTop=0., aBottom=0., zVal=0.;
904 std::vector<G4double> aVector1;
905 std::vector<G4double> aVector2;
906 std::vector<G4double> aVector3;
914 for(j=0; j<numPlanes-1; j++)
920 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
921 aVector1.push_back(area);
924 for(j=0; j<numPlanes-1; j++)
930 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
931 aVector2.push_back(area);
934 for(j=0; j<numPlanes-1; j++)
945 else { aVector3.push_back(0.); }
948 for(j=0; j<numPlanes-1; j++)
950 totArea +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
960 aTop = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
968 aBottom = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+b)*cosksi;
972 Achose2 =
numSide*(aVector1[0]+aVector2[0])+2.*aVector3[0];
975 if( (chose >= 0.) && (chose < aTop + aBottom) )
978 rang = std::floor((chose-
startPhi)/ksi-0.01);
979 if(rang<0) { rang=0; }
980 rang = std::fabs(rang);
981 sinphi1 = std::sin(
startPhi+rang*ksi);
982 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
983 cosphi1 = std::cos(
startPhi+rang*ksi);
984 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
986 if(chose>=0. && chose<aTop)
1006 for (j=0; j<numPlanes-1; j++)
1008 if( ((chose >= Achose1) && (chose < Achose2)) || (j == numPlanes-2) )
1012 Achose1 +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
1013 Achose2 = Achose1 +
numSide*(aVector1[j+1]+aVector2[j+1])
1023 totArea =
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
1026 if( (chose>=0.) && (chose<
numSide*aVector1[j]) )
1029 rang = std::floor((chose-
startPhi)/ksi-0.01);
1030 if(rang<0) { rang=0; }
1031 rang = std::fabs(rang);
1034 sinphi1 = std::sin(
startPhi+rang*ksi);
1035 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
1036 cosphi1 = std::cos(
startPhi+rang*ksi);
1037 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
1049 else if ( (chose >=
numSide*aVector1[j])
1050 && (chose <=
numSide*(aVector1[j]+aVector2[j])) )
1053 rang = std::floor((chose-
startPhi)/ksi-0.01);
1054 if(rang<0) { rang=0; }
1055 rang = std::fabs(rang);
1058 sinphi1 = std::sin(
startPhi+rang*ksi);
1059 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
1060 cosphi1 = std::cos(
startPhi+rang*ksi);
1061 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
1075 if( (chose>=0.) && (chose < 1.) )
1150 typedef G4int int4[4];
1157 std::vector<G4bool> chopped(
numCorner,
false);
1158 std::vector<G4int*> triQuads;
1161 while (remaining >= 3)
1166 G4int iStepper = iStarter;
1169 if (A < 0) { A = iStepper; }
1170 else if (
B < 0) {
B = iStepper; }
1171 else if (
C < 0) {
C = iStepper; }
1174 if (++iStepper >=
numCorner) iStepper = 0;
1176 while (chopped[iStepper]);
1178 while (
C < 0 && iStepper != iStarter);
1193 triQuads.push_back(tq);
1201 if (++iStarter >=
numCorner) { iStarter = 0; }
1203 while (chopped[iStarter]);
1211 faces_vec =
new int4[nFaces];
1215 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
1217 for (
size_t i = 0; i < triQuads.size(); ++i)
1230 a = triQuads[i][0] + addition;
1231 b = triQuads[i][2] + addition;
1232 c = triQuads[i][1] + addition;
1235 G4int bc = std::abs(c - b);
1236 G4int ca = std::abs(a - c);
1237 faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
1238 faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
1239 faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
1240 faces_vec[iface][3] = 0;
1247 xyz =
new double3[nNodes];
1255 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1256 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1258 if (iCorner < numCorner - 1)
1260 faces_vec[iface][0] = ixyz + 1;
1261 faces_vec[iface][1] = ixyz + numCorner + 1;
1262 faces_vec[iface][2] = ixyz + numCorner + 2;
1263 faces_vec[iface][3] = ixyz + 2;
1267 faces_vec[iface][0] = ixyz + 1;
1268 faces_vec[iface][1] = ixyz + numCorner + 1;
1269 faces_vec[iface][2] = ixyz + 2;
1270 faces_vec[iface][3] = ixyz - numCorner + 2;
1282 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1283 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1292 xyz =
new double3[nNodes];
1293 faces_vec =
new int4[nFaces];
1298 G4int ixyz = 0, iface = 0;
1303 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1304 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1306 if (iSide < numSide - 1)
1308 if (iCorner < numCorner - 1)
1310 faces_vec[iface][0] = ixyz + 1;
1311 faces_vec[iface][1] = ixyz + numCorner + 1;
1312 faces_vec[iface][2] = ixyz + numCorner + 2;
1313 faces_vec[iface][3] = ixyz + 2;
1317 faces_vec[iface][0] = ixyz + 1;
1318 faces_vec[iface][1] = ixyz + numCorner + 1;
1319 faces_vec[iface][2] = ixyz + 2;
1320 faces_vec[iface][3] = ixyz - numCorner + 2;
1325 if (iCorner < numCorner - 1)
1327 faces_vec[iface][0] = ixyz + 1;
1328 faces_vec[iface][1] = ixyz + numCorner - nFaces + 1;
1329 faces_vec[iface][2] = ixyz + numCorner - nFaces + 2;
1330 faces_vec[iface][3] = ixyz + 2;
1334 faces_vec[iface][0] = ixyz + 1;
1335 faces_vec[iface][1] = ixyz - nFaces + numCorner + 1;
1336 faces_vec[iface][2] = ixyz - nFaces + 2;
1337 faces_vec[iface][3] = ixyz - numCorner + 2;
1348 delete [] faces_vec;
1352 std::ostringstream message;
1353 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
1354 G4Exception(
"G4Polyhedra::CreatePolyhedron()",
"GeomSolids1002",
1370 G4bool isConvertible=
true;
1376 std::vector<G4double>
Z;
1377 std::vector<G4double> Rmin;
1378 std::vector<G4double> Rmax;
1380 G4int countPlanes=1;
1391 Rmax.push_back (
corners[1].r);icurr=1;
1393 else if (Zprev ==
corners[numPlanes-1].z)
1395 Rmin.push_back(
corners[numPlanes-1].r);
1396 Rmax.push_back (
corners[0].r);
1402 Rmax.push_back (
corners[0].r);
1407 G4int inextr=0, inextl=0;
1408 for (
G4int i=0; i < numPlanes-2; i++)
1411 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1413 if((
corners[inextr].z >= Zmax) & (
corners[inextl].
z >= Zmax)) {
break; }
1428 Rmin.push_back(
corners[inextl].r);
1429 Rmax.push_back(
corners[icurr].r);
1433 Rmin.push_back(
corners[inextl].r);
1442 Rmin.push_back(
corners[icurl].r);
1443 Rmax.push_back(
corners[icurr].r);
1447 Rmin.push_back(
corners[icurl].r);
1454 isConvertible=
false;
break;
1456 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1464 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1466 Rmin.push_back(
corners[inextl].r);
1467 Rmax.push_back (
corners[inextr].r);
1471 Z.push_back(Zright);
1480 Rmax.push_back(
corners[inextr].r);
1481 Rmin.push_back(
corners[icurr].r);
1485 Rmin.push_back(
corners[icurl].r + (Zright-
corners[icurl].z)/difZl
1487 Rmax.push_back(
corners[inextr].r);
1495 Rmax.push_back(
corners[inextr].r);
1496 Rmin.push_back (
corners[icurr].r);
1500 Rmax.push_back(
corners[inextr].r);
1508 isConvertible=
false;
break;
1518 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1520 Rmax.push_back(
corners[inextr].r);
1521 Rmin.push_back(
corners[inextl].r);
1533 for(
G4int j=0; j < countPlanes; j++)
1547 std::ostringstream message;
1549 <<
"cannot be converted to Polyhedra with (Rmin,Rmaz,Z) parameters!";
1550 G4Exception(
"G4Polyhedra::SetOriginalParameters()",
1559 for(
G4int j=0; j < numPlanes; j++)
void set(double x, double y, double z)
void CopyStuff(const G4Polyhedra &source)
G4bool CrossesItself(G4double tolerance)
ThreeVector shoot(const G4int Ap, const G4int Af)
void Extent(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
G4bool fRebuildPolyhedron
G4Polyhedron * fpPolyhedron
static const G4double kInfinity
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
CLHEP::Hep3Vector G4ThreeVector
G4double GetCosStartPhi() const
G4GeometryType GetEntityType() const
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
G4PolyhedraHistorical * original_parameters
G4ThreeVector GetPointOnPlane(G4ThreeVector p0, G4ThreeVector p1, G4ThreeVector p2, G4ThreeVector p3) const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4double GetSinStartPhi() const
G4PolyhedraSideRZ * corners
G4bool MustBeOutside(const G4ThreeVector &p) const
double B(double temperature)
G4double GetEndPhi() const
void Create(G4double phiStart, G4double phiTotal, G4int numSide, G4ReduciblePolygon *rz)
G4ThreeVector GetPointOnSurface() const
static constexpr double twopi
G4int GetNumRZCorner() const
static double normal(HepRandomEngine *eptr)
G4bool RemoveDuplicateVertices(G4double tolerance)
G4EnclosingCylinder * enclosingCylinder
G4bool RemoveRedundantVertices(G4double tolerance)
G4ThreeVector GetPointOnSurfaceGeneric() const
double A(double temperature)
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4int NumVertices() const
static constexpr double degree
void ScaleA(G4double scale)
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
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static const G4double emax
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
EInside Inside(const G4ThreeVector &p) const
G4Polyhedron * CreatePolyhedron() const
G4Polyhedra & operator=(const G4Polyhedra &source)
CLHEP::Hep2Vector G4TwoVector
G4double GetStartPhi() const
G4PolyhedraSideRZ GetCorner(const G4int index) const
void SetOriginalParameters(G4PolyhedraHistorical *pars)
G4double GetMaxExtent(const EAxis pAxis) const
G4ThreeVector GetPointOnTriangle(G4ThreeVector p0, G4ThreeVector p1, G4ThreeVector p2) const
virtual EInside Inside(const G4ThreeVector &p) const
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
std::ostream & StreamInfo(std::ostream &os) const
G4double GetMinExtent(const EAxis pAxis) const
G4Polyhedra(const G4String &name, G4double phiStart, G4double phiTotal, G4int numSide, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])