OpenVDB  7.0.0
VolumeAdvect.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
5 //
12 
13 #ifndef OPENVDB_TOOLS_VOLUME_ADVECT_HAS_BEEN_INCLUDED
14 #define OPENVDB_TOOLS_VOLUME_ADVECT_HAS_BEEN_INCLUDED
15 
16 #include <tbb/parallel_for.h>
17 #include <openvdb/Types.h>
18 #include <openvdb/math/Math.h>
20 #include "Interpolation.h"// for Sampler
21 #include "VelocityFields.h" // for VelocityIntegrator
22 #include "Morphology.h"//for dilateActiveValues and dilateVoxels
23 #include "Prune.h"// for prune
24 #include "Statistics.h" // for extrema
25 #include <functional>
26 
27 
28 namespace openvdb {
30 namespace OPENVDB_VERSION_NAME {
31 namespace tools {
32 
33 namespace Scheme {
39 }
40 
68 
69 template<typename VelocityGridT = Vec3fGrid,
70  bool StaggeredVelocity = false,
71  typename InterrupterType = util::NullInterrupter>
73 {
74 public:
75 
83  VolumeAdvection(const VelocityGridT& velGrid, InterrupterType* interrupter = nullptr)
84  : mVelGrid(velGrid)
85  , mInterrupter(interrupter)
86  , mIntegrator( Scheme::SEMI )
87  , mLimiter( Scheme::CLAMP )
88  , mGrainSize( 128 )
89  , mSubSteps( 1 )
90  {
91  math::Extrema e = extrema(velGrid.cbeginValueAll(), /*threading*/true);
92  e.add(velGrid.background().length());
93  mMaxVelocity = e.max();
94  }
95 
96  virtual ~VolumeAdvection()
97  {
98  }
99 
105  int spatialOrder() const { return (mIntegrator == Scheme::MAC ||
106  mIntegrator == Scheme::BFECC) ? 2 : 1; }
107 
113  int temporalOrder() const {
114  switch (mIntegrator) {
115  case Scheme::SEMI: return 1;
116  case Scheme::MID: return 2;
117  case Scheme::RK3: return 3;
118  case Scheme::RK4: return 4;
119  case Scheme::BFECC:return 2;
120  case Scheme::MAC: return 2;
121  }
122  return 0;//should never reach this point
123  }
124 
126  void setIntegrator(Scheme::SemiLagrangian integrator) { mIntegrator = integrator; }
127 
129  Scheme::SemiLagrangian getIntegrator() const { return mIntegrator; }
130 
132  void setLimiter(Scheme::Limiter limiter) { mLimiter = limiter; }
133 
135  Scheme::Limiter getLimiter() const { return mLimiter; }
136 
139  bool isLimiterOn() const { return this->spatialOrder()>1 &&
140  mLimiter != Scheme::NO_LIMITER; }
141 
144  size_t getGrainSize() const { return mGrainSize; }
145 
150  void setGrainSize(size_t grainsize) { mGrainSize = grainsize; }
151 
154  int getSubSteps() const { return mSubSteps; }
155 
161  void setSubSteps(int substeps) { mSubSteps = math::Max(1, substeps); }
162 
165  double getMaxVelocity() const { return mMaxVelocity; }
166 
177  template<typename VolumeGridT>
178  int getMaxDistance(const VolumeGridT& inGrid, double dt) const
179  {
180  if (!inGrid.hasUniformVoxels()) {
181  OPENVDB_THROW(RuntimeError, "Volume grid does not have uniform voxels!");
182  }
183  const double d = mMaxVelocity*math::Abs(dt)/inGrid.voxelSize()[0];
184  return static_cast<int>( math::RoundUp(d) );
185  }
186 
205  template<typename VolumeGridT,
206  typename VolumeSamplerT>//only C++11 allows for a default argument
207  typename VolumeGridT::Ptr advect(const VolumeGridT& inGrid, double timeStep)
208  {
209  typename VolumeGridT::Ptr outGrid = inGrid.deepCopy();
210  const double dt = timeStep/mSubSteps;
211  const int n = this->getMaxDistance(inGrid, dt);
212  dilateActiveValues( outGrid->tree(), n, NN_FACE, EXPAND_TILES);
213  this->template cook<VolumeGridT, VolumeSamplerT>(*outGrid, inGrid, dt);
214  for (int step = 1; step < mSubSteps; ++step) {
215  typename VolumeGridT::Ptr tmpGrid = outGrid->deepCopy();
216  dilateActiveValues( tmpGrid->tree(), n, NN_FACE, EXPAND_TILES);
217  this->template cook<VolumeGridT, VolumeSamplerT>(*tmpGrid, *outGrid, dt);
218  outGrid.swap( tmpGrid );
219  }
220 
221  return outGrid;
222  }
223 
251  template<typename VolumeGridT,
252  typename MaskGridT,
253  typename VolumeSamplerT>//only C++11 allows for a default argument
254  typename VolumeGridT::Ptr advect(const VolumeGridT& inGrid, const MaskGridT& mask, double timeStep)
255  {
256  if (inGrid.transform() != mask.transform()) {
257  OPENVDB_THROW(RuntimeError, "Volume grid and mask grid are misaligned! Consider "
258  "resampling either of the two grids into the index space of the other.");
259  }
260  typename VolumeGridT::Ptr outGrid = inGrid.deepCopy();
261  const double dt = timeStep/mSubSteps;
262  const int n = this->getMaxDistance(inGrid, dt);
263  dilateActiveValues( outGrid->tree(), n, NN_FACE, EXPAND_TILES);
264  outGrid->topologyIntersection( mask );
265  pruneInactive( outGrid->tree(), mGrainSize>0, mGrainSize );
266  this->template cook<VolumeGridT, VolumeSamplerT>(*outGrid, inGrid, dt);
267  outGrid->topologyUnion( inGrid );
268 
269  for (int step = 1; step < mSubSteps; ++step) {
270  typename VolumeGridT::Ptr tmpGrid = outGrid->deepCopy();
271  dilateActiveValues( tmpGrid->tree(), n, NN_FACE, EXPAND_TILES);
272  tmpGrid->topologyIntersection( mask );
273  pruneInactive( tmpGrid->tree(), mGrainSize>0, mGrainSize );
274  this->template cook<VolumeGridT, VolumeSamplerT>(*tmpGrid, *outGrid, dt);
275  tmpGrid->topologyUnion( inGrid );
276  outGrid.swap( tmpGrid );
277  }
278  return outGrid;
279  }
280 
281 private:
282  // disallow copy construction and copy by assignment!
283  VolumeAdvection(const VolumeAdvection&);// not implemented
284  VolumeAdvection& operator=(const VolumeAdvection&);// not implemented
285 
286  void start(const char* str) const
287  {
288  if (mInterrupter) mInterrupter->start(str);
289  }
290  void stop() const
291  {
292  if (mInterrupter) mInterrupter->end();
293  }
294  bool interrupt() const
295  {
296  if (mInterrupter && util::wasInterrupted(mInterrupter)) {
297  tbb::task::self().cancel_group_execution();
298  return true;
299  }
300  return false;
301  }
302 
303  template<typename VolumeGridT, typename VolumeSamplerT>
304  void cook(VolumeGridT& outGrid, const VolumeGridT& inGrid, double dt)
305  {
306  switch (mIntegrator) {
307  case Scheme::SEMI: {
308  Advect<VolumeGridT, 1, VolumeSamplerT> adv(inGrid, *this);
309  adv.cook(outGrid, dt);
310  break;
311  }
312  case Scheme::MID: {
313  Advect<VolumeGridT, 2, VolumeSamplerT> adv(inGrid, *this);
314  adv.cook(outGrid, dt);
315  break;
316  }
317  case Scheme::RK3: {
318  Advect<VolumeGridT, 3, VolumeSamplerT> adv(inGrid, *this);
319  adv.cook(outGrid, dt);
320  break;
321  }
322  case Scheme::RK4: {
323  Advect<VolumeGridT, 4, VolumeSamplerT> adv(inGrid, *this);
324  adv.cook(outGrid, dt);
325  break;
326  }
327  case Scheme::BFECC: {
328  Advect<VolumeGridT, 1, VolumeSamplerT> adv(inGrid, *this);
329  adv.cook(outGrid, dt);
330  break;
331  }
332  case Scheme::MAC: {
333  Advect<VolumeGridT, 1, VolumeSamplerT> adv(inGrid, *this);
334  adv.cook(outGrid, dt);
335  break;
336  }
337  default:
338  OPENVDB_THROW(ValueError, "Spatial difference scheme not supported!");
339  }
340  pruneInactive(outGrid.tree(), mGrainSize>0, mGrainSize);
341  }
342 
343  // Private class that implements the multi-threaded advection
344  template<typename VolumeGridT, size_t OrderRK, typename SamplerT> struct Advect;
345 
346  // Private member data of VolumeAdvection
347  const VelocityGridT& mVelGrid;
348  double mMaxVelocity;
349  InterrupterType* mInterrupter;
350  Scheme::SemiLagrangian mIntegrator;
351  Scheme::Limiter mLimiter;
352  size_t mGrainSize;
353  int mSubSteps;
354 };//end of VolumeAdvection class
355 
356 // Private class that implements the multi-threaded advection
357 template<typename VelocityGridT, bool StaggeredVelocity, typename InterrupterType>
358 template<typename VolumeGridT, size_t OrderRK, typename SamplerT>
359 struct VolumeAdvection<VelocityGridT, StaggeredVelocity, InterrupterType>::Advect
360 {
361  using TreeT = typename VolumeGridT::TreeType;
362  using AccT = typename VolumeGridT::ConstAccessor;
363  using ValueT = typename TreeT::ValueType;
364  using LeafManagerT = typename tree::LeafManager<TreeT>;
365  using LeafNodeT = typename LeafManagerT::LeafNodeType;
366  using LeafRangeT = typename LeafManagerT::LeafRange;
367  using VelocityIntegratorT = VelocityIntegrator<VelocityGridT, StaggeredVelocity>;
368  using RealT = typename VelocityIntegratorT::ElementType;
369  using VoxelIterT = typename TreeT::LeafNodeType::ValueOnIter;
370 
371  Advect(const VolumeGridT& inGrid, const VolumeAdvection& parent)
372  : mTask(nullptr)
373  , mInGrid(&inGrid)
374  , mVelocityInt(parent.mVelGrid)
375  , mParent(&parent)
376  {
377  }
378  inline void cook(const LeafRangeT& range)
379  {
380  if (mParent->mGrainSize > 0) {
381  tbb::parallel_for(range, *this);
382  } else {
383  (*this)(range);
384  }
385  }
386  void operator()(const LeafRangeT& range) const
387  {
388  assert(mTask);
389  mTask(const_cast<Advect*>(this), range);
390  }
391  void cook(VolumeGridT& outGrid, double time_step)
392  {
393  namespace ph = std::placeholders;
394 
395  mParent->start("Advecting volume");
396  LeafManagerT manager(outGrid.tree(), mParent->spatialOrder()==2 ? 1 : 0);
397  const LeafRangeT range = manager.leafRange(mParent->mGrainSize);
398  const RealT dt = static_cast<RealT>(-time_step);//method of characteristics backtracks
399  if (mParent->mIntegrator == Scheme::MAC) {
400  mTask = std::bind(&Advect::rk, ph::_1, ph::_2, dt, 0, mInGrid);//out[0]=forward
401  this->cook(range);
402  mTask = std::bind(&Advect::rk, ph::_1, ph::_2,-dt, 1, &outGrid);//out[1]=backward
403  this->cook(range);
404  mTask = std::bind(&Advect::mac, ph::_1, ph::_2);//out[0] = out[0] + (in[0] - out[1])/2
405  this->cook(range);
406  } else if (mParent->mIntegrator == Scheme::BFECC) {
407  mTask = std::bind(&Advect::rk, ph::_1, ph::_2, dt, 0, mInGrid);//out[0]=forward
408  this->cook(range);
409  mTask = std::bind(&Advect::rk, ph::_1, ph::_2,-dt, 1, &outGrid);//out[1]=backward
410  this->cook(range);
411  mTask = std::bind(&Advect::bfecc, ph::_1, ph::_2);//out[0] = (3*in[0] - out[1])/2
412  this->cook(range);
413  mTask = std::bind(&Advect::rk, ph::_1, ph::_2, dt, 1, &outGrid);//out[1]=forward
414  this->cook(range);
415  manager.swapLeafBuffer(1);// out[0] = out[1]
416  } else {// SEMI, MID, RK3 and RK4
417  mTask = std::bind(&Advect::rk, ph::_1, ph::_2, dt, 0, mInGrid);//forward
418  this->cook(range);
419  }
420 
421  if (mParent->spatialOrder()==2) manager.removeAuxBuffers();
422 
423  mTask = std::bind(&Advect::limiter, ph::_1, ph::_2, dt);// out[0] = limiter( out[0] )
424  this->cook(range);
425 
426  mParent->stop();
427  }
428  // Last step of the MacCormack scheme: out[0] = out[0] + (in[0] - out[1])/2
429  void mac(const LeafRangeT& range) const
430  {
431  if (mParent->interrupt()) return;
432  assert( mParent->mIntegrator == Scheme::MAC );
433  AccT acc = mInGrid->getAccessor();
434  for (typename LeafRangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
435  ValueT* out0 = leafIter.buffer( 0 ).data();// forward
436  const ValueT* out1 = leafIter.buffer( 1 ).data();// backward
437  const LeafNodeT* leaf = acc.probeConstLeaf( leafIter->origin() );
438  if (leaf != nullptr) {
439  const ValueT* in0 = leaf->buffer().data();
440  for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
441  const Index i = voxelIter.pos();
442  out0[i] += RealT(0.5) * ( in0[i] - out1[i] );
443  }
444  } else {
445  for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
446  const Index i = voxelIter.pos();
447  out0[i] += RealT(0.5) * ( acc.getValue(voxelIter.getCoord()) - out1[i] );
448  }//loop over active voxels
449  }
450  }//loop over leaf nodes
451  }
452  // Intermediate step in the BFECC scheme: out[0] = (3*in[0] - out[1])/2
453  void bfecc(const LeafRangeT& range) const
454  {
455  if (mParent->interrupt()) return;
456  assert( mParent->mIntegrator == Scheme::BFECC );
457  AccT acc = mInGrid->getAccessor();
458  for (typename LeafRangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
459  ValueT* out0 = leafIter.buffer( 0 ).data();// forward
460  const ValueT* out1 = leafIter.buffer( 1 ).data();// backward
461  const LeafNodeT* leaf = acc.probeConstLeaf(leafIter->origin());
462  if (leaf != nullptr) {
463  const ValueT* in0 = leaf->buffer().data();
464  for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
465  const Index i = voxelIter.pos();
466  out0[i] = RealT(0.5)*( RealT(3)*in0[i] - out1[i] );
467  }//loop over active voxels
468  } else {
469  for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
470  const Index i = voxelIter.pos();
471  out0[i] = RealT(0.5)*( RealT(3)*acc.getValue(voxelIter.getCoord()) - out1[i] );
472  }//loop over active voxels
473  }
474  }//loop over leaf nodes
475  }
476  // Semi-Lagrangian integration with Runge-Kutta of various orders (1->4)
477  void rk(const LeafRangeT& range, RealT dt, size_t n, const VolumeGridT* grid) const
478  {
479  if (mParent->interrupt()) return;
480  const math::Transform& xform = mInGrid->transform();
481  AccT acc = grid->getAccessor();
482  for (typename LeafRangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
483  ValueT* phi = leafIter.buffer( n ).data();
484  for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
485  ValueT& value = phi[voxelIter.pos()];
486  Vec3d wPos = xform.indexToWorld(voxelIter.getCoord());
487  mVelocityInt.template rungeKutta<OrderRK, Vec3d>(dt, wPos);
488  value = SamplerT::sample(acc, xform.worldToIndex(wPos));
489  }//loop over active voxels
490  }//loop over leaf nodes
491  }
492  void limiter(const LeafRangeT& range, RealT dt) const
493  {
494  if (mParent->interrupt()) return;
495  const bool doLimiter = mParent->isLimiterOn();
496  const bool doClamp = mParent->mLimiter == Scheme::CLAMP;
497  ValueT data[2][2][2], vMin, vMax;
498  const math::Transform& xform = mInGrid->transform();
499  AccT acc = mInGrid->getAccessor();
500  const ValueT backg = mInGrid->background();
501  for (typename LeafRangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
502  ValueT* phi = leafIter.buffer( 0 ).data();
503  for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
504  ValueT& value = phi[voxelIter.pos()];
505 
506  if ( doLimiter ) {
507  assert(OrderRK == 1);
508  Vec3d wPos = xform.indexToWorld(voxelIter.getCoord());
509  mVelocityInt.template rungeKutta<1, Vec3d>(dt, wPos);// Explicit Euler
510  Vec3d iPos = xform.worldToIndex(wPos);
511  Coord ijk = Coord::floor( iPos );
512  BoxSampler::getValues(data, acc, ijk);
513  BoxSampler::extrema(data, vMin, vMax);
514  if ( doClamp ) {
515  value = math::Clamp( value, vMin, vMax);
516  } else if (value < vMin || value > vMax ) {
517  iPos -= Vec3R(ijk[0], ijk[1], ijk[2]);//unit coordinates
518  value = BoxSampler::trilinearInterpolation( data, iPos );
519  }
520  }
521 
522  if (math::isApproxEqual(value, backg, math::Delta<ValueT>::value())) {
523  value = backg;
524  leafIter->setValueOff( voxelIter.pos() );
525  }
526  }//loop over active voxels
527  }//loop over leaf nodes
528  }
529  // Public member data of the private Advect class
530 
531  typename std::function<void (Advect*, const LeafRangeT&)> mTask;
532  const VolumeGridT* mInGrid;
533  const VelocityIntegratorT mVelocityInt;// lightweight!
534  const VolumeAdvection* mParent;
535 };// end of private member class Advect
536 
537 } // namespace tools
538 } // namespace OPENVDB_VERSION_NAME
539 } // namespace openvdb
540 
541 #endif // OPENVDB_TOOLS_VOLUME_ADVECT_HAS_BEEN_INCLUDED
openvdb::v7_0::tools::VolumeAdvection::advect
VolumeGridT::Ptr advect(const VolumeGridT &inGrid, double timeStep)
Definition: VolumeAdvect.h:207
openvdb::v7_0::Vec3fGrid
Vec3SGrid Vec3fGrid
Definition: openvdb.h:56
openvdb::v7_0::tools::VolumeAdvection
Performs advections of an arbitrary type of volume in a static velocity field. The advections are per...
Definition: VolumeAdvect.h:72
openvdb::v7_0::tools::VolumeAdvection::getMaxVelocity
double getMaxVelocity() const
Return the maximum magnitude of the velocity in the advection velocity field defined during construct...
Definition: VolumeAdvect.h:165
openvdb::v7_0::math::Extrema::max
double max() const
Return the maximum value.
Definition: Stats.h:128
openvdb::v7_0::tools::NN_FACE
@ NN_FACE
Definition: Morphology.h:60
openvdb::v7_0::math::isApproxEqual
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:351
openvdb::v7_0::tools::VolumeAdvection::advect
VolumeGridT::Ptr advect(const VolumeGridT &inGrid, const MaskGridT &mask, double timeStep)
Definition: VolumeAdvect.h:254
openvdb::v7_0::Vec3R
math::Vec3< Real > Vec3R
Definition: Types.h:49
Types.h
openvdb::v7_0::tools::extrema
math::Extrema extrema(const IterT &iter, bool threaded=true)
Iterate over a scalar grid and compute extrema (min/max) of the values of the voxels that are visited...
Definition: Statistics.h:352
openvdb::v7_0::tools::Scheme::MID
@ MID
Definition: VolumeAdvect.h:35
VelocityFields.h
Defines two simple wrapper classes for advection velocity fields as well as VelocitySampler and Veloc...
openvdb::v7_0::tools::Scheme::Limiter
Limiter
Flux-limiters employed to stabalize the second-order advection schemes MacCormack and BFECC.
Definition: VolumeAdvect.h:38
openvdb::v7_0::tools::VolumeAdvection::setSubSteps
void setSubSteps(int substeps)
Set the number of sub-steps per integration.
Definition: VolumeAdvect.h:161
openvdb::v7_0::tools::VolumeAdvection::setIntegrator
void setIntegrator(Scheme::SemiLagrangian integrator)
Set the integrator (see details in the table above)
Definition: VolumeAdvect.h:126
openvdb::v7_0::tools::VolumeAdvection::getSubSteps
int getSubSteps() const
Definition: VolumeAdvect.h:154
openvdb::v7_0::math::Max
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:542
openvdb::v7_0::tools::VolumeAdvection::getIntegrator
Scheme::SemiLagrangian getIntegrator() const
Return the integrator (see details in the table above)
Definition: VolumeAdvect.h:129
openvdb::v7_0::tools::VolumeAdvection::setGrainSize
void setGrainSize(size_t grainsize)
Set the grain-size used for multi-threading.
Definition: VolumeAdvect.h:150
openvdb::v7_0::math::Vec3d
Vec3< double > Vec3d
Definition: Vec3.h:662
openvdb::v7_0::util::NullInterrupter
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:25
openvdb::v7_0::math::Abs
Coord Abs(const Coord &xyz)
Definition: Coord.h:515
openvdb::v7_0::tools::VolumeAdvection::isLimiterOn
bool isLimiterOn() const
Return true if a limiter will be applied based on the current settings.
Definition: VolumeAdvect.h:139
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v7_0::tools::Scheme::SemiLagrangian
SemiLagrangian
Numerical advections schemes.
Definition: VolumeAdvect.h:35
openvdb::v7_0::tools::Scheme::NO_LIMITER
@ NO_LIMITER
Definition: VolumeAdvect.h:38
Prune.h
Defined various multi-threaded utility functions for trees.
openvdb::v7_0::tools::Scheme::SEMI
@ SEMI
Definition: VolumeAdvect.h:35
NullInterrupter.h
openvdb::v7_0::tools::Scheme::REVERT
@ REVERT
Definition: VolumeAdvect.h:38
openvdb::v7_0::tools::VolumeAdvection::temporalOrder
int temporalOrder() const
Return the temporal order of accuracy of the advection scheme.
Definition: VolumeAdvect.h:113
Interpolation.h
openvdb::v7_0::math::Extrema::add
void add(double val)
Add a single sample.
Definition: Stats.h:106
openvdb::v7_0::RuntimeError
Definition: Exceptions.h:63
openvdb::v7_0::tools::dilateActiveValues
void dilateActiveValues(TreeType &tree, int iterations=1, NearestNeighbors nn=NN_FACE, TilePolicy mode=PRESERVE_TILES)
Topologically dilate all active values (i.e. both voxels and tiles) in a tree using one of three near...
Definition: Morphology.h:1047
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
openvdb::v7_0::math::Extrema
This class computes the minimum and maximum values of a population of floating-point values.
Definition: Stats.h:92
openvdb::v7_0::tools::VolumeAdvection::getLimiter
Scheme::Limiter getLimiter() const
Retrun the limiter (see details above)
Definition: VolumeAdvect.h:135
openvdb::v7_0::tools::Scheme::MAC
@ MAC
Definition: VolumeAdvect.h:35
openvdb::v7_0::tools::Scheme::CLAMP
@ CLAMP
Definition: VolumeAdvect.h:38
openvdb::v7_0::Index
Index32 Index
Definition: Types.h:31
Morphology.h
Implementation of morphological dilation and erosion.
Statistics.h
Functions to efficiently compute histograms, extremas (min/max) and statistics (mean,...
openvdb::v7_0::tools::VolumeAdvection::VolumeAdvection
VolumeAdvection(const VelocityGridT &velGrid, InterrupterType *interrupter=nullptr)
Constructor.
Definition: VolumeAdvect.h:83
openvdb::v7_0::tools::VolumeAdvection::spatialOrder
int spatialOrder() const
Return the spatial order of accuracy of the advection scheme.
Definition: VolumeAdvect.h:105
openvdb::v7_0::tools::VolumeAdvection::setLimiter
void setLimiter(Scheme::Limiter limiter)
Set the limiter (see details above)
Definition: VolumeAdvect.h:132
openvdb::v7_0::tools::Scheme::RK4
@ RK4
Definition: VolumeAdvect.h:35
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:108
openvdb::v7_0::math::Clamp
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:203
openvdb::v7_0::math::RoundUp
float RoundUp(float x)
Return x rounded up to the nearest integer.
Definition: Math.h:734
openvdb::v7_0::tools::Scheme::RK3
@ RK3
Definition: VolumeAdvect.h:35
openvdb::v7_0::util::wasInterrupted
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:49
openvdb::v7_0::tools::VolumeAdvection::getMaxDistance
int getMaxDistance(const VolumeGridT &inGrid, double dt) const
Definition: VolumeAdvect.h:178
openvdb::v7_0::tools::VolumeAdvection::getGrainSize
size_t getGrainSize() const
Definition: VolumeAdvect.h:144
openvdb
Definition: Exceptions.h:13
openvdb::v7_0::tools::pruneInactive
void pruneInactive(TreeT &tree, bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing with background tiles any nodes whose values are a...
Definition: Prune.h:354
openvdb::v7_0::tools::Scheme::BFECC
@ BFECC
Definition: VolumeAdvect.h:35
openvdb::v7_0::tools::EXPAND_TILES
@ EXPAND_TILES
Definition: Morphology.h:75
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
openvdb::v7_0::tools::VolumeAdvection::~VolumeAdvection
virtual ~VolumeAdvection()
Definition: VolumeAdvect.h:96