34#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
50G4UPolyhedra::G4UPolyhedra(
const G4String& name,
58 : Base_t(
name, phiStart, phiTotal, numSide,
59 numZPlanes, zPlane, rInner, rOuter)
62 SetOriginalParameters();
69 if (wrDelta <= 0. || wrDelta >= twopi*(1-
DBL_EPSILON))
74 G4double convertRad = 1./std::cos(0.5*wrDelta/wrNumSide);
76 for (
G4int i=0; i<numZPlanes; ++i)
82 for (
G4int i=numZPlanes-1; i>=0; --i)
88 std::vector<G4int> iout;
97G4UPolyhedra::G4UPolyhedra(
const G4String& name,
104 : Base_t(
name, phiStart, phiTotal, numSide, numRZ, r, z)
107 SetOriginalParameters();
114 if (wrDelta <= 0. || wrDelta >= twopi*(1-
DBL_EPSILON))
120 for (
G4int i=0; i<numRZ; ++i)
124 std::vector<G4int> iout;
134G4UPolyhedra::G4UPolyhedra( __void__& a )
144G4UPolyhedra::~G4UPolyhedra()
153G4UPolyhedra::G4UPolyhedra(
const G4UPolyhedra& source )
156 fGenericPgon = source.fGenericPgon;
157 fOriginalParameters = source.fOriginalParameters;
158 wrStart = source.wrStart;
159 wrDelta = source.wrDelta;
160 wrNumSide = source.wrNumSide;
161 rzcorners = source.rzcorners;
169G4UPolyhedra& G4UPolyhedra::operator=(
const G4UPolyhedra& source )
171 if (
this == &source)
return *
this;
173 Base_t::operator=( source );
174 fGenericPgon = source.fGenericPgon;
175 fOriginalParameters = source.fOriginalParameters;
176 wrStart = source.wrStart;
177 wrDelta = source.wrDelta;
178 wrNumSide = source.wrNumSide;
179 rzcorners = source.rzcorners;
189G4int G4UPolyhedra::GetNumSide()
const
193G4double G4UPolyhedra::GetStartPhi()
const
197G4double G4UPolyhedra::GetEndPhi()
const
199 return (wrStart + wrDelta);
201G4double G4UPolyhedra::GetSinStartPhi()
const
204 return std::sin(phi);
206G4double G4UPolyhedra::GetCosStartPhi()
const
209 return std::cos(phi);
211G4double G4UPolyhedra::GetSinEndPhi()
const
214 return std::sin(phi);
216G4double G4UPolyhedra::GetCosEndPhi()
const
219 return std::cos(phi);
221G4bool G4UPolyhedra::IsOpen()
const
223 return (wrDelta < twopi);
225G4bool G4UPolyhedra::IsGeneric()
const
229G4int G4UPolyhedra::GetNumRZCorner()
const
231 return rzcorners.size();
244void G4UPolyhedra::SetOriginalParameters()
248 G4int numPlanes = GetZSegmentCount() + 1;
249 G4int numSides = GetSideCount();
251 fOriginalParameters.Start_angle = startPhi;
252 fOriginalParameters.Opening_angle = deltaPhi;
253 fOriginalParameters.Num_z_planes = numPlanes;
254 fOriginalParameters.numSide = numSides;
256 delete [] fOriginalParameters.Z_values;
257 delete [] fOriginalParameters.Rmin;
258 delete [] fOriginalParameters.Rmax;
259 fOriginalParameters.Z_values =
new G4double[numPlanes];
260 fOriginalParameters.Rmin =
new G4double[numPlanes];
261 fOriginalParameters.Rmax =
new G4double[numPlanes];
264 ? 1.0 : std::cos(0.5*deltaPhi/numSides);
265 for (
G4int i=0; i<numPlanes; ++i)
267 fOriginalParameters.Z_values[i] = GetZPlanes()[i];
268 fOriginalParameters.Rmax[i] = GetRMax()[i]/convertRad;
269 fOriginalParameters.Rmin[i] = GetRMin()[i]/convertRad;
274 fOriginalParameters = *pars;
275 fRebuildPolyhedron =
true;
279G4bool G4UPolyhedra::Reset()
283 std::ostringstream message;
284 message <<
"Solid " << GetName() <<
" built using generic construct."
285 <<
G4endl <<
"Not applicable to the generic construct !";
286 G4Exception(
"G4UPolyhedra::Reset()",
"GeomSolids1001",
294 wrStart = fOriginalParameters.Start_angle;
299 wrDelta = fOriginalParameters.Opening_angle;
300 if (wrDelta <= 0. || wrDelta >= twopi*(1-
DBL_EPSILON))
304 wrNumSide = fOriginalParameters.numSide;
306 for (
G4int i=0; i<fOriginalParameters.Num_z_planes; ++i)
308 G4double z = fOriginalParameters.Z_values[i];
309 G4double r = fOriginalParameters.Rmax[i];
312 for (
G4int i=fOriginalParameters.Num_z_planes-1; i>=0; --i)
314 G4double z = fOriginalParameters.Z_values[i];
315 G4double r = fOriginalParameters.Rmin[i];
318 std::vector<G4int> iout;
342G4VSolid* G4UPolyhedra::Clone()
const
344 return new G4UPolyhedra(*
this);
355 static G4bool checkBBox =
true;
356 static G4bool checkPhi =
true;
358 G4double rmin = kInfinity, rmax = -kInfinity;
359 G4double zmin = kInfinity, zmax = -kInfinity;
360 for (
G4int i=0; i<GetNumRZCorner(); ++i)
363 if (corner.
r < rmin) rmin = corner.
r;
364 if (corner.
r > rmax) rmax = corner.
r;
365 if (corner.
z < zmin) zmin = corner.
z;
366 if (corner.
z > zmax) zmax = corner.
z;
371 G4double dphi = IsOpen() ? ephi-sphi : twopi;
372 G4int ksteps = GetNumSide();
379 if (!IsOpen()) rmin = 0.;
380 G4double xmin = rmin*cosCur, xmax = xmin;
381 G4double ymin = rmin*sinCur, ymax = ymin;
382 for (
G4int k=0; k<ksteps+1; ++k)
385 if (x < xmin) xmin = x;
386 if (x > xmax) xmax = x;
388 if (y < ymin) ymin = y;
389 if (y > ymax) ymax = y;
393 if (xx < xmin) xmin = xx;
394 if (xx > xmax) xmax = xx;
396 if (yy < ymin) ymin = yy;
397 if (yy > ymax) ymax = yy;
400 sinCur = sinCur*cosStep + cosCur*sinStep;
401 cosCur = cosCur*cosStep - sinTmp*sinStep;
403 pMin.
set(xmin,ymin,zmin);
404 pMax.
set(xmax,ymax,zmax);
408 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
410 std::ostringstream message;
411 message <<
"Bad bounding box (min >= max) for solid: "
413 <<
"\npMin = " << pMin
414 <<
"\npMax = " << pMax;
415 G4Exception(
"G4UPolyhedra::BoundingLimits()",
"GeomMgt0001",
433 std::ostringstream message;
434 message <<
"Inconsistency in bounding boxes for solid: "
436 <<
"\nBBox min: wrapper = " << pMin <<
" solid = " << vmin
437 <<
"\nBBox max: wrapper = " << pMax <<
" solid = " << vmax;
438 G4Exception(
"G4UPolyhedra::BoundingLimits()",
"GeomMgt0001",
448 if (GetStartPhi() != GetPhiStart() ||
449 GetEndPhi() != GetPhiEnd() ||
450 GetNumSide() != GetSideCount() ||
451 IsOpen() != (Base_t::GetPhiDelta() < twopi))
453 std::ostringstream message;
454 message <<
"Inconsistency in Phi angles or # of sides for solid: "
456 <<
"\nPhi start : wrapper = " << GetStartPhi()
457 <<
" solid = " << GetPhiStart()
458 <<
"\nPhi end : wrapper = " << GetEndPhi()
459 <<
" solid = " << GetPhiEnd()
460 <<
"\nPhi # sides: wrapper = " << GetNumSide()
461 <<
" solid = " << GetSideCount()
462 <<
"\nPhi is open: wrapper = " << (IsOpen() ?
"true" :
"false")
464 << ((Base_t::GetPhiDelta() < twopi) ?
"true" :
"false");
465 G4Exception(
"G4UPolyhedra::BoundingLimits()",
"GeomMgt0001",
477G4UPolyhedra::CalculateExtent(
const EAxis pAxis,
487 BoundingLimits(bmin,bmax);
490 if (
true)
return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
492 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
494 return exist = (pMin < pMax) ?
true :
false;
503 std::vector<G4int> iout;
508 for (
G4int i=0; i<GetNumRZCorner(); ++i)
515 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
520 std::ostringstream message;
521 message <<
"Triangulation of RZ contour has failed for solid: "
523 <<
"\nExtent has been calculated using boundary box";
526 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
532 G4double dphi = IsOpen() ? ephi-sphi : twopi;
533 G4int ksteps = GetNumSide();
537 G4double sinStart = GetSinStartPhi();
538 G4double cosStart = GetCosStartPhi();
541 std::vector<const G4ThreeVectorList *> polygons;
542 polygons.resize(ksteps+1);
543 for (
G4int k=0; k<ksteps+1; ++k)
551 G4int ntria = triangles.size()/3;
552 for (
G4int i=0; i<ntria; ++i)
557 for (
G4int k=0; k<ksteps+1; ++k)
560 G4ThreeVectorList::iterator iter = ptr->begin();
561 iter->set(triangles[i3+0].x()*cosCur,
562 triangles[i3+0].x()*sinCur,
563 triangles[i3+0].y());
565 iter->set(triangles[i3+1].x()*cosCur,
566 triangles[i3+1].x()*sinCur,
567 triangles[i3+1].y());
569 iter->set(triangles[i3+2].x()*cosCur,
570 triangles[i3+2].x()*sinCur,
571 triangles[i3+2].y());
574 sinCur = sinCur*cosStep + cosCur*sinStep;
575 cosCur = cosCur*cosStep - sinTmp*sinStep;
581 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
582 if (emin < pMin) pMin = emin;
583 if (emax > pMax) pMax = emax;
584 if (eminlim > pMin && emaxlim < pMax)
break;
587 for (
G4int k=0; k<ksteps+1; ++k) {
delete polygons[k]; polygons[k]=0;}
588 return (pMin < pMax);
const G4double kCarTolerance
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep2Vector G4TwoVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const
const char * name(G4int ptype)