Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4TessellatedSolid Class Reference

G4TessellatedSolid is a solid defined by a number of facets. It is important that the supplied facets shall form a fully enclose space which is the solid. The facets can be of two types, G4TriangularFacet and G4QuadrangularFacet. More...

#include <G4TessellatedSolid.hh>

Inheritance diagram for G4TessellatedSolid:

Public Member Functions

 G4TessellatedSolid ()
 G4TessellatedSolid (const G4String &name)
 ~G4TessellatedSolid () override
 G4TessellatedSolid (__void__ &)
 G4TessellatedSolid (const G4TessellatedSolid &ts)
G4TessellatedSolidoperator= (const G4TessellatedSolid &right)
G4TessellatedSolidoperator+= (const G4TessellatedSolid &right)
G4bool AddFacet (G4VFacet *aFacet)
G4VFacetGetFacet (G4int i) const
G4int GetNumberOfFacets () const
G4int GetFacetIndex (const G4ThreeVector &p) const
G4double GetMinXExtent () const
G4double GetMaxXExtent () const
G4double GetMinYExtent () const
G4double GetMaxYExtent () const
G4double GetMinZExtent () const
G4double GetMaxZExtent () const
EInside Inside (const G4ThreeVector &p) const override
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const override
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const override
G4double DistanceToIn (const G4ThreeVector &p) const override
G4double DistanceToOut (const G4ThreeVector &p) const override
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm, G4bool *validNorm, G4ThreeVector *norm) const override
virtual G4bool Normal (const G4ThreeVector &p, G4ThreeVector &n) const
virtual G4double SafetyFromOutside (const G4ThreeVector &p, G4bool aAccurate=false) const
virtual G4double SafetyFromInside (const G4ThreeVector &p, G4bool aAccurate=false) const
G4GeometryType GetEntityType () const override
G4bool IsFaceted () const override
std::ostream & StreamInfo (std::ostream &os) const override
G4VSolidClone () const override
G4ThreeVector GetPointOnSurface () const override
G4double GetSurfaceArea () override
G4double GetCubicVolume () override
void SetSolidClosed (const G4bool t)
G4bool GetSolidClosed () const
G4int CheckStructure () const
void SetMaxVoxels (G4int max)
G4VoxelizerGetVoxels ()
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const override
void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const override
G4PolyhedronCreatePolyhedron () const override
G4PolyhedronGetPolyhedron () const override
void DescribeYourselfTo (G4VGraphicsScene &scene) const override
G4VisExtent GetExtent () const override
G4int AllocatedMemoryWithoutVoxels ()
G4int AllocatedMemory ()
void DisplayAllocatedMemory ()
Public Member Functions inherited from G4VSolid
 G4VSolid (const G4String &name)
virtual ~G4VSolid ()
 G4VSolid (const G4VSolid &rhs)
G4VSolidoperator= (const G4VSolid &rhs)
G4bool operator== (const G4VSolid &s) const
G4String GetName () const
void SetName (const G4String &name)
G4double GetTolerance () const
virtual void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
virtual G4int GetNumOfConstituents () const
void DumpInfo () const
virtual const G4VSolidGetConstituentSolid (G4int no) const
virtual G4VSolidGetConstituentSolid (G4int no)
virtual const G4DisplacedSolidGetDisplacedSolidPtr () const
virtual G4DisplacedSolidGetDisplacedSolidPtr ()
 G4VSolid (__void__ &)
G4double EstimateCubicVolume (G4int nStat, G4double epsilon) const
G4double EstimateSurfaceArea (G4int nStat, G4double epsilon) const

Protected Attributes

G4double kCarToleranceHalf
Protected Attributes inherited from G4VSolid
G4double kCarTolerance

Additional Inherited Members

