OpenVDB: VolumeAdvect.h Source File

OpenVDB 8.1.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>
19 #include <openvdb/util/NullInterrupter.h>
20 #include "Interpolation.h"// for Sampler
21 #include "VelocityFields.h" // for VelocityIntegrator
22 #include "Morphology.h"//for dilateActiveValues
23 #include "Prune.h"// for prune
24 #include "Statistics.h" // for extrema
25 #include <functional>
26
27
28 namespace openvdb {
29 OPENVDB_USE_VERSION_NAMESPACE
30 namespace OPENVDB_VERSION_NAME {
31 namespace tools {
32
33 namespace Scheme {
35 enum SemiLagrangian { SEMI, MID, RK3, RK4, MAC, BFECC };
38 enum Limiter { NO_LIMITER, CLAMP, REVERT };
39 }
40
68
69 template<typename VelocityGridT = Vec3fGrid,
70 bool StaggeredVelocity = false,
71 typename InterrupterType = util::NullInterrupter>
72 class VolumeAdvection
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
Interpolation.h
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Morphology.h
Implementation of morphological dilation and erosion.
NullInterrupter.h
Prune.h
Defined various multi-threaded utility functions for trees.
Statistics.h
Functions to efficiently compute histograms, extremas (min/max) and statistics (mean,...
VelocityFields.h
Defines two simple wrapper classes for advection velocity fields as well as VelocitySampler and Veloc...
openvdb::v8_1::RuntimeError
Definition: openvdb/Exceptions.h:63
openvdb::v8_1::math::Coord::floor
static Coord floor(const Vec3< T > &xyz)
Return the largest integer coordinates that are not greater than xyz (node centered conversion).
Definition: Coord.h:57
openvdb::v8_1::math::Extrema
This class computes the minimum and maximum values of a population of floating-point values.
Definition: Stats.h:93
openvdb::v8_1::math::Extrema::add
void add(double val)
Add a single sample.
Definition: Stats.h:106
openvdb::v8_1::math::Extrema::max
double max() const
Return the maximum value.
Definition: Stats.h:128
openvdb::v8_1::tools::VolumeAdvection
Performs advections of an arbitrary type of volume in a static velocity field. The advections are per...
Definition: VolumeAdvect.h:73
openvdb::v8_1::tools::VolumeAdvection::~VolumeAdvection
virtual ~VolumeAdvection()
Definition: VolumeAdvect.h:96
openvdb::v8_1::tools::VolumeAdvection::getIntegrator
Scheme::SemiLagrangian getIntegrator() const
Return the integrator (see details in the table above)
Definition: VolumeAdvect.h:129
openvdb::v8_1::tools::VolumeAdvection::getSubSteps
int getSubSteps() const
Definition: VolumeAdvect.h:154
openvdb::v8_1::tools::VolumeAdvection::getLimiter
Scheme::Limiter getLimiter() const
Retrun the limiter (see details above)
Definition: VolumeAdvect.h:135
openvdb::v8_1::tools::VolumeAdvection::setSubSteps
void setSubSteps(int substeps)
Set the number of sub-steps per integration.
Definition: VolumeAdvect.h:161
openvdb::v8_1::tools::VolumeAdvection::isLimiterOn
bool isLimiterOn() const
Return true if a limiter will be applied based on the current settings.
Definition: VolumeAdvect.h:139
openvdb::v8_1::tools::VolumeAdvection::spatialOrder
int spatialOrder() const
Return the spatial order of accuracy of the advection scheme.
Definition: VolumeAdvect.h:105
openvdb::v8_1::tools::VolumeAdvection::setLimiter
void setLimiter(Scheme::Limiter limiter)
Set the limiter (see details above)
Definition: VolumeAdvect.h:132
openvdb::v8_1::tools::VolumeAdvection::advect
VolumeGridT::Ptr advect(const VolumeGridT &inGrid, double timeStep)
Definition: VolumeAdvect.h:207
openvdb::v8_1::tools::VolumeAdvection::advect
VolumeGridT::Ptr advect(const VolumeGridT &inGrid, const MaskGridT &mask, double timeStep)
Definition: VolumeAdvect.h:254
openvdb::v8_1::tools::VolumeAdvection::VolumeAdvection
VolumeAdvection(const VelocityGridT &velGrid, InterrupterType *interrupter=nullptr)
Constructor.
Definition: VolumeAdvect.h:83
openvdb::v8_1::tools::VolumeAdvection::getGrainSize
size_t getGrainSize() const
Definition: VolumeAdvect.h:144
openvdb::v8_1::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::v8_1::tools::VolumeAdvection::temporalOrder
int temporalOrder() const
Return the temporal order of accuracy of the advection scheme.
Definition: VolumeAdvect.h:113
openvdb::v8_1::tools::VolumeAdvection::setIntegrator
void setIntegrator(Scheme::SemiLagrangian integrator)
Set the integrator (see details in the table above)
Definition: VolumeAdvect.h:126
openvdb::v8_1::tools::VolumeAdvection::getMaxDistance
int getMaxDistance(const VolumeGridT &inGrid, double dt) const
Definition: VolumeAdvect.h:178
openvdb::v8_1::tools::VolumeAdvection::setGrainSize
void setGrainSize(size_t grainsize)
Set the grain-size used for multi-threading.
Definition: VolumeAdvect.h:150
openvdb::v8_1::math::isApproxEqual
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:407
openvdb::v8_1::math::Abs
Coord Abs(const Coord &xyz)
Definition: Coord.h:515
openvdb::v8_1::math::Max
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:598
openvdb::v8_1::math::Vec3d
Vec3< double > Vec3d
Definition: Vec3.h:668
openvdb::v8_1::math::Clamp
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:260
openvdb::v8_1::math::RoundUp
float RoundUp(float x)
Return x rounded up to the nearest integer.
Definition: Math.h:790
openvdb::v8_1::tools::Scheme::Limiter
Limiter
Flux-limiters employed to stabalize the second-order advection schemes MacCormack and BFECC.
Definition: VolumeAdvect.h:38
openvdb::v8_1::tools::Scheme::REVERT
@ REVERT
Definition: VolumeAdvect.h:38
openvdb::v8_1::tools::Scheme::CLAMP
@ CLAMP
Definition: VolumeAdvect.h:38
openvdb::v8_1::tools::Scheme::NO_LIMITER
@ NO_LIMITER
Definition: VolumeAdvect.h:38
openvdb::v8_1::tools::Scheme::SemiLagrangian
SemiLagrangian
Numerical advections schemes.
Definition: VolumeAdvect.h:35
openvdb::v8_1::tools::Scheme::MID
@ MID
Definition: VolumeAdvect.h:35
openvdb::v8_1::tools::Scheme::RK4
@ RK4
Definition: VolumeAdvect.h:35
openvdb::v8_1::tools::Scheme::SEMI
@ SEMI
Definition: VolumeAdvect.h:35
openvdb::v8_1::tools::Scheme::RK3
@ RK3
Definition: VolumeAdvect.h:35
openvdb::v8_1::tools::Scheme::MAC
@ MAC
Definition: VolumeAdvect.h:35
openvdb::v8_1::tools::Scheme::BFECC
@ BFECC
Definition: VolumeAdvect.h:35
openvdb::v8_1::tools::NN_FACE
@ NN_FACE
Definition: Morphology.h:56
openvdb::v8_1::tools::dilateActiveValues
void dilateActiveValues(TreeOrLeafManagerT &tree, const int iterations=1, const NearestNeighbors nn=NN_FACE, const TilePolicy mode=PRESERVE_TILES, const bool threaded=true)
Topologically dilate all active values (i.e. both voxels and tiles) in a tree using one of three near...
Definition: Morphology.h:1049
openvdb::v8_1::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::v8_1::tools::EXPAND_TILES
@ EXPAND_TILES
Definition: Morphology.h:78
openvdb::v8_1::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::v8_1::util::wasInterrupted
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:49
openvdb::v8_1::Index
Index32 Index
Definition: openvdb/Types.h:50
openvdb::v8_1::Vec3fGrid
Vec3SGrid Vec3fGrid
Definition: openvdb.h:56
openvdb::v8_1::Vec3R
math::Vec3< Real > Vec3R
Definition: openvdb/Types.h:68
openvdb
Definition: openvdb/Exceptions.h:13
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
Types.h
openvdb::v8_1::util::NullInterrupter
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:26
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178