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> 
   60template<
typename TreeType>
 
  182    template<Index Order>
 
  232    template<Index Order>
 
  234    template<Index Order>
 
  244    template<Index Order>
 
  254    template<Index Order>
 
  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;
 
  359template<
typename TreeType>
 
  363    , mTransform(
math::Transform::createLinearTransform( voxelSize ))
 
  366    for (
size_t i=0; i<levels; ++i) mTrees[i] = 
TreePtr(
new TreeType(background));
 
 
  369template<
typename TreeType>
 
  377    mTrees[0].reset( 
new TreeType( 
grid.tree() ) );
 
  378    mTrees[0]->voxelizeActiveTiles();
 
  379    this->topDownRestrict(useInjection);
 
 
  382template<
typename TreeType>
 
  390    mTrees[0] = 
grid->treePtr();
 
  391    mTrees[0]->voxelizeActiveTiles();
 
  393    this->topDownRestrict(useInjection);
 
 
  396template<
typename TreeType>
 
  401    return *mTrees[level];
 
 
  404template<
typename TreeType>
 
  409    return *mTrees[level];
 
 
  412template<
typename TreeType>
 
  417    return mTrees[level];
 
 
  420template<
typename TreeType>
 
  425    return mTrees[level];
 
 
  428template<
typename TreeType>
 
  434    if (level>0) xform->preScale( 
Real(1 << level) );
 
  435    grid->setTransform( xform );
 
  438    std::stringstream ss;
 
  439    ss << this->
getName() << 
"_level_" << level;
 
  440    grid->setName( ss.str() );
 
 
  444template<
typename TreeType>
 
  446grid(
size_t level)
 const 
 
  451template<
typename TreeType>
 
  454createGrid(
float level, 
size_t grainSize)
 const 
  456    OPENVDB_ASSERT( level >= 0.0f && level <= 
float(mTrees.size()-1) );
 
  460    xform->preScale( 
math::Pow(2.0f, level) );
 
  461    grid->setTransform( xform );
 
  464    std::stringstream ss;
 
  465    ss << this->
getName() << 
"_level_" << level;
 
  466    grid->setName( ss.str() );
 
  468    if ( 
size_t(floorf(level)) == 
size_t(ceilf(level)) ) {
 
  469        grid->setTree( this->
constTree( 
size_t(floorf(level))).copy() );
 
  471        FractionOp<Order> tmp(*
this, 
grid->tree(), level, grainSize);
 
 
  481template<
typename TreeType>
 
  486    for (
size_t level=0; level<mTrees.size(); ++level) 
grids->push_back(this->grid(level));
 
 
  490template<
typename TreeType>
 
  495    for (
size_t level=0; level<mTrees.size(); ++level) 
grids->push_back(this->grid(level));
 
 
  499template<
typename TreeType>
 
  501xyz(
const Coord& in_ijk, 
size_t in_level, 
size_t out_level)
 
 
  506template<
typename TreeType>
 
  508xyz(
const Vec3R& in_xyz, 
size_t in_level, 
size_t out_level)
 
  510    return in_xyz * 
Real(1 << in_level) / 
Real(1 << out_level);
 
 
  513template<
typename TreeType>
 
  515xyz(
const Vec3R& in_xyz, 
double in_level, 
double out_level)
 
  517    return in_xyz * 
math::Pow(2.0, in_level - out_level);
 
 
  521template<
typename TreeType>
 
  528    const ConstAccessor acc(*mTrees[out_level]);
 
 
  532template<
typename TreeType>
 
  539    const ConstAccessor acc(*mTrees[out_level]);
 
 
  543template<
typename TreeType>
 
  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));
 
  551    if ( level0 == level1 ) 
return v0;
 
 
  560template<
typename TreeType>
 
  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));
 
  568    if ( level0 == level1 ) 
return v0;
 
 
  577template<
typename TreeType>
 
  582    const ConstAccessor acc(*mTrees[level + 1]);
 
 
  586template<
typename TreeType>
 
  591    TreeType &fineTree = *mTrees[ destlevel ];
 
  592    const TreeType &coarseTree = *mTrees[ destlevel+1 ];
 
  593    CookOp<ProlongateOp> tmp( coarseTree, fineTree, grainSize );
 
 
  596template<
typename TreeType>
 
  601    const TreeType &fineTree = *mTrees[ destlevel-1 ];
 
  602    if ( useInjection ) 
return fineTree.getValue(ijk<<1);
 
  603    const ConstAccessor acc( fineTree );
 
 
  607template<
typename TreeType>
 
  612    const TreeType &fineTree = *mTrees[ destlevel-1 ];
 
  613    TreeType &coarseTree = *mTrees[ destlevel ];
 
  614    CookOp<RestrictOp> tmp( fineTree, coarseTree, grainSize );
 
 
  617template<
typename TreeType>
 
  619print(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;
 
 
 
  644template<
typename TreeType>
 
  648    const size_t levels = this->numLevels();
 
  652    this->insertMeta(
"MultiResGrid_Levels", 
Int64Metadata( levels ) );
 
  655template<
typename TreeType>
 
  656void MultiResGrid<TreeType>::
 
  657topDownRestrict(
bool useInjection)
 
  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);
 
  672            this->restrictActiveVoxels(n, 64);
 
  681template<