Protected Member Functions inherited from G4VSolid
void CalculateClippedPolygonExtent (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
void ClipCrossSection (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
void ClipBetweenSections (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
void ClipPolygon (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis) const

Detailed Description

G4TessellatedSolid is a solid defined by a number of facets. It is important that the supplied facets shall form a fully enclose space which is the solid. The facets can be of two types, G4TriangularFacet and G4QuadrangularFacet.

Definition at line 135 of file G4TessellatedSolid.hh.

Constructor & Destructor Documentation

◆ G4TessellatedSolid() [1/4]

G4TessellatedSolid::G4TessellatedSolid ( )

Default Constructor.

Definition at line 86 of file G4TessellatedSolid.cc.

86 : G4VSolid("dummy")
87{
88 Initialize();
89}
G4VSolid(const G4String &name)
Definition G4VSolid.cc:59

Referenced by Clone(), G4ExtrudedSolid::G4ExtrudedSolid(), G4ExtrudedSolid::G4ExtrudedSolid(), G4ExtrudedSolid::G4ExtrudedSolid(), G4TessellatedSolid(), operator+=(), and operator=().

◆ G4TessellatedSolid() [2/4]

G4TessellatedSolid::G4TessellatedSolid ( const G4String & name)

Constructor with solid's name.

Parameters
[in]nameThe name of the solid.

Definition at line 96 of file G4TessellatedSolid.cc.

97 : G4VSolid(name)
98{
99 Initialize();
100}

◆ ~G4TessellatedSolid()

G4TessellatedSolid::~G4TessellatedSolid ( )
override

Destructor. Clearing all allocated facets and data.

Definition at line 116 of file G4TessellatedSolid.cc.

117{
118 DeleteObjects();
119}

◆ G4TessellatedSolid() [3/4]

G4TessellatedSolid::G4TessellatedSolid ( __void__ & a)

Fake default constructor for usage restricted to direct object persistency for clients requiring preallocation of memory for persistifiable objects.

Definition at line 107 of file G4TessellatedSolid.cc.

107 : G4VSolid(a)
108{
109 Initialize();
110 fMinExtent.set(0,0,0);
111 fMaxExtent.set(0,0,0);
112}

◆ G4TessellatedSolid() [4/4]

G4TessellatedSolid::G4TessellatedSolid ( const G4TessellatedSolid & ts)

Copy constructor and assignment operator.

Definition at line 125 of file G4TessellatedSolid.cc.

126 : G4VSolid(ts)
127{
128 Initialize();
129
130 CopyObjects(ts);
131}

Member Function Documentation

◆ AddFacet()

G4bool G4TessellatedSolid::AddFacet ( G4VFacet * aFacet)

Methods for adding or retrieving a facet given an index.

Definition at line 211 of file G4TessellatedSolid.cc.

212{
213 // Add the facet to the vector.
214 //
215 if (fSolidClosed)
216 {
217 G4Exception("G4TessellatedSolid::AddFacet()", "GeomSolids1002",
218 JustWarning, "Attempt to add facets when solid is closed.");
219 return false;
220 }
221 if (aFacet->IsDefined())
222 {
223 set<G4VertexInfo,G4VertexComparator>::iterator begin
224 = fFacetList.begin(), end = fFacetList.end(), pos, it;
225 G4ThreeVector p = aFacet->GetCircumcentre();
226 G4VertexInfo value;
227 value.id = (G4int)fFacetList.size();
228 value.mag2 = p.x() + p.y() + p.z();
229
230 G4bool found = false;
231 if (!OutsideOfExtent(p, kCarTolerance))
232 {
233 G4double kCarTolerance3 = 3 * kCarTolerance;
234 pos = fFacetList.lower_bound(value);
235
236 it = pos;
237 while (!found && it != end) // Loop checking, 13.08.2015, G.Cosmo
238 {
239 G4int id = (*it).id;
240 G4VFacet *facet = fFacets[id];
241 G4ThreeVector q = facet->GetCircumcentre();
242 if ((found = (facet == aFacet))) { break; }
243 G4double dif = q.x() + q.y() + q.z() - value.mag2;
244 if (dif > kCarTolerance3) { break; }
245 it++;
246 }
247
248 if (fFacets.size() > 1)
249 {
250 it = pos;
251 while (!found && it != begin) // Loop checking, 13.08.2015, G.Cosmo
252 {
253 --it;
254 G4int id = (*it).id;
255 G4VFacet *facet = fFacets[id];
256 G4ThreeVector q = facet->GetCircumcentre();
257 found = (facet == aFacet);
258 if (found) { break; }
259 G4double dif = value.mag2 - (q.x() + q.y() + q.z());
260 if (dif > kCarTolerance3) { break; }
261 }
262 }
263 }
264
265 if (!found)
266 {
267 fFacets.push_back(aFacet);
268 fFacetList.insert(value);
269 }
270 return true;
271 }
272
273 G4Exception("G4TessellatedSolid::AddFacet()", "GeomSolids1002",
274 JustWarning, "Attempt to add facet not properly defined.");
275 aFacet->StreamInfo(G4cout);
276 return false;
277}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
G4GLOB_DLL std::ostream G4cout
double z() const
double x() const
double y() const
virtual G4ThreeVector GetCircumcentre() const =0
std::ostream & StreamInfo(std::ostream &os) const
Definition G4VFacet.cc:96
virtual G4bool IsDefined() const =0
G4double kCarTolerance
Definition G4VSolid.hh:418

Referenced by G4tgbVolume::FindOrConstructG4Solid(), operator+=(), and G4GDMLReadSolids::TessellatedRead().

◆ AllocatedMemory()

G4int G4TessellatedSolid::AllocatedMemory ( )

Definition at line 2293 of file G4TessellatedSolid.cc.

2294{
2296 G4int sizeInsides = fInsides.GetNbytes();
2297 G4int sizeVoxels = fVoxels.AllocatedMemory();
2298 size += sizeInsides + sizeVoxels;
2299 return size;
2300}

Referenced by DisplayAllocatedMemory().

◆ AllocatedMemoryWithoutVoxels()

G4int G4TessellatedSolid::AllocatedMemoryWithoutVoxels ( )

Loggers reporting the total allocated memory.

Definition at line 2270 of file G4TessellatedSolid.cc.

2271{
2272 G4int base = sizeof(*this);
2273 base += fVertexList.capacity() * sizeof(G4ThreeVector);
2274 base += fRandir.capacity() * sizeof(G4ThreeVector);
2275
2276 std::size_t limit = fFacets.size();
2277 for (std::size_t i = 0; i < limit; ++i)
2278 {
2279 G4VFacet& facet = *fFacets[i];
2280 base += facet.AllocatedMemory();
2281 }
2282
2283 for (const auto & fExtremeFacet : fExtremeFacets)
2284 {
2285 G4VFacet &facet = *fExtremeFacet;
2286 base += facet.AllocatedMemory();
2287 }
2288 return base;
2289}
virtual G4int AllocatedMemory()=0

Referenced by AllocatedMemory(), and DisplayAllocatedMemory().

◆ BoundingLimits()

void G4TessellatedSolid::BoundingLimits ( G4ThreeVector & pMin,
G4ThreeVector & pMax ) const
overridevirtual

Computes the bounding limits of the solid.

Parameters
[out]pMinThe minimum bounding limit point.
[out]pMaxThe maximum bounding limit point.

Reimplemented from G4VSolid.

Definition at line 2018 of file G4TessellatedSolid.cc.

2020{
2021 pMin = fMinExtent;
2022 pMax = fMaxExtent;
2023
2024 // Check correctness of the bounding box
2025 //
2026 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
2027 {
2028 std::ostringstream message;
2029 message << "Bad bounding box (min >= max) for solid: "
2030 << GetName() << " !"
2031 << "\npMin = " << pMin
2032 << "\npMax = " << pMax;
2033 G4Exception("G4TessellatedSolid::BoundingLimits()",
2034 "GeomMgt0001", JustWarning, message);
2035 DumpInfo();
2036 }
2037}
G4String GetName() const
void DumpInfo() const

Referenced by CalculateExtent().

◆ CalculateExtent()

G4bool G4TessellatedSolid::CalculateExtent ( const EAxis pAxis,
const G4VoxelLimits & pVoxelLimit,
const G4AffineTransform & pTransform,
G4double & pMin,
G4double & pMax ) const
overridevirtual

Calculates the minimum and maximum extent of the solid, when under the specified transform, and within the specified limits.

Parameters
[in]pAxisThe axis along which compute the extent.
[in]pVoxelLimitThe limiting space dictated by voxels.
[in]pTransformThe internal transformation applied to the solid.
[out]pMinThe minimum extent value.
[out]pMaxThe maximum extent value.
Returns
True if the solid is intersected by the extent region.

Implements G4VSolid.

Definition at line 2044 of file G4TessellatedSolid.cc.

2048{
2049 G4ThreeVector bmin, bmax;
2050
2051 // Check bounding box (bbox)
2052 //
2053 BoundingLimits(bmin,bmax);
2054 G4BoundingEnvelope bbox(bmin,bmax);
2055
2056 // Use simple bounding-box to help in the case of complex meshes
2057 //
2058 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
2059
2060#if 0
2061 // Precise extent computation (disabled by default for this shape)
2062 //
2063 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
2064 {
2065 return (pMin < pMax) ? true : false;
2066 }
2067
2068 // The extent is calculated as cumulative extent of the pyramids
2069 // formed by facets and the center of the bounding box.
2070 //
2071 G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
2072 G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
2073
2074 G4ThreeVectorList base;
2075 G4ThreeVectorList apex(1);
2076 std::vector<const G4ThreeVectorList *> pyramid(2);
2077 pyramid[0] = &base;
2078 pyramid[1] = &apex;
2079 apex[0] = (bmin+bmax)*0.5;
2080
2081 // main loop along facets
2082 pMin = kInfinity;
2083 pMax = -kInfinity;
2084 for (G4int i=0; i<GetNumberOfFacets(); ++i)
2085 {
2086 G4VFacet* facet = GetFacet(i);
2087 if (std::abs((facet->GetSurfaceNormal()).dot(facet->GetVertex(0)-apex[0]))
2088 < kCarToleranceHalf) { continue; }
2089
2090 G4int nv = facet->GetNumberOfVertices();
2091 base.resize(nv);
2092 for (G4int k=0; k<nv; ++k) { base[k] = facet->GetVertex(k); }
2093
2094 G4double emin,emax;
2095 G4BoundingEnvelope benv(pyramid);
2096 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
2097 {
2098 continue;
2099 }
2100 if (emin < pMin) { pMin = emin; }
2101 if (emax > pMax) { pMax = emax; }
2102 if (eminlim > pMin && emaxlim < pMax) { break; } // max possible extent
2103 }
2104 return (pMin < pMax);
2105#endif
2106}
std::vector< G4ThreeVector > G4ThreeVectorList
G4int GetNumberOfFacets() const
G4VFacet * GetFacet(G4int i) const
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
virtual G4ThreeVector GetSurfaceNormal() const =0
virtual G4ThreeVector GetVertex(G4int i) const =0
virtual G4int GetNumberOfVertices() const =0
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const

◆ CheckStructure()

G4int G4TessellatedSolid::CheckStructure ( ) const

Checks the structure of the solid.

Returns
A value, sum of the following defect indicators, if any (0 means no defects): 1 - cubic volume is negative, wrong orientation of facets; 2 - some facets have wrong orientation; 4 - holes in the surface.

Definition at line 701 of file G4TessellatedSolid.cc.

702{
703 G4int nedge = 0;
704 std::size_t nface = fFacets.size();
705
706 // Calculate volume
707 //
708 G4double volume = 0.;
709 for (std::size_t i = 0; i < nface; ++i)
710 {
711 G4VFacet& facet = *fFacets[i];
712 nedge += facet.GetNumberOfVertices();
713 volume += facet.GetArea()*(facet.GetVertex(0).dot(facet.GetSurfaceNormal()));
714 }
715 auto ivolume = static_cast<G4int>(volume <= 0.);
716
717 // Create sorted vector of edges
718 //
719 std::vector<int64_t> iedge(nedge);
720 G4int kk = 0;
721 for (std::size_t i = 0; i < nface; ++i)
722 {
723 G4VFacet& facet = *fFacets[i];
724 G4int nnode = facet.GetNumberOfVertices();
725 for (G4int k = 0; k < nnode; ++k)
726 {
727 int64_t i1 = facet.GetVertexIndex((k == 0) ? nnode - 1 : k - 1);
728 int64_t i2 = facet.GetVertexIndex(k);
729 auto inverse = static_cast<int64_t>(i2 > i1);
730 if (inverse != 0) { std::swap(i1, i2); }
731 iedge[kk++] = i1*1000000000 + i2*2 + inverse;
732 }
733 }
734 std::sort(iedge.begin(), iedge.end());
735
736 // Check edges, correct structure should consist of paired edges
737 // with different orientation
738 //
739 G4int iorder = 0;
740 G4int ihole = 0;
741 G4int i = 0;
742 while (i < nedge - 1)
743 {
744 if (iedge[i + 1] - iedge[i] == 1) // paired edges with different orientation
745 {
746 i += 2;
747 }
748 else if (iedge[i + 1] == iedge[i]) // paired edges with the same orientation
749 {
750 iorder = 2;
751 i += 2;
752 }
753 else // unpaired edge
754 {
755 ihole = 4;
756 i++;
757 }
758 }
759 return ivolume + iorder + ihole;
760}
virtual G4double GetArea() const =0
virtual G4int GetVertexIndex(G4int i) const =0

Referenced by SetSolidClosed().

◆ Clone()

G4VSolid * G4TessellatedSolid::Clone ( ) const
overridevirtual

Makes a clone of the object for use in multi-treading.

Returns
A pointer to the new cloned allocated solid.

Reimplemented from G4VSolid.

Definition at line 1822 of file G4TessellatedSolid.cc.

1823{
1824 return new G4TessellatedSolid(*this);
1825}

◆ CreatePolyhedron()

G4Polyhedron * G4TessellatedSolid::CreatePolyhedron ( ) const
overridevirtual

Methods for creating graphical representations (i.e. for visualisation).

Reimplemented from G4VSolid.

Definition at line 1967 of file G4TessellatedSolid.cc.

1968{
1969 auto nVertices = (G4int)fVertexList.size();
1970 auto nFacets = (G4int)fFacets.size();
1971 auto polyhedron = new G4Polyhedron(nVertices, nFacets);
1972 for (auto i = 0; i < nVertices; ++i)
1973 {
1974 polyhedron->SetVertex(i+1, fVertexList[i]);
1975 }
1976
1977 for (auto i = 0; i < nFacets; ++i)
1978 {
1979 G4VFacet* facet = fFacets[i];
1980 G4int v[4] = {0};
1981 G4int n = facet->GetNumberOfVertices();
1982 if (n > 4) { n = 4; }
1983 for (auto j = 0; j < n; ++j)
1984 {
1985 v[j] = facet->GetVertexIndex(j) + 1;
1986 }
1987 polyhedron->SetFacet(i+1, v[0], v[1], v[2], v[3]);
1988 }
1989 polyhedron->SetReferences();
1990
1991 return polyhedron;
1992}

Referenced by GetPolyhedron().

◆ DescribeYourselfTo()

void G4TessellatedSolid::DescribeYourselfTo ( G4VGraphicsScene & scene) const
overridevirtual

A "double dispatch" function which identifies the solid to the graphics scene for visualization.

Implements G4VSolid.

Definition at line 1960 of file G4TessellatedSolid.cc.

1961{
1962 scene.AddSolid (*this);
1963}
virtual void AddSolid(const G4Box &)=0

◆ DisplayAllocatedMemory()

void G4TessellatedSolid::DisplayAllocatedMemory ( )

Definition at line 611 of file G4TessellatedSolid.cc.

612{
614 G4int with = AllocatedMemory();
615 G4double ratio = (G4double) with / without;
616 G4cout << "G4TessellatedSolid - Allocated memory without voxel overhead "
617 << without << "; with " << with << "; ratio: " << ratio << G4endl;
618}
#define G4endl
Definition G4ios.hh:67

Referenced by SetSolidClosed().

◆ DistanceToIn() [1/2]

G4double G4TessellatedSolid::DistanceToIn ( const G4ThreeVector & p) const
overridevirtual

Calculates the distance to the nearest surface of a shape from an outside point. The distance can be an underestimate.

Parameters
[in]pThe point at offset p.
Returns
The safety distance to enter the shape.

Implements G4VSolid.

Definition at line 1868 of file G4TessellatedSolid.cc.

1869{
1870 return SafetyFromOutside(p, false);
1871}
virtual G4double SafetyFromOutside(const G4ThreeVector &p, G4bool aAccurate=false) const

◆ DistanceToIn() [2/2]

G4double G4TessellatedSolid::DistanceToIn ( const G4ThreeVector & p,
const G4ThreeVector & v ) const
overridevirtual

Returns the distance along the normalised vector 'v' to the shape, from the point at offset 'p'. If there is no intersection, returns kInfinity. The first intersection resulting from 'leaving' a surface/volume is discarded. Hence, it is tolerant of points on the surface of the shape.

Parameters
[in]pThe point at offset p.
[in]vThe normalised direction vector.
Returns
The distance to enter the shape.

Implements G4VSolid.

Definition at line 1875 of file G4TessellatedSolid.cc.

1877{
1878 G4double dist = DistanceToInCore(p,v,kInfinity);
1879#ifdef G4SPECSDEBUG
1880 if (dist < kInfinity)
1881 {
1882 if (Inside(p + dist*v) != kSurface)
1883 {
1884 std::ostringstream message;
1885 message << "Invalid response from facet in solid '" << GetName() << "',"
1886 << G4endl
1887 << "at point: " << p << "and direction: " << v;
1888 G4Exception("G4TessellatedSolid::DistanceToIn(p,v)",
1889 "GeomSolids1002", JustWarning, message);
1890 }
1891 }
1892#endif
1893 return dist;
1894}
EInside Inside(const G4ThreeVector &p) const override
@ kSurface
Definition geomdefs.hh:69

Referenced by G4ExtrudedSolid::DistanceToIn(), G4ExtrudedSolid::DistanceToIn(), and SafetyFromInside().

◆ DistanceToOut() [1/2]

G4double G4TessellatedSolid::DistanceToOut ( const G4ThreeVector & p) const
overridevirtual

Calculates the distance to the nearest surface of a shape from an inside point 'p'. The distance can be an underestimate.

Parameters
[in]pThe point at offset p.
Returns
The safety distance to exit the shape.

Implements G4VSolid.

Definition at line 1903 of file G4TessellatedSolid.cc.

1904{
1905 return SafetyFromInside(p, false);
1906}
virtual G4double SafetyFromInside(const G4ThreeVector &p, G4bool aAccurate=false) const

Referenced by G4ExtrudedSolid::DistanceToOut(), G4ExtrudedSolid::DistanceToOut(), and SafetyFromOutside().

◆ DistanceToOut() [2/2]

G4double G4TessellatedSolid::DistanceToOut ( const G4ThreeVector & p,
const G4ThreeVector & v,
const G4bool calcNorm,
G4bool * validNorm,
G4ThreeVector * n ) const
overridevirtual

Returns the distance along the normalised vector 'v' to the shape, from a point at an offset 'p' inside or on the surface of the shape. Intersections with surfaces, when the point is less than Tolerance/2 from a surface must be ignored.

Parameters
[in]pThe point at offset p.
[in]vThe normalised direction vector.
[in]calcNormFlag to indicate if to calculate the normal or not.
[out]validNormFlag set to true if the solid lies entirely behind or on the exiting surface. It is set false if the solid does not lie entirely behind or on the exiting surface. 'calcNorm' must be true, otherwise it is unused.
[out]nThe exiting outwards normal vector (undefined Magnitude). 'calcNorm' must be true, otherwise it is unused.
Returns
The distance to exit the shape.

Implements G4VSolid.

Definition at line 1926 of file G4TessellatedSolid.cc.

1931{
1933 G4bool valid;
1934
1935 G4double dist = DistanceToOutCore(p, v, n, valid);
1936 if (calcNorm)
1937 {
1938 *norm = n;
1939 *validNorm = valid;
1940 }
1941#ifdef G4SPECSDEBUG
1942 if (dist < kInfinity)
1943 {
1944 if (Inside(p + dist*v) != kSurface)
1945 {
1946 std::ostringstream message;
1947 message << "Invalid response from facet in solid '" << GetName() << "',"
1948 << G4endl
1949 << "at point: " << p << "and direction: " << v;
1950 G4Exception("G4TessellatedSolid::DistanceToOut(p,v,..)",
1951 "GeomSolids1002", JustWarning, message);
1952 }
1953 }
1954#endif
1955 return dist;
1956}

◆ GetCubicVolume()

G4double G4TessellatedSolid::GetCubicVolume ( )
overridevirtual

Returns an estimation of the solid volume in internal units. This method may be overloaded by derived classes to compute the exact geometrical quantity for solids where this is possible, or anyway to cache the computed value. Note: the computed value is NOT cached.

Reimplemented from G4VSolid.

Definition at line 2161 of file G4TessellatedSolid.cc.

2162{
2163 if (fCubicVolume != 0.) { return fCubicVolume; }
2164
2165 // For explanation of the following algorithm see:
2166 // https://en.wikipedia.org/wiki/Polyhedron#Volume
2167 // http://wwwf.imperial.ac.uk/~rn/centroid.pdf
2168
2169 G4AutoLock l(&tessMutex);
2170 std::size_t size = fFacets.size();
2171 for (std::size_t i = 0; i < size; ++i)
2172 {
2173 G4VFacet &facet = *fFacets[i];
2174 G4double area = facet.GetArea();
2175 G4ThreeVector unit_normal = facet.GetSurfaceNormal();
2176 fCubicVolume += area * (facet.GetVertex(0).dot(unit_normal));
2177 }
2178 fCubicVolume /= 3.;
2179 l.unlock();
2180
2181 return fCubicVolume;
2182}
G4TemplateAutoLock< G4Mutex > G4AutoLock

◆ GetEntityType()

G4GeometryType G4TessellatedSolid::GetEntityType ( ) const
overridevirtual

Returns the type ID, "G4TessellatedSolid" of the solid.

Implements G4VSolid.

Definition at line 1783 of file G4TessellatedSolid.cc.

1784{
1785 return fGeometryType;
1786}

◆ GetExtent()

G4VisExtent G4TessellatedSolid::GetExtent ( ) const
overridevirtual

Provides extent (bounding box) as possible hint to the graphics view.

Reimplemented from G4VSolid.

Definition at line 2152 of file G4TessellatedSolid.cc.

2153{
2154 return { fMinExtent.x(), fMaxExtent.x(),
2155 fMinExtent.y(), fMaxExtent.y(),
2156 fMinExtent.z(), fMaxExtent.z() };
2157}

◆ GetFacet()

G4VFacet * G4TessellatedSolid::GetFacet ( G4int i) const
inline

Definition at line 476 of file G4TessellatedSolid.hh.

477{
478 return fFacets[i];
479}

Referenced by CalculateExtent(), operator+=(), and G4GDMLWriteSolids::TessellatedWrite().

◆ GetFacetIndex()

G4int G4TessellatedSolid::GetFacetIndex ( const G4ThreeVector & p) const

Definition at line 1143 of file G4TessellatedSolid.cc.

1144{
1145 G4int index = -1;
1146
1147 if (fVoxels.GetCountOfVoxels() > 1)
1148 {
1149 vector<G4int> curVoxel(3);
1150 fVoxels.GetVoxel(curVoxel, p);
1151 const vector<G4int> &candidates = fVoxels.GetCandidates(curVoxel);
1152 if (auto limit = (G4int)candidates.size())
1153 {
1154 G4double minDist = kInfinity;
1155 for(G4int i = 0 ; i < limit ; ++i)
1156 {
1157 G4int candidate = candidates[i];
1158 G4VFacet& facet = *fFacets[candidate];
1159 G4double dist = facet.Distance(p, minDist);
1160 if (dist <= kCarToleranceHalf) { return index = candidate; }
1161 if (dist < minDist)
1162 {
1163 minDist = dist;
1164 index = candidate;
1165 }
1166 }
1167 }
1168 }
1169 else
1170 {
1171 G4double minDist = kInfinity;
1172 std::size_t size = fFacets.size();
1173 for (std::size_t i = 0; i < size; ++i)
1174 {
1175 G4VFacet& facet = *fFacets[i];
1176 G4double dist = facet.Distance(p, minDist);
1177 if (dist < minDist)
1178 {
1179 minDist = dist;
1180 index = (G4int)i;
1181 }
1182 }
1183 }
1184 return index;
1185}
virtual G4double Distance(const G4ThreeVector &, G4double minDist)=0

◆ GetMaxXExtent()

G4double G4TessellatedSolid::GetMaxXExtent ( ) const

Definition at line 2117 of file G4TessellatedSolid.cc.

2118{
2119 return fMaxExtent.x();
2120}

Referenced by G4ExtrudedSolid::Inside().

◆ GetMaxYExtent()

G4double G4TessellatedSolid::GetMaxYExtent ( ) const

Definition at line 2131 of file G4TessellatedSolid.cc.

2132{
2133 return fMaxExtent.y();
2134}

Referenced by G4ExtrudedSolid::Inside().

◆ GetMaxZExtent()

G4double G4TessellatedSolid::GetMaxZExtent ( ) const

Definition at line 2145 of file G4TessellatedSolid.cc.

2146{
2147 return fMaxExtent.z();
2148}

Referenced by G4ExtrudedSolid::Inside().

◆ GetMinXExtent()

G4double G4TessellatedSolid::GetMinXExtent ( ) const

Definition at line 2110 of file G4TessellatedSolid.cc.

2111{
2112 return fMinExtent.x();
2113}

Referenced by G4ExtrudedSolid::Inside().

◆ GetMinYExtent()

G4double G4TessellatedSolid::GetMinYExtent ( ) const

Definition at line 2124 of file G4TessellatedSolid.cc.

2125{
2126 return fMinExtent.y();
2127}

Referenced by G4ExtrudedSolid::Inside().

◆ GetMinZExtent()

G4double G4TessellatedSolid::GetMinZExtent ( ) const

Definition at line 2138 of file G4TessellatedSolid.cc.

2139{
2140 return fMinExtent.z();
2141}

Referenced by G4ExtrudedSolid::Inside().

◆ GetNumberOfFacets()

G4int G4TessellatedSolid::GetNumberOfFacets ( ) const

Accessors.

Definition at line 786 of file G4TessellatedSolid.cc.

787{
788 return (G4int)fFacets.size();
789}

Referenced by CalculateExtent(), operator+=(), and G4GDMLWriteSolids::TessellatedWrite().

◆ GetPointOnSurface()

G4ThreeVector G4TessellatedSolid::GetPointOnSurface ( ) const
overridevirtual

Returns a random point located and uniformly distributed on the surface of the solid.

Reimplemented from G4VSolid.

Definition at line 2204 of file G4TessellatedSolid.cc.

2205{
2206 // Select randomly a facet and return a random point on it
2207
2208 auto i = (G4int)(fFacets.size()*G4QuickRand());
2209 return fFacets[i]->GetPointOnFace();
2210}
G4double G4QuickRand(uint32_t seed=0)

◆ GetPolyhedron()

G4Polyhedron * G4TessellatedSolid::GetPolyhedron ( ) const
overridevirtual

Smart access function - creates on request and stores for future access. A null pointer means "not available".

Reimplemented from G4VSolid.

Definition at line 1998 of file G4TessellatedSolid.cc.

1999{
2000 if (fpPolyhedron == nullptr ||
2001 fRebuildPolyhedron ||
2002 fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
2003 fpPolyhedron->GetNumberOfRotationSteps())
2004 {
2005 G4AutoLock l(&polyhedronMutex);
2006 delete fpPolyhedron;
2007 fpPolyhedron = CreatePolyhedron();
2008 fRebuildPolyhedron = false;
2009 l.unlock();
2010 }
2011 return fpPolyhedron;
2012}
G4Polyhedron * CreatePolyhedron() const override

◆ GetSolidClosed()

G4bool G4TessellatedSolid::GetSolidClosed ( ) const

Definition at line 686 of file G4TessellatedSolid.cc.

687{
688 return fSolidClosed;
689}

◆ GetSurfaceArea()

G4double G4TessellatedSolid::GetSurfaceArea ( )
overridevirtual

Returning an estimation of the solid volume (capacity) and surface area, in internal units.

Reimplemented from G4VSolid.

Definition at line 2186 of file G4TessellatedSolid.cc.

2187{
2188 if (fSurfaceArea != 0.) { return fSurfaceArea; }
2189
2190 G4AutoLock l(&tessMutex);
2191 std::size_t size = fFacets.size();
2192 for (std::size_t i = 0; i < size; ++i)
2193 {
2194 G4VFacet &facet = *fFacets[i];
2195 fSurfaceArea += facet.GetArea();
2196 }
2197 l.unlock();
2198
2199 return fSurfaceArea;
2200}

◆ GetVoxels()

G4Voxelizer & G4TessellatedSolid::GetVoxels ( )
inline

Returns the voxels structure.

Definition at line 486 of file G4TessellatedSolid.hh.

487{
488 return fVoxels;
489}

◆ Inside()

EInside G4TessellatedSolid::Inside ( const G4ThreeVector & p) const
overridevirtual

Concrete implementations of the expected query interfaces for solids, as defined in the base class G4VSolid.

Implements G4VSolid.

Definition at line 1837 of file G4TessellatedSolid.cc.

1838{
1839 EInside location;
1840
1841 if (fVoxels.GetCountOfVoxels() > 1)
1842 {
1843 location = InsideVoxels(aPoint);
1844 }
1845 else
1846 {
1847 location = InsideNoVoxels(aPoint);
1848 }
1849 return location;
1850}
EInside
Definition geomdefs.hh:67

Referenced by DistanceToIn(), DistanceToOut(), SafetyFromInside(), and SafetyFromOutside().

◆ IsFaceted()

G4bool G4TessellatedSolid::IsFaceted ( ) const
overridevirtual

Returns true as the solid has only planar faces.

Reimplemented from G4VSolid.

Definition at line 1792 of file G4TessellatedSolid.cc.

1793{
1794 return true;
1795}

◆ Normal()

G4bool G4TessellatedSolid::Normal ( const G4ThreeVector & p,
G4ThreeVector & n ) const
virtual

Returns the outwards pointing unit normal of the shape for the surface closest to the point at offset 'p'.

Parameters
[in]pThe point coordinates.
[out]nThe returned normal vector.
Returns
false if not a valid normal.

Definition at line 1192 of file G4TessellatedSolid.cc.

1194{
1195 G4double minDist;
1196 G4VFacet* facet = nullptr;
1197
1198 if (fVoxels.GetCountOfVoxels() > 1)
1199 {
1200 vector<G4int> curVoxel(3);
1201 fVoxels.GetVoxel(curVoxel, p);
1202 const vector<G4int> &candidates = fVoxels.GetCandidates(curVoxel);
1203 // fVoxels.GetCandidatesVoxelArray(p, candidates, 0);
1204
1205 if (auto limit = (G4int)candidates.size())
1206 {
1207 minDist = kInfinity;
1208 for(G4int i = 0 ; i < limit ; ++i)
1209 {
1210 G4int candidate = candidates[i];
1211 G4VFacet &fct = *fFacets[candidate];
1212 G4double dist = fct.Distance(p,minDist);
1213 if (dist < minDist) { minDist = dist; }
1214 if (dist <= kCarToleranceHalf)
1215 {
1216 aNormal = fct.GetSurfaceNormal();
1217 return true;
1218 }
1219 }
1220 }
1221 minDist = MinDistanceFacet(p, true, facet);
1222 }
1223 else
1224 {
1225 minDist = kInfinity;
1226 std::size_t size = fFacets.size();
1227 for (std::size_t i = 0; i < size; ++i)
1228 {
1229 G4VFacet& f = *fFacets[i];
1230 G4double dist = f.Distance(p, minDist);
1231 if (dist < minDist)
1232 {
1233 minDist = dist;
1234 facet = &f;
1235 }
1236 }
1237 }
1238
1239 if (minDist != kInfinity)
1240 {
1241 if (facet != nullptr) { aNormal = facet->GetSurfaceNormal(); }
1242 return minDist <= kCarToleranceHalf;
1243 }
1244
1245#ifdef G4VERBOSE
1246 std::ostringstream message;
1247 message << "Point p is not on surface !?" << G4endl
1248 << " No facets found for point: " << p << " !" << G4endl
1249 << " Returning approximated value for normal.";
1250
1251 G4Exception("G4TessellatedSolid::SurfaceNormal(p)",
1252 "GeomSolids1002", JustWarning, message );
1253#endif
1254
1255 aNormal = (p.z() > 0 ? G4ThreeVector(0,0,1) : G4ThreeVector(0,0,-1));
1256 return false;
1257}

Referenced by SurfaceNormal().

◆ operator+=()

G4TessellatedSolid & G4TessellatedSolid::operator+= ( const G4TessellatedSolid & right)

Operator +=, allowing to add two tessellated solids together, so that the solid on the left includes all of the facets in the solid on the right. To note that copies of the facets are generated, rather than using the original facet set of the solid on the right.

Definition at line 772 of file G4TessellatedSolid.cc.

773{
774 G4int size = right.GetNumberOfFacets();
775 for (G4int i = 0; i < size; ++i) {
776 AddFacet(right.GetFacet(i)->GetClone());
777}
778
779 return *this;
780}
G4bool AddFacet(G4VFacet *aFacet)
virtual G4VFacet * GetClone()=0

◆ operator=()

G4TessellatedSolid & G4TessellatedSolid::operator= ( const G4TessellatedSolid & right)

Definition at line 138 of file G4TessellatedSolid.cc.

139{
140 if (&ts == this) { return *this; }
141
142 // Copy base class data
144
145 DeleteObjects ();
146
147 Initialize();
148
149 CopyObjects (ts);
150
151 return *this;
152}
G4VSolid & operator=(const G4VSolid &rhs)
Definition G4VSolid.cc:108

Referenced by G4ExtrudedSolid::operator=().

◆ SafetyFromInside()

G4double G4TessellatedSolid::SafetyFromInside ( const G4ThreeVector & p,
G4bool aAccurate = false ) const
virtual

Returns the the safety distance from inside the solid at a point 'p'.

Parameters
[in]pThe point coordinates.
[in]aAccurateNot used.
Returns
The safety distance.

Definition at line 1734 of file G4TessellatedSolid.cc.

1735{
1736#if G4SPECSDEBUG
1737 if ( Inside(p) == kOutside )
1738 {
1739 std::ostringstream message;
1740 G4int oldprc = message.precision(16) ;
1741 message << "Point p is already outside!?" << G4endl
1742 << "Position:" << G4endl << G4endl
1743 << "p.x() = " << p.x()/mm << " mm" << G4endl
1744 << "p.y() = " << p.y()/mm << " mm" << G4endl
1745 << "p.z() = " << p.z()/mm << " mm" << G4endl
1746 << "DistanceToIn(p) == " << DistanceToIn(p);
1747 message.precision(oldprc) ;
1748 G4Exception("G4TriangularFacet::DistanceToOut(p)",
1749 "GeomSolids1002", JustWarning, message);
1750 }
1751#endif
1752
1753 G4double minDist;
1754
1755 if (OutsideOfExtent(p, kCarTolerance)) { return 0.0; }
1756
1757 if (fVoxels.GetCountOfVoxels() > 1)
1758 {
1759 G4VFacet* facet;
1760 minDist = MinDistanceFacet(p, true, facet);
1761 }
1762 else
1763 {
1764 minDist = kInfinity;
1765 G4double dist = 0.0;
1766 std::size_t size = fFacets.size();
1767 for (std::size_t i = 0; i < size; ++i)
1768 {
1769 G4VFacet& facet = *fFacets[i];
1770 dist = facet.Distance(p,minDist);
1771 if (dist < minDist) { minDist = dist; }
1772 }
1773 }
1774 return minDist;
1775}
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
@ kOutside
Definition geomdefs.hh:68

Referenced by DistanceToOut().

◆ SafetyFromOutside()

G4double G4TessellatedSolid::SafetyFromOutside ( const G4ThreeVector & p,
G4bool aAccurate = false ) const
virtual

Returns the the safety distance from outside the solid at a point 'p'.

Parameters
[in]pThe point coordinates.
[in]aAccurateAccuracy flag, if false quickly computes and returns the distance to the voxels bounding-box.
Returns
The safety distance.

Definition at line 1676 of file G4TessellatedSolid.cc.

1678{
1679#if G4SPECSDEBUG
1680 if ( Inside(p) == kInside )
1681 {
1682 std::ostringstream message;
1683 G4int oldprc = message.precision(16) ;
1684 message << "Point p is already inside!?" << G4endl
1685 << "Position:" << G4endl << G4endl
1686 << "p.x() = " << p.x()/mm << " mm" << G4endl
1687 << "p.y() = " << p.y()/mm << " mm" << G4endl
1688 << "p.z() = " << p.z()/mm << " mm" << G4endl
1689 << "DistanceToOut(p) == " << DistanceToOut(p);
1690 message.precision(oldprc) ;
1691 G4Exception("G4TriangularFacet::DistanceToIn(p)",
1692 "GeomSolids1002", JustWarning, message);
1693 }
1694#endif
1695
1696 G4double minDist;
1697
1698 if (fVoxels.GetCountOfVoxels() > 1)
1699 {
1700 if (!aAccurate) { return fVoxels.DistanceToBoundingBox(p); }
1701
1702 if (!OutsideOfExtent(p, kCarTolerance))
1703 {
1704 vector<G4int> startingVoxel(3);
1705 fVoxels.GetVoxel(startingVoxel, p);
1706 const vector<G4int> &candidates = fVoxels.GetCandidates(startingVoxel);
1707 if (candidates.empty() && (fInsides.GetNbits() != 0u))
1708 {
1709 G4int index = fVoxels.GetPointIndex(p);
1710 if (fInsides[index]) { return 0.; }
1711 }
1712 }
1713
1714 G4VFacet* facet;
1715 minDist = MinDistanceFacet(p, true, facet);
1716 }
1717 else
1718 {
1719 minDist = kInfinity;
1720 std::size_t size = fFacets.size();
1721 for (std::size_t i = 0; i < size; ++i)
1722 {
1723 G4VFacet& facet = *fFacets[i];
1724 G4double dist = facet.Distance(p,minDist);
1725 if (dist < minDist) { minDist = dist; }
1726 }
1727 }
1728 return minDist;
1729}
G4double DistanceToOut(const G4ThreeVector &p) const override
@ kInside
Definition geomdefs.hh:70

Referenced by DistanceToIn().

◆ SetMaxVoxels()

void G4TessellatedSolid::SetMaxVoxels ( G4int max)
inline

Allowing to tune the maximum number of voxels to use for optimisation.

Definition at line 481 of file G4TessellatedSolid.hh.

482{
483 fVoxels.SetMaxVoxels(max);
484}

◆ SetSolidClosed()

void G4TessellatedSolid::SetSolidClosed ( const G4bool t)

Modifier and accessor to close/finalise the solid.

Definition at line 622 of file G4TessellatedSolid.cc.

623{
624 if (t)
625 {
626#ifdef G4SPECSDEBUG
627 G4cout << "Creating vertex list..." << G4endl;
628#endif
629 CreateVertexList();
630
631#ifdef G4SPECSDEBUG
632 G4cout << "Setting extreme facets..." << G4endl;
633#endif
634 SetExtremeFacets();
635
636#ifdef G4SPECSDEBUG
637 G4cout << "Voxelizing..." << G4endl;
638#endif
639 Voxelize();
640
641#ifdef G4SPECSDEBUG
643#endif
644
645#ifdef G4SPECSDEBUG
646 G4cout << "Checking Structure..." << G4endl;
647#endif
648 G4int irep = CheckStructure();
649 if (irep != 0)
650 {
651 if ((irep & 1) != 0)
652 {
653 std::ostringstream message;
654 message << "Defects in solid: " << GetName()
655 << " - negative cubic volume, please check orientation of facets!";
656 G4Exception("G4TessellatedSolid::SetSolidClosed()",
657 "GeomSolids1001", JustWarning, message);
658 }
659 if ((irep & 2) != 0)
660 {
661 std::ostringstream message;
662 message << "Defects in solid: " << GetName()
663 << " - some facets have wrong orientation!";
664 G4Exception("G4TessellatedSolid::SetSolidClosed()",
665 "GeomSolids1001", JustWarning, message);
666 }
667 if ((irep & 4) != 0)
668 {
669 std::ostringstream message;
670 message << "Defects in solid: " << GetName()
671 << " - there are holes in the surface!";
672 G4Exception("G4TessellatedSolid::SetSolidClosed()",
673 "GeomSolids1001", JustWarning, message);
674 }
675 }
676 }
677 fSolidClosed = t;
678}

Referenced by G4GDMLReadSolids::TessellatedRead().

◆ StreamInfo()

std::ostream & G4TessellatedSolid::StreamInfo ( std::ostream & os) const
overridevirtual

Streams the object contents to an output stream.

Implements G4VSolid.

Definition at line 1799 of file G4TessellatedSolid.cc.

1800{
1801 os << G4endl;
1802 os << "Solid name = " << GetName() << G4endl;
1803 os << "Geometry Type = " << fGeometryType << G4endl;
1804 os << "Number of facets = " << fFacets.size() << G4endl;
1805
1806 std::size_t size = fFacets.size();
1807 for (std::size_t i = 0; i < size; ++i)
1808 {
1809 os << "FACET # = " << i + 1 << G4endl;
1810 G4VFacet &facet = *fFacets[i];
1811 facet.StreamInfo(os);
1812 }
1813 os << G4endl;
1814
1815 return os;
1816}

◆ SurfaceNormal()

G4ThreeVector G4TessellatedSolid::SurfaceNormal ( const G4ThreeVector & p) const
overridevirtual

Returns the outwards pointing unit normal of the shape for the surface closest to the point at offset 'p'.

Parameters
[in]pThe point at offset p.
Returns
The outwards pointing unit normal.

Implements G4VSolid.

Definition at line 1854 of file G4TessellatedSolid.cc.

1855{
1857 Normal(p, n);
1858 return n;
1859}
virtual G4bool Normal(const G4ThreeVector &p, G4ThreeVector &n) const

Referenced by G4ExtrudedSolid::SurfaceNormal().

Member Data Documentation

◆ kCarToleranceHalf


The documentation for this class was generated from the following files: