Geant4-11
Data Structures | Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions | Private Attributes
G4ExtrudedSolid Class Reference

#include <G4ExtrudedSolid.hh>

Inheritance diagram for G4ExtrudedSolid:
G4TessellatedSolid G4VSolid

Data Structures

struct  line
 
struct  plane
 
struct  ZSection
 

Public Member Functions

G4bool AddFacet (G4VFacet *aFacet)
 
G4int AllocatedMemory ()
 
G4int AllocatedMemoryWithoutVoxels ()
 
void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
 
G4int CheckStructure () const
 
G4VSolidClone () const
 
virtual void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
 
virtual G4PolyhedronCreatePolyhedron () const
 
virtual void DescribeYourselfTo (G4VGraphicsScene &scene) const
 
void DisplayAllocatedMemory ()
 
G4double DistanceToIn (const G4ThreeVector &p) const
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const
 
G4double DistanceToOut (const G4ThreeVector &p) const
 
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const
 
void DumpInfo () const
 
G4double EstimateCubicVolume (G4int nStat, G4double epsilon) const
 
G4double EstimateSurfaceArea (G4int nStat, G4double ell) const
 
 G4ExtrudedSolid (__void__ &)
 
 G4ExtrudedSolid (const G4ExtrudedSolid &rhs)
 
 G4ExtrudedSolid (const G4String &pName, const std::vector< G4TwoVector > &polygon, const std::vector< ZSection > &zsections)
 
 G4ExtrudedSolid (const G4String &pName, const std::vector< G4TwoVector > &polygon, G4double halfZ, const G4TwoVector &off1, G4double scale1, const G4TwoVector &off2, G4double scale2)
 
virtual G4VSolidGetConstituentSolid (G4int no)
 
virtual const G4VSolidGetConstituentSolid (G4int no) const
 
virtual G4double GetCubicVolume ()
 
virtual G4DisplacedSolidGetDisplacedSolidPtr ()
 
virtual const G4DisplacedSolidGetDisplacedSolidPtr () const
 
G4GeometryType GetEntityType () const
 
virtual G4VisExtent GetExtent () const
 
G4VFacetGetFacet (G4int i) const
 
G4int GetFacetIndex (const G4ThreeVector &p) const
 
G4double GetMaxXExtent () const
 
G4double GetMaxYExtent () const
 
G4double GetMaxZExtent () const
 
G4double GetMinXExtent () const
 
G4double GetMinYExtent () const
 
G4double GetMinZExtent () const
 
G4String GetName () const
 
G4int GetNofVertices () const
 
G4int GetNofZSections () const
 
G4int GetNumberOfFacets () const
 
virtual G4ThreeVector GetPointOnSurface () const
 
std::vector< G4TwoVectorGetPolygon () const
 
virtual G4PolyhedronGetPolyhedron () const
 
G4bool GetSolidClosed () const
 
virtual G4double GetSurfaceArea ()
 
G4double GetTolerance () const
 
G4TwoVector GetVertex (G4int index) const
 
G4VoxelizerGetVoxels ()
 
ZSection GetZSection (G4int index) const
 
std::vector< ZSectionGetZSections () const
 
EInside Inside (const G4ThreeVector &p) const
 
virtual G4bool Normal (const G4ThreeVector &p, G4ThreeVector &n) const
 
G4TessellatedSolidoperator+= (const G4TessellatedSolid &right)
 
G4ExtrudedSolidoperator= (const G4ExtrudedSolid &rhs)
 
G4bool operator== (const G4VSolid &s) const
 
virtual G4double SafetyFromInside (const G4ThreeVector &p, G4bool aAccurate=false) const
 
virtual G4double SafetyFromOutside (const G4ThreeVector &p, G4bool aAccurate=false) const
 
void SetMaxVoxels (G4int max)
 
void SetName (const G4String &name)
 
void SetSolidClosed (const G4bool t)
 
std::ostream & StreamInfo (std::ostream &os) const
 
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const
 
virtual ~G4ExtrudedSolid ()
 

Protected Member Functions

void CalculateClippedPolygonExtent (G4ThreeVectorList &pPolygon, 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 ClipCrossSection (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
 

Protected Attributes

G4double kCarTolerance
 
G4double kCarToleranceHalf
 

Private Member Functions

G4bool AddGeneralPolygonFacets ()
 
G4ThreeVector ApproxSurfaceNormal (const G4ThreeVector &p) const
 
void ClipPolygonToSimpleLimits (G4ThreeVectorList &pPolygon, G4ThreeVectorList &outputPolygon, const G4VoxelLimits &pVoxelLimit) const
 
void ComputeLateralPlanes ()
 
void ComputeProjectionParameters ()
 
void CopyObjects (const G4TessellatedSolid &s)
 
void CreateVertexList ()
 
void DeleteObjects ()
 
G4double DistanceToInCandidates (const std::vector< G4int > &candidates, const G4ThreeVector &aPoint, const G4ThreeVector &aDirection) const
 
G4double DistanceToInCore (const G4ThreeVector &p, const G4ThreeVector &v, G4double aPstep=kInfinity) const
 
G4double DistanceToInNoVoxels (const G4ThreeVector &p, const G4ThreeVector &v, G4double aPstep=kInfinity) const
 
void DistanceToOutCandidates (const std::vector< G4int > &candidates, const G4ThreeVector &aPoint, const G4ThreeVector &direction, G4double &minDist, G4ThreeVector &minNormal, G4int &minCandidate) const
 
G4double DistanceToOutCore (const G4ThreeVector &p, const G4ThreeVector &v, G4ThreeVector &aNormalVector, G4bool &aConvex, G4double aPstep=kInfinity) const
 
G4double DistanceToOutNoVoxels (const G4ThreeVector &p, const G4ThreeVector &v, G4ThreeVector &aNormalVector, G4bool &aConvex, G4double aPstep=kInfinity) const
 
G4double DistanceToPolygonSqr (const G4ThreeVector &p) const
 
G4double GetAngle (const G4TwoVector &p0, const G4TwoVector &pa, const G4TwoVector &pb) const
 
G4ThreeVector GetVertex (G4int iz, G4int ind) const
 
void Initialize ()
 
EInside InsideNoVoxels (const G4ThreeVector &p) const
 
EInside InsideVoxels (const G4ThreeVector &aPoint) const
 
G4bool IsPointInside (const G4TwoVector &a, const G4TwoVector &b, const G4TwoVector &c, const G4TwoVector &p) const
 
G4bool IsSameLine (const G4TwoVector &p, const G4TwoVector &l1, const G4TwoVector &l2) const
 
G4bool IsSameLineSegment (const G4TwoVector &p, const G4TwoVector &l1, const G4TwoVector &l2) const
 
G4bool IsSameSide (const G4TwoVector &p1, const G4TwoVector &p2, const G4TwoVector &l1, const G4TwoVector &l2) const
 
G4VFacetMakeDownFacet (G4int ind1, G4int ind2, G4int ind3) const
 
G4bool MakeFacets ()
 
G4VFacetMakeUpFacet (G4int ind1, G4int ind2, G4int ind3) const
 
G4double MinDistanceFacet (const G4ThreeVector &p, G4bool simple, G4VFacet *&facet) const
 
G4bool OutsideOfExtent (const G4ThreeVector &p, G4double tolerance=0.0) const
 
G4bool PointInPolygon (const G4ThreeVector &p) const
 
void PrecalculateInsides ()
 
G4TwoVector ProjectPoint (const G4ThreeVector &point) const
 
G4int SetAllUsingStack (const std::vector< G4int > &voxel, const std::vector< G4int > &max, G4bool status, G4SurfBits &checked)
 
void SetExtremeFacets ()
 
void SetRandomVectors ()
 
void Voxelize ()
 

Static Private Member Functions

static G4bool CompareSortedVoxel (const std::pair< G4int, G4double > &l, const std::pair< G4int, G4double > &r)
 

Private Attributes

G4double fCubicVolume = 0.0
 
std::set< G4VFacet * > fExtremeFacets
 
std::set< G4VertexInfo, G4VertexComparatorfFacetList
 
std::vector< G4VFacet * > fFacets
 
G4GeometryType fGeometryType
 
G4SurfBits fInsides
 
G4bool fIsConvex = false
 
std::vector< G4TwoVectorfKOffsets
 
std::vector< G4doublefKScales
 
std::vector< G4doublefLengths
 
std::vector< linefLines
 
G4ThreeVector fMaxExtent
 
G4int fMaxTries
 
G4ThreeVector fMinExtent
 
G4int fNv
 
G4int fNz
 
std::vector< G4TwoVectorfOffset0s
 
std::vector< planefPlanes
 
std::vector< G4TwoVectorfPolygon
 
G4PolyhedronfpPolyhedron = nullptr
 
std::vector< G4ThreeVectorfRandir
 
G4bool fRebuildPolyhedron = false
 
std::vector< G4doublefScale0s
 
G4String fshapeName
 
G4bool fSolidClosed = false
 
G4int fSolidType = 0
 
G4double fSurfaceArea = 0.0
 
std::vector< std::vector< G4int > > fTriangles
 
std::vector< G4ThreeVectorfVertexList
 
G4Voxelizer fVoxels
 
std::vector< ZSectionfZSections
 

Detailed Description

Definition at line 71 of file G4ExtrudedSolid.hh.

Constructor & Destructor Documentation

◆ G4ExtrudedSolid() [1/4]

G4ExtrudedSolid::G4ExtrudedSolid ( const G4String pName,
const std::vector< G4TwoVector > &  polygon,
const std::vector< ZSection > &  zsections 
)

Definition at line 66 of file G4ExtrudedSolid.cc.

69 : G4TessellatedSolid(pName),
70 fNv(polygon.size()),
71 fNz(zsections.size()),
72 fIsConvex(false),
73 fGeometryType("G4ExtrudedSolid"),
74 fSolidType(0)
75{
76 // General constructor
77
78 // First check input parameters
79
80 if (fNv < 3)
81 {
82 std::ostringstream message;
83 message << "Number of vertices in polygon < 3 - " << pName;
84 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
85 FatalErrorInArgument, message);
86 }
87
88 if (fNz < 2)
89 {
90 std::ostringstream message;
91 message << "Number of z-sides < 2 - " << pName;
92 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
93 FatalErrorInArgument, message);
94 }
95
96 for ( G4int i=0; i<fNz-1; ++i )
97 {
98 if ( zsections[i].fZ > zsections[i+1].fZ )
99 {
100 std::ostringstream message;
101 message << "Z-sections have to be ordered by z value (z0 < z1 < z2...) - "
102 << pName;
103 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
104 FatalErrorInArgument, message);
105 }
106 if ( std::fabs( zsections[i+1].fZ - zsections[i].fZ ) < kCarToleranceHalf )
107 {
108 std::ostringstream message;
109 message << "Z-sections with the same z position are not supported - "
110 << pName;
111 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0001",
112 FatalException, message);
113 }
114 }
115
116 // Copy polygon
117 //
118 fPolygon = polygon;
119
120 // Remove collinear and coincident vertices, if any
121 //
122 std::vector<G4int> removedVertices;
124 2*kCarTolerance);
125 if (removedVertices.size() != 0)
126 {
127 G4int nremoved = removedVertices.size();
128 std::ostringstream message;
129 message << "The following "<< nremoved
130 << " vertices have been removed from polygon in " << pName
131 << "\nas collinear or coincident with other vertices: "
132 << removedVertices[0];
133 for (G4int i=1; i<nremoved; ++i) message << ", " << removedVertices[i];
134 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
135 JustWarning, message);
136 }
137
138 fNv = fPolygon.size();
139 if (fNv < 3)
140 {
141 std::ostringstream message;
142 message << "Number of vertices in polygon after removal < 3 - " << pName;
143 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
144 FatalErrorInArgument, message);
145 }
146
147 // Check if polygon vertices are defined clockwise
148 // (the area is positive if polygon vertices are defined anti-clockwise)
149 //
151 {
152 // Polygon vertices are defined anti-clockwise, we revert them
153 // G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
154 // JustWarning,
155 // "Polygon vertices defined anti-clockwise, reverting polygon");
156 std::reverse(fPolygon.begin(),fPolygon.end());
157 }
158
159 // Copy z-sections
160 //
161 fZSections = zsections;
162
163 G4bool result = MakeFacets();
164 if (!result)
165 {
166 std::ostringstream message;
167 message << "Making facets failed - " << pName;
168 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0003",
169 FatalException, message);
170 }
172
174
175 // Check if the solid is a right prism, if so then set lateral planes
176 //
177 if ((fNz == 2)
178 && (fZSections[0].fScale == 1) && (fZSections[1].fScale == 1)
179 && (fZSections[0].fOffset == G4TwoVector(0,0))
180 && (fZSections[1].fOffset == G4TwoVector(0,0)))
181 {
182 fSolidType = (fIsConvex) ? 1 : 2; // 1 - convex, 2 - non-convex right prism
184 }
185}
@ JustWarning
@ FatalException
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:36
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
std::vector< ZSection > fZSections
G4GeometryType fGeometryType
void ComputeProjectionParameters()
std::vector< G4TwoVector > fPolygon
static void RemoveRedundantVertices(G4TwoVectorList &polygon, std::vector< G4int > &iout, G4double tolerance=0.0)
Definition: G4GeomTools.cc:305
static G4double PolygonArea(const G4TwoVectorList &polygon)
Definition: G4GeomTools.cc:76
static G4bool IsConvex(const G4TwoVectorList &polygon)
Definition: G4GeomTools.cc:165
G4double kCarTolerance
Definition: G4VSolid.hh:299

References ComputeLateralPlanes(), ComputeProjectionParameters(), FatalErrorInArgument, FatalException, fIsConvex, fNv, fNz, fPolygon, fSolidType, fZSections, G4Exception(), G4GeomTools::IsConvex(), JustWarning, G4VSolid::kCarTolerance, G4TessellatedSolid::kCarToleranceHalf, MakeFacets(), G4GeomTools::PolygonArea(), and G4GeomTools::RemoveRedundantVertices().

Referenced by Clone().

◆ G4ExtrudedSolid() [2/4]

G4ExtrudedSolid::G4ExtrudedSolid ( const G4String pName,
const std::vector< G4TwoVector > &  polygon,
G4double  halfZ,
const G4TwoVector off1,
G4double  scale1,
const G4TwoVector off2,
G4double  scale2 
)

Definition at line 189 of file G4ExtrudedSolid.cc.

194 : G4TessellatedSolid(pName),
195 fNv(polygon.size()),
196 fNz(2),
197 fGeometryType("G4ExtrudedSolid")
198{
199 // Special constructor for solid with 2 z-sections
200
201 // First check input parameters
202 //
203 if (fNv < 3)
204 {
205 std::ostringstream message;
206 message << "Number of vertices in polygon < 3 - " << pName;
207 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
208 FatalErrorInArgument, message);
209 }
210
211 // Copy polygon
212 //
213 fPolygon = polygon;
214
215 // Remove collinear and coincident vertices, if any
216 //
217 std::vector<G4int> removedVertices;
219 2*kCarTolerance);
220 if (removedVertices.size() != 0)
221 {
222 G4int nremoved = removedVertices.size();
223 std::ostringstream message;
224 message << "The following "<< nremoved
225 << " vertices have been removed from polygon in " << pName
226 << "\nas collinear or coincident with other vertices: "
227 << removedVertices[0];
228 for (G4int i=1; i<nremoved; ++i) message << ", " << removedVertices[i];
229 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
230 JustWarning, message);
231 }
232
233 fNv = fPolygon.size();
234 if (fNv < 3)
235 {
236 std::ostringstream message;
237 message << "Number of vertices in polygon after removal < 3 - " << pName;
238 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
239 FatalErrorInArgument, message);
240 }
241
242 // Check if polygon vertices are defined clockwise
243 // (the area is positive if polygon vertices are defined anti-clockwise)
244 //
246 {
247 // Polygon vertices are defined anti-clockwise, we revert them
248 // G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
249 // JustWarning,
250 // "Polygon vertices defined anti-clockwise, reverting polygon");
251 std::reverse(fPolygon.begin(),fPolygon.end());
252 }
253
254 // Copy z-sections
255 //
256 fZSections.push_back(ZSection(-dz, off1, scale1));
257 fZSections.push_back(ZSection( dz, off2, scale2));
258
259 G4bool result = MakeFacets();
260 if (!result)
261 {
262 std::ostringstream message;
263 message << "Making facets failed - " << pName;
264 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0003",
265 FatalException, message);
266 }
268
270
271 // Check if the solid is a right prism, if so then set lateral planes
272 //
273 if ((scale1 == 1) && (scale2 == 1)
274 && (off1 == G4TwoVector(0,0)) && (off2 == G4TwoVector(0,0)))
275 {
276 fSolidType = (fIsConvex) ? 1 : 2; // 1 - convex, 2 - non-convex right prism
278 }
279}

References ComputeLateralPlanes(), ComputeProjectionParameters(), FatalErrorInArgument, FatalException, fIsConvex, fNv, fPolygon, fSolidType, fZSections, G4Exception(), G4GeomTools::IsConvex(), JustWarning, G4VSolid::kCarTolerance, MakeFacets(), G4GeomTools::PolygonArea(), and G4GeomTools::RemoveRedundantVertices().

◆ ~G4ExtrudedSolid()

G4ExtrudedSolid::~G4ExtrudedSolid ( )
virtual

Definition at line 333 of file G4ExtrudedSolid.cc.

334{
335 // Destructor
336}

◆ G4ExtrudedSolid() [3/4]

G4ExtrudedSolid::G4ExtrudedSolid ( __void__ &  a)

Definition at line 283 of file G4ExtrudedSolid.cc.

284 : G4TessellatedSolid(a), fNv(0), fNz(0),
285 fGeometryType("G4ExtrudedSolid")
286{
287 // Fake default constructor - sets only member data and allocates memory
288 // for usage restricted to object persistency.
289}

◆ G4ExtrudedSolid() [4/4]

G4ExtrudedSolid::G4ExtrudedSolid ( const G4ExtrudedSolid rhs)

Definition at line 293 of file G4ExtrudedSolid.cc.

294 : G4TessellatedSolid(rhs), fNv(rhs.fNv), fNz(rhs.fNz),
299 fLines(rhs.fLines), fLengths(rhs.fLengths),
302{
303}
std::vector< G4double > fKScales
std::vector< G4TwoVector > fOffset0s
std::vector< G4double > fLengths
std::vector< G4double > fScale0s
std::vector< G4TwoVector > fKOffsets
std::vector< plane > fPlanes
std::vector< line > fLines
std::vector< std::vector< G4int > > fTriangles

Member Function Documentation

◆ AddFacet()

G4bool G4TessellatedSolid::AddFacet ( G4VFacet aFacet)
inherited

Definition at line 208 of file G4TessellatedSolid.cc.

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

