51 #ifndef OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 52 #define OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 68 #include <tbb/enumerable_thread_specific.h> 69 #include <tbb/task_scheduler_init.h> 70 #include <tbb/tbb_thread.h> 72 #include <boost/type_traits/is_floating_point.hpp> 73 #include <boost/utility/enable_if.hpp> 85 template<
typename TreeType>
90 typedef boost::shared_ptr<MultiResGrid>
Ptr;
91 typedef boost::shared_ptr<const MultiResGrid>
ConstPtr;
108 MultiResGrid(
size_t levels, ValueType background,
double voxelSize = 1.0);
129 MultiResGrid(
size_t levels, GridPtr grid,
bool useInjection =
false);
149 TreeType& tree(
size_t level);
154 const TreeType& constTree(
size_t level)
const;
159 TreePtr treePtr(
size_t level);
164 ConstTreePtr constTreePtr(
size_t level)
const;
195 GridPtr grid(
size_t level);
200 ConstGridPtr grid(
size_t level)
const;
209 template<Index Order>
210 GridPtr
createGrid(
float level,
size_t grainSize = 1)
const;
238 static Vec3R xyz(
const Coord& in_ijk,
size_t in_level,
size_t out_level);
241 static Vec3R xyz(
const Vec3R& in_xyz,
size_t in_level,
size_t out_level);
242 static Vec3R xyz(
const Vec3R& in_xyz,
double in_level,
double out_level);
250 template<Index Order>
260 ValueType sampleValue(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
const;
261 template<Index Order>
262 ValueType sampleValue(
const Vec3R& in_ijk,
size_t in_level,
size_t out_level)
const;
271 template<Index Order>
272 ValueType sampleValue(
const Coord& ijk,
double level)
const;
281 template<Index Order>
282 ValueType sampleValue(
const Vec3R& xyz,
double level)
const;
292 ValueType prolongateVoxel(
const Coord& coords,
const size_t level)
const;
298 void prolongateActiveVoxels(
size_t destlevel,
size_t grainSize = 1);
306 ValueType restrictVoxel(
Coord ijk,
const size_t level,
bool useInjection =
false)
const;
314 void restrictActiveVoxels(
size_t destlevel,
size_t grainSize = 1);
317 void print(std::ostream& = std::cout,
int verboseLevel = 1)
const;
359 void topDownRestrict(
bool useInjection);
361 inline void initMeta();
374 template<Index Order>
378 template<
typename OpType>
struct CookOp;
381 std::vector<TreePtr> mTrees;
386 template<
typename TreeType>
390 , mTransform(math::Transform::createLinearTransform( voxelSize ))
393 for (
size_t i=0; i<levels; ++i) mTrees[i] =
TreePtr(
new TreeType(background));
396 template<
typename TreeType>
404 mTrees[0].reset(
new TreeType( grid.
tree() ) );
405 mTrees[0]->voxelizeActiveTiles();
406 this->topDownRestrict(useInjection);
409 template<
typename TreeType>
417 mTrees[0] = grid->treePtr();
418 mTrees[0]->voxelizeActiveTiles();
420 this->topDownRestrict(useInjection);
423 template<
typename TreeType>
427 assert( level < mTrees.size() );
428 return *mTrees[level];
431 template<
typename TreeType>
435 assert( level < mTrees.size() );
436 return *mTrees[level];
439 template<
typename TreeType>
443 assert( level < mTrees.size() );
444 return mTrees[level];
447 template<
typename TreeType>
451 assert( level < mTrees.size() );
452 return mTrees[level];
455 template<
typename TreeType>
461 if (level>0) xform->preScale(
Real(1 << level) );
465 std::stringstream ss;
466 ss << this->
getName() <<
"_level_" << level;
471 template<
typename TreeType>
478 template<
typename TreeType>
479 template<Index Order>
483 assert( level >= 0.0f && level <=
float(mTrees.size()-1) );
487 xform->preScale(
math::Pow(2.0f, level) );
491 std::stringstream ss;
492 ss << this->
getName() <<
"_level_" << level;
495 if (
size_t(floorf(level)) == size_t(ceilf(level)) ) {
498 FractionOp<Order> tmp(*
this, grid->
tree(), level, grainSize);
508 template<
typename TreeType>
513 for (
size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
517 template<
typename TreeType>
522 for (
size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
526 template<
typename TreeType>
528 xyz(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
533 template<
typename TreeType>
535 xyz(
const Vec3R& in_xyz,
size_t in_level,
size_t out_level)
537 return in_xyz *
Real(1 << in_level) /
Real(1 << out_level);
540 template<
typename TreeType>
542 xyz(
const Vec3R& in_xyz,
double in_level,
double out_level)
544 return in_xyz *
math::Pow(2.0, in_level - out_level);
548 template<
typename TreeType>
549 template<Index Order>
553 assert( in_level >= 0 && in_level < mTrees.size() );
554 assert( out_level >= 0 && out_level < mTrees.size() );
559 template<
typename TreeType>
560 template<Index Order>
564 assert( in_level >= 0 && in_level < mTrees.size() );
565 assert( out_level >= 0 && out_level < mTrees.size() );
570 template<
typename TreeType>
571 template<Index Order>
575 assert( level >= 0.0 && level <=
double(mTrees.size()-1) );
576 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
577 const ValueType v0 = this->
template sampleValue<Order>( ijk, 0, level0 );
578 if ( level0 == level1 )
return v0;
579 assert( level1 - level0 == 1 );
580 const ValueType v1 = this->
template sampleValue<Order>( ijk, 0, level1 );
585 template<
typename TreeType>
586 template<Index Order>
590 assert( level >= 0.0 && level <=
double(mTrees.size()-1) );
591 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
592 const ValueType v0 = this->
template sampleValue<Order>(
xyz, 0, level0 );
593 if ( level0 == level1 )
return v0;
594 assert( level1 - level0 == 1 );
595 const ValueType v1 = this->
template sampleValue<Order>(
xyz, 0, level1 );
600 template<
typename TreeType>
604 assert( level+1 < mTrees.size() );
609 template<
typename TreeType>
613 assert( destlevel < mTrees.size()-1 );
614 TreeType &fineTree = *mTrees[ destlevel ];
615 const TreeType &coarseTree = *mTrees[ destlevel+1 ];
616 CookOp<ProlongateOp> tmp( coarseTree, fineTree, grainSize );
619 template<
typename TreeType>
623 assert( destlevel > 0 && destlevel < mTrees.size() );
624 const TreeType &fineTree = *mTrees[ destlevel-1 ];
625 if ( useInjection )
return fineTree.getValue(ijk<<1);
630 template<
typename TreeType>
634 assert( destlevel > 0 && destlevel < mTrees.size() );
635 const TreeType &fineTree = *mTrees[ destlevel-1 ];
636 TreeType &coarseTree = *mTrees[ destlevel ];
637 CookOp<RestrictOp> tmp( fineTree, coarseTree, grainSize );
640 template<
typename TreeType>
642 print(std::ostream& os,
int verboseLevel)
const 644 os <<
"MultiResGrid with " << mTrees.size() <<
" levels\n";
645 for (
size_t i=0; i<mTrees.size(); ++i) {
646 os <<
"Level " << i <<
": ";
647 mTrees[i]->print(os, verboseLevel);
651 os <<
"Additional metadata:" << std::endl;
653 os <<
" " << it->first;
655 const std::string value = it->second->str();
656 if (!value.empty()) os <<
": " << value;
662 os <<
"Transform:" << std::endl;
667 template<
typename TreeType>
678 template<
typename TreeType>
683 for (
size_t n=1; n<mTrees.size(); ++n) {
684 const TreeType &fineTree = *mTrees[n-1];
685 mTrees[n] =
TreePtr(
new TreeType( fineTree.background() ) );
686 TreeType &coarseTree = *mTrees[n];
688 for (
ValueOnCIter it = fineTree.cbeginValueOn(); it; ++it) {
689 const Coord ijk = it.getCoord();
690 if ( (ijk[0] & 1) || (ijk[1] & 1) || (ijk[2] & 1) )
continue;
691 coarseTree.setValue( ijk >> 1, *it );
694 MaskOp tmp(fineTree, coarseTree, 128);
704 template<
typename TreeType>
707 typedef typename TreeType::template ValueConverter<ValueMask>::Type
MaskT;
708 typedef tbb::enumerable_thread_specific<TreeType>
PoolType;
711 typedef typename ManagerT::LeafNodeType::ValueOnCIter
VoxelIterT;
713 MaskOp(
const TreeType& fineTree, TreeType& coarseTree,
size_t grainSize = 1)
714 : mPool(new PoolType( coarseTree ) )
716 assert( coarseTree.empty() );
725 ManagerT leafs( mask );
726 tbb::parallel_for(leafs.
leafRange( grainSize ), *
this);
729 typedef typename PoolType::const_iterator IterT;
730 for (IterT it=mPool->begin(); it!=mPool->end(); ++it) coarseTree.topologyUnion( *it );
735 Accessor coarseAcc( mPool->local() );
737 for (VoxelIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
738 Coord ijk = voxelIter.getCoord();
739 if ( (ijk[2] & 1) || (ijk[1] & 1) || (ijk[0] & 1) )
continue;
740 coarseAcc.setValueOn( ijk >> 1 );
747 template<
typename TreeType>
748 template<Index Order>
751 typedef typename TreeType::template ValueConverter<ValueMask>::Type
MaskT;
752 typedef tbb::enumerable_thread_specific<MaskT>
PoolType;
753 typedef typename PoolType::iterator PoolIterT;
756 typedef typename Manager1::LeafRange Range1;
757 typedef typename Manager2::LeafRange Range2;
762 size_t grainSize = 1)
765 , mTree0( &*(parent.mTrees[
size_t(floorf(level))]) )
766 , mTree1( &*(parent.mTrees[
size_t(ceilf(level))]) )
768 assert( midTree.empty() );
769 assert( mTree0 != mTree1 );
772 MaskT examplar(
false );
773 mPool =
new PoolType( examplar );
777 tbb::parallel_for( manager.
leafRange(grainSize), *this );
781 tbb::parallel_for(tbb::blocked_range<PoolIterT>(mPool->begin(),mPool->end(),1), *
this);
784 for (PoolIterT it=mPool->begin(); it!=mPool->end(); ++it) midTree.topologyUnion( *it );
788 Manager2 manager( midTree );
789 tbb::parallel_for(manager.leafRange(grainSize), *
this);
792 void operator()(
const Range1& range)
const 794 typedef typename Manager1::LeafNodeType::ValueOnCIter VoxelIter;
805 for (
typename Range1::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
806 for (VoxelIter voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
807 Coord ijk = voxelIter.getCoord();
811 acc.setValueOn( ijk );
815 void operator()(
const tbb::blocked_range<PoolIterT>& range)
const 817 for (PoolIterT it=range.begin(); it!=range.end(); ++it) {
821 void operator()(
const Range2 &r)
const 823 typedef typename TreeType::LeafNodeType::ValueOnIter VoxelIter;
837 const float scale0 =
math::Pow( 2.0f, b );
838 const float scale1 =
math::Pow( 2.0f,-a );
840 for (
typename Range2::Iterator leafIter = r.begin(); leafIter; ++leafIter) {
841 for (VoxelIter voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
845 voxelIter.setValue(
ValueType(a*v0 + b*v1) );
851 const TreeType *mTree0, *mTree1;
854 template<
typename TreeType>
855 template<
typename OperatorType>
860 CookOp(
const TreeType& srcTree, TreeType& dstTree,
size_t grainSize) : acc( srcTree )
862 ManagerT leafs( dstTree );
863 tbb::parallel_for( leafs.
leafRange( grainSize ), *this );
865 CookOp(
const CookOp &other) : acc( other.acc.tree() ) {}
866 void operator()(
const RangeT& range)
const 869 typedef typename ManagerT::LeafNodeType::ValueOnIter
VoxelIterT;
870 for (LeafIterT leaf = range.
begin(); leaf; ++leaf) {
872 for (VoxelIterT voxel = leaf->beginValueOn(); voxel; ++voxel) {
873 phi[ voxel.pos() ] = OperatorType::run(voxel.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
static const char *const META_GRID_NAME
Definition: Grid.h:281
GridClass
Definition: Types.h:211
Definition: LeafManager.h:132
std::vector< GridBase::Ptr > GridPtrVec
Definition: Grid.h:420
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
std::vector< GridBase::ConstPtr > GridCPtrVec
Definition: Grid.h:425
static GridClass stringToGridClass(const std::string &)
Return the class of volumetric data specified by the given string.
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
Type Pow(Type x, int n)
Return .
Definition: Math.h:527
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:115
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:47
boost::shared_ptr< GridPtrVec > GridPtrVecPtr
Definition: Grid.h:423
TypedMetadata< boost::int64_t > Int64Metadata
Definition: metadata/Metadata.h:380
boost::shared_ptr< Grid > Ptr
Definition: Grid.h:485
Definition: ValueAccessor.h:219
Defined various multi-threaded utility functions for trees.
TreeType & tree()
Return a reference to this grid's tree, which might be shared with other grids.
Definition: Grid.h:761
TypedMetadata< std::string > StringMetadata
Definition: StringMetadata.h:42
double Real
Definition: Types.h:64
virtual void setTree(TreeBase::Ptr)
Associate the given tree with this grid, in place of its existing tree.
Definition: Grid.h:1174
TypedMetadata< float > FloatMetadata
Definition: metadata/Metadata.h:378
static Ptr create()
Return a new grid with background value zero.
Definition: Grid.h:1104
#define OPENVDB_VERSION_NAME
Definition: version.h:43
GridClass getGridClass() const
Return the class of volumetric data (level set, fog volume, etc.) stored in this grid.
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:256
Propagates the sign of distance values from the active voxels in the narrow band to the inactive valu...
Implementation of morphological dilation and erosion.
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:111
Definition: Exceptions.h:39
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:594
const Int32 * data() const
Definition: Coord.h:155
BufferType & buffer(size_t bufferIdx)
Return the nth buffer for the leaf node to which this iterator is pointing, where n = bufferIdx and n...
Definition: LeafManager.h:154
static std::string gridClassToString(GridClass)
Return the metadata string value for the given class of volumetric data.
boost::shared_ptr< GridCPtrVec > GridCPtrVecPtr
Definition: Grid.h:428
Type FractionalPart(Type x)
Return the fractional part of x.
Definition: Math.h:809
Iterator begin() const
Definition: LeafManager.h:188
boost::shared_ptr< const Grid > ConstPtr
Definition: Grid.h:486
static const char *const META_GRID_CLASS
Definition: Grid.h:279
Definition: LeafManager.h:135
Definition: Exceptions.h:88
math::Vec3< Real > Vec3R
Definition: Types.h:76
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
#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...
GridType::Ptr createGrid(const typename GridType::ValueType &background)
Create a new grid of type GridType with a given background value.
Definition: Grid.h:1380
void setTransform(math::Transform::Ptr)
Associate the given transform with this grid, in place of its existing transform. ...
Definition: Grid.h:1039
void setName(const std::string &)
Specify a name for this grid.
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:785
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:381