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;
133 iTime = mTester.getIndexTime();
143 if (!mTester.setIndexRay(iRay))
return false;
145 mTester.getIndexPos(xyz);
157 if (!mTester.setIndexRay(iRay))
return false;
159 mTester.getIndexPos(xyz);
160 iTime = mTester.getIndexTime();
168 if (!mTester.setWorldRay(wRay))
return false;
178 if (!mTester.setWorldRay(wRay))
return false;
180 wTime = mTester.getWorldTime();
190 if (!mTester.setWorldRay(wRay))
return false;
192 mTester.getWorldPos(world);
204 if (!mTester.setWorldRay(wRay))
return false;
206 mTester.getWorldPos(world);
207 wTime = mTester.getWorldTime();
219 if (!mTester.setWorldRay(wRay))
return false;
221 mTester.getWorldPosAndNml(world, normal);
235 if (!mTester.setWorldRay(wRay))
return false;
237 mTester.getWorldPosAndNml(world, normal);
238 wTime = mTester.getWorldTime();
244 mutable SearchImplT mTester;
277template<
typename GridT,
278 int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
286 using RootType =
typename GridT::TreeType::RootNodeType;
289 static_assert(NodeLevel >= 0 && NodeLevel < int(
TreeT::DEPTH)-1,
"NodeLevel out of range");
305 if (!
grid.hasUniformVoxels() ) {
306 OPENVDB_THROW(RuntimeError,
307 "VolumeRayIntersector only supports uniform voxels!");
309 if (
grid.empty() ) {
310 OPENVDB_THROW(RuntimeError,
"LinearSearchImpl does not supports empty grids");
316 mTree->root().evalActiveBoundingBox(mBBox,
false);
318 mBBox.max().offset(1);
335 if (!
grid.hasUniformVoxels() ) {
336 OPENVDB_THROW(RuntimeError,
337 "VolumeRayIntersector only supports uniform voxels!");
339 if (
grid.empty() ) {
340 OPENVDB_THROW(RuntimeError,
"LinearSearchImpl does not supports empty grids");
371 const bool hit = mRay.clip(mBBox);
372 if (hit) mTmax = mRay.t1();
389 return this->
setIndexRay(wRay.worldToIndex(*mGrid));
392 inline typename RayT::TimeSpan
march()
394 const typename RayT::TimeSpan t = mHDDA.march(mRay, mAccessor);
415 const typename RayT::TimeSpan t = this->
march();
428 template <
typename ListType>
429 inline void hits(ListType& list)
431 mHDDA.hits(mRay, mAccessor, list);
444 return time*mGrid->transform().baseMap()->applyJacobian(mRay.dir()).length();
448 const GridT&
grid()
const {
return *mGrid; }
461 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
463 if (verboseLevel>0) {
464 os <<
"BBox: " << mBBox << std::endl;
465 if (verboseLevel==2) {
467 }
else if (verboseLevel>2) {
476 const bool mIsMaster;
514template<
typename Gr
idT,
int Iterations,
typename RealT>
520 using ValueT =
typename GridT::ValueType;
530 mMinValue(isoValue -
ValueT(2 * grid.voxelSize()[0])),
531 mMaxValue(isoValue +
ValueT(2 * grid.voxelSize()[0]))
533 if ( grid.empty() ) {
534 OPENVDB_THROW(RuntimeError,
"LinearSearchImpl does not supports empty grids");
536 if (mIsoValue<= -grid.background() ||
537 mIsoValue>= grid.background() ){
538 OPENVDB_THROW(ValueError,
"The iso-value must be inside the narrow-band!");
540 grid.tree().root().evalActiveBoundingBox(mBBox,
false);
552 return mRay.
clip(mBBox);
561 return mRay.
clip(mBBox);
570 inline void getWorldPos(
VecT& xyz)
const { xyz = mStencil.grid().indexToWorld(mRay(mTime)); }
578 mStencil.moveTo(xyz);
579 nml = mStencil.gradient(xyz);
581 xyz = mStencil.grid().indexToWorld(xyz);
590 return mTime*mStencil.grid().transform().baseMap()->applyJacobian(mRay.dir()).length();
597 inline void init(RealT t0)
600 mV[0] =
static_cast<ValueT
>(this->interpValue(t0));
603 inline void setRange(RealT t0, RealT t1) { mRay.setTimes(t0, t1); }
606 inline const RayT& ray()
const {
return mRay; }
609 template <
typename NodeT>
610 inline bool hasNode(
const Coord& ijk)
612 return mStencil.accessor().template probeConstNode<NodeT>(ijk) !=
nullptr;
620 inline bool operator()(
const Coord& ijk, RealT time)
623 if (mStencil.accessor().probeValue(ijk, V) &&
624 V>mMinValue && V<mMaxValue) {
626 mV[1] =
static_cast<ValueT
>(this->interpValue(time));
627 if (math::ZeroCrossing(mV[0], mV[1])) {
628 mTime = this->interpTime();
630 for (
int n=0; Iterations>0 && n<Iterations; ++n) {
631 V =
static_cast<ValueT
>(this->interpValue(mTime));
632 const int m = math::ZeroCrossing(mV[0], V) ? 1 : 0;
635 mTime = this->interpTime();
646 inline RealT interpTime()
648 OPENVDB_ASSERT( math::isApproxLarger(mT[1], mT[0], RealT(1e-6) ) );
649 return mT[0]+(mT[1]-mT[0])*mV[0]/(mV[0]-mV[1]);
652 inline RealT interpValue(RealT time)
654 const VecT pos = mRay(time);
655 mStencil.moveTo(pos);
656 return mStencil.interpolation(pos) - mIsoValue;
666 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:754
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:526
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:71
math::Vec3< Real > Vec3R
Definition Types.h:53
Definition Exceptions.h:13
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
static T value()
Definition Math.h:167
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