52 #ifndef OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 53 #define OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 55 #include <openvdb/Grid.h> 56 #include <openvdb/math/FiniteDifference.h> 57 #include <openvdb/math/Math.h> 58 #include <openvdb/math/Operators.h> 59 #include <openvdb/math/Stencils.h> 60 #include <openvdb/Metadata.h> 61 #include <openvdb/tree/LeafManager.h> 62 #include <openvdb/tree/NodeManager.h> 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
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
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
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
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