15 #ifndef OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED 16 #define OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED 22 #include <type_traits> 36 template<
typename GridT,
37 typename MaskT =
typename GridT::template ValueConverter<float>::Type,
38 typename InterruptT = util::NullInterrupter>
48 static_assert(std::is_floating_point<AlphaType>::value,
49 "LevelSetFilter requires a mask grid with floating-point values");
89 void invertMask(
bool invert=
true) { mInvertMask = invert; }
95 Filter f(
this, mask); f.meanCurvature();
112 Filter f(
this, mask); f.fillet();
119 Filter f(
this, mask); f.laplacian();
130 Filter f(
this, mask); f.gaussian(width);
138 Filter f(
this, mask); f.offset(offset);
149 Filter f(
this, mask); f.median(width);
159 Filter f(
this, mask); f.mean(width);
170 using LeafT =
typename TreeType::LeafNodeType;
171 using VoxelIterT =
typename LeafT::ValueOnIter;
172 using VoxelCIterT =
typename LeafT::ValueOnCIter;
175 using LeafIterT =
typename LeafRange::Iterator;
179 Filter(
const Filter&) =
default;
183 void median(
int width);
184 void mean(
int width);
185 void gaussian(
int width);
190 void operator()(
const LeafRange& r)
const 192 if (mTask) mTask(const_cast<Filter*>(
this), r);
197 const int n = mParent->getGrainSize();
199 tbb::parallel_for(mParent->leafs().leafRange(n), *
this);
201 (*this)(mParent->leafs().leafRange());
203 if (swap) mParent->leafs().swapLeafBuffer(1, n==0);
206 template <
size_t Axis>
209 acc(grid.tree()), width(w), frac(1/
ValueType(2*w+1)) {}
214 for (i -= width; i <= j; ++i) sum += acc.getValue(xyz);
217 typename GridT::ConstAccessor
acc;
222 template<
typename AvgT>
223 void boxImpl(
const LeafRange& r,
Int32 w);
225 void boxXImpl(
const LeafRange& r,
Int32 w) { this->boxImpl<Avg<0> >(r,w); }
226 void boxZImpl(
const LeafRange& r,
Int32 w) { this->boxImpl<Avg<1> >(r,w); }
227 void boxYImpl(
const LeafRange& r,
Int32 w) { this->boxImpl<Avg<2> >(r,w); }
229 void medianImpl(
const LeafRange&,
int);
230 void meanCurvatureImpl(
const LeafRange&);
231 void filletImpl(
const LeafRange&);
232 void laplacianImpl(
const LeafRange&);
233 void offsetImpl(
const LeafRange&,
ValueType);
237 typename std::function<void (Filter*, const LeafRange&)> mTask;
248 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
254 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
256 mTask = std::bind(&Filter::medianImpl,
257 std::placeholders::_1, std::placeholders::_2,
std::max(1, width));
262 mParent->endInterrupter();
265 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
273 mParent->endInterrupter();
276 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
282 for (
int n=0; n<4; ++n) this->box(width);
284 mParent->endInterrupter();
287 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
291 mParent->
leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
295 mTask = std::bind(&Filter::boxXImpl, std::placeholders::_1, std::placeholders::_2, width);
298 mTask = std::bind(&Filter::boxYImpl, std::placeholders::_1, std::placeholders::_2, width);
301 mTask = std::bind(&Filter::boxZImpl, std::placeholders::_1, std::placeholders::_2, width);
307 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
311 mParent->startInterrupter(
"Mean-curvature flow of level set");
313 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
315 mTask = std::bind(&Filter::meanCurvatureImpl, std::placeholders::_1, std::placeholders::_2);
320 mParent->endInterrupter();
323 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
329 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
331 mTask = std::bind(&Filter::filletImpl, std::placeholders::_1, std::placeholders::_2);
336 mParent->endInterrupter();
339 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
343 mParent->startInterrupter(
"Laplacian flow of level set");
345 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
347 mTask = std::bind(&Filter::laplacianImpl, std::placeholders::_1, std::placeholders::_2);
352 mParent->endInterrupter();
355 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
361 mParent->leafs().removeAuxBuffers();
365 while (offset-dist >
ValueType(0.001)*CFL && mParent->checkInterrupter()) {
369 mTask = std::bind(&Filter::offsetImpl,
370 std::placeholders::_1, std::placeholders::_2, copysign(delta, value));
376 mParent->endInterrupter();
383 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
393 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
394 mParent->maxMask(), mParent->isMaskInverted());
395 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
396 ValueType* buffer = leafIter.buffer(1).data();
397 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
398 if (alpha(iter.getCoord(), a, b)) {
399 stencil.moveTo(iter);
400 const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.meanCurvatureNormGrad();
401 buffer[iter.pos()] = b * phi0 + a * phi1;
406 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
407 ValueType* buffer = leafIter.buffer(1).data();
408 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
409 stencil.moveTo(iter);
410 buffer[iter.pos()] = *iter + dt*stencil.meanCurvatureNormGrad();
420 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
431 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
432 mParent->maxMask(), mParent->isMaskInverted());
433 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
434 ValueType* buffer = leafIter.buffer(1).data();
435 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
436 if (alpha(iter.getCoord(), a, b)) {
437 stencil.moveTo(iter);
439 const ValueType kappa = stencil.principalCurvatures().first;
443 buffer[iter.pos()] = b * phi0 + a * phi1;
448 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
449 ValueType* buffer = leafIter.buffer(1).data();
450 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
451 stencil.moveTo(iter);
453 const ValueType kappa = stencil.principalCurvatures().first;
456 buffer[iter.pos()] = *iter + dt*kappa;
469 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
479 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
480 mParent->maxMask(), mParent->isMaskInverted());
481 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
482 ValueType* buffer = leafIter.buffer(1).data();
483 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
484 if (alpha(iter.getCoord(), a, b)) {
485 stencil.moveTo(iter);
486 const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.laplacian();
487 buffer[iter.pos()] = b * phi0 + a * phi1;
492 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
493 ValueType* buffer = leafIter.buffer(1).data();
494 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
495 stencil.moveTo(iter);
496 buffer[iter.pos()] = *iter + dt*stencil.laplacian();
503 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
506 const LeafRange& range,
ValueType offset)
511 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
512 mParent->maxMask(), mParent->isMaskInverted());
513 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
514 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
515 if (alpha(iter.getCoord(), a, b)) iter.setValue(*iter + a*offset);
519 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
520 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
521 iter.setValue(*iter + offset);
528 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
536 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
537 mParent->maxMask(), mParent->isMaskInverted());
538 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
539 ValueType* buffer = leafIter.buffer(1).data();
540 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
541 if (alpha(iter.getCoord(), a, b)) {
542 stencil.moveTo(iter);
543 buffer[iter.pos()] = b * (*iter) + a * stencil.median();
548 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
549 ValueType* buffer = leafIter.buffer(1).data();
550 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
551 stencil.moveTo(iter);
552 buffer[iter.pos()] = stencil.median();
559 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
560 template <
typename AvgT>
565 AvgT avg(mParent->grid(), w);
568 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
569 mParent->maxMask(), mParent->isMaskInverted());
570 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
571 ValueType* buffer = leafIter.buffer(1).data();
572 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
573 const Coord xyz = iter.getCoord();
574 if (alpha(xyz, a, b)) buffer[iter.pos()] = b * (*iter)+ a * avg(xyz);
578 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
579 ValueType* buffer = leafIter.buffer(1).data();
580 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
581 buffer[iter.pos()] = avg(iter.getCoord());
593 #ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION 595 #ifdef OPENVDB_INSTANTIATE_LEVELSETFILTER 602 #endif // OPENVDB_USE_EXPLICIT_INSTANTIATION 609 #endif // OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED Type Pow2(Type x)
Return x2.
Definition: Math.h:548
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:367
Performs multi-threaded interface tracking of narrow band level sets. This is the building-block for ...
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Coord Abs(const Coord &xyz)
Definition: Coord.h:518
Definition: Stencils.h:1231
Definition: Stencils.h:1515
int32_t Int32
Definition: Types.h:56
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:656
Definition: Exceptions.h:65
Axis
Definition: Math.h:901
Definition: Exceptions.h:13
Dense stencil of a given width.
Definition: Stencils.h:1764
typename CopyConstness< TreeType, NonConstBufferType >::Type BufferType
Definition: LeafManager.h:96
#define OPENVDB_INSTANTIATE_CLASS
Definition: version.h.in:158
Definition: LeafManager.h:102
#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