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