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>
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();
102 Filter f(
this, mask); f.laplacian();
113 Filter f(
this, mask); f.gaussian(width);
121 Filter f(
this, mask); f.offset(offset);
132 Filter f(
this, mask); f.median(width);
142 Filter f(
this, mask); f.mean(width);
153 using LeafT =
typename TreeType::LeafNodeType;
154 using VoxelIterT =
typename LeafT::ValueOnIter;
155 using VoxelCIterT =
typename LeafT::ValueOnCIter;
158 using LeafIterT =
typename LeafRange::Iterator;
162 Filter(
const Filter&) =
default;
166 void median(
int width);
167 void mean(
int width);
168 void gaussian(
int width);
172 void operator()(
const LeafRange& r)
const 174 if (mTask) mTask(const_cast<Filter*>(
this), r);
179 const int n = mParent->getGrainSize();
181 tbb::parallel_for(mParent->leafs().leafRange(n), *
this);
183 (*this)(mParent->leafs().leafRange());
185 if (swap) mParent->leafs().swapLeafBuffer(1, n==0);
188 template <
size_t Axis>
191 acc(grid.tree()), width(w), frac(1/
ValueType(2*w+1)) {}
196 for (i -= width; i <= j; ++i) sum += acc.getValue(xyz);
199 typename GridT::ConstAccessor
acc;
204 template<
typename AvgT>
205 void boxImpl(
const LeafRange& r,
Int32 w);
207 void boxXImpl(
const LeafRange& r,
Int32 w) { this->boxImpl<Avg<0> >(r,w); }
208 void boxZImpl(
const LeafRange& r,
Int32 w) { this->boxImpl<Avg<1> >(r,w); }
209 void boxYImpl(
const LeafRange& r,
Int32 w) { this->boxImpl<Avg<2> >(r,w); }
211 void medianImpl(
const LeafRange&,
int);
212 void meanCurvatureImpl(
const LeafRange&);
213 void laplacianImpl(
const LeafRange&);
214 void offsetImpl(
const LeafRange&,
ValueType);
218 typename std::function<void (Filter*, const LeafRange&)> mTask;
229 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
235 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
237 mTask = std::bind(&Filter::medianImpl,
238 std::placeholders::_1, std::placeholders::_2,
std::max(1, width));
243 mParent->endInterrupter();
246 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
254 mParent->endInterrupter();
257 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
263 for (
int n=0; n<4; ++n) this->box(width);
265 mParent->endInterrupter();
268 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
272 mParent->
leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
276 mTask = std::bind(&Filter::boxXImpl, std::placeholders::_1, std::placeholders::_2, width);
279 mTask = std::bind(&Filter::boxYImpl, std::placeholders::_1, std::placeholders::_2, width);
282 mTask = std::bind(&Filter::boxZImpl, std::placeholders::_1, std::placeholders::_2, width);
288 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
292 mParent->startInterrupter(
"Mean-curvature flow of level set");
294 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
296 mTask = std::bind(&Filter::meanCurvatureImpl, std::placeholders::_1, std::placeholders::_2);
301 mParent->endInterrupter();
304 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
308 mParent->startInterrupter(
"Laplacian flow of level set");
310 mParent->leafs().rebuildAuxBuffers(1, mParent->getGrainSize()==0);
312 mTask = std::bind(&Filter::laplacianImpl, std::placeholders::_1, std::placeholders::_2);
317 mParent->endInterrupter();
320 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
326 mParent->leafs().removeAuxBuffers();
330 while (offset-dist >
ValueType(0.001)*CFL && mParent->checkInterrupter()) {
334 mTask = std::bind(&Filter::offsetImpl,
335 std::placeholders::_1, std::placeholders::_2, copysign(delta, value));
341 mParent->endInterrupter();
348 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
358 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
359 mParent->maxMask(), mParent->isMaskInverted());
360 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
361 ValueType* buffer = leafIter.buffer(1).data();
362 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
363 if (alpha(iter.getCoord(), a, b)) {
364 stencil.moveTo(iter);
365 const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.meanCurvatureNormGrad();
366 buffer[iter.pos()] = b * phi0 + a * phi1;
371 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
372 ValueType* buffer = leafIter.buffer(1).data();
373 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
374 stencil.moveTo(iter);
375 buffer[iter.pos()] = *iter + dt*stencil.meanCurvatureNormGrad();
388 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
398 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
399 mParent->maxMask(), mParent->isMaskInverted());
400 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
401 ValueType* buffer = leafIter.buffer(1).data();
402 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
403 if (alpha(iter.getCoord(), a, b)) {
404 stencil.moveTo(iter);
405 const ValueType phi0 = *iter, phi1 = phi0 + dt*stencil.laplacian();
406 buffer[iter.pos()] = b * phi0 + a * phi1;
411 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
412 ValueType* buffer = leafIter.buffer(1).data();
413 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
414 stencil.moveTo(iter);
415 buffer[iter.pos()] = *iter + dt*stencil.laplacian();
422 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
425 const LeafRange& range,
ValueType offset)
430 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
431 mParent->maxMask(), mParent->isMaskInverted());
432 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
433 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
434 if (alpha(iter.getCoord(), a, b)) iter.setValue(*iter + a*offset);
438 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
439 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
440 iter.setValue(*iter + offset);
447 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
455 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
456 mParent->maxMask(), mParent->isMaskInverted());
457 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
458 ValueType* buffer = leafIter.buffer(1).data();
459 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
460 if (alpha(iter.getCoord(), a, b)) {
461 stencil.moveTo(iter);
462 buffer[iter.pos()] = b * (*iter) + a * stencil.median();
467 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
468 ValueType* buffer = leafIter.buffer(1).data();
469 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
470 stencil.moveTo(iter);
471 buffer[iter.pos()] = stencil.median();
478 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
479 template <
typename AvgT>
484 AvgT avg(mParent->grid(), w);
487 AlphaMaskT alpha(mParent->grid(), *mMask, mParent->minMask(),
488 mParent->maxMask(), mParent->isMaskInverted());
489 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
490 ValueType* buffer = leafIter.buffer(1).data();
491 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
492 const Coord xyz = iter.getCoord();
493 if (alpha(xyz, a, b)) buffer[iter.pos()] = b * (*iter)+ a * avg(xyz);
497 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
498 ValueType* buffer = leafIter.buffer(1).data();
499 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
500 buffer[iter.pos()] = avg(iter.getCoord());
512 #ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION 514 #ifdef OPENVDB_INSTANTIATE_LEVELSETFILTER 521 #endif // OPENVDB_USE_EXPLICIT_INSTANTIATION 528 #endif // OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED
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
Definition: Exceptions.h:65
Axis
Definition: Math.h:904
Dense stencil of a given width.
Definition: Stencils.h:1764
Definition: LeafManager.h:101
Definition: Exceptions.h:13
ValueT value
Definition: GridBuilder.h:1287
Definition: Stencils.h:1515
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:659
#define OPENVDB_INSTANTIATE_CLASS
Definition: version.h.in:143
int32_t Int32
Definition: Types.h:56
typename CopyConstness< TreeType, NonConstBufferType >::Type BufferType
Definition: LeafManager.h:95
Definition: Stencils.h:1231
Coord Abs(const Coord &xyz)
Definition: Coord.h:514
Type Pow2(Type x)
Return x2.
Definition: Math.h:551
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202