34#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
54 : Base_t(
name, phiStart, phiTotal, numZPlanes, zPlane, rInner, rOuter)
57 SetOriginalParameters();
70 for (
G4int i=0; i<numZPlanes; ++i)
76 for (
G4int i=numZPlanes-1; i>=0; --i)
82 std::vector<G4int> iout;
97 : Base_t(
name, phiStart, phiTotal, numRZ, r, z)
100 SetOriginalParameters();
101 wrStart = phiStart;
while (wrStart < 0) wrStart +=
twopi;
109 for (
G4int i=0; i<numRZ; ++i)
113 std::vector<G4int> iout;
123G4UPolycone::G4UPolycone( __void__& a )
133G4UPolycone::~G4UPolycone()
142G4UPolycone::G4UPolycone(
const G4UPolycone&
source )
145 fGenericPcon =
source.fGenericPcon;
146 fOriginalParameters =
source.fOriginalParameters;
149 rzcorners =
source.rzcorners;
157G4UPolycone& G4UPolycone::operator=(
const G4UPolycone&
source )
159 if (
this == &
source)
return *
this;
161 Base_t::operator=(
source );
162 fGenericPcon =
source.fGenericPcon;
163 fOriginalParameters =
source.fOriginalParameters;
166 rzcorners =
source.rzcorners;
176G4double G4UPolycone::GetStartPhi()
const
180G4double G4UPolycone::GetDeltaPhi()
const
184G4double G4UPolycone::GetEndPhi()
const
186 return (wrStart + wrDelta);
188G4double G4UPolycone::GetSinStartPhi()
const
190 if (!IsOpen())
return 0.;
192 return std::sin(phi);
194G4double G4UPolycone::GetCosStartPhi()
const
196 if (!IsOpen())
return 1.;
198 return std::cos(phi);
200G4double G4UPolycone::GetSinEndPhi()
const
202 if (!IsOpen())
return 0.;
204 return std::sin(phi);
206G4double G4UPolycone::GetCosEndPhi()
const
208 if (!IsOpen())
return 1.;
210 return std::cos(phi);
212G4bool G4UPolycone::IsOpen()
const
214 return (wrDelta <
twopi);
216G4int G4UPolycone::GetNumRZCorner()
const
218 return rzcorners.size();
231void G4UPolycone::SetOriginalParameters()
233 vecgeom::PolyconeHistorical* original_parameters = Base_t::GetOriginalParameters();
235 fOriginalParameters.Start_angle = original_parameters->fHStart_angle;
236 fOriginalParameters.Opening_angle = original_parameters->fHOpening_angle;
237 fOriginalParameters.Num_z_planes = original_parameters->fHNum_z_planes;
239 delete [] fOriginalParameters.Z_values;
240 delete [] fOriginalParameters.Rmin;
241 delete [] fOriginalParameters.Rmax;
243 G4int numPlanes = fOriginalParameters.Num_z_planes;
244 fOriginalParameters.Z_values =
new G4double[numPlanes];
245 fOriginalParameters.Rmin =
new G4double[numPlanes];
246 fOriginalParameters.Rmax =
new G4double[numPlanes];
247 for (
G4int i=0; i<numPlanes; ++i)
249 fOriginalParameters.Z_values[i] = original_parameters->fHZ_values[i];
250 fOriginalParameters.Rmin[i] = original_parameters->fHRmin[i];
251 fOriginalParameters.Rmax[i] = original_parameters->fHRmax[i];
256 fOriginalParameters = *pars;
257 fRebuildPolyhedron =
true;
261G4bool G4UPolycone::Reset()
265 std::ostringstream message;
266 message <<
"Solid " << GetName() <<
" built using generic construct."
267 <<
G4endl <<
"Not applicable to the generic construct !";
268 G4Exception(
"G4UPolycone::Reset()",
"GeomSolids1001",
276 wrStart = fOriginalParameters.Start_angle;
281 wrDelta = fOriginalParameters.Opening_angle;
288 for (
G4int i=0; i<fOriginalParameters.Num_z_planes; ++i)
290 G4double z = fOriginalParameters.Z_values[i];
291 G4double r = fOriginalParameters.Rmax[i];
294 for (
G4int i=fOriginalParameters.Num_z_planes-1; i>=0; --i)
296 G4double z = fOriginalParameters.Z_values[i];
297 G4double r = fOriginalParameters.Rmin[i];
300 std::vector<G4int> iout;
325 return new G4UPolycone(*
this);
335 static G4bool checkBBox =
true;
336 static G4bool checkPhi =
true;
341 for (
G4int i=0; i<GetNumRZCorner(); ++i)
344 if (corner.
r < rmin) rmin = corner.
r;
345 if (corner.
r > rmax) rmax = corner.
r;
346 if (corner.
z < zmin) zmin = corner.
z;
347 if (corner.
z > zmax) zmax = corner.
z;
354 GetSinStartPhi(),GetCosStartPhi(),
355 GetSinEndPhi(),GetCosEndPhi(),
357 pMin.set(vmin.
x(),vmin.
y(),zmin);
358 pMax.set(vmax.
x(),vmax.
y(),zmax);
362 pMin.set(-rmax,-rmax, zmin);
363 pMax.set( rmax, rmax, zmax);
370 std::ostringstream message;
371 message <<
"Bad bounding box (min >= max) for solid: "
373 <<
"\npMin = " <<
pMin
374 <<
"\npMax = " <<
pMax;
375 G4Exception(
"G4UPolycone::BoundingLimits()",
"GeomMgt0001",
393 std::ostringstream message;
394 message <<
"Inconsistency in bounding boxes for solid: "
396 <<
"\nBBox min: wrapper = " <<
pMin <<
" solid = " << vmin
397 <<
"\nBBox max: wrapper = " <<
pMax <<
" solid = " << vmax;
398 G4Exception(
"G4UPolycone::BoundingLimits()",
"GeomMgt0001",
408 if (GetStartPhi() != Base_t::GetStartPhi() ||
409 GetEndPhi() != Base_t::GetEndPhi() ||
410 IsOpen() != (Base_t::GetDeltaPhi() <
twopi))
412 std::ostringstream message;
413 message <<
"Inconsistency in Phi angles or # of sides for solid: "
415 <<
"\nPhi start : wrapper = " << GetStartPhi()
416 <<
" solid = " << Base_t::GetStartPhi()
417 <<
"\nPhi end : wrapper = " << GetEndPhi()
418 <<
" solid = " << Base_t::GetEndPhi()
419 <<
"\nPhi is open: wrapper = " << (IsOpen() ?
"true" :
"false")
421 << ((Base_t::GetDeltaPhi() <
twopi) ?
"true" :
"false");
422 G4Exception(
"G4UPolycone::BoundingLimits()",
"GeomMgt0001",
433G4bool G4UPolycone::CalculateExtent(
const EAxis pAxis,
443 BoundingLimits(bmin,bmax);
446 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);
486 const G4int NSTEPS = 24;
492 G4int ksteps = (dphi <= astep) ? 1 : (
G4int)((dphi-
deg)/astep) + 1;
495 G4double sinHalf = std::sin(0.5*ang);
496 G4double cosHalf = std::cos(0.5*ang);
497 G4double sinStep = 2.*sinHalf*cosHalf;
498 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
500 G4double sinStart = GetSinStartPhi();
501 G4double cosStart = GetCosStartPhi();
506 std::vector<const G4ThreeVectorList *> polygons;
507 polygons.resize(ksteps+2);
509 for (
G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
510 for (
G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
517 G4int ntria = triangles.size()/3;
518 for (
G4int i=0; i<ntria; ++i)
521 for (
G4int k=0; k<3; ++k)
523 G4int e0 = i3+k,
e1 = (k<2) ? e0+1 : i3;
526 r0[k2+0] = triangles[e0].x();
z0[k2+0] = triangles[e0].y();
527 r0[k2+1] = triangles[
e1].x();
z0[k2+1] = triangles[
e1].y();
531 if (
z0[k2+1] -
z0[k2+0] <= 0)
continue;
537 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
538 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
539 for (
G4int j=0; j<6; ++j) pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,
z0[j]);
540 for (
G4int k=1; k<ksteps+1; ++k)
542 for (
G4int j=0; j<6; ++j) pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,
z0[j]);
544 sinCur = sinCur*cosStep + cosCur*sinStep;
545 cosCur = cosCur*cosStep - sinTmp*sinStep;
547 for (
G4int j=0; j<6; ++j) pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,
z0[j]);
552 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,
emax))
continue;
555 if (eminlim >
pMin && emaxlim <
pMax)
return true;
static const G4double e1[44]
const G4double kCarTolerance
std::vector< G4ThreeVector > G4ThreeVectorList
static const G4double emax
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
static const G4double pMax
static const G4double pMin
static constexpr double twopi
static constexpr double deg
CLHEP::Hep2Vector G4TwoVector
G4GLOB_DLL std::ostream G4cout
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const
static const G4double kInfinity
const char * name(G4int ptype)