59 #ifndef OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED
60 #define OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED
62 #include <openvdb/math/Ray.h>
63 #include <openvdb/math/Stencils.h>
64 #include <openvdb/Grid.h>
65 #include <openvdb/Types.h>
66 #include <openvdb/math/Math.h>
67 #include <boost/utility.hpp>
68 #include <boost/type_traits/is_floating_point.hpp>
82 template <
typename Gr
idT,
int NodeLevel>
struct VolumeHDDA;
87 template<
typename Gr
idT,
int Iterations = 0,
typename RealT =
double>
111 template<
typename GridT,
113 int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
122 typedef typename GridT::ValueType
ValueT;
123 typedef typename GridT::TreeType
TreeT;
125 BOOST_STATIC_ASSERT( NodeLevel >= -1 && NodeLevel <
int(TreeT::DEPTH)-1);
126 BOOST_STATIC_ASSERT(boost::is_floating_point<ValueT>::value);
132 if (!grid.hasUniformVoxels() ) {
134 "LevelSetRayIntersector only supports uniform voxels!");
138 "LevelSetRayIntersector only supports level sets!"
139 "\nUse Grid::setGridClass(openvdb::GRID_LEVEL_SET)");
147 if (!mTester.setIndexRay(iRay))
return false;
157 if (!mTester.setIndexRay(iRay))
return false;
159 mTester.getIndexPos(xyz);
167 if (!mTester.setWorldRay(wRay))
return false;
177 if (!mTester.setWorldRay(wRay))
return false;
179 mTester.getWorldPos(world);
191 if (!mTester.setWorldRay(wRay))
return false;
193 mTester.getWorldPosAndNml(world, normal);
199 mutable SearchImplT mTester;
233 template<
typename GridT,
234 int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
242 typedef typename GridT::TreeType
TreeT;
244 BOOST_STATIC_ASSERT( NodeLevel >= 0 && NodeLevel <
int(TreeT::DEPTH)-1);
251 if (!grid.hasUniformVoxels() ) {
253 "VolumeRayIntersector only supports uniform voxels!");
255 if ( grid.empty() ) {
258 grid.tree().root().evalActiveBoundingBox(mBBox,
false);
260 mBBox.max().offset(1);
271 const bool hit = mRay.clip(mBBox);
272 if (hit) mTmax = mRay.t1();
289 return this->setIndexRay(wRay.worldToIndex(*mGrid));
322 inline void setRange(
Real t0,
Real t1) { mRay.setTimes(t0, t1); }
325 inline const RayT& ray()
const {
return mRay; }
328 template <
typename NodeT>
329 inline bool hasNode(
const Coord& ijk)
331 return mAccessor.template probeConstNode<NodeT>(ijk) != NULL;
334 bool isValueOn(
const Coord& ijk) {
return mAccessor.isValueOn(ijk); }
338 typedef typename GridT::ConstAccessor AccessorT;
371 template<
typename Gr
idT,
int Iterations,
typename RealT>
376 typedef typename GridT::ValueType
ValueT;
383 : mStencil(grid), mThreshold(2*grid.voxelSize()[0])
385 if ( grid.empty() ) {
388 grid.tree().root().evalActiveBoundingBox(mBBox,
false);
397 return mRay.
clip(mBBox);
406 return mRay.
clip(mBBox);
415 inline void getWorldPos(
Vec3d& xyz)
const { xyz = mStencil.grid().indexToWorld(mRay(mTime)); }
422 this->getIndexPos(xyz);
423 mStencil.moveTo(xyz);
424 nml = mStencil.gradient(xyz);
426 xyz = mStencil.grid().indexToWorld(xyz);
433 inline void init(RealT t0)
436 mV[0] = this->interpValue(t0);
439 inline void setRange(RealT t0, RealT t1) { mRay.setTimes(t0, t1); }
442 inline const RayT& ray()
const {
return mRay; }
445 template <
typename NodeT>
446 inline bool hasNode(
const Coord& ijk)
448 return mStencil.accessor().template probeConstNode<NodeT>(ijk) != NULL;
456 inline bool operator()(
const Coord& ijk, RealT time)
459 if (mStencil.accessor().probeValue(ijk, V) &&
462 mV[1] = this->interpValue(time);
464 mTime = this->interpTime();
466 for (
int n=0; Iterations>0 && n<Iterations; ++n) {
467 V = this->interpValue(mTime);
471 mTime = this->interpTime();
482 inline RealT interpTime()
485 return mT[0]+(mT[1]-mT[0])*mV[0]/(mV[0]-mV[1]);
488 inline RealT interpValue(RealT time)
490 const Vec3R pos = mRay(time);
491 mStencil.moveTo(pos);
492 return mStencil.interpolation(pos);
511 template<
typename TreeT,
int NodeLevel>
514 typedef typename TreeT::RootNodeType::NodeChainType
ChainT;
515 typedef typename boost::mpl::at<ChainT, boost::mpl::int_<NodeLevel> >::type
NodeT;
517 template <
typename TesterT>
518 static bool test(TesterT& tester)
522 if (tester.template hasNode<NodeT>(dda.voxel())) {
523 tester.setRange(dda.time(), dda.next());
533 template<
typename TreeT>
536 template <
typename TesterT>
537 static bool test(TesterT& tester)
540 tester.
init(dda.time());
541 do {
if (tester(dda.voxel(), dda.next()))
return true; }
while(dda.step());
552 template <
typename TreeT,
int NodeLevel>
555 typedef typename TreeT::RootNodeType::NodeChainType
ChainT;
556 typedef typename boost::mpl::at<ChainT, boost::mpl::int_<NodeLevel> >::type
NodeT;
558 template <
typename TesterT>
559 static int test(TesterT& tester)
563 if (tester.template hasNode<NodeT>(dda.voxel())) {
564 tester.setRange(dda.time(), dda.next());
566 if (hit > 0)
return hit;
567 }
else if (tester.isValueOn(dda.voxel())) {
568 tester.setRange(dda.time(), dda.next());
571 }
while (dda.step());
578 template <
typename TreeT>
581 template <
typename TesterT>
582 static int test(TesterT&) {
return 2; }
589 #endif // OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED
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:166
math::Vec3< Real > Vec3R
Definition: Types.h:74
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
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:647
int32_t Abs(int32_t i)
Return the absolute value of the given quantity.
Definition: Math.h:253
Delta for small floating-point offsets.
Definition: Math.h:123
Definition: Exceptions.h:86
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:229
#define OPENVDB_VERSION_NAME
Definition: version.h:45
Vec3< double > Vec3d
Definition: Vec3.h:605
A Digital Differential Analyzer specialized for OpenVDB grids.
Definition: Ray.h:321
double Real
Definition: Types.h:62
void init(const RayT &ray, RealT startTime, RealT maxTime)
Definition: Ray.h:335
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
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:351
bool clip(const Vec3T ¢er, RealT radius)
Return true if this ray intersects the specified sphere.
Definition: Ray.h:212