39 #ifndef OPENVDB_TOOLS_LEVEL_SET_TRACKER_HAS_BEEN_INCLUDED 40 #define OPENVDB_TOOLS_LEVEL_SET_TRACKER_HAS_BEEN_INCLUDED 42 #include <tbb/parallel_for.h> 43 #include <boost/bind.hpp> 44 #include <boost/function.hpp> 45 #include <type_traits> 66 template<
typename Gr
idT,
typename InterruptT = util::NullInterrupter>
72 typedef typename TreeType::LeafNodeType
LeafType;
77 typedef typename TreeType::template ValueConverter<ValueMask>::Type
MaskTreeType;
78 static_assert(std::is_floating_point<ValueType>::value,
79 "LevelSetTracker requires a level set grid with floating-point values");
86 : spatialScheme(s), temporalScheme(t), normCount(n), grainSize(g) {}
101 template <
typename MaskType>
105 void normalize() { this->normalize<MaskTreeType>(
nullptr); }
129 void dilate(
int iterations = 1);
133 void erode(
int iterations = 1);
177 void startInterrupter(
const char* msg);
179 void endInterrupter();
182 bool checkInterrupter();
184 const GridType&
grid()
const {
return *mGrid; }
186 LeafManagerType&
leafs() {
return *mLeafs; }
188 const LeafManagerType&
leafs()
const {
return *mLeafs; }
202 void operator()(
const LeafRange& r)
const;
213 typedef typename SchemeT::template ISStencil<GridType>::StencilType StencilT;
214 typedef typename MaskT::LeafNodeType MaskLeafT;
215 typedef typename MaskLeafT::ValueOnCIter MaskIterT;
216 typedef typename LeafType::ValueOnCIter VoxelIterT;
219 void operator()(
const LeafRange& r)
const {mTask(const_cast<Normalizer*>(
this), r);}
220 void cook(
const char* msg,
int swapBuffer=0);
221 template <
int Nominator,
int Denominator>
222 void euler(
const LeafRange& range,
Index phiBuffer,
Index resultBuffer);
223 inline void euler01(
const LeafRange& r) {this->euler<0,1>(r, 0, 1);}
224 inline void euler12(
const LeafRange& r) {this->euler<1,2>(r, 1, 1);}
225 inline void euler34(
const LeafRange& r) {this->euler<3,4>(r, 1, 2);}
226 inline void euler13(
const LeafRange& r) {this->euler<1,3>(r, 1, 2);}
227 template <
int Nominator,
int Denominator>
228 void eval(StencilT& stencil,
const ValueType* phi, ValueType* result,
Index n)
const;
231 const ValueType mDt, mInvDx;
232 typename boost::function<void (Normalizer*, const LeafRange&)> mTask;
235 template<math::BiasedGradientScheme SpatialScheme,
typename MaskT>
236 void normalize1(
const MaskT* mask);
240 void normalize2(
const MaskT* mask);
247 LeafManagerType* mLeafs;
248 InterruptT* mInterrupter;
253 template<
typename Gr
idT,
typename InterruptT>
257 mLeafs(new LeafManagerType(grid.tree())),
258 mInterrupter(interrupt),
259 mDx(static_cast<ValueType>(grid.voxelSize()[0])),
262 if ( !grid.hasUniformVoxels() ) {
264 "The transform must have uniform scale for the LevelSetTracker to function");
268 "LevelSetTracker expected a level set, got a grid of class \"" 269 + grid.gridClassToString(grid.getGridClass())
270 +
"\" [hint: Grid::setGridClass(openvdb::GRID_LEVEL_SET)]");
274 template<
typename Gr
idT,
typename InterruptT>
293 template<
typename Gr
idT,
typename InterruptT>
308 template<
typename Gr
idT,
typename InterruptT>
314 for (
int i=0; i < iterations; ++i) {
319 for (
int i=0; i < iterations; ++i) {
320 MaskTreeType mask0(mGrid->tree(),
false,
TopologyCopy());
323 MaskTreeType mask(mGrid->tree(),
false,
TopologyCopy());
324 mask.topologyDifference(mask0);
330 template<
typename Gr
idT,
typename InterruptT>
337 const ValueType background = mGrid->background() - iterations*mDx;
341 template<
typename Gr
idT,
typename InterruptT>
347 const int wNew =
static_cast<int>(halfWidth);
349 this->
dilate(wNew - wOld);
350 }
else if (wOld > wNew) {
351 this->
erode(wOld - wNew);
356 template<
typename Gr
idT,
typename InterruptT>
361 if (mInterrupter) mInterrupter->start(msg);
364 template<
typename Gr
idT,
typename InterruptT>
369 if (mInterrupter) mInterrupter->end();
372 template<
typename Gr
idT,
typename InterruptT>
378 tbb::task::self().cancel_group_execution();
384 template<
typename Gr
idT,
typename InterruptT>
385 template<
typename MaskT>
392 this->normalize1<math::FIRST_BIAS , MaskT>(mask);
break;
394 this->normalize1<math::SECOND_BIAS, MaskT>(mask);
break;
396 this->normalize1<math::THIRD_BIAS, MaskT>(mask);
break;
398 this->normalize1<math::WENO5_BIAS, MaskT>(mask);
break;
400 this->normalize1<math::HJWENO5_BIAS, MaskT>(mask);
break;
407 template<
typename Gr
idT,
typename InterruptT>
408 template<math::BiasedGradientScheme SpatialScheme,
typename MaskT>
415 this->normalize2<SpatialScheme, math::TVD_RK1, MaskT>(mask);
break;
417 this->normalize2<SpatialScheme, math::TVD_RK2, MaskT>(mask);
break;
419 this->normalize2<SpatialScheme, math::TVD_RK3, MaskT>(mask);
break;
426 template<
typename Gr
idT,
typename InterruptT>
434 Normalizer<SpatialScheme, TemporalScheme, MaskT> tmp(*
this, mask);
440 template<
typename Gr
idT,
typename InterruptT>
446 const LeafRange range = mTracker.leafs().leafRange(grainSize);
449 tbb::parallel_for(range, *
this);
456 template<
typename Gr
idT,
typename InterruptT>
461 typedef typename LeafType::ValueOnIter VoxelIterT;
463 const ValueType gamma = mTracker.mGrid->background();
466 LeafType &leaf = *leafIter;
467 for (VoxelIterT iter = leaf.beginValueOn(); iter; ++iter) {
468 const ValueType val = *iter;
470 leaf.setValueOff(iter.pos(), -gamma);
471 else if (val >= gamma)
472 leaf.setValueOff(iter.pos(), gamma);
479 template<
typename Gr
idT,
typename InterruptT>
496 template<
typename Gr
idT,
typename InterruptT>
506 mTracker.mLeafs->rebuildAuxBuffers(TemporalScheme ==
math::TVD_RK3 ? 2 : 1);
508 for (
int n=0, e=mTracker.getNormCount(); n < e; ++n) {
511 switch(TemporalScheme) {
515 mTask = boost::bind(&Normalizer::euler01, _1, _2);
518 this->cook(
"Normalizing level set using TVD_RK1", 1);
523 mTask = boost::bind(&Normalizer::euler01, _1, _2);
526 this->cook(
"Normalizing level set using TVD_RK1 (step 1 of 2)", 1);
530 mTask = boost::bind(&Normalizer::euler12, _1, _2);
533 this->cook(
"Normalizing level set using TVD_RK1 (step 2 of 2)", 1);
538 mTask = boost::bind(&Normalizer::euler01, _1, _2);
541 this->cook(
"Normalizing level set using TVD_RK3 (step 1 of 3)", 1);
545 mTask = boost::bind(&Normalizer::euler34, _1, _2);
548 this->cook(
"Normalizing level set using TVD_RK3 (step 2 of 3)", 2);
552 mTask = boost::bind(&Normalizer::euler13, _1, _2);
555 this->cook(
"Normalizing level set using TVD_RK3 (step 3 of 3)", 2);
563 mTracker.mLeafs->removeAuxBuffers();
568 template<
typename Gr
idT,
typename InterruptT>
575 cook(
const char* msg,
int swapBuffer)
579 const int grainSize = mTracker.getGrainSize();
580 const LeafRange range = mTracker.leafs().leafRange(grainSize);
582 grainSize>0 ? tbb::parallel_for(range, *
this) : (*this)(range);
584 mTracker.leafs().swapLeafBuffer(swapBuffer, grainSize==0);
586 mTracker.endInterrupter();
589 template<
typename Gr
idT,
typename InterruptT>
593 template <
int Nominator,
int Denominator>
597 eval(StencilT& stencil,
const ValueType* phi, ValueType* result,
Index n)
const 601 static const ValueType beta =
ValueType(1) - alpha;
603 const ValueType normSqGradPhi = GradientT::result(stencil);
604 const ValueType phi0 = stencil.getValue();
607 v = phi0 - mDt * v * (
math::Sqrt(normSqGradPhi) * mInvDx - 1.0f);
608 result[n] = Nominator ? alpha * phi[n] + beta * v : v;
611 template<
typename Gr
idT,
typename InterruptT>
615 template <
int Nominator,
int Denominator>
621 typedef typename LeafType::ValueOnCIter VoxelIterT;
625 StencilT stencil(mTracker.grid());
628 const ValueType* phi = leafIter.buffer(phiBuffer).data();
629 ValueType* result = leafIter.buffer(resultBuffer).data();
630 if (mMask ==
nullptr) {
631 for (VoxelIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
632 stencil.moveTo(iter);
633 this->eval<Nominator, Denominator>(stencil, phi, result, iter.pos());
635 }
else if (
const MaskLeafT* mask = mMask->probeLeaf(leafIter->origin())) {
636 const ValueType* phi0 = leafIter->buffer().data();
637 for (MaskIterT iter = mask->cbeginValueOn(); iter; ++iter) {
638 const Index i = iter.pos();
639 stencil.moveTo(iter.getCoord(), phi0[i]);
640 this->eval<Nominator, Denominator>(stencil, phi, result, i);
650 #endif // OPENVDB_TOOLS_LEVEL_SET_TRACKER_HAS_BEEN_INCLUDED Definition: LeafManager.h:132
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:503
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Definition: FiniteDifference.h:262
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
Efficient multi-threaded replacement of the background values in tree.
Definition: Operators.h:152
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:115
static T value()
Definition: Math.h:125
Definition: FiniteDifference.h:195
BiasedGradientScheme
Biased Gradients are limited to non-centered differences.
Definition: FiniteDifference.h:192
Defined various multi-threaded utility functions for trees.
static const Real LEVEL_SET_HALF_WIDTH
Definition: Types.h:270
Definition: Exceptions.h:90
float Sqrt(float x)
Return the square root of a floating-point value.
Definition: Math.h:727
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Implementation of morphological dilation and erosion.
Definition: FiniteDifference.h:264
Definition: Exceptions.h:39
TemporalIntegrationScheme
Temporal integration schemes.
Definition: FiniteDifference.h:261
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76
Definition: FiniteDifference.h:194
Definition: FiniteDifference.h:263
Definition: FiniteDifference.h:196
Definition: Exceptions.h:92
Definition: FiniteDifference.h:265
void rebuildLeafArray()
Remove the auxiliary buffers and rebuild the leaf array.
Definition: LeafManager.h:321
Definition: FiniteDifference.h:198
Iterator begin() const
Definition: LeafManager.h:186
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
Definition: FiniteDifference.h:193
Definition: LeafManager.h:135
#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...
Index32 Index
Definition: Types.h:57
float RoundDown(float x)
Return x rounded down to the nearest integer.
Definition: Math.h:769
Definition: FiniteDifference.h:197
Definition: Operators.h:253
CopyConstness< TreeType, NonConstBufferType >::Type BufferType
Definition: LeafManager.h:126
Type Pow2(Type x)
Return .
Definition: Math.h:514