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