59 #ifndef OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED 60 #define OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED 70 #include <type_traits> 81 template<
typename Gr
idT,
int Iterations = 0,
typename RealT =
double>
105 template<
typename GridT,
107 int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
116 using ValueT =
typename GridT::ValueType;
117 using TreeT =
typename GridT::TreeType;
119 static_assert(NodeLevel >= -1 && NodeLevel <
int(TreeT::DEPTH)-1,
"NodeLevel out of range");
120 static_assert(std::is_floating_point<ValueT>::value,
121 "level set grids must have scalar, floating-point value types");
127 : mTester(grid, isoValue)
129 if (!grid.hasUniformVoxels() ) {
131 "LevelSetRayIntersector only supports uniform voxels!");
135 "LevelSetRayIntersector only supports level sets!" 136 "\nUse Grid::setGridClass(openvdb::GRID_LEVEL_SET)");
147 if (!mTester.setIndexRay(iRay))
return false;
157 if (!mTester.setIndexRay(iRay))
return false;
158 iTime = mTester.getIndexTime();
168 if (!mTester.setIndexRay(iRay))
return false;
170 mTester.getIndexPos(xyz);
182 if (!mTester.setIndexRay(iRay))
return false;
184 mTester.getIndexPos(xyz);
185 iTime = mTester.getIndexTime();
193 if (!mTester.setWorldRay(wRay))
return false;
203 if (!mTester.setWorldRay(wRay))
return false;
204 wTime = mTester.getWorldTime();
214 if (!mTester.setWorldRay(wRay))
return false;
216 mTester.getWorldPos(world);
228 if (!mTester.setWorldRay(wRay))
return false;
230 mTester.getWorldPos(world);
231 wTime = mTester.getWorldTime();
243 if (!mTester.setWorldRay(wRay))
return false;
245 mTester.getWorldPosAndNml(world, normal);
259 if (!mTester.setWorldRay(wRay))
return false;
261 mTester.getWorldPosAndNml(world, normal);
262 wTime = mTester.getWorldTime();
268 mutable SearchImplT mTester;
301 template<
typename GridT,
302 int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
310 using RootType =
typename GridT::TreeType::RootNodeType;
313 static_assert(NodeLevel >= 0 && NodeLevel <
int(TreeT::DEPTH)-1,
"NodeLevel out of range");
329 if (!grid.hasUniformVoxels() ) {
331 "VolumeRayIntersector only supports uniform voxels!");
333 if ( grid.empty() ) {
340 mTree->root().evalActiveBoundingBox(mBBox,
false);
342 mBBox.max().offset(1);
359 if (!grid.hasUniformVoxels() ) {
361 "VolumeRayIntersector only supports uniform voxels!");
363 if ( grid.empty() ) {
395 const bool hit = mRay.clip(mBBox);
396 if (hit) mTmax = mRay.t1();
413 return this->setIndexRay(wRay.worldToIndex(*mGrid));
416 inline typename RayT::TimeSpan
march()
418 const typename RayT::TimeSpan t = mHDDA.march(mRay, mAccessor);
439 const typename RayT::TimeSpan t = this->march();
452 template <
typename ListType>
453 inline void hits(ListType& list)
455 mHDDA.hits(mRay, mAccessor, list);
468 return time*mGrid->transform().baseMap()->applyJacobian(mRay.dir()).length();
472 const GridT&
grid()
const {
return *mGrid; }
485 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
487 if (verboseLevel>0) {
488 os <<
"BBox: " << mBBox << std::endl;
489 if (verboseLevel==2) {
491 }
else if (verboseLevel>2) {
500 const bool mIsMaster;
538 template<
typename Gr
idT,
int Iterations,
typename RealT>
539 class LinearSearchImpl
544 using ValueT =
typename GridT::ValueType;
554 mMinValue(isoValue -
ValueT(2 * grid.voxelSize()[0])),
555 mMaxValue(isoValue +
ValueT(2 * grid.voxelSize()[0]))
557 if ( grid.empty() ) {
560 if (mIsoValue<= -grid.background() ||
561 mIsoValue>= grid.background() ){
564 grid.tree().root().evalActiveBoundingBox(mBBox,
false);
576 return mRay.
clip(mBBox);
585 return mRay.
clip(mBBox);
594 inline void getWorldPos(
VecT& xyz)
const { xyz = mStencil.grid().indexToWorld(mRay(mTime)); }
601 this->getIndexPos(xyz);
602 mStencil.moveTo(xyz);
603 nml = mStencil.gradient(xyz);
605 xyz = mStencil.grid().indexToWorld(xyz);
614 return mTime*mStencil.grid().transform().baseMap()->applyJacobian(mRay.dir()).length();
621 inline void init(RealT t0)
624 mV[0] = static_cast<ValueT>(this->interpValue(t0));
627 inline void setRange(RealT t0, RealT t1) { mRay.setTimes(t0, t1); }
630 inline const RayT& ray()
const {
return mRay; }
633 template <
typename NodeT>
634 inline bool hasNode(
const Coord& ijk)
636 return mStencil.accessor().template probeConstNode<NodeT>(ijk) !=
nullptr;
644 inline bool operator()(
const Coord& ijk, RealT time)
647 if (mStencil.accessor().probeValue(ijk, V) &&
648 V>mMinValue && V<mMaxValue) {
650 mV[1] = static_cast<ValueT>(this->interpValue(time));
652 mTime = this->interpTime();
654 for (
int n=0; Iterations>0 && n<Iterations; ++n) {
655 V = static_cast<ValueT>(this->interpValue(mTime));
659 mTime = this->interpTime();
670 inline RealT interpTime()
673 return mT[0]+(mT[1]-mT[0])*mV[0]/(mV[0]-mV[1]);
676 inline RealT interpValue(RealT time)
678 const VecT pos = mRay(time);
679 mStencil.moveTo(pos);
680 return mStencil.interpolation(pos) - mIsoValue;
690 const ValueT mIsoValue, mMinValue, mMaxValue;
698 #endif // OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:377
Definition: Exceptions.h:90
Delta for small floating-point offsets.
Definition: Math.h:124
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...
Definition: Math.h:707
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:518
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.
Definition: Math.h:386
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
Implementation of morphological dilation and erosion.
Definition: Exceptions.h:40
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
Definition: ValueAccessor.h:220
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:198
bool clip(const Vec3T ¢er, RealT radius)
Return true if this ray intersects the specified sphere.
Definition: Ray.h:244
Helper class that implements Hierarchical Digital Differential Analyzers and is specialized for ray i...
Definition: DDA.h:172
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
Definition: Exceptions.h:92
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
Digital Differential Analyzers specialized for VDB.
Helper class that implements Hierarchical Digital Differential Analyzers for ray intersections agains...
Definition: DDA.h:215