12#ifndef OPENVDB_TOOLS_TOPOLOGY_TO_LEVELSET_HAS_BEEN_INCLUDED 
   13#define OPENVDB_TOOLS_TOPOLOGY_TO_LEVELSET_HAS_BEEN_INCLUDED 
   25#include <tbb/task_group.h> 
   49template<
typename Gr
idT>
 
   50typename GridT::template ValueConverter<float>::Type::Ptr
 
   55    int smoothingSteps = 0);
 
   71template<
typename Gr
idT, 
typename InterrupterT>
 
   72typename GridT::template ValueConverter<float>::Type::Ptr
 
   77    int smoothingSteps = 0,
 
   78    InterrupterT* interrupt = 
nullptr);
 
   85namespace ttls_internal {
 
   88template<
typename TreeType>
 
   89struct OffsetAndMinComp
 
   91    using LeafNodeType = 
typename TreeType::LeafNodeType;
 
   92    using ValueType = 
typename TreeType::ValueType;
 
   94    OffsetAndMinComp(std::vector<LeafNodeType*>& lhsNodes,
 
   95        const TreeType& rhsTree,
 
  101    void operator()(
const tbb::blocked_range<size_t>& range)
 const 
  103        using Iterator = 
typename LeafNodeType::ValueOnIter;
 
  105        tree::ValueAccessor<const TreeType> rhsAcc(mRhsTree);
 
  106        const ValueType offset = mOffset;
 
  108        for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
 
  110            LeafNodeType& lhsNode = *mLhsNodes[n];
 
  111            const LeafNodeType* rhsNodePt = rhsAcc.probeConstLeaf(lhsNode.origin());
 
  112            if (!rhsNodePt) 
continue;
 
  114            auto* 
const data = lhsNode.buffer().data();
 
  115            for (Iterator it = lhsNode.beginValueOn(); it; ++it) {
 
  116                ValueType& val = data[it.pos()];
 
  117                val = std::min(val, offset + rhsNodePt->getValue(it.pos()));
 
  123    std::vector<LeafNodeType*>&  mLhsNodes;
 
  124    const TreeType&  mRhsTree;
 
  125    const ValueType  mOffset;
 
  129template<
typename Gr
idType, 
typename InterrupterType>
 
  131normalizeLevelSet(GridType& grid, 
const int halfWidthInVoxels, InterrupterType* interrupt = 
nullptr)
 
  133    LevelSetFilter<GridType, GridType, InterrupterType> filter(grid, interrupt);
 
  134    filter.setSpatialScheme(math::FIRST_BIAS);
 
  135    filter.setNormCount(halfWidthInVoxels);
 
  141template<
typename Gr
idType, 
typename InterrupterType>
 
  143smoothLevelSet(GridType& grid, 
int iterations, 
int halfBandWidthInVoxels,
 
  144    InterrupterType* interrupt = 
nullptr)
 
  146    using ValueType = 
typename GridType::ValueType;
 
  147    using TreeType = 
typename GridType::TreeType;
 
  148    using LeafNodeType = 
typename TreeType::LeafNodeType;
 
  152    LevelSetFilter<GridType, GridType, InterrupterType> filter(filterGrid, interrupt);
 
  153    filter.setSpatialScheme(math::FIRST_BIAS);
 
  155    for (
int n = 0; n < iterations; ++n) {
 
  156        if (interrupt && interrupt->wasInterrupted()) 
break;
 
  160    std::vector<LeafNodeType*> nodes;
 
  161    grid.tree().getNodes(nodes);
 
  163    const ValueType offset = ValueType(
double(0.5) * grid.transform().voxelSize()[0]);
 
  165    tbb::parallel_for(tbb::blocked_range<size_t>(0, nodes.size()),
 
  166        OffsetAndMinComp<TreeType>(nodes, filterGrid.tree(), -offset));
 
  169    normalizeLevelSet(grid, halfBandWidthInVoxels, interrupt);
 
  176template<
typename Gr
idT, 
typename InterrupterT>
 
  177typename GridT::template ValueConverter<float>::Type::Ptr
 
  179    int smoothingSteps, InterrupterT* interrupt)
 
  181    using MaskTreeT = 
typename GridT::TreeType::template ValueConverter<ValueMask>::Type;
 
  182    using FloatTreeT = 
typename GridT::TreeType::template ValueConverter<float>::Type;
 
  187    halfWidth = std::max(halfWidth, 1);
 
  188    closingSteps = std::max(closingSteps, 0);
 
  189    dilation = std::max(dilation, 0);
 
  191    if (!grid.hasUniformVoxels()) {
 
  205    const float background = float(grid.voxelSize()[0]) * float(halfWidth);
 
  206    typename FloatTreeT::Ptr lsTree(
 
  209    tbb::task_group pool;
 
  219    lsTree->topologyDifference(maskTree);
 
  222    lsTree->voxelizeActiveTiles(); 
 
  226    typename FloatGridT::Ptr lsGrid = FloatGridT::create(lsTree);
 
  227    lsGrid->setTransform(grid.transform().copy());
 
  232    ttls_internal::normalizeLevelSet(*lsGrid, 3*halfWidth, interrupt);
 
  235    if (smoothingSteps > 0) {
 
  236        ttls_internal::smoothLevelSet(*lsGrid, smoothingSteps, halfWidth, interrupt);
 
 
  243template<
typename Gr
idT>
 
  244typename GridT::template ValueConverter<float>::Type::Ptr
 
  245topologyToLevelSet(
const GridT& grid, 
int halfWidth, 
int closingSteps, 
int dilation, 
int smoothingSteps)
 
  248    return topologyToLevelSet(grid, halfWidth, closingSteps, dilation, smoothingSteps, &interrupt);
 
 
  257#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION 
  259#ifdef OPENVDB_INSTANTIATE_TOPOLOGYTOLEVELSET 
  263#define _FUNCTION(TreeT) \ 
  264    Grid<TreeT>::ValueConverter<float>::Type::Ptr topologyToLevelSet(const Grid<TreeT>&, int, int, int, int, \ 
  265        util::NullInterrupter*) 
Performs various types of level set deformations with interface tracking. These unrestricted deformat...
Implementation of morphological dilation and erosion.
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Container class that associates a tree with a transform and metadata.
Definition Grid.h:571
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition Types.h:683
Definition Exceptions.h:65
GridType
List of types that are currently supported by NanoVDB.
Definition NanoVDB.h:219
@ GRID_LEVEL_SET
Definition Types.h:455
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Base class for interrupters.
Definition NullInterrupter.h:26
#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_ALL_TREE_INSTANTIATE(Function)
Definition version.h.in:166