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;
77 G4UAdapter(
const G4String& name)
81 template <
typename... T>
82 G4UAdapter(
const G4String& name,
const T &... params)
83 : G4VSolid(
name), UnplacedVolume_t(params...)
86 virtual ~G4UAdapter();
92 const G4VoxelLimits& pVoxelLimit,
93 const G4AffineTransform& pTransform,
122 const G4bool calcNorm =
false,
145 virtual void ComputeDimensions(G4VPVParameterisation* p,
147 const G4VPhysicalVolume* pRep)
override;
151 virtual G4double GetCubicVolume()
override;
158 virtual G4double GetSurfaceArea()
override;
168 virtual G4int GetNumOfConstituents()
const override;
172 virtual G4bool IsFaceted()
const override;
179 virtual G4VSolid* Clone()
const override;
184 virtual std::ostream& StreamInfo(std::ostream& os)
const override;
187 virtual void DescribeYourselfTo(G4VGraphicsScene& scene)
const override;
191 virtual G4VisExtent GetExtent()
const override;
193 virtual G4Polyhedron* CreatePolyhedron()
const override;
195 virtual G4Polyhedron* GetPolyhedron()
const override;
201 G4UAdapter(__void__&);
206 G4UAdapter(
const G4UAdapter& rhs);
207 G4UAdapter& operator=(
const G4UAdapter& rhs);
213 DistanceToOut(U3Vector
const& position, U3Vector
const& direction,
214 vecgeom::Precision stepMax = kInfinity)
const override
216 return UnplacedVolume_t::DistanceToOut(position, direction, stepMax);
220 Inside(U3Vector
const& aPoint)
const override
222 return UnplacedVolume_t::Inside(aPoint);
226 DistanceToIn(U3Vector
const& position, U3Vector
const& direction,
227 const vecgeom::Precision step_max = kInfinity)
const override
229 return UnplacedVolume_t::DistanceToIn(position, direction, step_max);
232 G4bool Normal(U3Vector
const& aPoint, U3Vector& aNormal)
const override
234 return UnplacedVolume_t::Normal(aPoint, aNormal);
237 void Extent(U3Vector& aMin, U3Vector& aMax)
const override
239 return UnplacedVolume_t::Extent(aMin, aMax);
242 U3Vector SamplePointOnSurface()
const override
244 return UnplacedVolume_t::SamplePointOnSurface();
249 mutable G4bool fRebuildPolyhedron =
false;
250 mutable G4Polyhedron* fPolyhedron =
nullptr;
254 using UnplacedVolume_t::DistanceToOut;
255 using UnplacedVolume_t::DistanceToIn;
260template <
class UnplacedVolume_t>
261G4UAdapter<UnplacedVolume_t>::G4UAdapter(__void__& a)
262 :
G4VSolid(a), UnplacedVolume_t(*this),
267template <
class UnplacedVolume_t>
268G4UAdapter<UnplacedVolume_t>::~G4UAdapter()
270 delete fPolyhedron; fPolyhedron =
nullptr;
273template <
class UnplacedVolume_t>
274G4bool G4UAdapter<UnplacedVolume_t>::
275operator==(
const G4UAdapter& rhs)
const
277 return (
this == &rhs) ? true :
false;
280template <
class UnplacedVolume_t>
281G4UAdapter<UnplacedVolume_t>::
282G4UAdapter(
const G4UAdapter& rhs)
283 :
G4VSolid(rhs), UnplacedVolume_t(rhs)
288template <
class UnplacedVolume_t>
289G4UAdapter<UnplacedVolume_t>& G4UAdapter<UnplacedVolume_t>::
290operator=(
const G4UAdapter& rhs)
302 UnplacedVolume_t::operator=(rhs);
306 fRebuildPolyhedron =
false;
307 delete fPolyhedron; fPolyhedron =
nullptr;
313template <
class UnplacedVolume_t>
314EInside G4UAdapter<UnplacedVolume_t>::
317 U3Vector pt(p.
x(), p.
y(), p.
z());
318 vecgeom::EnumInside in_temp;
321 in_temp = UnplacedVolume_t::Inside(pt);
323 if (in_temp == vecgeom::EnumInside::eInside) in =
kInside;
324 else if (in_temp == vecgeom::EnumInside::eSurface) in =
kSurface;
329template <
class UnplacedVolume_t>
333 U3Vector p(pt.
x(), pt.
y(), pt.
z());
335 UnplacedVolume_t::Normal(p, n);
339template <
class UnplacedVolume_t>
340G4double G4UAdapter<UnplacedVolume_t>::
343 U3Vector p(pt.
x(), pt.
y(), pt.
z());
344 U3Vector v(d.
x(), d.
y(), d.
z());
345 G4double dist = UnplacedVolume_t::DistanceToIn(p, v, kInfinity);
349 if (dist < kHalfTolerance)
return 0.0;
350 return (dist > kInfinity) ? kInfinity : dist;
353template <
class UnplacedVolume_t>
354G4double G4UAdapter<UnplacedVolume_t>::
357 U3Vector p(pt.
x(), pt.
y(), pt.
z());
358 G4double dist = UnplacedVolume_t::SafetyToIn(p);
362 if (dist < kHalfTolerance)
return 0.0;
363 return (dist > kInfinity) ? kInfinity : dist;
366template <
class UnplacedVolume_t>
367G4double G4UAdapter<UnplacedVolume_t>::
372 U3Vector p(pt.
x(), pt.
y(), pt.
z());
373 U3Vector v(d.
x(), d.
y(), d.
z());
375 G4double dist = UnplacedVolume_t::DistanceToOut(p, v, kInfinity);
378 *validNorm = UnplacedVolume_t::IsConvex();
379 U3Vector
n, hitpoint = p + dist * v;
380 UnplacedVolume_t::Normal(hitpoint, n);
381 norm->
set(
n.x(),
n.y(),
n.z());
386 if (dist < kHalfTolerance)
return 0.0;
387 return (dist > kInfinity) ? kInfinity : dist;
390template <
class UnplacedVolume_t>
391G4double G4UAdapter<UnplacedVolume_t>::
394 U3Vector p(pt.
x(), pt.
y(), pt.
z());
395 G4double dist = UnplacedVolume_t::SafetyToOut(p);
399 if (dist < kHalfTolerance)
return 0.0;
400 return (dist > kInfinity) ? kInfinity : dist;
403template <
class UnplacedVolume_t>
404G4double G4UAdapter<UnplacedVolume_t>::GetCubicVolume()
406 return UnplacedVolume_t::Capacity();
409template <
class UnplacedVolume_t>
410G4double G4UAdapter<UnplacedVolume_t>::GetSurfaceArea()
412 return UnplacedVolume_t::SurfaceArea();
415template <
class UnplacedVolume_t>
416G4ThreeVector G4UAdapter<UnplacedVolume_t>::GetPointOnSurface()
const
418 U3Vector p = UnplacedVolume_t::SamplePointOnSurface();
422template <
class UnplacedVolume_t>
423G4int G4UAdapter<UnplacedVolume_t>::GetNumOfConstituents()
const
428template <
class UnplacedVolume_t>
429G4bool G4UAdapter<UnplacedVolume_t>::IsFaceted()
const
442template <
class UnplacedVolume_t>
444operator<<(std::ostream& os,
const G4UAdapter<UnplacedVolume_t>& uAdapted)
446 return uAdapted.StreamInfo(os);
449template <
class UnplacedVolume_t>
450void G4UAdapter<UnplacedVolume_t>::
454 std::ostringstream message;
455 message <<
"Illegal call to G4UAdapter::ComputeDimensions()" <<
G4endl
456 <<
"Method not overloaded by derived class !";
457 G4Exception(
"G4UAdapter::ComputeDimensions()",
"GeomSolids0003",
461template <
class UnplacedVolume_t>
462void G4UAdapter<UnplacedVolume_t>::
468template <
class UnplacedVolume_t>
477template <
class UnplacedVolume_t>
478std::ostream& G4UAdapter<UnplacedVolume_t>::
479StreamInfo(std::ostream& os)
const
481 UnplacedVolume_t::Print(os);
485template <
class UnplacedVolume_t>
486G4VSolid* G4UAdapter<UnplacedVolume_t>::Clone()
const
488 std::ostringstream message;
489 message <<
"Clone() method not implemented for type: "
490 << GetEntityType() <<
"!" <<
G4endl
491 <<
"Returning NULL pointer!";
496template <
class UnplacedVolume_t>
497G4bool G4UAdapter<UnplacedVolume_t>::CalculateExtent(
const EAxis pAxis,
503 UnplacedVolume_t::Extent(vmin,vmax);
509 if (bmin.x() >= bmax.x() || bmin.y() >= bmax.y() || bmin.z() >= bmax.z())
511 std::ostringstream message;
512 message <<
"Bad bounding box (min >= max) for solid: "
513 << GetName() <<
" - " << GetEntityType() <<
" !"
514 <<
"\nmin = " << bmin
515 <<
"\nmax = " << bmax;
516 G4Exception(
"G4UAdapter::CalculateExtent()",
"GeomMgt0001",
522 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
525template <
class UnplacedVolume_t>
526G4Polyhedron* G4UAdapter<UnplacedVolume_t>::CreatePolyhedron()
const
530 std::ostringstream message;
531 message <<
"Visualization not supported for USolid shape "
532 << GetEntityType() <<
"... Sorry!" <<
G4endl;
533 G4Exception(
"G4UAdapter::CreatePolyhedron()",
"GeomSolids0003",
538template <
class UnplacedVolume_t>
539G4Polyhedron* G4UAdapter<UnplacedVolume_t>::GetPolyhedron()
const
542 fRebuildPolyhedron ||
543 fPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
544 fPolyhedron->GetNumberOfRotationSteps())
548 fPolyhedron = CreatePolyhedron();
549 fRebuildPolyhedron =
false;
555template <
class UnplacedVolume_t>
556G4VisExtent G4UAdapter<UnplacedVolume_t>::GetExtent()
const
559 UnplacedVolume_t::Extent(vmin,vmax);
G4TemplateAutoLock< G4Mutex > G4AutoLock
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)