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,
121 typedef typename GridT::ValueType
ValueT;
122 typedef typename GridT::TreeType
TreeT;
124 BOOST_STATIC_ASSERT( NodeLevel >= -1 && NodeLevel <
int(TreeT::DEPTH)-1);
125 BOOST_STATIC_ASSERT(boost::is_floating_point<ValueT>::value);
131 if (!grid.hasUniformVoxels() ) {
133 "LevelSetRayIntersector only supports uniform voxels!");
137 "LevelSetRayIntersector only supports level sets!"
138 "\nUse Grid::setGridClass(openvdb::GRID_LEVEL_SET)");
146 if (!mTester.setIndexRay(iRay))
return false;
156 if (!mTester.setIndexRay(iRay))
return false;
158 mTester.getIndexPos(xyz);
166 if (!mTester.setWorldRay(wRay))
return false;
176 if (!mTester.setWorldRay(wRay))
return false;
178 mTester.getWorldPos(world);
190 if (!mTester.setWorldRay(wRay))
return false;
192 mTester.getWorldPosAndNml(world, normal);
198 mutable SearchImplT mTester;
232 template<
typename GridT,
233 int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
240 typedef typename GridT::TreeType
TreeT;
242 BOOST_STATIC_ASSERT( NodeLevel >= 0 && NodeLevel <
int(TreeT::DEPTH)-1);
249 if (!grid.hasUniformVoxels() ) {
251 "VolumeRayIntersector only supports uniform voxels!");
253 if ( grid.empty() ) {
256 grid.tree().root().evalActiveBoundingBox(mBBox,
false);
258 mBBox.max().offset(1);
269 const bool hit = mRay.clip(mBBox);
270 if (hit) mTmax = mRay.t1();
287 return this->setIndexRay(wRay.worldToIndex(*mGrid));
306 mRay.setTimes(mRay.t1() + 1e-9, mTmax);
320 inline void setRange(
Real t0,
Real t1) { mRay.setTimes(t0, t1); }
323 inline const RayT& ray()
const {
return mRay; }
326 template <
typename NodeT>
327 inline bool hasNode(
const Coord& ijk)
329 return mAccessor.template probeConstNode<NodeT>(ijk) != NULL;
332 bool isValueOn(
const Coord& ijk) {
return mAccessor.isValueOn(ijk); }
336 typedef typename GridT::ConstAccessor AccessorT;
369 template<
typename Gr
idT,
int Iterations,
typename RealT>
374 typedef typename GridT::ValueType
ValueT;
381 : mStencil(grid), mThreshold(2*grid.voxelSize()[0])
383 if ( grid.empty() ) {
386 grid.tree().root().evalActiveBoundingBox(mBBox,
false);
395 return mRay.
clip(mBBox);
404 return mRay.
clip(mBBox);
413 inline void getWorldPos(
Vec3d& xyz)
const { xyz = mStencil.grid().indexToWorld(mRay(mTime)); }
420 this->getIndexPos(xyz);
421 mStencil.moveTo(xyz);
422 nml = mStencil.gradient(xyz);
424 xyz = mStencil.grid().indexToWorld(xyz);
431 inline void init(RealT t0)
434 mV[0] = this->interpValue(t0);
437 inline void setRange(RealT t0, RealT t1) { mRay.setTimes(t0, t1); }
440 inline const RayT& ray()
const {
return mRay; }
443 template <
typename NodeT>
444 inline bool hasNode(
const Coord& ijk)
446 return mStencil.accessor().template probeConstNode<NodeT>(ijk) != NULL;
454 inline bool operator()(
const Coord& ijk, RealT time)
457 if (mStencil.accessor().probeValue(ijk, V) &&
460 mV[1] = this->interpValue(time);
462 mTime = this->interpTime();
464 for (
int n=0; Iterations>0 && n<Iterations; ++n) {
465 V = this->interpValue(mTime);
469 mTime = this->interpTime();
480 inline RealT interpTime()
483 return mT[0]+(mT[1]-mT[0])*mV[0]/(mV[0]-mV[1]);
486 inline RealT interpValue(RealT time)
488 const Vec3R pos = mRay(time);
489 mStencil.moveTo(pos);
490 return mStencil.interpolation(pos);
509 template<
typename TreeT,
int NodeLevel>
512 typedef typename TreeT::RootNodeType::NodeChainType
ChainT;
513 typedef typename boost::mpl::at<ChainT, boost::mpl::int_<NodeLevel> >::type
NodeT;
515 template <
typename TesterT>
516 static bool test(TesterT& tester)
520 if (tester.template hasNode<NodeT>(dda.voxel())) {
521 tester.setRange(dda.time(), dda.next());
531 template<
typename TreeT>
534 template <
typename TesterT>
535 static bool test(TesterT& tester)
538 tester.
init(dda.time());
539 do {
if (tester(dda.voxel(), dda.next()))
return true; }
while(dda.step());
550 template <
typename TreeT,
int NodeLevel>
553 typedef typename TreeT::RootNodeType::NodeChainType
ChainT;
554 typedef typename boost::mpl::at<ChainT, boost::mpl::int_<NodeLevel> >::type
NodeT;
556 template <
typename TesterT>
557 static int test(TesterT& tester)
561 if (tester.template hasNode<NodeT>(dda.voxel())) {
562 tester.setRange(dda.time(), dda.next());
564 if (hit > 0)
return hit;
565 }
else if (tester.isValueOn(dda.voxel())) {
566 tester.setRange(dda.time(), dda.next());
569 }
while (dda.step());
576 template <
typename TreeT>
579 template <
typename TesterT>
580 static int test(TesterT&) {
return 2; }
587 #endif // OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED
void init(const RayT &ray, RealT startTime, RealT maxTime)
Definition: Ray.h:333
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
double Real
Definition: Types.h:62
Definition: Exceptions.h:86
A Digital Differential Analyzer specialized for OpenVDB grids.
Definition: Ray.h:319
#define OPENVDB_VERSION_NAME
Definition: version.h:45
math::Vec3< Real > Vec3R
Definition: Types.h:74
bool clip(const Vec3T ¢er, RealT radius)
Return true if this ray intersects the specified sphere.
Definition: Ray.h:210
Vec3< double > Vec3d
Definition: Vec3.h:605
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:229
int32_t Abs(int32_t i)
Return the absolute value of the given quantity.
Definition: Math.h:246
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:344
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:164
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:640
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:56