32 #ifndef OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED 
   33 #define OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED 
   44 #include <type_traits> 
   55 template<
typename Gr
idT, 
int Iterations = 0, 
typename RealT = 
double>
 
   79 template<
typename GridT,
 
   81          int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
 
   91     using TreeT = 
typename GridT::TreeType;
 
   93     static_assert(NodeLevel >= -1 && NodeLevel < 
int(TreeT::DEPTH)-1, 
"NodeLevel out of range");
 
   95         "level set grids must have scalar, floating-point value types");
 
  101         : mTester(grid, isoValue)
 
  103         if (!grid.hasUniformVoxels() ) {
 
  105                           "LevelSetRayIntersector only supports uniform voxels!");
 
  109                           "LevelSetRayIntersector only supports level sets!" 
  110                           "\nUse Grid::setGridClass(openvdb::GRID_LEVEL_SET)");
 
  121         if (!mTester.setIndexRay(iRay)) 
return false;
 
  131         if (!mTester.setIndexRay(iRay)) 
return false;
 
  132         iTime = mTester.getIndexTime();
 
  142         if (!mTester.setIndexRay(iRay)) 
return false;
 
  144         mTester.getIndexPos(xyz);
 
  156         if (!mTester.setIndexRay(iRay)) 
return false;
 
  158         mTester.getIndexPos(xyz);
 
  159         iTime = mTester.getIndexTime();
 
  167         if (!mTester.setWorldRay(wRay)) 
return false;
 
  177         if (!mTester.setWorldRay(wRay)) 
return false;
 
  178         wTime = mTester.getWorldTime();
 
  188         if (!mTester.setWorldRay(wRay)) 
return false;
 
  190         mTester.getWorldPos(world);
 
  202         if (!mTester.setWorldRay(wRay)) 
return false;
 
  204         mTester.getWorldPos(world);
 
  205         wTime = mTester.getWorldTime();
 
  217         if (!mTester.setWorldRay(wRay)) 
return false;
 
  219         mTester.getWorldPosAndNml(world, normal);
 
  233         if (!mTester.setWorldRay(wRay)) 
return false;
 
  235         mTester.getWorldPosAndNml(world, normal);
 
  236         wTime = mTester.getWorldTime();
 
  242     mutable SearchImplT mTester;
 
  275 template<
typename GridT,
 
  276          int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
 
  284     using RootType = 