References G4TessellatedSolid::fFacetList, G4TessellatedSolid::fFacets, G4TessellatedSolid::fSolidClosed, G4cout, G4Exception(), G4VFacet::GetCircumcentre(), G4VertexInfo::id, G4VFacet::IsDefined(), JustWarning, G4VSolid::kCarTolerance, G4VertexInfo::mag2, G4TessellatedSolid::OutsideOfExtent(), pos, G4VFacet::StreamInfo(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by AddGeneralPolygonFacets(), G4TessellatedSolid::CopyObjects(), G4GenericTrap::CreateTessellatedSolid(), G4tgbVolume::FindOrConstructG4Solid(), MakeFacets(), G4TessellatedSolid::operator+=(), and G4GDMLReadSolids::TessellatedRead().

◆ AddGeneralPolygonFacets()

G4bool G4ExtrudedSolid::AddGeneralPolygonFacets ( )
private

Definition at line 637 of file G4ExtrudedSolid.cc.

638{
639 // Decompose polygonal sides in triangular facets
640
641 typedef std::pair < G4TwoVector, G4int > Vertex;
642
643 static const G4double kAngTolerance =
645
646 // Fill one more vector
647 //
648 std::vector< Vertex > verticesToBeDone;
649 for ( G4int i=0; i<fNv; ++i )
650 {
651 verticesToBeDone.push_back(Vertex(fPolygon[i], i));
652 }
653 std::vector< Vertex > ears;
654
655 std::vector< Vertex >::iterator c1 = verticesToBeDone.begin();
656 std::vector< Vertex >::iterator c2 = c1+1;
657 std::vector< Vertex >::iterator c3 = c1+2;
658 while ( verticesToBeDone.size()>2 ) // Loop checking, 13.08.2015, G.Cosmo
659 {
660
661 // G4cout << "Looking at triangle : "
662 // << c1->second << " " << c2->second
663 // << " " << c3->second << G4endl;
664 //G4cout << "Looking at triangle : "
665 // << c1->first << " " << c2->first
666 // << " " << c3->first << G4endl;
667
668 // skip concave vertices
669 //
670 G4double angle = GetAngle(c2->first, c3->first, c1->first);
671
672 //G4cout << "angle " << angle << G4endl;
673
674 G4int counter = 0;
675 while ( angle >= (pi-kAngTolerance) ) // Loop checking, 13.08.2015, G.Cosmo
676 {
677 // G4cout << "Skipping concave vertex " << c2->second << G4endl;
678
679 // try next three consecutive vertices
680 //
681 c1 = c2;
682 c2 = c3;
683 ++c3;
684 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
685
686 //G4cout << "Looking at triangle : "
687 // << c1->first << " " << c2->first
688 // << " " << c3->first << G4endl;
689
690 angle = GetAngle(c2->first, c3->first, c1->first);
691 //G4cout << "angle " << angle << G4endl;
692
693 ++counter;
694
695 if ( counter > fNv)
696 {
697 G4Exception("G4ExtrudedSolid::AddGeneralPolygonFacets",
698 "GeomSolids0003", FatalException,
699 "Triangularisation has failed.");
700 break;
701 }
702 }
703
704 G4bool good = true;
705 for ( auto it=verticesToBeDone.cbegin(); it!=verticesToBeDone.cend(); ++it )
706 {
707 // skip vertices of tested triangle
708 //
709 if ( it == c1 || it == c2 || it == c3 ) { continue; }
710
711 if ( IsPointInside(c1->first, c2->first, c3->first, it->first) )
712 {
713 // G4cout << "Point " << it->second << " is inside" << G4endl;
714 good = false;
715
716 // try next three consecutive vertices
717 //
718 c1 = c2;
719 c2 = c3;
720 ++c3;
721 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
722 break;
723 }
724 // else
725 // { G4cout << "Point " << it->second << " is outside" << G4endl; }
726 }
727 if ( good )
728 {
729 // all points are outside triangle, we can make a facet
730
731 // G4cout << "Found triangle : "
732 // << c1->second << " " << c2->second
733 // << " " << c3->second << G4endl;
734
735 G4bool result;
736 result = AddFacet( MakeDownFacet(c1->second, c2->second, c3->second) );
737 if ( ! result ) { return false; }
738
739 result = AddFacet( MakeUpFacet(c1->second, c2->second, c3->second) );
740 if ( ! result ) { return false; }
741
742 std::vector<G4int> triangle(3);
743 triangle[0] = c1->second;
744 triangle[1] = c2->second;
745 triangle[2] = c3->second;
746 fTriangles.push_back(triangle);
747
748 // remove the ear point from verticesToBeDone
749 //
750 verticesToBeDone.erase(c2);
751 c1 = verticesToBeDone.begin();
752 c2 = c1+1;
753 c3 = c1+2;
754 }
755 }
756 return true;
757}
static constexpr double pi
Definition: G4SIunits.hh:55
static const G4double angle[DIMMOTT]
G4double GetAngle(const G4TwoVector &p0, const G4TwoVector &pa, const G4TwoVector &pb) const
G4VFacet * MakeDownFacet(G4int ind1, G4int ind2, G4int ind3) const
G4VFacet * MakeUpFacet(G4int ind1, G4int ind2, G4int ind3) const
G4bool IsPointInside(const G4TwoVector &a, const G4TwoVector &b, const G4TwoVector &c, const G4TwoVector &p) const
static G4GeometryTolerance * GetInstance()
G4double GetAngularTolerance() const
G4bool AddFacet(G4VFacet *aFacet)

References G4TessellatedSolid::AddFacet(), angle, FatalException, fNv, fPolygon, fTriangles, G4Exception(), GetAngle(), G4GeometryTolerance::GetAngularTolerance(), G4GeometryTolerance::GetInstance(), IsPointInside(), MakeDownFacet(), MakeUpFacet(), and pi.

Referenced by MakeFacets().

◆ AllocatedMemory()

G4int G4TessellatedSolid::AllocatedMemory ( )
inherited

Definition at line 2248 of file G4TessellatedSolid.cc.

2249{
2251 G4int sizeInsides = fInsides.GetNbytes();
2252 G4int sizeVoxels = fVoxels.AllocatedMemory();
2253 size += sizeInsides + sizeVoxels;
2254 return size;
2255}
unsigned int GetNbytes() const
Definition: G4SurfBits.hh:93
G4int AllocatedMemory()

References G4Voxelizer::AllocatedMemory(), G4TessellatedSolid::AllocatedMemoryWithoutVoxels(), G4TessellatedSolid::fInsides, G4TessellatedSolid::fVoxels, and G4SurfBits::GetNbytes().

Referenced by G4TessellatedSolid::DisplayAllocatedMemory().

◆ AllocatedMemoryWithoutVoxels()

G4int G4TessellatedSolid::AllocatedMemoryWithoutVoxels ( )
inherited

Definition at line 2225 of file G4TessellatedSolid.cc.

2226{
2227 G4int base = sizeof(*this);
2228 base += fVertexList.capacity() * sizeof(G4ThreeVector);
2229 base += fRandir.capacity() * sizeof(G4ThreeVector);
2230
2231 G4int limit = fFacets.size();
2232 for (G4int i = 0; i < limit; ++i)
2233 {
2234 G4VFacet& facet = *fFacets[i];
2235 base += facet.AllocatedMemory();
2236 }
2237
2238 for (auto it = fExtremeFacets.cbegin(); it != fExtremeFacets.cend(); ++it)
2239 {
2240 G4VFacet &facet = *(*it);
2241 base += facet.AllocatedMemory();
2242 }
2243 return base;
2244}
CLHEP::Hep3Vector G4ThreeVector
std::vector< G4ThreeVector > fRandir
std::set< G4VFacet * > fExtremeFacets
std::vector< G4ThreeVector > fVertexList
virtual G4int AllocatedMemory()=0

References G4VFacet::AllocatedMemory(), G4TessellatedSolid::fExtremeFacets, G4TessellatedSolid::fFacets, G4TessellatedSolid::fRandir, and G4TessellatedSolid::fVertexList.

Referenced by G4TessellatedSolid::AllocatedMemory(), and G4TessellatedSolid::DisplayAllocatedMemory().

◆ ApproxSurfaceNormal()

G4ThreeVector G4ExtrudedSolid::ApproxSurfaceNormal ( const G4ThreeVector p) const
private

Definition at line 1070 of file G4ExtrudedSolid.cc.

1071{
1072 // This method is valid only for right prisms and
1073 // normally should not be called
1074
1075 if (fSolidType == 1 || fSolidType == 2)
1076 {
1077 // Find distances to z-planes
1078 //
1079 G4double dz0 = fZSections[0].fZ - p.z();
1080 G4double dz1 = p.z() - fZSections[1].fZ;
1081 G4double ddz0 = dz0*dz0;
1082 G4double ddz1 = dz1*dz1;
1083
1084 // Find nearest lateral side and distance to it
1085 //
1086 G4int iside = 0;
1087 G4double dd = DBL_MAX;
1088 for (G4int i=0, k=fNv-1; i<fNv; k=i++)
1089 {
1090 G4double ix = p.x() - fPolygon[i].x();
1091 G4double iy = p.y() - fPolygon[i].y();
1092 G4double u = fPlanes[i].a*iy - fPlanes[i].b*ix;
1093 if (u < 0)
1094 {
1095 G4double tmp = ix*ix + iy*iy;
1096 if (tmp < dd) { dd = tmp; iside = i; }
1097 }
1098 else if (u > fLengths[i])
1099 {
1100 G4double kx = p.x() - fPolygon[k].x();
1101 G4double ky = p.y() - fPolygon[k].y();
1102 G4double tmp = kx*kx + ky*ky;
1103 if (tmp < dd) { dd = tmp; iside = i; }
1104 }
1105 else
1106 {
1107 G4double tmp = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
1108 tmp *= tmp;
1109 if (tmp < dd) { dd = tmp; iside = i; }
1110 }
1111 }
1112
1113 // Find region
1114 //
1115 // 3 | 1 | 3
1116 // ----+-------+----
1117 // 2 | 0 | 2
1118 // ----+-------+----
1119 // 3 | 1 | 3
1120 //
1121 G4int iregion = 0;
1122 if (std::max(dz0,dz1) > 0) iregion = 1;
1123
1124 G4bool in = PointInPolygon(p);
1125 if (!in) iregion += 2;
1126
1127 // Return normal
1128 //
1129 switch (iregion)
1130 {
1131 case 0:
1132 {
1133 if (ddz0 <= ddz1 && ddz0 <= dd) return G4ThreeVector(0, 0,-1);
1134 if (ddz1 <= ddz0 && ddz1 <= dd) return G4ThreeVector(0, 0, 1);
1135 return G4ThreeVector(fPlanes[iside].a, fPlanes[iside].b, 0);
1136 }
1137 case 1:
1138 {
1139 return G4ThreeVector(0, 0, (dz0 > dz1) ? -1 : 1);
1140 }
1141 case 2:
1142 {
1143 return G4ThreeVector(fPlanes[iside].a, fPlanes[iside].b, 0);
1144 }
1145 case 3:
1146 {
1147 G4double dzmax = std::max(dz0,dz1);
1148 if (dzmax*dzmax > dd) return G4ThreeVector(0,0,(dz0 > dz1) ? -1 : 1);
1149 return G4ThreeVector(fPlanes[iside].a,fPlanes[iside].b, 0);
1150 }
1151 }
1152 }
1153 return G4ThreeVector(0,0,0);
1154}
G4bool PointInPolygon(const G4ThreeVector &p) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
#define DBL_MAX
Definition: templates.hh:62

References DBL_MAX, fLengths, fNv, fPlanes, fPolygon, fSolidType, fZSections, G4INCL::Math::max(), PointInPolygon(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by SurfaceNormal().

◆ BoundingLimits()

void G4ExtrudedSolid::BoundingLimits ( G4ThreeVector pMin,
G4ThreeVector pMax 
) const
virtual

Reimplemented from G4VSolid.

Definition at line 1371 of file G4ExtrudedSolid.cc.

1373{
1374 G4double xmin0 = kInfinity, xmax0 = -kInfinity;
1375 G4double ymin0 = kInfinity, ymax0 = -kInfinity;
1376
1377 for (G4int i=0; i<GetNofVertices(); ++i)
1378 {
1379 G4double x = fPolygon[i].x();
1380 if (x < xmin0) xmin0 = x;
1381 if (x > xmax0) xmax0 = x;
1382 G4double y = fPolygon[i].y();
1383 if (y < ymin0) ymin0 = y;
1384 if (y > ymax0) ymax0 = y;
1385 }
1386
1387 G4double xmin = kInfinity, xmax = -kInfinity;
1388 G4double ymin = kInfinity, ymax = -kInfinity;
1389
1390 G4int nsect = GetNofZSections();
1391 for (G4int i=0; i<nsect; ++i)
1392 {
1393 ZSection zsect = GetZSection(i);
1394 G4double dx = zsect.fOffset.x();
1395 G4double dy = zsect.fOffset.y();
1396 G4double scale = zsect.fScale;
1397 xmin = std::min(xmin,xmin0*scale+dx);
1398 xmax = std::max(xmax,xmax0*scale+dx);
1399 ymin = std::min(ymin,ymin0*scale+dy);
1400 ymax = std::max(ymax,ymax0*scale+dy);
1401 }
1402
1403 G4double zmin = GetZSection(0).fZ;
1404 G4double zmax = GetZSection(nsect-1).fZ;
1405
1406 pMin.set(xmin,ymin,zmin);
1407 pMax.set(xmax,ymax,zmax);
1408
1409 // Check correctness of the bounding box
1410 //
1411 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
1412 {
1413 std::ostringstream message;
1414 message << "Bad bounding box (min >= max) for solid: "
1415 << GetName() << " !"
1416 << "\npMin = " << pMin
1417 << "\npMax = " << pMax;
1418 G4Exception("G4ExtrudedSolid::BoundingLimits()",
1419 "GeomMgt0001", JustWarning, message);
1420 DumpInfo();
1421 }
1422}
static const G4double pMax
static const G4double pMin
ZSection GetZSection(G4int index) const
G4int GetNofZSections() const
G4int GetNofVertices() const
G4String GetName() const
void DumpInfo() const
static const G4double kInfinity
Definition: geomdefs.hh:41
T min(const T t1, const T t2)
brief Return the smallest of the two arguments

References G4VSolid::DumpInfo(), G4ExtrudedSolid::ZSection::fOffset, fPolygon, G4ExtrudedSolid::ZSection::fScale, G4ExtrudedSolid::ZSection::fZ, G4Exception(), G4VSolid::GetName(), GetNofVertices(), GetNofZSections(), GetZSection(), JustWarning, kInfinity, G4INCL::Math::max(), G4INCL::Math::min(), pMax, pMin, CLHEP::Hep2Vector::x(), and CLHEP::Hep2Vector::y().

Referenced by CalculateExtent().

◆ CalculateClippedPolygonExtent()

void G4VSolid::CalculateClippedPolygonExtent ( G4ThreeVectorList pPolygon,
const G4VoxelLimits pVoxelLimit,
const EAxis  pAxis,
G4double pMin,
G4double pMax 
) const
protectedinherited

Definition at line 489 of file G4VSolid.cc.

494{
495 G4int noLeft,i;
496 G4double component;
497
498 ClipPolygon(pPolygon,pVoxelLimit,pAxis);
499 noLeft = pPolygon.size();
500
501 if ( noLeft )
502 {
503 for (i=0; i<noLeft; ++i)
504 {
505 component = pPolygon[i].operator()(pAxis);
506
507 if (component < pMin)
508 {
509 pMin = component;
510 }
511 if (component > pMax)
512 {
513 pMax = component;
514 }
515 }
516 }
517}
void ClipPolygon(G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis) const
Definition: G4VSolid.cc:539

References G4VSolid::ClipPolygon(), pMax, and pMin.

Referenced by G4VSolid::ClipBetweenSections(), and G4VSolid::ClipCrossSection().

◆ CalculateExtent()

G4bool G4ExtrudedSolid::CalculateExtent ( const EAxis  pAxis,
const G4VoxelLimits pVoxelLimit,
const G4AffineTransform pTransform,
G4double pMin,
G4double pMax 
) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 1428 of file G4ExtrudedSolid.cc.

1432{
1433 G4ThreeVector bmin, bmax;
1434 G4bool exist;
1435
1436 // Check bounding box (bbox)
1437 //
1438 BoundingLimits(bmin,bmax);
1439 G4BoundingEnvelope bbox(bmin,bmax);
1440#ifdef G4BBOX_EXTENT
1441 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
1442#endif
1443 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
1444 {
1445 return exist = (pMin < pMax) ? true : false;
1446 }
1447
1448 // To find the extent, the base polygon is subdivided in triangles.
1449 // The extent is calculated as cumulative extent of the parts
1450 // formed by extrusion of the triangles
1451 //
1452 G4TwoVectorList triangles;
1453 G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
1454 G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
1455
1456 // triangulate the base polygon
1458 {
1459 std::ostringstream message;
1460 message << "Triangulation of the base polygon has failed for solid: "
1461 << GetName() << " !"
1462 << "\nExtent has been calculated using boundary box";
1463 G4Exception("G4ExtrudedSolid::CalculateExtent()",
1464 "GeomMgt1002",JustWarning,message);
1465 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
1466 }
1467
1468 // allocate vector lists
1469 G4int nsect = GetNofZSections();
1470 std::vector<const G4ThreeVectorList *> polygons;
1471 polygons.resize(nsect);
1472 for (G4int k=0; k<nsect; ++k) { polygons[k] = new G4ThreeVectorList(3); }
1473
1474 // main loop along triangles
1475 pMin = kInfinity;
1476 pMax = -kInfinity;
1477 G4int ntria = triangles.size()/3;
1478 for (G4int i=0; i<ntria; ++i)
1479 {
1480 G4int i3 = i*3;
1481 for (G4int k=0; k<nsect; ++k) // extrude triangle
1482 {
1483 ZSection zsect = GetZSection(k);
1484 G4double z = zsect.fZ;
1485 G4double dx = zsect.fOffset.x();
1486 G4double dy = zsect.fOffset.y();
1487 G4double scale = zsect.fScale;
1488
1489 G4ThreeVectorList* ptr = const_cast<G4ThreeVectorList*>(polygons[k]);
1490 G4ThreeVectorList::iterator iter = ptr->begin();
1491 G4double x0 = triangles[i3+0].x()*scale+dx;
1492 G4double y0 = triangles[i3+0].y()*scale+dy;
1493 iter->set(x0,y0,z);
1494 iter++;
1495 G4double x1 = triangles[i3+1].x()*scale+dx;
1496 G4double y1 = triangles[i3+1].y()*scale+dy;
1497 iter->set(x1,y1,z);
1498 iter++;
1499 G4double x2 = triangles[i3+2].x()*scale+dx;
1500 G4double y2 = triangles[i3+2].y()*scale+dy;
1501 iter->set(x2,y2,z);
1502 }
1503
1504 // set sub-envelope and adjust extent
1505 G4double emin,emax;
1506 G4BoundingEnvelope benv(polygons);
1507 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
1508 if (emin < pMin) pMin = emin;
1509 if (emax > pMax) pMax = emax;
1510 if (eminlim > pMin && emaxlim < pMax) break; // max possible extent
1511 }
1512 // free memory
1513 for (G4int k=0; k<nsect; ++k) { delete polygons[k]; polygons[k]=0;}
1514 return (pMin < pMax);
1515}
std::vector< G4ThreeVector > G4ThreeVectorList
static const G4double emax
std::vector< G4TwoVector > G4TwoVectorList
Definition: G4GeomTools.hh:42
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
static G4bool TriangulatePolygon(const G4TwoVectorList &polygon, G4TwoVectorList &result)
Definition: G4GeomTools.cc:193
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const

References G4BoundingEnvelope::BoundingBoxVsVoxelLimits(), BoundingLimits(), G4BoundingEnvelope::CalculateExtent(), emax, G4ExtrudedSolid::ZSection::fOffset, fPolygon, G4ExtrudedSolid::ZSection::fScale, G4ExtrudedSolid::ZSection::fZ, G4Exception(), G4VoxelLimits::GetMaxExtent(), G4VoxelLimits::GetMinExtent(), G4VSolid::GetName(), GetNofZSections(), GetZSection(), JustWarning, kInfinity, pMax, pMin, G4GeomTools::TriangulatePolygon(), CLHEP::Hep2Vector::x(), and CLHEP::Hep2Vector::y().

◆ CheckStructure()

G4int G4TessellatedSolid::CheckStructure ( ) const
inherited

Definition at line 677 of file G4TessellatedSolid.cc.

678{
679 G4int nedge = 0;
680 G4int nface = fFacets.size();
681
682 // Calculate volume
683 //
684 G4double volume = 0.;
685 for (G4int i = 0; i < nface; ++i)
686 {
687 G4VFacet& facet = *fFacets[i];
688 nedge += facet.GetNumberOfVertices();
689 volume += facet.GetArea()*(facet.GetVertex(0).dot(facet.GetSurfaceNormal()));
690 }
691 G4int ivolume = (volume <= 0.);
692
693 // Create sorted vector of edges
694 //
695 std::vector<int64_t> iedge(nedge);
696 G4int kk = 0;
697 for (G4int i = 0; i < nface; ++i)
698 {
699 G4VFacet& facet = *fFacets[i];
700 G4int nnode = facet.GetNumberOfVertices();
701 for (G4int k = 0; k < nnode; ++k)
702 {
703 int64_t i1 = facet.GetVertexIndex((k == 0) ? nnode - 1 : k - 1);
704 int64_t i2 = facet.GetVertexIndex(k);
705 int64_t inverse = (i2 > i1);
706 if (inverse) std::swap(i1, i2);
707 iedge[kk++] = i1*1000000000 + i2*2 + inverse;
708 }
709 }
710 std::sort(iedge.begin(), iedge.end());
711
712 // Check edges, correct structure should consist of paired edges
713 // with different orientation
714 //
715 G4int iorder = 0;
716 G4int ihole = 0;
717 G4int i = 0;
718 while (i < nedge - 1)
719 {
720 if (iedge[i + 1] - iedge[i] == 1) // paired edges with different orientation
721 {
722 i += 2;
723 }
724 else if (iedge[i + 1] == iedge[i]) // paired edges with the same orientation
725 {
726 iorder = 2;
727 i += 2;
728 }
729 else // unpaired edge
730 {
731 ihole = 4;
732 i++;
733 }
734 }
735 return ivolume + iorder + ihole;
736}
double dot(const Hep3Vector &) const
virtual G4ThreeVector GetSurfaceNormal() const =0
virtual G4ThreeVector GetVertex(G4int i) const =0
virtual G4double GetArea() const =0
virtual G4int GetNumberOfVertices() const =0
virtual G4int GetVertexIndex(G4int i) const =0

References CLHEP::Hep3Vector::dot(), G4TessellatedSolid::fFacets, G4VFacet::GetArea(), G4VFacet::GetNumberOfVertices(), G4VFacet::GetSurfaceNormal(), G4VFacet::GetVertex(), and G4VFacet::GetVertexIndex().

Referenced by G4TessellatedSolid::SetSolidClosed().

◆ ClipBetweenSections()

void G4VSolid::ClipBetweenSections ( G4ThreeVectorList pVertices,
const G4int  pSectionIndex,
const G4VoxelLimits pVoxelLimit,
const EAxis  pAxis,
G4double pMin,
G4double pMax 
) const
protectedinherited

Definition at line 444 of file G4VSolid.cc.

449{
450 G4ThreeVectorList polygon;
451 polygon.reserve(4);
452 polygon.push_back((*pVertices)[pSectionIndex]);
453 polygon.push_back((*pVertices)[pSectionIndex+4]);
454 polygon.push_back((*pVertices)[pSectionIndex+5]);
455 polygon.push_back((*pVertices)[pSectionIndex+1]);
456 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
457 polygon.clear();
458
459 polygon.push_back((*pVertices)[pSectionIndex+1]);
460 polygon.push_back((*pVertices)[pSectionIndex+5]);
461 polygon.push_back((*pVertices)[pSectionIndex+6]);
462 polygon.push_back((*pVertices)[pSectionIndex+2]);
463 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
464 polygon.clear();
465
466 polygon.push_back((*pVertices)[pSectionIndex+2]);
467 polygon.push_back((*pVertices)[pSectionIndex+6]);
468 polygon.push_back((*pVertices)[pSectionIndex+7]);
469 polygon.push_back((*pVertices)[pSectionIndex+3]);
470 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
471 polygon.clear();
472
473 polygon.push_back((*pVertices)[pSectionIndex+3]);
474 polygon.push_back((*pVertices)[pSectionIndex+7]);
475 polygon.push_back((*pVertices)[pSectionIndex+4]);
476 polygon.push_back((*pVertices)[pSectionIndex]);
477 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
478 return;
479}
void CalculateClippedPolygonExtent(G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
Definition: G4VSolid.cc:489

References G4VSolid::CalculateClippedPolygonExtent(), pMax, and pMin.

◆ ClipCrossSection()

void G4VSolid::ClipCrossSection ( G4ThreeVectorList pVertices,
const G4int  pSectionIndex,
const G4VoxelLimits pVoxelLimit,
const EAxis  pAxis,
G4double pMin,
G4double pMax 
) const
protectedinherited

Definition at line 414 of file G4VSolid.cc.

419{
420
421 G4ThreeVectorList polygon;
422 polygon.reserve(4);
423 polygon.push_back((*pVertices)[pSectionIndex]);
424 polygon.push_back((*pVertices)[pSectionIndex+1]);
425 polygon.push_back((*pVertices)[pSectionIndex+2]);
426 polygon.push_back((*pVertices)[pSectionIndex+3]);
427 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
428 return;
429}

References G4VSolid::CalculateClippedPolygonExtent(), pMax, and pMin.

◆ ClipPolygon()

void G4VSolid::ClipPolygon ( G4ThreeVectorList pPolygon,
const G4VoxelLimits pVoxelLimit,
const EAxis  pAxis 
) const
protectedinherited

Definition at line 539 of file G4VSolid.cc.

542{
543 G4ThreeVectorList outputPolygon;
544
545 if ( pVoxelLimit.IsLimited() )
546 {
547 if (pVoxelLimit.IsXLimited() ) // && pAxis != kXAxis)
548 {
549 G4VoxelLimits simpleLimit1;
550 simpleLimit1.AddLimit(kXAxis,pVoxelLimit.GetMinXExtent(),kInfinity);
551 ClipPolygonToSimpleLimits(pPolygon,outputPolygon,simpleLimit1);
552
553 pPolygon.clear();
554
555 if ( !outputPolygon.size() ) return;
556
557 G4VoxelLimits simpleLimit2;
558 simpleLimit2.AddLimit(kXAxis,-kInfinity,pVoxelLimit.GetMaxXExtent());
559 ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
560
561 if ( !pPolygon.size() ) return;
562 else outputPolygon.clear();
563 }
564 if ( pVoxelLimit.IsYLimited() ) // && pAxis != kYAxis)
565 {
566 G4VoxelLimits simpleLimit1;
567 simpleLimit1.AddLimit(kYAxis,pVoxelLimit.GetMinYExtent(),kInfinity);
568 ClipPolygonToSimpleLimits(pPolygon,outputPolygon,simpleLimit1);
569
570 // Must always clear pPolygon - for clip to simpleLimit2 and in case of
571 // early exit
572
573 pPolygon.clear();
574
575 if ( !outputPolygon.size() ) return;
576
577 G4VoxelLimits simpleLimit2;
578 simpleLimit2.AddLimit(kYAxis,-kInfinity,pVoxelLimit.GetMaxYExtent());
579 ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
580
581 if ( !pPolygon.size() ) return;
582 else outputPolygon.clear();
583 }
584 if ( pVoxelLimit.IsZLimited() ) // && pAxis != kZAxis)
585 {
586 G4VoxelLimits simpleLimit1;
587 simpleLimit1.AddLimit(kZAxis,pVoxelLimit.GetMinZExtent(),kInfinity);
588 ClipPolygonToSimpleLimits(pPolygon,outputPolygon,simpleLimit1);
589
590 // Must always clear pPolygon - for clip to simpleLimit2 and in case of
591 // early exit
592
593 pPolygon.clear();
594
595 if ( !outputPolygon.size() ) return;
596
597 G4VoxelLimits simpleLimit2;
598 simpleLimit2.AddLimit(kZAxis,-kInfinity,pVoxelLimit.GetMaxZExtent());
599 ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
600
601 // Return after final clip - no cleanup
602 }
603 }
604}
void ClipPolygonToSimpleLimits(G4ThreeVectorList &pPolygon, G4ThreeVectorList &outputPolygon, const G4VoxelLimits &pVoxelLimit) const
Definition: G4VSolid.cc:612
G4bool IsYLimited() const
G4double GetMinZExtent() const
void AddLimit(const EAxis pAxis, const G4double pMin, const G4double pMax)
G4bool IsXLimited() const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMinYExtent() const
G4double GetMinXExtent() const
G4bool IsZLimited() const
G4bool IsLimited() const
G4double GetMaxXExtent() const
@ kYAxis
Definition: geomdefs.hh:56
@ kXAxis
Definition: geomdefs.hh:55
@ kZAxis
Definition: geomdefs.hh:57

References G4VoxelLimits::AddLimit(), G4VSolid::ClipPolygonToSimpleLimits(), G4VoxelLimits::GetMaxXExtent(), G4VoxelLimits::GetMaxYExtent(), G4VoxelLimits::GetMaxZExtent(), G4VoxelLimits::GetMinXExtent(), G4VoxelLimits::GetMinYExtent(), G4VoxelLimits::GetMinZExtent(), G4VoxelLimits::IsLimited(), G4VoxelLimits::IsXLimited(), G4VoxelLimits::IsYLimited(), G4VoxelLimits::IsZLimited(), kInfinity, kXAxis, kYAxis, and kZAxis.

Referenced by G4VSolid::CalculateClippedPolygonExtent().

◆ ClipPolygonToSimpleLimits()

void G4VSolid::ClipPolygonToSimpleLimits ( G4ThreeVectorList pPolygon,
G4ThreeVectorList outputPolygon,
const G4VoxelLimits pVoxelLimit 
) const
privateinherited

Definition at line 612 of file G4VSolid.cc.

615{
616 G4int i;
617 G4int noVertices=pPolygon.size();
618 G4ThreeVector vEnd,vStart;
619
620 for (i = 0 ; i < noVertices ; ++i )
621 {
622 vStart = pPolygon[i];
623 if ( i == noVertices-1 ) vEnd = pPolygon[0];
624 else vEnd = pPolygon[i+1];
625
626 if ( pVoxelLimit.Inside(vStart) )
627 {
628 if (pVoxelLimit.Inside(vEnd))
629 {
630 // vStart and vEnd inside -> output end point
631 //
632 outputPolygon.push_back(vEnd);
633 }
634 else
635 {
636 // vStart inside, vEnd outside -> output crossing point
637 //
638 pVoxelLimit.ClipToLimits(vStart,vEnd);
639 outputPolygon.push_back(vEnd);
640 }
641 }
642 else
643 {
644 if (pVoxelLimit.Inside(vEnd))
645 {
646 // vStart outside, vEnd inside -> output inside section
647 //
648 pVoxelLimit.ClipToLimits(vStart,vEnd);
649 outputPolygon.push_back(vStart);
650 outputPolygon.push_back(vEnd);
651 }
652 else // Both point outside -> no output
653 {
654 // outputPolygon.push_back(vStart);
655 // outputPolygon.push_back(vEnd);
656 }
657 }
658 }
659}
G4bool ClipToLimits(G4ThreeVector &pStart, G4ThreeVector &pEnd) const
G4bool Inside(const G4ThreeVector &pVec) const

References G4VoxelLimits::ClipToLimits(), and G4VoxelLimits::Inside().

Referenced by G4VSolid::ClipPolygon().

◆ Clone()

G4VSolid * G4ExtrudedSolid::Clone ( ) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 850 of file G4ExtrudedSolid.cc.

851{
852 return new G4ExtrudedSolid(*this);
853}
G4ExtrudedSolid(const G4String &pName, const std::vector< G4TwoVector > &polygon, const std::vector< ZSection > &zsections)

References G4ExtrudedSolid().

◆ CompareSortedVoxel()

G4bool G4TessellatedSolid::CompareSortedVoxel ( const std::pair< G4int, G4double > &  l,
const std::pair< G4int, G4double > &  r 
)
staticprivateinherited

Definition at line 1585 of file G4TessellatedSolid.cc.

1587{
1588 return l.second < r.second;
1589}

Referenced by G4TessellatedSolid::MinDistanceFacet().

◆ ComputeDimensions()

void G4VSolid::ComputeDimensions ( G4VPVParameterisation p,
const G4int  n,
const G4VPhysicalVolume pRep 
)
virtualinherited

◆ ComputeLateralPlanes()

void G4ExtrudedSolid::ComputeLateralPlanes ( )
private

Definition at line 373 of file G4ExtrudedSolid.cc.

374{
375 // Compute lateral planes: a*x + b*y + c*z + d = 0
376 //
377 G4int Nv = fPolygon.size();
378 fPlanes.resize(Nv);
379 for (G4int i=0, k=Nv-1; i<Nv; k=i++)
380 {
381 G4TwoVector norm = (fPolygon[i] - fPolygon[k]).unit();
382 fPlanes[i].a = -norm.y();
383 fPlanes[i].b = norm.x();
384 fPlanes[i].c = 0;
385 fPlanes[i].d = norm.y()*fPolygon[i].x() - norm.x()*fPolygon[i].y();
386 }
387
388 // Compute edge equations: x = k*y + m
389 // and edge lengths
390 //
391 fLines.resize(Nv);
392 fLengths.resize(Nv);
393 for (G4int i=0, k=Nv-1; i<Nv; k=i++)
394 {
395 if (fPolygon[k].y() == fPolygon[i].y())
396 {
397 fLines[i].k = 0;
398 fLines[i].m = fPolygon[i].x();
399 }
400 else
401 {
402 G4double ctg = (fPolygon[k].x()-fPolygon[i].x())/(fPolygon[k].y()-fPolygon[i].y());
403 fLines[i].k = ctg;
404 fLines[i].m = fPolygon[i].x() - ctg*fPolygon[i].y();
405 }
406 fLengths[i] = (fPolygon[i] - fPolygon[k]).mag();
407 }
408}
double x() const
double y() const

References fLengths, fLines, fPlanes, fPolygon, CLHEP::Hep2Vector::x(), and CLHEP::Hep2Vector::y().

Referenced by G4ExtrudedSolid().

◆ ComputeProjectionParameters()

void G4ExtrudedSolid::ComputeProjectionParameters ( )
private

Definition at line 340 of file G4ExtrudedSolid.cc.

341{
342 // Compute parameters for point projections p(z)
343 // to the polygon scale & offset:
344 // scale(z) = k*z + scale0
345 // offset(z) = l*z + offset0
346 // p(z) = scale(z)*p0 + offset(z)
347 // p0 = (p(z) - offset(z))/scale(z);
348 //
349
350 for ( G4int iz=0; iz<fNz-1; ++iz)
351 {
352 G4double z1 = fZSections[iz].fZ;
353 G4double z2 = fZSections[iz+1].fZ;
354 G4double scale1 = fZSections[iz].fScale;
355 G4double scale2 = fZSections[iz+1].fScale;
356 G4TwoVector off1 = fZSections[iz].fOffset;
357 G4TwoVector off2 = fZSections[iz+1].fOffset;
358
359 G4double kscale = (scale2 - scale1)/(z2 - z1);
360 G4double scale0 = scale2 - kscale*(z2 - z1)/2.0;
361 G4TwoVector koff = (off2 - off1)/(z2 - z1);
362 G4TwoVector off0 = off2 - koff*(z2 - z1)/2.0;
363
364 fKScales.push_back(kscale);
365 fScale0s.push_back(scale0);
366 fKOffsets.push_back(koff);
367 fOffset0s.push_back(off0);
368 }
369}

References fKOffsets, fKScales, fNz, fOffset0s, fScale0s, and fZSections.

Referenced by G4ExtrudedSolid().

◆ CopyObjects()

void G4TessellatedSolid::CopyObjects ( const G4TessellatedSolid s)
privateinherited

Definition at line 185 of file G4TessellatedSolid.cc.

186{
187 G4ThreeVector reductionRatio;
188 G4int fmaxVoxels = fVoxels.GetMaxVoxels(reductionRatio);
189 if (fmaxVoxels < 0)
190 fVoxels.SetMaxVoxels(reductionRatio);
191 else
192 fVoxels.SetMaxVoxels(fmaxVoxels);
193
194 G4int n = ts.GetNumberOfFacets();
195 for (G4int i = 0; i < n; ++i)
196 {
197 G4VFacet *facetClone = (ts.GetFacet(i))->GetClone();
198 AddFacet(facetClone);
199 }
200 if (ts.GetSolidClosed()) SetSolidClosed(true);
201}
void SetSolidClosed(const G4bool t)
G4int GetMaxVoxels(G4ThreeVector &ratioOfReduction)
void SetMaxVoxels(G4int max)

References G4TessellatedSolid::AddFacet(), G4TessellatedSolid::fVoxels, G4Voxelizer::GetMaxVoxels(), CLHEP::detail::n, G4Voxelizer::SetMaxVoxels(), G4TessellatedSolid::SetSolidClosed(), and geant4_check_module_cycles::ts.

Referenced by G4TessellatedSolid::G4TessellatedSolid(), and G4TessellatedSolid::operator=().

◆ CreatePolyhedron()

G4Polyhedron * G4TessellatedSolid::CreatePolyhedron ( ) const
virtualinherited

Reimplemented from G4VSolid.

Definition at line 1928 of file G4TessellatedSolid.cc.

1929{
1930 G4int nVertices = fVertexList.size();
1931 G4int nFacets = fFacets.size();
1932 G4PolyhedronArbitrary* polyhedron =
1933 new G4PolyhedronArbitrary (nVertices, nFacets);
1934 for (auto v= fVertexList.cbegin(); v!=fVertexList.cend(); ++v)
1935 {
1936 polyhedron->AddVertex(*v);
1937 }
1938
1939 G4int size = fFacets.size();
1940 for (G4int i = 0; i < size; ++i)
1941 {
1942 G4VFacet* facet = fFacets[i];
1943 G4int v[4] = {0};
1944 G4int n = facet->GetNumberOfVertices();
1945 if (n > 4) n = 4;
1946 for (G4int j=0; j<n; ++j)
1947 {
1948 G4int k = facet->GetVertexIndex(j);
1949 v[j] = k+1;
1950 }
1951 polyhedron->AddFacet(v[0],v[1],v[2],v[3]);
1952 }
1953 polyhedron->SetReferences();
1954
1955 return (G4Polyhedron*) polyhedron;
1956}
void AddFacet(const G4int iv1, const G4int iv2, const G4int iv3, const G4int iv4=0)
void AddVertex(const G4ThreeVector &v)

References G4PolyhedronArbitrary::AddFacet(), G4PolyhedronArbitrary::AddVertex(), G4TessellatedSolid::fFacets, G4TessellatedSolid::fVertexList, G4VFacet::GetNumberOfVertices(), G4VFacet::GetVertexIndex(), CLHEP::detail::n, and G4PolyhedronArbitrary::SetReferences().

Referenced by G4GenericTrap::CreatePolyhedron(), and G4TessellatedSolid::GetPolyhedron().

◆ CreateVertexList()

void G4TessellatedSolid::CreateVertexList ( )
privateinherited

Definition at line 453 of file G4TessellatedSolid.cc.

454{
455 // The algorithm:
456 // we will have additional vertexListSorted, where all the items will be
457 // sorted by magnitude of vertice vector.
458 // New candidate for fVertexList - we will determine the position fo first
459 // item which would be within its magnitude - 0.5*kCarTolerance.
460 // We will go trough until we will reach > +0.5 kCarTolerance.
461 // Comparison (q-p).mag() < 0.5*kCarTolerance will be made.
462 // They can be just stored in std::vector, with custom insertion based
463 // on binary search.
464
465 set<G4VertexInfo,G4VertexComparator> vertexListSorted;
466 set<G4VertexInfo,G4VertexComparator>::iterator begin
467 = vertexListSorted.begin(), end = vertexListSorted.end(), pos, it;
469 G4VertexInfo value;
470
471 fVertexList.clear();
472 G4int size = fFacets.size();
473
474 G4double kCarTolerance24 = kCarTolerance * kCarTolerance / 4.0;
475 G4double kCarTolerance3 = 3 * kCarTolerance;
476 vector<G4int> newIndex(100);
477
478 for (G4int k = 0; k < size; ++k)
479 {
480 G4VFacet &facet = *fFacets[k];
481 G4int max = facet.GetNumberOfVertices();
482
483 for (G4int i = 0; i < max; ++i)
484 {
485 p = facet.GetVertex(i);
486 value.id = fVertexList.size();
487 value.mag2 = p.x() + p.y() + p.z();
488
489 G4bool found = false;
490 G4int id = 0;
492 {
493 pos = vertexListSorted.lower_bound(value);
494 it = pos;
495 while (it != end) // Loop checking, 13.08.2015, G.Cosmo
496 {
497 id = (*it).id;
499 G4double dif = (q-p).mag2();
500 found = (dif < kCarTolerance24);
501 if (found) break;
502 dif = q.x() + q.y() + q.z() - value.mag2;
503 if (dif > kCarTolerance3) break;
504 it++;
505 }
506
507 if (!found && (fVertexList.size() > 1))
508 {
509 it = pos;
510 while (it != begin) // Loop checking, 13.08.2015, G.Cosmo
511 {
512 --it;
513 id = (*it).id;
515 G4double dif = (q-p).mag2();
516 found = (dif < kCarTolerance24);
517 if (found) break;
518 dif = value.mag2 - (q.x() + q.y() + q.z());
519 if (dif > kCarTolerance3) break;
520 }
521 }
522 }
523
524 if (!found)
525 {
526#ifdef G4SPECSDEBUG
527 G4cout << p.x() << ":" << p.y() << ":" << p.z() << G4endl;
528 G4cout << "Adding new vertex #" << i << " of facet " << k
529 << " id " << value.id << G4endl;
530 G4cout << "===" << G4endl;
531#endif
532 fVertexList.push_back(p);
533 vertexListSorted.insert(value);
534 begin = vertexListSorted.begin();
535 end = vertexListSorted.end();
536 newIndex[i] = value.id;
537 //
538 // Now update the maximum x, y and z limits of the volume.
539 //
540 if (value.id == 0) fMinExtent = fMaxExtent = p;
541 else
542 {
543 if (p.x() > fMaxExtent.x()) fMaxExtent.setX(p.x());
544 else if (p.x() < fMinExtent.x()) fMinExtent.setX(p.x());
545 if (p.y() > fMaxExtent.y()) fMaxExtent.setY(p.y());
546 else if (p.y() < fMinExtent.y()) fMinExtent.setY(p.y());
547 if (p.z() > fMaxExtent.z()) fMaxExtent.setZ(p.z());
548 else if (p.z() < fMinExtent.z()) fMinExtent.setZ(p.z());
549 }
550 }
551 else
552 {
553#ifdef G4SPECSDEBUG
554 G4cout << p.x() << ":" << p.y() << ":" << p.z() << G4endl;
555 G4cout << "Vertex #" << i << " of facet " << k
556 << " found, redirecting to " << id << G4endl;
557 G4cout << "===" << G4endl;
558#endif
559 newIndex[i] = id;
560 }
561 }
562 // only now it is possible to change vertices pointer
563 //
564 facet.SetVertices(&fVertexList);
565 for (G4int i = 0; i < max; ++i)
566 facet.SetVertexIndex(i,newIndex[i]);
567 }
568 vector<G4ThreeVector>(fVertexList).swap(fVertexList);
569
570#ifdef G4SPECSDEBUG
571 G4double previousValue = 0.;
572 for (auto res=vertexListSorted.cbegin(); res!=vertexListSorted.cend(); ++res)
573 {
574 G4int id = (*res).id;
575 G4ThreeVector vec = fVertexList[id];
576 G4double mvalue = vec.x() + vec.y() + vec.z();
577 if (previousValue && (previousValue - 1e-9 > mvalue))
578 G4cout << "Error in CreateVertexList: previousValue " << previousValue
579 << " is smaller than mvalue " << mvalue << G4endl;
580 previousValue = mvalue;
581 }
582#endif
583}
void setY(double)
void setZ(double)
void setX(double)
virtual void SetVertexIndex(G4int i, G4int j)=0
virtual void SetVertices(std::vector< G4ThreeVector > *vertices)=0

References G4TessellatedSolid::fFacets, G4TessellatedSolid::fMaxExtent, G4TessellatedSolid::fMinExtent, G4TessellatedSolid::fVertexList, G4cout, G4endl, G4VFacet::GetNumberOfVertices(), G4VFacet::GetVertex(), G4VertexInfo::id, G4VSolid::kCarTolerance, G4VertexInfo::mag2, G4INCL::Math::max(), G4TessellatedSolid::OutsideOfExtent(), pos, G4VFacet::SetVertexIndex(), G4VFacet::SetVertices(), CLHEP::Hep3Vector::setX(), CLHEP::Hep3Vector::setY(), CLHEP::Hep3Vector::setZ(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by G4TessellatedSolid::SetSolidClosed().

◆ DeleteObjects()

void G4TessellatedSolid::DeleteObjects ( )
privateinherited

Definition at line 175 of file G4TessellatedSolid.cc.

176{
177 G4int size = fFacets.size();
178 for (G4int i = 0; i < size; ++i) { delete fFacets[i]; }
179 fFacets.clear();
180 delete fpPolyhedron; fpPolyhedron = nullptr;
181}
G4Polyhedron * fpPolyhedron

References G4TessellatedSolid::fFacets, and G4TessellatedSolid::fpPolyhedron.

Referenced by G4TessellatedSolid::operator=(), and G4TessellatedSolid::~G4TessellatedSolid().

◆ DescribeYourselfTo()

void G4TessellatedSolid::DescribeYourselfTo ( G4VGraphicsScene scene) const
virtualinherited

Implements G4VSolid.

Definition at line 1921 of file G4TessellatedSolid.cc.

1922{
1923 scene.AddSolid (*this);
1924}
virtual void AddSolid(const G4Box &)=0

References G4VGraphicsScene::AddSolid().

Referenced by G4GenericTrap::DescribeYourselfTo().

◆ DisplayAllocatedMemory()

void G4TessellatedSolid::DisplayAllocatedMemory ( )
inherited

Definition at line 587 of file G4TessellatedSolid.cc.

588{
590 G4int with = AllocatedMemory();
591 G4double ratio = (G4double) with / without;
592 G4cout << "G4TessellatedSolid - Allocated memory without voxel overhead "
593 << without << "; with " << with << "; ratio: " << ratio << G4endl;
594}

References G4TessellatedSolid::AllocatedMemory(), G4TessellatedSolid::AllocatedMemoryWithoutVoxels(), G4cout, and G4endl.

Referenced by G4TessellatedSolid::SetSolidClosed().

◆ DistanceToIn() [1/2]

G4double G4ExtrudedSolid::DistanceToIn ( const G4ThreeVector p) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 1219 of file G4ExtrudedSolid.cc.

1220{
1221 switch (fSolidType)
1222 {
1223 case 1: // convex right prism
1224 {
1225 G4double dist = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1226 G4int np = fPlanes.size();
1227 for (G4int i=0; i<np; ++i)
1228 {
1229 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
1230 if (dd > dist) dist = dd;
1231 }
1232 return (dist > 0) ? dist : 0.;
1233 }
1234 case 2: // non-convex right prism
1235 {
1236 G4bool in = PointInPolygon(p);
1237 if (in)
1238 {
1239 G4double distz= std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1240 return (distz > 0) ? distz : 0;
1241 }
1242 else
1243 {
1244 G4double distz= std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1246 if (distz > 0) dd += distz*distz;
1247 return std::sqrt(dd);
1248 }
1249 }
1250 }
1251
1252 // General case: use tessellated solid
1254}
G4double DistanceToPolygonSqr(const G4ThreeVector &p) const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const

References G4TessellatedSolid::DistanceToIn(), DistanceToPolygonSqr(), fPlanes, fSolidType, fZSections, G4INCL::Math::max(), PointInPolygon(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

◆ DistanceToIn() [2/2]

G4double G4ExtrudedSolid::DistanceToIn ( const G4ThreeVector p,
const G4ThreeVector v 
) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 1158 of file G4ExtrudedSolid.cc.

1160{
1161 G4double z0 = fZSections[0].fZ;
1162 G4double z1 = fZSections[fNz-1].fZ;
1163 if ((p.z() <= z0 + kCarToleranceHalf) && v.z() <= 0) return kInfinity;
1164 if ((p.z() >= z1 - kCarToleranceHalf) && v.z() >= 0) return kInfinity;
1165
1166 switch (fSolidType)
1167 {
1168 case 1: // convex right prism
1169 {
1170 // Intersection with Z planes
1171 //
1172 G4double dz = (z1 - z0)*0.5;
1173 G4double pz = p.z() - dz - z0;
1174
1175 G4double invz = (v.z() == 0) ? DBL_MAX : -1./v.z();
1176 G4double ddz = (invz < 0) ? dz : -dz;
1177 G4double tzmin = (pz + ddz)*invz;
1178 G4double tzmax = (pz - ddz)*invz;
1179
1180 // Intersection with lateral planes
1181 //
1182 G4int np = fPlanes.size();
1183 G4double txmin = tzmin, txmax = tzmax;
1184 for (G4int i=0; i<np; ++i)
1185 {
1186 G4double cosa = fPlanes[i].a*v.x()+fPlanes[i].b*v.y();
1187 G4double dist = fPlanes[i].a*p.x()+fPlanes[i].b*p.y()+fPlanes[i].d;
1188 if (dist >= -kCarToleranceHalf)
1189 {
1190 if (cosa >= 0) { return kInfinity; }
1191 G4double tmp = -dist/cosa;
1192 if (txmin < tmp) { txmin = tmp; }
1193 }
1194 else if (cosa > 0)
1195 {
1196 G4double tmp = -dist/cosa;
1197 if (txmax > tmp) { txmax = tmp; }
1198 }
1199 }
1200
1201 // Find distance
1202 //
1203 G4double tmin = txmin, tmax = txmax;
1204 if (tmax <= tmin + kCarToleranceHalf) // touch or no hit
1205 {
1206 return kInfinity;
1207 }
1208 return (tmin < kCarToleranceHalf) ? 0. : tmin;
1209 }
1210 case 2: // non-convex right prism
1211 {
1212 }
1213 }
1215}

References DBL_MAX, G4TessellatedSolid::DistanceToIn(), fNz, fPlanes, fSolidType, fZSections, G4TessellatedSolid::kCarToleranceHalf, kInfinity, CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), CLHEP::Hep3Vector::z(), and G4InuclParticleNames::z0.

◆ DistanceToInCandidates()

G4double G4TessellatedSolid::DistanceToInCandidates ( const std::vector< G4int > &  candidates,
const G4ThreeVector aPoint,
const G4ThreeVector aDirection 
) const
privateinherited

Definition at line 1482 of file G4TessellatedSolid.cc.

1486{
1487 G4int candidatesCount = candidates.size();
1488 G4double dist = 0.0;
1489 G4double distFromSurface = 0.0;
1491
1492 G4double minDistance = kInfinity;
1493 for (G4int i = 0 ; i < candidatesCount; ++i)
1494 {
1495 G4int candidate = candidates[i];
1496 G4VFacet& facet = *fFacets[candidate];
1497 if (facet.Intersect(aPoint,direction,false,dist,distFromSurface,normal))
1498 {
1499 //
1500 // Set minDist to the new distance to current facet if distFromSurface is
1501 // in positive direction and point is not at surface. If the point is
1502 // within 0.5*kCarTolerance of the surface, then force distance to be
1503 // zero and leave member function immediately (for efficiency), as
1504 // proposed by & credit to Akira Okumura.
1505 //
1506 if ( (distFromSurface > kCarToleranceHalf)
1507 && (dist >= 0.0) && (dist < minDistance))
1508 {
1509 minDistance = dist;
1510 }
1511 else
1512 {
1513 if (-kCarToleranceHalf <= dist && dist <= kCarToleranceHalf)
1514 {
1515 return 0.0;
1516 }
1517 else if (distFromSurface > -kCarToleranceHalf
1518 && distFromSurface < kCarToleranceHalf)
1519 {
1520 minDistance = dist;
1521 }
1522 }
1523 }
1524 }
1525 return minDistance;
1526}
virtual G4bool Intersect(const G4ThreeVector &, const G4ThreeVector &, const G4bool, G4double &, G4double &, G4ThreeVector &)=0
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:79

References G4TessellatedSolid::fFacets, G4VFacet::Intersect(), G4TessellatedSolid::kCarToleranceHalf, kInfinity, and CLHEP::normal().

Referenced by G4TessellatedSolid::DistanceToInCore().

◆ DistanceToInCore()

G4double G4TessellatedSolid::DistanceToInCore ( const G4ThreeVector p,
const G4ThreeVector v,
G4double  aPstep = kInfinity 
) const
privateinherited

Definition at line 1531 of file G4TessellatedSolid.cc.

1534{
1535 G4double minDistance;
1536
1537 if (fVoxels.GetCountOfVoxels() > 1)
1538 {
1539 minDistance = kInfinity;
1540 G4ThreeVector currentPoint = aPoint;
1541 G4ThreeVector direction = aDirection.unit();
1542 G4double shift = fVoxels.DistanceToFirst(currentPoint, direction);
1543 if (shift == kInfinity) return shift;
1544 G4double shiftBonus = kCarTolerance;
1545 if (shift)
1546 currentPoint += direction * (shift + shiftBonus);
1547 // if (!fVoxels.Contains(currentPoint)) return minDistance;
1548 G4double totalShift = shift;
1549
1550 // G4SurfBits exclusion; // (1/*fVoxels.GetBitsPerSlice()*/);
1551 vector<G4int> curVoxel(3);
1552
1553 fVoxels.GetVoxel(curVoxel, currentPoint);
1554 do // Loop checking, 13.08.2015, G.Cosmo
1555 {
1556 const vector<G4int>& candidates = fVoxels.GetCandidates(curVoxel);
1557 if (candidates.size())
1558 {
1559 G4double distance=DistanceToInCandidates(candidates, aPoint, direction);
1560 if (minDistance > distance) minDistance = distance;
1561 if (distance < totalShift) break;
1562 }
1563
1564 shift = fVoxels.DistanceToNext(currentPoint, direction, curVoxel);
1565 if (shift == kInfinity /*|| shift == 0*/) break;
1566
1567 totalShift += shift;
1568 if (minDistance < totalShift) break;
1569
1570 currentPoint += direction * (shift + shiftBonus);
1571 }
1572 while (fVoxels.UpdateCurrentVoxel(currentPoint, direction, curVoxel));
1573 }
1574 else
1575 {
1576 minDistance = DistanceToInNoVoxels(aPoint, aDirection, aPstep);
1577 }
1578
1579 return minDistance;
1580}
Hep3Vector unit() const
G4double DistanceToInNoVoxels(const G4ThreeVector &p, const G4ThreeVector &v, G4double aPstep=kInfinity) const
G4double DistanceToInCandidates(const std::vector< G4int > &candidates, const G4ThreeVector &aPoint, const G4ThreeVector &aDirection) const
long long GetCountOfVoxels() const
G4bool UpdateCurrentVoxel(const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
void GetVoxel(std::vector< G4int > &curVoxel, const G4ThreeVector &point) const
G4double DistanceToFirst(const G4ThreeVector &point, const G4ThreeVector &direction) const
G4double DistanceToNext(const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
const std::vector< G4int > & GetCandidates(std::vector< G4int > &curVoxel) const

References G4Voxelizer::DistanceToFirst(), G4TessellatedSolid::DistanceToInCandidates(), G4TessellatedSolid::DistanceToInNoVoxels(), G4Voxelizer::DistanceToNext(), G4TessellatedSolid::fVoxels, G4Voxelizer::GetCandidates(), G4Voxelizer::GetCountOfVoxels(), G4Voxelizer::GetVoxel(), G4VSolid::kCarTolerance, kInfinity, CLHEP::Hep3Vector::unit(), and G4Voxelizer::UpdateCurrentVoxel().

Referenced by G4TessellatedSolid::DistanceToIn().

◆ DistanceToInNoVoxels()

G4double G4TessellatedSolid::DistanceToInNoVoxels ( const G4ThreeVector p,
const G4ThreeVector v,
G4double  aPstep = kInfinity 
) const
privateinherited

Definition at line 1233 of file G4TessellatedSolid.cc.

1236{
1237 G4double minDist = kInfinity;
1238 G4double dist = 0.0;
1239 G4double distFromSurface = 0.0;
1241
1242#if G4SPECSDEBUG
1243 if (Inside(p) == kInside )
1244 {
1245 std::ostringstream message;
1246 G4int oldprc = message.precision(16) ;
1247 message << "Point p is already inside!?" << G4endl
1248 << "Position:" << G4endl << G4endl
1249 << " p.x() = " << p.x()/mm << " mm" << G4endl
1250 << " p.y() = " << p.y()/mm << " mm" << G4endl
1251 << " p.z() = " << p.z()/mm << " mm" << G4endl
1252 << "DistanceToOut(p) == " << DistanceToOut(p);
1253 message.precision(oldprc) ;
1254 G4Exception("G4TriangularFacet::DistanceToIn(p,v)",
1255 "GeomSolids1002", JustWarning, message);
1256 }
1257#endif
1258
1259 G4int size = fFacets.size();
1260 for (G4int i = 0; i < size; ++i)
1261 {
1262 G4VFacet& facet = *fFacets[i];
1263 if (facet.Intersect(p,v,false,dist,distFromSurface,normal))
1264 {
1265 //
1266 // set minDist to the new distance to current facet if distFromSurface
1267 // is in positive direction and point is not at surface. If the point is
1268 // within 0.5*kCarTolerance of the surface, then force distance to be
1269 // zero and leave member function immediately (for efficiency), as
1270 // proposed by & credit to Akira Okumura.
1271 //
1272 if (distFromSurface > kCarToleranceHalf && dist >= 0.0 && dist < minDist)
1273 {
1274 minDist = dist;
1275 }
1276 else
1277 {
1278 if (-kCarToleranceHalf <= dist && dist <= kCarToleranceHalf)
1279 {
1280 return 0.0;
1281 }
1282 else
1283 {
1284 if (distFromSurface > -kCarToleranceHalf
1285 && distFromSurface < kCarToleranceHalf)
1286 {
1287 minDist = dist;
1288 }
1289 }
1290 }
1291 }
1292 }
1293 return minDist;
1294}
static constexpr double mm
Definition: G4SIunits.hh:95
virtual G4double DistanceToOut(const G4ThreeVector &p) const
virtual EInside Inside(const G4ThreeVector &p) const
@ kInside
Definition: geomdefs.hh:70

References G4TessellatedSolid::DistanceToOut(), G4TessellatedSolid::fFacets, G4endl, G4Exception(), G4TessellatedSolid::Inside(), G4VFacet::Intersect(), JustWarning, G4TessellatedSolid::kCarToleranceHalf, kInfinity, kInside, mm, CLHEP::normal(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by G4TessellatedSolid::DistanceToInCore().

◆ DistanceToOut() [1/2]

G4double G4ExtrudedSolid::DistanceToOut ( const G4ThreeVector p) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 1340 of file G4ExtrudedSolid.cc.

1341{
1342 switch (fSolidType)
1343 {
1344 case 1: // convex right prism
1345 {
1346 G4double dist = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1347 G4int np = fPlanes.size();
1348 for (G4int i=0; i<np; ++i)
1349 {
1350 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
1351 if (dd > dist) dist = dd;
1352 }
1353 return (dist < 0) ? -dist : 0.;
1354 }
1355 case 2: // non-convex right prism
1356 {
1357 G4double distz = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1358 G4bool in = PointInPolygon(p);
1359 if (distz >= 0 || (!in)) return 0; // point is outside
1360 return std::min(-distz,std::sqrt(DistanceToPolygonSqr(p)));
1361 }
1362 }
1363
1364 // General case: use tessellated solid
1366}

References G4TessellatedSolid::DistanceToOut(), DistanceToPolygonSqr(), fPlanes, fSolidType, fZSections, G4INCL::Math::max(), G4INCL::Math::min(), PointInPolygon(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

◆ DistanceToOut() [2/2]

G4double G4ExtrudedSolid::DistanceToOut ( const G4ThreeVector p,
const G4ThreeVector v,
const G4bool  calcNorm = false,
G4bool validNorm = nullptr,
G4ThreeVector n = nullptr 
) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 1258 of file G4ExtrudedSolid.cc.

1263{
1264 G4bool getnorm = calcNorm;
1265 if (getnorm) *validNorm = true;
1266
1267 G4double z0 = fZSections[0].fZ;
1268 G4double z1 = fZSections[fNz-1].fZ;
1269 if ((p.z() <= z0 + kCarToleranceHalf) && v.z() < 0)
1270 {
1271 if (getnorm) n->set(0,0,-1);
1272 return 0;
1273 }
1274 if ((p.z() >= z1 - kCarToleranceHalf) && v.z() > 0)
1275 {
1276 if (getnorm) n->set(0,0,1);
1277 return 0;
1278 }
1279
1280 switch (fSolidType)
1281 {
1282 case 1: // convex right prism
1283 {
1284 // Intersection with Z planes
1285 //
1286 G4double dz = (z1 - z0)*0.5;
1287 G4double pz = p.z() - 0.5 * (z0 + z1);
1288
1289 G4double vz = v.z();
1290 G4double tmax = (vz == 0) ? DBL_MAX : (std::copysign(dz,vz) - pz)/vz;
1291 G4int iside = (vz < 0) ? -4 : -2; // little trick: (-4+3)=-1, (-2+3)=+1
1292
1293 // Intersection with lateral planes
1294 //
1295 G4int np = fPlanes.size();
1296 for (G4int i=0; i<np; ++i)
1297 {
1298 G4double cosa = fPlanes[i].a*v.x()+fPlanes[i].b*v.y();
1299 if (cosa > 0)
1300 {
1301 G4double dist = fPlanes[i].a*p.x()+fPlanes[i].b*p.y()+fPlanes[i].d;
1302 if (dist >= -kCarToleranceHalf)
1303 {
1304 if (getnorm) n->set(fPlanes[i].a, fPlanes[i].b, fPlanes[i].c);
1305 return 0;
1306 }
1307 G4double tmp = -dist/cosa;
1308 if (tmax > tmp) { tmax = tmp; iside = i; }
1309 }
1310 }
1311
1312 // Set normal, if required, and return distance
1313 //
1314 if (getnorm)
1315 {
1316 if (iside < 0)
1317 { n->set(0, 0, iside + 3); } // (-4+3)=-1, (-2+3)=+1
1318 else
1319 { n->set(fPlanes[iside].a, fPlanes[iside].b, fPlanes[iside].c); }
1320 }
1321 return tmax;
1322 }
1323 case 2: // non-convex right prism
1324 {
1325 }
1326 }
1327
1328 // Override the base class function to redefine validNorm
1329 // (the solid can be concave)
1330
1331 G4double distOut =
1332 G4TessellatedSolid::DistanceToOut(p, v, calcNorm, validNorm, n);
1333 if (validNorm) { *validNorm = fIsConvex; }
1334
1335 return distOut;
1336}

References DBL_MAX, G4TessellatedSolid::DistanceToOut(), fIsConvex, fNz, fPlanes, fSolidType, fZSections, G4TessellatedSolid::kCarToleranceHalf, CLHEP::detail::n, CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), CLHEP::Hep3Vector::z(), and G4InuclParticleNames::z0.

◆ DistanceToOutCandidates()

void G4TessellatedSolid::DistanceToOutCandidates ( const std::vector< G4int > &  candidates,
const G4ThreeVector aPoint,
const G4ThreeVector direction,
G4double minDist,
G4ThreeVector minNormal,
G4int minCandidate 
) const
privateinherited

Definition at line 1369 of file G4TessellatedSolid.cc.

1375{
1376 G4int candidatesCount = candidates.size();
1377 G4double dist = 0.0;
1378 G4double distFromSurface = 0.0;
1380
1381 for (G4int i = 0 ; i < candidatesCount; ++i)
1382 {
1383 G4int candidate = candidates[i];
1384 G4VFacet& facet = *fFacets[candidate];
1385 if (facet.Intersect(aPoint,direction,true,dist,distFromSurface,normal))
1386 {
1387 if (distFromSurface > 0.0 && distFromSurface <= kCarToleranceHalf
1388 && facet.Distance(aPoint,kCarTolerance) <= kCarToleranceHalf)
1389 {
1390 // We are on a surface
1391 //
1392 minDist = 0.0;
1393 minNormal = normal;
1394 minCandidate = candidate;
1395 break;
1396 }
1397 if (dist >= 0.0 && dist < minDist)
1398 {
1399 minDist = dist;
1400 minNormal = normal;
1401 minCandidate = candidate;
1402 }
1403 }
1404 }
1405}
virtual G4double Distance(const G4ThreeVector &, G4double)=0

References G4VFacet::Distance(), G4TessellatedSolid::fFacets, G4VFacet::Intersect(), G4VSolid::kCarTolerance, G4TessellatedSolid::kCarToleranceHalf, and CLHEP::normal().

Referenced by G4TessellatedSolid::DistanceToOutCore().

◆ DistanceToOutCore()

G4double G4TessellatedSolid::DistanceToOutCore ( const G4ThreeVector p,
const G4ThreeVector v,
G4ThreeVector aNormalVector,
G4bool aConvex,
G4double  aPstep = kInfinity 
) const
privateinherited

Definition at line 1410 of file G4TessellatedSolid.cc.

1415{
1416 G4double minDistance;
1417
1418 if (fVoxels.GetCountOfVoxels() > 1)
1419 {
1420 minDistance = kInfinity;
1421
1422 G4ThreeVector currentPoint = aPoint;
1423 G4ThreeVector direction = aDirection.unit();
1424 G4double totalShift = 0.;
1425 vector<G4int> curVoxel(3);
1426 if (!fVoxels.Contains(aPoint)) return 0.;
1427
1428 fVoxels.GetVoxel(curVoxel, currentPoint);
1429
1430 G4double shiftBonus = kCarTolerance;
1431
1432 const vector<G4int>* old = nullptr;
1433
1434 G4int minCandidate = -1;
1435 do // Loop checking, 13.08.2015, G.Cosmo
1436 {
1437 const vector<G4int>& candidates = fVoxels.GetCandidates(curVoxel);
1438 if (old == &candidates)
1439 ++old;
1440 if (old != &candidates && candidates.size())
1441 {
1442 DistanceToOutCandidates(candidates, aPoint, direction, minDistance,
1443 aNormalVector, minCandidate);
1444 if (minDistance <= totalShift) break;
1445 }
1446
1447 G4double shift=fVoxels.DistanceToNext(currentPoint, direction, curVoxel);
1448 if (shift == kInfinity) break;
1449
1450 totalShift += shift;
1451 if (minDistance <= totalShift) break;
1452
1453 currentPoint += direction * (shift + shiftBonus);
1454
1455 old = &candidates;
1456 }
1457 while (fVoxels.UpdateCurrentVoxel(currentPoint, direction, curVoxel));
1458
1459 if (minCandidate < 0)
1460 {
1461 // No intersection found
1462 minDistance = 0.;
1463 aConvex = false;
1464 Normal(aPoint, aNormalVector);
1465 }
1466 else
1467 {
1468 aConvex = (fExtremeFacets.find(fFacets[minCandidate])
1469 != fExtremeFacets.end());
1470 }
1471 }
1472 else
1473 {
1474 minDistance = DistanceToOutNoVoxels(aPoint, aDirection, aNormalVector,
1475 aConvex, aPstep);
1476 }
1477 return minDistance;
1478}
virtual G4bool Normal(const G4ThreeVector &p, G4ThreeVector &n) const
G4double DistanceToOutNoVoxels(const G4ThreeVector &p, const G4ThreeVector &v, G4ThreeVector &aNormalVector, G4bool &aConvex, G4double aPstep=kInfinity) const
void DistanceToOutCandidates(const std::vector< G4int > &candidates, const G4ThreeVector &aPoint, const G4ThreeVector &direction, G4double &minDist, G4ThreeVector &minNormal, G4int &minCandidate) const
G4bool Contains(const G4ThreeVector &point) const

References G4Voxelizer::Contains(), G4Voxelizer::DistanceToNext(), G4TessellatedSolid::DistanceToOutCandidates(), G4TessellatedSolid::DistanceToOutNoVoxels(), G4TessellatedSolid::fExtremeFacets, G4TessellatedSolid::fFacets, G4TessellatedSolid::fVoxels, G4Voxelizer::GetCandidates(), G4Voxelizer::GetCountOfVoxels(), G4Voxelizer::GetVoxel(), G4VSolid::kCarTolerance, kInfinity, G4TessellatedSolid::Normal(), CLHEP::Hep3Vector::unit(), and G4Voxelizer::UpdateCurrentVoxel().

Referenced by G4TessellatedSolid::DistanceToOut().

◆ DistanceToOutNoVoxels()

G4double G4TessellatedSolid::DistanceToOutNoVoxels ( const G4ThreeVector p,
const G4ThreeVector v,
G4ThreeVector aNormalVector,
G4bool aConvex,
G4double  aPstep = kInfinity 
) const
privateinherited

Definition at line 1299 of file G4TessellatedSolid.cc.

1304{
1305 G4double minDist = kInfinity;
1306 G4double dist = 0.0;
1307 G4double distFromSurface = 0.0;
1308 G4ThreeVector normal, minNormal;
1309
1310#if G4SPECSDEBUG
1311 if ( Inside(p) == kOutside )
1312 {
1313 std::ostringstream message;
1314 G4int oldprc = message.precision(16) ;
1315 message << "Point p is already outside!?" << G4endl
1316 << "Position:" << G4endl << G4endl
1317 << " p.x() = " << p.x()/mm << " mm" << G4endl
1318 << " p.y() = " << p.y()/mm << " mm" << G4endl
1319 << " p.z() = " << p.z()/mm << " mm" << G4endl
1320 << "DistanceToIn(p) == " << DistanceToIn(p);
1321 message.precision(oldprc) ;
1322 G4Exception("G4TriangularFacet::DistanceToOut(p)",
1323 "GeomSolids1002", JustWarning, message);
1324 }
1325#endif
1326
1327 G4bool isExtreme = false;
1328 G4int size = fFacets.size();
1329 for (G4int i = 0; i < size; ++i)
1330 {
1331 G4VFacet& facet = *fFacets[i];
1332 if (facet.Intersect(p,v,true,dist,distFromSurface,normal))
1333 {
1334 if (distFromSurface > 0.0 && distFromSurface <= kCarToleranceHalf
1336 {
1337 // We are on a surface. Return zero.
1338 aConvex = (fExtremeFacets.find(&facet) != fExtremeFacets.end());
1339 // Normal(p, aNormalVector);
1340 // aNormalVector = facet.GetSurfaceNormal();
1341 aNormalVector = normal;
1342 return 0.0;
1343 }
1344 if (dist >= 0.0 && dist < minDist)
1345 {
1346 minDist = dist;
1347 minNormal = normal;
1348 isExtreme = (fExtremeFacets.find(&facet) != fExtremeFacets.end());
1349 }
1350 }
1351 }
1352 if (minDist < kInfinity)
1353 {
1354 aNormalVector = minNormal;
1355 aConvex = isExtreme;
1356 return minDist;
1357 }
1358 else
1359 {
1360 // No intersection found
1361 aConvex = false;
1362 Normal(p, aNormalVector);
1363 return 0.0;
1364 }
1365}
@ kOutside
Definition: geomdefs.hh:68

References G4VFacet::Distance(), G4TessellatedSolid::DistanceToIn(), G4TessellatedSolid::fExtremeFacets, G4TessellatedSolid::fFacets, G4endl, G4Exception(), G4TessellatedSolid::Inside(), G4VFacet::Intersect(), JustWarning, G4VSolid::kCarTolerance, G4TessellatedSolid::kCarToleranceHalf, kInfinity, kOutside, mm, G4TessellatedSolid::Normal(), CLHEP::normal(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by G4TessellatedSolid::DistanceToOutCore().

◆ DistanceToPolygonSqr()

G4double G4ExtrudedSolid::DistanceToPolygonSqr ( const G4ThreeVector p) const
inlineprivate

Referenced by DistanceToIn(), DistanceToOut(), and Inside().

◆ DumpInfo()

void G4VSolid::DumpInfo ( ) const
inlineinherited

Referenced by G4Cons::ApproxSurfaceNormal(), G4CutTubs::ApproxSurfaceNormal(), G4Sphere::ApproxSurfaceNormal(), G4Torus::ApproxSurfaceNormal(), G4Tubs::ApproxSurfaceNormal(), G4ReflectedSolid::BoundingLimits(), G4DisplacedSolid::BoundingLimits(), G4IntersectionSolid::BoundingLimits(), G4ScaledSolid::BoundingLimits(), G4SubtractionSolid::BoundingLimits(), G4UnionSolid::BoundingLimits(), G4Box::BoundingLimits(), G4Cons::BoundingLimits(), G4CutTubs::BoundingLimits(), G4Orb::BoundingLimits(), G4Para::BoundingLimits(), G4Sphere::BoundingLimits(), G4Torus::BoundingLimits(), G4Trap::BoundingLimits(), G4Trd::BoundingLimits(), G4Tubs::BoundingLimits(), G4EllipticalCone::BoundingLimits(), BoundingLimits(), G4GenericPolycone::BoundingLimits(), G4GenericTrap::BoundingLimits(), G4Hype::BoundingLimits(), G4Paraboloid::BoundingLimits(), G4Polycone::BoundingLimits(), G4Polyhedra::BoundingLimits(), G4TessellatedSolid::BoundingLimits(), G4TwistedTubs::BoundingLimits(), G4ParameterisationBoxX::ComputeDimensions(), G4ParameterisationBoxY::ComputeDimensions(), G4ParameterisationBoxZ::ComputeDimensions(), G4ParameterisationConsRho::ComputeDimensions(), G4ParameterisationConsPhi::ComputeDimensions(), G4ParameterisationConsZ::ComputeDimensions(), G4ParameterisationParaX::ComputeDimensions(), G4ParameterisationParaY::ComputeDimensions(), G4ParameterisationParaZ::ComputeDimensions(), G4ParameterisationPolyconeRho::ComputeDimensions(), G4ParameterisationPolyconePhi::ComputeDimensions(), G4ParameterisationPolyconeZ::ComputeDimensions(), G4ParameterisationPolyhedraRho::ComputeDimensions(), G4ParameterisationPolyhedraPhi::ComputeDimensions(), G4ParameterisationPolyhedraZ::ComputeDimensions(), G4ParameterisationTrdX::ComputeDimensions(), G4ParameterisationTrdY::ComputeDimensions(), G4ParameterisationTrdZ::ComputeDimensions(), G4ParameterisationTubsRho::ComputeDimensions(), G4ParameterisationTubsPhi::ComputeDimensions(), G4ParameterisationTubsZ::ComputeDimensions(), G4ReflectedSolid::ComputeDimensions(), G4DisplacedSolid::ComputeDimensions(), G4ScaledSolid::ComputeDimensions(), G4ParameterisedNavigation::ComputeStep(), G4ReplicaNavigation::ComputeStep(), G4DisplacedSolid::CreatePolyhedron(), G4ScaledSolid::CreatePolyhedron(), G4SubtractionSolid::DistanceToIn(), G4Box::DistanceToOut(), G4Orb::DistanceToOut(), G4Para::DistanceToOut(), G4Trap::DistanceToOut(), G4Trd::DistanceToOut(), G4Paraboloid::DistanceToOut(), G4VTwistedFaceted::DistanceToOut(), G4Cons::DistanceToOut(), G4CutTubs::DistanceToOut(), G4Sphere::DistanceToOut(), G4Torus::DistanceToOut(), G4Tubs::DistanceToOut(), G4Ellipsoid::DistanceToOut(), G4EllipticalCone::DistanceToOut(), G4EllipticalTube::DistanceToOut(), G4GenericTrap::DistanceToOut(), export_G4VSolid(), G4Polycone::G4Polycone(), G4Polyhedra::G4Polyhedra(), G4BooleanSolid::GetConstituentSolid(), G4NavigationLogger::PostComputeStepLog(), G4Box::SurfaceNormal(), G4Para::SurfaceNormal(), G4Trap::SurfaceNormal(), G4Trd::SurfaceNormal(), G4Ellipsoid::SurfaceNormal(), G4EllipticalCone::SurfaceNormal(), G4EllipticalTube::SurfaceNormal(), SurfaceNormal(), and G4Tet::SurfaceNormal().

◆ EstimateCubicVolume()

G4double G4VSolid::EstimateCubicVolume ( G4int  nStat,
G4double  epsilon 
) const
inherited

Definition at line 203 of file G4VSolid.cc.

204{
205 G4int iInside=0;
206 G4double px,py,pz,minX,maxX,minY,maxY,minZ,maxZ,volume,halfepsilon;
208 EInside in;
209
210 // values needed for CalculateExtent signature
211
212 G4VoxelLimits limit; // Unlimited
213 G4AffineTransform origin;
214
215 // min max extents of pSolid along X,Y,Z
216
217 CalculateExtent(kXAxis,limit,origin,minX,maxX);
218 CalculateExtent(kYAxis,limit,origin,minY,maxY);
219 CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
220
221 // limits
222
223 if(nStat < 100) nStat = 100;
224 if(epsilon > 0.01) epsilon = 0.01;
225 halfepsilon = 0.5*epsilon;
226
227 for(auto i = 0; i < nStat; ++i )
228 {
229 px = minX-halfepsilon+(maxX-minX+epsilon)*G4QuickRand();
230 py = minY-halfepsilon+(maxY-minY+epsilon)*G4QuickRand();
231 pz = minZ-halfepsilon+(maxZ-minZ+epsilon)*G4QuickRand();
232 p = G4ThreeVector(px,py,pz);
233 in = Inside(p);
234 if(in != kOutside) ++iInside;
235 }
236 volume = (maxX-minX+epsilon)*(maxY-minY+epsilon)
237 * (maxZ-minZ+epsilon)*iInside/nStat;
238 return volume;
239}
G4double epsilon(G4double density, G4double temperature)
static const G4int maxZ
G4double G4QuickRand()
Definition: G4QuickRand.hh:34
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
virtual EInside Inside(const G4ThreeVector &p) const =0
EInside
Definition: geomdefs.hh:67

References G4VSolid::CalculateExtent(), epsilon(), G4QuickRand(), G4VSolid::Inside(), kOutside, kXAxis, kYAxis, kZAxis, and maxZ.

Referenced by G4VSolid::GetCubicVolume(), G4BooleanSolid::GetCubicVolume(), and G4VCSGfaceted::GetCubicVolume().

◆ EstimateSurfaceArea()

G4double G4VSolid::EstimateSurfaceArea ( G4int  nStat,
G4double  ell 
) const
inherited

Definition at line 265 of file G4VSolid.cc.

266{
267 static const G4double s2 = 1./std::sqrt(2.);
268 static const G4double s3 = 1./std::sqrt(3.);
269 static const G4ThreeVector directions[64] =
270 {
271 G4ThreeVector( 0, 0, 0), G4ThreeVector( -1, 0, 0), // ( , , ) ( -, , )
272 G4ThreeVector( 1, 0, 0), G4ThreeVector( -1, 0, 0), // ( +, , ) (-+, , )
273 G4ThreeVector( 0, -1, 0), G4ThreeVector(-s2,-s2, 0), // ( , -, ) ( -, -, )
274 G4ThreeVector( s2, -s2, 0), G4ThreeVector( 0, -1, 0), // ( +, -, ) (-+, -, )
275
276 G4ThreeVector( 0, 1, 0), G4ThreeVector( -s2, s2, 0), // ( , +, ) ( -, +, )
277 G4ThreeVector( s2, s2, 0), G4ThreeVector( 0, 1, 0), // ( +, +, ) (-+, +, )
278 G4ThreeVector( 0, -1, 0), G4ThreeVector( -1, 0, 0), // ( ,-+, ) ( -,-+, )
279 G4ThreeVector( 1, 0, 0), G4ThreeVector( -1, 0, 0), // ( +,-+, ) (-+,-+, )
280
281 G4ThreeVector( 0, 0, -1), G4ThreeVector(-s2, 0,-s2), // ( , , -) ( -, , -)
282 G4ThreeVector( s2, 0,-s2), G4ThreeVector( 0, 0, -1), // ( +, , -) (-+, , -)
283 G4ThreeVector( 0,-s2,-s2), G4ThreeVector(-s3,-s3,-s3), // ( , -, -) ( -, -, -)
284 G4ThreeVector( s3,-s3,-s3), G4ThreeVector( 0,-s2,-s2), // ( +, -, -) (-+, -, -)
285
286 G4ThreeVector( 0, s2,-s2), G4ThreeVector(-s3, s3,-s3), // ( , +, -) ( -, +, -)
287 G4ThreeVector( s3, s3,-s3), G4ThreeVector( 0, s2,-s2), // ( +, +, -) (-+, +, -)
288 G4ThreeVector( 0, 0, -1), G4ThreeVector(-s2, 0,-s2), // ( ,-+, -) ( -,-+, -)
289 G4ThreeVector( s2, 0,-s2), G4ThreeVector( 0, 0, -1), // ( +,-+, -) (-+,-+, -)
290
291 G4ThreeVector( 0, 0, 1), G4ThreeVector(-s2, 0, s2), // ( , , +) ( -, , +)
292 G4ThreeVector( s2, 0, s2), G4ThreeVector( 0, 0, 1), // ( +, , +) (-+, , +)
293 G4ThreeVector( 0,-s2, s2), G4ThreeVector(-s3,-s3, s3), // ( , -, +) ( -, -, +)
294 G4ThreeVector( s3,-s3, s3), G4ThreeVector( 0,-s2, s2), // ( +, -, +) (-+, -, +)
295
296 G4ThreeVector( 0, s2, s2), G4ThreeVector(-s3, s3, s3), // ( , +, +) ( -, +, +)
297 G4ThreeVector( s3, s3, s3), G4ThreeVector( 0, s2, s2), // ( +, +, +) (-+, +, +)
298 G4ThreeVector( 0, 0, 1), G4ThreeVector(-s2, 0, s2), // ( ,-+, +) ( -,-+, +)
299 G4ThreeVector( s2, 0, s2), G4ThreeVector( 0, 0, 1), // ( +,-+, +) (-+,-+, +)
300
301 G4ThreeVector( 0, 0, -1), G4ThreeVector( -1, 0, 0), // ( , ,-+) ( -, ,-+)
302 G4ThreeVector( 1, 0, 0), G4ThreeVector( -1, 0, 0), // ( +, ,-+) (-+, ,-+)
303 G4ThreeVector( 0, -1, 0), G4ThreeVector(-s2,-s2, 0), // ( , -,-+) ( -, -,-+)
304 G4ThreeVector( s2, -s2, 0), G4ThreeVector( 0, -1, 0), // ( +, -,-+) (-+, -,-+)
305
306 G4ThreeVector( 0, 1, 0), G4ThreeVector( -s2, s2, 0), // ( , +,-+) ( -, +,-+)
307 G4ThreeVector( s2, s2, 0), G4ThreeVector( 0, 1, 0), // ( +, +,-+) (-+, +,-+)
308 G4ThreeVector( 0, -1, 0), G4ThreeVector( -1, 0, 0), // ( ,-+,-+) ( -,-+,-+)
309 G4ThreeVector( 1, 0, 0), G4ThreeVector( -1, 0, 0), // ( +,-+,-+) (-+,-+,-+)
310 };
311
312 G4ThreeVector bmin, bmax;
313 BoundingLimits(bmin, bmax);
314
315 G4double dX = bmax.x() - bmin.x();
316 G4double dY = bmax.y() - bmin.y();
317 G4double dZ = bmax.z() - bmin.z();
318
319 // Define statistics and shell thickness
320 //
321 G4int npoints = (nstat < 1000) ? 1000 : nstat;
322 G4double coeff = 0.5 / std::cbrt(G4double(npoints));
323 G4double eps = (ell > 0) ? ell : coeff * std::min(std::min(dX, dY), dZ);
324 G4double del = 1.8 * eps; // shold be more than sqrt(3.)
325
326 G4double minX = bmin.x() - eps;
327 G4double minY = bmin.y() - eps;
328 G4double minZ = bmin.z() - eps;
329
330 G4double dd = 2. * eps;
331 dX += dd;
332 dY += dd;
333 dZ += dd;
334
335 // Calculate surface area
336 //
337 G4int icount = 0;
338 for(auto i = 0; i < npoints; ++i)
339 {
340 G4double px = minX + dX*G4QuickRand();
341 G4double py = minY + dY*G4QuickRand();
342 G4double pz = minZ + dZ*G4QuickRand();
343 G4ThreeVector p = G4ThreeVector(px, py, pz);
344 EInside in = Inside(p);
345 G4double dist = 0;
346 if (in == kInside)
347 {
348 if (DistanceToOut(p) >= eps) continue;
349 G4int icase = 0;
350 if (Inside(G4ThreeVector(px-del, py, pz)) != kInside) icase += 1;
351 if (Inside(G4ThreeVector(px+del, py, pz)) != kInside) icase += 2;
352 if (Inside(G4ThreeVector(px, py-del, pz)) != kInside) icase += 4;
353 if (Inside(G4ThreeVector(px, py+del, pz)) != kInside) icase += 8;
354 if (Inside(G4ThreeVector(px, py, pz-del)) != kInside) icase += 16;
355 if (Inside(G4ThreeVector(px, py, pz+del)) != kInside) icase += 32;
356 if (icase == 0) continue;
357 G4ThreeVector v = directions[icase];
358 dist = DistanceToOut(p, v);
359 G4ThreeVector n = SurfaceNormal(p + v*dist);
360 dist *= v.dot(n);
361 }
362 else if (in == kOutside)
363 {
364 if (DistanceToIn(p) >= eps) continue;
365 G4int icase = 0;
366 if (Inside(G4ThreeVector(px-del, py, pz)) != kOutside) icase += 1;
367 if (Inside(G4ThreeVector(px+del, py, pz)) != kOutside) icase += 2;
368 if (Inside(G4ThreeVector(px, py-del, pz)) != kOutside) icase += 4;
369 if (Inside(G4ThreeVector(px, py+del, pz)) != kOutside) icase += 8;
370 if (Inside(G4ThreeVector(px, py, pz-del)) != kOutside) icase += 16;
371 if (Inside(G4ThreeVector(px, py, pz+del)) != kOutside) icase += 32;
372 if (icase == 0) continue;
373 G4ThreeVector v = directions[icase];
374 dist = DistanceToIn(p, v);
375 if (dist == kInfinity) continue;
376 G4ThreeVector n = SurfaceNormal(p + v*dist);
377 dist *= -(v.dot(n));
378 }
379 if (dist < eps) ++icount;
380 }
381 return dX*dY*dZ*icount/npoints/dd;
382}
static const G4double eps
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
Definition: G4VSolid.cc:665
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0

References G4VSolid::BoundingLimits(), G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), CLHEP::Hep3Vector::dot(), eps, G4QuickRand(), G4VSolid::Inside(), kInfinity, kInside, kOutside, G4INCL::Math::min(), CLHEP::detail::n, G4VSolid::SurfaceNormal(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by G4VSolid::GetSurfaceArea(), G4MultiUnion::GetSurfaceArea(), and G4VCSGfaceted::GetSurfaceArea().

◆ GetAngle()

G4double G4ExtrudedSolid::GetAngle ( const G4TwoVector p0,
const G4TwoVector pa,
const G4TwoVector pb 
) const
private

Definition at line 551 of file G4ExtrudedSolid.cc.

554{
555 // Return the angle of the vertex in po
556
557 G4TwoVector t1 = pa - po;
558 G4TwoVector t2 = pb - po;
559
560 G4double result = (std::atan2(t1.y(), t1.x()) - std::atan2(t2.y(), t2.x()));
561
562 if ( result < 0 ) result += 2*pi;
563
564 return result;
565}

References pi, CLHEP::Hep2Vector::x(), and CLHEP::Hep2Vector::y().

Referenced by AddGeneralPolygonFacets().

◆ GetConstituentSolid() [1/2]

G4VSolid * G4VSolid::GetConstituentSolid ( G4int  no)
virtualinherited

Reimplemented in G4BooleanSolid.

Definition at line 170 of file G4VSolid.cc.

171{ return nullptr; }

◆ GetConstituentSolid() [2/2]

const G4VSolid * G4VSolid::GetConstituentSolid ( G4int  no) const
virtualinherited

Reimplemented in G4BooleanSolid.

Definition at line 167 of file G4VSolid.cc.

168{ return nullptr; }

Referenced by G4BooleanSolid::StackPolyhedron().

◆ GetCubicVolume()

G4double G4TessellatedSolid::GetCubicVolume ( )
virtualinherited

Reimplemented from G4VSolid.

Definition at line 2122 of file G4TessellatedSolid.cc.

2123{
2124 if (fCubicVolume != 0.) return fCubicVolume;
2125
2126 // For explanation of the following algorithm see:
2127 // https://en.wikipedia.org/wiki/Polyhedron#Volume
2128 // http://wwwf.imperial.ac.uk/~rn/centroid.pdf
2129
2130 G4int size = fFacets.size();
2131 for (G4int i = 0; i < size; ++i)
2132 {
2133 G4VFacet &facet = *fFacets[i];
2134 G4double area = facet.GetArea();
2135 G4ThreeVector unit_normal = facet.GetSurfaceNormal();
2136 fCubicVolume += area * (facet.GetVertex(0).dot(unit_normal));
2137 }
2138 fCubicVolume /= 3.;
2139 return fCubicVolume;
2140}

References CLHEP::Hep3Vector::dot(), G4TessellatedSolid::fCubicVolume, G4TessellatedSolid::fFacets, G4VFacet::GetArea(), G4VFacet::GetSurfaceNormal(), and G4VFacet::GetVertex().

◆ GetDisplacedSolidPtr() [1/2]

G4DisplacedSolid * G4VSolid::GetDisplacedSolidPtr ( )
virtualinherited

Reimplemented in G4DisplacedSolid.

Definition at line 176 of file G4VSolid.cc.

177{ return nullptr; }

◆ GetDisplacedSolidPtr() [2/2]

const G4DisplacedSolid * G4VSolid::GetDisplacedSolidPtr ( ) const
virtualinherited

Reimplemented in G4DisplacedSolid.

Definition at line 173 of file G4VSolid.cc.

174{ return nullptr; }

◆ GetEntityType()

G4GeometryType G4ExtrudedSolid::GetEntityType ( ) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 841 of file G4ExtrudedSolid.cc.

842{
843 // Return entity type
844
845 return fGeometryType;
846}

References fGeometryType.

◆ GetExtent()

G4VisExtent G4TessellatedSolid::GetExtent ( ) const
virtualinherited

◆ GetFacet()

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

◆ GetFacetIndex()

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

Definition at line 1105 of file G4TessellatedSolid.cc.

1106{
1107 G4int index = -1;
1108
1109 if (fVoxels.GetCountOfVoxels() > 1)
1110 {
1111 vector<G4int> curVoxel(3);
1112 fVoxels.GetVoxel(curVoxel, p);
1113 const vector<G4int> &candidates = fVoxels.GetCandidates(curVoxel);
1114 if (G4int limit = candidates.size())
1115 {
1116 G4double minDist = kInfinity;
1117 for(G4int i = 0 ; i < limit ; ++i)
1118 {
1119 G4int candidate = candidates[i];
1120 G4VFacet& facet = *fFacets[candidate];
1121 G4double dist = facet.Distance(p, minDist);
1122 if (dist <= kCarToleranceHalf) return index = candidate;
1123 if (dist < minDist)
1124 {
1125 minDist = dist;
1126 index = candidate;
1127 }
1128 }
1129 }
1130 }
1131 else
1132 {
1133 G4double minDist = kInfinity;
1134 G4int size = fFacets.size();
1135 for (G4int i = 0; i < size; ++i)
1136 {
1137 G4VFacet& facet = *fFacets[i];
1138 G4double dist = facet.Distance(p, minDist);
1139 if (dist < minDist)
1140 {
1141 minDist = dist;
1142 index = i;
1143 }
1144 }
1145 }
1146 return index;
1147}

References G4VFacet::Distance(), G4TessellatedSolid::fFacets, G4TessellatedSolid::fVoxels, G4Voxelizer::GetCandidates(), G4Voxelizer::GetCountOfVoxels(), G4Voxelizer::GetVoxel(), G4TessellatedSolid::kCarToleranceHalf, and kInfinity.

◆ GetMaxXExtent()

G4double G4TessellatedSolid::GetMaxXExtent ( ) const
inherited

Definition at line 2078 of file G4TessellatedSolid.cc.

2079{
2080 return fMaxExtent.x();
2081}

References G4TessellatedSolid::fMaxExtent, and CLHEP::Hep3Vector::x().

Referenced by Inside().

◆ GetMaxYExtent()

G4double G4TessellatedSolid::GetMaxYExtent ( ) const
inherited

Definition at line 2092 of file G4TessellatedSolid.cc.

2093{
2094 return fMaxExtent.y();
2095}

References G4TessellatedSolid::fMaxExtent, and CLHEP::Hep3Vector::y().

Referenced by Inside().

◆ GetMaxZExtent()

G4double G4TessellatedSolid::GetMaxZExtent ( ) const
inherited

Definition at line 2106 of file G4TessellatedSolid.cc.

2107{
2108 return fMaxExtent.z();
2109}

References G4TessellatedSolid::fMaxExtent, and CLHEP::Hep3Vector::z().

Referenced by Inside().

◆ GetMinXExtent()

G4double G4TessellatedSolid::GetMinXExtent ( ) const
inherited

Definition at line 2071 of file G4TessellatedSolid.cc.

2072{
2073 return fMinExtent.x();
2074}

References G4TessellatedSolid::fMinExtent, and CLHEP::Hep3Vector::x().

Referenced by Inside().

◆ GetMinYExtent()

G4double G4TessellatedSolid::GetMinYExtent ( ) const
inherited

Definition at line 2085 of file G4TessellatedSolid.cc.

2086{
2087 return fMinExtent.y();
2088}

References G4TessellatedSolid::fMinExtent, and CLHEP::Hep3Vector::y().

Referenced by Inside().

◆ GetMinZExtent()

G4double G4TessellatedSolid::GetMinZExtent ( ) const
inherited

Definition at line 2099 of file G4TessellatedSolid.cc.

2100{
2101 return fMinExtent.z();
2102}

References G4TessellatedSolid::fMinExtent, and CLHEP::Hep3Vector::z().

Referenced by Inside().

◆ GetName()

G4String G4VSolid::GetName ( ) const
inlineinherited

Referenced by G4GMocrenFileSceneHandler::AddDetector(), G4HepRepFileSceneHandler::AddHepRepInstance(), G4GMocrenFileSceneHandler::AddPrimitive(), G4HepRepFileSceneHandler::AddSolid(), G4GMocrenFileSceneHandler::AddSolid(), G4VtkSceneHandler::AddSolid(), G4GDMLWriteSolids::AddSolid(), G4NavigationLogger::AlongComputeStepLog(), G4GDMLWriteSolids::BooleanWrite(), G4ReflectedSolid::BoundingLimits(), G4DisplacedSolid::BoundingLimits(), G4IntersectionSolid::BoundingLimits(), G4ScaledSolid::BoundingLimits(), G4SubtractionSolid::BoundingLimits(), G4UnionSolid::BoundingLimits(), G4Box::BoundingLimits(), G4Cons::BoundingLimits(), G4CutTubs::BoundingLimits(), G4Orb::BoundingLimits(), G4Para::BoundingLimits(), G4Sphere::BoundingLimits(), G4Torus::BoundingLimits(), G4Trap::BoundingLimits(), G4Trd::BoundingLimits(), G4Tubs::BoundingLimits(), G4EllipticalCone::BoundingLimits(), BoundingLimits(), G4GenericPolycone::BoundingLimits(), G4GenericTrap::BoundingLimits(), G4Hype::BoundingLimits(), G4Paraboloid::BoundingLimits(), G4Polycone::BoundingLimits(), G4Polyhedra::BoundingLimits(), G4TessellatedSolid::BoundingLimits(), G4TwistedTubs::BoundingLimits(), G4GDMLWriteSolids::BoxWrite(), CalculateExtent(), G4GenericPolycone::CalculateExtent(), G4Polycone::CalculateExtent(), G4Polyhedra::CalculateExtent(), G4NavigationLogger::CheckDaughterEntryPoint(), G4VDivisionParameterisation::CheckNDivAndWidth(), G4VDivisionParameterisation::CheckOffset(), G4GenericTrap::CheckOrder(), G4Para::CheckParameters(), G4Trap::CheckParameters(), G4Trd::CheckParameters(), G4Ellipsoid::CheckParameters(), G4EllipticalTube::CheckParameters(), G4ParameterisationPolyconeRho::CheckParametersValidity(), G4ParameterisationPolyconeZ::CheckParametersValidity(), G4ParameterisationPolyhedraRho::CheckParametersValidity(), G4ParameterisationPolyhedraPhi::CheckParametersValidity(), G4ParameterisationPolyhedraZ::CheckParametersValidity(), G4PhantomParameterisation::CheckVoxelsFillContainer(), G4GenericTrap::ComputeIsTwisted(), G4VoxelNavigation::ComputeSafety(), G4VoxelSafety::ComputeSafety(), G4NavigationLogger::ComputeSafetyLog(), G4ParameterisedNavigation::ComputeStep(), G4ReplicaNavigation::ComputeStep(), G4GDMLWriteSolids::ConeWrite(), G4Polyhedra::Create(), G4GenericPolycone::Create(), G4Polycone::Create(), G4PhysicalVolumeModel::CreateCurrentAttValues(), G4ReflectedSolid::CreatePolyhedron(), G4ReflectionFactory::CreateReflectedLV(), G4GenericTrap::CreateTessellatedSolid(), G4GDMLWriteSolids::CutTubeWrite(), G4SolidStore::DeRegister(), G4PhysicalVolumeModel::DescribeSolid(), G4SubtractionSolid::DistanceToIn(), G4Paraboloid::DistanceToIn(), G4TessellatedSolid::DistanceToIn(), G4Box::DistanceToOut(), G4Orb::DistanceToOut(), G4Para::DistanceToOut(), G4Trap::DistanceToOut(), G4Trd::DistanceToOut(), G4EllipticalCone::DistanceToOut(), G4TessellatedSolid::DistanceToOut(), G4Ellipsoid::DistanceToOut(), G4EllipticalTube::DistanceToOut(), G4tgbGeometryDumper::DumpMultiUnionVolume(), G4tgbGeometryDumper::DumpScaledVolume(), G4tgbGeometryDumper::DumpSolid(), G4GDMLWriteSolids::ElconeWrite(), G4GDMLWriteSolids::EllipsoidWrite(), G4GDMLWriteSolids::EltubeWrite(), G4PVDivision::ErrorInAxis(), G4ReplicatedSlice::ErrorInAxis(), export_G4VSolid(), G4Box::G4Box(), G4Cons::G4Cons(), G4CutTubs::G4CutTubs(), G4EllipticalCone::G4EllipticalCone(), G4Hype::G4Hype(), G4Para::G4Para(), G4Paraboloid::G4Paraboloid(), G4Polycone::G4Polycone(), G4Polyhedra::G4Polyhedra(), G4Sphere::G4Sphere(), G4Tet::G4Tet(), G4Trap::G4Trap(), G4Tubs::G4Tubs(), G4VParameterisationCons::G4VParameterisationCons(), G4VParameterisationPara::G4VParameterisationPara(), G4VParameterisationPolycone::G4VParameterisationPolycone(), G4VParameterisationPolyhedra::G4VParameterisationPolyhedra(), G4VParameterisationTrd::G4VParameterisationTrd(), G4VTwistedFaceted::G4VTwistedFaceted(), G4GDMLWriteSolids::GenericPolyconeWrite(), G4GDMLWriteSolids::GenTrapWrite(), G4Navigator::GetGlobalExitNormal(), G4Navigator::GetLocalExitNormal(), G4ITNavigator1::GetLocalExitNormal(), G4ITNavigator2::GetLocalExitNormal(), G4BooleanSolid::GetPointOnSurface(), G4PhantomParameterisation::GetReplicaNo(), G4GDMLWriteSolids::HypeWrite(), G4TessellatedSolid::InsideNoVoxels(), G4TessellatedSolid::InsideVoxels(), G4ITNavigator1::LocateGlobalPointAndSetup(), G4ITNavigator2::LocateGlobalPointAndSetup(), G4Navigator::LocateGlobalPointAndSetup(), G4GenericTrap::MakeDownFacet(), G4Trap::MakePlanes(), G4GenericTrap::MakeUpFacet(), G4GDMLWriteSolids::MultiUnionWrite(), G4GDMLWriteSolids::OrbWrite(), G4GDMLWriteSolids::ParaboloidWrite(), G4GDMLWriteParamvol::ParametersWrite(), G4GDMLWriteSolids::ParaWrite(), G4GDMLWriteSolids::PolyconeWrite(), G4GDMLWriteSolids::PolyhedraWrite(), G4NavigationLogger::PostComputeStepLog(), G4NavigationLogger::PreComputeStepLog(), G4NavigationLogger::PrintDaughterLog(), G4PseudoScene::ProcessVolume(), G4SolidStore::Register(), G4tgbVolumeMgr::RegisterMe(), G4NavigationLogger::ReportOutsideMother(), G4ASCIITreeSceneHandler::RequestPrimitives(), G4VSceneHandler::RequestPrimitives(), G4GenericPolycone::Reset(), G4Polyhedra::Reset(), G4VoxelSafety::SafetyForVoxelNode(), G4GDMLWriteSolids::ScaledWrite(), G4Torus::SetAllParameters(), G4Tet::SetBoundingLimits(), G4Polycone::SetOriginalParameters(), G4Polyhedra::SetOriginalParameters(), G4TessellatedSolid::SetSolidClosed(), G4Tet::SetVertices(), G4Box::SetXHalfLength(), G4Box::SetYHalfLength(), G4Box::SetZHalfLength(), G4GDMLWriteSolids::SphereWrite(), G4BooleanSolid::StackPolyhedron(), G4ReflectedSolid::StreamInfo(), G4BooleanSolid::StreamInfo(), G4DisplacedSolid::StreamInfo(), G4MultiUnion::StreamInfo(), G4ScaledSolid::StreamInfo(), G4Box::StreamInfo(), G4Cons::StreamInfo(), G4CSGSolid::StreamInfo(), G4CutTubs::StreamInfo(), G4Orb::StreamInfo(), G4Para::StreamInfo(), G4Sphere::StreamInfo(), G4Torus::StreamInfo(), G4Trap::StreamInfo(), G4Trd::StreamInfo(), G4Tubs::StreamInfo(), G4Ellipsoid::StreamInfo(), G4EllipticalCone::StreamInfo(), G4EllipticalTube::StreamInfo(), StreamInfo(), G4GenericPolycone::StreamInfo(), G4GenericTrap::StreamInfo(), G4Hype::StreamInfo(), G4Paraboloid::StreamInfo(), G4Polycone::StreamInfo(), G4Polyhedra::StreamInfo(), G4TessellatedSolid::StreamInfo(), G4Tet::StreamInfo(), G4TwistedBox::StreamInfo(), G4TwistedTrap::StreamInfo(), G4TwistedTrd::StreamInfo(), G4TwistedTubs::StreamInfo(), G4VCSGfaceted::StreamInfo(), G4VTwistedFaceted::StreamInfo(), G4GDMLRead::StripNames(), SubstractSolids(), G4UnionSolid::SurfaceNormal(), G4Box::SurfaceNormal(), G4Para::SurfaceNormal(), G4Trap::SurfaceNormal(), G4Trd::SurfaceNormal(), G4Ellipsoid::SurfaceNormal(), G4EllipticalCone::SurfaceNormal(), G4EllipticalTube::SurfaceNormal(), SurfaceNormal(), G4Tet::SurfaceNormal(), G4GDMLWriteSolids::TessellatedWrite(), G4GDMLWriteSolids::TetWrite(), G4GDMLWriteSolids::TorusWrite(), G4GDMLWriteSolids::TrapWrite(), G4GDMLWriteStructure::TraverseVolumeTree(), G4GDMLWriteSolids::TrdWrite(), G4GDMLWriteSolids::TubeWrite(), G4GDMLWriteSolids::TwistedboxWrite(), G4GDMLWriteSolids::TwistedtrapWrite(), G4GDMLWriteSolids::TwistedtrdWrite(), G4GDMLWriteSolids::TwistedtubsWrite(), G4PhysicalVolumeModel::VisitGeometryAndGetVisReps(), and G4GDMLWriteSolids::XtruWrite().

◆ GetNofVertices()

G4int G4ExtrudedSolid::GetNofVertices ( ) const
inline

◆ GetNofZSections()

G4int G4ExtrudedSolid::GetNofZSections ( ) const
inline

◆ GetNumberOfFacets()

G4int G4TessellatedSolid::GetNumberOfFacets ( ) const
inherited

◆ GetPointOnSurface()

G4ThreeVector G4TessellatedSolid::GetPointOnSurface ( ) const
virtualinherited

Reimplemented from G4VSolid.

Definition at line 2159 of file G4TessellatedSolid.cc.

2160{
2161 // Select randomly a facet and return a random point on it
2162
2163 G4int i = (G4int) G4RandFlat::shoot(0., fFacets.size());
2164 return fFacets[i]->GetPointOnFace();
2165}
ThreeVector shoot(const G4int Ap, const G4int Af)

References G4TessellatedSolid::fFacets, and G4INCL::DeJongSpin::shoot().

Referenced by G4GenericTrap::GetPointOnSurface().

◆ GetPolygon()

std::vector< G4TwoVector > G4ExtrudedSolid::GetPolygon ( ) const
inline

◆ GetPolyhedron()

G4Polyhedron * G4TessellatedSolid::GetPolyhedron ( ) const
virtualinherited

◆ GetSolidClosed()

G4bool G4TessellatedSolid::GetSolidClosed ( ) const
inherited

Definition at line 662 of file G4TessellatedSolid.cc.

663{
664 return fSolidClosed;
665}

References G4TessellatedSolid::fSolidClosed.

◆ GetSurfaceArea()

G4double G4TessellatedSolid::GetSurfaceArea ( )
virtualinherited

Reimplemented from G4VSolid.

Definition at line 2144 of file G4TessellatedSolid.cc.

2145{
2146 if (fSurfaceArea != 0.) return fSurfaceArea;
2147
2148 G4int size = fFacets.size();
2149 for (G4int i = 0; i < size; ++i)
2150 {
2151 G4VFacet &facet = *fFacets[i];
2152 fSurfaceArea += facet.GetArea();
2153 }
2154 return fSurfaceArea;
2155}

References G4TessellatedSolid::fFacets, G4TessellatedSolid::fSurfaceArea, and G4VFacet::GetArea().

◆ GetTolerance()

G4double G4VSolid::GetTolerance ( ) const
inlineinherited

◆ GetVertex() [1/2]

G4TwoVector G4ExtrudedSolid::GetVertex ( G4int  index) const
inline

◆ GetVertex() [2/2]

G4ThreeVector G4ExtrudedSolid::GetVertex ( G4int  iz,
G4int  ind 
) const
private

Definition at line 412 of file G4ExtrudedSolid.cc.

413{
414 // Shift and scale vertices
415
416 return G4ThreeVector( fPolygon[ind].x() * fZSections[iz].fScale
417 + fZSections[iz].fOffset.x(),
418 fPolygon[ind].y() * fZSections[iz].fScale
419 + fZSections[iz].fOffset.y(), fZSections[iz].fZ);
420}

References fPolygon, and fZSections.

◆ GetVoxels()

G4Voxelizer & G4TessellatedSolid::GetVoxels ( )
inlineinherited

Definition at line 314 of file G4TessellatedSolid.hh.

315{
316 return fVoxels;
317}

References G4TessellatedSolid::fVoxels.

◆ GetZSection()

ZSection G4ExtrudedSolid::GetZSection ( G4int  index) const
inline

◆ GetZSections()

std::vector< ZSection > G4ExtrudedSolid::GetZSections ( ) const
inline

◆ Initialize()

void G4TessellatedSolid::Initialize ( )
privateinherited

◆ Inside()

EInside G4ExtrudedSolid::Inside ( const G4ThreeVector p) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 857 of file G4ExtrudedSolid.cc.

858{
859 switch (fSolidType)
860 {
861 case 1: // convex right prism
862 {
863 G4double dist = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
864 if (dist > kCarToleranceHalf) { return kOutside; }
865
866 G4int np = fPlanes.size();
867 for (G4int i=0; i<np; ++i)
868 {
869 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
870 if (dd > dist) { dist = dd; }
871 }
872 if (dist > kCarToleranceHalf) { return kOutside; }
873 return (dist > -kCarToleranceHalf) ? kSurface : kInside;
874 }
875 case 2: // non-convex right prism
876 {
877 G4double distz = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
878 if (distz > kCarToleranceHalf) { return kOutside; }
879
880 G4bool in = PointInPolygon(p);
881 if (distz > -kCarToleranceHalf && in) { return kSurface; }
882
884 if (in)
885 {
886 return (dd >= 0) ? kInside : kSurface;
887 }
888 else
889 {
890 return (dd > 0) ? kOutside : kSurface;
891 }
892 }
893 }
894
895 // Override the base class function as it fails in case of concave polygon.
896 // Project the point in the original polygon scale and check if it is inside
897 // for each triangle.
898
899 // Check first if outside extent
900 //
901 if ( p.x() < GetMinXExtent() - kCarToleranceHalf ||
907 {
908 // G4cout << "G4ExtrudedSolid::Outside extent: " << p << G4endl;
909 return kOutside;
910 }
911
912 // Project point p(z) to the polygon scale p0
913 //
914 G4TwoVector pscaled = ProjectPoint(p);
915
916 // Check if on surface of polygon
917 //
918 for ( G4int i=0; i<fNv; ++i )
919 {
920 G4int j = (i+1) % fNv;
921 if ( IsSameLineSegment(pscaled, fPolygon[i], fPolygon[j]) )
922 {
923 // G4cout << "G4ExtrudedSolid::Inside return Surface (on polygon) "
924 // << G4endl;
925
926 return kSurface;
927 }
928 }
929
930 // Now check if inside triangles
931 //
932 auto it = fTriangles.cbegin();
933 G4bool inside = false;
934 do // Loop checking, 13.08.2015, G.Cosmo
935 {
936 if ( IsPointInside(fPolygon[(*it)[0]], fPolygon[(*it)[1]],
937 fPolygon[(*it)[2]], pscaled) ) { inside = true; }
938 ++it;
939 } while ( (inside == false) && (it != fTriangles.cend()) );
940
941 if ( inside )
942 {
943 // Check if on surface of z sides
944 //
945 if ( std::fabs( p.z() - fZSections[0].fZ ) < kCarToleranceHalf ||
946 std::fabs( p.z() - fZSections[fNz-1].fZ ) < kCarToleranceHalf )
947 {
948 // G4cout << "G4ExtrudedSolid::Inside return Surface (on z side)"
949 // << G4endl;
950
951 return kSurface;
952 }
953
954 // G4cout << "G4ExtrudedSolid::Inside return Inside" << G4endl;
955
956 return kInside;
957 }
958
959 // G4cout << "G4ExtrudedSolid::Inside return Outside " << G4endl;
960
961 return kOutside;
962}
G4bool IsSameLineSegment(const G4TwoVector &p, const G4TwoVector &l1, const G4TwoVector &l2) const
G4TwoVector ProjectPoint(const G4ThreeVector &point) const
G4double GetMinYExtent() const
G4double GetMinZExtent() const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMaxXExtent() const
G4double GetMinXExtent() const
@ kSurface
Definition: geomdefs.hh:69

References DistanceToPolygonSqr(), fNv, fNz, fPlanes, fPolygon, fSolidType, fTriangles, fZSections, G4TessellatedSolid::GetMaxXExtent(), G4TessellatedSolid::GetMaxYExtent(), G4TessellatedSolid::GetMaxZExtent(), G4TessellatedSolid::GetMinXExtent(), G4TessellatedSolid::GetMinYExtent(), G4TessellatedSolid::GetMinZExtent(), IsPointInside(), IsSameLineSegment(), G4TessellatedSolid::kCarToleranceHalf, kInside, kOutside, kSurface, G4INCL::Math::max(), PointInPolygon(), ProjectPoint(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

◆ InsideNoVoxels()

EInside G4TessellatedSolid::InsideNoVoxels ( const G4ThreeVector p) const
privateinherited

Definition at line 959 of file G4TessellatedSolid.cc.

960{
961 //
962 // First the simple test - check if we're outside of the X-Y-Z extremes
963 // of the tessellated solid.
964 //
966 return kOutside;
967
968 const G4double dirTolerance = 1.0E-14;
969
970 G4double minDist = kInfinity;
971 //
972 // Check if we are close to a surface
973 //
974 G4int size = fFacets.size();
975 for (G4int i = 0; i < size; ++i)
976 {
977 G4VFacet& facet = *fFacets[i];
978 G4double dist = facet.Distance(p,minDist);
979 if (dist < minDist) minDist = dist;
980 if (dist <= kCarToleranceHalf)
981 {
982 return kSurface;
983 }
984 }
985 //
986 // The following is something of an adaptation of the method implemented by
987 // Rickard Holmberg augmented with information from Schneider & Eberly,
988 // "Geometric Tools for Computer Graphics," pp700-701, 2003. In essence, we're
989 // trying to determine whether we're inside the volume by projecting a few
990 // rays and determining if the first surface crossed is has a normal vector
991 // between 0 to pi/2 (out-going) or pi/2 to pi (in-going). We should also
992 // avoid rays which are nearly within the plane of the tessellated surface,
993 // and therefore produce rays randomly. For the moment, this is a bit
994 // over-engineered (belt-braces-and-ducttape).
995 //
996#if G4SPECSDEBUG
997 G4int nTry = 7;
998#else
999 G4int nTry = 3;
1000#endif
1001 G4double distOut = kInfinity;
1002 G4double distIn = kInfinity;
1003 G4double distO = 0.0;
1004 G4double distI = 0.0;
1005 G4double distFromSurfaceO = 0.0;
1006 G4double distFromSurfaceI = 0.0;
1007 G4ThreeVector normalO(0.0,0.0,0.0);
1008 G4ThreeVector normalI(0.0,0.0,0.0);
1009 G4bool crossingO = false;
1010 G4bool crossingI = false;
1011 EInside location = kOutside;
1012 EInside locationprime = kOutside;
1013 G4int sm = 0;
1014
1015 for (G4int i=0; i<nTry; ++i)
1016 {
1017 G4bool nearParallel = false;
1018 do // Loop checking, 13.08.2015, G.Cosmo
1019 {
1020 //
1021 // We loop until we find direction where the vector is not nearly parallel
1022 // to the surface of any facet since this causes ambiguities. The usual
1023 // case is that the angles should be sufficiently different, but there
1024 // are 20 random directions to select from - hopefully sufficient.
1025 //
1026 distOut = distIn = kInfinity;
1028 sm++;
1029 vector<G4VFacet*>::const_iterator f = fFacets.begin();
1030
1031 do // Loop checking, 13.08.2015, G.Cosmo
1032 {
1033 //
1034 // Here we loop through the facets to find out if there is an
1035 // intersection between the ray and that facet. The test if performed
1036 // separately whether the ray is entering the facet or exiting.
1037 //
1038 crossingO = ((*f)->Intersect(p,v,true,distO,distFromSurfaceO,normalO));
1039 crossingI = ((*f)->Intersect(p,v,false,distI,distFromSurfaceI,normalI));
1040 if (crossingO || crossingI)
1041 {
1042 nearParallel = (crossingO && std::fabs(normalO.dot(v))<dirTolerance)
1043 || (crossingI && std::fabs(normalI.dot(v))<dirTolerance);
1044 if (!nearParallel)
1045 {
1046 if (crossingO && distO > 0.0 && distO < distOut) distOut = distO;
1047 if (crossingI && distI > 0.0 && distI < distIn) distIn = distI;
1048 }
1049 }
1050 } while (!nearParallel && ++f != fFacets.end());
1051 } while (nearParallel && sm != fMaxTries);
1052
1053#ifdef G4VERBOSE
1054 if (sm == fMaxTries)
1055 {
1056 //
1057 // We've run out of random vector directions. If nTries is set
1058 // sufficiently low (nTries <= 0.5*maxTries) then this would indicate
1059 // that there is something wrong with geometry.
1060 //
1061 std::ostringstream message;
1062 G4int oldprc = message.precision(16);
1063 message << "Cannot determine whether point is inside or outside volume!"
1064 << G4endl
1065 << "Solid name = " << GetName() << G4endl
1066 << "Geometry Type = " << fGeometryType << G4endl
1067 << "Number of facets = " << fFacets.size() << G4endl
1068 << "Position:" << G4endl << G4endl
1069 << "p.x() = " << p.x()/mm << " mm" << G4endl
1070 << "p.y() = " << p.y()/mm << " mm" << G4endl
1071 << "p.z() = " << p.z()/mm << " mm";
1072 message.precision(oldprc);
1073 G4Exception("G4TessellatedSolid::Inside()",
1074 "GeomSolids1002", JustWarning, message);
1075 }
1076#endif
1077 //
1078 // In the next if-then-elseif G4String the logic is as follows:
1079 // (1) You don't hit anything so cannot be inside volume, provided volume
1080 // constructed correctly!
1081 // (2) Distance to inside (ie. nearest facet such that you enter facet) is
1082 // shorter than distance to outside (nearest facet such that you exit
1083 // facet) - on condition of safety distance - therefore we're outside.
1084 // (3) Distance to outside is shorter than distance to inside therefore
1085 // we're inside.
1086 //
1087 if (distIn == kInfinity && distOut == kInfinity)
1088 locationprime = kOutside;
1089 else if (distIn <= distOut - kCarToleranceHalf)
1090 locationprime = kOutside;
1091 else if (distOut <= distIn - kCarToleranceHalf)
1092 locationprime = kInside;
1093
1094 if (i == 0) location = locationprime;
1095 }
1096
1097 return location;
1098}

References G4VFacet::Distance(), CLHEP::Hep3Vector::dot(), G4TessellatedSolid::fFacets, G4TessellatedSolid::fGeometryType, G4TessellatedSolid::fMaxTries, G4TessellatedSolid::fRandir, G4endl, G4Exception(), G4VSolid::GetName(), JustWarning, G4VSolid::kCarTolerance, G4TessellatedSolid::kCarToleranceHalf, kInfinity, kInside, kOutside, kSurface, mm, G4TessellatedSolid::OutsideOfExtent(), G4InuclParticleNames::sm, CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by G4TessellatedSolid::Inside(), and G4TessellatedSolid::PrecalculateInsides().

◆ InsideVoxels()

EInside G4TessellatedSolid::InsideVoxels ( const G4ThreeVector aPoint) const
privateinherited

Definition at line 768 of file G4TessellatedSolid.cc.

769{
770 //
771 // First the simple test - check if we're outside of the X-Y-Z extremes
772 // of the tessellated solid.
773 //
775 return kOutside;
776
777 vector<G4int> startingVoxel(3);
778 fVoxels.GetVoxel(startingVoxel, p);
779
780 const G4double dirTolerance = 1.0E-14;
781
782 const vector<G4int> &startingCandidates =
783 fVoxels.GetCandidates(startingVoxel);
784 G4int limit = startingCandidates.size();
785 if (limit == 0 && fInsides.GetNbits())
786 {
787 G4int index = fVoxels.GetPointIndex(p);
788 EInside location = fInsides[index] ? kInside : kOutside;
789 return location;
790 }
791
792 G4double minDist = kInfinity;
793
794 for(G4int i = 0; i < limit; ++i)
795 {
796 G4int candidate = startingCandidates[i];
797 G4VFacet &facet = *fFacets[candidate];
798 G4double dist = facet.Distance(p,minDist);
799 if (dist < minDist) minDist = dist;
800 if (dist <= kCarToleranceHalf)
801 return kSurface;
802 }
803
804 // The following is something of an adaptation of the method implemented by
805 // Rickard Holmberg augmented with information from Schneider & Eberly,
806 // "Geometric Tools for Computer Graphics," pp700-701, 2003. In essence,
807 // we're trying to determine whether we're inside the volume by projecting
808 // a few rays and determining if the first surface crossed is has a normal
809 // vector between 0 to pi/2 (out-going) or pi/2 to pi (in-going).
810 // We should also avoid rays which are nearly within the plane of the
811 // tessellated surface, and therefore produce rays randomly.
812 // For the moment, this is a bit over-engineered (belt-braces-and-ducttape).
813 //
814 G4double distOut = kInfinity;
815 G4double distIn = kInfinity;
816 G4double distO = 0.0;
817 G4double distI = 0.0;
818 G4double distFromSurfaceO = 0.0;
819 G4double distFromSurfaceI = 0.0;
820 G4ThreeVector normalO, normalI;
821 G4bool crossingO = false;
822 G4bool crossingI = false;
823 EInside location = kOutside;
824 G4int sm = 0;
825
826 G4bool nearParallel = false;
827 do // Loop checking, 13.08.2015, G.Cosmo
828 {
829 // We loop until we find direction where the vector is not nearly parallel
830 // to the surface of any facet since this causes ambiguities. The usual
831 // case is that the angles should be sufficiently different, but there
832 // are 20 random directions to select from - hopefully sufficient.
833 //
834 distOut = distIn = kInfinity;
835 const G4ThreeVector& v = fRandir[sm];
836 ++sm;
837 //
838 // This code could be voxelized by the same algorithm, which is used for
839 // DistanceToOut(). We will traverse through fVoxels. we will call
840 // intersect only for those, which would be candidates and was not
841 // checked before.
842 //
843 G4ThreeVector currentPoint = p;
844 G4ThreeVector direction = v.unit();
845 // G4SurfBits exclusion(fVoxels.GetBitsPerSlice());
846 vector<G4int> curVoxel(3);
847 curVoxel = startingVoxel;
848 G4double shiftBonus = kCarTolerance;
849
850 G4bool crossed = false;
851 G4bool started = true;
852
853 do // Loop checking, 13.08.2015, G.Cosmo
854 {
855 const vector<G4int> &candidates =
856 started ? startingCandidates : fVoxels.GetCandidates(curVoxel);
857 started = false;
858 if (G4int candidatesCount = candidates.size())
859 {
860 for (G4int i = 0 ; i < candidatesCount; ++i)
861 {
862 G4int candidate = candidates[i];
863 // bits.SetBitNumber(candidate);
864 G4VFacet& facet = *fFacets[candidate];
865
866 crossingO = facet.Intersect(p,v,true,distO,distFromSurfaceO,normalO);
867 crossingI = facet.Intersect(p,v,false,distI,distFromSurfaceI,normalI);
868
869 if (crossingO || crossingI)
870 {
871 crossed = true;
872
873 nearParallel = (crossingO
874 && std::fabs(normalO.dot(v))<dirTolerance)
875 || (crossingI && std::fabs(normalI.dot(v))<dirTolerance);
876 if (!nearParallel)
877 {
878 if (crossingO && distO > 0.0 && distO < distOut)
879 distOut = distO;
880 if (crossingI && distI > 0.0 && distI < distIn)
881 distIn = distI;
882 }
883 else break;
884 }
885 }
886 if (nearParallel) break;
887 }
888 else
889 {
890 if (!crossed)
891 {
892 G4int index = fVoxels.GetVoxelsIndex(curVoxel);
893 G4bool inside = fInsides[index];
894 location = inside ? kInside : kOutside;
895 return location;
896 }
897 }
898
899 G4double shift=fVoxels.DistanceToNext(currentPoint, direction, curVoxel);
900 if (shift == kInfinity) break;
901
902 currentPoint += direction * (shift + shiftBonus);
903 }
904 while (fVoxels.UpdateCurrentVoxel(currentPoint, direction, curVoxel));
905
906 }
907 while (nearParallel && sm != fMaxTries);
908 //
909 // Here we loop through the facets to find out if there is an intersection
910 // between the ray and that facet. The test if performed separately whether
911 // the ray is entering the facet or exiting.
912 //
913#ifdef G4VERBOSE
914 if (sm == fMaxTries)
915 {
916 //
917 // We've run out of random vector directions. If nTries is set sufficiently
918 // low (nTries <= 0.5*maxTries) then this would indicate that there is
919 // something wrong with geometry.
920 //
921 std::ostringstream message;
922 G4int oldprc = message.precision(16);
923 message << "Cannot determine whether point is inside or outside volume!"
924 << G4endl
925 << "Solid name = " << GetName() << G4endl
926 << "Geometry Type = " << fGeometryType << G4endl
927 << "Number of facets = " << fFacets.size() << G4endl
928 << "Position:" << G4endl << G4endl
929 << "p.x() = " << p.x()/mm << " mm" << G4endl
930 << "p.y() = " << p.y()/mm << " mm" << G4endl
931 << "p.z() = " << p.z()/mm << " mm";
932 message.precision(oldprc);
933 G4Exception("G4TessellatedSolid::Inside()",
934 "GeomSolids1002", JustWarning, message);
935 }
936#endif
937
938 // In the next if-then-elseif G4String the logic is as follows:
939 // (1) You don't hit anything so cannot be inside volume, provided volume
940 // constructed correctly!
941 // (2) Distance to inside (ie. nearest facet such that you enter facet) is
942 // shorter than distance to outside (nearest facet such that you exit
943 // facet) - on condition of safety distance - therefore we're outside.
944 // (3) Distance to outside is shorter than distance to inside therefore
945 // we're inside.
946 //
947 if (distIn == kInfinity && distOut == kInfinity)
948 location = kOutside;
949 else if (distIn <= distOut - kCarToleranceHalf)
950 location = kOutside;
951 else if (distOut <= distIn - kCarToleranceHalf)
952 location = kInside;
953
954 return location;
955}
unsigned int GetNbits() const
Definition: G4SurfBits.hh:92
G4int GetPointIndex(const G4ThreeVector &p) const
G4int GetVoxelsIndex(G4int x, G4int y, G4int z) const

References G4VFacet::Distance(), G4Voxelizer::DistanceToNext(), CLHEP::Hep3Vector::dot(), G4TessellatedSolid::fFacets, G4TessellatedSolid::fGeometryType, G4TessellatedSolid::fInsides, G4TessellatedSolid::fMaxTries, G4TessellatedSolid::fRandir, G4TessellatedSolid::fVoxels, G4endl, G4Exception(), G4Voxelizer::GetCandidates(), G4VSolid::GetName(), G4SurfBits::GetNbits(), G4Voxelizer::GetPointIndex(), G4Voxelizer::GetVoxel(), G4Voxelizer::GetVoxelsIndex(), G4VFacet::Intersect(), JustWarning, G4VSolid::kCarTolerance, G4TessellatedSolid::kCarToleranceHalf, kInfinity, kInside, kOutside, kSurface, mm, G4TessellatedSolid::OutsideOfExtent(), G4InuclParticleNames::sm, CLHEP::Hep3Vector::unit(), G4Voxelizer::UpdateCurrentVoxel(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by G4TessellatedSolid::Inside().

◆ IsPointInside()

G4bool G4ExtrudedSolid::IsPointInside ( const G4TwoVector a,
const G4TwoVector b,
const G4TwoVector c,
const G4TwoVector p 
) const
private

Definition at line 520 of file G4ExtrudedSolid.cc.

524{
525 // Return true if p is inside of triangle abc or on its edges,
526 // else returns false
527
528 // Check extent first
529 //
530 if ( ( p.x() < a.x() && p.x() < b.x() && p.x() < c.x() ) ||
531 ( p.x() > a.x() && p.x() > b.x() && p.x() > c.x() ) ||
532 ( p.y() < a.y() && p.y() < b.y() && p.y() < c.y() ) ||
533 ( p.y() > a.y() && p.y() > b.y() && p.y() > c.y() ) ) return false;
534
535 G4bool inside
536 = IsSameSide(p, a, b, c)
537 && IsSameSide(p, b, a, c)
538 && IsSameSide(p, c, a, b);
539
540 G4bool onEdge
541 = IsSameLineSegment(p, a, b)
542 || IsSameLineSegment(p, b, c)
543 || IsSameLineSegment(p, c, a);
544
545 return inside || onEdge;
546}
G4bool IsSameSide(const G4TwoVector &p1, const G4TwoVector &p2, const G4TwoVector &l1, const G4TwoVector &l2) const

References IsSameLineSegment(), IsSameSide(), CLHEP::Hep2Vector::x(), and CLHEP::Hep2Vector::y().

Referenced by AddGeneralPolygonFacets(), and Inside().

◆ IsSameLine()

G4bool G4ExtrudedSolid::IsSameLine ( const G4TwoVector p,
const G4TwoVector l1,
const G4TwoVector l2 
) const
private

Definition at line 455 of file G4ExtrudedSolid.cc.

458{
459 // Return true if p is on the line through l1, l2
460
461 if ( l1.x() == l2.x() )
462 {
463 return std::fabs(p.x() - l1.x()) < kCarToleranceHalf;
464 }
465 G4double slope= ((l2.y() - l1.y())/(l2.x() - l1.x()));
466 G4double predy= l1.y() + slope *(p.x() - l1.x());
467 G4double dy= p.y() - predy;
468
469 // Calculate perpendicular distance
470 //
471 // G4double perpD= std::fabs(dy) / std::sqrt( 1 + slope * slope );
472 // G4bool simpleComp= (perpD<kCarToleranceHalf);
473
474 // Check perpendicular distance vs tolerance 'directly'
475 //
476 G4bool squareComp = (dy*dy < (1+slope*slope)
478
479 // return simpleComp;
480 return squareComp;
481}

References G4TessellatedSolid::kCarToleranceHalf, CLHEP::Hep2Vector::x(), and CLHEP::Hep2Vector::y().

Referenced by IsSameLineSegment().

◆ IsSameLineSegment()

G4bool G4ExtrudedSolid::IsSameLineSegment ( const G4TwoVector p,
const G4TwoVector l1,
const G4TwoVector l2 
) const
private

Definition at line 485 of file G4ExtrudedSolid.cc.

488{
489 // Return true if p is on the line through l1, l2 and lies between
490 // l1 and l2
491
492 if ( p.x() < std::min(l1.x(), l2.x()) - kCarToleranceHalf ||
493 p.x() > std::max(l1.x(), l2.x()) + kCarToleranceHalf ||
494 p.y() < std::min(l1.y(), l2.y()) - kCarToleranceHalf ||
495 p.y() > std::max(l1.y(), l2.y()) + kCarToleranceHalf )
496 {
497 return false;
498 }
499
500 return IsSameLine(p, l1, l2);
501}
G4bool IsSameLine(const G4TwoVector &p, const G4TwoVector &l1, const G4TwoVector &l2) const

References IsSameLine(), G4TessellatedSolid::kCarToleranceHalf, G4INCL::Math::max(), G4INCL::Math::min(), CLHEP::Hep2Vector::x(), and CLHEP::Hep2Vector::y().

Referenced by Inside(), and IsPointInside().

◆ IsSameSide()

G4bool G4ExtrudedSolid::IsSameSide ( const G4TwoVector p1,
const G4TwoVector p2,
const G4TwoVector l1,
const G4TwoVector l2 
) const
private

Definition at line 505 of file G4ExtrudedSolid.cc.

509{
510 // Return true if p1 and p2 are on the same side of the line through l1, l2
511
512 return ( (p1.x() - l1.x()) * (l2.y() - l1.y())
513 - (l2.x() - l1.x()) * (p1.y() - l1.y()) )
514 * ( (p2.x() - l1.x()) * (l2.y() - l1.y())
515 - (l2.x() - l1.x()) * (p2.y() - l1.y()) ) > 0;
516}

References CLHEP::Hep2Vector::x(), and CLHEP::Hep2Vector::y().

Referenced by IsPointInside().

◆ MakeDownFacet()

G4VFacet * G4ExtrudedSolid::MakeDownFacet ( G4int  ind1,
G4int  ind2,
G4int  ind3 
) const
private

Definition at line 570 of file G4ExtrudedSolid.cc.

571{
572 // Create a triangular facet from the polygon points given by indices
573 // forming the down side ( the normal goes in -z)
574
575 std::vector<G4ThreeVector> vertices;
576 vertices.push_back(GetVertex(0, ind1));
577 vertices.push_back(GetVertex(0, ind2));
578 vertices.push_back(GetVertex(0, ind3));
579
580 // first vertex most left
581 //
582 G4ThreeVector cross
583 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
584
585 if ( cross.z() > 0.0 )
586 {
587 // vertices ordered clock wise has to be reordered
588
589 // G4cout << "G4ExtrudedSolid::MakeDownFacet: reordering vertices "
590 // << ind1 << ", " << ind2 << ", " << ind3 << G4endl;
591
592 G4ThreeVector tmp = vertices[1];
593 vertices[1] = vertices[2];
594 vertices[2] = tmp;
595 }
596
597 return new G4TriangularFacet(vertices[0], vertices[1],
598 vertices[2], ABSOLUTE);
599}
@ ABSOLUTE
Definition: G4VFacet.hh:48
G4TwoVector GetVertex(G4int index) const

References ABSOLUTE, GetVertex(), and CLHEP::Hep3Vector::z().

Referenced by AddGeneralPolygonFacets().

◆ MakeFacets()

G4bool G4ExtrudedSolid::MakeFacets ( )
private

Definition at line 761 of file G4ExtrudedSolid.cc.

762{
763 // Define facets
764
765 G4bool good;
766
767 // Decomposition of polygonal sides in the facets
768 //
769 if ( fNv == 3 )
770 {
771 good = AddFacet( new G4TriangularFacet( GetVertex(0, 0), GetVertex(0, 1),
772 GetVertex(0, 2), ABSOLUTE) );
773 if ( ! good ) { return false; }
774
775 good = AddFacet( new G4TriangularFacet( GetVertex(fNz-1, 2),
776 GetVertex(fNz-1, 1),
777 GetVertex(fNz-1, 0),
778 ABSOLUTE) );
779 if ( ! good ) { return false; }
780
781 std::vector<G4int> triangle(3);
782 triangle[0] = 0;
783 triangle[1] = 1;
784 triangle[2] = 2;
785 fTriangles.push_back(triangle);
786 }
787
788 else if ( fNv == 4 )
789 {
790 good = AddFacet( new G4QuadrangularFacet( GetVertex(0, 0),GetVertex(0, 1),
791 GetVertex(0, 2),GetVertex(0, 3),
792 ABSOLUTE) );
793 if ( ! good ) { return false; }
794
795 good = AddFacet( new G4QuadrangularFacet( GetVertex(fNz-1, 3),
796 GetVertex(fNz-1, 2),
797 GetVertex(fNz-1, 1),
798 GetVertex(fNz-1, 0),
799 ABSOLUTE) );
800 if ( ! good ) { return false; }
801
802 std::vector<G4int> triangle1(3);
803 triangle1[0] = 0;
804 triangle1[1] = 1;
805 triangle1[2] = 2;
806 fTriangles.push_back(triangle1);
807
808 std::vector<G4int> triangle2(3);
809 triangle2[0] = 0;
810 triangle2[1] = 2;
811 triangle2[2] = 3;
812 fTriangles.push_back(triangle2);
813 }
814 else
815 {
817 if ( ! good ) { return false; }
818 }
819
820 // The quadrangular sides
821 //
822 for ( G4int iz = 0; iz < fNz-1; ++iz )
823 {
824 for ( G4int i = 0; i < fNv; ++i )
825 {
826 G4int j = (i+1) % fNv;
827 good = AddFacet( new G4QuadrangularFacet
828 ( GetVertex(iz, j), GetVertex(iz, i),
829 GetVertex(iz+1, i), GetVertex(iz+1, j), ABSOLUTE) );
830 if ( ! good ) { return false; }
831 }
832 }
833
834 SetSolidClosed(true);
835
836 return good;
837}
G4bool AddGeneralPolygonFacets()

References ABSOLUTE, G4TessellatedSolid::AddFacet(), AddGeneralPolygonFacets(), fNv, fNz, fTriangles, GetVertex(), and G4TessellatedSolid::SetSolidClosed().

Referenced by G4ExtrudedSolid().

◆ MakeUpFacet()

G4VFacet * G4ExtrudedSolid::MakeUpFacet ( G4int  ind1,
G4int  ind2,
G4int  ind3 
) const
private

Definition at line 604 of file G4ExtrudedSolid.cc.

605{
606 // Creates a triangular facet from the polygon points given by indices
607 // forming the upper side ( z>0 )
608
609 std::vector<G4ThreeVector> vertices;
610 vertices.push_back(GetVertex(fNz-1, ind1));
611 vertices.push_back(GetVertex(fNz-1, ind2));
612 vertices.push_back(GetVertex(fNz-1, ind3));
613
614 // first vertex most left
615 //
616 G4ThreeVector cross
617 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
618
619 if ( cross.z() < 0.0 )
620 {
621 // vertices ordered clock wise has to be reordered
622
623 // G4cout << "G4ExtrudedSolid::MakeUpFacet: reordering vertices "
624 // << ind1 << ", " << ind2 << ", " << ind3 << G4endl;
625
626 G4ThreeVector tmp = vertices[1];
627 vertices[1] = vertices[2];
628 vertices[2] = tmp;
629 }
630
631 return new G4TriangularFacet(vertices[0], vertices[1],
632 vertices[2], ABSOLUTE);
633}

References ABSOLUTE, fNz, GetVertex(), and CLHEP::Hep3Vector::z().

Referenced by AddGeneralPolygonFacets().

◆ MinDistanceFacet()

G4double G4TessellatedSolid::MinDistanceFacet ( const G4ThreeVector p,
G4bool  simple,
G4VFacet *&  facet 
) const
privateinherited

Definition at line 1594 of file G4TessellatedSolid.cc.

1597{
1598 G4double minDist = kInfinity;
1599
1601 vector<pair<G4int, G4double> > voxelsSorted(size);
1602
1603 pair<G4int, G4double> info;
1604
1605 for (G4int i = 0; i < size; ++i)
1606 {
1607 const G4VoxelBox& voxelBox = fVoxels.GetVoxelBox(i);
1608
1609 G4ThreeVector pointShifted = p - voxelBox.pos;
1610 G4double safety = fVoxels.MinDistanceToBox(pointShifted, voxelBox.hlen);
1611 info.first = i;
1612 info.second = safety;
1613 voxelsSorted[i] = info;
1614 }
1615
1616 std::sort(voxelsSorted.begin(), voxelsSorted.end(),
1618
1619 for (G4int i = 0; i < size; ++i)
1620 {
1621 const pair<G4int,G4double>& inf = voxelsSorted[i];
1622 G4double dist = inf.second;
1623 if (dist > minDist) break;
1624
1625 const vector<G4int>& candidates = fVoxels.GetVoxelBoxCandidates(inf.first);
1626 G4int csize = candidates.size();
1627 for (G4int j = 0; j < csize; ++j)
1628 {
1629 G4int candidate = candidates[j];
1630 G4VFacet& facet = *fFacets[candidate];
1631 dist = simple ? facet.Distance(p,minDist)
1632 : facet.Distance(p,minDist,false);
1633 if (dist < minDist)
1634 {
1635 minDist = dist;
1636 minFacet = &facet;
1637 }
1638 }
1639 }
1640 return minDist;
1641}
static G4bool CompareSortedVoxel(const std::pair< G4int, G4double > &l, const std::pair< G4int, G4double > &r)
G4int GetVoxelBoxesSize() const
static G4double MinDistanceToBox(const G4ThreeVector &aPoint, const G4ThreeVector &f)
const G4VoxelBox & GetVoxelBox(G4int i) const
const std::vector< G4int > & GetVoxelBoxCandidates(G4int i) const
G4ThreeVector hlen
Definition: G4Voxelizer.hh:51
G4ThreeVector pos
Definition: G4Voxelizer.hh:52

References G4TessellatedSolid::CompareSortedVoxel(), G4VFacet::Distance(), G4TessellatedSolid::fFacets, G4TessellatedSolid::fVoxels, G4Voxelizer::GetVoxelBox(), G4Voxelizer::GetVoxelBoxCandidates(), G4Voxelizer::GetVoxelBoxesSize(), G4VoxelBox::hlen, kInfinity, G4Voxelizer::MinDistanceToBox(), and G4VoxelBox::pos.

Referenced by G4TessellatedSolid::Normal(), G4TessellatedSolid::SafetyFromInside(), and G4TessellatedSolid::SafetyFromOutside().

◆ Normal()

G4bool G4TessellatedSolid::Normal ( const G4ThreeVector p,
G4ThreeVector n 
) const
virtualinherited

Definition at line 1154 of file G4TessellatedSolid.cc.

1156{
1157 G4double minDist;
1158 G4VFacet* facet = nullptr;
1159
1160 if (fVoxels.GetCountOfVoxels() > 1)
1161 {
1162 vector<G4int> curVoxel(3);
1163 fVoxels.GetVoxel(curVoxel, p);
1164 const vector<G4int> &candidates = fVoxels.GetCandidates(curVoxel);
1165 // fVoxels.GetCandidatesVoxelArray(p, candidates, 0);
1166
1167 if (G4int limit = candidates.size())
1168 {
1169 minDist = kInfinity;
1170 for(G4int i = 0 ; i < limit ; ++i)
1171 {
1172 G4int candidate = candidates[i];
1173 G4VFacet &fct = *fFacets[candidate];
1174 G4double dist = fct.Distance(p,minDist);
1175 if (dist < minDist) minDist = dist;
1176 if (dist <= kCarToleranceHalf)
1177 {
1178 aNormal = fct.GetSurfaceNormal();
1179 return true;
1180 }
1181 }
1182 }
1183 minDist = MinDistanceFacet(p, true, facet);
1184 }
1185 else
1186 {
1187 minDist = kInfinity;
1188 G4int size = fFacets.size();
1189 for (G4int i = 0; i < size; ++i)
1190 {
1191 G4VFacet& f = *fFacets[i];
1192 G4double dist = f.Distance(p, minDist);
1193 if (dist < minDist)
1194 {
1195 minDist = dist;
1196 facet = &f;
1197 }
1198 }
1199 }
1200
1201 if (minDist != kInfinity)
1202 {
1203 if (facet) { aNormal = facet->GetSurfaceNormal(); }
1204 return minDist <= kCarToleranceHalf;
1205 }
1206 else
1207 {
1208#ifdef G4VERBOSE
1209 std::ostringstream message;
1210 message << "Point p is not on surface !?" << G4endl
1211 << " No facets found for point: " << p << " !" << G4endl
1212 << " Returning approximated value for normal.";
1213
1214 G4Exception("G4TessellatedSolid::SurfaceNormal(p)",
1215 "GeomSolids1002", JustWarning, message );
1216#endif
1217 aNormal = (p.z() > 0 ? G4ThreeVector(0,0,1) : G4ThreeVector(0,0,-1));
1218 return false;
1219 }
1220}
G4double MinDistanceFacet(const G4ThreeVector &p, G4bool simple, G4VFacet *&facet) const

References G4VFacet::Distance(), G4TessellatedSolid::fFacets, G4TessellatedSolid::fVoxels, G4endl, G4Exception(), G4Voxelizer::GetCandidates(), G4Voxelizer::GetCountOfVoxels(), G4VFacet::GetSurfaceNormal(), G4Voxelizer::GetVoxel(), JustWarning, G4TessellatedSolid::kCarToleranceHalf, kInfinity, G4TessellatedSolid::MinDistanceFacet(), and CLHEP::Hep3Vector::z().

Referenced by G4TessellatedSolid::DistanceToOutCore(), G4TessellatedSolid::DistanceToOutNoVoxels(), and G4TessellatedSolid::SurfaceNormal().

◆ operator+=()

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

Definition at line 748 of file G4TessellatedSolid.cc.

749{
750 G4int size = right.GetNumberOfFacets();
751 for (G4int i = 0; i < size; ++i)
752 AddFacet(right.GetFacet(i)->GetClone());
753
754 return *this;
755}
G4int GetNumberOfFacets() const
G4VFacet * GetFacet(G4int i) const
virtual G4VFacet * GetClone()=0

References G4TessellatedSolid::AddFacet(), G4VFacet::GetClone(), G4TessellatedSolid::GetFacet(), and G4TessellatedSolid::GetNumberOfFacets().

◆ operator=()

G4ExtrudedSolid & G4ExtrudedSolid::operator= ( const G4ExtrudedSolid rhs)

Definition at line 307 of file G4ExtrudedSolid.cc.

308{
309 // Check assignment to self
310 //
311 if (this == &rhs) { return *this; }
312
313 // Copy base class data
314 //
316
317 // Copy data
318 //
319 fNv = rhs.fNv; fNz = rhs.fNz;
324 fLines = rhs.fLines; fLengths = rhs.fLengths;
325 fKScales = rhs.fKScales; fScale0s = rhs.fScale0s;
327
328 return *this;
329}
G4TessellatedSolid & operator=(const G4TessellatedSolid &right)

References fGeometryType, fIsConvex, fKOffsets, fKScales, fLengths, fLines, fNv, fNz, fOffset0s, fPlanes, fPolygon, fScale0s, fSolidType, fTriangles, fZSections, and G4TessellatedSolid::operator=().

◆ operator==()

G4bool G4VSolid::operator== ( const G4VSolid s) const
inlineinherited

◆ OutsideOfExtent()

G4bool G4TessellatedSolid::OutsideOfExtent ( const G4ThreeVector p,
G4double  tolerance = 0.0 
) const
inlineprivateinherited

◆ PointInPolygon()

G4bool G4ExtrudedSolid::PointInPolygon ( const G4ThreeVector p) const
inlineprivate

◆ PrecalculateInsides()

void G4TessellatedSolid::PrecalculateInsides ( )
privateinherited

Definition at line 336 of file G4TessellatedSolid.cc.

337{
338 vector<G4int> voxel(3), maxVoxels(3);
339 for (auto i = 0; i <= 2; ++i) maxVoxels[i] = fVoxels.GetBoundary(i).size();
340 G4int size = maxVoxels[0] * maxVoxels[1] * maxVoxels[2];
341
342 G4SurfBits checked(size-1);
343 fInsides.Clear();
344 fInsides.ResetBitNumber(size-1);
345
346 G4ThreeVector point;
347 for (voxel[2] = 0; voxel[2] < maxVoxels[2] - 1; ++voxel[2])
348 {
349 for (voxel[1] = 0; voxel[1] < maxVoxels[1] - 1; ++voxel[1])
350 {
351 for (voxel[0] = 0; voxel[0] < maxVoxels[0] - 1; ++voxel[0])
352 {
353 G4int index = fVoxels.GetVoxelsIndex(voxel);
354 if (!checked[index] && fVoxels.IsEmpty(index))
355 {
356 for (auto i = 0; i <= 2; ++i)
357 {
358 point[i] = fVoxels.GetBoundary(i)[voxel[i]];
359 }
360 G4bool inside = (G4bool) (InsideNoVoxels(point) == kInside);
361 SetAllUsingStack(voxel, maxVoxels, inside, checked);
362 }
363 else checked.SetBitNumber(index);
364 }
365 }
366 }
367}
void Clear()
Definition: G4SurfBits.cc:89
void ResetBitNumber(unsigned int bitnumber)
Definition: G4SurfBits.hh:154
EInside InsideNoVoxels(const G4ThreeVector &p) const
G4int SetAllUsingStack(const std::vector< G4int > &voxel, const std::vector< G4int > &max, G4bool status, G4SurfBits &checked)
const std::vector< G4double > & GetBoundary(G4int index) const
G4bool IsEmpty(G4int index) const

References G4SurfBits::Clear(), G4TessellatedSolid::fInsides, G4TessellatedSolid::fVoxels, G4Voxelizer::GetBoundary(), G4Voxelizer::GetVoxelsIndex(), G4TessellatedSolid::InsideNoVoxels(), G4Voxelizer::IsEmpty(), kInside, G4SurfBits::ResetBitNumber(), G4TessellatedSolid::SetAllUsingStack(), and G4SurfBits::SetBitNumber().

Referenced by G4TessellatedSolid::Voxelize().

◆ ProjectPoint()

G4TwoVector G4ExtrudedSolid::ProjectPoint ( const G4ThreeVector point) const
private

Definition at line 424 of file G4ExtrudedSolid.cc.

425{
426 // Project point in the polygon scale
427 // scale(z) = k*z + scale0
428 // offset(z) = l*z + offset0
429 // p(z) = scale(z)*p0 + offset(z)
430 // p0 = (p(z) - offset(z))/scale(z);
431
432 // Select projection (z-segment of the solid) according to p.z()
433 //
434 G4int iz = 0;
435 while ( point.z() > fZSections[iz+1].fZ && iz < fNz-2 ) { ++iz; }
436 // Loop checking, 13.08.2015, G.Cosmo
437
438 G4double z0 = ( fZSections[iz+1].fZ + fZSections[iz].fZ )/2.0;
439 G4TwoVector p2(point.x(), point.y());
440 G4double pscale = fKScales[iz]*(point.z()-z0) + fScale0s[iz];
441 G4TwoVector poffset = fKOffsets[iz]*(point.z()-z0) + fOffset0s[iz];
442
443 // G4cout << point << " projected to "
444 // << iz << "-th z-segment polygon as "
445 // << (p2 - poffset)/pscale << G4endl;
446
447 // pscale is always >0 as it is an interpolation between two
448 // positive scale values
449 //
450 return (p2 - poffset)/pscale;
451}

References fKOffsets, fKScales, fNz, fOffset0s, fScale0s, fZSections, CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), CLHEP::Hep3Vector::z(), and G4InuclParticleNames::z0.

Referenced by Inside().

◆ SafetyFromInside()

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

Definition at line 1704 of file G4TessellatedSolid.cc.

1705{
1706#if G4SPECSDEBUG
1707 if ( Inside(p) == kOutside )
1708 {
1709 std::ostringstream message;
1710 G4int oldprc = message.precision(16) ;
1711 message << "Point p is already outside!?" << G4endl
1712 << "Position:" << G4endl << G4endl
1713 << "p.x() = " << p.x()/mm << " mm" << G4endl
1714 << "p.y() = " << p.y()/mm << " mm" << G4endl
1715 << "p.z() = " << p.z()/mm << " mm" << G4endl
1716 << "DistanceToIn(p) == " << DistanceToIn(p);
1717 message.precision(oldprc) ;
1718 G4Exception("G4TriangularFacet::DistanceToOut(p)",
1719 "GeomSolids1002", JustWarning, message);
1720 }
1721#endif
1722
1723 G4double minDist;
1724
1725 if (OutsideOfExtent(p, kCarTolerance)) return 0.0;
1726
1727 if (fVoxels.GetCountOfVoxels() > 1)
1728 {
1729 G4VFacet* facet;
1730 minDist = MinDistanceFacet(p, true, facet);
1731 }
1732 else
1733 {
1734 minDist = kInfinity;
1735 G4double dist = 0.0;
1736 G4int size = fFacets.size();
1737 for (G4int i = 0; i < size; ++i)
1738 {
1739 G4VFacet& facet = *fFacets[i];
1740 dist = facet.Distance(p,minDist);
1741 if (dist < minDist) minDist = dist;
1742 }
1743 }
1744 return minDist;
1745}

References G4VFacet::Distance(), G4TessellatedSolid::DistanceToIn(), G4TessellatedSolid::fFacets, G4TessellatedSolid::fVoxels, G4endl, G4Exception(), G4Voxelizer::GetCountOfVoxels(), G4TessellatedSolid::Inside(), JustWarning, G4VSolid::kCarTolerance, kInfinity, kOutside, G4TessellatedSolid::MinDistanceFacet(), mm, G4TessellatedSolid::OutsideOfExtent(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by G4TessellatedSolid::DistanceToOut().

◆ SafetyFromOutside()

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

Definition at line 1645 of file G4TessellatedSolid.cc.

1647{
1648#if G4SPECSDEBUG
1649 if ( Inside(p) == kInside )
1650 {
1651 std::ostringstream message;
1652 G4int oldprc = message.precision(16) ;
1653 message << "Point p is already inside!?" << G4endl
1654 << "Position:" << G4endl << G4endl
1655 << "p.x() = " << p.x()/mm << " mm" << G4endl
1656 << "p.y() = " << p.y()/mm << " mm" << G4endl
1657 << "p.z() = " << p.z()/mm << " mm" << G4endl
1658 << "DistanceToOut(p) == " << DistanceToOut(p);
1659 message.precision(oldprc) ;
1660 G4Exception("G4TriangularFacet::DistanceToIn(p)",
1661 "GeomSolids1002", JustWarning, message);
1662 }
1663#endif
1664
1665 G4double minDist;
1666
1667 if (fVoxels.GetCountOfVoxels() > 1)
1668 {
1669 if (!aAccurate)
1671
1673 {
1674 vector<G4int> startingVoxel(3);
1675 fVoxels.GetVoxel(startingVoxel, p);
1676 const vector<G4int> &candidates = fVoxels.GetCandidates(startingVoxel);
1677 if (candidates.size() == 0 && fInsides.GetNbits())
1678 {
1679 G4int index = fVoxels.GetPointIndex(p);
1680 if (fInsides[index]) return 0.;
1681 }
1682 }
1683
1684 G4VFacet* facet;
1685 minDist = MinDistanceFacet(p, true, facet);
1686 }
1687 else
1688 {
1689 minDist = kInfinity;
1690 G4int size = fFacets.size();
1691 for (G4int i = 0; i < size; ++i)
1692 {
1693 G4VFacet& facet = *fFacets[i];
1694 G4double dist = facet.Distance(p,minDist);
1695 if (dist < minDist) minDist = dist;
1696 }
1697 }
1698 return minDist;
1699}
G4double DistanceToBoundingBox(const G4ThreeVector &point) const

References G4VFacet::Distance(), G4Voxelizer::DistanceToBoundingBox(), G4TessellatedSolid::DistanceToOut(), G4TessellatedSolid::fFacets, G4TessellatedSolid::fInsides, G4TessellatedSolid::fVoxels, G4endl, G4Exception(), G4Voxelizer::GetCandidates(), G4Voxelizer::GetCountOfVoxels(), G4SurfBits::GetNbits(), G4Voxelizer::GetPointIndex(), G4Voxelizer::GetVoxel(), G4TessellatedSolid::Inside(), JustWarning, G4VSolid::kCarTolerance, kInfinity, kInside, G4TessellatedSolid::MinDistanceFacet(), mm, G4TessellatedSolid::OutsideOfExtent(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by G4TessellatedSolid::DistanceToIn().

◆ SetAllUsingStack()

G4int G4TessellatedSolid::SetAllUsingStack ( const std::vector< G4int > &  voxel,
const std::vector< G4int > &  max,
G4bool  status,
G4SurfBits checked 
)
privateinherited

Definition at line 280 of file G4TessellatedSolid.cc.

283{
284 vector<G4int> xyz = voxel;
285 stack<vector<G4int> > pos;
286 pos.push(xyz);
287 G4int filled = 0;
288 G4int cc = 0, nz = 0;
289
290 vector<G4int> candidates;
291
292 while (!pos.empty()) // Loop checking, 13.08.2015, G.Cosmo
293 {
294 xyz = pos.top();
295 pos.pop();
296 G4int index = fVoxels.GetVoxelsIndex(xyz);
297 if (!checked[index])
298 {
299 checked.SetBitNumber(index, true);
300 ++cc;
301
302 if (fVoxels.IsEmpty(index))
303 {
304 ++filled;
305
306 fInsides.SetBitNumber(index, status);
307
308 for (auto i = 0; i <= 2; ++i)
309 {
310 if (xyz[i] < max[i] - 1)
311 {
312 xyz[i]++;
313 pos.push(xyz);
314 xyz[i]--;
315 }
316
317 if (xyz[i] > 0)
318 {
319 xyz[i]--;
320 pos.push(xyz);
321 xyz[i]++;
322 }
323 }
324 }
325 else
326 {
327 ++nz;
328 }
329 }
330 }
331 return filled;
332}
void SetBitNumber(unsigned int bitnumber, G4bool value=true)
Definition: G4SurfBits.hh:114

References G4TessellatedSolid::fInsides, G4TessellatedSolid::fVoxels, G4Voxelizer::GetVoxelsIndex(), G4Voxelizer::IsEmpty(), G4INCL::Math::max(), pos, and G4SurfBits::SetBitNumber().

Referenced by G4TessellatedSolid::PrecalculateInsides().

◆ SetExtremeFacets()

void G4TessellatedSolid::SetExtremeFacets ( )
privateinherited

Definition at line 399 of file G4TessellatedSolid.cc.

400{
401 // Copy vertices to local array
402 G4int vsize = fVertexList.size();
403 std::vector<G4ThreeVector> vertices(vsize);
404 for (G4int i = 0; i < vsize; ++i) { vertices[i] = fVertexList[i]; }
405
406 // Shuffle vertices
407 std::mt19937 gen(12345678);
408 std::shuffle(vertices.begin(), vertices.end(), gen);
409
410 // Select six extreme vertices in different directions
411 G4ThreeVector points[6];
412 for (G4int i=0; i < 6; ++i) { points[i] = vertices[0]; }
413 for (G4int i=1; i < vsize; ++i)
414 {
415 if (vertices[i].x() < points[0].x()) points[0] = vertices[i];
416 if (vertices[i].x() > points[1].x()) points[1] = vertices[i];
417 if (vertices[i].y() < points[2].y()) points[2] = vertices[i];
418 if (vertices[i].y() > points[3].y()) points[3] = vertices[i];
419 if (vertices[i].z() < points[4].z()) points[4] = vertices[i];
420 if (vertices[i].z() > points[5].z()) points[5] = vertices[i];
421 }
422
423 // Find extreme facets
424 G4int size = fFacets.size();
425 for (G4int j = 0; j < size; ++j)
426 {
427 G4VFacet &facet = *fFacets[j];
428
429 // Check extreme vertices
430 if (!facet.IsInside(points[0])) continue;
431 if (!facet.IsInside(points[1])) continue;
432 if (!facet.IsInside(points[2])) continue;
433 if (!facet.IsInside(points[3])) continue;
434 if (!facet.IsInside(points[4])) continue;
435 if (!facet.IsInside(points[5])) continue;
436
437 // Check vertices
438 G4bool isExtreme = true;
439 for (G4int i=0; i < vsize; ++i)
440 {
441 if (!facet.IsInside(vertices[i]))
442 {
443 isExtreme = false;
444 break;
445 }
446 }
447 if (isExtreme) fExtremeFacets.insert(&facet);
448 }
449}
G4bool IsInside(const G4ThreeVector &p) const
Definition: G4VFacet.cc:112

References G4TessellatedSolid::fExtremeFacets, G4TessellatedSolid::fFacets, G4TessellatedSolid::fVertexList, and G4VFacet::IsInside().

Referenced by G4TessellatedSolid::SetSolidClosed().

◆ SetMaxVoxels()

void G4TessellatedSolid::SetMaxVoxels ( G4int  max)
inlineinherited

◆ SetName()

void G4VSolid::SetName ( const G4String name)
inherited

Definition at line 127 of file G4VSolid.cc.

128{
131}
void SetMapValid(G4bool val)
Definition: G4SolidStore.hh:76
static G4SolidStore * GetInstance()
G4String fshapeName
Definition: G4VSolid.hh:312
const char * name(G4int ptype)

References G4VSolid::fshapeName, G4SolidStore::GetInstance(), G4InuclParticleNames::name(), and G4SolidStore::SetMapValid().

Referenced by export_G4VSolid(), G4MultiUnion::G4MultiUnion(), and G4GDMLRead::StripNames().

◆ SetRandomVectors()

void G4TessellatedSolid::SetRandomVectors ( )
privateinherited

Definition at line 2176 of file G4TessellatedSolid.cc.

2177{
2178 fRandir.resize(20);
2179 fRandir[0] =
2180 G4ThreeVector(-0.9577428892113370, 0.2732676269591740, 0.0897405271949221);
2181 fRandir[1] =
2182 G4ThreeVector(-0.8331264504940770,-0.5162067214954600,-0.1985722492445700);
2183 fRandir[2] =
2184 G4ThreeVector(-0.1516671651108820, 0.9666292616127460, 0.2064580868390110);
2185 fRandir[3] =
2186 G4ThreeVector( 0.6570250350323190,-0.6944539025883300, 0.2933460081893360);
2187 fRandir[4] =
2188 G4ThreeVector(-0.4820456281280320,-0.6331060000098690,-0.6056474264406270);
2189 fRandir[5] =
2190 G4ThreeVector( 0.7629032554236800 , 0.1016854697539910,-0.6384658864065180);
2191 fRandir[6] =
2192 G4ThreeVector( 0.7689540409061150, 0.5034929891988220, 0.3939600142169160);
2193 fRandir[7] =
2194 G4ThreeVector( 0.5765188359255740, 0.5997271636278330,-0.5549354566343150);
2195 fRandir[8] =
2196 G4ThreeVector( 0.6660632777862070,-0.6362809868288380, 0.3892379937580790);
2197 fRandir[9] =
2198 G4ThreeVector( 0.3824415020414780, 0.6541792713761380,-0.6525243125110690);
2199 fRandir[10] =
2200 G4ThreeVector(-0.5107726564526760, 0.6020905056811610, 0.6136760679616570);
2201 fRandir[11] =
2202 G4ThreeVector( 0.7459135439578050, 0.6618796061649330, 0.0743530220183488);
2203 fRandir[12] =
2204 G4ThreeVector( 0.1536405855311580, 0.8117477913978260,-0.5634359711967240);
2205 fRandir[13] =
2206 G4ThreeVector( 0.0744395301705579,-0.8707110101772920,-0.4861286795736560);
2207 fRandir[14] =
2208 G4ThreeVector(-0.1665874645185400, 0.6018553940549240,-0.7810369397872780);
2209 fRandir[15] =
2210 G4ThreeVector( 0.7766902003633100, 0.6014617505959970,-0.1870724331097450);
2211 fRandir[16] =
2212 G4ThreeVector(-0.8710128685847430,-0.1434320216603030,-0.4698551243971010);
2213 fRandir[17] =
2214 G4ThreeVector( 0.8901082092766820,-0.4388411398893870, 0.1229871120030100);
2215 fRandir[18] =
2216 G4ThreeVector(-0.6430417431544370,-0.3295938228697690, 0.6912779675984150);
2217 fRandir[19] =
2218 G4ThreeVector( 0.6331124368380410, 0.6306211461665000, 0.4488714875425340);
2219
2220 fMaxTries = 20;
2221}

References G4TessellatedSolid::fMaxTries, and G4TessellatedSolid::fRandir.

Referenced by G4TessellatedSolid::Initialize().

◆ SetSolidClosed()

void G4TessellatedSolid::SetSolidClosed ( const G4bool  t)
inherited

Definition at line 598 of file G4TessellatedSolid.cc.

599{
600 if (t)
601 {
602#ifdef G4SPECSDEBUG
603 G4cout << "Creating vertex list..." << G4endl;
604#endif
606
607#ifdef G4SPECSDEBUG
608 G4cout << "Setting extreme facets..." << G4endl;
609#endif
611
612#ifdef G4SPECSDEBUG
613 G4cout << "Voxelizing..." << G4endl;
614#endif
615 Voxelize();
616
617#ifdef G4SPECSDEBUG
619#endif
620
621#ifdef G4SPECSDEBUG
622 G4cout << "Checking Structure..." << G4endl;
623#endif
624 G4int irep = CheckStructure();
625 if (irep != 0)
626 {
627 if (irep & 1)
628 {
629 std::ostringstream message;
630 message << "Defects in solid: " << GetName()
631 << " - negative cubic volume, please check orientation of facets!";
632 G4Exception("G4TessellatedSolid::SetSolidClosed()",
633 "GeomSolids1001", JustWarning, message);
634 }
635 if (irep & 2)
636 {
637 std::ostringstream message;
638 message << "Defects in solid: " << GetName()
639 << " - some facets have wrong orientation!";
640 G4Exception("G4TessellatedSolid::SetSolidClosed()",
641 "GeomSolids1001", JustWarning, message);
642 }
643 if (irep & 4)
644 {
645 std::ostringstream message;
646 message << "Defects in solid: " << GetName()
647 << " - there are holes in the surface!";
648 G4Exception("G4TessellatedSolid::SetSolidClosed()",
649 "GeomSolids1001", JustWarning, message);
650 }
651 }
652 }
653 fSolidClosed = t;
654}
G4int CheckStructure() const

References G4TessellatedSolid::CheckStructure(), G4TessellatedSolid::CreateVertexList(), G4TessellatedSolid::DisplayAllocatedMemory(), G4TessellatedSolid::fSolidClosed, G4cout, G4endl, G4Exception(), G4VSolid::GetName(), JustWarning, G4TessellatedSolid::SetExtremeFacets(), and G4TessellatedSolid::Voxelize().

Referenced by G4TessellatedSolid::CopyObjects(), G4GenericTrap::CreateTessellatedSolid(), MakeFacets(), and G4GDMLReadSolids::TessellatedRead().

◆ StreamInfo()

std::ostream & G4ExtrudedSolid::StreamInfo ( std::ostream &  os) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 1519 of file G4ExtrudedSolid.cc.

1520{
1521 G4int oldprc = os.precision(16);
1522 os << "-----------------------------------------------------------\n"
1523 << " *** Dump for solid - " << GetName() << " ***\n"
1524 << " ===================================================\n"
1525 << " Solid geometry type: " << fGeometryType << G4endl;
1526
1527 if ( fIsConvex)
1528 { os << " Convex polygon; list of vertices:" << G4endl; }
1529 else
1530 { os << " Concave polygon; list of vertices:" << G4endl; }
1531
1532 for ( G4int i=0; i<fNv; ++i )
1533 {
1534 os << std::setw(5) << "#" << i
1535 << " vx = " << fPolygon[i].x()/mm << " mm"
1536 << " vy = " << fPolygon[i].y()/mm << " mm" << G4endl;
1537 }
1538
1539 os << " Sections:" << G4endl;
1540 for ( G4int iz=0; iz<fNz; ++iz )
1541 {
1542 os << " z = " << fZSections[iz].fZ/mm << " mm "
1543 << " x0= " << fZSections[iz].fOffset.x()/mm << " mm "
1544 << " y0= " << fZSections[iz].fOffset.y()/mm << " mm "
1545 << " scale= " << fZSections[iz].fScale << G4endl;
1546 }
1547
1548/*
1549 // Triangles (for debugging)
1550 os << G4endl;
1551 os << " Triangles:" << G4endl;
1552 os << " Triangle # vertex1 vertex2 vertex3" << G4endl;
1553
1554 G4int counter = 0;
1555 std::vector< std::vector<G4int> >::const_iterator it;
1556 for ( it = fTriangles.begin(); it != fTriangles.end(); it++ ) {
1557 std::vector<G4int> triangle = *it;
1558 os << std::setw(10) << counter++
1559 << std::setw(10) << triangle[0] << std::setw(10) << triangle[1]
1560 << std::setw(10) << triangle[2]
1561 << G4endl;
1562 }
1563*/
1564 os.precision(oldprc);
1565
1566 return os;
1567}

References fGeometryType, fIsConvex, fNv, fNz, fPolygon, fZSections, G4endl, G4VSolid::GetName(), and mm.

◆ SurfaceNormal()

G4ThreeVector G4ExtrudedSolid::SurfaceNormal ( const G4ThreeVector p) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 966 of file G4ExtrudedSolid.cc.

967{
968 G4int nsurf = 0;
969 G4double nx = 0, ny = 0, nz = 0;
970 switch (fSolidType)
971 {
972 case 1: // convex right prism
973 {
974 if (std::abs(p.z() - fZSections[0].fZ) <= kCarToleranceHalf)
975 {
976 nz = -1; ++nsurf;
977 }
978 if (std::abs(p.z() - fZSections[1].fZ) <= kCarToleranceHalf)
979 {
980 nz = 1; ++nsurf;
981 }
982 for (G4int i=0; i<fNv; ++i)
983 {
984 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
985 if (std::abs(dd) > kCarToleranceHalf) continue;
986 nx += fPlanes[i].a;
987 ny += fPlanes[i].b;
988 ++nsurf;
989 }
990 break;
991 }
992 case 2: // non-convex right prism
993 {
994 if (std::abs(p.z() - fZSections[0].fZ) <= kCarToleranceHalf)
995 {
996 nz = -1; ++nsurf;
997 }
998 if (std::abs(p.z() - fZSections[1].fZ) <= kCarToleranceHalf)
999 {
1000 nz = 1; ++nsurf;
1001 }
1002
1003 G4double sqrCarToleranceHalf = kCarToleranceHalf*kCarToleranceHalf;
1004 for (G4int i=0, k=fNv-1; i<fNv; k=i++)
1005 {
1006 G4double ix = p.x() - fPolygon[i].x();
1007 G4double iy = p.y() - fPolygon[i].y();
1008 G4double u = fPlanes[i].a*iy - fPlanes[i].b*ix;
1009 if (u < 0)
1010 {
1011 if (ix*ix + iy*iy > sqrCarToleranceHalf) continue;
1012 }
1013 else if (u > fLengths[i])
1014 {
1015 G4double kx = p.x() - fPolygon[k].x();
1016 G4double ky = p.y() - fPolygon[k].y();
1017 if (kx*kx + ky*ky > sqrCarToleranceHalf) continue;
1018 }
1019 else
1020 {
1021 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
1022 if (dd*dd > sqrCarToleranceHalf) continue;
1023 }
1024 nx += fPlanes[i].a;
1025 ny += fPlanes[i].b;
1026 ++nsurf;
1027 }
1028 break;
1029 }
1030 default:
1031 {
1033 }
1034 }
1035
1036 // Return normal (right prism)
1037 //
1038 if (nsurf == 1)
1039 {
1040 return G4ThreeVector(nx,ny,nz);
1041 }
1042 else if (nsurf != 0) // edge or corner
1043 {
1044 return G4ThreeVector(nx,ny,nz).unit();
1045 }
1046 else
1047 {
1048 // Point is not on the surface, compute approximate normal
1049 //
1050#ifdef G4CSGDEBUG
1051 std::ostringstream message;
1052 G4int oldprc = message.precision(16);
1053 message << "Point p is not on surface (!?) of solid: "
1054 << GetName() << G4endl;
1055 message << "Position:\n";
1056 message << " p.x() = " << p.x()/mm << " mm\n";
1057 message << " p.y() = " << p.y()/mm << " mm\n";
1058 message << " p.z() = " << p.z()/mm << " mm";
1059 G4cout.precision(oldprc) ;
1060 G4Exception("G4TesselatedSolid::SurfaceNormal(p)", "GeomSolids1002",
1061 JustWarning, message );
1062 DumpInfo();
1063#endif
1064 return ApproxSurfaceNormal(p);
1065 }
1066}
G4ThreeVector ApproxSurfaceNormal(const G4ThreeVector &p) const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const

References ApproxSurfaceNormal(), G4VSolid::DumpInfo(), fLengths, fNv, fPlanes, fPolygon, fSolidType, fZSections, G4cout, G4endl, G4Exception(), G4VSolid::GetName(), JustWarning, G4TessellatedSolid::kCarToleranceHalf, mm, G4TessellatedSolid::SurfaceNormal(), CLHEP::Hep3Vector::unit(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

◆ Voxelize()

void G4TessellatedSolid::Voxelize ( )
privateinherited

Definition at line 371 of file G4TessellatedSolid.cc.

372{
373#ifdef G4SPECSDEBUG
374 G4cout << "Voxelizing..." << G4endl;
375#endif
377
378 if (fVoxels.Empty().GetNbits())
379 {
380#ifdef G4SPECSDEBUG
381 G4cout << "Precalculating Insides..." << G4endl;
382#endif
384 }
385}
const G4SurfBits & Empty() const
void Voxelize(std::vector< G4VSolid * > &solids, std::vector< G4Transform3D > &transforms)
Definition: G4Voxelizer.cc:713

References G4Voxelizer::Empty(), G4TessellatedSolid::fFacets, G4TessellatedSolid::fVoxels, G4cout, G4endl, G4SurfBits::GetNbits(), G4TessellatedSolid::PrecalculateInsides(), and G4Voxelizer::Voxelize().

Referenced by G4TessellatedSolid::SetSolidClosed().

Field Documentation

◆ fCubicVolume

G4double G4TessellatedSolid::fCubicVolume = 0.0
privateinherited

◆ fExtremeFacets

std::set<G4VFacet*> G4TessellatedSolid::fExtremeFacets
privateinherited

◆ fFacetList

std::set<G4VertexInfo,G4VertexComparator> G4TessellatedSolid::fFacetList
privateinherited

Definition at line 285 of file G4TessellatedSolid.hh.

Referenced by G4TessellatedSolid::AddFacet().

◆ fFacets

std::vector<G4VFacet*> G4TessellatedSolid::fFacets
privateinherited

◆ fGeometryType

G4GeometryType G4ExtrudedSolid::fGeometryType
private

Definition at line 190 of file G4ExtrudedSolid.hh.

Referenced by GetEntityType(), operator=(), and StreamInfo().

◆ fInsides

G4SurfBits G4TessellatedSolid::fInsides
privateinherited

◆ fIsConvex

G4bool G4ExtrudedSolid::fIsConvex = false
private

Definition at line 189 of file G4ExtrudedSolid.hh.

Referenced by DistanceToOut(), G4ExtrudedSolid(), operator=(), and StreamInfo().

◆ fKOffsets

std::vector<G4TwoVector> G4ExtrudedSolid::fKOffsets
private

Definition at line 201 of file G4ExtrudedSolid.hh.

Referenced by ComputeProjectionParameters(), operator=(), and ProjectPoint().

◆ fKScales

std::vector<G4double> G4ExtrudedSolid::fKScales
private

Definition at line 199 of file G4ExtrudedSolid.hh.

Referenced by ComputeProjectionParameters(), operator=(), and ProjectPoint().

◆ fLengths

std::vector<G4double> G4ExtrudedSolid::fLengths
private

◆ fLines

std::vector<line> G4ExtrudedSolid::fLines
private

Definition at line 196 of file G4ExtrudedSolid.hh.

Referenced by ComputeLateralPlanes(), and operator=().

◆ fMaxExtent

G4ThreeVector G4TessellatedSolid::fMaxExtent
privateinherited

◆ fMaxTries

G4int G4TessellatedSolid::fMaxTries
privateinherited

◆ fMinExtent

G4ThreeVector G4TessellatedSolid::fMinExtent
privateinherited

◆ fNv

G4int G4ExtrudedSolid::fNv
private

◆ fNz

G4int G4ExtrudedSolid::fNz
private

◆ fOffset0s

std::vector<G4TwoVector> G4ExtrudedSolid::fOffset0s
private

Definition at line 202 of file G4ExtrudedSolid.hh.

Referenced by ComputeProjectionParameters(), operator=(), and ProjectPoint().

◆ fPlanes

std::vector<plane> G4ExtrudedSolid::fPlanes
private

◆ fPolygon

std::vector<G4TwoVector> G4ExtrudedSolid::fPolygon
private

◆ fpPolyhedron

G4Polyhedron* G4TessellatedSolid::fpPolyhedron = nullptr
mutableprivateinherited

◆ fRandir

std::vector<G4ThreeVector> G4TessellatedSolid::fRandir
privateinherited

◆ fRebuildPolyhedron

G4bool G4TessellatedSolid::fRebuildPolyhedron = false
mutableprivateinherited

◆ fScale0s

std::vector<G4double> G4ExtrudedSolid::fScale0s
private

Definition at line 200 of file G4ExtrudedSolid.hh.

Referenced by ComputeProjectionParameters(), operator=(), and ProjectPoint().

◆ fshapeName

G4String G4VSolid::fshapeName
privateinherited

Definition at line 312 of file G4VSolid.hh.

Referenced by G4VSolid::operator=(), and G4VSolid::SetName().

◆ fSolidClosed

G4bool G4TessellatedSolid::fSolidClosed = false
privateinherited

◆ fSolidType

G4int G4ExtrudedSolid::fSolidType = 0
private

◆ fSurfaceArea

G4double G4TessellatedSolid::fSurfaceArea = 0.0
privateinherited

◆ fTriangles

std::vector< std::vector<G4int> > G4ExtrudedSolid::fTriangles
private

Definition at line 188 of file G4ExtrudedSolid.hh.

Referenced by AddGeneralPolygonFacets(), Inside(), MakeFacets(), and operator=().

◆ fVertexList

std::vector<G4ThreeVector> G4TessellatedSolid::fVertexList
privateinherited

◆ fVoxels

G4Voxelizer G4TessellatedSolid::fVoxels
privateinherited

◆ fZSections

std::vector<ZSection> G4ExtrudedSolid::fZSections
private

◆ kCarTolerance

G4double G4VSolid::kCarTolerance
protectedinherited

Definition at line 299 of file G4VSolid.hh.

Referenced by G4TessellatedSolid::AddFacet(), G4Polycone::CalculateExtent(), G4Polyhedra::CalculateExtent(), G4Tet::CheckDegeneracy(), G4Para::CheckParameters(), G4Trd::CheckParameters(), G4Ellipsoid::CheckParameters(), G4EllipticalTube::CheckParameters(), G4GenericTrap::ComputeIsTwisted(), G4Polyhedra::Create(), G4GenericPolycone::Create(), G4Polycone::Create(), G4CutTubs::CreatePolyhedron(), G4TessellatedSolid::CreateVertexList(), G4VCSGfaceted::DistanceTo(), G4Sphere::DistanceToIn(), G4Ellipsoid::DistanceToIn(), G4Hype::DistanceToIn(), G4Paraboloid::DistanceToIn(), G4VCSGfaceted::DistanceToIn(), G4TessellatedSolid::DistanceToInCore(), G4Cons::DistanceToOut(), G4CutTubs::DistanceToOut(), G4Sphere::DistanceToOut(), G4Torus::DistanceToOut(), G4Tubs::DistanceToOut(), G4GenericTrap::DistanceToOut(), G4Hype::DistanceToOut(), G4Paraboloid::DistanceToOut(), G4VCSGfaceted::DistanceToOut(), G4TessellatedSolid::DistanceToOutCandidates(), G4TessellatedSolid::DistanceToOutCore(), G4TessellatedSolid::DistanceToOutNoVoxels(), G4GenericTrap::DistToPlane(), G4GenericTrap::DistToTriangle(), G4Box::G4Box(), G4Cons::G4Cons(), G4CutTubs::G4CutTubs(), G4EllipticalCone::G4EllipticalCone(), G4ExtrudedSolid(), G4GenericTrap::G4GenericTrap(), G4Hype::G4Hype(), G4Para::G4Para(), G4Sphere::G4Sphere(), G4Tet::G4Tet(), G4Trap::G4Trap(), G4Tubs::G4Tubs(), G4UnionSolid::G4UnionSolid(), G4VSolid::G4VSolid(), G4VTwistedFaceted::G4VTwistedFaceted(), G4GenericPolycone::GetPointOnSurface(), G4Polycone::GetPointOnSurface(), G4UnionSolid::Init(), G4Orb::Initialize(), G4TessellatedSolid::Initialize(), G4SubtractionSolid::Inside(), G4Hype::Inside(), G4Paraboloid::Inside(), G4VCSGfaceted::Inside(), G4VTwistedFaceted::Inside(), G4TessellatedSolid::InsideNoVoxels(), G4GenericTrap::InsidePolygone(), G4TessellatedSolid::InsideVoxels(), G4CutTubs::IsCrossingCutPlanes(), G4GenericTrap::IsSegCrossingZ(), G4Trap::MakePlane(), G4GenericTrap::NormalToPlane(), G4VSolid::operator=(), G4TessellatedSolid::SafetyFromInside(), G4TessellatedSolid::SafetyFromOutside(), G4Torus::SetAllParameters(), G4Polycone::SetOriginalParameters(), G4Polyhedra::SetOriginalParameters(), G4Box::SetXHalfLength(), G4Box::SetYHalfLength(), G4Box::SetZHalfLength(), G4Torus::SurfaceNormal(), G4GenericTrap::SurfaceNormal(), and G4Paraboloid::SurfaceNormal().

◆ kCarToleranceHalf

G4double G4TessellatedSolid::kCarToleranceHalf
protectedinherited

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