35 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) ) 
   42 using namespace CLHEP;
 
   58   : G4USolid(name, new UPolyhedra(name,phiStart, phiTotal, numSide,
 
   59                                   numZPlanes, zPlane, rInner, rOuter))
 
   61   wrStart = phiStart; 
while (wrStart < 0) wrStart += 
twopi;
 
   68   G4double convertRad = 1./std::cos(0.5*wrDelta/wrNumSide);
 
   70   for (
G4int i=0; i<numZPlanes; ++i)
 
   76   for (
G4int i=numZPlanes-1; i>=0; --i)
 
   82   std::vector<G4int> iout;
 
   91 G4UPolyhedra::G4UPolyhedra(
const G4String& name, 
 
   98   : G4USolid(name, new UPolyhedra(name, phiStart, phiTotal, numSide,
 
  101   wrStart = phiStart; 
while (wrStart < 0) wrStart += 
twopi;
 
  108   G4double convertRad = 1./std::cos(0.5*wrDelta/wrNumSide);
 
  110   for (
G4int i=0; i<numRZ; ++i)
 
  112     rzcorners.push_back(
G4TwoVector(r[i]*convertRad,z[i]));
 
  114   std::vector<G4int> iout;
 
  124 G4UPolyhedra::G4UPolyhedra( __void__& a )
 
  134 G4UPolyhedra::~G4UPolyhedra()
 
  143 G4UPolyhedra::G4UPolyhedra( 
const G4UPolyhedra &source )
 
  146   wrStart   = source.wrStart;
 
  147   wrDelta   = source.wrDelta;
 
  148   wrNumSide = source.wrNumSide;
 
  149   rzcorners = source.rzcorners;
 
  157 G4UPolyhedra& G4UPolyhedra::operator=( 
const G4UPolyhedra &source )
 
  159   if (
this == &source) 
return *
this;
 
  161   G4USolid::operator=( source );
 
  162   wrStart   = source.wrStart;
 
  163   wrDelta   = source.wrDelta;
 
  164   wrNumSide = source.wrNumSide;
 
  165   rzcorners = source.rzcorners;
 
  175 G4int G4UPolyhedra::GetNumSide()
 const 
  179 G4double G4UPolyhedra::GetStartPhi()
 const 
  183 G4double G4UPolyhedra::GetEndPhi()
 const 
  185   return (wrStart + wrDelta);
 
  187 G4double G4UPolyhedra::GetSinStartPhi()
 const 
  190   return std::sin(phi);
 
  192 G4double G4UPolyhedra::GetCosStartPhi()
 const 
  195   return std::cos(phi);
 
  197 G4double G4UPolyhedra::GetSinEndPhi()
 const 
  200   return std::sin(phi);
 
  202 G4double G4UPolyhedra::GetCosEndPhi()
 const 
  205   return std::cos(phi);
 
  207 G4bool G4UPolyhedra::IsOpen()
 const 
  209   return (wrDelta < 
twopi);
 
  211 G4bool G4UPolyhedra::IsGeneric()
 const 
  213   return GetShape()->IsGeneric();
 
  215 G4int G4UPolyhedra::GetNumRZCorner()
 const 
  217   return rzcorners.size();
 
  228   UPolyhedraHistorical* pars = GetShape()->GetOriginalParameters();
 
  232   pdata->
numSide = pars->fNumSide;
 
  233   for (
G4int i=0; i<pars->fNumZPlanes; ++i)
 
  235     pdata->
Z_values[i] = pars->fZValues[i];
 
  236     pdata->
Rmin[i] = pars->Rmin[i];
 
  237     pdata->
Rmax[i] = pars->Rmax[i];
 
  243   UPolyhedraHistorical* pdata = GetShape()->GetOriginalParameters();
 
  246   pdata->fNumSide = pars->
numSide;
 
  248   for (
G4int i=0; i<pdata->fNumZPlanes; ++i)
 
  250     pdata->fZValues[i] = pars->
Z_values[i];
 
  251     pdata->Rmin[i] = pars->
Rmin[i];
 
  252     pdata->Rmax[i] = pars->
Rmax[i];
 
  254   fRebuildPolyhedron = 
true;
 
  256   wrStart = pdata->fStartAngle; 
while (wrStart < 0) wrStart += 
twopi;
 
  257   wrDelta = pdata->fOpeningAngle;
 
  262   wrNumSide = pdata->fNumSide;
 
  263   G4double convertRad = 1./std::cos(0.5*wrDelta/wrNumSide);
 
  265   for (
G4int i=0; i<pdata->fNumZPlanes; ++i)
 
  268     G4double r = pdata->Rmax[i]*convertRad;
 
  271   for (
G4int i=pdata->fNumZPlanes-1; i>=0; --i)
 
  274     G4double r = pdata->Rmin[i]*convertRad;
 
  277   std::vector<G4int> iout;
 
  280 G4bool G4UPolyhedra::Reset()
 
  282   return GetShape()->Reset();
 
  303 G4VSolid* G4UPolyhedra::Clone()
 const 
  305   return new G4UPolyhedra(*
this);
 
  315   static G4bool checkBBox = 
true;
 
  316   static G4bool checkPhi  = 
true;
 
  320   for (
G4int i=0; i<GetNumRZCorner(); ++i)
 
  323     if (corner.
r < rmin) rmin = corner.
r;
 
  324     if (corner.
r > rmax) rmax = corner.
r;
 
  325     if (corner.
z < zmin) zmin = corner.
z;
 
  326     if (corner.
z > zmax) zmax = corner.
z;
 
  332   G4int    ksteps  = GetNumSide();
 
  339   if (!IsOpen()) rmin = 0;
 
  340   G4double xmin = rmin*cosCur, xmax = xmin;
 
  341   G4double ymin = rmin*sinCur, ymax = ymin;
 
  342   for (
G4int k=0; k<ksteps+1; ++k)
 
  345     if (x < xmin) xmin = x;
 
  346     if (x > xmax) xmax = x;
 
  348     if (y < ymin) ymin = y;
 
  349     if (y > ymax) ymax = y;
 
  353       if (xx < xmin) xmin = xx;
 
  354       if (xx > xmax) xmax = xx;
 
  356       if (yy < ymin) ymin = yy;
 
  357       if (yy > ymax) ymax = yy;
 
  360     sinCur = sinCur*cosStep + cosCur*sinStep;
 
  361     cosCur = cosCur*cosStep - sinTmp*sinStep;
 
  363   pMin.
set(xmin,ymin,zmin);
 
  364   pMax.
set(xmax,ymax,zmax);
 
  368   if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
 
  370     std::ostringstream message;
 
  371     message << 
"Bad bounding box (min >= max) for solid: " 
  373             << 
"\npMin = " << pMin
 
  374             << 
"\npMax = " << pMax;
 
  384     GetShape()->Extent(vmin,vmax);
 
  392       std::ostringstream message;
 
  393       message << 
"Inconsistency in bounding boxes for solid: " 
  395               << 
"\nBBox min: wrapper = " << pMin << 
" solid = " << vmin
 
  396               << 
"\nBBox max: wrapper = " << pMax << 
" solid = " << vmax;
 
  406     if (GetStartPhi() != GetShape()->GetStartPhi() ||
 
  407     GetEndPhi()   != GetShape()->GetEndPhi()   ||
 
  408         IsOpen()      != GetShape()->IsOpen()      ||
 
  409     GetNumSide()  != GetShape()->GetNumSide())
 
  411       std::ostringstream message;
 
  412       message << 
"Inconsistency in Phi angles or # of sides for solid: " 
  414               << 
"\nPhi start  : wrapper = " << GetStartPhi()
 
  415               << 
" solid = " <<     GetShape()->GetStartPhi()
 
  416               << 
"\nPhi end    : wrapper = " << GetEndPhi()
 
  417               << 
" solid = " <<     GetShape()->GetEndPhi()
 
  418               << 
"\nPhi is open: wrapper = " << (IsOpen() ? 
"true" : 
"false")
 
  419               << 
" solid = " <<     (GetShape()->IsOpen() ? 
"true" : 
"false")
 
  420               << 
"\nPhi # sides: wrapper = " << GetNumSide()
 
  421               << 
" solid = " <<     GetShape()->GetNumSide();
 
  433 G4UPolyhedra::CalculateExtent(
const EAxis pAxis,
 
  446   if (
true) 
return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
 
  448   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
 
  450     return exist = (pMin < pMax) ? 
true : 
false;
 
  459   std::vector<G4int> iout;
 
  464   for (
G4int i=0; i<GetNumRZCorner(); ++i)
 
  471   if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
 
  476     std::ostringstream message;
 
  477     message << 
"Triangulation of RZ contour has failed for solid: " 
  479             << 
"\nExtent has been calculated using boundary box";
 
  482     return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
 
  489   G4int    ksteps   = GetNumSide();
 
  493   G4double sinStart = GetSinStartPhi();
 
  494   G4double cosStart = GetCosStartPhi();
 
  497   std::vector<const G4ThreeVectorList *> polygons;
 
  498   polygons.resize(ksteps+1);
 
  499   for (
G4int k=0; k<ksteps+1; ++k) {
 
  506   G4int ntria = triangles.size()/3;
 
  507   for (
G4int i=0; i<ntria; ++i)
 
  512     for (
G4int k=0; k<ksteps+1; ++k) 
 
  515       G4ThreeVectorList::iterator iter = ptr->begin();
 
  516       iter->set(triangles[i3+0].x()*cosCur,
 
  517                 triangles[i3+0].x()*sinCur,
 
  518                 triangles[i3+0].y());
 
  520       iter->set(triangles[i3+1].x()*cosCur,
 
  521                 triangles[i3+1].x()*sinCur,
 
  522                 triangles[i3+1].y());
 
  524       iter->set(triangles[i3+2].x()*cosCur,
 
  525                 triangles[i3+2].x()*sinCur,
 
  526                 triangles[i3+2].y());
 
  529       sinCur = sinCur*cosStep + cosCur*sinStep;
 
  530       cosCur = cosCur*cosStep - sinTmp*sinStep;
 
  536     if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) 
continue;
 
  537     if (emin < pMin) pMin = emin;
 
  538     if (emax > pMax) pMax = 
emax;
 
  539     if (eminlim > pMin && emaxlim < pMax) 
break; 
 
  542   for (
G4int k=0; k<ksteps+1; ++k) { 
delete polygons[k]; polygons[k]=0;}
 
  543   return (pMin < pMax);
 
  558                                  GetOriginalParameters()->Opening_angle,
 
  559                                  GetOriginalParameters()->numSide,
 
  560                                  GetOriginalParameters()->Num_z_planes,
 
  561                                  GetOriginalParameters()->Z_values,
 
  562                                  GetOriginalParameters()->Rmin,
 
  563                                  GetOriginalParameters()->Rmax);
 
  564     delete original_parameters;  
 
  595     typedef G4int int4[4];
 
  602       std::vector<G4bool> chopped(GetNumRZCorner(), 
false);
 
  603       std::vector<G4int*> triQuads;
 
  604       G4int remaining = GetNumRZCorner();
 
  606       while (remaining >= 3)    
 
  611         G4int iStepper = iStarter;
 
  614           if (A < 0)      { A = iStepper; }
 
  615           else if (
B < 0) { 
B = iStepper; }
 
  616           else if (
C < 0) { 
C = iStepper; }
 
  619             if (++iStepper >= GetNumRZCorner()) iStepper = 0;
 
  621           while (chopped[iStepper]);
 
  623         while (
C < 0 && iStepper != iStarter);
 
  628         G4double BAr = GetCorner(A).r - GetCorner(
B).r;
 
  629         G4double BAz = GetCorner(A).z - GetCorner(
B).z;
 
  630         G4double BCr = GetCorner(
C).r - GetCorner(
B).r;
 
  631         G4double BCz = GetCorner(
C).z - GetCorner(
B).z;
 
  638           triQuads.push_back(tq);
 
  646             if (++iStarter >= GetNumRZCorner()) { iStarter = 0; }
 
  648           while (chopped[iStarter]);
 
  653       G4int numSide=GetNumSide();
 
  654       nNodes = (numSide + 1) * GetNumRZCorner();
 
  655       nFaces = numSide * GetNumRZCorner() + 2 * triQuads.size();
 
  656       faces_vec = 
new int4[nFaces];
 
  658       G4int addition = GetNumRZCorner() * numSide;
 
  659       G4int d = GetNumRZCorner() - 1;
 
  660       for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
 
  662         for (
size_t i = 0; i < triQuads.size(); ++i)
 
  675             a = triQuads[i][0] + addition;
 
  676             b = triQuads[i][2] + addition;
 
  677             c = triQuads[i][1] + addition;
 
  680           G4int bc = std::abs(c - b);
 
  681           G4int ca = std::abs(a - c);
 
  682           faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
 
  683           faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
 
  684           faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
 
  685           faces_vec[iface][3] = 0;
 
  692       xyz = 
new double3[nNodes];
 
  693       const G4double dPhi = (GetEndPhi() - GetStartPhi()) / numSide;
 
  696       for (
G4int iSide = 0; iSide < numSide; ++iSide)
 
  698         for (
G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
 
  700           xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
 
  701           xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
 
  702           xyz[ixyz][2] = GetCorner(iCorner).z;
 
  703           if (iCorner < GetNumRZCorner() - 1)
 
  705             faces_vec[iface][0] = ixyz + 1;
 
  706             faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
 
  707             faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
 
  708             faces_vec[iface][3] = ixyz + 2;
 
  712             faces_vec[iface][0] = ixyz + 1;
 
  713             faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
 
  714             faces_vec[iface][2] = ixyz + 2;
 
  715             faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
 
  725       for (
G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
 
  727         xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
 
  728         xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
 
  729         xyz[ixyz][2] = GetCorner(iCorner).z;
 
  735       nNodes = GetNumSide() * GetNumRZCorner();
 
  736       nFaces = GetNumSide() * GetNumRZCorner();;
 
  737       xyz = 
new double3[nNodes];
 
  738       faces_vec = 
new int4[nFaces];
 
  743       G4int ixyz = 0, iface = 0;
 
  744       for (
G4int iSide = 0; iSide < GetNumSide(); ++iSide)
 
  746         for (
G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
 
  748           xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
 
  749           xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
 
  750           xyz[ixyz][2] = GetCorner(iCorner).z;
 
  751           if (iSide < GetNumSide() - 1)
 
  753             if (iCorner < GetNumRZCorner() - 1)
 
  755               faces_vec[iface][0] = ixyz + 1;
 
  756               faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
 
  757               faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
 
  758               faces_vec[iface][3] = ixyz + 2;
 
  762               faces_vec[iface][0] = ixyz + 1;
 
  763               faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
 
  764               faces_vec[iface][2] = ixyz + 2;
 
  765               faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
 
  770             if (iCorner < GetNumRZCorner() - 1)
 
  772               faces_vec[iface][0] = ixyz + 1;
 
  773               faces_vec[iface][1] = ixyz + GetNumRZCorner() - nFaces + 1;
 
  774               faces_vec[iface][2] = ixyz + GetNumRZCorner() - nFaces + 2;
 
  775               faces_vec[iface][3] = ixyz + 2;
 
  779               faces_vec[iface][0] = ixyz + 1;
 
  780               faces_vec[iface][1] = ixyz - nFaces + GetNumRZCorner() + 1;
 
  781               faces_vec[iface][2] = ixyz - nFaces + 2;
 
  782               faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
 
  797       std::ostringstream message;
 
  798       message << 
"Problem creating G4Polyhedron for: " << GetName();
 
  799       G4Exception(
"G4Polyhedra::CreatePolyhedron()", 
"GeomSolids1002",
 
  811 #endif  // G4GEOM_USE_USOLIDS 
void set(double x, double y, double z)
 
static const G4double kInfinity
 
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
 
double B(double temperature)
 
static constexpr double twopi
 
G4GLOB_DLL std::ostream G4cout
 
double A(double temperature)
 
const G4double kCarTolerance
 
std::vector< G4ThreeVector > G4ThreeVectorList
 
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
 
static const G4double emax
 
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const 
 
CLHEP::Hep2Vector G4TwoVector
 
G4double GetMaxExtent(const EAxis pAxis) const 
 
G4double GetMinExtent(const EAxis pAxis) const