OpenVDB  6.2.0
RayIntersector.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 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:
542  using RayT = math::Ray<RealT>;
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) 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/ )
LevelSetRayIntersector(const GridT &grid, const ValueT &isoValue=zeroVal< ValueT >())
Constructor.
Definition: RayIntersector.h:126
bool intersectsWS(const RayType &wRay) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:191
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
typename GridT::TreeType::RootNodeType RootType
Definition: RayIntersector.h:310
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:387
bool intersectsIS(const RayType &iRay, Vec3Type &xyz) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:166
Helper class that implements Hierarchical Digital Differential Analyzers for ray intersections agains...
Definition: DDA.h:215
RealT getIndexTime() const
Return the time of intersection along the index ray.
Definition: RayIntersector.h:609
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
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
Delta for small floating-point offsets.
Definition: Math.h:124
RealT getWorldTime() const
Return the time of intersection along the world ray.
Definition: RayIntersector.h:612
const TreeT & tree() const
Return a const reference to the (potentially dilated) bool tree used to accelerate the ray marching...
Definition: RayIntersector.h:476
bool setWorldRay(const RayT &wRay)
Return false if the ray misses the bbox of the grid.
Definition: RayIntersector.h:582
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
typename RayT::Vec3T Vec3Type
Definition: RayIntersector.h:115
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
Definition: Exceptions.h:90
typename GridT::ValueType ValueT
Definition: RayIntersector.h:544
VolumeRayIntersector(const GridT &grid, const math::CoordBBox &bbox)
Grid and BBox constructor.
Definition: RayIntersector.h:352
Vec3R getIndexPos(RealType time) const
Return the floating-point index position along the current index ray at the specified time...
Definition: RayIntersector.h:460
typename RayT::RealType RealType
Definition: RayIntersector.h:114
RayT RayType
Definition: RayIntersector.h:113
RayT RayType
Definition: RayIntersector.h:308
void print(std::ostream &os=std::cout, int verboseLevel=1)
Print bbox, statistics, memory usage and other information.
Definition: RayIntersector.h:485
void getWorldPosAndNml(VecT &xyz, VecT &nml)
Get the intersection point and normal in world space.
Definition: RayIntersector.h:599
void getIndexPos(VecT &xyz) const
Get the intersection point in index space.
Definition: RayIntersector.h:590
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:750
bool intersectsIS(const RayType &iRay) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:145
LinearSearchImpl(const GridT &grid, const ValueT &isoValue=zeroVal< ValueT >())
Constructor from a grid.
Definition: RayIntersector.h:551
typename GridT::TreeType TreeT
Definition: RayIntersector.h:117
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::RealType RealType
Definition: RayIntersector.h:309
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:128
Helper class that implements Hierarchical Digital Differential Analyzers and is specialized for ray i...
Definition: DDA.h:172
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:275
GridT GridType
Definition: RayIntersector.h:112
VolumeRayIntersector(const VolumeRayIntersector &other)
Shallow copy constructor.
Definition: RayIntersector.h:373
RayT::TimeSpan march()
Definition: RayIntersector.h:416
Implements linear iterative search for an iso-value of the level set along the direction of the ray...
Definition: RayIntersector.h:82
Implementation of morphological dilation and erosion.
Definition: Tree.h:203
Definition: Exceptions.h:40
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:149
void hits(ListType &list)
Generates a list of hits along the ray.
Definition: RayIntersector.h:453
~VolumeRayIntersector()
Destructor.
Definition: RayIntersector.h:385
const ValueT & getIsoValue() const
Return the iso-value used for ray-intersections.
Definition: RayIntersector.h:141
Definition: Ray.h:53
typename GridT::ConstAccessor AccessorT
Definition: RayIntersector.h:545
Definition: Types.h:504
bool clip(const Vec3T &center, RealT radius)
Return true if this ray intersects the specified sphere.
Definition: Ray.h:244
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
typename GridT::ValueType ValueT
Definition: RayIntersector.h:116
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:727
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:150
This class provides the public API for intersecting a ray with a generic (e.g. density) volume...
Definition: RayIntersector.h:304
Definition: ValueAccessor.h:220
RealType getWorldTime(RealType time) const
Definition: RayIntersector.h:466
Vec3R getWorldPos(RealType time) const
Return the floating-point world position along the current index ray at the specified time...
Definition: RayIntersector.h:464
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:406
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
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
Definition: Exceptions.h:92
bool intersectsWS(const RayType &wRay, Vec3Type &world) const
Return true if the world-space ray intersects the level set.
Definition: RayIntersector.h:212
void getWorldPos(VecT &xyz) const
Get the intersection point in world space.
Definition: RayIntersector.h:594
const math::CoordBBox & bbox() const
Return a const reference to the BBOX of the grid.
Definition: RayIntersector.h:479
bool setWorldRay(const RayT &wRay)
Return false if the world ray misses the bbox of the grid.
Definition: RayIntersector.h:411
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:180
const GridT & grid() const
Return a const reference to the input grid.
Definition: RayIntersector.h:472
bool intersectsIS(const RayType &iRay, RealType &iTime) const
Return true if the index-space ray intersects the level set.
Definition: RayIntersector.h:155
Digital Differential Analyzers specialized for VDB.
A Ray class.
const ValueT & getIsoValue() const
Return the iso-value used for ray-intersections.
Definition: RayIntersector.h:568
VolumeRayIntersector(const GridT &grid, int dilationCount=0)
Grid constructor.
Definition: RayIntersector.h:323
bool setIndexRay(const RayT &iRay)
Return false if the index ray misses the bbox of the grid.
Definition: RayIntersector.h:392
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
This class provides the public API for intersecting a ray with a narrow-band level set...
Definition: RayIntersector.h:109
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:859
bool setIndexRay(const RayT &iRay)
Return false if the ray misses the bbox of the grid.
Definition: RayIntersector.h:573
GridT GridType
Definition: RayIntersector.h:307