49 #ifndef OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 50 #define OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 66 #include <tbb/enumerable_thread_specific.h> 67 #include <tbb/task_scheduler_init.h> 68 #include <tbb/tbb_thread.h> 80 template<
typename TreeType>
85 typedef boost::shared_ptr<MultiResGrid>
Ptr;
86 typedef boost::shared_ptr<const MultiResGrid>
ConstPtr;
103 MultiResGrid(
size_t levels, ValueType background,
double voxelSize = 1.0);
124 MultiResGrid(
size_t levels, GridPtr grid,
bool useInjection =
false);
144 TreeType& tree(
size_t level);
149 const TreeType& constTree(
size_t level)
const;
154 TreePtr treePtr(
size_t level);
159 ConstTreePtr constTreePtr(
size_t level)
const;
190 GridPtr grid(
size_t level);
195 ConstGridPtr grid(
size_t level)
const;
204 template<Index Order>
205 GridPtr
createGrid(
float level,
size_t grainSize = 1)
const;
233 static Vec3R xyz(
const Coord& in_ijk,
size_t in_level,
size_t out_level);
236 static Vec3R xyz(
const Vec3R& in_xyz,
size_t in_level,
size_t out_level);
237 static Vec3R xyz(
const Vec3R& in_xyz,
double in_level,
double out_level);
245 template<Index Order>
255 ValueType sampleValue(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
const;
256 template<Index Order>
257 ValueType sampleValue(
const Vec3R& in_ijk,
size_t in_level,
size_t out_level)
const;
266 template<Index Order>
267 ValueType sampleValue(
const Coord& ijk,
double level)
const;
276 template<Index Order>
277 ValueType sampleValue(
const Vec3R& xyz,
double level)
const;
287 ValueType prolongateVoxel(
const Coord& coords,
const size_t level)
const;
293 void prolongateActiveVoxels(
size_t destlevel,
size_t grainSize = 1);
301 ValueType restrictVoxel(Coord ijk,
const size_t level,
bool useInjection =
false)
const;
309 void restrictActiveVoxels(
size_t destlevel,
size_t grainSize = 1);
312 void print(std::ostream& = std::cout,
int verboseLevel = 1)
const;
354 void topDownRestrict(
bool useInjection);
356 inline void initMeta();
369 template<Index Order>
373 template<
typename OpType>
struct CookOp;
376 std::vector<TreePtr> mTrees;
381 template<
typename TreeType>
385 , mTransform(math::Transform::createLinearTransform( voxelSize ))
388 for (
size_t i=0; i<levels; ++i) mTrees[i] =
TreePtr(
new TreeType(background));
391 template<
typename TreeType>
399 mTrees[0].reset(
new TreeType( grid.
tree() ) );
400 mTrees[0]->voxelizeActiveTiles();
401 this->topDownRestrict(useInjection);
404 template<
typename TreeType>
412 mTrees[0] = grid->treePtr();
413 mTrees[0]->voxelizeActiveTiles();
415 this->topDownRestrict(useInjection);
418 template<
typename TreeType>
422 assert( level < mTrees.size() );
423 return *mTrees[level];
426 template<
typename TreeType>
430 assert( level < mTrees.size() );
431 return *mTrees[level];
434 template<
typename TreeType>
438 assert( level < mTrees.size() );
439 return mTrees[level];
442 template<
typename TreeType>
446 assert( level < mTrees.size() );
447 return mTrees[level];
450 template<
typename TreeType>
456 if (level>0) xform->preScale(
Real(1 << level) );
460 std::stringstream ss;
461 ss << this->
getName() <<
"_level_" << level;
466 template<
typename TreeType>
473 template<
typename TreeType>
474 template<Index Order>
478 assert( level >= 0.0f && level <=
float(mTrees.size()-1) );
482 xform->preScale(
math::Pow(2.0f, level) );
486 std::stringstream ss;
487 ss << this->
getName() <<
"_level_" << level;
490 if (
size_t(floorf(level)) == size_t(ceilf(level)) ) {
493 FractionOp<Order> tmp(*
this, grid->
tree(), level, grainSize);
503 template<
typename TreeType>
508 for (
size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
512 template<
typename TreeType>
517 for (
size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
521 template<
typename TreeType>
523 xyz(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
525 return Vec3R( in_ijk.data() ) *
Real(1 << in_level) /
Real(1 << out_level);
528 template<
typename TreeType>
530 xyz(
const Vec3R& in_xyz,
size_t in_level,
size_t out_level)
532 return in_xyz *
Real(1 << in_level) /
Real(1 << out_level);
535 template<
typename TreeType>
537 xyz(
const Vec3R& in_xyz,
double in_level,
double out_level)
539 return in_xyz *
math::Pow(2.0, in_level - out_level);
543 template<
typename TreeType>
544 template<Index Order>
546 sampleValue(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
const 548 assert( in_level >= 0 && in_level < mTrees.size() );
549 assert( out_level >= 0 && out_level < mTrees.size() );
554 template<
typename TreeType>
555 template<Index Order>
559 assert( in_level >= 0 && in_level < mTrees.size() );
560 assert( out_level >= 0 && out_level < mTrees.size() );
565 template<
typename TreeType>
566 template<Index Order>
570 assert( level >= 0.0 && level <=
double(mTrees.size()-1) );
571 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
572 const ValueType v0 = this->
template sampleValue<Order>( ijk, 0, level0 );
573 if ( level0 == level1 )
return v0;
574 assert( level1 - level0 == 1 );
575 const ValueType v1 = this->
template sampleValue<Order>( ijk, 0, level1 );
580 template<
typename TreeType>
581 template<Index Order>
585 assert( level >= 0.0 && level <=
double(mTrees.size()-1) );
586 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
587 const ValueType v0 = this->
template sampleValue<Order>(
xyz, 0, level0 );
588 if ( level0 == level1 )
return v0;
589 assert( level1 - level0 == 1 );
590 const ValueType v1 = this->
template sampleValue<Order>(
xyz, 0, level1 );
595 template<
typename TreeType>
599 assert( level+1 < mTrees.size() );
604 template<
typename TreeType>
608 assert( destlevel < mTrees.size()-1 );
609 TreeType &fineTree = *mTrees[ destlevel ];
610 const TreeType &coarseTree = *mTrees[ destlevel+1 ];
611 CookOp<ProlongateOp> tmp( coarseTree, fineTree, grainSize );
614 template<
typename TreeType>
618 assert( destlevel > 0 && destlevel < mTrees.size() );
619 const TreeType &fineTree = *mTrees[ destlevel-1 ];
620 if ( useInjection )
return fineTree.getValue(ijk<<1);
625 template<
typename TreeType>
629 assert( destlevel > 0 && destlevel < mTrees.size() );
630 const TreeType &fineTree = *mTrees[ destlevel-1 ];
631 TreeType &coarseTree = *mTrees[ destlevel ];
632 CookOp<RestrictOp> tmp( fineTree, coarseTree, grainSize );
635 template<
typename TreeType>
637 print(std::ostream& os,
int verboseLevel)
const 639 os <<
"MultiResGrid with " << mTrees.size() <<
" levels\n";
640 for (
size_t i=0; i<mTrees.size(); ++i) {
641 os <<
"Level " << i <<
": ";
642 mTrees[i]->print(os, verboseLevel);
646 os <<
"Additional metadata:" << std::endl;
648 os <<
" " << it->first;
650 const std::string value = it->second->str();
651 if (!value.empty()) os <<
": " << value;
657 os <<
"Transform:" << std::endl;
662 template<
typename TreeType>
673 template<
typename TreeType>
678 for (
size_t n=1; n<mTrees.size(); ++n) {
679 const TreeType &fineTree = *mTrees[n-1];
680 mTrees[n] =
TreePtr(
new TreeType( fineTree.background() ) );
681 TreeType &coarseTree = *mTrees[n];
683 for (
ValueOnCIter it = fineTree.cbeginValueOn(); it; ++it) {
684 const Coord ijk = it.getCoord();
685 if ( (ijk[0] & 1) || (ijk[1] & 1) || (ijk[2] & 1) )
continue;
686 coarseTree.setValue( ijk >> 1, *it );
689 MaskOp tmp(fineTree, coarseTree, 128);
699 template<
typename TreeType>
702 typedef typename TreeType::template ValueConverter<ValueMask>::Type
MaskT;
703 typedef tbb::enumerable_thread_specific<TreeType>
PoolType;
706 typedef typename ManagerT::LeafNodeType::ValueOnCIter
VoxelIterT;
708 MaskOp(
const TreeType& fineTree, TreeType& coarseTree,
size_t grainSize = 1)
709 : mPool(new PoolType( coarseTree ) )
711 assert( coarseTree.empty() );
720 ManagerT leafs( mask );
721 tbb::parallel_for(leafs.
leafRange( grainSize ), *
this);
724 typedef typename PoolType::const_iterator IterT;
725 for (IterT it=mPool->begin(); it!=mPool->end(); ++it) coarseTree.topologyUnion( *it );
730 Accessor coarseAcc( mPool->local() );
732 for (VoxelIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
733 Coord ijk = voxelIter.getCoord();
734 if ( (ijk[2] & 1) || (ijk[1] & 1) || (ijk[0] & 1) )
continue;
742 template<
typename TreeType>
743 template<Index Order>
746 typedef typename TreeType::template ValueConverter<ValueMask>::Type
MaskT;
747 typedef tbb::enumerable_thread_specific<MaskT>
PoolType;
748 typedef typename PoolType::iterator PoolIterT;
751 typedef typename Manager1::LeafRange Range1;
752 typedef typename Manager2::LeafRange Range2;
757 size_t grainSize = 1)
760 , mTree0( &*(parent.mTrees[
size_t(floorf(level))]) )
761 , mTree1( &*(parent.mTrees[
size_t(ceilf(level))]) )
763 assert( midTree.empty() );
764 assert( mTree0 != mTree1 );
767 MaskT examplar(
false );
768 mPool =
new PoolType( examplar );
772 tbb::parallel_for( manager.
leafRange(grainSize), *this );
776 tbb::parallel_for(tbb::blocked_range<PoolIterT>(mPool->begin(),mPool->end(),1), *
this);
779 for (PoolIterT it=mPool->begin(); it!=mPool->end(); ++it) midTree.topologyUnion( *it );
783 Manager2 manager( midTree );
784 tbb::parallel_for(manager.leafRange(grainSize), *
this);
787 void operator()(
const Range1& range)
const 789 typedef typename Manager1::LeafNodeType::ValueOnCIter VoxelIter;
800 for (
typename Range1::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
801 for (VoxelIter voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
802 Coord ijk = voxelIter.getCoord();
806 acc.setValueOn( ijk );
810 void operator()(
const tbb::blocked_range<PoolIterT>& range)
const 812 for (PoolIterT it=range.begin(); it!=range.end(); ++it) {
816 void operator()(
const Range2 &r)
const 818 typedef typename TreeType::LeafNodeType::ValueOnIter VoxelIter;
832 const float scale0 =
math::Pow( 2.0f, b );
833 const float scale1 =
math::Pow( 2.0f,-a );
835 for (
typename Range2::Iterator leafIter = r.begin(); leafIter; ++leafIter) {
836 for (VoxelIter voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
840 voxelIter.setValue(
ValueType(a*v0 + b*v1) );
846 const TreeType *mTree0, *mTree1;
850 template<
typename TreeType>
851 template<
typename OperatorType>
857 CookOp(
const TreeType& srcTree, TreeType& dstTree,
size_t grainSize): acc(srcTree)
859 ManagerT leafs(dstTree);
860 tbb::parallel_for(leafs.
leafRange(grainSize), *
this);
862 CookOp(
const CookOp &other): acc(other.acc.tree()) {}
864 void operator()(
const RangeT& range)
const 866 for (
auto leafIt = range.
begin(); leafIt; ++leafIt) {
867 auto& phi = leafIt.buffer(0);
868 for (
auto voxelIt = leafIt->beginValueOn(); voxelIt; ++voxelIt) {
869 phi.setValue(voxelIt.pos(), OperatorType::run(voxelIt.getCoord(), acc));
878 template<
typename TreeType>
890 v += 4*(acc.
getValue(ijk.offsetBy(-1, 0, 0)) + acc.
getValue(ijk.offsetBy( 1, 0, 0)) +
891 acc.
getValue(ijk.offsetBy( 0,-1, 0)) + acc.
getValue(ijk.offsetBy( 0, 1, 0)) +
892 acc.
getValue(ijk.offsetBy( 0, 0,-1)) + acc.
getValue(ijk.offsetBy( 0, 0, 1)));
894 v += 2*(acc.
getValue(ijk.offsetBy(-1,-1, 0)) + acc.
getValue(ijk.offsetBy(-1, 1, 0)) +
895 acc.
getValue(ijk.offsetBy( 1,-1, 0)) + acc.
getValue(ijk.offsetBy( 1, 1, 0)) +
896 acc.
getValue(ijk.offsetBy(-1, 0,-1)) + acc.
getValue(ijk.offsetBy(-1, 0, 1)) +
897 acc.
getValue(ijk.offsetBy( 1, 0,-1)) + acc.
getValue(ijk.offsetBy( 1, 0, 1)) +
898 acc.
getValue(ijk.offsetBy( 0,-1,-1)) + acc.
getValue(ijk.offsetBy( 0,-1, 1)) +
899 acc.
getValue(ijk.offsetBy( 0, 1,-1)) + acc.
getValue(ijk.offsetBy( 0, 1, 1)));
901 for (
int i=-1; i<=1; i+=2) {
902 for (
int j=-1; j<=1; j+=2) {
903 for (
int k=-1; k<=1; k+=2) v += acc.
getValue(ijk.offsetBy(i,j,k));
911 template<
typename TreeType>
919 switch ( (ijk[0] & 1) | ((ijk[1] & 1) << 1) | ((ijk[2] & 1) << 2) ) {
924 acc.
getValue(ijk.offsetBy( 1,0,0)>>1));
927 acc.
getValue(ijk.offsetBy(0, 1,0)>>1));
930 acc.
getValue(ijk.offsetBy(-1, 1,0)>>1) +
931 acc.
getValue(ijk.offsetBy( 1,-1,0)>>1) +
932 acc.
getValue(ijk.offsetBy( 1, 1,0)>>1));
935 acc.
getValue(ijk.offsetBy(0,0, 1)>>1));
938 acc.
getValue(ijk.offsetBy(-1,0, 1)>>1) +
939 acc.
getValue(ijk.offsetBy( 1,0,-1)>>1) +
940 acc.
getValue(ijk.offsetBy( 1,0, 1)>>1));
943 acc.
getValue(ijk.offsetBy(0,-1, 1)>>1) +
944 acc.
getValue(ijk.offsetBy(0, 1,-1)>>1) +
945 acc.
getValue(ijk.offsetBy(0, 1, 1)>>1));
949 for (
int i=-1; i<=1; i+=2) {
950 for (
int j=-1; j<=1; j+=2) {
951 for (
int k=-1; k<=1; k+=2) v += acc.
getValue(ijk.offsetBy(i,j,k)>>1);
962 #endif // OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED Definition: LeafManager.h:132
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:503
GridClass getGridClass() const
Return the class of volumetric data (level set, fog volume, etc.) stored in this grid.
static GridClass stringToGridClass(const std::string &)
Return the class of volumetric data specified by the given string.
SharedPtr< GridCPtrVec > GridCPtrVecPtr
Definition: Grid.h:444
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
double Real
Definition: Types.h:63
Definition: ValueAccessor.h:219
#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...
void setTree(TreeBase::Ptr) override
Associate the given tree with this grid, in place of its existing tree.
Definition: Grid.h:1301
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:115
TypedMetadata< int64_t > Int64Metadata
Definition: Metadata.h:379
GridType::Ptr createGrid(const typename GridType::ValueType &background)
Create a new grid of type GridType with a given background value.
Definition: Grid.h:1573
std::vector< GridBase::ConstPtr > GridCPtrVec
Definition: Grid.h:441
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:610
TreeType & tree()
Return a reference to this grid's tree, which might be shared with other grids.
Definition: Grid.h:796
TypedMetadata< float > FloatMetadata
Definition: Metadata.h:377
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: ValueAccessor.h:292
Defined various multi-threaded utility functions for trees.
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:256
GridClass
Definition: Types.h:262
static Ptr create()
Return a new grid with background value zero.
Definition: Grid.h:1178
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Type Pow(Type x, int n)
Return .
Definition: Math.h:527
Propagates the sign of distance values from the active voxels in the narrow band to the inactive valu...
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:391
Implementation of morphological dilation and erosion.
Definition: Exceptions.h:39
Definition: Exceptions.h:92
math::Vec3< Real > Vec3R
Definition: Types.h:75
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:785
void setTransform(math::Transform::Ptr)
Associate the given transform with this grid, in place of its existing transform. ...
Definition: Grid.h:1104
void setName(const std::string &)
Specify a name for this grid.
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
std::vector< GridBase::Ptr > GridPtrVec
Definition: Grid.h:436
SharedPtr< const Grid > ConstPtr
Definition: Grid.h:502
Definition: LeafManager.h:135
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
static const char *const META_GRID_CLASS
Definition: Grid.h:290
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
TypedMetadata< std::string > StringMetadata
Definition: Metadata.h:380
static std::string gridClassToString(GridClass)
Return the metadata string value for the given class of volumetric data.
Iterator begin() const
Definition: LeafManager.h:186
static const char *const META_GRID_NAME
Definition: Grid.h:292
SharedPtr< Grid > Ptr
Definition: Grid.h:501
SharedPtr< GridPtrVec > GridPtrVecPtr
Definition: Grid.h:439
Type FractionalPart(Type x)
Return the fractional part of x.
Definition: Math.h:809