42 #ifndef OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED 43 #define OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED 49 #include <type_traits> 63 template<
typename GridT,
64 typename MaskT =
typename GridT::template ValueConverter<float>::Type,
65 typename InterruptT = util::NullInterrupter>
75 static_assert(std::is_floating_point<AlphaType>::value,
76 "LevelSetFilter requires a mask grid with floating-point values");
122 Filter f(
this, mask); f.meanCurvature();
129 Filter f(
this, mask); f.laplacian();
140 Filter f(
this, mask); f.gaussian(width);
148 Filter f(
this, mask); f.offset(offset);
159 Filter f(
this, mask); f.median(width);
169 Filter f(
this, mask); f.mean(width);
180 using LeafT =
typename TreeType::LeafNodeType;
181 using VoxelIterT =
typename LeafT::ValueOnIter;
182 using VoxelCIterT =
typename LeafT::ValueOnCIter;
185 using LeafIterT =
typename LeafRange::Iterator;
189 Filter(
const Filter&) =
default;
193 void median(
int width);
194 void mean(
int width);
195 void gaussian(
int width);
199 void operator()(
const LeafRange& r)
const 201 if (mTask) mTask(const_cast<Filter*>(
this), r);
206 const int n = mParent->getGrainSize();
208 tbb::parallel_for(mParent->leafs().leafRange(n), *
this);
210 (*this)(mParent->leafs().leafRange());
212 if (swap) mParent->leafs().swapLeafBuffer(1, n==0);
215 template <
size_t Axis>
218 acc(grid.tree()), width(w), frac(1/
ValueType(2*w+1)) {}
223 for (i -= width; i <= j; ++i) sum += acc.getValue(xyz);
226 typename GridT::ConstAccessor
acc;
231 template<
typename AvgT>
232 void boxImpl(
const LeafRange& r,
Int32 w);
234 void boxXImpl(
const LeafRange& r,
Int32 w) { this->boxImpl<Avg<0> >(r,w); }
235 void boxZImpl(
const LeafRange& r,
Int32 w) { this->boxImpl<Avg<1> >(r,w); }
236 void boxYImpl(
const LeafRange& r,
Int32 w) { this->boxImpl<Avg<2> >(r,w); }
238 void medianImpl(
const LeafRange&,
int);
239 void meanCurvatureImpl(
const LeafRange&);
240 void laplacianImpl(
const LeafRange&);
241 void offsetImpl(
const LeafRange&,
ValueType);
245 typename std::function<void (Filter*, const LeafRange&)> mTask;
256 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
262 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
264 mTask = std::bind(&Filter::medianImpl,
265 std::placeholders::_1, std::placeholders::_2,
std::max(1, width));
270 mParent->endInterrupter();
273 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
281 mParent->endInterrupter();
284 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
290 for (
int n=0; n<4; ++n) this->box(width);
292 mParent->endInterrupter();
295 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
299 mParent->
leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
303 mTask = std::bind(&Filter::boxXImpl, std::placeholders::_1, std::placeholders::_2, width);
306 mTask = std::bind(&Filter::boxYImpl, std::placeholders::_1, std::placeholders::_2, width);
309 mTask = std::bind(&Filter::boxZImpl, std::placeholders::_1, std::placeholders::_2, width);
315 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
319 mParent->startInterrupter(
"Mean-curvature flow of level set");
321 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
323 mTask = std::bind(&Filter::meanCurvatureImpl, std::placeholders::_1, std::placeholders::_2);
328 mParent->endInterrupter();
331 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
335 mParent->startInterrupter(
"Laplacian flow of level set");
337 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
339 mTask = std::bind(&Filter::laplacianImpl, std::placeholders::_1, std::placeholders::_2);
344 mParent->endInterrupter();
347 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
353 mParent->leafs().removeAuxBuffers();
357 while (offset-dist >
ValueType(0.001)*CFL && mParent->checkInterrupter()) {
361 mTask = std::bind(&Filter::offsetImpl,
362 std::placeholders::_1, std::placeholders::_2, copysign(delta, value));
368 mParent->endInterrupter();
375 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
385 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
386 mParent->maxMask(), mParent->isMaskInverted());
387 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
388 ValueType* buffer = leafIter.buffer(1).data();
389 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
390 if (alpha(iter.getCoord(), a, b)) {
391 stencil.moveTo(iter);
392 const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.meanCurvatureNormGrad();
393 buffer[iter.pos()] = b * phi0 + a * phi1;
398 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
399 ValueType* buffer = leafIter.buffer(1).data();
400 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
401 stencil.moveTo(iter);
402 buffer[iter.pos()] = *iter + dt*stencil.meanCurvatureNormGrad();
415 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
425 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
426 mParent->maxMask(), mParent->isMaskInverted());
427 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
428 ValueType* buffer = leafIter.buffer(1).data();
429 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
430 if (alpha(iter.getCoord(), a, b)) {
431 stencil.moveTo(iter);
432 const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.laplacian();
433 buffer[iter.pos()] = b * phi0 + a * phi1;
438 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
439 ValueType* buffer = leafIter.buffer(1).data();
440 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
441 stencil.moveTo(iter);
442 buffer[iter.pos()] = *iter + dt*stencil.laplacian();
449 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
452 const LeafRange& range,
ValueType offset)
457 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
458 mParent->maxMask(), mParent->isMaskInverted());
459 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
460 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
461 if (alpha(iter.getCoord(), a, b)) iter.setValue(*iter + a*offset);
465 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
466 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
467 iter.setValue(*iter + offset);
474 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
482 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
483 mParent->maxMask(), mParent->isMaskInverted());
484 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
485 ValueType* buffer = leafIter.buffer(1).data();
486 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
487 if (alpha(iter.getCoord(), a, b)) {
488 stencil.moveTo(iter);
489 buffer[iter.pos()] = b * (*iter) + a * stencil.median();
494 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
495 ValueType* buffer = leafIter.buffer(1).data();
496 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
497 stencil.moveTo(iter);
498 buffer[iter.pos()] = stencil.median();
505 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
506 template <
typename AvgT>
511 AvgT avg(mParent->grid(), w);
514 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
515 mParent->maxMask(), mParent->isMaskInverted());
516 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
517 ValueType* buffer = leafIter.buffer(1).data();
518 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
519 const Coord xyz = iter.getCoord();
520 if (alpha(xyz, a, b)) buffer[iter.pos()] = b * (*iter)+ a * avg(xyz);
524 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
525 ValueType* buffer = leafIter.buffer(1).data();
526 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
527 buffer[iter.pos()] = avg(iter.getCoord());
537 #endif // OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED
Performs multi-threaded interface tracking of narrow band level sets. This is the building-block for ...
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:610
Coord Abs(const Coord &xyz)
Definition: Coord.h:513
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
Definition: Exceptions.h:92
int32_t Int32
Definition: Types.h:63
Definition: Exceptions.h:40
typename CopyConstness< TreeType, NonConstBufferType >::Type BufferType
Definition: LeafManager.h:121
Axis
Definition: Math.h:856
Definition: LeafManager.h:127
Type Pow2(Type x)
Return x2.
Definition: Math.h:502
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
Definition: Stencils.h:1495
Dense stencil of a given width.
Definition: Stencils.h:1633
Definition: Stencils.h:1217