OpenVDB 10.0.1
Loading...
Searching...
No Matches
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, openvdb::math::pi<double>()/4.0)));
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,
140 MergePolicy merge = MERGE_ACTIVE_STATES);
141
142template<typename InIterT, typename OutGridT, typename XformOp>
143inline void transformValues(const InIterT& inIter, OutGridT& outGrid,
144 const XformOp& op, bool threaded = true, bool shareOp = true,
145 MergePolicy merge = MERGE_ACTIVE_STATES);
146
147
148/// Iterate over a grid and at each step call @c op(iter). If threading is enabled,
149/// call @c op.join(otherOp) to accumulate intermediate results from pairs of threads.
150/// @param iter an iterator over a grid or its tree (@c Grid::ValueOnCIter,
151/// @c Tree::NodeIter, etc.)
152/// @param op a functor with a join method of the form <tt>void join(XformOp&)</tt>
153/// and a call method of the form <tt>void op(const IterT&)</tt>,
154/// where @c IterT is the type of @a iter
155/// @param threaded if true, transform multiple values of the grid in parallel
156/// @note If @a threaded is true, each thread gets its own copy of the @e original functor.
157/// The order in which threads are joined is unspecified.
158/// @note If @a threaded is false, the join method is never called.
159///
160/// @par Example:
161/// Compute the average of the active values of a scalar, floating-point grid
162/// using the math::Stats class.
163/// @code
164/// namespace {
165/// struct Average {
166/// math::Stats stats;
167///
168/// // Accumulate voxel and tile values into this functor's Stats object.
169/// inline void operator()(const FloatGrid::ValueOnCIter& iter) {
170/// if (iter.isVoxelValue()) stats.add(*iter);
171/// else stats.add(*iter, iter.getVoxelCount());
172/// }
173///
174/// // Accumulate another functor's Stats object into this functor's.
175/// inline void join(Average& other) { stats.add(other.stats); }
176///
177/// // Return the cumulative result.
178/// inline double average() const { return stats.mean(); }
179/// };
180/// }
181/// {
182/// FloatGrid grid = ...;
183/// Average op;
184/// tools::accumulate(grid.cbeginValueOn(), op);
185/// double average = op.average();
186/// }
187/// @endcode
188///
189/// @note For more complex operations that require finer control over threading,
190/// consider using @c tbb::parallel_for() or @c tbb::parallel_reduce() in conjunction
191/// with a tree::IteratorRange that wraps a grid or tree iterator.
192template<typename IterT, typename XformOp>
193inline void accumulate(const IterT& iter, XformOp& op, bool threaded = true);
194
195
196/// @brief Set the value of the voxel at the given coordinates in @a tree to
197/// the minimum of its current value and @a value, and mark the voxel as active.
198/// @details This is typically significantly faster than calling getValue()
199/// followed by setValueOn().
200/// @note @a TreeT can be either a Tree or a ValueAccessor.
201template<typename TreeT>
202void setValueOnMin(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value);
203
204/// @brief Set the value of the voxel at the given coordinates in @a tree to
205/// the maximum of its current value and @a value, and mark the voxel as active.
206/// @details This is typically significantly faster than calling getValue()
207/// followed by setValueOn().
208/// @note @a TreeT can be either a Tree or a ValueAccessor.
209template<typename TreeT>
210void setValueOnMax(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value);
211
212/// @brief Set the value of the voxel at the given coordinates in @a tree to
213/// the sum of its current value and @a value, and mark the voxel as active.
214/// @details This is typically significantly faster than calling getValue()
215/// followed by setValueOn().
216/// @note @a TreeT can be either a Tree or a ValueAccessor.
217template<typename TreeT>
218void setValueOnSum(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value);
219
220/// @brief Set the value of the voxel at the given coordinates in @a tree to
221/// the product of its current value and @a value, and mark the voxel as active.
222/// @details This is typically significantly faster than calling getValue()
223/// followed by setValueOn().
224/// @note @a TreeT can be either a Tree or a ValueAccessor.
225template<typename TreeT>
226void setValueOnMult(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value);
227
228
229////////////////////////////////////////
230
231
232namespace valxform {
233
234template<typename ValueType>
235struct MinOp {
236 const ValueType val;
237 MinOp(const ValueType& v): val(v) {}
238 inline void operator()(ValueType& v) const { v = std::min<ValueType>(v, val); }
239};
240
241template<typename ValueType>
242struct MaxOp {
243 const ValueType val;
244 MaxOp(const ValueType& v): val(v) {}
245 inline void operator()(ValueType& v) const { v = std::max<ValueType>(v, val); }
246};
247
248template<typename ValueType>
249struct SumOp {
250 const ValueType val;
251 SumOp(const ValueType& v): val(v) {}
252 inline void operator()(ValueType& v) const { v += val; }
253};
254
255template<>
256struct SumOp<bool> {
257 using ValueType = bool;
259 SumOp(const ValueType& v): val(v) {}
260 inline void operator()(ValueType& v) const { v = v || val; }
261};
262
263template<typename ValueType>
264struct MultOp {
265 const ValueType val;
266 MultOp(const ValueType& v): val(v) {}
267 inline void operator()(ValueType& v) const { v *= val; }
268};
269
270template<>
271struct MultOp<bool> {
272 using ValueType = bool;
274 MultOp(const ValueType& v): val(v) {}
275 inline void operator()(ValueType& v) const { v = v && val; }
276};
277
278}
279
280
281template<typename TreeT>
282void
283setValueOnMin(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
284{
286}
287
288
289template<typename TreeT>
290void
291setValueOnMax(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
292{
294}
295
296
297template<typename TreeT>
298void
299setValueOnSum(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
300{
302}
303
304
305template<typename TreeT>
306void
307setValueOnMult(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
308{
310}
311
312
313////////////////////////////////////////
314
315
316namespace valxform {
317
318template<typename IterT, typename OpT>
320{
321public:
323
324 SharedOpApplier(const IterT& iter, OpT& op): mIter(iter), mOp(op) {}
325
326 void process(bool threaded = true)
327 {
328 IterRange range(mIter);
329 if (threaded) {
330 tbb::parallel_for(range, *this);
331 } else {
332 (*this)(range);
333 }
334 }
335
336 void operator()(IterRange& r) const { for ( ; r; ++r) mOp(r.iterator()); }
337
338private:
339 IterT mIter;
340 OpT& mOp;
341};
342
343
344template<typename IterT, typename OpT>
346{
347public:
349
350 CopyableOpApplier(const IterT& iter, const OpT& op): mIter(iter), mOp(op), mOrigOp(&op) {}
351
352 // When splitting this task, give the subtask a copy of the original functor,
353 // not of this task's functor, which might have been modified arbitrarily.
355 mIter(other.mIter), mOp(*other.mOrigOp), mOrigOp(other.mOrigOp) {}
356
357 void process(bool threaded = true)
358 {
359 IterRange range(mIter);
360 if (threaded) {
361 tbb::parallel_for(range, *this);
362 } else {
363 (*this)(range);
364 }
365 }
366
367 void operator()(IterRange& r) const { for ( ; r; ++r) mOp(r.iterator()); }
368
369private:
370 IterT mIter;
371 OpT mOp; // copy of original functor
372 OpT const * const mOrigOp; // pointer to original functor
373};
374
375} // namespace valxform
376
377
378template<typename IterT, typename XformOp>
379inline void
380foreach(const IterT& iter, XformOp& op, bool threaded, bool shared)
381{
382 if (shared) {
383 typename valxform::SharedOpApplier<IterT, XformOp> proc(iter, op);
384 proc.process(threaded);
385 } else {
386 using Processor = typename valxform::CopyableOpApplier<IterT, XformOp>;
387 Processor proc(iter, op);
388 proc.process(threaded);
389 }
390}
391
392template<typename IterT, typename XformOp>
393inline void
394foreach(const IterT& iter, const XformOp& op, bool threaded, bool /*shared*/)
395{
396 // Const ops are shared across threads, not copied.
398 proc.process(threaded);
399}
400
401
402////////////////////////////////////////
403
404
405namespace valxform {
406
407template<typename InIterT, typename OutTreeT, typename OpT>
409{
410public:
411 using InTreeT = typename InIterT::TreeT;
413 using OutValueT = typename OutTreeT::ValueType;
414
415 SharedOpTransformer(const InIterT& inIter, OutTreeT& outTree, OpT& op, MergePolicy merge):
416 mIsRoot(true),
417 mInputIter(inIter),
418 mInputTree(inIter.getTree()),
419 mOutputTree(&outTree),
420 mOp(op),
421 mMergePolicy(merge)
422 {
423 if (static_cast<const void*>(mInputTree) == static_cast<void*>(mOutputTree)) {
424 OPENVDB_LOG_INFO("use tools::foreach(), not transformValues(),"
425 " to transform a grid in place");
426 }
427 }
428
429 /// Splitting constructor
431 mIsRoot(false),
432 mInputIter(other.mInputIter),
433 mInputTree(other.mInputTree),
434 mOutputTree(new OutTreeT(zeroVal<OutValueT>())),
435 mOp(other.mOp),
436 mMergePolicy(other.mMergePolicy)
437 {}
438
440 {
441 // Delete the output tree only if it was allocated locally
442 // (the top-level output tree was supplied by the caller).
443 if (!mIsRoot) {
444 delete mOutputTree;
445 mOutputTree = nullptr;
446 }
447 }
448
449 void process(bool threaded = true)
450 {
451 if (!mInputTree || !mOutputTree) return;
452
453 IterRange range(mInputIter);
454
455 // Independently transform elements in the iterator range,
456 // either in parallel or serially.
457 if (threaded) {
458 tbb::parallel_reduce(range, *this);
459 } else {
460 (*this)(range);
461 }
462 }
463
464 /// Transform each element in the given range.
465 void operator()(IterRange& range) const
466 {
467 if (!mOutputTree) return;
468 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
469 for ( ; range; ++range) {
470 mOp(range.iterator(), outAccessor);
471 }
472 }
473
474 void join(const SharedOpTransformer& other)
475 {
476 if (mOutputTree && other.mOutputTree) {
477 mOutputTree->merge(*other.mOutputTree, mMergePolicy);
478 }
479 }
480
481private:
482 bool mIsRoot;
483 InIterT mInputIter;
484 const InTreeT* mInputTree;
485 OutTreeT* mOutputTree;
486 OpT& mOp;
487 MergePolicy mMergePolicy;
488}; // class SharedOpTransformer
489
490
491template<typename InIterT, typename OutTreeT, typename OpT>
493{
494public:
495 using InTreeT = typename InIterT::TreeT;
497 using OutValueT = typename OutTreeT::ValueType;
498
499 CopyableOpTransformer(const InIterT& inIter, OutTreeT& outTree,
500 const OpT& op, MergePolicy merge):
501 mIsRoot(true),
502 mInputIter(inIter),
503 mInputTree(inIter.getTree()),
504 mOutputTree(&outTree),
505 mOp(op),
506 mOrigOp(&op),
507 mMergePolicy(merge)
508 {
509 if (static_cast<const void*>(mInputTree) == static_cast<void*>(mOutputTree)) {
510 OPENVDB_LOG_INFO("use tools::foreach(), not transformValues(),"
511 " to transform a grid in place");
512 }
513 }
514
515 // When splitting this task, give the subtask a copy of the original functor,
516 // not of this task's functor, which might have been modified arbitrarily.
518 mIsRoot(false),
519 mInputIter(other.mInputIter),
520 mInputTree(other.mInputTree),
521 mOutputTree(new OutTreeT(zeroVal<OutValueT>())),
522 mOp(*other.mOrigOp),
523 mOrigOp(other.mOrigOp),
524 mMergePolicy(other.mMergePolicy)
525 {}
526
528 {
529 // Delete the output tree only if it was allocated locally
530 // (the top-level output tree was supplied by the caller).
531 if (!mIsRoot) {
532 delete mOutputTree;
533 mOutputTree = nullptr;
534 }
535 }
536
537 void process(bool threaded = true)
538 {
539 if (!mInputTree || !mOutputTree) return;
540
541 IterRange range(mInputIter);
542
543 // Independently transform elements in the iterator range,
544 // either in parallel or serially.
545 if (threaded) {
546 tbb::parallel_reduce(range, *this);
547 } else {
548 (*this)(range);
549 }
550 }
551
552 /// Transform each element in the given range.
554 {
555 if (!mOutputTree) return;
556 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
557 for ( ; range; ++range) {
558 mOp(range.iterator(), outAccessor);
559 }
560 }
561
562 void join(const CopyableOpTransformer& other)
563 {
564 if (mOutputTree && other.mOutputTree) {
565 mOutputTree->merge(*other.mOutputTree, mMergePolicy);
566 }
567 }
568
569private:
570 bool mIsRoot;
571 InIterT mInputIter;
572 const InTreeT* mInputTree;
573 OutTreeT* mOutputTree;
574 OpT mOp; // copy of original functor
575 OpT const * const mOrigOp; // pointer to original functor
576 MergePolicy mMergePolicy;
577}; // class CopyableOpTransformer
578
579} // namespace valxform
580
581
582////////////////////////////////////////
583
584
585template<typename InIterT, typename OutGridT, typename XformOp>
586inline void
587transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op,
588 bool threaded, bool shared, MergePolicy merge)
589{
590 using Adapter = TreeAdapter<OutGridT>;
591 using OutTreeT = typename Adapter::TreeType;
592 if (shared) {
594 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
595 proc.process(threaded);
596 } else {
598 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
599 proc.process(threaded);
600 }
601}
602
603template<typename InIterT, typename OutGridT, typename XformOp>
604inline void
605transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op,
606 bool threaded, bool /*share*/, MergePolicy merge)
607{
608 using Adapter = TreeAdapter<OutGridT>;
609 using OutTreeT = typename Adapter::TreeType;
610 // Const ops are shared across threads, not copied.
612 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
613 proc.process(threaded);
614}
615
616
617////////////////////////////////////////
618
619
620namespace valxform {
621
622template<typename IterT, typename OpT>
624{
625public:
627
628 // The root task makes a const copy of the original functor (mOrigOp)
629 // and keeps a pointer to the original functor (mOp), which it then modifies.
630 // Each subtask keeps a const pointer to the root task's mOrigOp
631 // and makes and then modifies a non-const copy (mOp) of it.
632 OpAccumulator(const IterT& iter, OpT& op):
633 mIsRoot(true),
634 mIter(iter),
635 mOp(&op),
636 mOrigOp(new OpT(op))
637 {}
638
639 // When splitting this task, give the subtask a copy of the original functor,
640 // not of this task's functor, which might have been modified arbitrarily.
641 OpAccumulator(OpAccumulator& other, tbb::split):
642 mIsRoot(false),
643 mIter(other.mIter),
644 mOp(new OpT(*other.mOrigOp)),
645 mOrigOp(other.mOrigOp)
646 {}
647
648 ~OpAccumulator() { if (mIsRoot) delete mOrigOp; else delete mOp; }
649
650 void process(bool threaded = true)
651 {
652 IterRange range(mIter);
653 if (threaded) {
654 tbb::parallel_reduce(range, *this);
655 } else {
656 (*this)(range);
657 }
658 }
659
660 void operator()(IterRange& r) { for ( ; r; ++r) (*mOp)(r.iterator()); }
661
662 void join(OpAccumulator& other) { mOp->join(*other.mOp); }
663
664private:
665 const bool mIsRoot;
666 const IterT mIter;
667 OpT* mOp; // pointer to original functor, which might get modified
668 OpT const * const mOrigOp; // const copy of original functor
669}; // class OpAccumulator
670
671} // namespace valxform
672
673
674////////////////////////////////////////
675
676
677template<typename IterT, typename XformOp>
678inline void
679accumulate(const IterT& iter, XformOp& op, bool threaded)
680{
681 typename valxform::OpAccumulator<IterT, XformOp> proc(iter, op);
682 proc.process(threaded);
683}
684
685
686////////////////////////////////////////
687
688
689// Explicit Template Instantiation
690
691#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
692
693#ifdef OPENVDB_INSTANTIATE_VALUETRANSFORMER
695#endif
696
697#define _FUNCTION(TreeT) \
698 void setValueOnMin(TreeT&, const Coord&, const TreeT::ValueType&)
700#undef _FUNCTION
701
702#define _FUNCTION(TreeT) \
703 void setValueOnMax(TreeT&, const Coord&, const TreeT::ValueType&)
705#undef _FUNCTION
706
707#define _FUNCTION(TreeT) \
708 void setValueOnSum(TreeT&, const Coord&, const TreeT::ValueType&)
710#undef _FUNCTION
711
712#define _FUNCTION(TreeT) \
713 void setValueOnMult(TreeT&, const Coord&, const TreeT::ValueType&)
715#undef _FUNCTION
716
717#endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
718
719
720} // namespace tools
721} // namespace OPENVDB_VERSION_NAME
722} // namespace openvdb
723
724#endif // OPENVDB_TOOLS_VALUETRANSFORMER_HAS_BEEN_INCLUDED
ValueT value
Definition: GridBuilder.h:1290
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
Definition: ValueTransformer.h:346
CopyableOpApplier(const CopyableOpApplier &other)
Definition: ValueTransformer.h:354
typename tree::IteratorRange< IterT > IterRange
Definition: ValueTransformer.h:348
CopyableOpApplier(const IterT &iter, const OpT &op)
Definition: ValueTransformer.h:350
void process(bool threaded=true)
Definition: ValueTransformer.h:357
void operator()(IterRange &r) const
Definition: ValueTransformer.h:367
CopyableOpTransformer(CopyableOpTransformer &other, tbb::split)
Definition: ValueTransformer.h:517
~CopyableOpTransformer()
Definition: ValueTransformer.h:527
typename InIterT::TreeT InTreeT
Definition: ValueTransformer.h:495
void join(const CopyableOpTransformer &other)
Definition: ValueTransformer.h:562
typename OutTreeT::ValueType OutValueT
Definition: ValueTransformer.h:497
void operator()(IterRange &range)
Transform each element in the given range.
Definition: ValueTransformer.h:553
void process(bool threaded=true)
Definition: ValueTransformer.h:537
CopyableOpTransformer(const InIterT &inIter, OutTreeT &outTree, const OpT &op, MergePolicy merge)
Definition: ValueTransformer.h:499
typename tree::IteratorRange< InIterT > IterRange
Definition: ValueTransformer.h:496
Definition: ValueTransformer.h:624
void operator()(IterRange &r)
Definition: ValueTransformer.h:660
typename tree::IteratorRange< IterT > IterRange
Definition: ValueTransformer.h:626
OpAccumulator(const IterT &iter, OpT &op)
Definition: ValueTransformer.h:632
void join(OpAccumulator &other)
Definition: ValueTransformer.h:662
OpAccumulator(OpAccumulator &other, tbb::split)
Definition: ValueTransformer.h:641
void process(bool threaded=true)
Definition: ValueTransformer.h:650
~OpAccumulator()
Definition: ValueTransformer.h:648
Definition: ValueTransformer.h:320
typename tree::IteratorRange< IterT > IterRange
Definition: ValueTransformer.h:322
SharedOpApplier(const IterT &iter, OpT &op)
Definition: ValueTransformer.h:324
void process(bool threaded=true)
Definition: ValueTransformer.h:326
void operator()(IterRange &r) const
Definition: ValueTransformer.h:336
SharedOpTransformer(SharedOpTransformer &other, tbb::split)
Splitting constructor.
Definition: ValueTransformer.h:430
SharedOpTransformer(const InIterT &inIter, OutTreeT &outTree, OpT &op, MergePolicy merge)
Definition: ValueTransformer.h:415
typename InIterT::TreeT InTreeT
Definition: ValueTransformer.h:411
typename OutTreeT::ValueType OutValueT
Definition: ValueTransformer.h:413
void process(bool threaded=true)
Definition: ValueTransformer.h:449
~SharedOpTransformer()
Definition: ValueTransformer.h:439
void join(const SharedOpTransformer &other)
Definition: ValueTransformer.h:474
void operator()(IterRange &range) const
Transform each element in the given range.
Definition: ValueTransformer.h:465
typename tree::IteratorRange< InIterT > IterRange
Definition: ValueTransformer.h:412
Definition: TreeIterator.h:1303
Definition: ValueAccessor.h:191
#define OPENVDB_LOG_INFO(message)
Log an info message of the form 'someVar << "some text" << ...'.
Definition: logging.h:254
PromoteType< ValueT >::Highest accumulate(const PointDataTreeT &points, const std::string &attribute, const FilterT &filter=NullFilter())
Evaluates the total value of a point attribute.
Definition: PointStatistics.h:729
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:307
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:291
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:299
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:283
void transformValues(const InIterT &inIter, OutGridT &outGrid, XformOp &op, bool threaded=true, bool shareOp=true, MergePolicy merge=MERGE_ACTIVE_STATES)
Definition: ValueTransformer.h:587
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:70
MergePolicy
Definition: Types.h:467
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:1060
Definition: ValueTransformer.h:242
MaxOp(const ValueType &v)
Definition: ValueTransformer.h:244
void operator()(ValueType &v) const
Definition: ValueTransformer.h:245
const ValueType val
Definition: ValueTransformer.h:243
Definition: ValueTransformer.h:235
MinOp(const ValueType &v)
Definition: ValueTransformer.h:237
void operator()(ValueType &v) const
Definition: ValueTransformer.h:238
const ValueType val
Definition: ValueTransformer.h:236
MultOp(const ValueType &v)
Definition: ValueTransformer.h:274
void operator()(ValueType &v) const
Definition: ValueTransformer.h:275
const ValueType val
Definition: ValueTransformer.h:273
bool ValueType
Definition: ValueTransformer.h:272
Definition: ValueTransformer.h:264
MultOp(const ValueType &v)
Definition: ValueTransformer.h:266
void operator()(ValueType &v) const
Definition: ValueTransformer.h:267
const ValueType val
Definition: ValueTransformer.h:265
void operator()(ValueType &v) const
Definition: ValueTransformer.h:260
const ValueType val
Definition: ValueTransformer.h:258
bool ValueType
Definition: ValueTransformer.h:257
SumOp(const ValueType &v)
Definition: ValueTransformer.h:259
Definition: ValueTransformer.h:249
void operator()(ValueType &v) const
Definition: ValueTransformer.h:252
const ValueType val
Definition: ValueTransformer.h:250
SumOp(const ValueType &v)
Definition: ValueTransformer.h:251
#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:212
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition: version.h.in:160