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> 49 template<
typename Gr
idT>
50 typename GridT::template ValueConverter<float>::Type::Ptr
55 int smoothingSteps = 0);
71 template<
typename Gr
idT,
typename InterrupterT>
72 typename GridT::template ValueConverter<float>::Type::Ptr
77 int smoothingSteps = 0,
78 InterrupterT* interrupt =
nullptr);
85 namespace ttls_internal {
88 template<
typename TreeType>
89 struct 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;
129 template<
typename Gr
idType,
typename InterrupterType>
131 normalizeLevelSet(
GridType& grid,
const int halfWidthInVoxels, InterrupterType* interrupt =
nullptr)
133 LevelSetFilter<GridType, GridType, InterrupterType> filter(grid, interrupt);
135 filter.setNormCount(halfWidthInVoxels);
141 template<
typename Gr
idType,
typename InterrupterType>
143 smoothLevelSet(
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);
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);
176 template<
typename Gr
idT,
typename InterrupterT>
177 typename 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;
188 closingSteps =
std::max(closingSteps, 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);
243 template<
typename Gr
idT>
244 typename GridT::template ValueConverter<float>::Type::Ptr
245 topologyToLevelSet(
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*) 269 #endif // OPENVDB_USE_EXPLICIT_INSTANTIATION 276 #endif // OPENVDB_TOOLS_TOPOLOGY_TO_LEVELSET_HAS_BEEN_INCLUDED
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Base class for interrupters.
Definition: NullInterrupter.h:25
Definition: Exceptions.h:65
Performs various types of level set deformations with interface tracking. These unrestricted deformat...
#define OPENVDB_ALL_TREE_INSTANTIATE(Function)
Definition: version.h.in:166
Implementation of morphological dilation and erosion.
Definition: Exceptions.h:13
GridType
List of types that are currently supported by NanoVDB.
Definition: NanoVDB.h:219
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Definition: FiniteDifference.h:166
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:683
#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
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218