OpenVDB 13.1.0
Loading...
Searching...
No Matches
MultiResGrid.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/// @file MultiResGrid.h
5///
6/// @author Ken Museth
7///
8/// @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...
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
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
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:291
#define OPENVDB_INSTANTIATE_CLASS
Definition version.h.in:231