Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4UAdapter.hh
이 파일의 문서화 페이지로 가기
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id:$
28 //
29 //
30 // class G4UAdapter
31 //
32 // Class description:
33 //
34 // Utility class for adapting VecGeom solids API to Geant4 solids.
35 // NOTE: Using protected inheritance since the Adapter is supposed to
36 // be a G4VSolid "implemented-in-terms-of" the VecGeom UnplacedVolume_t.
37 // The choice of protected vs private is due to the fact that we want
38 // to propagate functions further down in the inheritance hierarchy.
39 
40 // Author:
41 // 17.05.17 G.Cosmo: Adapted for G4VSolid from original G4USolids bridge
42 // class and the USolidsAdapter class in VecGeom.
43 // ------------------------------------------------------------------------
44 #ifndef G4UADAPTER_HH
45 #define G4UADAPTER_HH
46 
47 #include "G4ThreeVector.hh"
48 #include "G4VSolid.hh"
49 
50 // Required for inline visualization adapter functions
51 //
52 #include "G4AffineTransform.hh"
53 #include "G4VoxelLimits.hh"
54 #include "G4VGraphicsScene.hh"
55 #include "G4Polyhedron.hh"
56 #include "G4VisExtent.hh"
57 #include "G4BoundingEnvelope.hh"
58 #include "G4AutoLock.hh"
59 
60 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
61 
62 #include <base/Global.h>
63 #include <base/Vector3D.h>
64 
66 
67 template <class UnplacedVolume_t>
68 class G4UAdapter : public G4VSolid, protected UnplacedVolume_t
69 {
70  public:
71 
72  typedef vecgeom::Vector3D<G4double> U3Vector;
73 
74  using UnplacedVolume_t::operator delete;
75  using UnplacedVolume_t::operator new;
76  // VecGeom volumes have special delete/new ("AlignedBase")
77  // and we need to make these functions public again
78 
79  G4UAdapter(const G4String& name)
80  : G4VSolid(name), fRebuildPolyhedron(false), fPolyhedron(0)
81  { kHalfTolerance = 0.5*kCarTolerance; }
82 
83  template <typename... T>
84  G4UAdapter(const G4String& name, const T &... params)
85  : G4VSolid(name), UnplacedVolume_t(params...),
86  fRebuildPolyhedron(false), fPolyhedron(0)
87  { kHalfTolerance = 0.5*kCarTolerance; }
88 
89  virtual ~G4UAdapter();
90 
91  G4bool operator==(const G4UAdapter& s) const;
92  // Return true only if addresses are the same.
93 
94  virtual G4bool CalculateExtent(const EAxis pAxis,
95  const G4VoxelLimits& pVoxelLimit,
96  const G4AffineTransform& pTransform,
97  G4double& pMin, G4double& pMax) const override;
98  // Calculate the minimum and maximum extent of the solid, when under the
99  // specified transform, and within the specified limits. If the solid
100  // is not intersected by the region, return false, else return true.
101 
102  virtual EInside Inside(const G4ThreeVector& p) const override;
103  // Returns kOutside if the point at offset p is outside the shapes
104  // boundaries plus Tolerance/2, kSurface if the point is <= Tolerance/2
105  // from a surface, otherwise kInside.
106 
107  virtual G4ThreeVector SurfaceNormal(const G4ThreeVector& p) const override;
108  // Returns the outwards pointing unit normal of the shape for the
109  // surface closest to the point at offset p.
110 
111  virtual G4double DistanceToIn(const G4ThreeVector& p,
112  const G4ThreeVector& v) const override;
113  // Return the distance along the normalised vector v to the shape,
114  // from the point at offset p. If there is no intersection, return
115  // kInfinity. The first intersection resulting from `leaving' a
116  // surface/volume is discarded. Hence, it is tolerant of points on
117  // the surface of the shape.
118 
119  virtual G4double DistanceToIn(const G4ThreeVector& p) const override;
120  // Calculate the distance to the nearest surface of a shape from an
121  // outside point. The distance can be an underestimate.
122 
123  virtual G4double DistanceToOut(const G4ThreeVector& p,
124  const G4ThreeVector& v,
125  const G4bool calcNorm = false,
126  G4bool* validNorm = 0,
127  G4ThreeVector* n = 0) const override;
128  // Return the distance along the normalised vector v to the shape,
129  // from a point at an offset p inside or on the surface of the shape.
130  // Intersections with surfaces, when the point is < Tolerance/2 from a
131  // surface must be ignored.
132  // If calcNorm==true:
133  // validNorm set true if the solid lies entirely behind or on the
134  // exiting surface.
135  // n set to exiting outwards normal vector (undefined Magnitude).
136  // validNorm set to false if the solid does not lie entirely behind
137  // or on the exiting surface
138  // If calcNorm==false:
139  // validNorm and n are unused.
140  //
141  // Must be called as solid.DistanceToOut(p,v) or by specifying all
142  // the parameters.
143 
144  virtual G4double DistanceToOut(const G4ThreeVector& p) const override;
145  // Calculate the distance to the nearest surface of a shape from an
146  // inside point. The distance can be an underestimate.
147 
149  const G4int n,
150  const G4VPhysicalVolume* pRep) override;
151  // Throw exception if ComputeDimensions called from an illegal
152  // derived class.
153 
154  virtual G4double GetCubicVolume() override;
155  // Returns an estimation of the solid volume in internal units.
156  // This method may be overloaded by derived classes to compute the
157  // exact geometrical quantity for solids where this is possible,
158  // or anyway to cache the computed value.
159  // Note: the computed value is NOT cached.
160 
161  virtual G4double GetSurfaceArea() override;
162  // Return an estimation of the solid surface area in internal units.
163  // This method may be overloaded by derived classes to compute the
164  // exact geometrical quantity for solids where this is possible,
165  // or anyway to cache the computed value.
166  // Note: the computed value is NOT cached.
167 
168  virtual G4ThreeVector GetPointOnSurface() const override;
169  // Returns a random point located on the surface of the solid.
170 
171  virtual G4GeometryType GetEntityType() const override;
172  // Provide identification of the class of an object.
173  // (required for persistency)
174 
175  virtual G4VSolid* Clone() const override;
176  // Returns a pointer of a dynamically allocated copy of the solid.
177  // Returns NULL pointer with warning in case the concrete solid does not
178  // implement this method. The caller has responsibility for ownership.
179 
180  virtual std::ostream& StreamInfo(std::ostream& os) const override;
181  // Dumps contents of the solid to a stream.
182 
183  virtual void DescribeYourselfTo(G4VGraphicsScene& scene) const override;
184  // A "double dispatch" function which identifies the solid
185  // to the graphics scene for visualization.
186 
187  virtual G4VisExtent GetExtent() const override;
188  // Provide extent (bounding box) as possible hint to the graphics view.
189  virtual G4Polyhedron* CreatePolyhedron() const override;
190  // Create Polyhedron used for Visualisation
191  virtual G4Polyhedron* GetPolyhedron() const override;
192  // Smart access function - creates on request and stores for future
193  // access. A null pointer means "not available".
194 
195  public: // without description
196 
197  G4UAdapter(__void__&);
198  // Fake default constructor for usage restricted to direct object
199  // persistency for clients requiring preallocation of memory for
200  // persistifiable objects.
201 
202  G4UAdapter(const G4UAdapter& rhs);
203  G4UAdapter& operator=(const G4UAdapter& rhs);
204  // Copy constructor and assignment operator.
205 
206  public: // VecGeom overridden methods
207 
208  vecgeom::Precision
209  DistanceToOut(U3Vector const &position, U3Vector const &direction,
210  vecgeom::Precision stepMax = kInfinity) const override
211  {
212  return UnplacedVolume_t::DistanceToOut(position, direction, stepMax);
213  }
214 
215  vecgeom::EnumInside
216  Inside(U3Vector const &aPoint) const override
217  {
218  return UnplacedVolume_t::Inside(aPoint);
219  }
220 
221  vecgeom::Precision
222  DistanceToIn(U3Vector const &position, U3Vector const &direction,
223  const vecgeom::Precision step_max = kInfinity) const override
224  {
225  return UnplacedVolume_t::DistanceToIn(position, direction, step_max);
226  }
227 
228  G4bool Normal(U3Vector const &aPoint, U3Vector &aNormal) const override
229  {
230  return UnplacedVolume_t::Normal(aPoint, aNormal);
231  }
232 
233  void Extent(U3Vector &aMin, U3Vector &aMax) const override
234  {
235  return UnplacedVolume_t::Extent(aMin, aMax);
236  }
237 
238  U3Vector SamplePointOnSurface() const override
239  {
240  return UnplacedVolume_t::SamplePointOnSurface();
241  }
242 
243  protected: // data
244 
245  mutable G4bool fRebuildPolyhedron;
246  mutable G4Polyhedron* fPolyhedron;
247 
248  G4double kHalfTolerance; // Cached geometrical tolerance
249 
250  using UnplacedVolume_t::DistanceToOut;
251  using UnplacedVolume_t::DistanceToIn;
252 };
253 
254 // Inline implementations
255 
256 template <class UnplacedVolume_t>
257 G4UAdapter<UnplacedVolume_t>::G4UAdapter(__void__& a)
258  : G4VSolid(a), UnplacedVolume_t(*this),
259  fRebuildPolyhedron(false), fPolyhedron(0),
260  kHalfTolerance(0.5*kCarTolerance)
261 {
262 }
263 
264 template <class UnplacedVolume_t>
265 G4UAdapter<UnplacedVolume_t>::~G4UAdapter()
266 {
267  delete fPolyhedron; fPolyhedron = 0;
268 }
269 
270 template <class UnplacedVolume_t>
272 operator==(const G4UAdapter& rhs) const
273 {
274  return (this == &rhs) ? true : false;
275 }
276 
277 template <class UnplacedVolume_t>
278 G4UAdapter<UnplacedVolume_t>::
279 G4UAdapter(const G4UAdapter& rhs)
280  : G4VSolid(rhs), UnplacedVolume_t(rhs),
281  fRebuildPolyhedron(false), fPolyhedron(0)
282 {
283  kHalfTolerance = 0.5*kCarTolerance;
284 }
285 
286 template <class UnplacedVolume_t>
287 G4UAdapter<UnplacedVolume_t>& G4UAdapter<UnplacedVolume_t>::
288 operator=(const G4UAdapter& rhs)
289 {
290  // Check assignment to self
291  //
292  if (this == &rhs)
293  {
294  return *this;
295  }
296 
297  // Copy base class data
298  //
299  G4VSolid::operator=(rhs);
300  UnplacedVolume_t::operator=(rhs);
301 
302  // Copy data
303  //
304  fRebuildPolyhedron = false;
305  delete fPolyhedron; fPolyhedron = 0;
306  kHalfTolerance = 0.5*kCarTolerance;
307 
308  return *this;
309 }
310 
311 template <class UnplacedVolume_t>
312 EInside G4UAdapter<UnplacedVolume_t>::
313 Inside(const G4ThreeVector& p) const
314 {
315  U3Vector pt(p.x(), p.y(), p.z());
316  vecgeom::EnumInside in_temp;
317  EInside in = kOutside;
318 
319  in_temp = UnplacedVolume_t::Inside(pt);
320 
321  if (in_temp == vecgeom::EnumInside::eInside) in = kInside;
322  else if (in_temp == vecgeom::EnumInside::eSurface) in = kSurface;
323 
324  return in;
325 }
326 
327 template <class UnplacedVolume_t>
328 G4ThreeVector G4UAdapter<UnplacedVolume_t>::
329 SurfaceNormal(const G4ThreeVector& pt) const
330 {
331  U3Vector p(pt.x(), pt.y(), pt.z());
332  U3Vector n;
333  UnplacedVolume_t::Normal(p, n);
334  return G4ThreeVector(n.x(), n.y(), n.z());
335 }
336 
337 template <class UnplacedVolume_t>
338 G4double G4UAdapter<UnplacedVolume_t>::
339 DistanceToIn(const G4ThreeVector& pt, const G4ThreeVector& d) const
340 {
341  U3Vector p(pt.x(), pt.y(), pt.z());
342  U3Vector v(d.x(), d.y(), d.z());
343  G4double dist = UnplacedVolume_t::DistanceToIn(p, v, kInfinity);
344 
345  // apply Geant4 distance conventions
346  //
347  if (dist < kHalfTolerance) return 0.0;
348  return (dist > kInfinity) ? kInfinity : dist;
349 }
350 
351 template <class UnplacedVolume_t>
352 G4double G4UAdapter<UnplacedVolume_t>::
353 DistanceToIn(const G4ThreeVector& pt) const
354 {
355  U3Vector p(pt.x(), pt.y(), pt.z());
356  G4double dist = UnplacedVolume_t::SafetyToIn(p);
357 
358  // Apply Geant4 convention: convert negative values to zero
359  //
360  if (dist < kHalfTolerance) return 0.0;
361  return (dist > kInfinity) ? kInfinity : dist;
362 }
363 
364 template <class UnplacedVolume_t>
365 G4double G4UAdapter<UnplacedVolume_t>::
366 DistanceToOut(const G4ThreeVector& pt, const G4ThreeVector& d,
367  const G4bool calcNorm, G4bool* validNorm,
368  G4ThreeVector* norm) const
369 {
370  U3Vector p(pt.x(), pt.y(), pt.z());
371  U3Vector v(d.x(), d.y(), d.z());
372 
373  G4double dist = UnplacedVolume_t::DistanceToOut(p, v, kInfinity);
374  if(calcNorm) // *norm=n, but only after calcNorm check and if convex volume
375  {
376  if (UnplacedVolume_t::IsConvex())
377  {
378  U3Vector n, hitpoint = p + dist * v;
379  UnplacedVolume_t::Normal(hitpoint, n);
380  *validNorm = true;
381  norm->set(n.x(), n.y(), n.z());
382  }
383  else
384  {
385  *validNorm = false;
386  }
387  }
388 
389  // Apply Geant4 distance conventions
390  //
391  if (dist < kHalfTolerance) return 0.0;
392  return (dist > kInfinity) ? kInfinity : dist;
393 }
394 
395 template <class UnplacedVolume_t>
396 G4double G4UAdapter<UnplacedVolume_t>::
397 DistanceToOut(const G4ThreeVector& pt) const
398 {
399  U3Vector p(pt.x(), pt.y(), pt.z());
400  G4double dist = UnplacedVolume_t::SafetyToOut(p);
401 
402  // Apply Geant4 convention: convert negative values to zero
403  //
404  if (dist < kHalfTolerance) return 0.0;
405  return (dist > kInfinity) ? kInfinity : dist;
406 }
407 
408 template <class UnplacedVolume_t>
409 G4double G4UAdapter<UnplacedVolume_t>::GetCubicVolume()
410 {
411  return UnplacedVolume_t::Capacity();
412 }
413 
414 template <class UnplacedVolume_t>
415 G4double G4UAdapter<UnplacedVolume_t>::GetSurfaceArea()
416 {
417  return UnplacedVolume_t::SurfaceArea();
418 }
419 
420 template <class UnplacedVolume_t>
421 G4ThreeVector G4UAdapter<UnplacedVolume_t>::GetPointOnSurface() const
422 {
423  U3Vector p = UnplacedVolume_t::SamplePointOnSurface();;
424  return G4ThreeVector(p.x(), p.y(), p.z());
425 }
426 
427 // Inline visualization adapters
428 
429 namespace
430 {
431  G4Mutex pMutex = G4MUTEX_INITIALIZER;
432 }
433 
434 template <class UnplacedVolume_t>
435 void G4UAdapter<UnplacedVolume_t>::
436 ComputeDimensions(G4VPVParameterisation*, const G4int,
437  const G4VPhysicalVolume*)
438 {
439  std::ostringstream message;
440  message << "Illegal call to G4UAdapter::ComputeDimensions()" << G4endl
441  << "Method not overloaded by derived class !";
442  G4Exception("G4UAdapter::ComputeDimensions()", "GeomSolids0003",
443  FatalException, message);
444 }
445 
446 template <class UnplacedVolume_t>
447 void G4UAdapter<UnplacedVolume_t>::
448 DescribeYourselfTo(G4VGraphicsScene& scene) const
449 {
450  scene.AddSolid(*this);
451 }
452 
453 template <class UnplacedVolume_t>
454 G4GeometryType G4UAdapter<UnplacedVolume_t>::
455 GetEntityType() const
456 {
457 
458  G4String string = "VSolid"; // UnplacedVolume_t::GetEntityType();
459  return "G4" + string;
460 }
461 
462 template <class UnplacedVolume_t>
463 std::ostream& G4UAdapter<UnplacedVolume_t>::
464 StreamInfo(std::ostream& os) const
465 {
467  return os;
468 }
469 
470 template <class UnplacedVolume_t>
471 G4VSolid* G4UAdapter<UnplacedVolume_t>::Clone() const
472 {
473  std::ostringstream message;
474  message << "Clone() method not implemented for type: "
475  << GetEntityType() << "!" << G4endl
476  << "Returning NULL pointer!";
477  G4Exception("G4UAdapter::Clone()", "GeomSolids1001", JustWarning, message);
478  return 0;
479 }
480 
481 template <class UnplacedVolume_t>
482 G4bool G4UAdapter<UnplacedVolume_t>::CalculateExtent(const EAxis pAxis,
483  const G4VoxelLimits& pVoxelLimit,
484  const G4AffineTransform& pTransform,
485  G4double& pMin, G4double& pMax) const
486 {
487  U3Vector vmin, vmax;
488  UnplacedVolume_t::Extent(vmin,vmax);
489  G4ThreeVector bmin(vmin.x(),vmin.y(),vmin.z());
490  G4ThreeVector bmax(vmax.x(),vmax.y(),vmax.z());
491 
492  // Check correctness of the bounding box
493  //
494  if (bmin.x() >= bmax.x() || bmin.y() >= bmax.y() || bmin.z() >= bmax.z())
495  {
496  std::ostringstream message;
497  message << "Bad bounding box (min >= max) for solid: "
498  << GetName() << " - " << GetEntityType() << " !"
499  << "\nmin = " << bmin
500  << "\nmax = " << bmax;
501  G4Exception("G4UAdapter::CalculateExtent()", "GeomMgt0001",
502  JustWarning, message);
503  StreamInfo(G4cout);
504  }
505 
506  G4BoundingEnvelope bbox(bmin,bmax);
507  return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
508 }
509 
510 template <class UnplacedVolume_t>
511 G4Polyhedron* G4UAdapter<UnplacedVolume_t>::CreatePolyhedron() const
512 {
513  // Must be implemented in concrete wrappers...
514 
515  std::ostringstream message;
516  message << "Visualization not supported for USolid shape "
517  << GetEntityType() << "... Sorry!" << G4endl;
518  G4Exception("G4UAdapter::CreatePolyhedron()", "GeomSolids0003",
519  FatalException, message);
520  return 0;
521 }
522 
523 template <class UnplacedVolume_t>
524 G4Polyhedron* G4UAdapter<UnplacedVolume_t>::GetPolyhedron() const
525 {
526  if (!fPolyhedron ||
527  fRebuildPolyhedron ||
528  fPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
529  fPolyhedron->GetNumberOfRotationSteps())
530  {
531  G4AutoLock l(&pMutex);
532  delete fPolyhedron;
533  fPolyhedron = CreatePolyhedron();
534  fRebuildPolyhedron = false;
535  l.unlock();
536  }
537  return fPolyhedron;
538 }
539 
540 template <class UnplacedVolume_t>
541 G4VisExtent G4UAdapter<UnplacedVolume_t>::GetExtent() const
542 {
543  U3Vector vmin, vmax;
544  UnplacedVolume_t::Extent(vmin,vmax);
545  return G4VisExtent(vmin.x(),vmax.x(),
546  vmin.y(),vmax.y(),
547  vmin.z(),vmax.z());
548 }
549 
550 #endif // G4GEOM_USE_USOLIDS
551 
552 #endif // G4UADAPTER_HH
void set(double x, double y, double z)
const XML_Char * name
Definition: expat.h:151
CLHEP::Hep3Vector G4ThreeVector
std::vector< ExP01TrackerHit * > a
Definition: ExP01Classes.hh:33
virtual void AddSolid(const G4Box &)=0
static const G4double kInfinity
Definition: geomdefs.hh:42
virtual G4VisExtent GetExtent() const
Definition: G4VSolid.cc:642
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
virtual G4Polyhedron * GetPolyhedron() const
Definition: G4VSolid.cc:665
#define G4endl
Definition: G4ios.hh:61
const char * p
Definition: xmltok.h:285
void message(RunManager *runmanager)
Definition: ts_scorers.cc:72
virtual G4double GetSurfaceArea()
Definition: G4VSolid.cc:250
virtual G4ThreeVector GetPointOnSurface() const
Definition: G4VSolid.cc:152
virtual G4VSolid * Clone() const
Definition: G4VSolid.cc:324
G4bool operator==(const G4VSolid &s) const
double z() const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
virtual void DescribeYourselfTo(G4VGraphicsScene &scene) const =0
const G4double kCarTolerance
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
virtual EInside Inside(const G4ThreeVector &p) const =0
G4VSolid & operator=(const G4VSolid &rhs)
Definition: G4VSolid.cc:110
const XML_Char * s
Definition: expat.h:262
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:88
G4double kCarTolerance
Definition: G4VSolid.hh:307
TMarker * pt
Definition: egs.C:25
Float_t d
virtual std::ostream & StreamInfo(std::ostream &os) const =0
void Print(G4Element &ele)
Definition: pyG4Element.cc:56
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
int G4int
Definition: G4Types.hh:78
EInside
Definition: geomdefs.hh:58
ifstream in
Definition: comparison.C:7
EAxis
Definition: geomdefs.hh:54
Float_t norm
virtual G4double GetCubicVolume()
Definition: G4VSolid.cc:188
G4GLOB_DLL std::ostream G4cout
double x() const
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition: G4VSolid.cc:137
virtual G4Polyhedron * CreatePolyhedron() const
Definition: G4VSolid.cc:660
Char_t n[5]
double y() const
virtual G4GeometryType GetEntityType() const =0
bool operator==(const HepRotation &r, const HepLorentzRotation &lt)
std::mutex G4Mutex
Definition: G4Threading.hh:84