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