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

#include <G4ExtrudedSolid.hh>

+ Inheritance diagram for G4ExtrudedSolid:

Classes

struct  ZSection
 

Public Member Functions

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

Additional Inherited Members

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

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 ( std::size_t 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;
123 G4GeomTools::RemoveRedundantVertices(fPolygon,removedVertices,
124 2*kCarTolerance);
125 if (removedVertices.size() != 0)
126 {
127 std::size_t 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 (std::size_t 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 //
150 if (G4GeomTools::PolygonArea(fPolygon) > 0.)
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 }
171 fIsConvex = G4GeomTools::IsConvex(fPolygon);
172
173 ComputeProjectionParameters();
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
183 ComputeLateralPlanes();
184 }
185}
@ JustWarning
@ FatalException
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:36
bool G4bool
Definition: G4Types.hh:86
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

◆ G4ExtrudedSolid() [2/4]

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

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;
218 G4GeomTools::RemoveRedundantVertices(fPolygon,removedVertices,
219 2*kCarTolerance);
220 if (removedVertices.size() != 0)
221 {
222 std::size_t 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 (std::size_t 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 //
245 if (G4GeomTools::PolygonArea(fPolygon) > 0.)
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 }
267 fIsConvex = G4GeomTools::IsConvex(fPolygon);
268
269 ComputeProjectionParameters();
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
277 ComputeLateralPlanes();
278 }
279}

◆ ~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),
295 fPolygon(rhs.fPolygon), fZSections(rhs.fZSections),
296 fTriangles(rhs.fTriangles), fIsConvex(rhs.fIsConvex),
297 fGeometryType(rhs.fGeometryType),
298 fSolidType(rhs.fSolidType), fPlanes(rhs.fPlanes),
299 fLines(rhs.fLines), fLengths(rhs.fLengths),
300 fKScales(rhs.fKScales), fScale0s(rhs.fScale0s),
301 fKOffsets(rhs.fKOffsets), fOffset0s(rhs.fOffset0s)
302{
303}

Member Function Documentation

◆ 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}
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
double z() const
double x() const
double y() const
void set(double x, double y, double z)
ZSection GetZSection(G4int index) const
G4int GetNofZSections() const
G4int GetNofVertices() const
G4String GetName() const
void DumpInfo() const

Referenced by CalculateExtent().

◆ 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
1457 if (!G4GeomTools::TriangulatePolygon(fPolygon,triangles))
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 = (G4int)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
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

◆ Clone()

G4VSolid * G4ExtrudedSolid::Clone ( ) const
virtual

Reimplemented from G4TessellatedSolid.

Definition at line 850 of file G4ExtrudedSolid.cc.

851{
852 return new G4ExtrudedSolid(*this);
853}

◆ 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 std::size_t np = fPlanes.size();
1227 for (std::size_t 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);
1245 G4double dd = DistanceToPolygonSqr(p);
1246 if (distz > 0) dd += distz*distz;
1247 return std::sqrt(dd);
1248 }
1249 }
1250 }
1251
1252 // General case: use tessellated solid
1254}
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const

◆ 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 std::size_t np = fPlanes.size();
1183 G4double txmin = tzmin, txmax = tzmax;
1184 for (std::size_t 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}
#define DBL_MAX
Definition: templates.hh:62

◆ 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 std::size_t np = fPlanes.size();
1348 for (std::size_t 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}
virtual G4double DistanceToOut(const G4ThreeVector &p) const

◆ 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 std::size_t np = fPlanes.size();
1296 for (std::size_t 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 = (G4int)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}

◆ 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}

◆ GetNofVertices()

G4int G4ExtrudedSolid::GetNofVertices ( ) const
inline

◆ GetNofZSections()

G4int G4ExtrudedSolid::GetNofZSections ( ) const
inline

◆ GetPolygon()

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

◆ GetVertex()

G4TwoVector G4ExtrudedSolid::GetVertex ( G4int  index) const
inline

◆ GetZSection()

ZSection G4ExtrudedSolid::GetZSection ( G4int  index) const
inline

◆ GetZSections()

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

◆ 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 std::size_t np = fPlanes.size();
867 for (std::size_t 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
883 G4double dd = DistanceToPolygonSqr(p) - kCarToleranceHalf*kCarToleranceHalf;
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<(G4int)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}
G4double GetMinYExtent() const
G4double GetMinZExtent() const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMaxXExtent() const
G4double GetMinXExtent() const
@ kInside
Definition: geomdefs.hh:70
@ kOutside
Definition: geomdefs.hh:68
@ kSurface
Definition: geomdefs.hh:69

◆ 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;
320 fPolygon = rhs.fPolygon; fZSections = rhs.fZSections;
321 fTriangles = rhs.fTriangles; fIsConvex = rhs.fIsConvex;
322 fGeometryType = rhs.fGeometryType;
323 fSolidType = rhs.fSolidType; fPlanes = rhs.fPlanes;
324 fLines = rhs.fLines; fLengths = rhs.fLengths;
325 fKScales = rhs.fKScales; fScale0s = rhs.fScale0s;
326 fKOffsets = rhs.fKOffsets; fOffset0s = rhs.fOffset0s;
327
328 return *this;
329}
G4TessellatedSolid & operator=(const G4TessellatedSolid &right)

◆ StreamInfo()

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

Reimplemented from G4TessellatedSolid.

Definition at line 1519 of file G4ExtrudedSolid.cc.

1520{
1521 G4long 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 ( std::size_t 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 ( std::size_t 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}
long G4long
Definition: G4Types.hh:87
#define G4endl
Definition: G4ios.hh:57

◆ 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 (std::size_t 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 (std::size_t 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 G4long 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}
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
Hep3Vector unit() const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const

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