52 #ifndef OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 53 #define OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 69 #include <tbb/enumerable_thread_specific.h> 70 #include <tbb/task_scheduler_init.h> 71 #include <tbb/tbb_thread.h> 83 template<
typename TreeType>
88 typedef boost::shared_ptr<MultiResGrid>
Ptr;
89 typedef boost::shared_ptr<const MultiResGrid>
ConstPtr;
106 MultiResGrid(
size_t levels, ValueType background,
double voxelSize = 1.0);
126 MultiResGrid(
size_t levels, GridPtr grid,
bool useInjection =
false);
146 TreeType& tree(
size_t level);
151 const TreeType& constTree(
size_t level)
const;
156 TreePtr treePtr(
size_t level);
161 ConstTreePtr constTreePtr(
size_t level)
const;
192 GridPtr grid(
size_t level);
197 ConstGridPtr grid(
size_t level)
const;
206 template<Index Order>
207 GridPtr
createGrid(
float level,
size_t grainSize = 1)
const;
235 static Vec3R xyz(
const Coord& in_ijk,
size_t in_level,
size_t out_level);
238 static Vec3R xyz(
const Vec3R& in_xyz,
size_t in_level,
size_t out_level);
239 static Vec3R xyz(
const Vec3R& in_xyz,
double in_level,
double out_level);
247 template<Index Order>
257 ValueType sampleValue(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
const;
258 template<Index Order>
259 ValueType sampleValue(
const Vec3R& in_ijk,
size_t in_level,
size_t out_level)
const;
268 template<Index Order>
269 ValueType sampleValue(
const Coord& ijk,
double level)
const;
278 template<Index Order>
279 ValueType sampleValue(
const Vec3R& xyz,
double level)
const;
289 ValueType prolongateVoxel(
const Coord& coords,
const size_t level)
const;
295 void prolongateActiveVoxels(
size_t destlevel,
size_t grainSize = 1);
303 ValueType restrictVoxel(
Coord ijk,
const size_t level,
bool useInjection =
false)
const;
311 void restrictActiveVoxels(
size_t destlevel,
size_t grainSize = 1);
314 void print(std::ostream& = std::cout,
int verboseLevel = 1)
const;
356 void topDownRestrict(
bool useInjection);
358 inline void initMeta();
371 template<Index Order>
375 template<
typename OpType>
struct CookOp;
378 std::vector<TreePtr> mTrees;
383 template<
typename TreeType>
387 , mTransform(math::Transform::createLinearTransform( voxelSize ))
390 for (
size_t i=0;
i<levels; ++
i) mTrees[
i] =
TreePtr(
new TreeType(background));
393 template<
typename TreeType>
401 mTrees[0].reset(
new TreeType( grid.
tree() ) );
402 mTrees[0]->voxelizeActiveTiles();
403 this->topDownRestrict(useInjection);
406 template<
typename TreeType>
414 mTrees[0] = grid->treePtr();
415 mTrees[0]->voxelizeActiveTiles();
417 this->topDownRestrict(useInjection);
420 template<
typename TreeType>
424 assert( level < mTrees.size() );
425 return *mTrees[level];
428 template<
typename TreeType>
432 assert( level < mTrees.size() );
433 return *mTrees[level];
436 template<
typename TreeType>
440 assert( level < mTrees.size() );
441 return mTrees[level];
444 template<
typename TreeType>
448 assert( level < mTrees.size() );
449 return mTrees[level];
452 template<
typename TreeType>
458 if (level>0) xform->preScale(
Real(1 << level) );
462 std::stringstream ss;
463 ss << this->
getName() <<
"_level_" << level;
468 template<
typename TreeType>
475 template<
typename TreeType>
476 template<Index Order>
480 assert( level >= 0.0f && level <=
float(mTrees.size()-1) );
484 xform->preScale(
math::Pow(2.0f, level) );
488 std::stringstream ss;
489 ss << this->
getName() <<
"_level_" << level;
492 if (
size_t(floorf(level)) == size_t(ceilf(level)) ) {
495 FractionOp<Order> tmp(*
this, grid->
tree(), level, grainSize);
505 template<
typename TreeType>
510 for (
size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
514 template<
typename TreeType>
519 for (
size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
523 template<
typename TreeType>
525 xyz(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
530 template<
typename TreeType>
532 xyz(
const Vec3R& in_xyz,
size_t in_level,
size_t out_level)
534 return in_xyz *
Real(1 << in_level) /
Real(1 << out_level);
537 template<
typename TreeType>
539 xyz(
const Vec3R& in_xyz,
double in_level,
double out_level)
541 return in_xyz *
math::Pow(2.0, in_level - out_level);
545 template<
typename TreeType>
546 template<Index Order>
550 assert( in_level >= 0 && in_level < mTrees.size() );
551 assert( out_level >= 0 && out_level < mTrees.size() );
556 template<
typename TreeType>
557 template<Index Order>
561 assert( in_level >= 0 && in_level < mTrees.size() );
562 assert( out_level >= 0 && out_level < mTrees.size() );
567 template<
typename TreeType>
568 template<Index Order>
572 assert( level >= 0.0 && level <=
double(mTrees.size()-1) );
573 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
574 const ValueType v0 = this->
template sampleValue<Order>( ijk, 0, level0 );
575 if ( level0 == level1 )
return v0;
576 assert( level1 - level0 == 1 );
577 const ValueType v1 = this->
template sampleValue<Order>( ijk, 0, level1 );
582 template<
typename TreeType>
583 template<Index Order>
587 assert( level >= 0.0 && level <=
double(mTrees.size()-1) );
588 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
589 const ValueType v0 = this->
template sampleValue<Order>(
xyz, 0, level0 );
590 if ( level0 == level1 )
return v0;
591 assert( level1 - level0 == 1 );
592 const ValueType v1 = this->
template sampleValue<Order>(
xyz, 0, level1 );
597 template<
typename TreeType>
601 assert( level+1 < mTrees.size() );
606 template<
typename TreeType>
610 assert( destlevel < mTrees.size()-1 );
611 TreeType &fineTree = *mTrees[ destlevel ];
612 const TreeType &coarseTree = *mTrees[ destlevel+1 ];
613 CookOp<ProlongateOp> tmp( coarseTree, fineTree, grainSize );
616 template<
typename TreeType>
620 assert( destlevel > 0 && destlevel < mTrees.size() );
621 const TreeType &fineTree = *mTrees[ destlevel-1 ];
622 if ( useInjection )
return fineTree.getValue(ijk<<1);
627 template<
typename TreeType>
631 assert( destlevel > 0 && destlevel < mTrees.size() );
632 const TreeType &fineTree = *mTrees[ destlevel-1 ];
633 TreeType &coarseTree = *mTrees[ destlevel ];
634 CookOp<RestrictOp> tmp( fineTree, coarseTree, grainSize );
637 template<
typename TreeType>
639 print(std::ostream& os,
int verboseLevel)
const 641 os <<
"MultiResGrid with " << mTrees.size() <<
" levels\n";
642 for (
size_t i=0;
i<mTrees.size(); ++
i) {
643 os <<
"Level " <<
i <<
": ";
644 mTrees[
i]->print(os, verboseLevel);
648 os <<
"Additional metadata:" << std::endl;
650 os <<
" " << it->first;
652 const std::string value = it->second->str();
653 if (!value.empty()) os <<
": " << value;
659 os <<
"Transform:" << std::endl;
664 template<
typename TreeType>
675 template<
typename TreeType>
680 for (
size_t n=1; n<mTrees.size(); ++n) {
681 const TreeType &fineTree = *mTrees[n-1];
682 mTrees[n] =
TreePtr(
new TreeType( fineTree.background() ) );
683 TreeType &coarseTree = *mTrees[n];
685 for (
ValueOnCIter it = fineTree.cbeginValueOn(); it; ++it) {
686 const Coord ijk = it.getCoord();
687 if ( (ijk[0] & 1) || (ijk[1] & 1) || (ijk[2] & 1) )
continue;
688 coarseTree.setValue( ijk >> 1, *it );
691 MaskOp tmp(fineTree, coarseTree, 128);
701 template<
typename TreeType>
704 typedef typename TreeType::template ValueConverter<ValueMask>::Type
MaskT;
705 typedef tbb::enumerable_thread_specific<TreeType>
PoolType;
708 typedef typename ManagerT::LeafNodeType::ValueOnCIter
VoxelIterT;
710 MaskOp(
const TreeType& fineTree, TreeType& coarseTree,
size_t grainSize = 1)
711 : mPool(new PoolType( coarseTree ) )
713 assert( coarseTree.empty() );
722 ManagerT leafs( mask );
723 tbb::parallel_for(leafs.
leafRange( grainSize ), *
this);
726 typedef typename PoolType::const_iterator IterT;
727 for (IterT it=mPool->begin(); it!=mPool->end(); ++it) coarseTree.topologyUnion( *it );
732 Accessor coarseAcc( mPool->local() );
734 for (VoxelIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
735 Coord ijk = voxelIter.getCoord();
736 if ( (ijk[2] & 1) || (ijk[1] & 1) || (ijk[0] & 1) )
continue;
737 coarseAcc.setValueOn( ijk >> 1 );
744 template<
typename TreeType>
745 template<Index Order>
748 typedef typename TreeType::template ValueConverter<ValueMask>::Type
MaskT;
749 typedef tbb::enumerable_thread_specific<MaskT>
PoolType;
750 typedef typename PoolType::iterator PoolIterT;
753 typedef typename Manager1::LeafRange Range1;
754 typedef typename Manager2::LeafRange Range2;
759 size_t grainSize = 1)
762 , mTree0( &*(parent.mTrees[
size_t(floorf(level))]) )
763 , mTree1( &*(parent.mTrees[
size_t(ceilf(level))]) )
765 assert( midTree.empty() );
766 assert( mTree0 != mTree1 );
769 MaskT examplar(
false );
770 mPool =
new PoolType( examplar );
774 tbb::parallel_for( manager.
leafRange(grainSize), *this );
778 tbb::parallel_for(tbb::blocked_range<PoolIterT>(mPool->begin(),mPool->end(),1), *
this);
781 for (PoolIterT it=mPool->begin(); it!=mPool->end(); ++it) midTree.topologyUnion( *it );
785 Manager2 manager( midTree );
786 tbb::parallel_for(manager.leafRange(grainSize), *
this);
789 void operator()(
const Range1& range)
const 791 typedef typename Manager1::LeafNodeType::ValueOnCIter VoxelIter;
802 for (
typename Range1::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
803 for (VoxelIter voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
804 Coord ijk = voxelIter.getCoord();
808 acc.setValueOn( ijk );
812 void operator()(
const tbb::blocked_range<PoolIterT>& range)
const 814 for (PoolIterT it=range.begin(); it!=range.end(); ++it) {
818 void operator()(
const Range2 &r)
const 820 typedef typename TreeType::LeafNodeType::ValueOnIter VoxelIter;
834 const float scale0 =
math::Pow( 2.0f, b );
835 const float scale1 =
math::Pow( 2.0f,-a );
837 for (
typename Range2::Iterator leafIter = r.begin(); leafIter; ++leafIter) {
838 for (VoxelIter voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
842 voxelIter.setValue(
ValueType(a*v0 + b*v1) );
848 const TreeType *mTree0, *mTree1;
852 template<
typename TreeType>
853 template<
typename OperatorType>
859 CookOp(
const TreeType& srcTree, TreeType& dstTree,
size_t grainSize): acc(srcTree)
861 ManagerT leafs(dstTree);
862 tbb::parallel_for(leafs.
leafRange(grainSize), *
this);
864 CookOp(
const CookOp &other): acc(other.acc.tree()) {}
866 void operator()(
const RangeT& range)
const 868 for (
auto leafIt = range.
begin(); leafIt; ++leafIt) {
869 auto& phi = leafIt.buffer(0);
870 for (
auto voxelIt = leafIt->beginValueOn(); voxelIt; ++voxelIt) {
871 phi.setValue(voxelIt.pos(), OperatorType::run(voxelIt.getCoord(), acc));
880 template<
typename TreeType>
903 for (
int i=-1;
i<=1;
i+=2) {
904 for (
int j=-1; j<=1; j+=2) {
913 template<
typename TreeType>
921 switch ( (ijk[0] & 1) | ((ijk[1] & 1) << 1) | ((ijk[2] & 1) << 2) ) {
951 for (
int i=-1;
i<=1;
i+=2) {
952 for (
int j=-1; j<=1; j+=2) {
964 #endif // OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:115
Type FractionalPart(Type x)
Return the fractional part of x.
Definition: Math.h:793
double Real
Definition: Types.h:63
TreeType & tree()
Return a reference to this grid's tree, which might be shared with other grids.
Definition: Grid.h:797
SharedPtr< GridPtrVec > GridPtrVecPtr
Definition: Grid.h:440
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
GridClass getGridClass() const
Return the class of volumetric data (level set, fog volume, etc.) stored in this grid.
SharedPtr< Grid > Ptr
Definition: Grid.h:502
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
tbb::atomic< Index32 > i
Definition: LeafBuffer.h:71
std::vector< GridBase::Ptr > GridPtrVec
Definition: Grid.h:437
const Int32 * data() const
Definition: Coord.h:163
Type Pow(Type x, int n)
Return .
Definition: Math.h:511
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:643
Defined various multi-threaded utility functions for trees.
Definition: LeafManager.h:127
static const char *const META_GRID_NAME
Definition: Grid.h:293
#define OPENVDB_VERSION_NAME
Definition: version.h:43
void setName(const std::string &)
Specify a name for this grid.
Definition: LeafManager.h:130
Propagates the sign of distance values from the active voxels in the narrow band to the inactive valu...
Implementation of morphological dilation and erosion.
Definition: Exceptions.h:39
SharedPtr< GridCPtrVec > GridCPtrVecPtr
Definition: Grid.h:445
std::vector< GridBase::ConstPtr > GridCPtrVec
Definition: Grid.h:442
static Ptr create()
Return a new grid with background value zero.
Definition: Grid.h:1186
Definition: ValueAccessor.h:219
SharedPtr< const Grid > ConstPtr
Definition: Grid.h:503
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:386
Definition: Exceptions.h:92
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:110
Iterator begin() const
Definition: LeafManager.h:181
static GridClass stringToGridClass(const std::string &)
Return the class of volumetric data specified by the given string.
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:503
GridClass
Definition: Types.h:262
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:48
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:769
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
static const char *const META_GRID_CLASS
Definition: Grid.h:291
TypedMetadata< int64_t > Int64Metadata
Definition: Metadata.h:379
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:256
void setTransform(math::Transform::Ptr)
Associate the given transform with this grid, in place of its existing transform. ...
Definition: Grid.h:1112
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:55
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
TypedMetadata< float > FloatMetadata
Definition: Metadata.h:377
math::Vec3< Real > Vec3R
Definition: Types.h:75
TypedMetadata< std::string > StringMetadata
Definition: Metadata.h:380
GridType::Ptr createGrid(const typename GridType::ValueType &background)
Create a new grid of type GridType with a given background value.
Definition: Grid.h:1581
void setTree(TreeBase::Ptr) override
Associate the given tree with this grid, in place of its existing tree.
Definition: Grid.h:1309