58#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
60#include <VecGeom/base/Global.h>
61#include <VecGeom/base/Vector3D.h>
65template <
class UnplacedVolume_t>
66class G4UAdapter :
public G4VSolid,
protected UnplacedVolume_t
70 using U3Vector = vecgeom::Vector3D<G4double>;
72 using UnplacedVolume_t::operator
delete;
73 using UnplacedVolume_t::operator
new;
81 template <
typename... T>
82 G4UAdapter(
const G4String& name,
const T &... params)
86 virtual ~G4UAdapter();
122 const G4bool calcNorm =
false,
151 virtual G4double GetCubicVolume()
override;
158 virtual G4double GetSurfaceArea()
override;
172 virtual G4VSolid* Clone()
const override;
177 virtual std::ostream& StreamInfo(std::ostream& os)
const override;
186 virtual G4Polyhedron* CreatePolyhedron()
const override;
194 G4UAdapter(__void__&);
199 G4UAdapter(
const G4UAdapter& rhs);
200 G4UAdapter& operator=(
const G4UAdapter& rhs);
206 DistanceToOut(U3Vector
const&
position, U3Vector
const& direction,
207 vecgeom::Precision stepMax = kInfinity)
const override
209 return UnplacedVolume_t::DistanceToOut(
position, direction, stepMax);
213 Inside(U3Vector
const& aPoint)
const override
215 return UnplacedVolume_t::Inside(aPoint);
219 DistanceToIn(U3Vector
const&
position, U3Vector
const& direction,
220 const vecgeom::Precision step_max = kInfinity)
const override
222 return UnplacedVolume_t::DistanceToIn(
position, direction, step_max);
225 G4bool Normal(U3Vector
const& aPoint, U3Vector& aNormal)
const override
227 return UnplacedVolume_t::Normal(aPoint, aNormal);
230 void Extent(U3Vector& aMin, U3Vector& aMax)
const override
232 return UnplacedVolume_t::Extent(aMin, aMax);
235 U3Vector SamplePointOnSurface()
const override
237 return UnplacedVolume_t::SamplePointOnSurface();
242 mutable G4bool fRebuildPolyhedron =
false;
247 using UnplacedVolume_t::DistanceToOut;
248 using UnplacedVolume_t::DistanceToIn;
253template <
class UnplacedVolume_t>
254G4UAdapter<UnplacedVolume_t>::G4UAdapter(__void__& a)
255 :
G4VSolid(a), UnplacedVolume_t(*this),
260template <
class UnplacedVolume_t>
261G4UAdapter<UnplacedVolume_t>::~G4UAdapter()
263 delete fPolyhedron; fPolyhedron =
nullptr;
266template <
class UnplacedVolume_t>
267G4bool G4UAdapter<UnplacedVolume_t>::
268operator==(
const G4UAdapter& rhs)
const
270 return (
this == &rhs) ? true :
false;
273template <
class UnplacedVolume_t>
274G4UAdapter<UnplacedVolume_t>::
275G4UAdapter(
const G4UAdapter& rhs)
276 :
G4VSolid(rhs), UnplacedVolume_t(rhs)
281template <
class UnplacedVolume_t>
282G4UAdapter<UnplacedVolume_t>& G4UAdapter<UnplacedVolume_t>::
283operator=(
const G4UAdapter& rhs)
295 UnplacedVolume_t::operator=(rhs);
299 fRebuildPolyhedron =
false;
300 delete fPolyhedron; fPolyhedron =
nullptr;
306template <
class UnplacedVolume_t>
307EInside G4UAdapter<UnplacedVolume_t>::
310 U3Vector pt(p.
x(), p.
y(), p.
z());
311 vecgeom::EnumInside in_temp;
314 in_temp = UnplacedVolume_t::Inside(pt);
316 if (in_temp == vecgeom::EnumInside::eInside) in =
kInside;
317 else if (in_temp == vecgeom::EnumInside::eSurface) in =
kSurface;
322template <
class UnplacedVolume_t>
326 U3Vector p(pt.
x(), pt.
y(), pt.
z());
328 UnplacedVolume_t::Normal(p, n);
332template <
class UnplacedVolume_t>
333G4double G4UAdapter<UnplacedVolume_t>::
336 U3Vector p(pt.
x(), pt.
y(), pt.
z());
337 U3Vector v(d.
x(), d.
y(), d.
z());
338 G4double dist = UnplacedVolume_t::DistanceToIn(p, v, kInfinity);
342 if (dist < kHalfTolerance)
return 0.0;
343 return (dist > kInfinity) ? kInfinity : dist;
346template <
class UnplacedVolume_t>
347G4double G4UAdapter<UnplacedVolume_t>::
350 U3Vector p(pt.
x(), pt.
y(), pt.
z());
351 G4double dist = UnplacedVolume_t::SafetyToIn(p);
355 if (dist < kHalfTolerance)
return 0.0;
356 return (dist > kInfinity) ? kInfinity : dist;
359template <
class UnplacedVolume_t>
360G4double G4UAdapter<UnplacedVolume_t>::
365 U3Vector p(pt.
x(), pt.
y(), pt.
z());
366 U3Vector v(d.
x(), d.
y(), d.
z());
368 G4double dist = UnplacedVolume_t::DistanceToOut(p, v, kInfinity);
371 *validNorm = UnplacedVolume_t::IsConvex();
372 U3Vector
n, hitpoint = p + dist * v;
373 UnplacedVolume_t::Normal(hitpoint, n);
374 norm->
set(
n.x(),
n.y(),
n.z());
379 if (dist < kHalfTolerance)
return 0.0;
380 return (dist > kInfinity) ? kInfinity : dist;
383template <
class UnplacedVolume_t>
384G4double G4UAdapter<UnplacedVolume_t>::
387 U3Vector p(pt.
x(), pt.
y(), pt.
z());
388 G4double dist = UnplacedVolume_t::SafetyToOut(p);
392 if (dist < kHalfTolerance)
return 0.0;
393 return (dist > kInfinity) ? kInfinity : dist;
396template <
class UnplacedVolume_t>
397G4double G4UAdapter<UnplacedVolume_t>::GetCubicVolume()
399 return UnplacedVolume_t::Capacity();
402template <
class UnplacedVolume_t>
403G4double G4UAdapter<UnplacedVolume_t>::GetSurfaceArea()
405 return UnplacedVolume_t::SurfaceArea();
408template <
class UnplacedVolume_t>
409G4ThreeVector G4UAdapter<UnplacedVolume_t>::GetPointOnSurface()
const
411 U3Vector p = UnplacedVolume_t::SamplePointOnSurface();
422template <
class UnplacedVolume_t>
423void G4UAdapter<UnplacedVolume_t>::
427 std::ostringstream message;
428 message <<
"Illegal call to G4UAdapter::ComputeDimensions()" <<
G4endl
429 <<
"Method not overloaded by derived class !";
430 G4Exception(
"G4UAdapter::ComputeDimensions()",
"GeomSolids0003",
434template <
class UnplacedVolume_t>
435void G4UAdapter<UnplacedVolume_t>::
441template <
class UnplacedVolume_t>
447 return "G4" + string;
450template <
class UnplacedVolume_t>
451std::ostream& G4UAdapter<UnplacedVolume_t>::
452StreamInfo(std::ostream& os)
const
454 UnplacedVolume_t::Print(os);
458template <
class UnplacedVolume_t>
459G4VSolid* G4UAdapter<UnplacedVolume_t>::Clone()
const
461 std::ostringstream message;
462 message <<
"Clone() method not implemented for type: "
463 << GetEntityType() <<
"!" <<
G4endl
464 <<
"Returning NULL pointer!";
469template <
class UnplacedVolume_t>
470G4bool G4UAdapter<UnplacedVolume_t>::CalculateExtent(
const EAxis pAxis,
476 UnplacedVolume_t::Extent(vmin,vmax);
482 if (bmin.x() >= bmax.x() || bmin.y() >= bmax.y() || bmin.z() >= bmax.z())
484 std::ostringstream message;
485 message <<
"Bad bounding box (min >= max) for solid: "
486 << GetName() <<
" - " << GetEntityType() <<
" !"
487 <<
"\nmin = " << bmin
488 <<
"\nmax = " << bmax;
489 G4Exception(
"G4UAdapter::CalculateExtent()",
"GeomMgt0001",
495 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
498template <
class UnplacedVolume_t>
499G4Polyhedron* G4UAdapter<UnplacedVolume_t>::CreatePolyhedron()
const
503 std::ostringstream message;
504 message <<
"Visualization not supported for USolid shape "
505 << GetEntityType() <<
"... Sorry!" <<
G4endl;
506 G4Exception(
"G4UAdapter::CreatePolyhedron()",
"GeomSolids0003",
511template <
class UnplacedVolume_t>
512G4Polyhedron* G4UAdapter<UnplacedVolume_t>::GetPolyhedron()
const
515 fRebuildPolyhedron ||
516 fPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
517 fPolyhedron->GetNumberOfRotationSteps())
521 fPolyhedron = CreatePolyhedron();
522 fRebuildPolyhedron =
false;
528template <
class UnplacedVolume_t>
529G4VisExtent G4UAdapter<UnplacedVolume_t>::GetExtent()
const
532 UnplacedVolume_t::Extent(vmin,vmax);
const G4double kCarTolerance
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
G4bool operator==(const G4VSolid &s) const
const char * name(G4int ptype)