OpenVDB  3.1.0
RayIntersector.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2015 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
57 
58 
59 #ifndef OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED
60 #define OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED
61 
62 #include <openvdb/math/DDA.h>
63 #include <openvdb/math/Math.h>
64 #include <openvdb/math/Ray.h>
65 #include <openvdb/math/Stencils.h>
66 #include <openvdb/Grid.h>
67 #include <openvdb/Types.h>
68 #include "Morphology.h"
69 #include <boost/utility.hpp>
70 #include <boost/type_traits/is_floating_point.hpp>
71 
72 
73 namespace openvdb {
75 namespace OPENVDB_VERSION_NAME {
76 namespace tools {
77 
78 // Helper class that implements the actual search of the zero-crossing
79 // of the level set along the direction of a ray. This particular
80 // implementation uses iterative linear search.
81 template<typename GridT, int Iterations = 0, typename RealT = double>
83 
84 
86 
87 
105 template<typename GridT,
106  typename SearchImplT = LinearSearchImpl<GridT>,
107  int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
108  typename RayT = math::Ray<Real> >
110 {
111 public:
112  typedef GridT GridType;
113  typedef RayT RayType;
114  typedef typename RayT::RealType RealType;
115  typedef typename RayT::Vec3T Vec3Type;
116  typedef typename GridT::ValueType ValueT;
117  typedef typename GridT::TreeType TreeT;
118 
119  BOOST_STATIC_ASSERT( NodeLevel >= -1 && NodeLevel < int(TreeT::DEPTH)-1);
120  BOOST_STATIC_ASSERT(boost::is_floating_point<ValueT>::value);
121 
125  LevelSetRayIntersector(const GridT& grid, const ValueT& isoValue = zeroVal<ValueT>())
126  : mTester(grid, isoValue)
127  {
128  if (!grid.hasUniformVoxels() ) {
130  "LevelSetRayIntersector only supports uniform voxels!");
131  }
132  if (grid.getGridClass() != GRID_LEVEL_SET) {
134  "LevelSetRayIntersector only supports level sets!"
135  "\nUse Grid::setGridClass(openvdb::GRID_LEVEL_SET)");
136  }
137  }
138 
140  const ValueT& getIsoValue() const { return mTester.getIsoValue(); }
141 
144  bool intersectsIS(const RayType& iRay) const
145  {
146  if (!mTester.setIndexRay(iRay)) return false;//missed bbox
148  }
149 
154  bool intersectsIS(const RayType& iRay, RealType &iTime) const
155  {
156  if (!mTester.setIndexRay(iRay)) return false;//missed bbox
157  iTime = mTester.getIndexTime();
159  }
160 
165  bool intersectsIS(const RayType& iRay, Vec3Type& xyz) const
166  {
167  if (!mTester.setIndexRay(iRay)) return false;//missed bbox
168  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
169  mTester.getIndexPos(xyz);
170  return true;
171  }
172 
179  bool intersectsIS(const RayType& iRay, Vec3Type& xyz, RealType &iTime) const
180  {
181  if (!mTester.setIndexRay(iRay)) return false;//missed bbox
182  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
183  mTester.getIndexPos(xyz);
184  iTime = mTester.getIndexTime();
185  return true;
186  }
187 
190  bool intersectsWS(const RayType& wRay) const
191  {
192  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
194  }
195 
200  bool intersectsWS(const RayType& wRay, RealType &wTime) const
201  {
202  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
203  wTime = mTester.getWorldTime();
205  }
206 
211  bool intersectsWS(const RayType& wRay, Vec3Type& world) const
212  {
213  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
214  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
215  mTester.getWorldPos(world);
216  return true;
217  }
218 
225  bool intersectsWS(const RayType& wRay, Vec3Type& world, RealType &wTime) const
226  {
227  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
228  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
229  mTester.getWorldPos(world);
230  wTime = mTester.getWorldTime();
231  return true;
232  }
233 
240  bool intersectsWS(const RayType& wRay, Vec3Type& world, Vec3Type& normal) const
241  {
242  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
243  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
244  mTester.getWorldPosAndNml(world, normal);
245  return true;
246  }
247 
256  bool intersectsWS(const RayType& wRay, Vec3Type& world, Vec3Type& normal, RealType &wTime) const
257  {
258  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
259  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
260  mTester.getWorldPosAndNml(world, normal);
261  wTime = mTester.getWorldTime();
262  return true;
263  }
264 
265 private:
266 
267  mutable SearchImplT mTester;
268 
269 };// LevelSetRayIntersector
270 
271 
273 
274 
300 template<typename GridT,
301  int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
302  typename RayT = math::Ray<Real> >
304 {
305 public:
306  typedef GridT GridType;
307  typedef RayT RayType;
308  typedef typename RayT::RealType RealType;
309  typedef typename GridT::TreeType::RootNodeType RootType;
311 
312  BOOST_STATIC_ASSERT( NodeLevel >= 0 && NodeLevel < int(TreeT::DEPTH)-1);
313 
322  VolumeRayIntersector(const GridT& grid, int dilationCount = 0)
323  : mIsMaster(true)
324  , mTree(new TreeT(grid.tree(), false, TopologyCopy()))
325  , mGrid(&grid)
326  , mAccessor(*mTree)
327  {
328  if (!grid.hasUniformVoxels() ) {
330  "VolumeRayIntersector only supports uniform voxels!");
331  }
332  if ( grid.empty() ) {
333  OPENVDB_THROW(RuntimeError, "LinearSearchImpl does not supports empty grids");
334  }
335 
336  // Dilate active voxels to better account for the size of interpolation kernels
337  tools::dilateVoxels(*mTree, dilationCount);
338 
339  mTree->root().evalActiveBoundingBox(mBBox, /*visit individual voxels*/false);
340 
341  mBBox.max().offset(1);//padding so the bbox of a node becomes (origin,origin + node_dim)
342  }
343 
351  VolumeRayIntersector(const GridT& grid, const math::CoordBBox& bbox)
352  : mIsMaster(true)
353  , mTree(new TreeT(grid.tree(), false, TopologyCopy()))
354  , mGrid(&grid)
355  , mAccessor(*mTree)
356  , mBBox(bbox)
357  {
358  if (!grid.hasUniformVoxels() ) {
360  "VolumeRayIntersector only supports uniform voxels!");
361  }
362  if ( grid.empty() ) {
363  OPENVDB_THROW(RuntimeError, "LinearSearchImpl does not supports empty grids");
364  }
365  }
366 
373  : mIsMaster(false)
374  , mTree(other.mTree)//shallow copy
375  , mGrid(other.mGrid)//shallow copy
376  , mAccessor(*mTree)//initialize new (vs deep copy)
377  , mRay(other.mRay)//deep copy
378  , mTmax(other.mTmax)//deep copy
379  , mBBox(other.mBBox)//deep copy
380  {
381  }
382 
384  ~VolumeRayIntersector() { if (mIsMaster) delete mTree; }
385 
391  inline bool setIndexRay(const RayT& iRay)
392  {
393  mRay = iRay;
394  const bool hit = mRay.clip(mBBox);
395  if (hit) mTmax = mRay.t1();
396  return hit;
397  }
398 
410  inline bool setWorldRay(const RayT& wRay)
411  {
412  return this->setIndexRay(wRay.worldToIndex(*mGrid));
413  }
414 
415  inline typename RayT::TimeSpan march()
416  {
417  const typename RayT::TimeSpan t = mHDDA.march(mRay, mAccessor);
418  if (t.t1>0) mRay.setTimes(t.t1 + math::Delta<RealType>::value(), mTmax);
419  return t;
420  }
421 
436  inline bool march(RealType& t0, RealType& t1)
437  {
438  const typename RayT::TimeSpan t = this->march();
439  t.get(t0, t1);
440  return t.valid();
441  }
442 
451  template <typename ListType>
452  inline void hits(ListType& list)
453  {
454  mHDDA.hits(mRay, mAccessor, list);
455  }
456 
459  inline Vec3R getIndexPos(RealType time) const { return mRay(time); }
460 
463  inline Vec3R getWorldPos(RealType time) const { return mGrid->indexToWorld(mRay(time)); }
464 
465  inline RealType getWorldTime(RealType time) const
466  {
467  return time*mGrid->transform().baseMap()->applyJacobian(mRay.dir()).length();
468  }
469 
471  const GridT& grid() const { return *mGrid; }
472 
475  const TreeT& tree() const { return *mTree; }
476 
478  const math::CoordBBox& bbox() const { return mBBox; }
479 
484  void print(std::ostream& os = std::cout, int verboseLevel = 1)
485  {
486  if (verboseLevel>0) {
487  os << "BBox: " << mBBox << std::endl;
488  if (verboseLevel==2) {
489  mTree->print(os, 1);
490  } else if (verboseLevel>2) {
491  mTree->print(os, 2);
492  }
493  }
494  }
495 
496 private:
497 
498  typedef typename tree::ValueAccessor<const TreeT,/*IsSafe=*/false> AccessorT;
499 
500  const bool mIsMaster;
501  TreeT* mTree;
502  const GridT* mGrid;
503  AccessorT mAccessor;
504  RayT mRay;
505  RealType mTmax;
506  math::CoordBBox mBBox;
508 
509 };// VolumeRayIntersector
510 
511 
513 
514 
538 template<typename GridT, int Iterations, typename RealT>
539 class LinearSearchImpl
540 {
541 public:
543  typedef typename GridT::ValueType ValueT;
544  typedef typename GridT::ConstAccessor AccessorT;
546 
550  LinearSearchImpl(const GridT& grid, const ValueT& isoValue = zeroVal<ValueT>())
551  : mStencil(grid),
552  mIsoValue(isoValue),
553  mMinValue(isoValue - ValueT(2 * grid.voxelSize()[0])),
554  mMaxValue(isoValue + ValueT(2 * grid.voxelSize()[0]))
555  {
556  if ( grid.empty() ) {
557  OPENVDB_THROW(RuntimeError, "LinearSearchImpl does not supports empty grids");
558  }
559  if (mIsoValue<= -grid.background() ||
560  mIsoValue>= grid.background() ){
561  OPENVDB_THROW(ValueError, "The iso-value must be inside the narrow-band!");
562  }
563  grid.tree().root().evalActiveBoundingBox(mBBox, /*visit individual voxels*/false);
564  }
565 
567  const ValueT& getIsoValue() const { return mIsoValue; }
568 
572  inline bool setIndexRay(const RayT& iRay)
573  {
574  mRay = iRay;
575  return mRay.clip(mBBox);//did it hit the bbox
576  }
577 
581  inline bool setWorldRay(const RayT& wRay)
582  {
583  mRay = wRay.worldToIndex(mStencil.grid());
584  return mRay.clip(mBBox);//did it hit the bbox
585  }
586 
589  inline void getIndexPos(Vec3d& xyz) const { xyz = mRay(mTime); }
590 
593  inline void getWorldPos(Vec3d& xyz) const { xyz = mStencil.grid().indexToWorld(mRay(mTime)); }
594 
598  inline void getWorldPosAndNml(Vec3d& xyz, Vec3d& nml)
599  {
600  this->getIndexPos(xyz);
601  mStencil.moveTo(xyz);
602  nml = mStencil.gradient(xyz);
603  nml.normalize();
604  xyz = mStencil.grid().indexToWorld(xyz);
605  }
606 
608  inline RealT getIndexTime() const { return mTime; }
609 
611  inline RealT getWorldTime() const
612  {
613  return mTime*mStencil.grid().transform().baseMap()->applyJacobian(mRay.dir()).length();
614  }
615 
616 private:
617 
620  inline void init(RealT t0)
621  {
622  mT[0] = t0;
623  mV[0] = static_cast<ValueT>(this->interpValue(t0));
624  }
625 
626  inline void setRange(RealT t0, RealT t1) { mRay.setTimes(t0, t1); }
627 
629  inline const RayT& ray() const { return mRay; }
630 
632  template <typename NodeT>
633  inline bool hasNode(const Coord& ijk)
634  {
635  return mStencil.accessor().template probeConstNode<NodeT>(ijk) != NULL;
636  }
637 
643  inline bool operator()(const Coord& ijk, RealT time)
644  {
645  ValueT V;
646  if (mStencil.accessor().probeValue(ijk, V) &&//within narrow band
647  V>mMinValue && V<mMaxValue) {// and close to iso-value?
648  mT[1] = time;
649  mV[1] = static_cast<ValueT>(this->interpValue(time));
650  if (math::ZeroCrossing(mV[0], mV[1])) {
651  mTime = this->interpTime();
653  for (int n=0; Iterations>0 && n<Iterations; ++n) {//resolved at compile-time
654  V = static_cast<ValueT>(this->interpValue(mTime));
655  const int m = math::ZeroCrossing(mV[0], V) ? 1 : 0;
656  mV[m] = V;
657  mT[m] = mTime;
658  mTime = this->interpTime();
659  }
661  return true;
662  }
663  mT[0] = mT[1];
664  mV[0] = mV[1];
665  }
666  return false;
667  }
668 
669  inline RealT interpTime()
670  {
671  assert(math::isApproxLarger(mT[1], mT[0], 1e-6));
672  return mT[0]+(mT[1]-mT[0])*mV[0]/(mV[0]-mV[1]);
673  }
674 
675  inline RealT interpValue(RealT time)
676  {
677  const Vec3R pos = mRay(time);
678  mStencil.moveTo(pos);
679  return mStencil.interpolation(pos) - mIsoValue;
680  }
681 
682  template<typename, int> friend struct math::LevelSetHDDA;
683 
684  RayT mRay;
685  StencilT mStencil;
686  RealT mTime;//time of intersection
687  ValueT mV[2];
688  RealT mT[2];
689  const ValueT mIsoValue, mMinValue, mMaxValue;
690  math::CoordBBox mBBox;
691 };// LinearSearchImpl
692 
693 } // namespace tools
694 } // namespace OPENVDB_VERSION_NAME
695 } // namespace openvdb
696 
697 #endif // OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED
698 
699 // Copyright (c) 2012-2015 DreamWorks Animation LLC
700 // All rights reserved. This software is distributed under the
701 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
VolumeRayIntersector(const GridT &grid, const math::CoordBBox &bbox)
Grid and BBox constructor.
Definition: RayIntersector.h:351
This class provides the public API for intersecting a ray with a narrow-band level set...
Definition: RayIntersector.h:109
bool intersectsWS(const RayType &wRay, Vec3Type &world, Vec3Type &normal) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:240
bool intersectsWS(const RayType &wRay, Vec3Type &world, Vec3Type &normal, RealType &wTime) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:256
bool intersectsWS(const RayType &wRay, RealType &wTime) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:200
bool setIndexRay(const RayT &iRay)
Return false if the index ray misses the bbox of the grid.
Definition: RayIntersector.h:391
bool intersectsWS(const RayType &wRay) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:190
RealT getIndexTime() const
Return the time of intersection along the index ray.
Definition: RayIntersector.h:608
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:701
bool setWorldRay(const RayT &wRay)
Return false if the ray misses the bbox of the grid.
Definition: RayIntersector.h:581
Helper class that implements Hierarchical Digital Differential Analyzers and is specialized for ray i...
Definition: DDA.h:170
Delta for small floating-point offsets.
Definition: Math.h:132
Definition: Exceptions.h:88
Implements linear iterative search for an iso-value of the level set along the direction of the ray...
Definition: RayIntersector.h:82
GridT::ConstAccessor AccessorT
Definition: RayIntersector.h:544
RayT::RealType RealType
Definition: RayIntersector.h:114
This class provides the public API for intersecting a ray with a generic (e.g. density) volume...
Definition: RayIntersector.h:303
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Helper class that implements Hierarchical Digital Differential Analyzers for ray intersections agains...
Definition: DDA.h:213
void getWorldPos(Vec3d &xyz) const
Get the intersection point in world space.
Definition: RayIntersector.h:593
bool intersectsIS(const RayType &iRay, Vec3Type &xyz, RealType &iTime) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:179
VolumeRayIntersector(const GridT &grid, int dilationCount=0)
Grid constructor.
Definition: RayIntersector.h:322
bool intersectsIS(const RayType &iRay) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:144
tree::Tree< typename RootType::template ValueConverter< bool >::Type > TreeT
Definition: RayIntersector.h:310
LevelSetRayIntersector(const GridT &grid, const ValueT &isoValue=zeroVal< ValueT >())
Constructor.
Definition: RayIntersector.h:125
OPENVDB_STATIC_SPECIALIZATION void dilateVoxels(TreeType &tree, int iterations=1, NearestNeighbors nn=NN_FACE)
Topologically dilate all leaf-level active voxels in a tree using one of three nearest neighbor conne...
Definition: Morphology.h:778
math::Ray< RealT > RayT
Definition: RayIntersector.h:542
Definition: Tree.h:203
const TreeT & tree() const
Return a const reference to the (potentially dilated) bool tree used to accelerate the ray marching...
Definition: RayIntersector.h:475
bool intersectsIS(const RayType &iRay, Vec3Type &xyz) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:165
bool setWorldRay(const RayT &wRay)
Return false if the world ray misses the bbox of the grid.
Definition: RayIntersector.h:410
RealT getWorldTime() const
Return the time of intersection along the world ray.
Definition: RayIntersector.h:611
bool clip(const Vec3T &center, RealT radius)
Return true if this ray intersects the specified sphere.
Definition: Ray.h:244
const ValueT & getIsoValue() const
Return the iso-value used for ray-intersections.
Definition: RayIntersector.h:140
GridT::TreeType TreeT
Definition: RayIntersector.h:117
#define OPENVDB_VERSION_NAME
Definition: version.h:43
RayT::RealType RealType
Definition: RayIntersector.h:308
RayT RayType
Definition: RayIntersector.h:307
Definition: Exceptions.h:86
Implementation of morphological dilation and erosion.
GridT GridType
Definition: RayIntersector.h:112
GridT::TreeType::RootNodeType RootType
Definition: RayIntersector.h:309
Definition: Exceptions.h:39
bool intersectsWS(const RayType &wRay, Vec3Type &world) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:211
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:129
void hits(ListType &list)
Generates a list of hits along the ray.
Definition: RayIntersector.h:452
Definition: Types.h:419
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 march(RealType &t0, RealType &t1)
Return true if the ray intersects active values, i.e. either active voxels or tiles. Only when a hit is detected are t0 and t1 updated with the corresponding entry and exit times along the INDEX ray!
Definition: RayIntersector.h:436
Vec3< double > Vec3d
Definition: Vec3.h:643
Definition: Types.h:206
RayT::TimeSpan march()
Definition: RayIntersector.h:415
LinearSearchImpl(const GridT &grid, const ValueT &isoValue=zeroVal< ValueT >())
Constructor from a grid.
Definition: RayIntersector.h:550
Vec3R getIndexPos(RealType time) const
Return the floating-point index position along the current index ray at the specified time...
Definition: RayIntersector.h:459
GridT::ValueType ValueT
Definition: RayIntersector.h:543
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:398
const ValueT & getIsoValue() const
Return the iso-value used for ray-intersections.
Definition: RayIntersector.h:567
~VolumeRayIntersector()
Destructor.
Definition: RayIntersector.h:384
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:130
RealType getWorldTime(RealType time) const
Definition: RayIntersector.h:465
const GridT & grid() const
Return a const reference to the input grid.
Definition: RayIntersector.h:471
bool setIndexRay(const RayT &iRay)
Return false if the ray misses the bbox of the grid.
Definition: RayIntersector.h:572
Definition: ValueAccessor.h:219
Vec3R getWorldPos(RealType time) const
Return the floating-point world position along the current index ray at the specified time...
Definition: RayIntersector.h:463
RayT::Vec3T Vec3Type
Definition: RayIntersector.h:115
GridT::ValueType ValueT
Definition: RayIntersector.h:116
const math::CoordBBox & bbox() const
Return a const reference to the BBOX of the grid.
Definition: RayIntersector.h:478
void getIndexPos(Vec3d &xyz) const
Get the intersection point in index space.
Definition: RayIntersector.h:589
bool intersectsIS(const RayType &iRay, RealType &iTime) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:154
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
void getWorldPosAndNml(Vec3d &xyz, Vec3d &nml)
Get the intersection point and normal in world space.
Definition: RayIntersector.h:598
RayT RayType
Definition: RayIntersector.h:113
bool intersectsWS(const RayType &wRay, Vec3Type &world, RealType &wTime) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:225
VolumeRayIntersector(const VolumeRayIntersector &other)
Shallow copy constructor.
Definition: RayIntersector.h:372
void print(std::ostream &os=std::cout, int verboseLevel=1)
Print bbox, statistics, memory usage and other information.
Definition: RayIntersector.h:484
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:252
math::BoxStencil< GridT > StencilT
Definition: RayIntersector.h:545
GridT GridType
Definition: RayIntersector.h:306
Definition: Ray.h:53