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