typename GridT::TreeType::RootNodeType;
 
  287     static_assert(NodeLevel >= 0 && NodeLevel < 
int(
TreeT::DEPTH)-1, 
"NodeLevel out of range");
 
  303         if (!grid.hasUniformVoxels() ) {
 
  305                           "VolumeRayIntersector only supports uniform voxels!");
 
  307         if ( grid.empty() ) {
 
  308             OPENVDB_THROW(RuntimeError, 
"LinearSearchImpl does not supports empty grids");
 
  314         mTree->
root().evalActiveBoundingBox(mBBox, 
false);
 
  316         mBBox.
max().offset(1);
 
  333         if (!grid.hasUniformVoxels() ) {
 
  335                           "VolumeRayIntersector only supports uniform voxels!");
 
  337         if ( grid.empty() ) {
 
  338             OPENVDB_THROW(RuntimeError, 
"LinearSearchImpl does not supports empty grids");
 
  369         const bool hit = mRay.clip(mBBox);
 
  370         if (hit) mTmax = mRay.t1();
 
  387         return this->
setIndexRay(wRay.worldToIndex(*mGrid));
 
  390     inline typename RayT::TimeSpan 
march()
 
  392         const typename RayT::TimeSpan 
t = mHDDA.march(mRay, mAccessor);
 
  413         const typename RayT::TimeSpan 
t = this->
march();
 
  426     template <
typename ListType>
 
  427     inline void hits(ListType& list)
 
  429         mHDDA.hits(mRay, mAccessor, list);
 
  442         return time*mGrid->transform().baseMap()->applyJacobian(mRay.dir()).
length();
 
  446     const GridT& 
grid()
 const { 
return *mGrid; }
 
  459     void print(std::ostream& os = std::cout, 
int verboseLevel = 1)
 
  461         if (verboseLevel>0) {
 
  462             os << 
"BBox: " << mBBox << std::endl;
 
  463             if (verboseLevel==2) {
 
  465             } 
else if (verboseLevel>2) {
 
  474     const bool      mIsMaster;
 
  512 template<
typename Gr
idT, 
int Iterations, 
typename RealT>
 
  513 class LinearSearchImpl
 
  528           mMinValue(isoValue - 
ValueT(2 * grid.voxelSize()[0])),
 
  529           mMaxValue(isoValue + 
ValueT(2 * grid.voxelSize()[0]))
 
  531           if ( grid.empty() ) {
 
  532               OPENVDB_THROW(RuntimeError, 
"LinearSearchImpl does not supports empty grids");
 
  534           if (mIsoValue<= -grid.background() ||
 
  535               mIsoValue>=  grid.background() ){
 
  536               OPENVDB_THROW(ValueError, 
"The iso-value must be inside the narrow-band!");
 
  538           grid.tree().root().evalActiveBoundingBox(mBBox, 
false);
 
  550         return mRay.
clip(mBBox);
 
  559         return mRay.
clip(mBBox);
 
  579         xyz = mStencil.
grid().indexToWorld(xyz);
 
  588         return mTime*mStencil.
grid().transform().baseMap()->applyJacobian(mRay.
dir()).
length();
 
  595     inline void init(RealT t0)
 
  598         mV[0] = 
static_cast<ValueT>(this->interpValue(t0));
 
  601     inline void setRange(RealT t0, RealT t1) { mRay.
setTimes(t0, t1); }
 
  604     inline const RayT& ray()
 const { 
return mRay; }
 
  607     template <
typename NodeT>
 
  608     inline bool hasNode(
const Coord& ijk)
 
  610         return mStencil.
accessor().template probeConstNode<NodeT>(ijk) != 
nullptr;
 
  618     inline bool operator()(
const Coord& ijk, RealT 
time)
 
  622             V>mMinValue && V<mMaxValue) {
 
  624             mV[1] = 
static_cast<ValueT>(this->interpValue(time));
 
  626                 mTime = this->interpTime();
 
  628                 for (
int n=0; Iterations>0 && 
n<Iterations; ++
n) {
 
  629                     V = 
static_cast<ValueT>(this->interpValue(mTime));
 
  633                     mTime = this->interpTime();
 
  644     inline RealT interpTime()
 
  647         return mT[0]+(mT[1]-mT[0])*mV[0]/(mV[0]-mV[1]);
 
  650     inline RealT interpValue(RealT time)
 
  652         const VecT pos = mRay(time);
 
  664     const ValueT    mIsoValue, mMinValue, mMaxValue;
 
  672 #endif // OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED 
void setTimes(RealT t0=math::Delta< RealT >::value(), RealT t1=std::numeric_limits< RealT >::max())
 
bool clip(const Vec3T ¢er, RealT radius)
Return true if this ray intersects the specified sphere. 
 
bool ZeroCrossing(const Type &a, const Type &b)
Return true if the interval [a, b] includes zero, i.e., if either a or b is zero or if they have diff...
 
bool normalize(T eps=T(1.0e-7))
this = normalized this 
 
GT_API const UT_StringHolder time
 
GLsizei const GLfloat * value
 
Ray worldToIndex(const GridType &grid) const 
Return a new ray in the index space of the specified grid, assuming the existing ray is represented i...
 
static bool test(TesterT &tester)
 
GLuint GLsizei GLsizei * length
 
RootNodeType & root()
Return this tree's root node. 
 
#define OPENVDB_USE_VERSION_NAMESPACE
 
The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compa...
 
math::Vec3< ValueType > gradient(const math::Vec3< ValueType > &xyz) const 
Return the gradient in world space of the trilinear interpolation kernel. 
 
const AccessorType & accessor() const 
Return a const reference to the ValueAccessor associated with this Stencil. 
 
#define OPENVDB_ASSERT(X)
 
bool probeValue(const Coord &xyz, ValueType &value) const 
Return the active state of the value at a given coordinate as well as its value. 
 
void print(std::ostream &os=std::cout, int verboseLevel=1) const override
Print statistics, memory usage and other information about this tree. 
 
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
 
Delta for small floating-point offsets. 
 
const Coord & max() const 
 
Axis-aligned bounding box of signed integer coordinates. 
 
void moveTo(const Coord &ijk)
Initialize the stencil buffer with the values of voxel (i, j, k) and its neighbors. 
 
ValueType interpolation(const math::Vec3< ValueType > &xyz) const 
Return the trilinear interpolation at the normalized position. 
 
Helper class that implements Hierarchical Digital Differential Analyzers and is specialized for ray i...
 
const GridType & grid() const 
Return a const reference to the grid from which this stencil was constructed. 
 
const Vec3T & dir() const 
 
Implementation of morphological dilation and erosion. 
 
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors. 
 
Digital Differential Analyzers specialized for VDB. 
 
#define OPENVDB_VERSION_NAME
The version namespace name for this library version. 
 
Helper class that implements Hierarchical Digital Differential Analyzers for ray intersections agains...
 
#define OPENVDB_THROW(exception, message)
 
bool isApproxLarger(const Type &a, const Type &b, const Type &tolerance)
Return true if a is larger than b to within the given tolerance, i.e., if b - a < tolerance...