126 if (
this == &rhs) {
return *
this; }
134 halfCarTolerance = rhs.halfCarTolerance;
143void G4UnionSolid::Init()
148 fPMin = pmin - pdelta;
149 fPMax = pmax + pdelta;
164 pMin.
set(std::min(minA.
x(),minB.
x()),
165 std::min(minA.
y(),minB.
y()),
166 std::min(minA.
z(),minB.
z()));
168 pMax.
set(std::max(maxA.
x(),maxB.
x()),
169 std::max(maxA.
y(),maxB.
y()),
170 std::max(maxA.
z(),maxB.
z()));
174 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
176 std::ostringstream message;
177 message <<
"Bad bounding box (min >= max) for solid: "
179 <<
"\npMin = " << pMin
180 <<
"\npMax = " << pMax;
181 G4Exception(
"G4UnionSolid::BoundingLimits()",
"GeomMgt0001",
198 G4bool touchesA, touchesB, out ;
199 G4double minA = kInfinity, minB = kInfinity,
200 maxA = -kInfinity, maxB = -kInfinity;
202 touchesA =
fPtrSolidA->CalculateExtent( pAxis, pVoxelLimit,
203 pTransform, minA, maxA);
204 touchesB =
fPtrSolidB->CalculateExtent( pAxis, pVoxelLimit,
205 pTransform, minB, maxB);
206 if( touchesA || touchesB )
208 pMin = std::min( minA, minB );
209 pMax = std::max( maxA, maxB );
228 if (std::max(p.
z()-fPMax.z(), fPMin.z()-p.
z()) > 0) {
return kOutside; }
231 if (positionA ==
kInside) {
return positionA; }
233 if (positionA ==
kOutside) {
return positionB; }
235 if (positionB ==
kInside) {
return positionB; }
236 if (positionB ==
kOutside) {
return positionA; }
270 return (normalA + normalB).unit();
274 G4String surf[3] = {
"OUTSIDE",
"SURFACE",
"INSIDE" };
275 std::ostringstream message;
276 G4int oldprc = message.precision(16);
277 message <<
"Invalid call of SurfaceNormal(p) for union solid: "
279 <<
"\nPoint p" << p <<
" is " << surf[
Inside(p)] <<
" !!!";
280 message.precision(oldprc);
281 G4Exception(
"G4UnionSolid::SurfaceNormal()",
"GeomMgt0001",
298 G4cout <<
"WARNING - Invalid call in "
299 <<
"G4UnionSolid::DistanceToIn(p,v)" <<
G4endl
300 <<
" Point p is inside !" <<
G4endl;
303 G4cerr <<
"WARNING - Invalid call in "
304 <<
"G4UnionSolid::DistanceToIn(p,v)" <<
G4endl
305 <<
" Point p is inside !" <<
G4endl;
311 return std::min(
fPtrSolidA->DistanceToIn(p,v),
326 G4cout <<
"WARNING - Invalid call in "
327 <<
"G4UnionSolid::DistanceToIn(p)" <<
G4endl
328 <<
" Point p is inside !" <<
G4endl;
330 G4cerr <<
"WARNING - Invalid call in "
331 <<
"G4UnionSolid::DistanceToIn(p)" <<
G4endl
332 <<
" Point p is inside !" <<
G4endl;
338 G4double safety = std::min(distA,distB) ;
339 if(safety < 0.0) { safety = 0.0 ; }
369 G4cout <<
"WARNING - Invalid call in "
370 <<
"G4UnionSolid::DistanceToOut(p,v)" <<
G4endl
371 <<
" Point p is outside !" <<
G4endl;
374 G4cerr <<
"WARNING - Invalid call in "
375 <<
"G4UnionSolid::DistanceToOut(p,v)" <<
G4endl
376 <<
" Point p is outside !" <<
G4endl;
389 disTmp =
fPtrSolidA->DistanceToOut(p+dist*v,v,calcNorm,
395 disTmp =
fPtrSolidB->DistanceToOut(p+dist*v,v,calcNorm,
401 && (disTmp > halfCarTolerance) );
407 disTmp =
fPtrSolidB->DistanceToOut(p+dist*v,v,calcNorm,
413 disTmp =
fPtrSolidA->DistanceToOut(p+dist*v,v,calcNorm,
419 && (disTmp > halfCarTolerance) );
441 G4cout <<
"WARNING - Invalid call in "
442 <<
"G4UnionSolid::DistanceToOut(p)" <<
G4endl
443 <<
" Point p is outside !" <<
G4endl;
445 G4cerr <<
"WARNING - Invalid call in "
446 <<
"G4UnionSolid::DistanceToOut(p)" <<
G4endl
447 <<
" Point p is outside !" <<
G4endl;
463 distout= std::max(
fPtrSolidA->DistanceToOut(p),
487 return {
"G4UnionSolid"};
511 "Method not applicable in this context!");
538 if (processor.
execute(*result))
565 bminA.
x() >= bmaxB.
x() || bminA.
y() >= bmaxB.
y() || bminA.
z() >= bmaxB.
z() ||
566 bminB.
x() >= bmaxA.
x() || bminB.
y() >= bmaxA.
y() || bminB.
z() >= bmaxA.
z();
G4TemplateAutoLock< G4RecursiveMutex > G4RecursiveAutoLock
const G4double kCarTolerance
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::HepRotation G4RotationMatrix
#define G4MUTEX_INITIALIZER
std::recursive_mutex G4RecursiveMutex
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
G4BooleanSolid & operator=(const G4BooleanSolid &rhs)
void SetCubVolEpsilon(G4double ep)
G4double GetCubVolEpsilon() const
G4double GetCubicVolume() override
G4BooleanSolid(const G4String &pName, G4VSolid *pSolidA, G4VSolid *pSolidB)
G4int GetCubVolStatistics() const
G4int GetNumOfConstituents() const override
static G4VBooleanProcessor * fExternalBoolProcessor
G4Polyhedron * StackPolyhedron(HepPolyhedronProcessor &, const G4VSolid *) const
void SetCubVolStatistics(G4int st)
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4IntersectionSolid is a solid describing the Boolean intersection of two solids.
G4UnionSolid(const G4String &pName, G4VSolid *pSolidA, G4VSolid *pSolidB)
void DescribeYourselfTo(G4VGraphicsScene &scene) const override
G4GeometryType GetEntityType() const override
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const override
G4UnionSolid & operator=(const G4UnionSolid &rhs)
EInside Inside(const G4ThreeVector &p) const override
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const override
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
G4double GetCubicVolume() final
G4Polyhedron * CreatePolyhedron() const override
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const override
G4VSolid * Clone() const override
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep) override
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
virtual void AddSolid(const G4Box &)=0
G4VPVParameterisation ia an abstract base class for Parameterisation, able to compute the transformat...
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
G4VSolid(const G4String &name)
G4VoxelLimits represents limitation/restrictions of space, where restrictions are only made perpendic...
bool execute(HepPolyhedron &)