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

#include <G4BoundingEnvelope.hh>

Public Member Functions

 G4BoundingEnvelope (const G4ThreeVector &pMin, const G4ThreeVector &pMax)
 
 G4BoundingEnvelope (const std::vector< const G4ThreeVectorList * > &polygons)
 
 G4BoundingEnvelope (const G4ThreeVector &pMin, const G4ThreeVector &pMax, const std::vector< const G4ThreeVectorList * > &polygons)
 
 ~G4BoundingEnvelope ()=default
 
G4bool BoundingBoxVsVoxelLimits (const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
 

Detailed Description

Definition at line 58 of file G4BoundingEnvelope.hh.

Constructor & Destructor Documentation

◆ G4BoundingEnvelope() [1/3]

G4BoundingEnvelope::G4BoundingEnvelope ( const G4ThreeVector pMin,
const G4ThreeVector pMax 
)

Definition at line 45 of file G4BoundingEnvelope.cc.

47 : fMin(pMin), fMax(pMax)
48{
49 // Check correctness of bounding box
50 //
51 CheckBoundingBox();
52}

◆ G4BoundingEnvelope() [2/3]

G4BoundingEnvelope::G4BoundingEnvelope ( const std::vector< const G4ThreeVectorList * > &  polygons)

Definition at line 58 of file G4BoundingEnvelope.cc.

60 : fPolygons(&polygons)
61{
62 // Check correctness of polygons
63 //
64 CheckBoundingPolygons();
65
66 // Set bounding box
67 //
68 G4double xmin = kInfinity, ymin = kInfinity, zmin = kInfinity;
69 G4double xmax = -kInfinity, ymax = -kInfinity, zmax = -kInfinity;
70 for (auto ibase = fPolygons->cbegin(); ibase != fPolygons->cend(); ++ibase)
71 {
72 for (auto ipoint = (*ibase)->cbegin(); ipoint != (*ibase)->cend(); ++ipoint)
73 {
74 G4double x = ipoint->x();
75 if (x < xmin) xmin = x;
76 if (x > xmax) xmax = x;
77 G4double y = ipoint->y();
78 if (y < ymin) ymin = y;
79 if (y > ymax) ymax = y;
80 G4double z = ipoint->z();
81 if (z < zmin) zmin = z;
82 if (z > zmax) zmax = z;
83 }
84 }
85 fMin.set(xmin,ymin,zmin);
86 fMax.set(xmax,ymax,zmax);
87
88 // Check correctness of bounding box
89 //
90 CheckBoundingBox();
91}
double G4double
Definition: G4Types.hh:83
void set(double x, double y, double z)

◆ G4BoundingEnvelope() [3/3]

G4BoundingEnvelope::G4BoundingEnvelope ( const G4ThreeVector pMin,
const G4ThreeVector pMax,
const std::vector< const G4ThreeVectorList * > &  polygons 
)

Definition at line 97 of file G4BoundingEnvelope.cc.

101 : fMin(pMin), fMax(pMax), fPolygons(&polygons)
102{
103 // Check correctness of bounding box and polygons
104 //
105 CheckBoundingBox();
106 CheckBoundingPolygons();
107}

◆ ~G4BoundingEnvelope()

G4BoundingEnvelope::~G4BoundingEnvelope ( )
default

Member Function Documentation

◆ BoundingBoxVsVoxelLimits()

G4bool G4BoundingEnvelope::BoundingBoxVsVoxelLimits ( const EAxis  pAxis,
const G4VoxelLimits pVoxelLimits,
const G4Transform3D pTransform3D,
G4double pMin,
G4double pMax 
) const

Definition at line 181 of file G4BoundingEnvelope.cc.

186{
187 pMin = kInfinity;
188 pMax = -kInfinity;
189 G4double xminlim = pVoxelLimits.GetMinXExtent();
190 G4double xmaxlim = pVoxelLimits.GetMaxXExtent();
191 G4double yminlim = pVoxelLimits.GetMinYExtent();
192 G4double ymaxlim = pVoxelLimits.GetMaxYExtent();
193 G4double zminlim = pVoxelLimits.GetMinZExtent();
194 G4double zmaxlim = pVoxelLimits.GetMaxZExtent();
195
196 // Special case of pure translation
197 //
198 if (pTransform3D.xx()==1 && pTransform3D.yy()==1 && pTransform3D.zz()==1)
199 {
200 G4double xmin = fMin.x() + pTransform3D.dx();
201 G4double xmax = fMax.x() + pTransform3D.dx();
202 G4double ymin = fMin.y() + pTransform3D.dy();
203 G4double ymax = fMax.y() + pTransform3D.dy();
204 G4double zmin = fMin.z() + pTransform3D.dz();
205 G4double zmax = fMax.z() + pTransform3D.dz();
206
207 if (xmin-kCarTolerance > xmaxlim) return true;
208 if (xmax+kCarTolerance < xminlim) return true;
209 if (ymin-kCarTolerance > ymaxlim) return true;
210 if (ymax+kCarTolerance < yminlim) return true;
211 if (zmin-kCarTolerance > zmaxlim) return true;
212 if (zmax+kCarTolerance < zminlim) return true;
213
214 if (xmin >= xminlim && xmax <= xmaxlim &&
215 ymin >= yminlim && ymax <= ymaxlim &&
216 zmin >= zminlim && zmax <= zmaxlim)
217 {
218 if (pAxis == kXAxis)
219 {
220 pMin = (xmin-kCarTolerance < xminlim) ? xminlim : xmin;
221 pMax = (xmax+kCarTolerance > xmaxlim) ? xmaxlim : xmax;
222 }
223 else if (pAxis == kYAxis)
224 {
225 pMin = (ymin-kCarTolerance < yminlim) ? yminlim : ymin;
226 pMax = (ymax+kCarTolerance > ymaxlim) ? ymaxlim : ymax;
227 }
228 else if (pAxis == kZAxis)
229 {
230 pMin = (zmin-kCarTolerance < zminlim) ? zminlim : zmin;
231 pMax = (zmax+kCarTolerance > zmaxlim) ? zmaxlim : zmax;
232 }
233 pMin -= kCarTolerance;
234 pMax += kCarTolerance;
235 return true;
236 }
237 }
238
239 // Find max scale factor of the transformation, set delta
240 // equal to kCarTolerance multiplied by the scale factor
241 //
242 G4double scale = FindScaleFactor(pTransform3D);
243 G4double delta = kCarTolerance*scale;
244
245 // Set the sphere surrounding the bounding box
246 //
247 G4Point3D center = pTransform3D*G4Point3D(0.5*(fMin+fMax));
248 G4double radius = 0.5*scale*(fMax-fMin).mag() + delta;
249
250 // Check if the sphere surrounding the bounding box is outside
251 // the voxel limits
252 //
253 if (center.x()-radius > xmaxlim) return true;
254 if (center.y()-radius > ymaxlim) return true;
255 if (center.z()-radius > zmaxlim) return true;
256 if (center.x()+radius < xminlim) return true;
257 if (center.y()+radius < yminlim) return true;
258 if (center.z()+radius < zminlim) return true;
259 return false;
260}
const G4double kCarTolerance
HepGeom::Point3D< G4double > G4Point3D
Definition: G4Point3D.hh:34
double z() const
double x() const
double y() const
G4double GetMinZExtent() const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMinYExtent() const
G4double GetMinXExtent() const
G4double GetMaxXExtent() const
double dy() const
Definition: Transform3D.h:287
double zz() const
Definition: Transform3D.h:281
double dz() const
Definition: Transform3D.h:290
double dx() const
Definition: Transform3D.h:284
double xx() const
Definition: Transform3D.h:257
double yy() const
Definition: Transform3D.h:269
@ kYAxis
Definition: geomdefs.hh:56
@ kXAxis
Definition: geomdefs.hh:55
@ kZAxis
Definition: geomdefs.hh:57

Referenced by G4Cons::CalculateExtent(), G4CutTubs::CalculateExtent(), G4Orb::CalculateExtent(), G4Para::CalculateExtent(), G4Torus::CalculateExtent(), G4Trap::CalculateExtent(), G4Trd::CalculateExtent(), G4Tubs::CalculateExtent(), G4EllipticalCone::CalculateExtent(), G4EllipticalTube::CalculateExtent(), G4ExtrudedSolid::CalculateExtent(), G4GenericPolycone::CalculateExtent(), G4GenericTrap::CalculateExtent(), G4Polycone::CalculateExtent(), G4Polyhedra::CalculateExtent(), G4TessellatedSolid::CalculateExtent(), and G4Tet::CalculateExtent().

◆ CalculateExtent()

G4bool G4BoundingEnvelope::CalculateExtent ( const EAxis  pAxis,
const G4VoxelLimits pVoxelLimits,
const G4Transform3D pTransform3D,
G4double pMin,
G4double pMax 
) const

Definition at line 267 of file G4BoundingEnvelope.cc.

271{
272 pMin = kInfinity;
273 pMax = -kInfinity;
274 G4double xminlim = pVoxelLimits.GetMinXExtent();
275 G4double xmaxlim = pVoxelLimits.GetMaxXExtent();
276 G4double yminlim = pVoxelLimits.GetMinYExtent();
277 G4double ymaxlim = pVoxelLimits.GetMaxYExtent();
278 G4double zminlim = pVoxelLimits.GetMinZExtent();
279 G4double zmaxlim = pVoxelLimits.GetMaxZExtent();
280
281 // Special case of pure translation
282 //
283 if (pTransform3D.xx()==1 && pTransform3D.yy()==1 && pTransform3D.zz()==1)
284 {
285 G4double xmin = fMin.x() + pTransform3D.dx();
286 G4double xmax = fMax.x() + pTransform3D.dx();
287 G4double ymin = fMin.y() + pTransform3D.dy();
288 G4double ymax = fMax.y() + pTransform3D.dy();
289 G4double zmin = fMin.z() + pTransform3D.dz();
290 G4double zmax = fMax.z() + pTransform3D.dz();
291
292 if (xmin-kCarTolerance > xmaxlim) return false;
293 if (xmax+kCarTolerance < xminlim) return false;
294 if (ymin-kCarTolerance > ymaxlim) return false;
295 if (ymax+kCarTolerance < yminlim) return false;
296 if (zmin-kCarTolerance > zmaxlim) return false;
297 if (zmax+kCarTolerance < zminlim) return false;
298
299 if (fPolygons == nullptr)
300 {
301 if (pAxis == kXAxis)
302 {
303 pMin = (xmin-kCarTolerance < xminlim) ? xminlim : xmin;
304 pMax = (xmax+kCarTolerance > xmaxlim) ? xmaxlim : xmax;
305 }
306 else if (pAxis == kYAxis)
307 {
308 pMin = (ymin-kCarTolerance < yminlim) ? yminlim : ymin;
309 pMax = (ymax+kCarTolerance > ymaxlim) ? ymaxlim : ymax;
310 }
311 else if (pAxis == kZAxis)
312 {
313 pMin = (zmin-kCarTolerance < zminlim) ? zminlim : zmin;
314 pMax = (zmax+kCarTolerance > zmaxlim) ? zmaxlim : zmax;
315 }
316 pMin -= kCarTolerance;
317 pMax += kCarTolerance;
318 return true;
319 }
320 }
321
322 // Find max scale factor of the transformation, set delta
323 // equal to kCarTolerance multiplied by the scale factor
324 //
325 G4double scale = FindScaleFactor(pTransform3D);
326 G4double delta = kCarTolerance*scale;
327
328 // Set the sphere surrounding the bounding box
329 //
330 G4Point3D center = pTransform3D*G4Point3D(0.5*(fMin+fMax));
331 G4double radius = 0.5*scale*(fMax-fMin).mag() + delta;
332
333 // Check if the sphere surrounding the bounding box is within
334 // the voxel limits, if so then transform only one coordinate
335 //
336 if (center.x()-radius >= xminlim && center.x()+radius <= xmaxlim &&
337 center.y()-radius >= yminlim && center.y()+radius <= ymaxlim &&
338 center.z()-radius >= zminlim && center.z()+radius <= zmaxlim )
339 {
340 G4double cx, cy, cz, cd;
341 if (pAxis == kXAxis)
342 {
343 cx = pTransform3D.xx();
344 cy = pTransform3D.xy();
345 cz = pTransform3D.xz();
346 cd = pTransform3D.dx();
347 }
348 else if (pAxis == kYAxis)
349 {
350 cx = pTransform3D.yx();
351 cy = pTransform3D.yy();
352 cz = pTransform3D.yz();
353 cd = pTransform3D.dy();
354 }
355 else if (pAxis == kZAxis)
356 {
357 cx = pTransform3D.zx();
358 cy = pTransform3D.zy();
359 cz = pTransform3D.zz();
360 cd = pTransform3D.dz();
361 }
362 else
363 {
364 cx = cy = cz = cd = kInfinity;
365 }
366 G4double emin = kInfinity, emax = -kInfinity;
367 if (fPolygons == nullptr)
368 {
369 G4double coor;
370 coor = cx*fMin.x() + cy*fMin.y() + cz*fMin.z() + cd;
371 if (coor < emin) emin = coor;
372 if (coor > emax) emax = coor;
373 coor = cx*fMax.x() + cy*fMin.y() + cz*fMin.z() + cd;
374 if (coor < emin) emin = coor;
375 if (coor > emax) emax = coor;
376 coor = cx*fMax.x() + cy*fMax.y() + cz*fMin.z() + cd;
377 if (coor < emin) emin = coor;
378 if (coor > emax) emax = coor;
379 coor = cx*fMin.x() + cy*fMax.y() + cz*fMin.z() + cd;
380 if (coor < emin) emin = coor;
381 if (coor > emax) emax = coor;
382 coor = cx*fMin.x() + cy*fMin.y() + cz*fMax.z() + cd;
383 if (coor < emin) emin = coor;
384 if (coor > emax) emax = coor;
385 coor = cx*fMax.x() + cy*fMin.y() + cz*fMax.z() + cd;
386 if (coor < emin) emin = coor;
387 if (coor > emax) emax = coor;
388 coor = cx*fMax.x() + cy*fMax.y() + cz*fMax.z() + cd;
389 if (coor < emin) emin = coor;
390 if (coor > emax) emax = coor;
391 coor = cx*fMin.x() + cy*fMax.y() + cz*fMax.z() + cd;
392 if (coor < emin) emin = coor;
393 if (coor > emax) emax = coor;
394 }
395 else
396 {
397 for (auto ibase=fPolygons->cbegin(); ibase!=fPolygons->cend(); ++ibase)
398 {
399 for (auto ipoint=(*ibase)->cbegin(); ipoint!=(*ibase)->cend(); ++ipoint)
400 {
401 G4double coor = ipoint->x()*cx + ipoint->y()*cy + ipoint->z()*cz + cd;
402 if (coor < emin) emin = coor;
403 if (coor > emax) emax = coor;
404 }
405 }
406 }
407 pMin = emin - delta;
408 pMax = emax + delta;
409 return true;
410 }
411
412 // Check if the sphere surrounding the bounding box is outside
413 // the voxel limits
414 //
415 if (center.x()-radius > xmaxlim) return false;
416 if (center.y()-radius > ymaxlim) return false;
417 if (center.z()-radius > zmaxlim) return false;
418 if (center.x()+radius < xminlim) return false;
419 if (center.y()+radius < yminlim) return false;
420 if (center.z()+radius < zminlim) return false;
421
422 // Transform polygons
423 //
424 std::vector<G4Point3D> vertices;
425 std::vector<std::pair<G4int, G4int>> bases;
426 TransformVertices(pTransform3D, vertices, bases);
427 std::size_t nbases = bases.size();
428
429 // Create adjusted G4VoxelLimits box. New limits are extended by
430 // delta, kCarTolerance multiplied by max scale factor of
431 // the transformation
432 //
433 EAxis axis[] = { kXAxis, kYAxis, kZAxis };
434 G4VoxelLimits limits; // default is unlimited
435 for (auto i=0; i<3; ++i)
436 {
437 if (pVoxelLimits.IsLimited(axis[i]))
438 {
439 G4double emin = pVoxelLimits.GetMinExtent(axis[i]) - delta;
440 G4double emax = pVoxelLimits.GetMaxExtent(axis[i]) + delta;
441 limits.AddLimit(axis[i], emin, emax);
442 }
443 }
444
445 // Main loop along the set of prisms
446 //
447 G4Polygon3D baseA, baseB;
448 G4Segment3D extent;
449 extent.first = G4Point3D( kInfinity, kInfinity, kInfinity);
450 extent.second = G4Point3D(-kInfinity,-kInfinity,-kInfinity);
451 for (std::size_t k=0; k<nbases-1; ++k)
452 {
453 baseA.resize(bases[k].second);
454 for (G4int i = 0; i < bases[k].second; ++i)
455 baseA[i] = vertices[bases[k].first + i];
456
457 baseB.resize(bases[k+1].second);
458 for (G4int i = 0; i < bases[k+1].second; ++i)
459 baseB[i] = vertices[bases[k+1].first + i];
460
461 // Find bounding box of current prism
462 G4Segment3D prismAABB;
463 GetPrismAABB(baseA, baseB, prismAABB);
464
465 // Check if prismAABB is completely within the voxel limits
466 if (prismAABB.first.x() >= limits.GetMinXExtent() &&
467 prismAABB.first.y() >= limits.GetMinYExtent() &&
468 prismAABB.first.z() >= limits.GetMinZExtent() &&
469 prismAABB.second.x()<= limits.GetMaxXExtent() &&
470 prismAABB.second.y()<= limits.GetMaxYExtent() &&
471 prismAABB.second.z()<= limits.GetMaxZExtent())
472 {
473 if (extent.first.x() > prismAABB.first.x())
474 extent.first.setX( prismAABB.first.x() );
475 if (extent.first.y() > prismAABB.first.y())
476 extent.first.setY( prismAABB.first.y() );
477 if (extent.first.z() > prismAABB.first.z())
478 extent.first.setZ( prismAABB.first.z() );
479 if (extent.second.x() < prismAABB.second.x())
480 extent.second.setX(prismAABB.second.x());
481 if (extent.second.y() < prismAABB.second.y())
482 extent.second.setY(prismAABB.second.y());
483 if (extent.second.z() < prismAABB.second.z())
484 extent.second.setZ(prismAABB.second.z());
485 continue;
486 }
487
488 // Check if prismAABB is outside the voxel limits
489 if (prismAABB.first.x() > limits.GetMaxXExtent()) continue;
490 if (prismAABB.first.y() > limits.GetMaxYExtent()) continue;
491 if (prismAABB.first.z() > limits.GetMaxZExtent()) continue;
492 if (prismAABB.second.x() < limits.GetMinXExtent()) continue;
493 if (prismAABB.second.y() < limits.GetMinYExtent()) continue;
494 if (prismAABB.second.z() < limits.GetMinZExtent()) continue;
495
496 // Clip edges of the prism by adjusted G4VoxelLimits box
497 std::vector<G4Segment3D> vecEdges;
498 CreateListOfEdges(baseA, baseB, vecEdges);
499 if (ClipEdgesByVoxel(vecEdges, limits, extent)) continue;
500
501 // Some edges of the prism are completely outside of the voxel
502 // limits, clip selected edges (see bits) of adjusted G4VoxelLimits
503 // by the prism
504 G4int bits = 0x000;
505 if (limits.GetMinXExtent() < prismAABB.first.x())
506 bits |= 0x988; // 1001 1000 1000
507 if (limits.GetMaxXExtent() > prismAABB.second.x())
508 bits |= 0x622; // 0110 0010 0010
509
510 if (limits.GetMinYExtent() < prismAABB.first.y())
511 bits |= 0x311; // 0011 0001 0001
512 if (limits.GetMaxYExtent() > prismAABB.second.y())
513 bits |= 0xC44; // 1100 0100 0100
514
515 if (limits.GetMinZExtent() < prismAABB.first.z())
516 bits |= 0x00F; // 0000 0000 1111
517 if (limits.GetMaxZExtent() > prismAABB.second.z())
518 bits |= 0x0F0; // 0000 1111 0000
519 if (bits == 0xFFF) continue;
520
521 std::vector<G4Plane3D> vecPlanes;
522 CreateListOfPlanes(baseA, baseB, vecPlanes);
523 ClipVoxelByPlanes(bits, limits, vecPlanes, prismAABB, extent);
524 } // End of the main loop
525
526 // Final adjustment of the extent
527 //
528 G4double emin = 0, emax = 0;
529 if (pAxis == kXAxis) { emin = extent.first.x(); emax = extent.second.x(); }
530 if (pAxis == kYAxis) { emin = extent.first.y(); emax = extent.second.y(); }
531 if (pAxis == kZAxis) { emin = extent.first.z(); emax = extent.second.z(); }
532
533 if (emin > emax) return false;
534 emin -= delta;
535 emax += delta;
536 G4double minlim = pVoxelLimits.GetMinExtent(pAxis);
537 G4double maxlim = pVoxelLimits.GetMaxExtent(pAxis);
538 pMin = (emin < minlim) ? minlim-kCarTolerance : emin;
539 pMax = (emax > maxlim) ? maxlim+kCarTolerance : emax;
540 return true;
541}
std::pair< G4Point3D, G4Point3D > G4Segment3D
std::vector< G4Point3D > G4Polygon3D
int G4int
Definition: G4Types.hh:85
G4double GetMinExtent(const EAxis pAxis) const
void AddLimit(const EAxis pAxis, const G4double pMin, const G4double pMax)
G4double GetMaxExtent(const EAxis pAxis) const
G4bool IsLimited() const
double yz() const
Definition: Transform3D.h:272
double xy() const
Definition: Transform3D.h:260
double zx() const
Definition: Transform3D.h:275
double yx() const
Definition: Transform3D.h:266
double zy() const
Definition: Transform3D.h:278
double xz() const
Definition: Transform3D.h:263
EAxis
Definition: geomdefs.hh:54

Referenced by G4MultiUnion::CalculateExtent(), G4ScaledSolid::CalculateExtent(), G4Box::CalculateExtent(), G4Cons::CalculateExtent(), G4CutTubs::CalculateExtent(), G4Orb::CalculateExtent(), G4Para::CalculateExtent(), G4Sphere::CalculateExtent(), G4Torus::CalculateExtent(), G4Trap::CalculateExtent(), G4Trd::CalculateExtent(), G4Tubs::CalculateExtent(), G4Ellipsoid::CalculateExtent(), G4EllipticalCone::CalculateExtent(), G4EllipticalTube::CalculateExtent(), G4ExtrudedSolid::CalculateExtent(), G4GenericPolycone::CalculateExtent(), G4GenericTrap::CalculateExtent(), G4Hype::CalculateExtent(), G4Paraboloid::CalculateExtent(), G4Polycone::CalculateExtent(), G4Polyhedra::CalculateExtent(), G4TessellatedSolid::CalculateExtent(), G4Tet::CalculateExtent(), G4TwistedTubs::CalculateExtent(), and G4VTwistedFaceted::CalculateExtent().


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