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