25 #ifndef OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 26 #define OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED 45 #include <tbb/blocked_range.h> 46 #include <tbb/enumerable_thread_specific.h> 47 #include <tbb/parallel_for.h> 60 template<
typename TreeType>
122 TreeType& tree(
size_t level);
127 const TreeType& constTree(
size_t level)
const;
182 template<Index Order>
213 static Vec3R xyz(
const Coord& in_ijk,
size_t in_level,
size_t out_level);
214 static Vec3R xyz(
const Vec3R& in_xyz,
size_t in_level,
size_t out_level);
215 static Vec3R xyz(
const Vec3R& in_xyz,
double in_level,
double out_level);
232 template<Index Order>
233 ValueType sampleValue(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
const;
234 template<Index Order>
235 ValueType sampleValue(
const Vec3R& in_ijk,
size_t in_level,
size_t out_level)
const;
244 template<Index Order>
245 ValueType sampleValue(
const Coord& ijk,
double level)
const;
254 template<Index Order>
265 ValueType prolongateVoxel(
const Coord& coords,
const size_t level)
const;
271 void prolongateActiveVoxels(
size_t destlevel,
size_t grainSize = 1);
279 ValueType restrictVoxel(Coord ijk,
const size_t level,
bool useInjection =
false)
const;
287 void restrictActiveVoxels(
size_t destlevel,
size_t grainSize = 1);
290 void print(std::ostream& = std::cout,
int verboseLevel = 1)
const;
332 void topDownRestrict(
bool useInjection);
334 inline void initMeta();
347 template<Index Order>
351 template<
typename OpType>
struct CookOp;
354 std::vector<TreePtr> mTrees;
359 template<
typename TreeType>
363 , mTransform(math::Transform::createLinearTransform( voxelSize ))
366 for (
size_t i=0; i<levels; ++i) mTrees[i] =
TreePtr(
new TreeType(background));
369 template<
typename TreeType>
377 mTrees[0].reset(
new TreeType( grid.
tree() ) );
378 mTrees[0]->voxelizeActiveTiles();
379 this->topDownRestrict(useInjection);
382 template<
typename TreeType>
390 mTrees[0] = grid->treePtr();
391 mTrees[0]->voxelizeActiveTiles();
393 this->topDownRestrict(useInjection);
396 template<
typename TreeType>
401 return *mTrees[level];
404 template<
typename TreeType>
409 return *mTrees[level];
412 template<
typename TreeType>
417 return mTrees[level];
420 template<
typename TreeType>
425 return mTrees[level];
428 template<
typename TreeType>
434 if (level>0) xform->preScale(
Real(1 << level) );
438 std::stringstream ss;
439 ss << this->
getName() <<
"_level_" << level;
444 template<
typename TreeType>
451 template<
typename TreeType>
452 template<Index Order>
456 OPENVDB_ASSERT( level >= 0.0f && level <=
float(mTrees.size()-1) );
460 xform->preScale(
math::Pow(2.0f, level) );
464 std::stringstream ss;
465 ss << this->
getName() <<
"_level_" << level;
468 if (
size_t(floorf(level)) == size_t(ceilf(level)) ) {
471 FractionOp<Order> tmp(*
this, grid->
tree(), level, grainSize);
481 template<
typename TreeType>
486 for (
size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
490 template<
typename TreeType>
495 for (
size_t level=0; level<mTrees.size(); ++level) grids->push_back(this->grid(level));
499 template<
typename TreeType>
501 xyz(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
503 return Vec3R( in_ijk.data() ) *
Real(1 << in_level) /
Real(1 << out_level);
506 template<
typename TreeType>
508 xyz(
const Vec3R& in_xyz,
size_t in_level,
size_t out_level)
510 return in_xyz *
Real(1 << in_level) /
Real(1 << out_level);
513 template<
typename TreeType>
515 xyz(
const Vec3R& in_xyz,
double in_level,
double out_level)
517 return in_xyz *
math::Pow(2.0, in_level - out_level);
521 template<
typename TreeType>
522 template<Index Order>
524 sampleValue(
const Coord& in_ijk,
size_t in_level,
size_t out_level)
const 532 template<
typename TreeType>
533 template<Index Order>
543 template<
typename TreeType>
544 template<Index Order>
548 OPENVDB_ASSERT( level >= 0.0 && level <=
double(mTrees.size()-1) );
549 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
550 const ValueType v0 = this->
template sampleValue<Order>( ijk, 0, level0 );
551 if ( level0 == level1 )
return v0;
553 const ValueType v1 = this->
template sampleValue<Order>( ijk, 0, level1 );
560 template<
typename TreeType>
561 template<Index Order>
565 OPENVDB_ASSERT( level >= 0.0 && level <=
double(mTrees.size()-1) );
566 const size_t level0 = size_t(floor(level)), level1 = size_t(ceil(level));
567 const ValueType v0 = this->
template sampleValue<Order>(
xyz, 0, level0 );
568 if ( level0 == level1 )
return v0;
570 const ValueType v1 = this->
template sampleValue<Order>(
xyz, 0, level1 );
577 template<
typename TreeType>
586 template<
typename TreeType>
591 TreeType &fineTree = *mTrees[ destlevel ];
592 const TreeType &coarseTree = *mTrees[ destlevel+1 ];
593 CookOp<ProlongateOp> tmp( coarseTree, fineTree, grainSize );
596 template<
typename TreeType>
601 const TreeType &fineTree = *mTrees[ destlevel-1 ];
602 if ( useInjection )
return fineTree.getValue(ijk<<1);
607 template<
typename TreeType>
612 const TreeType &fineTree = *mTrees[ destlevel-1 ];
613 TreeType &coarseTree = *mTrees[ destlevel ];
614 CookOp<RestrictOp> tmp( fineTree, coarseTree, grainSize );
617 template<
typename TreeType>
619 print(std::ostream& os,
int verboseLevel)
const 621 os <<
"MultiResGrid with " << mTrees.size() <<
" levels\n";
622 for (
size_t i=0; i<mTrees.size(); ++i) {
623 os <<
"Level " << i <<
": ";
624 mTrees[i]->print(os, verboseLevel);
628 os <<
"Additional metadata:" << std::endl;
630 os <<
" " << it->first;
632 const std::string value = it->second->str();
633 if (!value.empty()) os <<
": " << value;
639 os <<
"Transform:" << std::endl;
644 template<
typename TreeType>
655 template<
typename TreeType>
660 for (
size_t n=1; n<mTrees.size(); ++n) {
661 const TreeType &fineTree = *mTrees[n-1];
662 mTrees[n] =
TreePtr(
new TreeType( fineTree.background() ) );
663 TreeType &coarseTree = *mTrees[n];
665 for (
ValueOnCIter it = fineTree.cbeginValueOn(); it; ++it) {
666 const Coord ijk = it.getCoord();
667 if ( (ijk[0] & 1) || (ijk[1] & 1) || (ijk[2] & 1) )
continue;
668 coarseTree.setValue( ijk >> 1, *it );
671 MaskOp tmp(fineTree, coarseTree, 128);
681 template<
typename TreeType>
684 using MaskT =
typename TreeType::template ValueConverter<ValueMask>::Type;
685 using PoolType = tbb::enumerable_thread_specific<TreeType>;
688 using VoxelIterT =
typename ManagerT::LeafNodeType::ValueOnCIter;
690 MaskOp(
const TreeType& fineTree, TreeType& coarseTree,
size_t grainSize = 1)
691 : mPool(new
PoolType( coarseTree ) )
703 tbb::parallel_for(leafs.
leafRange( grainSize ), *
this);
706 using IterT =
typename PoolType::const_iterator;
707 for (IterT it=mPool->begin(); it!=mPool->end(); ++it) coarseTree.topologyUnion( *it );
712 Accessor coarseAcc( mPool->local() );
713 for (
typename RangeT::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
714 for (
VoxelIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
715 Coord ijk = voxelIter.getCoord();
716 if ( (ijk[2] & 1) || (ijk[1] & 1) || (ijk[0] & 1) )
continue;
724 template<
typename TreeType>
725 template<Index Order>
728 using MaskT =
typename TreeType::template ValueConverter<ValueMask>::Type;
729 using PoolType = tbb::enumerable_thread_specific<MaskT>;
730 using PoolIterT =
typename PoolType::iterator;
733 using Range1 =
typename Manager1::LeafRange;
734 using Range2 =
typename Manager2::LeafRange;
739 size_t grainSize = 1)
742 , mTree0( &*(parent.mTrees[
size_t(floorf(level))]) )
743 , mTree1( &*(parent.mTrees[
size_t(ceilf(level))]) )
749 MaskT examplar(
false );
754 tbb::parallel_for( manager.
leafRange(grainSize), *this );
758 tbb::parallel_for(tbb::blocked_range<PoolIterT>(mPool->begin(),mPool->end(),1), *
this);
761 for (PoolIterT it=mPool->begin(); it!=mPool->end(); ++it) midTree.topologyUnion( *it );
765 Manager2 manager( midTree );
766 tbb::parallel_for(manager.leafRange(grainSize), *
this);
769 void operator()(
const Range1& range)
const 771 using VoxelIter =
typename Manager1::LeafNodeType::ValueOnCIter;
782 for (
typename Range1::Iterator leafIter = range.begin(); leafIter; ++leafIter) {
783 for (VoxelIter voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
784 Coord ijk = voxelIter.getCoord();
786 const auto value0 = ijk[0] *
scale;
787 const auto value1 = ijk[1] *
scale;
788 const auto value2 = ijk[2] *
scale;
794 acc.setValueOn( ijk );
798 void operator()(
const tbb::blocked_range<PoolIterT>& range)
const 800 for (PoolIterT it=range.begin(); it!=range.end(); ++it) {
804 void operator()(
const Range2 &r)
const 806 using VoxelIter =
typename TreeType::LeafNodeType::ValueOnIter;
820 const float scale0 =
math::Pow( 2.0f, b );
821 const float scale1 =
math::Pow( 2.0f,-a );
823 for (
typename Range2::Iterator leafIter = r.begin(); leafIter; ++leafIter) {
824 for (VoxelIter voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
829 const auto value0 = a*v0;
830 const auto value1 = b*v1;
832 voxelIter.setValue(
ValueType(value0 + value1) );
838 const TreeType *mTree0, *mTree1;
842 template<
typename TreeType>
843 template<
typename OperatorType>
849 CookOp(
const TreeType& srcTree, TreeType& dstTree,
size_t grainSize): acc(srcTree)
852 tbb::parallel_for(leafs.
leafRange(grainSize), *
this);
854 CookOp(
const CookOp &other): acc(other.acc.tree()) {}
856 void operator()(
const RangeT& range)
const 858 for (
auto leafIt = range.begin(); leafIt; ++leafIt) {
859 auto& phi = leafIt.buffer(0);
860 for (
auto voxelIt = leafIt->beginValueOn(); voxelIt; ++voxelIt) {
870 template<
typename TreeType>
882 v += 4*(acc.
getValue(ijk.offsetBy(-1, 0, 0)) + acc.
getValue(ijk.offsetBy( 1, 0, 0)) +
883 acc.
getValue(ijk.offsetBy( 0,-1, 0)) + acc.
getValue(ijk.offsetBy( 0, 1, 0)) +
884 acc.
getValue(ijk.offsetBy( 0, 0,-1)) + acc.
getValue(ijk.offsetBy( 0, 0, 1)));
886 v += 2*(acc.
getValue(ijk.offsetBy(-1,-1, 0)) + acc.
getValue(ijk.offsetBy(-1, 1, 0)) +
887 acc.
getValue(ijk.offsetBy( 1,-1, 0)) + acc.
getValue(ijk.offsetBy( 1, 1, 0)) +
888 acc.
getValue(ijk.offsetBy(-1, 0,-1)) + acc.
getValue(ijk.offsetBy(-1, 0, 1)) +
889 acc.
getValue(ijk.offsetBy( 1, 0,-1)) + acc.
getValue(ijk.offsetBy( 1, 0, 1)) +
890 acc.
getValue(ijk.offsetBy( 0,-1,-1)) + acc.
getValue(ijk.offsetBy( 0,-1, 1)) +
891 acc.
getValue(ijk.offsetBy( 0, 1,-1)) + acc.
getValue(ijk.offsetBy( 0, 1, 1)));
893 for (
int i=-1; i<=1; i+=2) {
894 for (
int j=-1; j<=1; j+=2) {
895 for (
int k=-1; k<=1; k+=2) v += acc.
getValue(ijk.offsetBy(i,j,k));
903 template<
typename TreeType>
911 switch ( (ijk[0] & 1) | ((ijk[1] & 1) << 1) | ((ijk[2] & 1) << 2) ) {
916 acc.
getValue(ijk.offsetBy( 1,0,0)>>1));
919 acc.
getValue(ijk.offsetBy(0, 1,0)>>1));
922 acc.
getValue(ijk.offsetBy(-1, 1,0)>>1) +
923 acc.
getValue(ijk.offsetBy( 1,-1,0)>>1) +
924 acc.
getValue(ijk.offsetBy( 1, 1,0)>>1));
927 acc.
getValue(ijk.offsetBy(0,0, 1)>>1));
930 acc.
getValue(ijk.offsetBy(-1,0, 1)>>1) +
931 acc.
getValue(ijk.offsetBy( 1,0,-1)>>1) +
932 acc.
getValue(ijk.offsetBy( 1,0, 1)>>1));
935 acc.
getValue(ijk.offsetBy(0,-1, 1)>>1) +
936 acc.
getValue(ijk.offsetBy(0, 1,-1)>>1) +
937 acc.
getValue(ijk.offsetBy(0, 1, 1)>>1));
941 for (
int i=-1; i<=1; i+=2) {
942 for (
int j=-1; j<=1; j+=2) {
943 for (
int k=-1; k<=1; k+=2) v += acc.
getValue(ijk.offsetBy(i,j,k)>>1);
956 #ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION 958 #ifdef OPENVDB_INSTANTIATE_MULTIRESGRID 965 #endif // OPENVDB_USE_EXPLICIT_INSTANTIATION 972 #endif // OPENVDB_TOOLS_MULTIRESGRID_HAS_BEEN_INCLUDED
void setValueOn(const Coord &xyz, const ValueType &value)
Set a particular value at the given coordinate and mark the coordinate as active. ...
Definition: ValueAccessor.h:569
TypedMetadata< std::string > StringMetadata
Definition: Metadata.h:364
SharedPtr< const Grid > ConstPtr
Definition: Grid.h:574
std::vector< GridBase::ConstPtr > GridCPtrVec
Definition: Grid.h:513
The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compa...
Definition: ValueAccessor.h:68
SharedPtr< GridCPtrVec > GridCPtrVecPtr
Definition: Grid.h:516
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
void setTree(TreeBase::Ptr) override
Associate the given tree with this grid, in place of its existing tree.
Definition: Grid.h:1489
static Ptr create()
Return a new grid with background value zero.
Definition: Grid.h:1343
TypedMetadata< float > FloatMetadata
Definition: Metadata.h:361
TypedMetadata< int64_t > Int64Metadata
Definition: Metadata.h:363
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.
Type Pow(Type x, int n)
Return xn.
Definition: Math.h:561
SharedPtr< GridPtrVec > GridPtrVecPtr
Definition: Grid.h:511
static std::string gridClassToString(GridClass)
Return the metadata string value for the given class of volumetric data.
static const char *const META_GRID_NAME
Definition: Grid.h:353
std::vector< GridBase::Ptr > GridPtrVec
Definition: Grid.h:508
Defined various multi-threaded utility functions for trees.
Definition: Exceptions.h:65
TreeType & tree()
Return a reference to this grid's tree, which might be shared with other grids.
Definition: Grid.h:908
Type FractionalPart(Type x)
Return the fractional part of x.
Definition: Math.h:843
std::shared_ptr< T > SharedPtr
Definition: Types.h:114
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:615
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:346
Propagate the signs of distance values from the active voxels in the narrow band to the inactive valu...
Implementation of morphological dilation and erosion.
SharedPtr< Grid > Ptr
Definition: Grid.h:573
Definition: Exceptions.h:13
void setName(const std::string &)
Specify a name for this grid.
double Real
Definition: Types.h:60
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.
void setTransform(math::Transform::Ptr)
Associate the given transform with this grid, in place of its existing transform. ...
Definition: Grid.h:1269
#define OPENVDB_INSTANTIATE_CLASS
Definition: version.h.in:158
GridClass getGridClass() const
Return the class of volumetric data (level set, fog volume, etc.) that is stored in this grid...
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:455
Definition: LeafManager.h:102
static const char *const META_GRID_CLASS
Definition: Grid.h:351
GridType::Ptr createGrid(const typename GridType::ValueType &background)
Create a new grid of type GridType with a given background value.
Definition: Grid.h:1757
GridClass
Definition: Types.h:453
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:683
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:819
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:28
math::Vec3< Real > Vec3R
Definition: Types.h:72
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218
static GridClass stringToGridClass(const std::string &)
Return the class of volumetric data specified by the given string.