157 lines
6.4 KiB
C++
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
|
|
|