typename TreeType>
 
  684    using MaskT = 
typename TreeType::template ValueConverter<ValueMask>::Type;
 
  685    using PoolType = tbb::enumerable_thread_specific<TreeType>;
 
  687    using RangeT = 
typename ManagerT::LeafRange;
 
  688    using VoxelIterT = 
typename ManagerT::LeafNodeType::ValueOnCIter;
 
  690    MaskOp(
const TreeType& fineTree, TreeType& coarseTree, 
size_t grainSize = 1)
 
  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;
 
 
 
  724template<
typename TreeType>
 
  726struct MultiResGrid<TreeType>::FractionOp
 
  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 );
 
  750        mPool = 
new PoolType( examplar );
 
  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 );
 
  822        ConstAccessor acc0( *mTree0 ), acc1( *mTree1 );
 
  823        for (
typename Range2::Iterator leafIter = r.begin(); leafIter; ++leafIter) {
 
  824            for (VoxelIter voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
 
  825                const Vec3R xyz =  
Vec3R( voxelIter.getCoord().data() );
 
  829                const auto value0 = a*v0;
 
  830                const auto value1 = b*v1;
 
  832                voxelIter.setValue( ValueType(value0 + value1) );
 
  838    const TreeType *mTree0, *mTree1;
 
  842template<
typename TreeType>
 
  843template<
typename OperatorType>
 
  844struct MultiResGrid<TreeType>::CookOp
 
  846    using ManagerT = tree::LeafManager<TreeType>;
 
  847    using RangeT = 
typename ManagerT::LeafRange;
 
  849    CookOp(
const TreeType& srcTree, TreeType& dstTree, 
size_t grainSize): acc(srcTree)
 
  851        ManagerT leafs(dstTree);
 
  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) {
 
  861                phi.setValue(voxelIt.pos(), OperatorType::run(voxelIt.getCoord(), acc));
 
  866    const ConstAccessor acc;
 
  870template<
typename TreeType>
 
  893        for (
int i=-1; i<=1; i+=2) {
 
  894            for (
int j=-1; j<=1; j+=2) {
 
 
 
  903template<
typename TreeType>
 
  911        switch ( (ijk[0] & 1) | ((ijk[1] & 1) << 1) | ((ijk[2] & 1) << 2) ) {
 
  941        for (
int i=-1; i<=1; i+=2) {
 
  942            for (
int j=-1; j<=1; j+=2) {
 
 
 
  956#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION 
  958#ifdef OPENVDB_INSTANTIATE_MULTIRESGRID 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Implementation of morphological dilation and erosion.
Defined various multi-threaded utility functions for trees.
Propagate the signs of distance values from the active voxels in the narrow band to the inactive valu...
static const char *const META_GRID_NAME
Definition Grid.h:353
static const char *const META_GRID_CLASS
Definition Grid.h:351
static GridClass stringToGridClass(const std::string &)
Return the class of volumetric data specified by the given string.
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:571
SharedPtr< const Grid > ConstPtr
Definition Grid.h:574
SharedPtr< Grid > Ptr
Definition Grid.h:573
static Ptr create()
Return a new grid with background value zero.
Definition Grid.h:1343
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition Types.h:683
Definition Exceptions.h:65
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition Coord.h:92
const Int32 * data() const
Definition Coord.h:140
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:86
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition LeafManager.h:346
void setValueOn(const Coord &xyz, const ValueType &value)
Definition ValueAccessor.h:569
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition ValueAccessor.h:455
Type Pow(Type x, int n)
Return xn.
Definition Math.h:561
float Round(float x)
Return x rounded to the nearest integer.
Definition Math.h:819
Type FractionalPart(Type x)
Return the fractional part of x.
Definition Math.h:843
ValueAccessorImpl< TreeType, IsSafe, MutexType, openvdb::make_index_sequence< CacheLevels > > ValueAccessor
Default alias for a ValueAccessor. This is simply a helper alias for the generic definition but takes...
Definition ValueAccessor.h:86
std::vector< GridBase::Ptr > GridPtrVec
Definition Grid.h:508
TypedMetadata< float > FloatMetadata
Definition Metadata.h:361
double Real
Definition Types.h:60
GridClass
Definition Types.h:453
@ GRID_LEVEL_SET
Definition Types.h:455
@ GRID_UNKNOWN
Definition Types.h:454
SharedPtr< GridCPtrVec > GridCPtrVecPtr
Definition Grid.h:516
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
SharedPtr< GridPtrVec > GridPtrVecPtr
Definition Grid.h:511
TypedMetadata< std::string > StringMetadata
Definition Metadata.h:364
math::Vec3< Real > Vec3R
Definition Types.h:72
std::shared_ptr< T > SharedPtr
Definition Types.h:114
TypedMetadata< int64_t > Int64Metadata
Definition Metadata.h:363
std::vector< GridBase::ConstPtr > GridCPtrVec
Definition Grid.h:513
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
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
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218
#define OPENVDB_INSTANTIATE_CLASS
Definition version.h.in:158