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.
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:298
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
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
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:291