OpenVDB  5.1.0
RayIntersector.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 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 <iostream>
70 #include <type_traits>
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  using GridType = GridT;
113  using RayType = RayT;
114  using RealType = typename RayT::RealType;
115  using Vec3Type = typename RayT::Vec3T;
116  using ValueT = typename GridT::ValueType;
117  using TreeT = typename GridT::TreeType;
118 
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");
122 
126  LevelSetRayIntersector(const GridT& grid, const ValueT& isoValue = zeroVal<ValueT>())
127  : mTester(grid, isoValue)
128  {
129  if (!grid.hasUniformVoxels() ) {
131  "LevelSetRayIntersector only supports uniform voxels!");
132  }
133  if (grid.getGridClass() != GRID_LEVEL_SET) {
135  "LevelSetRayIntersector only supports level sets!"
136  "\nUse Grid::setGridClass(openvdb::GRID_LEVEL_SET)");
137  }
138  }
139 
141  const ValueT& getIsoValue() const { return mTester.getIsoValue(); }
142 
145  bool intersectsIS(const RayType& iRay) const
146  {
147  if (!mTester.setIndexRay(iRay)) return false;//missed bbox
149  }
150 
155  bool intersectsIS(const RayType& iRay, RealType &iTime) const
156  {
157  if (!mTester.setIndexRay(iRay)) return false;//missed bbox
158  iTime = mTester.getIndexTime();
160  }
161 
166  bool intersectsIS(const RayType& iRay, Vec3Type& xyz) const
167  {
168  if (!mTester.setIndexRay(iRay)) return false;//missed bbox
169  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
170  mTester.getIndexPos(xyz);
171  return true;
172  }
173 
180  bool intersectsIS(const RayType& iRay, Vec3Type& xyz, RealType &iTime) const
181  {
182  if (!mTester.setIndexRay(iRay)) return false;//missed bbox
183  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
184  mTester.getIndexPos(xyz);
185  iTime = mTester.getIndexTime();
186  return true;
187  }
188 
191  bool intersectsWS(const RayType& wRay) const
192  {
193  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
195  }
196 
201  bool intersectsWS(const RayType& wRay, RealType &wTime) const
202  {
203  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
204  wTime = mTester.getWorldTime();
206  }
207 
212  bool intersectsWS(const RayType& wRay, Vec3Type& world) const
213  {
214  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
215  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
216  mTester.getWorldPos(world);
217  return true;
218  }
219 
226  bool intersectsWS(const RayType& wRay, Vec3Type& world, RealType &wTime) const
227  {
228  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
229  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
230  mTester.getWorldPos(world);
231  wTime = mTester.getWorldTime();
232  return true;
233  }
234 
241  bool intersectsWS(const RayType& wRay, Vec3Type& world, Vec3Type& normal) const
242  {
243  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
244  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
245  mTester.getWorldPosAndNml(world, normal);
246  return true;
247  }
248 
257  bool intersectsWS(const RayType& wRay, Vec3Type& world, Vec3Type& normal, RealType &wTime) const
258  {
259  if (!mTester.setWorldRay(wRay)) return false;//missed bbox
260  if (!math::LevelSetHDDA<TreeT, NodeLevel>::test(mTester)) return false;//missed level set
261  mTester.getWorldPosAndNml(world, normal);
262  wTime = mTester.getWorldTime();
263  return true;
264  }
265 
266 private:
267 
268  mutable SearchImplT mTester;
269 
270 };// LevelSetRayIntersector
271 
272 
274 
275 
301 template<typename GridT,
302  int NodeLevel = GridT::TreeType::RootNodeType::ChildNodeType::LEVEL,
303  typename RayT = math::Ray<Real> >
305 {
306 public:
307  using GridType = GridT;
308  using RayType = RayT;
309  using RealType = typename RayT::RealType;
310  using RootType = typename GridT::TreeType::RootNodeType;
312 
313  static_assert(NodeLevel >= 0 && NodeLevel < int(TreeT::DEPTH)-1, "NodeLevel out of range");
314 
323  VolumeRayIntersector(const GridT& grid, int dilationCount = 0)
324  : mIsMaster(true)
325  , mTree(new TreeT(grid.tree(), false, TopologyCopy()))
326  , mGrid(&grid)
327  , mAccessor(*mTree)
328  {
329  if (!grid.hasUniformVoxels() ) {
331  "VolumeRayIntersector only supports uniform voxels!");
332  }
333  if ( grid.empty() ) {
334  OPENVDB_THROW(RuntimeError, "LinearSearchImpl does not supports empty grids");
335  }
336 
337  // Dilate active voxels to better account for the size of interpolation kernels
338  tools::dilateVoxels(*mTree, dilationCount);
339 
340  mTree->root().evalActiveBoundingBox(mBBox, /*visit individual voxels*/false);
341 
342  mBBox.max().offset(1);//padding so the bbox of a node becomes (origin,origin + node_dim)
343  }
344 
352  VolumeRayIntersector(const GridT& grid, const math::CoordBBox& bbox)
353  : mIsMaster(true)
354  , mTree(new TreeT(grid.tree(), false, TopologyCopy()))
355  , mGrid(&grid)
356  , mAccessor(*mTree)
357  , mBBox(bbox)
358  {
359  if (!grid.hasUniformVoxels() ) {
361  "VolumeRayIntersector only supports uniform voxels!");
362  }
363  if ( grid.empty() ) {
364  OPENVDB_THROW(RuntimeError, "LinearSearchImpl does not supports empty grids");
365  }
366  }
367 
374  : mIsMaster(false)
375  , mTree(other.mTree)//shallow copy
376  , mGrid(other.mGrid)//shallow copy
377  , mAccessor(*mTree)//initialize new (vs deep copy)
378  , mRay(other.mRay)//deep copy
379  , mTmax(other.mTmax)//deep copy
380  , mBBox(other.mBBox)//deep copy
381  {
382  }
383 
385  ~VolumeRayIntersector() { if (mIsMaster) delete mTree; }
386 
392  inline bool setIndexRay(const RayT& iRay)
393  {
394  mRay = iRay;
395  const bool hit = mRay.clip(mBBox);
396  if (hit) mTmax = mRay.t1();
397  return hit;
398  }
399 
411  inline bool setWorldRay(const RayT& wRay)
412  {
413  return this->setIndexRay(wRay.worldToIndex(*mGrid));
414  }
415 
416  inline typename RayT::TimeSpan march()
417  {
418  const typename RayT::TimeSpan t = mHDDA.march(mRay, mAccessor);
419  if (t.t1>0) mRay.setTimes(t.t1 + math::Delta<RealType>::value(), mTmax);
420  return t;
421  }
422 
437  inline bool march(RealType& t0, RealType& t1)
438  {
439  const typename RayT::TimeSpan t = this->march();
440  t.get(t0, t1);
441  return t.valid();
442  }
443 
452  template <typename ListType>
453  inline void hits(ListType& list)
454  {
455  mHDDA.hits(mRay, mAccessor, list);
456  }
457 
460  inline Vec3R getIndexPos(RealType time) const { return mRay(time); }
461 
464  inline Vec3R getWorldPos(RealType time) const { return mGrid->indexToWorld(mRay(time)); }
465 
466  inline RealType getWorldTime(RealType time) const
467  {
468  return time*mGrid->transform().baseMap()->applyJacobian(mRay.dir()).length();
469  }
470 
472  const GridT& grid() const { return *mGrid; }
473 
476  const TreeT& tree() const { return *mTree; }
477 
479  const math::CoordBBox& bbox() const { return mBBox; }
480 
485  void print(std::ostream& os = std::cout, int verboseLevel = 1)
486  {
487  if (verboseLevel>0) {
488  os << "BBox: " << mBBox << std::endl;
489  if (verboseLevel==2) {
490  mTree->print(os, 1);
491  } else if (verboseLevel>2) {
492  mTree->print(os, 2);
493  }
494  }
495  }
496 
497 private:
498  using AccessorT = typename tree::ValueAccessor<const TreeT,/*IsSafe=*/false>;
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:
544  using ValueT = typename GridT::ValueType;
545  using AccessorT = typename GridT::ConstAccessor;
547 
551  LinearSearchImpl(const GridT& grid, const ValueT& isoValue = zeroVal<ValueT>())
552  : mStencil(grid),
553  mIsoValue(isoValue),
554  mMinValue(isoValue - ValueT(2 * grid.voxelSize()[0])),
555  mMaxValue(isoValue + ValueT(2 * grid.voxelSize()[0]))
556  {
557  if ( grid.empty() ) {
558  OPENVDB_THROW(RuntimeError, "LinearSearchImpl does not supports empty grids");
559  }
560  if (mIsoValue<= -grid.background() ||
561  mIsoValue>= grid.background() ){
562  OPENVDB_THROW(ValueError, "The iso-value must be inside the narrow-band!");
563  }
564  grid.tree().root().evalActiveBoundingBox(mBBox, /*visit individual voxels*/false);
565  }
566 
568  const ValueT& getIsoValue() const { return mIsoValue; }
569 
573  inline bool setIndexRay(const RayT& iRay)
574  {
575  mRay = iRay;
576  return mRay.clip(mBBox);//did it hit the bbox
577  }
578 
582  inline bool setWorldRay(const RayT& wRay)
583  {
584  mRay = wRay.worldToIndex(mStencil.grid());
585  return mRay.clip(mBBox);//did it hit the bbox
586  }
587 
590  inline void getIndexPos(VecT& xyz) const { xyz = mRay(mTime); }
591 
594  inline void getWorldPos(VecT& xyz) const { xyz = mStencil.grid().indexToWorld(mRay(mTime)); }
595 
599  inline void getWorldPosAndNml(VecT& xyz, VecT& nml)
600  {
601  this->getIndexPos(xyz);
602  mStencil.moveTo(xyz);
603  nml = mStencil.gradient(xyz);
604  nml.normalize();
605  xyz = mStencil.grid().indexToWorld(xyz);
606  }
607 
609  inline RealT getIndexTime() const { return mTime; }
610 
612  inline RealT getWorldTime() const
613  {
614  return mTime*mStencil.grid().transform().baseMap()->applyJacobian(mRay.dir()).length();
615  }
616 
617 private:
618 
621  inline void init(RealT t0)
622  {
623  mT[0] = t0;
624  mV[0] = static_cast<ValueT>(this->interpValue(t0));
625  }
626 
627  inline void setRange(RealT t0, RealT t1) { mRay.setTimes(t0, t1); }
628 
630  inline const RayT& ray() const { return mRay; }
631 
633  template <typename NodeT>
634  inline bool hasNode(const Coord& ijk)
635  {
636  return mStencil.accessor().template probeConstNode<NodeT>(ijk) != nullptr;
637  }
638 
644  inline bool operator()(const Coord& ijk, RealT time)
645  {
646  ValueT V;
647  if (mStencil.accessor().probeValue(ijk, V) &&//within narrow band
648  V>mMinValue && V<mMaxValue) {// and close to iso-value?
649  mT[1] = time;
650  mV[1] = static_cast<ValueT>(this->interpValue(time));
651  if (math::ZeroCrossing(mV[0], mV[1])) {
652  mTime = this->interpTime();
654  for (int n=0; Iterations>0 && n<Iterations; ++n) {//resolved at compile-time
655  V = static_cast<ValueT>(this->interpValue(mTime));
656  const int m = math::ZeroCrossing(mV[0], V) ? 1 : 0;
657  mV[m] = V;
658  mT[m] = mTime;
659  mTime = this->interpTime();
660  }
662  return true;
663  }
664  mT[0] = mT[1];
665  mV[0] = mV[1];
666  }
667  return false;
668  }
669 
670  inline RealT interpTime()
671  {
672  assert( math::isApproxLarger(mT[1], mT[0], RealT(1e-6) ) );
673  return mT[0]+(mT[1]-mT[0])*mV[0]/(mV[0]-mV[1]);
674  }
675 
676  inline RealT interpValue(RealT time)
677  {
678  const VecT pos = mRay(time);
679  mStencil.moveTo(pos);
680  return mStencil.interpolation(pos) - mIsoValue;
681  }
682 
683  template<typename, int> friend struct math::LevelSetHDDA;
684 
685  RayT mRay;
686  StencilT mStencil;
687  RealT mTime;//time of intersection
688  ValueT mV[2];
689  RealT mT[2];
690  const ValueT mIsoValue, mMinValue, mMaxValue;
691  math::CoordBBox mBBox;
692 };// LinearSearchImpl
693 
694 } // namespace tools
695 } // namespace OPENVDB_VERSION_NAME
696 } // namespace openvdb
697 
698 #endif // OPENVDB_TOOLS_RAYINTERSECTOR_HAS_BEEN_INCLUDED
699 
700 // Copyright (c) 2012-2018 DreamWorks Animation LLC
701 // All rights reserved. This software is distributed under the
702 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Definition: Ray.h:53
LevelSetRayIntersector(const GridT &grid, const ValueT &isoValue=zeroVal< ValueT >())
Constructor.
Definition: RayIntersector.h:126
This class provides the public API for intersecting a ray with a narrow-band level set...
Definition: RayIntersector.h:109
RealT getWorldTime() const
Return the time of intersection along the world ray.
Definition: RayIntersector.h:612
bool intersectsIS(const RayType &iRay, Vec3Type &xyz) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:166
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
bool setIndexRay(const RayT &iRay)
Return false if the ray misses the bbox of the grid.
Definition: RayIntersector.h:573
bool setIndexRay(const RayT &iRay)
Return false if the index ray misses the bbox of the grid.
Definition: RayIntersector.h:392
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
bool intersectsIS(const RayType &iRay) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:145
bool intersectsWS(const RayType &wRay, RealType &wTime) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:201
typename RayT::Vec3T Vec3Type
Definition: RayIntersector.h:115
bool clip(const Vec3T &center, RealT radius)
Return true if this ray intersects the specified sphere.
Definition: Ray.h:244
void getWorldPosAndNml(VecT &xyz, VecT &nml)
Get the intersection point and normal in world space.
Definition: RayIntersector.h:599
VolumeRayIntersector(const GridT &grid, const math::CoordBBox &bbox)
Grid and BBox constructor.
Definition: RayIntersector.h:352
bool intersectsWS(const RayType &wRay, Vec3Type &world, Vec3Type &normal) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:241
void print(std::ostream &os=std::cout, int verboseLevel=1)
Print bbox, statistics, memory usage and other information.
Definition: RayIntersector.h:485
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:515
typename RayT::RealType RealType
Definition: RayIntersector.h:114
void getIndexPos(VecT &xyz) const
Get the intersection point in index space.
Definition: RayIntersector.h:590
const math::CoordBBox & bbox() const
Return a const reference to the BBOX of the grid.
Definition: RayIntersector.h:479
VolumeRayIntersector(const VolumeRayIntersector &other)
Shallow copy constructor.
Definition: RayIntersector.h:373
Vec3R getWorldPos(RealType time) const
Return the floating-point world position along the current index ray at the specified time...
Definition: RayIntersector.h:464
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:226
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:857
Implements linear iterative search for an iso-value of the level set along the direction of the ray...
Definition: RayIntersector.h:82
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
const TreeT & tree() const
Return a const reference to the (potentially dilated) bool tree used to accelerate the ray marching...
Definition: RayIntersector.h:476
typename GridT::ConstAccessor AccessorT
Definition: RayIntersector.h:545
const ValueT & getIsoValue() const
Return the iso-value used for ray-intersections.
Definition: RayIntersector.h:568
Definition: Exceptions.h:92
typename RayT::RealType RealType
Definition: RayIntersector.h:309
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
const GridT & grid() const
Return a const reference to the input grid.
Definition: RayIntersector.h:472
Implementation of morphological dilation and erosion.
Definition: Exceptions.h:40
RayT::TimeSpan march()
Definition: RayIntersector.h:416
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:129
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:377
void hits(ListType &list)
Generates a list of hits along the ray.
Definition: RayIntersector.h:453
~VolumeRayIntersector()
Destructor.
Definition: RayIntersector.h:385
Delta for small floating-point offsets.
Definition: Math.h:124
Definition: Types.h:274
LinearSearchImpl(const GridT &grid, const ValueT &isoValue=zeroVal< ValueT >())
Constructor from a grid.
Definition: RayIntersector.h:551
typename GridT::TreeType::RootNodeType RootType
Definition: RayIntersector.h:310
GridT GridType
Definition: RayIntersector.h:112
Vec3R getIndexPos(RealType time) const
Return the floating-point index position along the current index ray at the specified time...
Definition: RayIntersector.h:460
Helper class that implements Hierarchical Digital Differential Analyzers for ray intersections agains...
Definition: DDA.h:215
typename GridT::TreeType TreeT
Definition: RayIntersector.h:117
typename GridT::ValueType ValueT
Definition: RayIntersector.h:544
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:437
void getWorldPos(VecT &xyz) const
Get the intersection point in world space.
Definition: RayIntersector.h:594
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:130
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
bool intersectsIS(const RayType &iRay, RealType &iTime) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:155
RealT getIndexTime() const
Return the time of intersection along the index ray.
Definition: RayIntersector.h:609
This class provides the public API for intersecting a ray with a generic (e.g. density) volume...
Definition: RayIntersector.h:304
typename GridT::ValueType ValueT
Definition: RayIntersector.h:116
VolumeRayIntersector(const GridT &grid, int dilationCount=0)
Grid constructor.
Definition: RayIntersector.h:323
Definition: ValueAccessor.h:220
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:257
const ValueT & getIsoValue() const
Return the iso-value used for ray-intersections.
Definition: RayIntersector.h:141
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
RealType getWorldTime(RealType time) const
Definition: RayIntersector.h:466
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
Helper class that implements Hierarchical Digital Differential Analyzers and is specialized for ray i...
Definition: DDA.h:172
RayT RayType
Definition: RayIntersector.h:308
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
bool intersectsIS(const RayType &iRay, Vec3Type &xyz, RealType &iTime) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:180
bool setWorldRay(const RayT &wRay)
Return false if the ray misses the bbox of the grid.
Definition: RayIntersector.h:582
Digital Differential Analyzers specialized for VDB.
A Ray class.
bool setWorldRay(const RayT &wRay)
Return false if the world ray misses the bbox of the grid.
Definition: RayIntersector.h:411
Definition: Tree.h:203
bool intersectsWS(const RayType &wRay) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:191
GridT GridType
Definition: RayIntersector.h:307
bool intersectsWS(const RayType &wRay, Vec3Type &world) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:212
Definition: Exceptions.h:90