OpenVDB 9.0.0
ValueTransformer.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: MPL-2.0
3//
4/// @file ValueTransformer.h
5///
6/// @author Peter Cucka
7///
8/// tools::foreach() and tools::transformValues() transform the values in a grid
9/// by iterating over the grid with a user-supplied iterator and applying a
10/// user-supplied functor at each step of the iteration. With tools::foreach(),
11/// the transformation is done in-place on the input grid, whereas with
12/// tools::transformValues(), transformed values are written to an output grid
13/// (which can, for example, have a different value type than the input grid).
14/// Both functions can optionally transform multiple values of the grid in parallel.
15///
16/// tools::accumulate() can be used to accumulate the results of applying a functor
17/// at each step of a grid iteration. (The functor is responsible for storing and
18/// updating intermediate results.) When the iteration is done serially the behavior is
19/// the same as with tools::foreach(), but when multiple values are processed in parallel,
20/// an additional step is performed: when any two threads finish processing,
21/// @c op.join(otherOp) is called on one thread's functor to allow it to coalesce
22/// its intermediate result with the other thread's.
23///
24/// Finally, tools::setValueOnMin(), tools::setValueOnMax(), tools::setValueOnSum()
25/// and tools::setValueOnMult() are wrappers around Tree::modifyValue() (or
26/// ValueAccessor::modifyValue()) for some commmon in-place operations.
27/// These are typically significantly faster than calling getValue() followed by setValue().
28
29#ifndef OPENVDB_TOOLS_VALUETRANSFORMER_HAS_BEEN_INCLUDED
30#define OPENVDB_TOOLS_VALUETRANSFORMER_HAS_BEEN_INCLUDED
31
32#include <algorithm> // for std::min(), std::max()
33#include <tbb/parallel_for.h>
34#include <tbb/parallel_reduce.h>
35#include <openvdb/Types.h>
36#include <openvdb/Grid.h>
37#include <openvdb/openvdb.h>
38
39
40namespace openvdb {
42namespace OPENVDB_VERSION_NAME {
43namespace tools {
44
45/// Iterate over a grid and at each step call @c op(iter).
46/// @param iter an iterator over a grid or its tree (@c Grid::ValueOnCIter,
47/// @c Tree::NodeIter, etc.)
48/// @param op a functor of the form <tt>void op(const IterT&)</tt>, where @c IterT is
49/// the type of @a iter
50/// @param threaded if true, transform multiple values of the grid in parallel
51/// @param shareOp if true and @a threaded is true, all threads use the same functor;
52/// otherwise, each thread gets its own copy of the @e original functor
53///
54/// @par Example:
55/// Multiply all values (both set and unset) of a scalar, floating-point grid by two.
56/// @code
57/// struct Local {
58/// static inline void op(const FloatGrid::ValueAllIter& iter) {
59/// iter.setValue(*iter * 2);
60/// }
61/// };
62/// FloatGrid grid = ...;
63/// tools::foreach(grid.beginValueAll(), Local::op);
64/// @endcode
65///
66/// @par Example:
67/// Rotate all active vectors of a vector grid by 45 degrees about the y axis.
68/// @code
69/// namespace {
70/// struct MatMul {
71/// math::Mat3s M;
72/// MatMul(const math::Mat3s& mat): M(mat) {}
73/// inline void operator()(const VectorGrid::ValueOnIter& iter) const {
74/// iter.setValue(M.transform(*iter));
75/// }
76/// };
77/// }
78/// {
79/// VectorGrid grid = ...;
80/// tools::foreach(grid.beginValueOn(),
81/// MatMul(math::rotation<math::Mat3s>(math::Y, M_PI_4)));
82/// }
83/// @endcode
84///
85/// @note For more complex operations that require finer control over threading,
86/// consider using @c tbb::parallel_for() or @c tbb::parallel_reduce() in conjunction
87/// with a tree::IteratorRange that wraps a grid or tree iterator.
88template<typename IterT, typename XformOp>
89inline void foreach(const IterT& iter, XformOp& op,
90 bool threaded = true, bool shareOp = true);
91
92template<typename IterT, typename XformOp>
93inline void foreach(const IterT& iter, const XformOp& op,
94 bool threaded = true, bool shareOp = true);
95
96
97/// Iterate over a grid and at each step call <tt>op(iter, accessor)</tt> to
98/// populate (via the accessor) the given output grid, whose @c ValueType
99/// need not be the same as the input grid's.
100/// @param inIter a non-<tt>const</tt> or (preferably) @c const iterator over an
101/// input grid or its tree (@c Grid::ValueOnCIter, @c Tree::NodeIter, etc.)
102/// @param outGrid an empty grid to be populated
103/// @param op a functor of the form
104/// <tt>void op(const InIterT&, OutGridT::ValueAccessor&)</tt>,
105/// where @c InIterT is the type of @a inIter
106/// @param threaded if true, transform multiple values of the input grid in parallel
107/// @param shareOp if true and @a threaded is true, all threads use the same functor;
108/// otherwise, each thread gets its own copy of the @e original functor
109/// @param merge how to merge intermediate results from multiple threads (see Types.h)
110///
111/// @par Example:
112/// Populate a scalar floating-point grid with the lengths of the vectors from all
113/// active voxels of a vector-valued input grid.
114/// @code
115/// struct Local {
116/// static void op(
117/// const Vec3fGrid::ValueOnCIter& iter,
118/// FloatGrid::ValueAccessor& accessor)
119/// {
120/// if (iter.isVoxelValue()) { // set a single voxel
121/// accessor.setValue(iter.getCoord(), iter->length());
122/// } else { // fill an entire tile
123/// CoordBBox bbox;
124/// iter.getBoundingBox(bbox);
125/// accessor.getTree()->fill(bbox, iter->length());
126/// }
127/// }
128/// };
129/// Vec3fGrid inGrid = ...;
130/// FloatGrid outGrid;
131/// tools::transformValues(inGrid.cbeginValueOn(), outGrid, Local::op);
132/// @endcode
133///
134/// @note For more complex operations that require finer control over threading,
135/// consider using @c tbb::parallel_for() or @c tbb::parallel_reduce() in conjunction
136/// with a tree::IteratorRange that wraps a grid or tree iterator.
137template<typename InIterT, typename OutGridT, typename XformOp>
138inline void transformValues(const InIterT& inIter, OutGridT& outGrid,
139 XformOp& op, bool threaded = true, bool shareOp = true,
141
142#ifndef _MSC_VER
143template<typename InIterT, typename OutGridT, typename XformOp>
144inline void transformValues(const InIterT& inIter, OutGridT& outGrid,
145 const XformOp& op, bool threaded = true, bool shareOp = true,
147#endif
148
149
150/// Iterate over a grid and at each step call @c op(iter). If threading is enabled,
151/// call @c op.join(otherOp) to accumulate intermediate results from pairs of threads.
152/// @param iter an iterator over a grid or its tree (@c Grid::ValueOnCIter,
153/// @c Tree::NodeIter, etc.)
154/// @param op a functor with a join method of the form <tt>void join(XformOp&)</tt>
155/// and a call method of the form <tt>void op(const IterT&)</tt>,
156/// where @c IterT is the type of @a iter
157/// @param threaded if true, transform multiple values of the grid in parallel
158/// @note If @a threaded is true, each thread gets its own copy of the @e original functor.
159/// The order in which threads are joined is unspecified.
160/// @note If @a threaded is false, the join method is never called.
161///
162/// @par Example:
163/// Compute the average of the active values of a scalar, floating-point grid
164/// using the math::Stats class.
165/// @code
166/// namespace {
167/// struct Average {
168/// math::Stats stats;
169///
170/// // Accumulate voxel and tile values into this functor's Stats object.
171/// inline void operator()(const FloatGrid::ValueOnCIter& iter) {
172/// if (iter.isVoxelValue()) stats.add(*iter);
173/// else stats.add(*iter, iter.getVoxelCount());
174/// }
175///
176/// // Accumulate another functor's Stats object into this functor's.
177/// inline void join(Average& other) { stats.add(other.stats); }
178///
179/// // Return the cumulative result.
180/// inline double average() const { return stats.mean(); }
181/// };
182/// }
183/// {
184/// FloatGrid grid = ...;
185/// Average op;
186/// tools::accumulate(grid.cbeginValueOn(), op);
187/// double average = op.average();
188/// }
189/// @endcode
190///
191/// @note For more complex operations that require finer control over threading,
192/// consider using @c tbb::parallel_for() or @c tbb::parallel_reduce() in conjunction
193/// with a tree::IteratorRange that wraps a grid or tree iterator.
194template<typename IterT, typename XformOp>
195inline void accumulate(const IterT& iter, XformOp& op, bool threaded = true);
196
197
198/// @brief Set the value of the voxel at the given coordinates in @a tree to
199/// the minimum of its current value and @a value, and mark the voxel as active.
200/// @details This is typically significantly faster than calling getValue()
201/// followed by setValueOn().
202/// @note @a TreeT can be either a Tree or a ValueAccessor.
203template<typename TreeT>
204void setValueOnMin(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value);
205
206/// @brief Set the value of the voxel at the given coordinates in @a tree to
207/// the maximum of its current value and @a value, and mark the voxel as active.
208/// @details This is typically significantly faster than calling getValue()
209/// followed by setValueOn().
210/// @note @a TreeT can be either a Tree or a ValueAccessor.
211template<typename TreeT>
212void setValueOnMax(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value);
213
214/// @brief Set the value of the voxel at the given coordinates in @a tree to
215/// the sum of its current value and @a value, and mark the voxel as active.
216/// @details This is typically significantly faster than calling getValue()
217/// followed by setValueOn().
218/// @note @a TreeT can be either a Tree or a ValueAccessor.
219template<typename TreeT>
220void setValueOnSum(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value);
221
222/// @brief Set the value of the voxel at the given coordinates in @a tree to
223/// the product of its current value and @a value, and mark the voxel as active.
224/// @details This is typically significantly faster than calling getValue()
225/// followed by setValueOn().
226/// @note @a TreeT can be either a Tree or a ValueAccessor.
227template<typename TreeT>
228void setValueOnMult(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value);
229
230
231////////////////////////////////////////
232
233
234namespace valxform {
235
236template<typename ValueType>
237struct MinOp {
238 const ValueType val;
239 MinOp(const ValueType& v): val(v) {}
240 inline void operator()(ValueType& v) const { v = std::min<ValueType>(v, val); }
241};
242
243template<typename ValueType>
244struct MaxOp {
245 const ValueType val;
246 MaxOp(const ValueType& v): val(v) {}
247 inline void operator()(ValueType& v) const { v = std::max<ValueType>(v, val); }
248};
249
250template<typename ValueType>
251struct SumOp {
252 const ValueType val;
253 SumOp(const ValueType& v): val(v) {}
254 inline void operator()(ValueType& v) const { v += val; }
255};
256
257template<>
258struct SumOp<bool> {
259 using ValueType = bool;
261 SumOp(const ValueType& v): val(v) {}
262 inline void operator()(ValueType& v) const { v = v || val; }
263};
264
265template<typename ValueType>
266struct MultOp {
267 const ValueType val;
268 MultOp(const ValueType& v): val(v) {}
269 inline void operator()(ValueType& v) const { v *= val; }
270};
271
272template<>
273struct MultOp<bool> {
274 using ValueType = bool;
276 MultOp(const ValueType& v): val(v) {}
277 inline void operator()(ValueType& v) const { v = v && val; }
278};
279
280}
281
282
283template<typename TreeT>
284void
285setValueOnMin(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
286{
288}
289
290
291template<typename TreeT>
292void
293setValueOnMax(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
294{
296}
297
298
299template<typename TreeT>
300void
301setValueOnSum(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
302{
304}
305
306
307template<typename TreeT>
308void
309setValueOnMult(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
310{
312}
313
314
315////////////////////////////////////////
316
317
318namespace valxform {
319
320template<typename IterT, typename OpT>
322{
323public:
325
326 SharedOpApplier(const IterT& iter, OpT& op): mIter(iter), mOp(op) {}
327
328 void process(bool threaded = true)
329 {
330 IterRange range(mIter);
331 if (threaded) {
332 tbb::parallel_for(range, *this);
333 } else {
334 (*this)(range);
335 }
336 }
337
338 void operator()(IterRange& r) const { for ( ; r; ++r) mOp(r.iterator()); }
339
340private:
341 IterT mIter;
342 OpT& mOp;
343};
344
345
346template<typename IterT, typename OpT>
348{
349public:
351
352 CopyableOpApplier(const IterT& iter, const OpT& op): mIter(iter), mOp(op), mOrigOp(&op) {}
353
354 // When splitting this task, give the subtask a copy of the original functor,
355 // not of this task's functor, which might have been modified arbitrarily.
357 mIter(other.mIter), mOp(*other.mOrigOp), mOrigOp(other.mOrigOp) {}
358
359 void process(bool threaded = true)
360 {
361 IterRange range(mIter);
362 if (threaded) {
363 tbb::parallel_for(range, *this);
364 } else {
365 (*this)(range);
366 }
367 }
368
369 void operator()(IterRange& r) const { for ( ; r; ++r) mOp(r.iterator()); }
370
371private:
372 IterT mIter;
373 OpT mOp; // copy of original functor
374 OpT const * const mOrigOp; // pointer to original functor
375};
376
377} // namespace valxform
378
379
380template<typename IterT, typename XformOp>
381inline void
382foreach(const IterT& iter, XformOp& op, bool threaded, bool shared)
383{
384 if (shared) {
385 typename valxform::SharedOpApplier<IterT, XformOp> proc(iter, op);
386 proc.process(threaded);
387 } else {
388 using Processor = typename valxform::CopyableOpApplier<IterT, XformOp>;
389 Processor proc(iter, op);
390 proc.process(threaded);
391 }
392}
393
394template<typename IterT, typename XformOp>
395inline void
396foreach(const IterT& iter, const XformOp& op, bool threaded, bool /*shared*/)
397{
398 // Const ops are shared across threads, not copied.
400 proc.process(threaded);
401}
402
403
404////////////////////////////////////////
405
406
407namespace valxform {
408
409template<typename InIterT, typename OutTreeT, typename OpT>
411{
412public:
413 using InTreeT = typename InIterT::TreeT;
415 using OutValueT = typename OutTreeT::ValueType;
416
417 SharedOpTransformer(const InIterT& inIter, OutTreeT& outTree, OpT& op, MergePolicy merge):
418 mIsRoot(true),
419 mInputIter(inIter),
420 mInputTree(inIter.getTree()),
421 mOutputTree(&outTree),
422 mOp(op),
423 mMergePolicy(merge)
424 {
425 if (static_cast<const void*>(mInputTree) == static_cast<void*>(mOutputTree)) {
426 OPENVDB_LOG_INFO("use tools::foreach(), not transformValues(),"
427 " to transform a grid in place");
428 }
429 }
430
431 /// Splitting constructor
433 mIsRoot(false),
434 mInputIter(other.mInputIter),
435 mInputTree(other.mInputTree),
436 mOutputTree(new OutTreeT(zeroVal<OutValueT>())),
437 mOp(other.mOp),
438 mMergePolicy(other.mMergePolicy)
439 {}
440
442 {
443 // Delete the output tree only if it was allocated locally
444 // (the top-level output tree was supplied by the caller).
445 if (!mIsRoot) {
446 delete mOutputTree;
447 mOutputTree = nullptr;
448 }
449 }
450
451 void process(bool threaded = true)
452 {
453 if (!mInputTree || !mOutputTree) return;
454
455 IterRange range(mInputIter);
456
457 // Independently transform elements in the iterator range,
458 // either in parallel or serially.
459 if (threaded) {
460 tbb::parallel_reduce(range, *this);
461 } else {
462 (*this)(range);
463 }
464 }
465
466 /// Transform each element in the given range.
467 void operator()(IterRange& range) const
468 {
469 if (!mOutputTree) return;
470 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
471 for ( ; range; ++range) {
472 mOp(range.iterator(), outAccessor);
473 }
474 }
475
476 void join(const SharedOpTransformer& other)
477 {
478 if (mOutputTree && other.mOutputTree) {
479 mOutputTree->merge(*other.mOutputTree, mMergePolicy);
480 }
481 }
482
483private:
484 bool mIsRoot;
485 InIterT mInputIter;
486 const InTreeT* mInputTree;
487 OutTreeT* mOutputTree;
488 OpT& mOp;
489 MergePolicy mMergePolicy;
490}; // class SharedOpTransformer
491
492
493template<typename InIterT, typename OutTreeT, typename OpT>
495{
496public:
497 using InTreeT = typename InIterT::TreeT;
499 using OutValueT = typename OutTreeT::ValueType;
500
501 CopyableOpTransformer(const InIterT& inIter, OutTreeT& outTree,
502 const OpT& op, MergePolicy merge):
503 mIsRoot(true),
504 mInputIter(inIter),
505 mInputTree(inIter.getTree()),
506 mOutputTree(&outTree),
507 mOp(op),
508 mOrigOp(&op),
509 mMergePolicy(merge)
510 {
511 if (static_cast<const void*>(mInputTree) == static_cast<void*>(mOutputTree)) {
512 OPENVDB_LOG_INFO("use tools::foreach(), not transformValues(),"
513 " to transform a grid in place");
514 }
515 }
516
517 // When splitting this task, give the subtask a copy of the original functor,
518 // not of this task's functor, which might have been modified arbitrarily.
520 mIsRoot(false),
521 mInputIter(other.mInputIter),
522 mInputTree(other.mInputTree),
523 mOutputTree(new OutTreeT(zeroVal<OutValueT>())),
524 mOp(*other.mOrigOp),
525 mOrigOp(other.mOrigOp),
526 mMergePolicy(other.mMergePolicy)
527 {}
528
530 {
531 // Delete the output tree only if it was allocated locally
532 // (the top-level output tree was supplied by the caller).
533 if (!mIsRoot) {
534 delete mOutputTree;
535 mOutputTree = nullptr;
536 }
537 }
538
539 void process(bool threaded = true)
540 {
541 if (!mInputTree || !mOutputTree) return;
542
543 IterRange range(mInputIter);
544
545 // Independently transform elements in the iterator range,
546 // either in parallel or serially.
547 if (threaded) {
548 tbb::parallel_reduce(range, *this);
549 } else {
550 (*this)(range);
551 }
552 }
553
554 /// Transform each element in the given range.
556 {
557 if (!mOutputTree) return;
558 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
559 for ( ; range; ++range) {
560 mOp(range.iterator(), outAccessor);
561 }
562 }
563
564 void join(const CopyableOpTransformer& other)
565 {
566 if (mOutputTree && other.mOutputTree) {
567 mOutputTree->merge(*other.mOutputTree, mMergePolicy);
568 }
569 }
570
571private:
572 bool mIsRoot;
573 InIterT mInputIter;
574 const InTreeT* mInputTree;
575 OutTreeT* mOutputTree;
576 OpT mOp; // copy of original functor
577 OpT const * const mOrigOp; // pointer to original functor
578 MergePolicy mMergePolicy;
579}; // class CopyableOpTransformer
580
581} // namespace valxform
582
583
584////////////////////////////////////////
585
586
587template<typename InIterT, typename OutGridT, typename XformOp>
588inline void
589transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op,
590 bool threaded, bool shared, MergePolicy merge)
591{
592 using Adapter = TreeAdapter<OutGridT>;
593 using OutTreeT = typename Adapter::TreeType;
594 if (shared) {
596 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
597 proc.process(threaded);
598 } else {
600 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
601 proc.process(threaded);
602 }
603}
604
605#ifndef _MSC_VER
606template<typename InIterT, typename OutGridT, typename XformOp>
607inline void
608transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op,
609 bool threaded, bool /*share*/, MergePolicy merge)
610{
611 using Adapter = TreeAdapter<OutGridT>;
612 using OutTreeT = typename Adapter::TreeType;
613 // Const ops are shared across threads, not copied.
615 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
616 proc.process(threaded);
617}
618#endif
619
620
621////////////////////////////////////////
622
623
624namespace valxform {
625
626template<typename IterT, typename OpT>
628{
629public:
631
632 // The root task makes a const copy of the original functor (mOrigOp)
633 // and keeps a pointer to the original functor (mOp), which it then modifies.
634 // Each subtask keeps a const pointer to the root task's mOrigOp
635 // and makes and then modifies a non-const copy (mOp) of it.
636 OpAccumulator(const IterT& iter, OpT& op):
637 mIsRoot(true),
638 mIter(iter),
639 mOp(&op),
640 mOrigOp(new OpT(op))
641 {}
642
643 // When splitting this task, give the subtask a copy of the original functor,
644 // not of this task's functor, which might have been modified arbitrarily.
645 OpAccumulator(OpAccumulator& other, tbb::split):
646 mIsRoot(false),
647 mIter(other.mIter),
648 mOp(new OpT(*other.mOrigOp)),
649 mOrigOp(other.mOrigOp)
650 {}
651
652 ~OpAccumulator() { if (mIsRoot) delete mOrigOp; else delete mOp; }
653
654 void process(bool threaded = true)
655 {
656 IterRange range(mIter);
657 if (threaded) {
658 tbb::parallel_reduce(range, *this);
659 } else {
660 (*this)(range);
661 }
662 }
663
664 void operator()(IterRange& r) { for ( ; r; ++r) (*mOp)(r.iterator()); }
665
666 void join(OpAccumulator& other) { mOp->join(*other.mOp); }
667
668private:
669 const bool mIsRoot;
670 const IterT mIter;
671 OpT* mOp; // pointer to original functor, which might get modified
672 OpT const * const mOrigOp; // const copy of original functor
673}; // class OpAccumulator
674
675} // namespace valxform
676
677
678////////////////////////////////////////
679
680
681template<typename IterT, typename XformOp>
682inline void
683accumulate(const IterT& iter, XformOp& op, bool threaded)
684{
685 typename valxform::OpAccumulator<IterT, XformOp> proc(iter, op);
686 proc.process(threaded);
687}
688
689
690////////////////////////////////////////
691
692
693// Explicit Template Instantiation
694
695#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
696
697#ifdef OPENVDB_INSTANTIATE_VALUETRANSFORMER
699#endif
700
701#define _FUNCTION(TreeT) \
702 void setValueOnMin(TreeT&, const Coord&, const TreeT::ValueType&)
704#undef _FUNCTION
705
706#define _FUNCTION(TreeT) \
707 void setValueOnMax(TreeT&, const Coord&, const TreeT::ValueType&)
709#undef _FUNCTION
710
711#define _FUNCTION(TreeT) \
712 void setValueOnSum(TreeT&, const Coord&, const TreeT::ValueType&)
714#undef _FUNCTION
715
716#define _FUNCTION(TreeT) \
717 void setValueOnMult(TreeT&, const Coord&, const TreeT::ValueType&)
719#undef _FUNCTION
720
721#endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
722
723
724} // namespace tools
725} // namespace OPENVDB_VERSION_NAME
726} // namespace openvdb
727
728#endif // OPENVDB_TOOLS_VALUETRANSFORMER_HAS_BEEN_INCLUDED
ValueT value
Definition: GridBuilder.h:1287
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
Definition: ValueTransformer.h:348
CopyableOpApplier(const CopyableOpApplier &other)
Definition: ValueTransformer.h:356
typename tree::IteratorRange< IterT > IterRange
Definition: ValueTransformer.h:350
CopyableOpApplier(const IterT &iter, const OpT &op)
Definition: ValueTransformer.h:352
void process(bool threaded=true)
Definition: ValueTransformer.h:359
void operator()(IterRange &r) const
Definition: ValueTransformer.h:369
CopyableOpTransformer(CopyableOpTransformer &other, tbb::split)
Definition: ValueTransformer.h:519
~CopyableOpTransformer()
Definition: ValueTransformer.h:529
typename InIterT::TreeT InTreeT
Definition: ValueTransformer.h:497
void join(const CopyableOpTransformer &other)
Definition: ValueTransformer.h:564
typename OutTreeT::ValueType OutValueT
Definition: ValueTransformer.h:499
void operator()(IterRange &range)
Transform each element in the given range.
Definition: ValueTransformer.h:555
void process(bool threaded=true)
Definition: ValueTransformer.h:539
CopyableOpTransformer(const InIterT &inIter, OutTreeT &outTree, const OpT &op, MergePolicy merge)
Definition: ValueTransformer.h:501
typename tree::IteratorRange< InIterT > IterRange
Definition: ValueTransformer.h:498
Definition: ValueTransformer.h:628
void operator()(IterRange &r)
Definition: ValueTransformer.h:664
typename tree::IteratorRange< IterT > IterRange
Definition: ValueTransformer.h:630
OpAccumulator(const IterT &iter, OpT &op)
Definition: ValueTransformer.h:636
void join(OpAccumulator &other)
Definition: ValueTransformer.h:666
OpAccumulator(OpAccumulator &other, tbb::split)
Definition: ValueTransformer.h:645
void process(bool threaded=true)
Definition: ValueTransformer.h:654
~OpAccumulator()
Definition: ValueTransformer.h:652
Definition: ValueTransformer.h:322
typename tree::IteratorRange< IterT > IterRange
Definition: ValueTransformer.h:324
SharedOpApplier(const IterT &iter, OpT &op)
Definition: ValueTransformer.h:326
void process(bool threaded=true)
Definition: ValueTransformer.h:328
void operator()(IterRange &r) const
Definition: ValueTransformer.h:338
Definition: ValueTransformer.h:411
SharedOpTransformer(SharedOpTransformer &other, tbb::split)
Splitting constructor.
Definition: ValueTransformer.h:432
SharedOpTransformer(const InIterT &inIter, OutTreeT &outTree, OpT &op, MergePolicy merge)
Definition: ValueTransformer.h:417
typename InIterT::TreeT InTreeT
Definition: ValueTransformer.h:413
typename OutTreeT::ValueType OutValueT
Definition: ValueTransformer.h:415
void process(bool threaded=true)
Definition: ValueTransformer.h:451
~SharedOpTransformer()
Definition: ValueTransformer.h:441
void join(const SharedOpTransformer &other)
Definition: ValueTransformer.h:476
void operator()(IterRange &range) const
Transform each element in the given range.
Definition: ValueTransformer.h:467
typename tree::IteratorRange< InIterT > IterRange
Definition: ValueTransformer.h:414
Definition: TreeIterator.h:1303
Definition: ValueAccessor.h:183
#define OPENVDB_LOG_INFO(message)
Log an info message of the form 'someVar << "some text" << ...'.
Definition: logging.h:254
void transformValues(const InIterT &inIter, OutGridT &outGrid, const XformOp &op, bool threaded=true, bool shareOp=true, MergePolicy merge=MERGE_ACTIVE_STATES)
Definition: ValueTransformer.h:608
void setValueOnMult(TreeT &tree, const Coord &xyz, const typename TreeT::ValueType &value)
Set the value of the voxel at the given coordinates in tree to the product of its current value and v...
Definition: ValueTransformer.h:309
void setValueOnMax(TreeT &tree, const Coord &xyz, const typename TreeT::ValueType &value)
Set the value of the voxel at the given coordinates in tree to the maximum of its current value and v...
Definition: ValueTransformer.h:293
void accumulate(const IterT &iter, XformOp &op, bool threaded=true)
Definition: ValueTransformer.h:683
void setValueOnSum(TreeT &tree, const Coord &xyz, const typename TreeT::ValueType &value)
Set the value of the voxel at the given coordinates in tree to the sum of its current value and value...
Definition: ValueTransformer.h:301
void setValueOnMin(TreeT &tree, const Coord &xyz, const typename TreeT::ValueType &value)
Set the value of the voxel at the given coordinates in tree to the minimum of its current value and v...
Definition: ValueTransformer.h:285
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:69
MergePolicy
Definition: Types.h:388
@ MERGE_ACTIVE_STATES
Definition: Types.h:389
Definition: Exceptions.h:13
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:1071
Definition: ValueTransformer.h:244
MaxOp(const ValueType &v)
Definition: ValueTransformer.h:246
void operator()(ValueType &v) const
Definition: ValueTransformer.h:247
const ValueType val
Definition: ValueTransformer.h:245
Definition: ValueTransformer.h:237
MinOp(const ValueType &v)
Definition: ValueTransformer.h:239
void operator()(ValueType &v) const
Definition: ValueTransformer.h:240
const ValueType val
Definition: ValueTransformer.h:238
MultOp(const ValueType &v)
Definition: ValueTransformer.h:276
void operator()(ValueType &v) const
Definition: ValueTransformer.h:277
const ValueType val
Definition: ValueTransformer.h:275
bool ValueType
Definition: ValueTransformer.h:274
Definition: ValueTransformer.h:266
MultOp(const ValueType &v)
Definition: ValueTransformer.h:268
void operator()(ValueType &v) const
Definition: ValueTransformer.h:269
const ValueType val
Definition: ValueTransformer.h:267
void operator()(ValueType &v) const
Definition: ValueTransformer.h:262
const ValueType val
Definition: ValueTransformer.h:260
bool ValueType
Definition: ValueTransformer.h:259
SumOp(const ValueType &v)
Definition: ValueTransformer.h:261
Definition: ValueTransformer.h:251
void operator()(ValueType &v) const
Definition: ValueTransformer.h:254
const ValueType val
Definition: ValueTransformer.h:252
SumOp(const ValueType &v)
Definition: ValueTransformer.h:253
#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
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition: version.h.in:150