OpenVDB 12.0.0
 
Loading...
Searching...
No Matches
MultiResGrid.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/// @file MultiResGrid.h
5///
6/// @author Ken Museth
7///
8/// @warning This class is fairly new and as such has not seen a lot of
9/// use in production. Please report any issues or request for new
10/// features directly to ken.museth@dreamworks.com.
11///
12/// @brief Multi-resolution grid that contains LoD sequences of trees
13/// with powers of two refinements.
14///
15/// @note While this class can arguably be used to implement a sparse
16/// Multi-Grid solver it is currently intended as a means to
17/// efficiently compute LoD levels for applications like rendering
18///
19/// @note Prolongation means interpolation from coarse -> fine
20/// @note Restriction means interpolation (or remapping) from fine -> coarse
21///
22/// @todo Add option to define the level of the input grid (currenlty
23/// 0) so as to allow for super-sampling.
24
25#ifndef OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED
26#define OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED
27
28#include <openvdb/openvdb.h>
29#include <openvdb/Grid.h>
31#include <openvdb/math/Math.h>
34#include <openvdb/Metadata.h>
37#include <openvdb/util/Assert.h>
38
39#include "Interpolation.h"
40#include "Morphology.h"
41#include "Prune.h"
42#include "SignedFloodFill.h"
43#include "ValueTransformer.h"
44
45#include <tbb/blocked_range.h>
46#include <tbb/enumerable_thread_specific.h>
47#include <tbb/parallel_for.h>
48
49#include <iostream>
50#include <sstream>
51#include <string>
52#include <vector>
53
54
55namespace openvdb {
57namespace OPENVDB_VERSION_NAME {
58namespace tools {
59
60template<typename TreeType>
61class MultiResGrid: public MetaMap
62{
63public:
66
67 using ValueType = typename TreeType::ValueType;
68 using ValueOnCIter = typename TreeType::ValueOnCIter;
69 using ValueOnIter = typename TreeType::ValueOnIter;
70 using TreePtr = typename TreeType::Ptr;
71 using ConstTreePtr = typename TreeType::ConstPtr;
72 using GridPtr = typename Grid<TreeType>::Ptr;
74
75 //////////////////////////////////////////////////////////////////////
76
77 /// @brief Constructor of empty grids
78 /// @param levels The number of trees in this MultiResGrid
79 /// @param background Background value
80 /// @param voxelSize Size of a (uniform voxel). Defaults to one.
81 /// @note The multiple grids are all empty.
82 MultiResGrid(size_t levels, ValueType background, double voxelSize = 1.0);
83
84 /// @brief Given an initial high-resolution grid this constructor
85 /// generates all the coarser grids by means of restriction.
86 /// @param levels The number of trees in this MultiResGrid
87 /// @param grid High-resolution input grid
88 /// @param useInjection Use restriction by injection, vs
89 /// full-weighting. It defaults to false and should rarely be used.
90 /// @note This constructor will perform a deep copy of the input
91 /// grid and use it as the highest level grid.
92 MultiResGrid(size_t levels, const Grid<TreeType> &grid, bool useInjection = false);
93
94 /// @brief Given an initial high-resolution grid this constructor
95 /// generates all the coarser grids by means of restriction.
96 /// @param levels The number of trees in this MultiResGrid
97 /// @param grid High-resolution input grid
98 /// @param useInjection Use restriction by injection, vs
99 /// full-weighting. It defaults to false and should rarely be used.
100 /// @note This constructor will steal the input grid and use it
101 /// as the highest level grid. On output the grid is empty.
102 MultiResGrid(size_t levels, GridPtr grid, bool useInjection = false);
103
104 //////////////////////////////////////////////////////////////////////
105
106 /// @brief Return the number of levels, i.e. trees, in this MultiResGrid
107 /// @note level 0 is the finest level and numLevels()-1 is the coarsest
108 /// level.
109 size_t numLevels() const { return mTrees.size(); }
110
111 /// @brief Return the level of the finest grid (always 0)
112 static size_t finestLevel() { return 0; }
113
114 /// @brief Return the level of the coarsest grid, i.e. numLevels()-1
115 size_t coarsestLevel() const { return mTrees.size()-1; }
116
117 //////////////////////////////////////////////////////////////////////
118
119 /// @brief Return a reference to the tree at the specified level
120 /// @param level The level of the tree to be returned
121 /// @note Level 0 is by definition the finest tree.
122 TreeType& tree(size_t level);
123
124 /// @brief Return a const reference to the tree at the specified level
125 /// @param level The level of the tree to be returned
126 /// @note Level 0 is by definition the finest tree.
127 const TreeType& constTree(size_t level) const;
128
129 /// @brief Return a shared pointer to the tree at the specified level
130 /// @param level The level of the tree to be returned
131 /// @note Level 0 is by definition the finest tree.
132 TreePtr treePtr(size_t level);
133
134 /// @brief Return a const shared pointer to the tree at the specified level
135 /// @param level The level of the tree to be returned
136 /// @note Level 0 is by definition the finest tree.
137 ConstTreePtr constTreePtr(size_t level) const;
138
139 /// @brief Return a reference to the tree at the finest level
140 TreeType& finestTree() { return *mTrees.front(); }
141
142 /// @brief Return a const reference to the tree at the finest level
143 const TreeType& finestConstTree() const { return *mTrees.front(); }
144
145 /// @brief Return a shared pointer to the tree at the finest level
146 TreePtr finestTreePtr() { return mTrees.front(); }
147
148 /// @brief Return a const shared pointer to the tree at the finest level
149 ConstTreePtr finestConstTreePtr() const { return mTrees.front(); }
150
151 /// @brief Return a reference to the tree at the coarsest level
152 TreeType& coarsestTree() { return *mTrees.back(); }
153
154 /// @brief Return a const reference to the tree at the coarsest level
155 const TreeType& coarsestConstTree() const { return *mTrees.back(); }
156
157 /// @brief Return a shared pointer to the tree at the coarsest level
158 TreePtr coarsestTreePtr() { return mTrees.back(); }
159
160 /// @brief Return a const shared pointer to the tree at the coarsest level
161 ConstTreePtr coarsestConstTreePtr() const { return mTrees.back(); }
162
163 //////////////////////////////////////////////////////////////////////
164
165 /// @brief Return a shared pointer to the grid at the specified integer level
166 /// @param level Integer level of the grid to be returned
167 /// @note Level 0 is by definition the finest grid.
168 GridPtr grid(size_t level);
169
170 /// @brief Return a const shared pointer to the grid at the specified level
171 /// @param level The level of the grid to be returned
172 /// @note Level 0 is by definition the finest grid.
173 ConstGridPtr grid(size_t level) const;
174
175 /// @brief Return a shared pointer to a new grid at the specified
176 /// floating-point level.
177 /// @param level Floating-point level of the grid to be returned
178 /// @param grainSize Grain size for the multi-threading
179 /// @details Interpolation of the specified order is performed
180 /// between the bracketing integer levels.
181 /// @note Level 0 is by definition the finest grid.
182 template<Index Order>
183 GridPtr createGrid(float level, size_t grainSize = 1) const;
184
185 /// @brief Return a shared pointer to a vector of all the base
186 /// grids in this instance of the MultiResGrid.
187 /// @brief This method is useful for I/O
189
190 /// @brief Return a const shared pointer to a vector of all the base
191 /// grids in this instance of the MultiResGrid.
192 /// @brief This method is useful for I/O
194
195 //////////////////////////////////////////////////////////////////////
196
197 //@{
198 /// @brief Return a reference to the finest grid's transform, which might be
199 /// shared with other grids.
200 /// @note Calling setTransform() on this grid invalidates all references
201 /// previously returned by this method.
202 /// @warning The transform is relative to the finest level (=0) grid!
203 math::Transform& transform() { return *mTransform; }
204 const math::Transform& transform() const { return *mTransform; }
205 const math::Transform& constTransform() const { return *mTransform; }
206 //@}
207
208 //////////////////////////////////////////////////////////////////////
209
210 //@{
211 /// @brief Return the floating-point index coordinate at out_level given
212 /// the index coordinate in_xyz at in_level.
213 static Vec3R xyz(const Coord& in_ijk, size_t in_level, size_t out_level);
214 static Vec3R xyz(const Vec3R& in_xyz, size_t in_level, size_t out_level);
215 static Vec3R xyz(const Vec3R& in_xyz, double in_level, double out_level);
216 //@}
217
218 //////////////////////////////////////////////////////////////////////
219
220
221
222 //@{
223 /// @brief Return the value at the specified coordinate position using
224 /// interpolation of the specified order into the tree at the out_level.
225 ///
226 /// @details First in_ijk is mapped from index space at in_level to
227 /// out_level, and then a value is interpolated from the tree at out_level.
228 ///
229 /// @param in_ijk Index coordinate position relative to tree at in_level
230 /// @param in_level Integer level of the input coordinate in_ijk
231 /// @param out_level Integer level of the interpolated value
232 template<Index Order>
233 ValueType sampleValue(const Coord& in_ijk, size_t in_level, size_t out_level) const;
234 template<Index Order>
235 ValueType sampleValue(const Vec3R& in_ijk, size_t in_level, size_t out_level) const;
236 //@}
237
238 /// @brief Return the value at the specified integer coordinate position
239 /// and level using interpolation of the specified order.
240 /// @param ijk Integer coordinate position relative to the highest level (=0) grid
241 /// @param level Floating-point level from which to interpolate the value.
242 /// @brief Non-integer values of the level will use linear-interpolation
243 /// between the neighboring integer levels.
244 template<Index Order>
245 ValueType sampleValue(const Coord& ijk, double level) const;
246
247 /// @brief Return the value at the specified floating-point coordinate position
248 /// and level using interpolation of the specified order.
249 /// @param xyz Floating-point coordinate position relative to the highest level grid
250 /// @param level Floating-point level from which to interpolate
251 /// the value.
252 /// @brief Non-integer values of the level will use linear-interpolation
253 /// between the neighboring integer levels.
254 template<Index Order>
255 ValueType sampleValue(const Vec3R& xyz, double level) const;
256
257 //////////////////////////////////////////////////////////////////////
258
259 /// @brief Return the value at coordinate location in @a level tree
260 /// from the coarser tree at @a level+1 using trilinear interpolation
261 /// @param coords input coords relative to the fine tree at level
262 /// @param level The fine level to receive values from the coarser
263 /// level-1
264 /// @note Prolongation means to interpolation from coarse -> fine
265 ValueType prolongateVoxel(const Coord& coords, const size_t level) const;
266
267
268 /// (coarse->fine) Populates all the active voxel values in a fine (@a level) tree
269 /// from the coarse (@a level+1) tree using linear interpolation
270 /// This transforms multiple values of the tree in parallel
271 void prolongateActiveVoxels(size_t destlevel, size_t grainSize = 1);
272
273 //////////////////////////////////////////////////////////////////////
274
275 /// Populate a coordinate location in @a level (coarse) tree
276 /// from the @a level-1 (fine) tree using trilinear interpolation
277 /// input coords are relative to the mTree[level] (coarse)
278 /// @note Restriction means remapping from fine -> coarse
279 ValueType restrictVoxel(Coord ijk, const size_t level, bool useInjection = false) const;
280
281 /// (fine->coarse) Populates all the active voxel values in the coarse (@a level) tree
282 /// from the fine (@a level-1) tree using trilinear interpolation.
283 /// For cell-centered data, this is equivalent to an average
284 /// For vertex-centered data this is equivalent to transferring the data
285 /// from the fine vertex directly above the coarse vertex.
286 /// This transforms multiple values of the tree in parallel
287 void restrictActiveVoxels(size_t destlevel, size_t grainSize = 1);
288
289 /// Output a human-readable description of this MultiResGrid
290 void print(std::ostream& = std::cout, int verboseLevel = 1) const;
291
292 /// @brief Return a string with the name of this MultiResGrid
293 std::string getName() const
294 {
295 if (Metadata::ConstPtr meta = (*this)[GridBase::META_GRID_NAME]) return meta->str();
296 return "";
297 }
298
299 /// @brief Set the name of this MultiResGrid
300 void setName(const std::string& name)
301 {
304 }
305
306 /// Return the class of volumetric data (level set, fog volume, etc.) stored in this grid.
313
314 /// Specify the class of volumetric data (level set, fog volume, etc.) stored in this grid.
319
320 /// Remove the setting specifying the class of this grid's volumetric data.
322
323private:
324
325 MultiResGrid(const MultiResGrid& other);//disallow copy construction
326 MultiResGrid& operator=(const MultiResGrid& other);//disallow copy assignment
327
328 // For optimal performance we disable registration of the ValueAccessor
330 using ConstAccessor = tree::ValueAccessor<const TreeType, false>;
331
332 void topDownRestrict(bool useInjection);
333
334 inline void initMeta();
335
336 // Private struct that concurrently creates a mask of active voxel
337 // in a coarse tree from the active voxels in a fine tree
338 struct MaskOp;
339
340 /// Private struct that performs multi-threaded restriction
341 struct RestrictOp;
342
343 /// Private struct that performs multi-threaded prolongation
344 struct ProlongateOp;
345
346 // Private struct that performs multi-threaded computation of grids a fraction levels
347 template<Index Order>
348 struct FractionOp;
349
350 /// Private template struct that performs the actual multi-threading
351 template<typename OpType> struct CookOp;
352
353 // Array of shared pointer to trees, level 0 has the highest resolution.
354 std::vector<TreePtr> mTrees;
355 // Shared pointer to a transform associated with the finest level grid
356 typename math::Transform::Ptr mTransform;
357};// MultiResGrid
358
359template<typename TreeType>
361MultiResGrid(size_t levels, ValueType background, double voxelSize)
362 : mTrees(levels)
363 , mTransform(math::Transform::createLinearTransform( voxelSize ))
364{
365 this->initMeta();
366 for (size_t i=0; i<levels; ++i) mTrees[i] = TreePtr(new TreeType(background));
367}
368
369template<typename TreeType>
371MultiResGrid(size_t levels, const Grid<TreeType> &grid, bool useInjection)
372 : MetaMap(grid)
373 , mTrees(levels)
374 , mTransform( grid.transform().copy() )
375{
376 this->initMeta();
377 mTrees[0].reset( new TreeType( grid.tree() ) );// deep copy input tree
378 mTrees[0]->voxelizeActiveTiles();
379 this->topDownRestrict(useInjection);
380}
381
382template<typename TreeType>
384MultiResGrid(size_t levels, GridPtr grid, bool useInjection)
385 : MetaMap(*grid)
386 , mTrees(levels)
387 , mTransform( grid->transform().copy() )
388{
389 this->initMeta();
390 mTrees[0] = grid->treePtr();// steal tree from input grid
391 mTrees[0]->voxelizeActiveTiles();
392 grid->newTree();
393 this->topDownRestrict(useInjection);
394}
395
396template<typename TreeType>
398tree(size_t level)
399{
400 OPENVDB_ASSERT( level < mTrees.size() );
401 return *mTrees[level];
402}
403
404template<typename TreeType>
405inline const TreeType& MultiResGrid<TreeType>::
406constTree(size_t level) const
407{
408 OPENVDB_ASSERT( level < mTrees.size() );
409 return *mTrees[level];
410}
411
412template<typename TreeType>
413inline typename TreeType::Ptr MultiResGrid<TreeType>::
414treePtr(size_t level)
415{
416 OPENVDB_ASSERT( level < mTrees.size() );
417 return mTrees[level];
418}
419
420template<typename TreeType>
421inline typename TreeType::ConstPtr MultiResGrid<TreeType>::
422constTreePtr(size_t level) const
423{
424 OPENVDB_ASSERT( level < mTrees.size() );
425 return mTrees[level];
426}
427
428template<typename TreeType>
430grid(size_t level)
431{
433 math::Transform::Ptr xform = mTransform->copy();
434 if (level>0) xform->preScale( Real(1 << level) );
435 grid->setTransform( xform );
436 grid->insertMeta( *this->copyMeta() );
437 grid->insertMeta( "MultiResGrid_Level", Int64Metadata(level));
438 std::stringstream ss;
439 ss << this->getName() << "_level_" << level;
440 grid->setName( ss.str() );
441 return grid;
442}
443
444template<typename TreeType>
446grid(size_t level) const
447{
448 return const_cast<MultiResGrid*>(this)->grid(level);
449}
450
451template<typename TreeType>
452template<Index Order>
454createGrid(float level, size_t grainSize) const
455{
456 OPENVDB_ASSERT( level >= 0.0f && level <= float(mTrees.size()-1) );
457
458 typename Grid<TreeType>::Ptr grid(new Grid<TreeType>(this->constTree(0).background()));
459 math::Transform::Ptr xform = mTransform->copy();
460 xform->preScale( math::Pow(2.0f, level) );
461 grid->setTransform( xform );
462 grid->insertMeta( *(this->copyMeta()) );
463 grid->insertMeta( "MultiResGrid_Level", FloatMetadata(level) );
464 std::stringstream ss;
465 ss << this->getName() << "_level_" << level;
466 grid->setName( ss.str() );
467
468 if ( size_t(floorf(level)) == size_t(ceilf(level)) ) {
469 grid->setTree( this->constTree( size_t(floorf(level))).copy() );
470 } else {
471 FractionOp<Order> tmp(*this, grid->tree(), level, grainSize);
472 if ( grid->getGridClass() == GRID_LEVEL_SET ) {
473 signedFloodFill( grid->tree() );
474 pruneLevelSet( grid->tree() );//only creates inactive tiles
475 }
476 }
477
478 return grid;
479}
480
481template<typename TreeType>
483grids()
484{
486 for (size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
487 return grids;
488}
489
490template<typename TreeType>
492grids() const
493{
495 for (size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
496 return grids;
497}
498
499template<typename TreeType>
501xyz(const Coord& in_ijk, size_t in_level, size_t out_level)
502{
503 return Vec3R( in_ijk.data() ) * Real(1 << in_level) / Real(1 << out_level);
504}
505
506template<typename TreeType>
508xyz(const Vec3R& in_xyz, size_t in_level, size_t out_level)
509{
510 return in_xyz * Real(1 << in_level) / Real(1 << out_level);
511}
512
513template<typename TreeType>
515xyz(const Vec3R& in_xyz, double in_level, double out_level)
516{
517 return in_xyz * math::Pow(2.0, in_level - out_level);
518
519}
520
521template<typename TreeType>
522template<Index Order>
523typename TreeType::ValueType MultiResGrid<TreeType>::
524sampleValue(const Coord& in_ijk, size_t in_level, size_t out_level) const
525{
526 OPENVDB_ASSERT( in_level < mTrees.size() );
527 OPENVDB_ASSERT( out_level < mTrees.size() );
528 const ConstAccessor acc(*mTrees[out_level]);// has disabled registration!
529 return tools::Sampler<Order>::sample( acc, this->xyz(in_ijk, in_level, out_level) );
530}
531
532template<typename TreeType>
533template<Index Order>
534typename TreeType::ValueType MultiResGrid<TreeType>::
535sampleValue(const Vec3R& in_xyz, size_t in_level, size_t out_level) const
536{
537 OPENVDB_ASSERT( in_level < mTrees.size() );
538 OPENVDB_ASSERT( out_level < mTrees.size() );
539 const ConstAccessor acc(*mTrees[out_level]);// has disabled registration!
540 return tools::Sampler<Order>::sample( acc, this->xyz(in_xyz, in_level, out_level) );
541}
542
543template<typename TreeType>
544template<Index Order>
545typename TreeType::ValueType MultiResGrid<TreeType>::
546sampleValue(const Coord& ijk, double level) const
547{
548 OPENVDB_ASSERT( level >= 0.0 && level <= double(mTrees.size()-1) );
549 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
550 const ValueType v0 = this->template sampleValue<Order>( ijk, 0, level0 );
551 if ( level0 == level1 ) return v0;
552 OPENVDB_ASSERT( level1 - level0 == 1 );
553 const ValueType v1 = this->template sampleValue<Order>( ijk, 0, level1 );
555 const ValueType a = ValueType(level1 - level);
557 return a * v0 + (ValueType(1) - a) * v1;
558}
559
560template<typename TreeType>
561template<Index Order>
562typename TreeType::ValueType MultiResGrid<TreeType>::
563sampleValue(const Vec3R& xyz, double level) const
564{
565 OPENVDB_ASSERT( level >= 0.0 && level <= double(mTrees.size()-1) );
566 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
567 const ValueType v0 = this->template sampleValue<Order>( xyz, 0, level0 );
568 if ( level0 == level1 ) return v0;
569 OPENVDB_ASSERT( level1 - level0 == 1 );
570 const ValueType v1 = this->template sampleValue<Order>( xyz, 0, level1 );
572 const ValueType a = ValueType(level1 - level);
574 return a * v0 + (ValueType(1) - a) * v1;
575}
576
577template<typename TreeType>
578typename TreeType::ValueType MultiResGrid<TreeType>::
579prolongateVoxel(const Coord& ijk, const size_t level) const
580{
581 OPENVDB_ASSERT( level+1 < mTrees.size() );
582 const ConstAccessor acc(*mTrees[level + 1]);// has disabled registration!
583 return ProlongateOp::run(ijk, acc);
584}
585
586template<typename TreeType>
588prolongateActiveVoxels(size_t destlevel, size_t grainSize)
589{
590 OPENVDB_ASSERT( destlevel < mTrees.size()-1 );
591 TreeType &fineTree = *mTrees[ destlevel ];
592 const TreeType &coarseTree = *mTrees[ destlevel+1 ];
593 CookOp<ProlongateOp> tmp( coarseTree, fineTree, grainSize );
594}
595
596template<typename TreeType>
597typename TreeType::ValueType MultiResGrid<TreeType>::
598restrictVoxel(Coord ijk, const size_t destlevel, bool useInjection) const
599{
600 OPENVDB_ASSERT( destlevel > 0 && destlevel < mTrees.size() );
601 const TreeType &fineTree = *mTrees[ destlevel-1 ];
602 if ( useInjection ) return fineTree.getValue(ijk<<1);
603 const ConstAccessor acc( fineTree );// has disabled registration!
604 return RestrictOp::run( ijk, acc);
605}
606
607template<typename TreeType>
609restrictActiveVoxels(size_t destlevel, size_t grainSize)
610{
611 OPENVDB_ASSERT( destlevel > 0 && destlevel < mTrees.size() );
612 const TreeType &fineTree = *mTrees[ destlevel-1 ];
613 TreeType &coarseTree = *mTrees[ destlevel ];
614 CookOp<RestrictOp> tmp( fineTree, coarseTree, grainSize );
615}
616
617template<typename TreeType>
619print(std::ostream& os, int verboseLevel) const
620{
621 os << "MultiResGrid with " << mTrees.size() << " levels\n";
622 for (size_t i=0; i<mTrees.size(); ++i) {
623 os << "Level " << i << ": ";
624 mTrees[i]->print(os, verboseLevel);
625 }
626
627 if ( MetaMap::metaCount() > 0) {
628 os << "Additional metadata:" << std::endl;
629 for (ConstMetaIterator it = beginMeta(), end = endMeta(); it != end; ++it) {
630 os << " " << it->first;
631 if (it->second) {
632 const std::string value = it->second->str();
633 if (!value.empty()) os << ": " << value;
634 }
635 os << "\n";
636 }
637 }
638
639 os << "Transform:" << std::endl;
640 transform().print(os, /*indent=*/" ");
641 os << std::endl;
642}
643
644template<typename TreeType>
646initMeta()
647{
648 const size_t levels = this->numLevels();
649 if (levels < 2) {
650 OPENVDB_THROW(ValueError, "MultiResGrid: at least two levels are required");
651 }
652 this->insertMeta("MultiResGrid_Levels", Int64Metadata( levels ) );
653}
654
655template<typename TreeType>
656void MultiResGrid<TreeType>::
657topDownRestrict(bool useInjection)
658{
659 const bool isLevelSet = this->getGridClass() == GRID_LEVEL_SET;
660 for (size_t n=1; n<mTrees.size(); ++n) {
661 const TreeType &fineTree = *mTrees[n-1];
662 mTrees[n] = TreePtr(new TreeType( fineTree.background() ) );// empty tree
663 TreeType &coarseTree = *mTrees[n];
664 if (useInjection) {// Restriction by injection
665 for (ValueOnCIter it = fineTree.cbeginValueOn(); it; ++it) {
666 const Coord ijk = it.getCoord();
667 if ( (ijk[0] & 1) || (ijk[1] & 1) || (ijk[2] & 1) ) continue;
668 coarseTree.setValue( ijk >> 1, *it );
669 }
670 } else {// Restriction by full-weighting
671 MaskOp tmp(fineTree, coarseTree, 128);
672 this->restrictActiveVoxels(n, 64);
673 }
674 if ( isLevelSet ) {
675 tools::signedFloodFill( coarseTree );
676 tools::pruneLevelSet( coarseTree );//only creates inactive tiles
677 }
678 }// loop over grid levels
679}
680
681template<typename TreeType>
683{
684 using MaskT = typename TreeType::template ValueConverter<ValueMask>::Type;
685 using PoolType = tbb::enumerable_thread_specific<TreeType>;
687 using RangeT = typename ManagerT::LeafRange;
688 using VoxelIterT = typename ManagerT::LeafNodeType::ValueOnCIter;
689
690 MaskOp(const TreeType& fineTree, TreeType& coarseTree, size_t grainSize = 1)
691 : mPool(new PoolType( coarseTree ) )// empty coarse tree acts as examplar
692 {
693 OPENVDB_ASSERT( coarseTree.empty() );
694
695 // Create Mask of restruction performed on fineTree
696 MaskT mask(fineTree, false, true, TopologyCopy() );
697
698 // Multi-threaded dilation which also linearizes the tree to leaf nodes
700
701 // Restriction by injection using thread-local storage of coarse tree masks
702 ManagerT leafs( mask );
703 tbb::parallel_for(leafs.leafRange( grainSize ), *this);
704
705 // multithreaded union of thread-local coarse tree masks with the coarse tree
706 using IterT = typename PoolType::const_iterator;
707 for (IterT it=mPool->begin(); it!=mPool->end(); ++it) coarseTree.topologyUnion( *it );
708 delete mPool;
709 }
710 void operator()(const RangeT& range) const
711 {
712 Accessor coarseAcc( mPool->local() );// disabled registration
713 for (typename RangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
714 for (VoxelIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
715 Coord ijk = voxelIter.getCoord();
716 if ( (ijk[2] & 1) || (ijk[1] & 1) || (ijk[0] & 1) ) continue;//no overlap
717 coarseAcc.setValueOn( ijk >> 1 );//injection from fine to coarse level
718 }//loop over active voxels in the fine tree
719 }// loop over leaf nodes in the fine tree
720 }
722};// MaskOp
723
724template<typename TreeType>
725template<Index Order>
726struct MultiResGrid<TreeType>::FractionOp
727{
728 using MaskT = typename TreeType::template ValueConverter<ValueMask>::Type;
729 using PoolType = tbb::enumerable_thread_specific<MaskT>;
730 using PoolIterT = typename PoolType::iterator;
731 using Manager1 = tree::LeafManager<const TreeType>;
732 using Manager2 = tree::LeafManager<TreeType>;
733 using Range1 = typename Manager1::LeafRange;
734 using Range2 = typename Manager2::LeafRange;
735
736 FractionOp(const MultiResGrid& parent,
737 TreeType& midTree,
738 float level,
739 size_t grainSize = 1)
740 : mLevel( level )
741 , mPool(nullptr)
742 , mTree0( &*(parent.mTrees[size_t(floorf(level))]) )//high-resolution
743 , mTree1( &*(parent.mTrees[size_t(ceilf(level))]) ) //low-resolution
744 {
745 OPENVDB_ASSERT( midTree.empty() );
746 OPENVDB_ASSERT( mTree0 != mTree1 );
747
748 // Create a pool of thread-local masks
749 MaskT examplar( false );
750 mPool = new PoolType( examplar );
751
752 {// create mask from re-mapping coarse tree to mid-level tree
753 tree::LeafManager<const TreeType> manager( *mTree1 );
754 tbb::parallel_for( manager.leafRange(grainSize), *this );
755 }
756
757 // Multi-threaded dilation of mask
758 tbb::parallel_for(tbb::blocked_range<PoolIterT>(mPool->begin(),mPool->end(),1), *this);
759
760 // Union thread-local coarse tree masks into the coarse tree
761 for (PoolIterT it=mPool->begin(); it!=mPool->end(); ++it) midTree.topologyUnion( *it );
762 delete mPool;
763
764 {// Interpolate values into the static mid level tree
765 Manager2 manager( midTree );
766 tbb::parallel_for(manager.leafRange(grainSize), *this);
767 }
768 }
769 void operator()(const Range1& range) const
770 {
771 using VoxelIter = typename Manager1::LeafNodeType::ValueOnCIter;
772 // Let mLevel = level + frac, where
773 // level is integer part of mLevel and frac is the fractional part
774 // low-res voxel size in world units = dx1 = 2^(level + 1)
775 // mid-res voxel size in world units = dx = 2^(mLevel) = 2^(level + frac)
776 // low-res index -> world: ijk * dx1
777 // world -> mid-res index: world / dx
778 // low-res index -> mid-res index: (ijk * dx1) / dx = ijk * scale where
779 // scale = dx1/dx = 2^(level+1)/2^(level+frac) = 2^(1-frac)
780 const float scale = math::Pow(2.0f, 1.0f - math::FractionalPart(mLevel));
781 tree::ValueAccessor<MaskT, false> acc( mPool->local() );// disabled registration
782 for (typename Range1::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
783 for (VoxelIter voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
784 Coord ijk = voxelIter.getCoord();
786 const auto value0 = ijk[0] * scale;
787 const auto value1 = ijk[1] * scale;
788 const auto value2 = ijk[2] * scale;
790 ijk[0] = int(math::Round(value0));
791 ijk[1] = int(math::Round(value1));
792 ijk[2] = int(math::Round(value2));
793
794 acc.setValueOn( ijk );
795 }//loop over active voxels in the fine tree
796 }// loop over leaf nodes in the fine tree
797 }
798 void operator()(const tbb::blocked_range<PoolIterT>& range) const
799 {
800 for (PoolIterT it=range.begin(); it!=range.end(); ++it) {
802 }
803 }
804 void operator()(const Range2 &r) const
805 {
806 using VoxelIter = typename TreeType::LeafNodeType::ValueOnIter;
807 // Let mLevel = level + frac, where
808 // level is integer part of mLevel and frac is the fractional part
809 // high-res voxel size in world units = dx0 = 2^(level)
810 // low-res voxel size in world units = dx1 = 2^(level+1)
811 // mid-res voxel size in world units = dx = 2^(mLevel) = 2^(level + frac)
812 // mid-res index -> world: ijk * dx
813 // world -> high-res index: world / dx0
814 // world -> low-res index: world / dx1
815 // mid-res index -> high-res index: (ijk * dx) / dx0 = ijk * scale0 where
816 // scale0 = dx/dx0 = 2^(level+frac)/2^(level) = 2^(frac)
817 // mid-res index -> low-res index: (ijk * dx) / dx1 = ijk * scale1 where
818 // scale1 = dx/dx1 = 2^(level+frac)/2^(level+1) = 2^(frac-1)
819 const float b = math::FractionalPart(mLevel), a = 1.0f - b;
820 const float scale0 = math::Pow( 2.0f, b );
821 const float scale1 = math::Pow( 2.0f,-a );
822 ConstAccessor acc0( *mTree0 ), acc1( *mTree1 );
823 for (typename Range2::Iterator leafIter = r.begin(); leafIter; ++leafIter) {
824 for (VoxelIter voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
825 const Vec3R xyz = Vec3R( voxelIter.getCoord().data() );// mid level coord
826 const ValueType v0 = tools::Sampler<Order>::sample( acc0, xyz * scale0 );
827 const ValueType v1 = tools::Sampler<Order>::sample( acc1, xyz * scale1 );
829 const auto value0 = a*v0;
830 const auto value1 = b*v1;
832 voxelIter.setValue( ValueType(value0 + value1) );
833 }
834 }
835 }
836 const float mLevel;
837 PoolType* mPool;
838 const TreeType *mTree0, *mTree1;
839};// FractionOp
840
841
842template<typename TreeType>
843template<typename OperatorType>
844struct MultiResGrid<TreeType>::CookOp
845{
846 using ManagerT = tree::LeafManager<TreeType>;
847 using RangeT = typename ManagerT::LeafRange;
848
849 CookOp(const TreeType& srcTree, TreeType& dstTree, size_t grainSize): acc(srcTree)
850 {
851 ManagerT leafs(dstTree);
852 tbb::parallel_for(leafs.leafRange(grainSize), *this);
853 }
854 CookOp(const CookOp &other): acc(other.acc.tree()) {}
855
856 void operator()(const RangeT& range) const
857 {
858 for (auto leafIt = range.begin(); leafIt; ++leafIt) {
859 auto& phi = leafIt.buffer(0);
860 for (auto voxelIt = leafIt->beginValueOn(); voxelIt; ++voxelIt) {
861 phi.setValue(voxelIt.pos(), OperatorType::run(voxelIt.getCoord(), acc));
862 }
863 }
864 }
865
866 const ConstAccessor acc;
867};// CookOp
868
869
870template<typename TreeType>
872{
873 /// @brief Static method that performs restriction by full weighting
874 /// @param ijk Coordinate location on the coarse tree
875 /// @param acc ValueAccessor to the fine tree
876 static ValueType run(Coord ijk, const ConstAccessor &acc)
877 {
878 ijk <<= 1;
879 // Overlapping grid point
880 ValueType v = 8*acc.getValue(ijk);
881 // neighbors in one axial direction
882 v += 4*(acc.getValue(ijk.offsetBy(-1, 0, 0)) + acc.getValue(ijk.offsetBy( 1, 0, 0)) +// x
883 acc.getValue(ijk.offsetBy( 0,-1, 0)) + acc.getValue(ijk.offsetBy( 0, 1, 0)) +// y
884 acc.getValue(ijk.offsetBy( 0, 0,-1)) + acc.getValue(ijk.offsetBy( 0, 0, 1)));// z
885 // neighbors in two axial directions
886 v += 2*(acc.getValue(ijk.offsetBy(-1,-1, 0)) + acc.getValue(ijk.offsetBy(-1, 1, 0)) +// xy
887 acc.getValue(ijk.offsetBy( 1,-1, 0)) + acc.getValue(ijk.offsetBy( 1, 1, 0)) +// xy
888 acc.getValue(ijk.offsetBy(-1, 0,-1)) + acc.getValue(ijk.offsetBy(-1, 0, 1)) +// xz
889 acc.getValue(ijk.offsetBy( 1, 0,-1)) + acc.getValue(ijk.offsetBy( 1, 0, 1)) +// xz
890 acc.getValue(ijk.offsetBy( 0,-1,-1)) + acc.getValue(ijk.offsetBy( 0,-1, 1)) +// yz
891 acc.getValue(ijk.offsetBy( 0, 1,-1)) + acc.getValue(ijk.offsetBy( 0, 1, 1)));// yz
892 // neighbors in three axial directions
893 for (int i=-1; i<=1; i+=2) {
894 for (int j=-1; j<=1; j+=2) {
895 for (int k=-1; k<=1; k+=2) v += acc.getValue(ijk.offsetBy(i,j,k));// xyz
896 }
897 }
898 v *= ValueType(1.0f/64.0f);
899 return v;
900 }
901};// RestrictOp
902
903template<typename TreeType>
905{
906 /// @brief Interpolate values from a coarse grid (acc) into the index space (ijk) of a fine grid
907 /// @param ijk Coordinate location on the fine tree
908 /// @param acc ValueAccessor to the coarse tree
909 static ValueType run(const Coord& ijk, const ConstAccessor &acc)
910 {
911 switch ( (ijk[0] & 1) | ((ijk[1] & 1) << 1) | ((ijk[2] & 1) << 2) ) {
912 case 0:// all even
913 return acc.getValue(ijk>>1);
914 case 1:// x is odd
915 return ValueType(0.5)*(acc.getValue(ijk.offsetBy(-1,0,0)>>1) +
916 acc.getValue(ijk.offsetBy( 1,0,0)>>1));
917 case 2:// y is odd
918 return ValueType(0.5)*(acc.getValue(ijk.offsetBy(0,-1,0)>>1) +
919 acc.getValue(ijk.offsetBy(0, 1,0)>>1));
920 case 3:// x&y are odd
921 return ValueType(0.25)*(acc.getValue(ijk.offsetBy(-1,-1,0)>>1) +
922 acc.getValue(ijk.offsetBy(-1, 1,0)>>1) +
923 acc.getValue(ijk.offsetBy( 1,-1,0)>>1) +
924 acc.getValue(ijk.offsetBy( 1, 1,0)>>1));
925 case 4:// z is odd
926 return ValueType(0.5)*(acc.getValue(ijk.offsetBy(0,0,-1)>>1) +
927 acc.getValue(ijk.offsetBy(0,0, 1)>>1));
928 case 5:// x&z are odd
929 return ValueType(0.25)*(acc.getValue(ijk.offsetBy(-1,0,-1)>>1) +
930 acc.getValue(ijk.offsetBy(-1,0, 1)>>1) +
931 acc.getValue(ijk.offsetBy( 1,0,-1)>>1) +
932 acc.getValue(ijk.offsetBy( 1,0, 1)>>1));
933 case 6:// y&z are odd
934 return ValueType(0.25)*(acc.getValue(ijk.offsetBy(0,-1,-1)>>1) +
935 acc.getValue(ijk.offsetBy(0,-1, 1)>>1) +
936 acc.getValue(ijk.offsetBy(0, 1,-1)>>1) +
937 acc.getValue(ijk.offsetBy(0, 1, 1)>>1));
938 }
939 // all are odd
941 for (int i=-1; i<=1; i+=2) {
942 for (int j=-1; j<=1; j+=2) {
943 for (int k=-1; k<=1; k+=2) v += acc.getValue(ijk.offsetBy(i,j,k)>>1);// xyz
944 }
945 }
946 return ValueType(0.125) * v;
947 }
948};// ProlongateOp
949
950
951////////////////////////////////////////
952
953
954// Explicit Template Instantiation
955
956#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
957
958#ifdef OPENVDB_INSTANTIATE_MULTIRESGRID
960#endif
961
964
965#endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
966
967
968} // namespace tools
969} // namespace OPENVDB_VERSION_NAME
970} // namespace openvdb
971
972#endif // OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Implementation of morphological dilation and erosion.
#define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
Bracket code with OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN/_END, to inhibit warnings about type conve...
Definition Platform.h:221
#define OPENVDB_NO_TYPE_CONVERSION_WARNING_END
Definition Platform.h:222
Defined various multi-threaded utility functions for trees.
Propagate the signs of distance values from the active voxels in the narrow band to the inactive valu...
static const char *const META_GRID_NAME
Definition Grid.h:353
static const char *const META_GRID_CLASS
Definition Grid.h:351
static GridClass stringToGridClass(const std::string &)
Return the class of volumetric data specified by the given string.
static std::string gridClassToString(GridClass)
Return the metadata string value for the given class of volumetric data.
Container class that associates a tree with a transform and metadata.
Definition Grid.h:571
SharedPtr< const Grid > ConstPtr
Definition Grid.h:574
SharedPtr< Grid > Ptr
Definition Grid.h:573
static Ptr create()
Return a new grid with background value zero.
Definition Grid.h:1343
MetaMap::Ptr copyMeta() const
Return a copy of this map whose fields are shared with this map.
T::Ptr getMetadata(const Name &)
Return a pointer to a TypedMetadata object of type T and with the given name. If no such field exists...
Definition MetaMap.h:138
size_t metaCount() const
Definition MetaMap.h:91
MetaIterator beginMeta()
Definition MetaMap.h:84
MetadataMap::const_iterator ConstMetaIterator
Definition MetaMap.h:27
void removeMeta(const Name &)
Remove the given metadata field if it exists.
MetaIterator endMeta()
Definition MetaMap.h:85
MetaMap()
Definition MetaMap.h:30
void insertMeta(const Name &, const Metadata &value)
Insert a new metadata field or overwrite the value of an existing field.
SharedPtr< const Metadata > ConstPtr
Definition Metadata.h:28
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition Types.h:683
Definition Exceptions.h:65
SharedPtr< const TypedMetadata< std::string > > ConstPtr
Definition Metadata.h:126
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition Coord.h:92
const Int32 * data() const
Definition Coord.h:140
Definition Transform.h:40
SharedPtr< Transform > Ptr
Definition Transform.h:42
Definition MultiResGrid.h:62
ValueType restrictVoxel(Coord ijk, const size_t level, bool useInjection=false) const
Definition MultiResGrid.h:598
void setGridClass(GridClass cls)
Specify the class of volumetric data (level set, fog volume, etc.) stored in this grid.
Definition MultiResGrid.h:315
typename TreeType::ValueOnIter ValueOnIter
Definition MultiResGrid.h:69
void prolongateActiveVoxels(size_t destlevel, size_t grainSize=1)
Definition MultiResGrid.h:588
ValueType sampleValue(const Coord &in_ijk, size_t in_level, size_t out_level) const
Return the value at the specified coordinate position using interpolation of the specified order into...
ConstTreePtr coarsestConstTreePtr() const
Return a const shared pointer to the tree at the coarsest level.
Definition MultiResGrid.h:161
typename TreeType::ValueType ValueType
Definition MultiResGrid.h:67
void print(std::ostream &=std::cout, int verboseLevel=1) const
Definition MultiResGrid.h:619
const math::Transform & constTransform() const
Definition MultiResGrid.h:205
GridPtr grid(size_t level)
Definition MultiResGrid.h:430
void clearGridClass()
Remove the setting specifying the class of this grid's volumetric data.
Definition MultiResGrid.h:321
SharedPtr< MultiResGrid > Ptr
Definition MultiResGrid.h:64
TreeType & tree(size_t level)
Definition MultiResGrid.h:398
GridPtrVecPtr grids()
Definition MultiResGrid.h:483
MultiResGrid(size_t levels, ValueType background, double voxelSize=1.0)
Constructor of empty grids.
Definition MultiResGrid.h:361
math::Transform & transform()
Return a reference to the finest grid's transform, which might be shared with other grids.
Definition MultiResGrid.h:203
TreeType & coarsestTree()
Return a reference to the tree at the coarsest level.
Definition MultiResGrid.h:152
static size_t finestLevel()
Return the level of the finest grid (always 0)
Definition MultiResGrid.h:112
size_t coarsestLevel() const
Return the level of the coarsest grid, i.e. numLevels()-1.
Definition MultiResGrid.h:115
size_t numLevels() const
Return the number of levels, i.e. trees, in this MultiResGrid.
Definition MultiResGrid.h:109
ConstTreePtr constTreePtr(size_t level) const
Definition MultiResGrid.h:422
ValueType sampleValue(const Vec3R &in_ijk, size_t in_level, size_t out_level) const
std::string getName() const
Return a string with the name of this MultiResGrid.
Definition MultiResGrid.h:293
ValueType sampleValue(const Coord &ijk, double level) const
Return the value at the specified integer coordinate position and level using interpolation of the sp...
SharedPtr< const MultiResGrid > ConstPtr
Definition MultiResGrid.h:65
GridClass getGridClass() const
Return the class of volumetric data (level set, fog volume, etc.) stored in this grid.
Definition MultiResGrid.h:307
typename TreeType::ValueOnCIter ValueOnCIter
Definition MultiResGrid.h:68
void setName(const std::string &name)
Set the name of this MultiResGrid.
Definition MultiResGrid.h:300
typename Grid< TreeType >::Ptr GridPtr
Definition MultiResGrid.h:72
ValueType prolongateVoxel(const Coord &coords, const size_t level) const
Definition MultiResGrid.h:579
TreeType::ValueType sampleValue(const Coord &in_ijk, size_t in_level, size_t out_level) const
Definition MultiResGrid.h:524
typename Grid< TreeType >::ConstPtr ConstGridPtr
Definition MultiResGrid.h:73
const math::Transform & transform() const
Definition MultiResGrid.h:204
void restrictActiveVoxels(size_t destlevel, size_t grainSize=1)
Definition MultiResGrid.h:609
const TreeType & constTree(size_t level) const
Definition MultiResGrid.h:406
ConstTreePtr finestConstTreePtr() const
Return a const shared pointer to the tree at the finest level.
Definition MultiResGrid.h:149
TreePtr finestTreePtr()
Return a shared pointer to the tree at the finest level.
Definition MultiResGrid.h:146
typename TreeType::Ptr TreePtr
Definition MultiResGrid.h:70
GridPtr createGrid(float level, size_t grainSize=1) const
Return a shared pointer to a new grid at the specified floating-point level.
const TreeType & finestConstTree() const
Return a const reference to the tree at the finest level.
Definition MultiResGrid.h:143
ValueType sampleValue(const Vec3R &xyz, double level) const
Return the value at the specified floating-point coordinate position and level using interpolation of...
TreePtr treePtr(size_t level)
Definition MultiResGrid.h:414
typename TreeType::ConstPtr ConstTreePtr
Definition MultiResGrid.h:71
const TreeType & coarsestConstTree() const
Return a const reference to the tree at the coarsest level.
Definition MultiResGrid.h:155
static Vec3R xyz(const Coord &in_ijk, size_t in_level, size_t out_level)
Definition MultiResGrid.h:501
TreePtr coarsestTreePtr()
Return a shared pointer to the tree at the coarsest level.
Definition MultiResGrid.h:158
TreeType & finestTree()
Return a reference to the tree at the finest level.
Definition MultiResGrid.h:140
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:86
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition LeafManager.h:346
void setValueOn(const Coord &xyz, const ValueType &value)
Definition ValueAccessor.h:569
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition ValueAccessor.h:455
Definition Types.h:28
Type Pow(Type x, int n)
Return xn.
Definition Math.h:561
float Round(float x)
Return x rounded to the nearest integer.
Definition Math.h:819
Type FractionalPart(Type x)
Return the fractional part of x.
Definition Math.h:843
@ NN_FACE_EDGE_VERTEX
Definition Morphology.h:60
void pruneLevelSet(TreeT &tree, bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing nodes whose values are all inactive with inactive ...
Definition Prune.h:390
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:1057
void signedFloodFill(TreeOrLeafManagerT &tree, bool threaded=true, size_t grainSize=1, Index minLevel=0)
Set the values of all inactive voxels and tiles of a narrow-band level set from the signs of the acti...
Definition SignedFloodFill.h:267
@ EXPAND_TILES
Definition Morphology.h:82
@ IGNORE_TILES
Definition Morphology.h:82
ValueAccessorImpl< TreeType, IsSafe, MutexType, openvdb::make_index_sequence< CacheLevels > > ValueAccessor
Default alias for a ValueAccessor. This is simply a helper alias for the generic definition but takes...
Definition ValueAccessor.h:86
std::vector< GridBase::Ptr > GridPtrVec
Definition Grid.h:508
TypedMetadata< float > FloatMetadata
Definition Metadata.h:361
double Real
Definition Types.h:60
GridClass
Definition Types.h:453
@ GRID_LEVEL_SET
Definition Types.h:455
@ GRID_UNKNOWN
Definition Types.h:454
SharedPtr< GridCPtrVec > GridCPtrVecPtr
Definition Grid.h:516
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
SharedPtr< GridPtrVec > GridPtrVecPtr
Definition Grid.h:511
TypedMetadata< std::string > StringMetadata
Definition Metadata.h:364
math::Vec3< Real > Vec3R
Definition Types.h:72
std::shared_ptr< T > SharedPtr
Definition Types.h:114
TypedMetadata< int64_t > Int64Metadata
Definition Metadata.h:363
std::vector< GridBase::ConstPtr > GridCPtrVec
Definition Grid.h:513
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
Definition MultiResGrid.h:683
typename ManagerT::LeafNodeType::ValueOnCIter VoxelIterT
Definition MultiResGrid.h:688
tree::LeafManager< const MaskT > ManagerT
Definition MultiResGrid.h:686
MaskOp(const TreeType &fineTree, TreeType &coarseTree, size_t grainSize=1)
Definition MultiResGrid.h:690
tbb::enumerable_thread_specific< TreeType > PoolType
Definition MultiResGrid.h:685
PoolType * mPool
Definition MultiResGrid.h:721
void operator()(const RangeT &range) const
Definition MultiResGrid.h:710
typename ManagerT::LeafRange RangeT
Definition MultiResGrid.h:687
typename TreeType::template ValueConverter< ValueMask >::Type MaskT
Definition MultiResGrid.h:684
static ValueType run(const Coord &ijk, const ConstAccessor &acc)
Interpolate values from a coarse grid (acc) into the index space (ijk) of a fine grid.
Definition MultiResGrid.h:909
static ValueType run(Coord ijk, const ConstAccessor &acc)
Static method that performs restriction by full weighting.
Definition MultiResGrid.h:876
static bool sample(const TreeT &inTree, const Vec3R &inCoord, typename TreeT::ValueType &result)
Sample inTree at the floating-point index coordinate inCoord and store the result in result.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218
#define OPENVDB_INSTANTIATE_CLASS
Definition version.h.in:158