35 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
42 using namespace CLHEP;
55 : G4USolid(name, new UPolycone(name, phiStart, phiTotal,
56 numZPlanes, zPlane, rInner, rOuter))
58 wrStart = phiStart;
while (wrStart < 0) wrStart +=
twopi;
66 for (
G4int i=0; i<numZPlanes; ++i)
72 for (
G4int i=numZPlanes-1; i>=0; --i)
78 std::vector<G4int> iout;
87 G4UPolycone::G4UPolycone(
const G4String& name,
93 : G4USolid(name, new UPolycone(name, phiStart, phiTotal, numRZ, r, z))
95 wrStart = phiStart;
while (wrStart < 0) wrStart +=
twopi;
103 for (
G4int i=0; i<numRZ; ++i)
107 std::vector<G4int> iout;
117 G4UPolycone::G4UPolycone( __void__&
a )
127 G4UPolycone::~G4UPolycone()
136 G4UPolycone::G4UPolycone(
const G4UPolycone &source )
139 wrStart = source.wrStart;
140 wrDelta = source.wrDelta;
141 rzcorners = source.rzcorners;
149 G4UPolycone &G4UPolycone::operator=(
const G4UPolycone &source )
151 if (
this == &source)
return *
this;
153 G4USolid::operator=( source );
154 wrStart = source.wrStart;
155 wrDelta = source.wrDelta;
156 rzcorners = source.rzcorners;
166 G4double G4UPolycone::GetStartPhi()
const
170 G4double G4UPolycone::GetEndPhi()
const
172 return (wrStart + wrDelta);
174 G4double G4UPolycone::GetSinStartPhi()
const
176 if (!IsOpen())
return 0;
178 return std::sin(phi);
180 G4double G4UPolycone::GetCosStartPhi()
const
182 if (!IsOpen())
return 1;
184 return std::cos(phi);
186 G4double G4UPolycone::GetSinEndPhi()
const
188 if (!IsOpen())
return 0;
190 return std::sin(phi);
192 G4double G4UPolycone::GetCosEndPhi()
const
194 if (!IsOpen())
return 1;
196 return std::cos(phi);
198 G4bool G4UPolycone::IsOpen()
const
200 return (wrDelta <
twopi);
202 G4int G4UPolycone::GetNumRZCorner()
const
204 return rzcorners.size();
215 UPolyconeHistorical* pars = GetShape()->GetOriginalParameters();
219 for (
G4int i=0; i<pars->fNumZPlanes; ++i)
221 pdata->
Z_values[i] = pars->fZValues[i];
222 pdata->
Rmin[i] = pars->Rmin[i];
223 pdata->
Rmax[i] = pars->Rmax[i];
229 UPolyconeHistorical* pdata = GetShape()->GetOriginalParameters();
233 for (
G4int i=0; i<pdata->fNumZPlanes; ++i)
235 pdata->fZValues[i] = pars->
Z_values[i];
236 pdata->Rmin[i] = pars->
Rmin[i];
237 pdata->Rmax[i] = pars->
Rmax[i];
239 fRebuildPolyhedron =
true;
241 wrStart = pdata->fStartAngle;
while (wrStart < 0) wrStart +=
twopi;
242 wrDelta = pdata->fOpeningAngle;
249 for (
G4int i=0; i<pdata->fNumZPlanes; ++i)
255 for (
G4int i=pdata->fNumZPlanes-1; i>=0; --i)
261 std::vector<G4int> iout;
264 G4bool G4UPolycone::Reset()
287 G4VSolid* G4UPolycone::Clone()
const
289 return new G4UPolycone(*
this);
298 static G4bool checkBBox =
true;
299 static G4bool checkPhi =
true;
304 for (
G4int i=0; i<GetNumRZCorner(); ++i)
307 if (corner.
r < rmin) rmin = corner.
r;
308 if (corner.
r > rmax) rmax = corner.
r;
309 if (corner.
z < zmin) zmin = corner.
z;
310 if (corner.
z > zmax) zmax = corner.
z;
317 GetSinStartPhi(),GetCosStartPhi(),
318 GetSinEndPhi(),GetCosEndPhi(),
320 pMin.set(vmin.x(),vmin.y(),zmin);
321 pMax.set(vmax.x(),vmax.y(),zmax);
325 pMin.set(-rmax,-rmax, zmin);
326 pMax.set( rmax, rmax, zmax);
331 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
333 std::ostringstream message;
334 message <<
"Bad bounding box (min >= max) for solid: "
336 <<
"\npMin = " << pMin
337 <<
"\npMax = " << pMax;
347 GetShape()->Extent(vmin,vmax);
355 std::ostringstream message;
356 message <<
"Inconsistency in bounding boxes for solid: "
358 <<
"\nBBox min: wrapper = " << pMin <<
" solid = " << vmin
359 <<
"\nBBox max: wrapper = " << pMax <<
" solid = " << vmax;
369 if (GetStartPhi() != GetShape()->GetStartPhi() ||
370 GetEndPhi() != GetShape()->GetEndPhi() ||
371 IsOpen() != GetShape()->IsOpen())
373 std::ostringstream message;
374 message <<
"Inconsistency in Phi angles or # of sides for solid: "
376 <<
"\nPhi start : wrapper = " << GetStartPhi()
377 <<
" solid = " << GetShape()->GetStartPhi()
378 <<
"\nPhi end : wrapper = " << GetEndPhi()
379 <<
" solid = " << GetShape()->GetEndPhi()
380 <<
"\nPhi is open: wrapper = " << (IsOpen() ?
"true" :
"false")
381 <<
" solid = " << (GetShape()->IsOpen() ?
"true" :
"false");
392 G4bool G4UPolycone::CalculateExtent(
const EAxis pAxis,
405 if (
true)
return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
407 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
409 return exist = (pMin < pMax) ?
true :
false;
418 std::vector<G4int> iout;
423 for (
G4int i=0; i<GetNumRZCorner(); ++i)
430 if (area < 0.)
std::reverse(contourRZ.begin(),contourRZ.end());
435 std::ostringstream message;
436 message <<
"Triangulation of RZ contour has failed for solid: "
438 <<
"\nExtent has been calculated using boundary box";
441 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
445 const G4int NSTEPS = 24;
451 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-
deg)/astep) + 1;
454 G4double sinHalf = std::sin(0.5*ang);
455 G4double cosHalf = std::cos(0.5*ang);
456 G4double sinStep = 2.*sinHalf*cosHalf;
457 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
459 G4double sinStart = GetSinStartPhi();
460 G4double cosStart = GetCosStartPhi();
465 std::vector<const G4ThreeVectorList *> polygons;
466 polygons.resize(ksteps+2);
468 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
469 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
476 G4int ntria = triangles.size()/3;
477 for (
G4int i=0; i<ntria; ++i)
480 for (
G4int k=0; k<3; ++k)
482 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
485 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
486 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
490 if (z0[k2+1] - z0[k2+0] <= 0)
continue;
496 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
497 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
498 for (
G4int j=0; j<6; ++j) pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
499 for (
G4int k=1; k<ksteps+1; ++k)
501 for (
G4int j=0; j<6; ++j) pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
503 sinCur = sinCur*cosStep + cosCur*sinStep;
504 cosCur = cosCur*cosStep - sinTmp*sinStep;
506 for (
G4int j=0; j<6; ++j) pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
511 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
512 if (emin < pMin) pMin = emin;
513 if (emax > pMax) pMax =
emax;
514 if (eminlim > pMin && emaxlim < pMax)
return true;
516 return (pMin < pMax);
531 original_parameters->
Rmin,
532 original_parameters->
Rmax );
534 delete original_parameters;
539 #endif // G4GEOM_USE_USOLIDS
static const G4double kInfinity
CLHEP::Hep3Vector G4ThreeVector
std::vector< ExP01TrackerHit * > a
const char * name(G4int ptype)
static constexpr double twopi
G4GLOB_DLL std::ostream G4cout
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
static constexpr double deg
G4double GetMaxExtent(const EAxis pAxis) const
G4double GetMinExtent(const EAxis pAxis) const