32#ifndef OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED 
   33#define OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED 
   55template<
typename Gr
idT, 
int Iterations = 0, 
typename RealT = 
double>
 
   56class LinearSearchImpl;
 
   79template<
typename GridT,
 
   80         typename SearchImplT = LinearSearchImpl<GridT>,
 
   81         int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
 
   82         typename RayT = math::Ray<Real> >
 
   90    using ValueT = 
typename GridT::ValueType;
 
   91    using TreeT = 
typename GridT::TreeType;
 
   93    static_assert(NodeLevel >= -1 && NodeLevel < int(TreeT::DEPTH)-1, 
"NodeLevel out of range");
 
   94    static_assert(std::is_floating_point<ValueT>::value,
 
   95        "level set grids must have scalar, floating-point value types");
 
  101        : mTester(grid, isoValue)
 
  103        if (!grid.hasUniformVoxels() ) {
 
  104            OPENVDB_THROW(RuntimeError,
 
  105                          "LevelSetRayIntersector only supports uniform voxels!");
 
  108            OPENVDB_THROW(RuntimeError,
 
  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;
 
 
  275template<
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() ) {
 
  304            OPENVDB_THROW(RuntimeError,
 
  305                          "VolumeRayIntersector only supports uniform voxels!");
 
  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() ) {
 
  334            OPENVDB_THROW(RuntimeError,
 
  335                          "VolumeRayIntersector only supports uniform voxels!");
 
  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;
 
 
  512template<
typename Gr
idT, 
int Iterations, 
typename RealT>
 
  518    using ValueT = 
typename GridT::ValueType;
 
  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);
 
 
  568    inline void getWorldPos(
VecT& xyz)
 const { xyz = mStencil.grid().indexToWorld(mRay(mTime)); }
 
  576        mStencil.moveTo(xyz);
 
  577        nml = mStencil.gradient(xyz);
 
  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)
 
  621        if (mStencil.accessor().probeValue(ijk, V) &&
 
  622            V>mMinValue && V<mMaxValue) {
 
  624            mV[1] = 
static_cast<ValueT
>(this->interpValue(time));
 
  625            if (math::ZeroCrossing(mV[0], mV[1])) {
 
  626                mTime = this->interpTime();
 
  628                for (
int n=0; Iterations>0 && n<Iterations; ++n) {
 
  629                    V = 
static_cast<ValueT
>(this->interpValue(mTime));
 
  630                    const int m = math::ZeroCrossing(mV[0], V) ? 1 : 0;
 
  633                    mTime = this->interpTime();
 
  644    inline RealT interpTime()
 
  646        OPENVDB_ASSERT( math::isApproxLarger(mT[1], mT[0], RealT(1e-6) ) );
 
  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);
 
  653        mStencil.moveTo(pos);
 
  654        return mStencil.interpolation(pos) - mIsoValue;
 
  664    const ValueT    mIsoValue, mMinValue, mMaxValue;
 
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Digital Differential Analyzers specialized for VDB.
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Implementation of morphological dilation and erosion.
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition Types.h:683
Definition Stencils.h:301
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:252
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...
Definition Ray.h:172
bool clip(const Vec3T ¢er, RealT radius)
Return true if this ray intersects the specified sphere.
Definition Ray.h:218
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition Vec3.h:363
Helper class that implements Hierarchical Digital Differential Analyzers for ray intersections agains...
Definition DDA.h:189
static const Index DEPTH
Definition Tree.h:205
ValueAccessorImpl< TreeType, IsSafe, MutexType, openvdb::make_index_sequence< CacheLevels > > ValueAccessor
Default alias for a ValueAccessor. This is simply a helper alias for the generic definition but takes...
Definition ValueAccessor.h:86
@ GRID_LEVEL_SET
Definition Types.h:455
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
math::Vec3< Real > Vec3R
Definition Types.h:72
Definition Exceptions.h:13
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
static T value()
Definition Math.h:155
Helper class that implements Hierarchical Digital Differential Analyzers and is specialized for ray i...
Definition DDA.h:146
static bool test(TesterT &tester)
Definition DDA.h:151
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218