44 #if !defined(G4GEOM_USE_UPOLYHEDRA)
62 using namespace CLHEP;
81 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
82 <<
" No sides specified !";
83 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
93 G4double convertRad = std::cos(0.5*phiTotal/theNumSide);
108 for (
G4int i=0; i<numZPlanes; ++i)
110 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
112 if( (rInner[i] > rOuter[i+1])
113 ||(rInner[i+1] > rOuter[i]) )
117 message <<
"Cannot create a Polyhedra with no contiguous segments."
119 <<
" Segments are not contiguous !" <<
G4endl
120 <<
" rMin[" << i <<
"] = " << rInner[i]
121 <<
" -- rMax[" << i+1 <<
"] = " << rOuter[i+1] <<
G4endl
122 <<
" rMin[" << i+1 <<
"] = " << rInner[i+1]
123 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
124 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
139 rz->
ScaleA( 1/convertRad );
144 Create( phiStart, phiTotal, theNumSide, rz );
163 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
164 <<
" No sides specified !";
165 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
171 Create( phiStart, phiTotal, theNumSide, rz );
193 if (rz->
Amin() < 0.0)
196 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
197 <<
" All R values must be >= 0 !";
198 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
210 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
211 <<
" R/Z cross section is zero or near zero: " << rzArea;
212 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
220 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
221 <<
" Too few unique R/Z values !";
222 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
229 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
230 <<
" R/Z segments cross !";
231 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
257 endPhi = phiStart+phiTotal;
281 next->
r = iterRZ.
GetA();
282 next->
z = iterRZ.
GetB();
283 }
while( ++next, iterRZ.
Next() );
335 }
while( prev=corner, corner=next, corner >
corners );
387 if (
this == &source)
return *
this;
454 message <<
"Solid " <<
GetName() <<
" built using generic construct."
455 <<
G4endl <<
"Not applicable to the generic construct !";
456 G4Exception(
"G4Polyhedra::Reset()",
"GeomSolids1001",
539 if (corner.
r < rmin) rmin = corner.
r;
540 if (corner.
r > rmax) rmax = corner.
r;
541 if (corner.
z < zmin) zmin = corner.
z;
542 if (corner.
z > zmax) zmax = corner.
z;
561 if (x < xmin) xmin =
x;
562 if (x > xmax) xmax =
x;
564 if (y < ymin) ymin =
y;
565 if (y > ymax) ymax =
y;
569 if (xx < xmin) xmin =
xx;
570 if (xx > xmax) xmax =
xx;
572 if (yy < ymin) ymin = yy;
573 if (yy > ymax) ymax = yy;
576 sinCur = sinCur*cosStep + cosCur*sinStep;
577 cosCur = cosCur*cosStep - sinTmp*sinStep;
579 pMin.
set(xmin,ymin,zmin);
580 pMax.
set(xmax,ymax,zmax);
584 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
587 message <<
"Bad bounding box (min >= max) for solid: "
589 <<
"\npMin = " << pMin
590 <<
"\npMax = " <<
pMax;
591 G4Exception(
"G4Polyhedra::BoundingLimits()",
"GeomMgt0001",
616 return exist = (pMin <
pMax) ?
true :
false;
625 std::vector<G4int> iout;
637 if (area < 0.)
std::reverse(contourRZ.begin(),contourRZ.end());
643 message <<
"Triangulation of RZ contour has failed for solid: "
645 <<
"\nExtent has been calculated using boundary box";
663 std::vector<const G4ThreeVectorList *> polygons;
664 polygons.resize(ksteps+1);
673 G4int ntria = triangles.size()/3;
674 for (
G4int i=0; i<ntria; ++i)
682 G4ThreeVectorList::iterator iter = ptr->begin();
683 iter->set(triangles[i3+0].
x()*cosCur,
684 triangles[i3+0].
x()*sinCur,
685 triangles[i3+0].
y());
687 iter->set(triangles[i3+1].
x()*cosCur,
688 triangles[i3+1].
x()*sinCur,
689 triangles[i3+1].
y());
691 iter->set(triangles[i3+2].
x()*cosCur,
692 triangles[i3+2].
x()*sinCur,
693 triangles[i3+2].
y());
696 sinCur = sinCur*cosStep + cosCur*sinStep;
697 cosCur = cosCur*cosStep - sinTmp*sinStep;
703 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
704 if (emin < pMin) pMin =
emin;
705 if (emax > pMax) pMax =
emax;
706 if (eminlim > pMin && emaxlim < pMax)
break;
709 for (
G4int k=0;
k<ksteps+1; ++
k) {
delete polygons[
k]; polygons[
k]=0;}
710 return (pMin < pMax);
740 G4int oldprc = os.precision(16);
741 os <<
"-----------------------------------------------------------\n"
742 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
743 <<
" ===================================================\n"
744 <<
" Solid type: G4Polyhedra\n"
747 <<
" ending phi angle : " <<
endPhi/
degree <<
" degrees \n"
748 <<
" number of sides : " <<
numSide <<
" \n";
753 os <<
" number of Z planes: " << numPlanes <<
"\n"
755 for (i=0; i<numPlanes; ++i)
757 os <<
" Z plane " << i <<
": "
760 os <<
" Tangent distances to inner surface (Rmin): \n";
761 for (i=0; i<numPlanes; ++i)
763 os <<
" Z plane " << i <<
": "
766 os <<
" Tangent distances to outer surface (Rmax): \n";
767 for (i=0; i<numPlanes; ++i)
769 os <<
" Z plane " << i <<
": "
773 os <<
" number of RZ points: " <<
numCorner <<
"\n"
774 <<
" RZ values (corners): \n";
780 os <<
"-----------------------------------------------------------\n";
781 os.precision(oldprc);
794 G4double lambda1, lambda2, chose,aOne,aTwo;
805 if( (chose>=0.) && (chose < aOne) )
809 return (p2+lambda1*v+lambda2*w);
814 return (p0+lambda1*t+lambda2*u);
831 return (p2 + lambda1*w + lambda2*v);
841 G4double chose, totArea=0., Achose1, Achose2,
842 rad1, rad2, sinphi1, sinphi2, cosphi1, cosphi2;
844 area, aTop=0., aBottom=0., zVal=0.;
847 std::vector<G4double> aVector1;
848 std::vector<G4double> aVector2;
849 std::vector<G4double> aVector3;
857 for(j=0; j<numPlanes-1; ++j)
863 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+
b)*cosksi;
864 aVector1.push_back(area);
867 for(j=0; j<numPlanes-1; ++j)
873 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+
b)*cosksi;
874 aVector2.push_back(area);
877 for(j=0; j<numPlanes-1; ++j)
888 else { aVector3.push_back(0.); }
891 for(j=0; j<numPlanes-1; ++j)
893 totArea +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
903 aTop = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+
b)*cosksi;
911 aBottom = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+
b)*cosksi;
915 Achose2 =
numSide*(aVector1[0]+aVector2[0])+2.*aVector3[0];
918 if( (chose >= 0.) && (chose < aTop + aBottom) )
921 rang = std::floor((chose-
startPhi)/ksi-0.01);
922 if(rang<0) { rang=0; }
923 rang = std::fabs(rang);
924 sinphi1 = std::sin(
startPhi+rang*ksi);
925 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
926 cosphi1 = std::cos(
startPhi+rang*ksi);
927 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
929 if(chose>=0. && chose<aTop)
949 for (j=0; j<numPlanes-1; ++j)
951 if( ((chose >= Achose1) && (chose < Achose2)) || (j == numPlanes-2) )
955 Achose1 +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
956 Achose2 = Achose1 +
numSide*(aVector1[j+1]+aVector2[j+1])
966 totArea =
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
969 if( (chose>=0.) && (chose<
numSide*aVector1[j]) )
972 rang = std::floor((chose-
startPhi)/ksi-0.01);
973 if(rang<0) { rang=0; }
974 rang = std::fabs(rang);
977 sinphi1 = std::sin(
startPhi+rang*ksi);
978 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
979 cosphi1 = std::cos(
startPhi+rang*ksi);
980 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
992 else if ( (chose >=
numSide*aVector1[j])
993 && (chose <=
numSide*(aVector1[j]+aVector2[j])) )
996 rang = std::floor((chose-
startPhi)/ksi-0.01);
997 if(rang<0) { rang=0; }
998 rang = std::fabs(rang);
1001 sinphi1 = std::sin(
startPhi+rang*ksi);
1002 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
1003 cosphi1 = std::cos(
startPhi+rang*ksi);
1004 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
1018 if( (chose>=0.) && (chose < 1.) )
1092 typedef G4int int4[4];
1099 std::vector<G4bool> chopped(
numCorner,
false);
1100 std::vector<G4int*> triQuads;
1103 while (remaining >= 3)
1108 G4int iStepper = iStarter;
1111 if (A < 0) { A = iStepper; }
1112 else if (
B < 0) {
B = iStepper; }
1113 else if (
C < 0) {
C = iStepper; }
1116 if (++iStepper >=
numCorner) iStepper = 0;
1118 while (chopped[iStepper]);
1120 while (
C < 0 && iStepper != iStarter);
1135 triQuads.push_back(tq);
1143 if (++iStarter >=
numCorner) { iStarter = 0; }
1145 while (chopped[iStarter]);
1153 faces_vec =
new int4[nFaces];
1157 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
1159 for (
size_t i = 0; i < triQuads.size(); ++i)
1172 a = triQuads[i][0] + addition;
1173 b = triQuads[i][2] + addition;
1174 c = triQuads[i][1] + addition;
1179 faces_vec[iface][0] = (ab == 1 || ab ==
d)? a: -a;
1180 faces_vec[iface][1] = (bc == 1 || bc ==
d)? b: -b;
1181 faces_vec[iface][2] = (ca == 1 || ca ==
d)? c: -c;
1182 faces_vec[iface][3] = 0;
1189 xyz =
new double3[nNodes];
1197 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1198 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1200 if (iCorner < numCorner - 1)
1202 faces_vec[iface][0] = ixyz + 1;
1203 faces_vec[iface][1] = ixyz + numCorner + 1;
1204 faces_vec[iface][2] = ixyz + numCorner + 2;
1205 faces_vec[iface][3] = ixyz + 2;
1209 faces_vec[iface][0] = ixyz + 1;
1210 faces_vec[iface][1] = ixyz + numCorner + 1;
1211 faces_vec[iface][2] = ixyz + 2;
1212 faces_vec[iface][3] = ixyz - numCorner + 2;
1224 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1225 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1234 xyz =
new double3[nNodes];
1235 faces_vec =
new int4[nFaces];
1240 G4int ixyz = 0, iface = 0;
1245 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1246 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1248 if (iSide < numSide - 1)
1250 if (iCorner < numCorner - 1)
1252 faces_vec[iface][0] = ixyz + 1;
1253 faces_vec[iface][1] = ixyz + numCorner + 1;
1254 faces_vec[iface][2] = ixyz + numCorner + 2;
1255 faces_vec[iface][3] = ixyz + 2;
1259 faces_vec[iface][0] = ixyz + 1;
1260 faces_vec[iface][1] = ixyz + numCorner + 1;
1261 faces_vec[iface][2] = ixyz + 2;
1262 faces_vec[iface][3] = ixyz - numCorner + 2;
1267 if (iCorner < numCorner - 1)
1269 faces_vec[iface][0] = ixyz + 1;
1270 faces_vec[iface][1] = ixyz + numCorner - nFaces + 1;
1271 faces_vec[iface][2] = ixyz + numCorner - nFaces + 2;
1272 faces_vec[iface][3] = ixyz + 2;
1276 faces_vec[iface][0] = ixyz + 1;
1277 faces_vec[iface][1] = ixyz - nFaces + numCorner + 1;
1278 faces_vec[iface][2] = ixyz - nFaces + 2;
1279 faces_vec[iface][3] = ixyz - numCorner + 2;
1290 delete [] faces_vec;
1295 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
1296 G4Exception(
"G4Polyhedra::CreatePolyhedron()",
"GeomSolids1002",
1313 G4bool isConvertible =
true;
1319 std::vector<G4double>
Z;
1320 std::vector<G4double> Rmin;
1321 std::vector<G4double> Rmax;
1323 G4int countPlanes=1;
1334 Rmax.push_back (
corners[1].r);icurr=1;
1336 else if (Zprev ==
corners[numPlanes-1].z)
1338 Rmin.push_back(
corners[numPlanes-1].
r);
1345 Rmax.push_back (
corners[0].r);
1350 G4int inextr=0, inextl=0;
1351 for (
G4int i=0; i < numPlanes-2; ++i)
1354 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1372 Rmax.push_back(
corners[icurr].r);
1386 Rmax.push_back(
corners[icurr].r);
1397 isConvertible=
false;
break;
1399 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1407 icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1410 Rmax.push_back (
corners[inextr].r);
1414 Z.push_back(Zright);
1424 Rmin.push_back(
corners[icurr].r);
1430 Rmax.push_back(
corners[inextr].r);
1439 Rmin.push_back (
corners[icurr].r);
1451 isConvertible=
false;
break;
1461 inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1464 Rmin.push_back(
corners[inextl].r);
1476 for(
G4int j=0; j < countPlanes; ++j)
1492 <<
"cannot be converted to Polyhedra with (Rmin,Rmaz,Z) parameters!";
1493 G4Exception(
"G4Polyhedra::SetOriginalParameters()",
1502 for(
G4int j=0; j < numPlanes; ++j)