42 #ifndef OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED
43 #define OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED
57 template<
typename GridT,
58 typename InterruptT = util::NullInterrupter>
72 :
BaseType(grid, interrupt), mTask(0), mMask(NULL)
79 :
BaseType(other), mTask(other.mTask), mMask(other.mMask)
90 if (mTask) mTask(const_cast<LevelSetFilter*>(
this), range);
100 void laplacian(
const GridT* mask = NULL);
108 void gaussian(
int width = 1,
const GridT* mask = NULL);
113 void offset(ValueType offset,
const GridT* mask = NULL);
121 void median(
int width = 1,
const GridT* mask = NULL);
128 void mean(
int width = 1,
const GridT* mask = NULL);
131 typedef typename GridT::ConstAccessor AccT;
132 typedef typename TreeType::LeafNodeType LeafT;
133 typedef typename LeafT::ValueOnIter VoxelIterT;
134 typedef typename LeafT::ValueOnCIter VoxelCIterT;
136 typedef typename RangeType::Iterator LeafIterT;
139 typename boost::function<void (LevelSetFilter*, const RangeType&)> mTask;
145 const int n = BaseType::getGrainSize();
147 tbb::parallel_for(BaseType::leafs().leafRange(n), *
this);
149 (*this)(BaseType::leafs().leafRange());
151 if (swap) BaseType::leafs().swapLeafBuffer(1, n==0);
157 AffineCombine(
const GridT& grid,
const GridT* mask)
158 : mGrid(&grid), mMask(mask),
mAcc(mask ? new AccT(mask->tree()) : NULL),
159 mIdentical(mask ? grid.transform() == mask->transform() : false)
162 ~AffineCombine() {
delete mAcc; }
163 inline ValueType alpha(
const Coord& xyz)
const
166 if (mIdentical)
return mAcc->getValue(xyz);
167 const Vec3R world = mGrid->indexToWorld(xyz);
168 const Vec3R voxel = mMask->worldToIndex(world);
169 return tools::BoxSampler::sample<AccT>(*
mAcc, voxel);
171 inline ValueType operator()(
const Coord& xyz, ValueType unfiltered, ValueType filtered)
const
173 if (mMask==NULL)
return filtered;
174 const ValueType alpha = this->alpha(xyz);
175 return alpha*filtered + (1-alpha)*unfiltered;
180 const bool mIdentical;
186 template <
size_t Axis>
188 Avg(
const GridT& grid,
Int32 w) : acc(grid.tree()), width(w), frac(1/ValueType(2*w+1)) {}
189 ValueType operator()(Coord xyz) {
190 ValueType sum = zeroVal<ValueType>();
192 for (i -= width; i <= j; ++i) sum += acc.getValue(xyz);
195 typename GridT::ConstAccessor acc;
197 const ValueType frac;
201 template <
typename AvgT>
202 void doBox(
const RangeType& r,
Int32 w);
203 void doBoxX(
const RangeType& r,
Int32 w) { this->doBox<Avg<0> >(r,w); }
204 void doBoxZ(
const RangeType& r,
Int32 w) { this->doBox<Avg<1> >(r,w); }
205 void doBoxY(
const RangeType& r,
Int32 w) { this->doBox<Avg<2> >(r,w); }
206 void doMedian(
const RangeType&,
int);
207 void doMeanCurvature(
const RangeType&);
208 void doLaplacian(
const RangeType&);
209 void doOffset(
const RangeType&, ValueType);
216 template<
typename Gr
idT,
typename InterruptT>
222 BaseType::startInterrupter(
"Median-value flow of level set");
224 BaseType::leafs().rebuildAuxBuffers(1, BaseType::getGrainSize()==0);
226 mTask = boost::bind(&LevelSetFilter::doMedian, _1, _2,
std::max(1, width));
231 BaseType::endInterrupter();
235 template<
typename Gr
idT,
typename InterruptT>
241 BaseType::startInterrupter(
"Mean-value flow of level set");
245 BaseType::endInterrupter();
248 template<
typename Gr
idT,
typename InterruptT>
254 BaseType::startInterrupter(
"Gaussian flow of level set");
256 for (
int n=0; n<4; ++n) this->box(width);
258 BaseType::endInterrupter();
261 template<
typename Gr
idT,
typename InterruptT>
265 BaseType::leafs().rebuildAuxBuffers(1, BaseType::getGrainSize()==0);
269 mTask = boost::bind(&LevelSetFilter::doBoxX, _1, _2, width);
272 mTask = boost::bind(&LevelSetFilter::doBoxY, _1, _2, width);
275 mTask = boost::bind(&LevelSetFilter::doBoxZ, _1, _2, width);
282 template<
typename Gr
idT,
typename InterruptT>
288 BaseType::startInterrupter(
"Mean-curvature flow of level set");
290 BaseType::leafs().rebuildAuxBuffers(1, BaseType::getGrainSize()==0);
292 mTask = boost::bind(&LevelSetFilter::doMeanCurvature, _1, _2);
297 BaseType::endInterrupter();
300 template<
typename Gr
idT,
typename InterruptT>
306 BaseType::startInterrupter(
"Laplacian flow of level set");
308 BaseType::leafs().rebuildAuxBuffers(1, BaseType::getGrainSize()==0);
310 mTask = boost::bind(&LevelSetFilter::doLaplacian, _1, _2);
315 BaseType::endInterrupter();
319 template<
typename Gr
idT,
typename InterruptT>
325 BaseType::startInterrupter(
"Offsetting level set");
327 BaseType::leafs().removeAuxBuffers();
331 while (offset-dist >
ValueType(0.001)*CFL && BaseType::checkInterrupter()) {
335 mTask = boost::bind(&LevelSetFilter::doOffset, _1, _2, copysign(delta, value));
341 BaseType::endInterrupter();
348 template<
typename Gr
idT,
typename InterruptT>
352 BaseType::checkInterrupter();
354 const ValueType dx = BaseType::voxelSize(),dt =
math::Pow2(dx) / ValueType(3.0);
356 AffineCombine comb(BaseType::grid(), mMask);
357 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
358 BufferT& buffer = leafIter.buffer(1);
359 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
360 stencil.moveTo(iter);
361 ValueType A = stencil.getCenterValue(), B = A + dt * stencil.meanCurvatureNormGrad();
362 buffer.setValue(iter.pos(), comb(stencil.getCenterCoord(), A, B));
374 template<
typename Gr
idT,
typename InterruptT>
376 LevelSetFilter<GridT, InterruptT>::doLaplacian(
const RangeType& range)
378 BaseType::checkInterrupter();
380 const ValueType dx = BaseType::voxelSize(), dt =
math::Pow2(dx) / ValueType(6.0);
381 math::GradStencil<GridType> stencil(BaseType::grid(), dx);
382 AffineCombine comb(BaseType::grid(), mMask);
383 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
384 BufferT& buffer = leafIter.buffer(1);
385 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
386 stencil.moveTo(iter);
387 const ValueType A = stencil.getCenterValue(), B = A + dt * stencil.laplacian();
388 buffer.setValue(iter.pos(), comb(stencil.getCenterCoord(), A, B));
394 template<
typename Gr
idT,
typename InterruptT>
396 LevelSetFilter<GridT, InterruptT>::doOffset(
const RangeType& range, ValueType offset)
398 BaseType::checkInterrupter();
400 AffineCombine comb(BaseType::grid(), mMask);
401 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
402 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
403 iter.setValue(*iter + comb.alpha(iter.getCoord())*offset);
407 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
408 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
409 iter.setValue(*iter + offset);
416 template<
typename Gr
idT,
typename InterruptT>
418 LevelSetFilter<GridT, InterruptT>::doMedian(
const RangeType& range,
int width)
420 BaseType::checkInterrupter();
421 typename math::DenseStencil<GridType> stencil(BaseType::grid(), width);
422 AffineCombine comb(BaseType::grid(), mMask);
423 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
424 BufferT& buffer = leafIter.buffer(1);
425 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
426 stencil.moveTo(iter);
427 const ValueType A = stencil.getCenterValue(), B = stencil.median();
428 buffer.setValue(iter.pos(), comb(stencil.getCenterCoord(), A, B));
434 template<
typename Gr
idT,
typename InterruptT>
435 template <
typename AvgT>
437 LevelSetFilter<GridT, InterruptT>::doBox(
const RangeType& range,
Int32 w)
439 BaseType::checkInterrupter();
440 AvgT avg(BaseType::grid(), w);
441 AffineCombine comb(BaseType::grid(), mMask);
442 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
443 BufferT& buffer = leafIter.buffer(1);
444 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
445 const Coord xyz = iter.getCoord();
446 buffer.setValue(iter.pos(), comb(xyz, *iter, avg(xyz)));
455 #endif // OPENVDB_TOOLS_LEVELSETFILTER_HAS_BEEN_INCLUDED
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
Definition: Stencils.h:1452
Performs multi-threaded interface tracking of narrow band level sets. This is the building-block for ...
int32_t Int32
Definition: Types.h:58
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Type Pow2(Type x)
Return .
Definition: Math.h:460
AccessorT mAcc
Definition: GridOperators.h:259
#define OPENVDB_VERSION_NAME
Definition: version.h:45
math::Vec3< Real > Vec3R
Definition: Types.h:74
CopyConstness< TreeType, NonConstBufferType >::Type BufferType
Definition: LeafManager.h:117
Definition: Exceptions.h:88
int32_t Abs(int32_t i)
Return the absolute value of the given quantity.
Definition: Math.h:246
Definition: LeafManager.h:122
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:56
Axis
Definition: Math.h:762
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:568