OpenVDB: VolumeAdvect.h Source File

OpenVDB 3.1.0

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

VolumeAdvect.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 //
30 //
32 //
41
42 #ifndef OPENVDB_TOOLS_VOLUME_ADVECT_HAS_BEEN_INCLUDED
43 #define OPENVDB_TOOLS_VOLUME_ADVECT_HAS_BEEN_INCLUDED
44
45 #include <tbb/parallel_for.h>
46 #include <boost/bind.hpp>
47 #include <boost/function.hpp>
48 #include <openvdb/Types.h>
49 #include <openvdb/math/Math.h>
50 #include <openvdb/util/NullInterrupter.h>
51 #include "Interpolation.h"// for Sampler
52 #include "VelocityFields.h" // for VelocityIntegrator
53 #include "Morphology.h"//for dilateVoxels
54 #include "Prune.h"// for prune
55 #include "Statistics.h" // for extrema
56
57 namespace openvdb {
58 OPENVDB_USE_VERSION_NAMESPACE
59 namespace OPENVDB_VERSION_NAME {
60 namespace tools {
61
62
63 namespace Scheme {
65 enum SemiLagrangian { SEMI, MID, RK3, RK4, MAC, BFECC };
68 enum Limiter { NO_LIMITER, CLAMP, REVERT };
69 }
70
96 template<typename VelocityGridT = Vec3fGrid,
97 bool StaggeredVelocity = false,
98 typename InterrupterType = util::NullInterrupter>
99 class VolumeAdvection
100 {
101 public:
102
110 VolumeAdvection(const VelocityGridT& velGrid, InterrupterType* interrupter = NULL)
111 : mVelGrid(velGrid)
112 , mInterrupter(interrupter)
113 , mIntegrator( Scheme::SEMI )
114 , mLimiter( Scheme::CLAMP )
115 , mGrainSize( 128 )
116 , mSubSteps( 1 )
117 {
118 math::Extrema e = extrema(velGrid.cbeginValueAll(), /*threading*/true);
119 e.add(velGrid.background().length());
120 mMaxVelocity = e.max();
121 }
122
123 virtual ~VolumeAdvection()
124 {
125 }
126
132 int spatialOrder() const { return (mIntegrator == Scheme::MAC ||
133 mIntegrator == Scheme::BFECC) ? 2 : 1; }
134
140 int temporalOrder() const {
141 switch (mIntegrator) {
142 case Scheme::SEMI: return 1;
143 case Scheme::MID: return 2;
144 case Scheme::RK3: return 3;
145 case Scheme::RK4: return 4;
146 case Scheme::BFECC:return 2;
147 case Scheme::MAC: return 2;
148 }
149 return 0;//should never reach this point
150 }
151
153 void setIntegrator(Scheme::SemiLagrangian integrator) { mIntegrator = integrator; }
154
156 Scheme::SemiLagrangian getIntegrator() const { return mIntegrator; }
157
159 void setLimiter(Scheme::Limiter limiter) { mLimiter = limiter; }
160
162 Scheme::Limiter getLimiter() const { return mLimiter; }
163
166 bool isLimiterOn() const { return this->spatialOrder()>1 &&
167 mLimiter != Scheme::NO_LIMITER; }
168
171 size_t getGrainSize() const { return mGrainSize; }
172
177 void setGrainSize(size_t grainsize) { mGrainSize = grainsize; }
178
181 int getSubSteps() const { return mSubSteps; }
182
188 void setSubSteps(int substeps) { mSubSteps = math::Max(1, substeps); }
189
192 double getMaxVelocity() const { return mMaxVelocity; }
193
204 template<typename VolumeGridT>
205 int getMaxDistance(const VolumeGridT& inGrid, double dt) const
206 {
207 if (!inGrid.hasUniformVoxels()) {
208 OPENVDB_THROW(RuntimeError, "Volume grid does not have uniform voxels!");
209 }
210 const double d = mMaxVelocity*math::Abs(dt)/inGrid.voxelSize()[0];
211 return static_cast<int>( math::RoundUp(d) );
212 }
213
232 template<typename VolumeGridT,
233 typename VolumeSamplerT>//only C++11 allows for a default argument
234 typename VolumeGridT::Ptr advect(const VolumeGridT& inGrid, double timeStep)
235 {
236 typename VolumeGridT::Ptr outGrid = inGrid.deepCopy();
237 const double dt = timeStep/mSubSteps;
238 const int n = this->getMaxDistance(inGrid, dt);
239 dilateVoxels( outGrid->tree(), n );
240 this->template cook<VolumeGridT, VolumeSamplerT>(*outGrid, inGrid, dt);
241
242 for (int step = 1; step < mSubSteps; ++step) {
243 typename VolumeGridT::Ptr tmpGrid = outGrid->deepCopy();
244 dilateVoxels( tmpGrid->tree(), n );
245 this->template cook<VolumeGridT, VolumeSamplerT>(*tmpGrid, *outGrid, dt);
246 outGrid.swap( tmpGrid );
247 }
248
249 return outGrid;
250 }
251
279 template<typename VolumeGridT,
280 typename MaskGridT,
281 typename VolumeSamplerT>//only C++11 allows for a default argument
282 typename VolumeGridT::Ptr advect(const VolumeGridT& inGrid, const MaskGridT& mask, double timeStep)
283 {
284 if (inGrid.transform() != mask.transform()) {
285 OPENVDB_THROW(RuntimeError, "Volume grid and mask grid are misaligned! Consider "
286 "resampling either of the two grids into the index space of the other.");
287 }
288 typename VolumeGridT::Ptr outGrid = inGrid.deepCopy();
289 const double dt = timeStep/mSubSteps;
290 const int n = this->getMaxDistance(inGrid, dt);
291 dilateVoxels( outGrid->tree(), n );
292 outGrid->topologyIntersection( mask );
293 pruneInactive( outGrid->tree(), mGrainSize>0, mGrainSize );
294 this->template cook<VolumeGridT, VolumeSamplerT>(*outGrid, inGrid, dt);
295 outGrid->topologyUnion( inGrid );
296
297 for (int step = 1; step < mSubSteps; ++step) {
298 typename VolumeGridT::Ptr tmpGrid = outGrid->deepCopy();
299 dilateVoxels( tmpGrid->tree(), n );
300 tmpGrid->topologyIntersection( mask );
301 pruneInactive( tmpGrid->tree(), mGrainSize>0, mGrainSize );
302 this->template cook<VolumeGridT, VolumeSamplerT>(*tmpGrid, *outGrid, dt);
303 tmpGrid->topologyUnion( inGrid );
304 outGrid.swap( tmpGrid );
305 }
306 return outGrid;
307 }
308
309 private:
310 // disallow copy construction and copy by assignment!
311 VolumeAdvection(const VolumeAdvection&);// not implemented
312 VolumeAdvection& operator=(const VolumeAdvection&);// not implemented
313
314 void start(const char* str) const
315 {
316 if (mInterrupter) mInterrupter->start(str);
317 }
318 void stop() const
319 {
320 if (mInterrupter) mInterrupter->end();
321 }
322 bool interrupt() const
323 {
324 if (mInterrupter && util::wasInterrupted(mInterrupter)) {
325 tbb::task::self().cancel_group_execution();
326 return true;
327 }
328 return false;
329 }
330
331 template<typename VolumeGridT, typename VolumeSamplerT>
332 void cook(VolumeGridT& outGrid, const VolumeGridT& inGrid, double dt)
333 {
334 outGrid.tree().voxelizeActiveTiles();
335 switch (mIntegrator) {
336 case Scheme::SEMI: {
337 Advect<VolumeGridT, 1, VolumeSamplerT> adv(inGrid, *this);
338 adv.cook(outGrid, dt);
339 break;
340 }
341 case Scheme::MID: {
342 Advect<VolumeGridT, 2, VolumeSamplerT> adv(inGrid, *this);
343 adv.cook(outGrid, dt);
344 break;
345 }
346 case Scheme::RK3: {
347 Advect<VolumeGridT, 3, VolumeSamplerT> adv(inGrid, *this);
348 adv.cook(outGrid, dt);
349 break;
350 }
351 case Scheme::RK4: {
352 Advect<VolumeGridT, 4, VolumeSamplerT> adv(inGrid, *this);
353 adv.cook(outGrid, dt);
354 break;
355 }
356 case Scheme::BFECC: {
357 Advect<VolumeGridT, 1, VolumeSamplerT> adv(inGrid, *this);
358 adv.cook(outGrid, dt);
359 break;
360 }
361 case Scheme::MAC: {
362 Advect<VolumeGridT, 1, VolumeSamplerT> adv(inGrid, *this);
363 adv.cook(outGrid, dt);
364 break;
365 }
366 default:
367 OPENVDB_THROW(ValueError, "Spatial difference scheme not supported!");
368 }
369 pruneInactive(outGrid.tree(), mGrainSize>0, mGrainSize);
370 }
371
372 // Private class that implements the multi-threaded advection
373 template<typename VolumeGridT, size_t OrderRK, typename SamplerT> struct Advect;
374
375 // Private member data of VolumeAdvection
376 const VelocityGridT& mVelGrid;
377 double mMaxVelocity;
378 InterrupterType* mInterrupter;
379 Scheme::SemiLagrangian mIntegrator;
380 Scheme::Limiter mLimiter;
381 size_t mGrainSize;
382 int mSubSteps;
383 };//end of VolumeAdvection class
384
385 // Private class that implements the multi-threaded advection
386 template<typename VelocityGridT, bool StaggeredVelocity, typename InterrupterType>
387 template<typename VolumeGridT, size_t OrderRK, typename SamplerT>
388 struct VolumeAdvection<VelocityGridT, StaggeredVelocity, InterrupterType>::Advect
389 {
390 typedef typename VolumeGridT::TreeType TreeT;
391 typedef typename VolumeGridT::ConstAccessor AccT;
392 typedef typename TreeT::ValueType ValueT;
393 typedef typename tree::LeafManager<TreeT> LeafManagerT;
394 typedef typename LeafManagerT::LeafNodeType LeafNodeT;
395 typedef typename LeafManagerT::LeafRange LeafRangeT;
396 typedef VelocityIntegrator<VelocityGridT, StaggeredVelocity> VelocityIntegratorT;
397 typedef typename VelocityIntegratorT::ElementType RealT;
398 typedef typename TreeT::LeafNodeType::ValueOnIter VoxelIterT;
399
400
401 Advect(const VolumeGridT& inGrid, const VolumeAdvection& parent)
402 : mTask(0)
403 , mInGrid(&inGrid)
404 , mVelocityInt(parent.mVelGrid)
405 , mParent(&parent)
406 {
407 }
408 inline void cook(const LeafRangeT& range)
409 {
410 if (mParent->mGrainSize > 0) {
411 tbb::parallel_for(range, *this);
412 } else {
413 (*this)(range);
414 }
415 }
416 void operator()(const LeafRangeT& range) const
417 {
418 assert(mTask);
419 mTask(const_cast<Advect*>(this), range);
420 }
421 void cook(VolumeGridT& outGrid, double time_step)
422 {
423 mParent->start("Advecting volume");
424 LeafManagerT manager(outGrid.tree(), mParent->spatialOrder()==2 ? 1 : 0);
425 const LeafRangeT range = manager.leafRange(mParent->mGrainSize);
426
427 const RealT dt = static_cast<RealT>(-time_step);//method of characteristics backtracks
428 if (mParent->mIntegrator == Scheme::MAC) {
429 mTask = boost::bind(&Advect::rk, _1, _2, dt, 0, *mInGrid);//out[0]=forward
430 this->cook(range);
431 mTask = boost::bind(&Advect::rk, _1, _2,-dt, 1, outGrid);//out[1]=backward
432 this->cook(range);
433 mTask = boost::bind(&Advect::mac, _1, _2);//out[0] = out[0] + (in[0] - out[1])/2
434 this->cook(range);
435 } else if (mParent->mIntegrator == Scheme::BFECC) {
436 mTask = boost::bind(&Advect::rk, _1, _2, dt, 0, *mInGrid);//out[0]=forward
437 this->cook(range);
438 mTask = boost::bind(&Advect::rk, _1, _2,-dt, 1, outGrid);//out[1]=backward
439 this->cook(range);
440 mTask = boost::bind(&Advect::bfecc, _1, _2);//out[0] = (3*in[0] - out[1])/2
441 this->cook(range);
442 mTask = boost::bind(&Advect::rk, _1, _2, dt, 1, outGrid);//out[1]=forward
443 this->cook(range);
444 manager.swapLeafBuffer(1);// out[0] = out[1]
445 } else {// SEMI, MID, RK3 and RK4
446 mTask = boost::bind(&Advect::rk, _1, _2, dt, 0, *mInGrid);//forward
447 this->cook(range);
448 }
449
450 if (mParent->spatialOrder()==2) manager.removeAuxBuffers();
451
452 mTask = boost::bind(&Advect::limiter, _1, _2, dt);// out[0] = limiter( out[0] )
453 this->cook(range);
454
455 mParent->stop();
456 }
457 // Last step of the MacCormack scheme: out[0] = out[0] + (in[0] - out[1])/2
458 void mac(const LeafRangeT& range) const
459 {
460 if (mParent->interrupt()) return;
461 assert( mParent->mIntegrator == Scheme::MAC );
462 AccT acc = mInGrid->getAccessor();
463 for (typename LeafRangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
464 ValueT* out0 = leafIter.buffer( 0 ).data();// forward
465 const ValueT* out1 = leafIter.buffer( 1 ).data();// backward
466 const LeafNodeT* leaf = acc.probeConstLeaf( leafIter->origin() );
467 if (leaf !=NULL) {
468 const ValueT* in0 = leaf->buffer().data();
469 for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
470 const Index i = voxelIter.pos();
471 out0[i] += RealT(0.5) * ( in0[i] - out1[i] );
472 }
473 } else {
474 for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
475 const Index i = voxelIter.pos();
476 out0[i] += RealT(0.5) * ( acc.getValue(voxelIter.getCoord()) - out1[i] );
477 }//loop over active voxels
478 }
479 }//loop over leaf nodes
480 }
481 // Intermediate step in the BFECC scheme: out[0] = (3*in[0] - out[1])/2
482 void bfecc(const LeafRangeT& range) const
483 {
484 if (mParent->interrupt()) return;
485 assert( mParent->mIntegrator == Scheme::BFECC );
486 AccT acc = mInGrid->getAccessor();
487 for (typename LeafRangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
488 ValueT* out0 = leafIter.buffer( 0 ).data();// forward
489 const ValueT* out1 = leafIter.buffer( 1 ).data();// backward
490 const LeafNodeT* leaf = acc.probeConstLeaf(leafIter->origin());
491 if (leaf !=NULL) {
492 const ValueT* in0 = leaf->buffer().data();
493 for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
494 const Index i = voxelIter.pos();
495 out0[i] = RealT(0.5)*( RealT(3)*in0[i] - out1[i] );
496 }//loop over active voxels
497 } else {
498 for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
499 const Index i = voxelIter.pos();
500 out0[i] = RealT(0.5)*( RealT(3)*acc.getValue(voxelIter.getCoord()) - out1[i] );
501 }//loop over active voxels
502 }
503 }//loop over leaf nodes
504 }
505 // Semi-Lagrangian integration with Runge-Kutta of various orders (1->4)
506 void rk(const LeafRangeT& range, RealT dt, size_t n, const VolumeGridT& grid) const
507 {
508 if (mParent->interrupt()) return;
509 const math::Transform& xform = mInGrid->transform();
510 AccT acc = grid.getAccessor();
511 for (typename LeafRangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
512 ValueT* phi = leafIter.buffer( n ).data();
513 for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
514 ValueT& value = phi[voxelIter.pos()];
515 Vec3d wPos = xform.indexToWorld(voxelIter.getCoord());
516 mVelocityInt.template rungeKutta<OrderRK, Vec3d>(dt, wPos);
517 value = SamplerT::sample(acc, xform.worldToIndex(wPos));
518 }//loop over active voxels
519 }//loop over leaf nodes
520 }
521 void limiter(const LeafRangeT& range, RealT dt) const
522 {
523 if (mParent->interrupt()) return;
524 const bool doLimiter = mParent->isLimiterOn();
525 const bool doClamp = mParent->mLimiter == Scheme::CLAMP;
526 ValueT data[2][2][2], vMin, vMax;
527 const math::Transform& xform = mInGrid->transform();
528 AccT acc = mInGrid->getAccessor();
529 const ValueT backg = mInGrid->background();
530 for (typename LeafRangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
531 ValueT* phi = leafIter.buffer( 0 ).data();
532 for (VoxelIterT voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
533 ValueT& value = phi[voxelIter.pos()];
534
535 if ( doLimiter ) {
536 assert(OrderRK == 1);
537 Vec3d wPos = xform.indexToWorld(voxelIter.getCoord());
538 mVelocityInt.template rungeKutta<1, Vec3d>(dt, wPos);// Explicit Euler
539 Vec3d iPos = xform.worldToIndex(wPos);
540 Coord ijk = Coord::floor( iPos );
541 BoxSampler::getValues(data, acc, ijk);
542 BoxSampler::extrema(data, vMin, vMax);
543 if ( doClamp ) {
544 value = math::Clamp( value, vMin, vMax);
545 } else if (value < vMin || value > vMax ) {
546 iPos -= Vec3R(ijk[0], ijk[1], ijk[2]);//unit coordinates
547 value = BoxSampler::trilinearInterpolation( data, iPos );
548 }
549 }
550
551 if (math::isApproxEqual(value, backg, math::Delta<ValueT>::value())) {
552 value = backg;
553 leafIter->setValueOff( voxelIter.pos() );
554 }
555 }//loop over active voxels
556 }//loop over leaf nodes
557 }
558 // Public member data of the private Advect class
559 typename boost::function<void (Advect*, const LeafRangeT&)> mTask;
560 const VolumeGridT* mInGrid;
561 const VelocityIntegratorT mVelocityInt;// lightweight!
562 const VolumeAdvection* mParent;
563 };// end of private member class Advect
564
565 } // namespace tools
566 } // namespace OPENVDB_VERSION_NAME
567 } // namespace openvdb
568
569 #endif // OPENVDB_TOOLS_VOLUME_ADVECT_HAS_BEEN_INCLUDED
570
571 // Copyright (c) 2012-2015 DreamWorks Animation LLC
572 // All rights reserved. This software is distributed under the
573 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v3_1_0::tools::Scheme::SemiLagrangian
SemiLagrangian
Numerical advections schemes.
Definition: VolumeAdvect.h:65
openvdb::v3_1_0::Index
Index32 Index
Definition: Types.h:58
openvdb::v3_1_0::tools::VolumeAdvection::getGrainSize
size_t getGrainSize() const
Definition: VolumeAdvect.h:171
openvdb::v3_1_0::util::wasInterrupted
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76
openvdb::v3_1_0::tools::Scheme::CLAMP
Definition: VolumeAdvect.h:68
Types.h
openvdb::v3_1_0::tools::VolumeAdvection::getIntegrator
Scheme::SemiLagrangian getIntegrator() const
Return the integrator (see details in the table above)
Definition: VolumeAdvect.h:156
openvdb::v3_1_0::math::Extrema
This class computes the minimum and maximum values of a population of floating-point values...
Definition: Stats.h:55
openvdb::v3_1_0::tools::VolumeAdvection::setSubSteps
void setSubSteps(int substeps)
Set the number of sub-steps per integration.
Definition: VolumeAdvect.h:188
NullInterrupter.h
openvdb::v3_1_0::tools::VolumeAdvection::setGrainSize
void setGrainSize(size_t grainsize)
Set the grain-size used for multi-threading.
Definition: VolumeAdvect.h:177
openvdb::v3_1_0::tools::Scheme::BFECC
Definition: VolumeAdvect.h:65
openvdb::v3_1_0::tools::VolumeAdvection::setIntegrator
void setIntegrator(Scheme::SemiLagrangian integrator)
Set the integrator (see details in the table above)
Definition: VolumeAdvect.h:153
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
VelocityFields.h
Defines two simple wrapper classes for advection velocity fields as well as VelocitySampler and Veloc...
openvdb::v3_1_0::math::Abs
int32_t Abs(int32_t i)
Return the absolute value of the given quantity.
Definition: Math.h:293
openvdb::v3_1_0::math::Delta
Delta for small floating-point offsets.
Definition: Math.h:132
openvdb::v3_1_0::math::RoundUp
float RoundUp(float x)
Return x rounded up to the nearest integer.
Definition: Math.h:735
openvdb::v3_1_0::ValueError
Definition: Exceptions.h:88
openvdb::v3_1_0::Vec3R
math::Vec3< Real > Vec3R
Definition: Types.h:76
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
openvdb::v3_1_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:192
openvdb::v3_1_0::math::Transform::worldToIndex
Vec3d worldToIndex(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:137
Statistics.h
Functions to efficiently compute histograms, extremas (min/max) and statistics (mean, variance, etc.) of grid values.
openvdb::v3_1_0::tools::VolumeAdvection::getLimiter
Scheme::Limiter getLimiter() const
Retrun the limiter (see details above)
Definition: VolumeAdvect.h:162
openvdb::v3_1_0::tools::Scheme::RK3
Definition: VolumeAdvect.h:65
openvdb::v3_1_0::tree::LeafManager
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:114
openvdb::v3_1_0::tools::VolumeAdvection
Performs advections of an arbitrary type of volume in a static velocity field. The advections is perf...
Definition: VolumeAdvect.h:99
openvdb::v3_1_0::tools::dilateVoxels
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
openvdb::v3_1_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:370
openvdb::v3_1_0::math::Transform::indexToWorld
Vec3d indexToWorld(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:135
Prune.h
Defined various multi-threaded utility functions for trees.
openvdb::v3_1_0::tools::Scheme::NO_LIMITER
Definition: VolumeAdvect.h:68
openvdb::v3_1_0::tools::Scheme::Limiter
Limiter
Flux-limiters employed to stabalize the second-order advection schemes MacCormack and BFECC...
Definition: VolumeAdvect.h:68
openvdb::v3_1_0::tools::Scheme::RK4
Definition: VolumeAdvect.h:65
openvdb::v3_1_0::tools::VolumeAdvection::isLimiterOn
bool isLimiterOn() const
Return true if a limiter will be applied based on the current settings.
Definition: VolumeAdvect.h:166
openvdb::v3_1_0::tools::Scheme::MAC
Definition: VolumeAdvect.h:65
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:43
openvdb::v3_1_0::util::NullInterrupter
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
openvdb::v3_1_0::tools::VolumeAdvection::spatialOrder
int spatialOrder() const
Return the spatial order of accuracy of the advection scheme.
Definition: VolumeAdvect.h:132
openvdb::v3_1_0::tools::VolumeAdvection::setLimiter
void setLimiter(Scheme::Limiter limiter)
Set the limiter (see details above)
Definition: VolumeAdvect.h:159
openvdb::v3_1_0::tools::VolumeAdvection::getSubSteps
int getSubSteps() const
Definition: VolumeAdvect.h:181
openvdb::v3_1_0::Vec3fGrid
Vec3SGrid Vec3fGrid
Definition: openvdb.h:77
openvdb::v3_1_0::RuntimeError
Definition: Exceptions.h:86
Morphology.h
Implementation of morphological dilation and erosion.
openvdb::v3_1_0::tools::VolumeAdvection::advect
VolumeGridT::Ptr advect(const VolumeGridT &inGrid, double timeStep)
Definition: VolumeAdvect.h:234
openvdb
Definition: Exceptions.h:39
openvdb::v3_1_0::tools::VolumeAdvection::~VolumeAdvection
virtual ~VolumeAdvection()
Definition: VolumeAdvect.h:123
openvdb::v3_1_0::math::Max
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:561
openvdb::v3_1_0::math::Vec3d
Vec3< double > Vec3d
Definition: Vec3.h:643
openvdb::v3_1_0::math::Extrema::add
void add(double val)
Add a single sample.
Definition: Stats.h:69
openvdb::v3_1_0::tools::VolumeAdvection::temporalOrder
int temporalOrder() const
Return the temporal order of accuracy of the advection scheme.
Definition: VolumeAdvect.h:140
openvdb::v3_1_0::tools::VelocityIntegrator
Performs Runge-Kutta time integration of variable order in a static velocity field.
Definition: VelocityFields.h:218
openvdb::v3_1_0::tools::Scheme::REVERT
Definition: VolumeAdvect.h:68
openvdb::v3_1_0::tools::Scheme::MID
Definition: VolumeAdvect.h:65
openvdb::v3_1_0::math::Transform
Calculate an axis-aligned bounding box in index space from a bounding sphere in world space...
Definition: Transform.h:66
openvdb::v3_1_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:367
openvdb::v3_1_0::tools::VolumeAdvection::VolumeAdvection
VolumeAdvection(const VelocityGridT &velGrid, InterrupterType *interrupter=NULL)
Constructor.
Definition: VolumeAdvect.h:110
Interpolation.h
openvdb::v3_1_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:379
openvdb::v3_1_0::math::Clamp
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:246
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
openvdb::v3_1_0::tools::VolumeAdvection::getMaxDistance
int getMaxDistance(const VolumeGridT &inGrid, double dt) const
Definition: VolumeAdvect.h:205
openvdb::v3_1_0::tools::Scheme::SEMI
Definition: VolumeAdvect.h:65
openvdb::v3_1_0::tools::VolumeAdvection::advect
VolumeGridT::Ptr advect(const VolumeGridT &inGrid, const MaskGridT &mask, double timeStep)
Definition: VolumeAdvect.h:282
openvdb::v3_1_0::math::Extrema::max
double max() const
Return the maximum value.
Definition: Stats.h:91