OpenVDB 12.0.0
 
Loading...
Searching...
No Matches
ValueTransformer.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-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 OPENVDB_UBSAN_SUPPRESS("undefined")
139void transformValues(const InIterT& inIter, OutGridT& outGrid,
140 XformOp& op, bool threaded = true, bool shareOp = true,
142
143template<typename InIterT, typename OutGridT, typename XformOp>
144inline OPENVDB_UBSAN_SUPPRESS("undefined")
145void transformValues(const InIterT& inIter, OutGridT& outGrid,
146 const XformOp& op, bool threaded = true, bool shareOp = true,
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> {
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> {
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{
287 tree.modifyValue(xyz, valxform::MinOp<typename TreeT::ValueType>(value));
288}
289
290
291template<typename TreeT>
292void
293setValueOnMax(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
294{
295 tree.modifyValue(xyz, valxform::MaxOp<typename TreeT::ValueType>(value));
296}
297
298
299template<typename TreeT>
300void
301setValueOnSum(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
302{
303 tree.modifyValue(xyz, valxform::SumOp<typename TreeT::ValueType>(value));
304}
305
306
307template<typename TreeT>
308void
309setValueOnMult(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
310{
311 tree.modifyValue(xyz, valxform::MultOp<typename TreeT::ValueType>(value));
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) {
386 proc.process(threaded);
387 } else {
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()(const IterRange& range) const
468 {
469 if (!mOutputTree) return;
470 IterRange r(range);
471 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
472 for ( ; r; ++r) {
473 mOp(r.iterator(), outAccessor);
474 }
475 }
476
477 void join(const SharedOpTransformer& other)
478 {
479 if (mOutputTree && other.mOutputTree) {
480 mOutputTree->merge(*other.mOutputTree, mMergePolicy);
481 }
482 }
483
484private:
485 bool mIsRoot;
486 InIterT mInputIter;
487 const InTreeT* mInputTree;
488 OutTreeT* mOutputTree;
489 OpT& mOp;
490 MergePolicy mMergePolicy;
491}; // class SharedOpTransformer
492
493
494template<typename InIterT, typename OutTreeT, typename OpT>
496{
497public:
498 using InTreeT = typename InIterT::TreeT;
500 using OutValueT = typename OutTreeT::ValueType;
501
502 CopyableOpTransformer(const InIterT& inIter, OutTreeT& outTree,
503 const OpT& op, MergePolicy merge):
504 mIsRoot(true),
505 mInputIter(inIter),
506 mInputTree(inIter.getTree()),
507 mOutputTree(&outTree),
508 mOp(op),
509 mOrigOp(&op),
510 mMergePolicy(merge)
511 {
512 if (static_cast<const void*>(mInputTree) == static_cast<void*>(mOutputTree)) {
513 OPENVDB_LOG_INFO("use tools::foreach(), not transformValues(),"
514 " to transform a grid in place");
515 }
516 }
517
518 // When splitting this task, give the subtask a copy of the original functor,
519 // not of this task's functor, which might have been modified arbitrarily.
521 mIsRoot(false),
522 mInputIter(other.mInputIter),
523 mInputTree(other.mInputTree),
524 mOutputTree(new OutTreeT(zeroVal<OutValueT>())),
525 mOp(*other.mOrigOp),
526 mOrigOp(other.mOrigOp),
527 mMergePolicy(other.mMergePolicy)
528 {}
529
531 {
532 // Delete the output tree only if it was allocated locally
533 // (the top-level output tree was supplied by the caller).
534 if (!mIsRoot) {
535 delete mOutputTree;
536 mOutputTree = nullptr;
537 }
538 }
539
540 void process(bool threaded = true)
541 {
542 if (!mInputTree || !mOutputTree) return;
543
544 IterRange range(mInputIter);
545
546 // Independently transform elements in the iterator range,
547 // either in parallel or serially.
548 if (threaded) {
549 tbb::parallel_reduce(range, *this);
550 } else {
551 (*this)(range);
552 }
553 }
554
555 /// Transform each element in the given range.
556 void operator()(const IterRange& range)
557 {
558 if (!mOutputTree) return;
559 IterRange r(range);
560 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
561 for ( ; r; ++r) {
562 mOp(r.iterator(), outAccessor);
563 }
564 }
565
566 void join(const CopyableOpTransformer& other)
567 {
568 if (mOutputTree && other.mOutputTree) {
569 mOutputTree->merge(*other.mOutputTree, mMergePolicy);
570 }
571 }
572
573private:
574 bool mIsRoot;
575 InIterT mInputIter;
576 const InTreeT* mInputTree;
577 OutTreeT* mOutputTree;
578 OpT mOp; // copy of original functor
579 OpT const * const mOrigOp; // pointer to original functor
580 MergePolicy mMergePolicy;
581}; // class CopyableOpTransformer
582
583} // namespace valxform
584
585
586////////////////////////////////////////
587
588
589template<typename InIterT, typename OutGridT, typename XformOp>
590inline OPENVDB_UBSAN_SUPPRESS("undefined")
591void transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op,
593{
594 using Adapter = TreeAdapter<OutGridT>;
595 using OutTreeT = typename Adapter::TreeType;
596 if (shared) {
598 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
599 proc.process(threaded);
600 } else {
601 using Processor = typename valxform::CopyableOpTransformer<InIterT, OutTreeT, XformOp>;
602 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
603 proc.process(threaded);
604 }
605}
606
607template<typename InIterT, typename OutGridT, typename XformOp>
608inline OPENVDB_UBSAN_SUPPRESS("undefined")
609void transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op,
610 bool threaded, bool /*share*/, MergePolicy merge)
611{
612 using Adapter = TreeAdapter<OutGridT>;
613 using OutTreeT = typename Adapter::TreeType;
614 // Const ops are shared across threads, not copied.
616 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
617 proc.process(threaded);
618}
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()(const IterRange& r) { for (IterRange it(r); it.test(); ++it) (*mOp)(it.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{
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
#define OPENVDB_UBSAN_SUPPRESS(X)
SIMD Intrinsic Headers.
Definition Platform.h:77
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
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:520
~CopyableOpTransformer()
Definition ValueTransformer.h:530
typename InIterT::TreeT InTreeT
Definition ValueTransformer.h:498
void join(const CopyableOpTransformer &other)
Definition ValueTransformer.h:566
typename OutTreeT::ValueType OutValueT
Definition ValueTransformer.h:500
void process(bool threaded=true)
Definition ValueTransformer.h:540
CopyableOpTransformer(const InIterT &inIter, OutTreeT &outTree, const OpT &op, MergePolicy merge)
Definition ValueTransformer.h:502
void operator()(const IterRange &range)
Transform each element in the given range.
Definition ValueTransformer.h:556
typename tree::IteratorRange< InIterT > IterRange
Definition ValueTransformer.h:499
Definition ValueTransformer.h:628
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
void operator()(const IterRange &r)
Definition ValueTransformer.h:664
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
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
void operator()(const IterRange &range) const
Transform each element in the given range.
Definition ValueTransformer.h:467
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:477
typename tree::IteratorRange< InIterT > IterRange
Definition ValueTransformer.h:414
Definition TreeIterator.h:1304
#define OPENVDB_LOG_INFO(message)
Log an info message of the form 'someVar << "some text" << ...'.
Definition logging.h:254
Definition ValueTransformer.h:234
Processor proc(inIter, Adapter::tree(outGrid), op, merge)
OPENVDB_UBSAN_SUPPRESS("undefined") void transformValues(const InIterT &inIter
OutGridT const XformOp bool bool
Definition ValueTransformer.h:610
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
OutGridT XformOp & op
Definition ValueTransformer.h:140
OutGridT XformOp bool bool shareOp
Definition ValueTransformer.h:140
OutGridT XformOp bool bool shared
Definition ValueTransformer.h:592
OutGridT & outGrid
Definition ValueTransformer.h:139
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
typename valxform::SharedOpTransformer< InIterT, OutTreeT, const XformOp > Processor
Definition ValueTransformer.h:615
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
OutGridT XformOp bool bool MergePolicy merge
Definition ValueTransformer.h:141
typename Adapter::TreeType OutTreeT
Definition ValueTransformer.h:595
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
OutGridT XformOp bool threaded
Definition ValueTransformer.h:140
Definition PointDataGrid.h:170
ValueAccessorImpl< TreeType, IsSafe, MutexType, openvdb::make_index_sequence< CacheLevels > > ValueAccessor
Default alias for a ValueAccessor. This is simply a helper alias for the generic definition but takes...
Definition ValueAccessor.h:86
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
MergePolicy
Definition Types.h:506
@ MERGE_ACTIVE_STATES
Definition Types.h:507
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: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:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition version.h.in:165