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