Files
geant4/source/geometry/solids/usolids/include/VUSolid.hh
T
2016-06-10 11:51:14 +02:00

157 lines
6.4 KiB
C++

#ifndef USOLIDS_VUSolid
#define USOLIDS_VUSolid
////////////////////////////////////////////////////////////////////////////////
// "Universal" Solid Interface
// Authors: J. Apostolakis, G. Cosmo, M. Gayer, A. Gheata, A. Munnich, T. Nikitina (CERN)
//
// Created: 25 May 2011
//
////////////////////////////////////////////////////////////////////////////////
#include "UTypes.hh"
#include "UVector3.hh"
#include "UUtils.hh"
#define USOLIDS
#define USOLIDSONLY
class VUSolid
{
public:
enum EnumInside { eInside=0, eSurface=1, eOutside=2 };
// Use eInside < eSurface < eOutside: allows "max(,)" to combine Inside of surfaces
// Potentially replace eSurface with eInSurface, eOutSurface
enum EAxisType { eXaxis=0, eYaxis=1, eZaxis=2};
protected:
static double fgTolerance;
static double frTolerance;
static double faTolerance;
// =>10 degrees/wedge for complete tube
public:
VUSolid();
VUSolid(const std::string &name);
virtual ~VUSolid();
// Accessors and modifiers for Tolerance
inline double GetCarTolerance() const;
inline double GetRadTolerance() const;
inline double GetAngTolerance() const;
void SetCarTolerance(double eps);
void SetRadTolerance(double eps);
void SetAngTolerance(double eps);
// Navigation methods
virtual EnumInside Inside (const UVector3 &aPoint) const = 0;
//
// Evaluate if point is inside, outside or on the surface within the tolerance
virtual double SafetyFromInside ( const UVector3 &aPoint,
bool aAccurate=false) const = 0;
virtual double SafetyFromOutside( const UVector3 &aPoint,
bool aAccurate=false) const = 0;
//
// Estimates isotropic distance to the surface of the solid. This must
// be either accurate or an underestimate.
// Two modes: - default/fast mode, sacrificing accuracy for speed
// - "precise" mode, requests accurate value if available.
// For both modes, if at a large distance from solid ( > ? )
// it is expected that a simplified calculation will be made if available.
virtual double DistanceToIn( const UVector3 &aPoint,
const UVector3 &aDirection,
double aPstep = UUtils::kInfinity) const = 0;
virtual double DistanceToOut( const UVector3 &aPoint,
const UVector3 &aDirection,
UVector3 &aNormalVector,
bool &aConvex,
double aPstep = UUtils::kInfinity) const = 0;
//
// o return the exact distance (double) from a surface, given a direction
// o compute the normal on the surface, returned as argument, calculated
// within the method to verify if it is close to the surface or not
// o for DistanceToOut(), normal-vector and convexity flag could be optional (to decide).
// If normal cannot be computed (or shape is not convex), set 'convex' to 'false'.
// o for DistanceToIn(), the normal-vector could be added as optional
virtual bool Normal( const UVector3& aPoint, UVector3 &aNormal ) const = 0;
// Computes the normal on a surface and returns it as a unit vector
// In case a point is further than tolerance_normal from a surface, set validNormal=false
// Must return a valid vector. (even if the point is not on the surface.)
//
// On an edge or corner, provide an average normal of all facets within tolerance
// Decision: provide or not the Boolean 'validNormal' argument for returning validity
virtual void ExtentAxis(EAxisType aAxis, double &aMin, double &aMax) const;
virtual void Extent( UVector3 &aMin, UVector3 &aMax ) const = 0;
// Return the minimum and maximum extent along all Cartesian axes
// For both the Extent methods
// o Expect mostly to use a GetBBox()/CalculateBBox() method internally to compute the extent
// o Decision: whether to store the computed BBox (containing or representing 6 double values),
// and whether to compute it at construction time.
// Methods are *not* const to allow caching of the Bounding Box
virtual UGeometryType GetEntityType() const = 0;
// Provide identification of the class of an object.
// (required for persistency and STEP interface)
const std::string &GetName() const {return fName;}
void SetName(const std::string &aName) {fName = aName;}
// Auxiliary methods
virtual double Capacity() = 0 ; // like CubicVolume()
virtual double SurfaceArea() = 0 ;
// Expect the solids to cache the values of Capacity and Surface Area
// Sampling
virtual void SamplePointsInside(int /*aNpoints*/, UVector3 * /*aArray*/) const {}
virtual void SamplePointsOnSurface(int /*aNpoints*/, UVector3 * /*aArray*/) const {}
virtual void SamplePointsOnEdge(int /*aNpoints*/, UVector3 * /*aArray*/) const {}
// o generates points on the edges of a solid - primarily for testing purposes
// o for solids composed only of curved surfaces(like full spheres or toruses) or
// where an implementation is not available, it defaults to PointOnSurface.
// Visualisation
virtual void GetParametersList(int aNumber,double *aArray) const =0;
virtual VUSolid* Clone() const =0;
// o provide a new object which is a clone of the solid
// Visualization
static double Tolerance() {return fgTolerance;}
inline virtual std::ostream& StreamInfo( std::ostream& os ) const = 0;
virtual UVector3 GetPointOnSurface() const = 0;
double EstimateCubicVolume(int nStat, double epsilon) const;
// Calculate cubic volume based on Inside() method.
// Accuracy is limited by the second argument or the statistics
// expressed by the first argument.
double EstimateSurfaceArea(int nStat, double ell) const;
// Calculate surface area only based on Inside() method.
// Accuracy is limited by the second argument or the statistics
// expressed by the first argument.
protected:
virtual void ComputeBBox(UBBox *aBox, bool aStore = false) = 0;
// o Compute the bounding box for the solid. Called automatically and stored ?
// o Can throw an exception if the solid is invalid
private:
std::string fName; // Name of the solid
//UBBox *fBBox; // Bounding box
};
inline double VUSolid::GetCarTolerance() const { return fgTolerance;}
inline double VUSolid::GetRadTolerance() const { return frTolerance;}
inline double VUSolid::GetAngTolerance() const { return faTolerance;}
#endif