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();
423template <
class UnplacedVolume_t>
425operator<<(std::ostream& os,
const G4UAdapter<UnplacedVolume_t>& uAdapted)
427 return uAdapted.StreamInfo(os);
430template <
class UnplacedVolume_t>
431void G4UAdapter<UnplacedVolume_t>::
435 std::ostringstream message;
436 message <<
"Illegal call to G4UAdapter::ComputeDimensions()" <<
G4endl
437 <<
"Method not overloaded by derived class !";
438 G4Exception(
"G4UAdapter::ComputeDimensions()",
"GeomSolids0003",
442template <
class UnplacedVolume_t>
443void G4UAdapter<UnplacedVolume_t>::
449template <
class UnplacedVolume_t>
455 return "G4" + string;
458template <
class UnplacedVolume_t>
459std::ostream& G4UAdapter<UnplacedVolume_t>::
460StreamInfo(std::ostream& os)
const
462 UnplacedVolume_t::Print(os);
466template <
class UnplacedVolume_t>
467G4VSolid* G4UAdapter<UnplacedVolume_t>::Clone()
const
469 std::ostringstream message;
470 message <<
"Clone() method not implemented for type: "
471 << GetEntityType() <<
"!" <<
G4endl
472 <<
"Returning NULL pointer!";
477template <
class UnplacedVolume_t>
478G4bool G4UAdapter<UnplacedVolume_t>::CalculateExtent(
const EAxis pAxis,
484 UnplacedVolume_t::Extent(vmin,vmax);
490 if (bmin.x() >= bmax.x() || bmin.y() >= bmax.y() || bmin.z() >= bmax.z())
492 std::ostringstream message;
493 message <<
"Bad bounding box (min >= max) for solid: "
494 << GetName() <<
" - " << GetEntityType() <<
" !"
495 <<
"\nmin = " << bmin
496 <<
"\nmax = " << bmax;
497 G4Exception(
"G4UAdapter::CalculateExtent()",
"GeomMgt0001",
503 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
506template <
class UnplacedVolume_t>
507G4Polyhedron* G4UAdapter<UnplacedVolume_t>::CreatePolyhedron()
const
511 std::ostringstream message;
512 message <<
"Visualization not supported for USolid shape "
513 << GetEntityType() <<
"... Sorry!" <<
G4endl;
514 G4Exception(
"G4UAdapter::CreatePolyhedron()",
"GeomSolids0003",
519template <
class UnplacedVolume_t>
520G4Polyhedron* G4UAdapter<UnplacedVolume_t>::GetPolyhedron()
const
523 fRebuildPolyhedron ||
524 fPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
525 fPolyhedron->GetNumberOfRotationSteps())
529 fPolyhedron = CreatePolyhedron();
530 fRebuildPolyhedron =
false;
536template <
class UnplacedVolume_t>
537G4VisExtent G4UAdapter<UnplacedVolume_t>::GetExtent()
const
540 UnplacedVolume_t::Extent(vmin,vmax);
const G4double kCarTolerance
std::ostream & operator<<(std::ostream &out, const G4CellScoreComposer &ps)
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)
yystype & operator=(const yystype &right)