39 #ifndef OPENVDB_TOOLS_FILTER_HAS_BEEN_INCLUDED 40 #define OPENVDB_TOOLS_FILTER_HAS_BEEN_INCLUDED 42 #include <tbb/parallel_for.h> 43 #include <boost/bind.hpp> 44 #include <boost/function.hpp> 45 #include <boost/type_traits/is_floating_point.hpp> 63 template<
typename GridT,
64 typename MaskT =
typename GridT::template ValueConverter<float>::Type,
65 typename InterruptT = util::NullInterrupter>
72 typedef typename TreeType::LeafNodeType
LeafType;
78 BOOST_STATIC_ASSERT(boost::is_floating_point<AlphaType>::value);
83 Filter(GridT& grid, InterruptT* interrupt = NULL)
86 , mInterrupter(interrupt)
101 , mInterrupter(other.mInterrupter)
103 , mGrainSize(other.mGrainSize)
104 , mMinMask(other.mMinMask)
105 , mMaxMask(other.mMaxMask)
106 , mInvertMask(other.mInvertMask)
118 AlphaType
minMask()
const {
return mMinMask; }
121 AlphaType
maxMask()
const {
return mMaxMask; }
146 void mean(
int width = 1,
int iterations = 1,
const MaskType* mask = NULL);
155 void gaussian(
int width = 1,
int iterations = 1,
const MaskType* mask = NULL);
163 void median(
int width = 1,
int iterations = 1,
const MaskType* mask = NULL);
168 void offset(ValueType offset,
const MaskType* mask = NULL);
176 if (mTask) mTask(const_cast<Filter*>(
this), range);
181 typedef typename TreeType::LeafNodeType LeafT;
182 typedef typename LeafT::ValueOnIter VoxelIterT;
183 typedef typename LeafT::ValueOnCIter VoxelCIterT;
188 void cook(LeafManagerType& leafs);
190 template<
size_t Axis>
192 Avg(
const GridT* grid,
Int32 w): acc(grid->tree()), width(w), frac(1.f/
float(2*w+1)) {}
193 inline ValueType operator()(
Coord xyz);
194 typename GridT::ConstAccessor acc;
200 template <
typename AvgT>
201 void doBox(
const RangeType& r,
Int32 w);
202 void doBoxX(
const RangeType& r,
Int32 w) { this->doBox<Avg<0> >(r,w); }
203 void doBoxZ(
const RangeType& r,
Int32 w) { this->doBox<Avg<1> >(r,w); }
204 void doBoxY(
const RangeType& r,
Int32 w) { this->doBox<Avg<2> >(r,w); }
205 void doMedian(
const RangeType&,
int);
206 void doOffset(
const RangeType&, ValueType);
211 typename boost::function<void (Filter*, const RangeType&)> mTask;
212 InterruptT* mInterrupter;
213 const MaskType* mMask;
215 AlphaType mMinMask, mMaxMask;
223 namespace filter_internal {
225 template<
typename T>
static inline void accum(T& sum, T addend) { sum += addend; }
227 inline void accum(
bool& sum,
bool addend) { sum = sum || addend; }
231 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
232 template<
size_t Axis>
233 inline typename GridT::ValueType
236 ValueType sum = zeroVal<ValueType>();
239 return static_cast<ValueType
>(sum * frac);
246 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
252 if (mInterrupter) mInterrupter->start(
"Applying mean filter");
259 mTask = boost::bind(&Filter::doBoxX, _1, _2, w);
262 mTask = boost::bind(&Filter::doBoxY, _1, _2, w);
265 mTask = boost::bind(&Filter::doBoxZ, _1, _2, w);
269 if (mInterrupter) mInterrupter->end();
273 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
279 if (mInterrupter) mInterrupter->start(
"Applying Gaussian filter");
285 for (
int i=0;
i<iterations; ++
i) {
287 mTask = boost::bind(&Filter::doBoxX, _1, _2, w);
290 mTask = boost::bind(&Filter::doBoxY, _1, _2, w);
293 mTask = boost::bind(&Filter::doBoxZ, _1, _2, w);
298 if (mInterrupter) mInterrupter->end();
302 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
308 if (mInterrupter) mInterrupter->start(
"Applying median filter");
312 mTask = boost::bind(&Filter::doMedian, _1, _2,
std::max(1, width));
315 if (mInterrupter) mInterrupter->end();
319 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
325 if (mInterrupter) mInterrupter->start(
"Applying offset");
329 mTask = boost::bind(&Filter::doOffset, _1, _2, value);
332 if (mInterrupter) mInterrupter->end();
341 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
346 tbb::parallel_for(leafs.
leafRange(mGrainSize), *
this);
355 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
356 template <
typename AvgT>
364 AlphaMaskT alpha(*mGrid, *mMask, mMinMask, mMaxMask, mInvertMask);
366 BufferT& buffer = leafIter.buffer(1);
367 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
368 const Coord xyz = iter.getCoord();
369 if (alpha(xyz, a, b)) {
370 buffer.setValue(iter.pos(),
ValueType(b*(*iter) + a*avg(xyz)));
376 BufferT& buffer = leafIter.buffer(1);
377 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
378 buffer.setValue(iter.pos(), avg(iter.getCoord()));
386 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
394 AlphaMaskT alpha(*mGrid, *mMask, mMinMask, mMaxMask, mInvertMask);
396 BufferT& buffer = leafIter.buffer(1);
397 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
398 if (alpha(iter.getCoord(), a, b)) {
400 buffer.setValue(iter.pos(),
ValueType(b*(*iter) + a*stencil.
median()));
406 BufferT& buffer = leafIter.buffer(1);
407 for (VoxelCIterT iter = leafIter->cbeginValueOn(); iter; ++iter) {
409 buffer.setValue(iter.pos(), stencil.
median());
417 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
424 AlphaMaskT alpha(*mGrid, *mMask, mMinMask, mMaxMask, mInvertMask);
426 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
427 if (alpha(iter.getCoord(), a, b)) iter.setValue(
ValueType(*iter + a*offset));
432 for (VoxelIterT iter = leafIter->beginValueOn(); iter; ++iter) {
433 iter.setValue(*iter + offset);
440 template<
typename Gr
idT,
typename MaskT,
typename InterruptT>
445 tbb::task::self().cancel_group_execution();
455 #endif // OPENVDB_TOOLS_FILTER_HAS_BEEN_INCLUDED
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
tbb::atomic< Index32 > i
Definition: LeafBuffer.h:71
Definition: LeafManager.h:127
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Definition: LeafManager.h:130
ValueType median() const
Return the median value of the current stencil.
Definition: Stencils.h:147
Dense stencil of a given width.
Definition: Stencils.h:1633
typename CopyConstness< TreeType, NonConstBufferType >::Type BufferType
Definition: LeafManager.h:121
Definition: Exceptions.h:39
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:386
Definition: Exceptions.h:92
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:110
Iterator begin() const
Definition: LeafManager.h:181
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:48
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
int32_t Int32
Definition: Types.h:59
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Axis
Definition: Math.h:852
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
void moveTo(const Coord &ijk)
Initialize the stencil buffer with the values of voxel (x, y, z) and its neighbors.
Definition: Stencils.h:1653
bool swapLeafBuffer(size_t bufferIdx, bool serial=false)
Swap each leaf node's buffer with the nth corresponding auxiliary buffer, where n = bufferIdx...
Definition: LeafManager.h:400