Geant4  10.03.p01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 ()
 
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 65 of file G4BoundingEnvelope.hh.

Constructor & Destructor Documentation

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

Definition at line 51 of file G4BoundingEnvelope.cc.

53  : fMin(pMin), fMax(pMax), fPolygons(0)
54 {
55  // Check correctness of bounding box
56  //
57  CheckBoundingBox();
58 }
G4BoundingEnvelope::G4BoundingEnvelope ( const std::vector< const G4ThreeVectorList * > &  polygons)

Definition at line 65 of file G4BoundingEnvelope.cc.

66  : fPolygons(&polygons)
67 {
68  // Check correctness of polygons
69  //
70  CheckBoundingPolygons();
71 
72  // Set bounding box
73  //
74  G4double xmin = kInfinity, ymin = kInfinity, zmin = kInfinity;
75  G4double xmax = -kInfinity, ymax = -kInfinity, zmax = -kInfinity;
76  std::vector<const G4ThreeVectorList*>::const_iterator ibase;
77  for (ibase = fPolygons->begin(); ibase != fPolygons->end(); ibase++)
78  {
79  std::vector<G4ThreeVector>::const_iterator ipoint;
80  for (ipoint = (*ibase)->begin(); ipoint != (*ibase)->end(); ipoint++)
81  {
82  G4double x = ipoint->x();
83  if (x < xmin) xmin = x;
84  if (x > xmax) xmax = x;
85  G4double y = ipoint->y();
86  if (y < ymin) ymin = y;
87  if (y > ymax) ymax = y;
88  G4double z = ipoint->z();
89  if (z < zmin) zmin = z;
90  if (z > zmax) zmax = z;
91  }
92  }
93  fMin.set(xmin,ymin,zmin);
94  fMax.set(xmax,ymax,zmax);
95 
96  // Check correctness of bounding box
97  //
98  CheckBoundingBox();
99 }
void set(double x, double y, double z)
static const G4double kInfinity
Definition: geomdefs.hh:42
double G4double
Definition: G4Types.hh:76

Here is the call graph for this function:

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

Definition at line 106 of file G4BoundingEnvelope.cc.

109  : fMin(pMin), fMax(pMax), fPolygons(&polygons)
110 {
111  // Check correctness of bounding box and polygons
112  //
113  CheckBoundingBox();
114  CheckBoundingPolygons();
115 }
G4BoundingEnvelope::~G4BoundingEnvelope ( )

Definition at line 121 of file G4BoundingEnvelope.cc.

122 {
123 }

Member Function Documentation

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

Definition at line 198 of file G4BoundingEnvelope.cc.

202 {
203  pMin = kInfinity;
204  pMax = -kInfinity;
205  G4double xminlim = pVoxelLimits.GetMinXExtent();
206  G4double xmaxlim = pVoxelLimits.GetMaxXExtent();
207  G4double yminlim = pVoxelLimits.GetMinYExtent();
208  G4double ymaxlim = pVoxelLimits.GetMaxYExtent();
209  G4double zminlim = pVoxelLimits.GetMinZExtent();
210  G4double zmaxlim = pVoxelLimits.GetMaxZExtent();
211 
212  // Special case of pure translation
213  //
214  if (pTransform3D.xx()==1 && pTransform3D.yy()==1 && pTransform3D.zz()==1)
215  {
216  G4double xmin = fMin.x() + pTransform3D.dx();
217  G4double xmax = fMax.x() + pTransform3D.dx();
218  G4double ymin = fMin.y() + pTransform3D.dy();
219  G4double ymax = fMax.y() + pTransform3D.dy();
220  G4double zmin = fMin.z() + pTransform3D.dz();
221  G4double zmax = fMax.z() + pTransform3D.dz();
222 
223  if (xmin-kCarTolerance > xmaxlim) return true;
224  if (xmax+kCarTolerance < xminlim) return true;
225  if (ymin-kCarTolerance > ymaxlim) return true;
226  if (ymax+kCarTolerance < yminlim) return true;
227  if (zmin-kCarTolerance > zmaxlim) return true;
228  if (zmax+kCarTolerance < zminlim) return true;
229 
230  if (xmin >= xminlim && xmax <= xmaxlim &&
231  ymin >= yminlim && ymax <= ymaxlim &&
232  zmin >= zminlim && zmax <= zmaxlim)
233  {
234  if (pAxis == kXAxis)
235  {
236  pMin = (xmin-kCarTolerance < xminlim) ? xminlim : xmin;
237  pMax = (xmax+kCarTolerance > xmaxlim) ? xmaxlim : xmax;
238  }
239  else if (pAxis == kYAxis)
240  {
241  pMin = (ymin-kCarTolerance < yminlim) ? yminlim : ymin;
242  pMax = (ymax+kCarTolerance > ymaxlim) ? ymaxlim : ymax;
243  }
244  else if (pAxis == kZAxis)
245  {
246  pMin = (zmin-kCarTolerance < zminlim) ? zminlim : zmin;
247  pMax = (zmax+kCarTolerance > zmaxlim) ? zmaxlim : zmax;
248  }
249  pMin -= kCarTolerance;
250  pMax += kCarTolerance;
251  return true;
252  }
253  }
254 
255  // Find max scale factor of the transformation, set delta
256  // equal to kCarTolerance multiplied by the scale factor
257  //
258  G4double scale = FindScaleFactor(pTransform3D);
259  G4double delta = kCarTolerance*scale;
260 
261  // Set the sphere surrounding the bounding box
262  //
263  G4Point3D center = pTransform3D*G4Point3D(0.5*(fMin+fMax));
264  G4double radius = 0.5*scale*(fMax-fMin).mag() + delta;
265 
266  // Check if the sphere surrounding the bounding box is outside
267  // the voxel limits
268  //
269  if (center.x()-radius > xmaxlim) return true;
270  if (center.y()-radius > ymaxlim) return true;
271  if (center.z()-radius > zmaxlim) return true;
272  if (center.x()+radius < xminlim) return true;
273  if (center.y()+radius < yminlim) return true;
274  if (center.z()+radius < zminlim) return true;
275  return false;
276 }
double yy() const
Definition: Transform3D.h:264
static const G4double kInfinity
Definition: geomdefs.hh:42
G4double GetMinYExtent() const
double x() const
double dx() const
Definition: Transform3D.h:279
HepGeom::Point3D< G4double > G4Point3D
Definition: G4Point3D.hh:35
double zz() const
Definition: Transform3D.h:276
double z() const
G4double GetMaxXExtent() const
G4double GetMinZExtent() const
const G4double kCarTolerance
double dy() const
Definition: Transform3D.h:282
G4double GetMinXExtent() const
double dz() const
Definition: Transform3D.h:285
G4double GetMaxZExtent() const
double y() const
double xx() const
Definition: Transform3D.h:252
G4double GetMaxYExtent() const
double G4double
Definition: G4Types.hh:76

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 283 of file G4BoundingEnvelope.cc.

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

Here is the call graph for this function:

Here is the caller graph for this function:


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