OpenVDB 13.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: 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/// @brief 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/// @brief 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,
141 MergePolicy merge = MERGE_ACTIVE_STATES);
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,
147 MergePolicy merge = MERGE_ACTIVE_STATES);
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 {
241 if (math::cwiseLessThan(val, v)) v = val;
242 }
243};
244
245template<typename ValueType>
246struct MaxOp {
247 const ValueType val;
248 MaxOp(const ValueType& v): val(v) {}
249 inline void operator()(ValueType& v) const {
250 if (math::cwiseGreaterThan(val, v)) v = val;
251 }
252};
253
254template<typename ValueType>
255struct SumOp {
256 const ValueType val;
257 SumOp(const ValueType& v): val(v) {}
258 inline void operator()(ValueType& v) const { v += val; }
259};
260
261template<>
262struct SumOp<bool> {
263 using ValueType = bool;
265 SumOp(const ValueType& v): val(v) {}
266 inline void operator()(ValueType& v) const { v = v || val; }
267};
268
269template<typename ValueType>
270struct MultOp {
271 const ValueType val;
272 MultOp(const ValueType& v): val(v) {}
273 inline void operator()(ValueType& v) const { v *= val; }
274};
275
276template<>
277struct MultOp<bool> {
278 using ValueType = bool;
280 MultOp(const ValueType& v): val(v) {}
281 inline void operator()(ValueType& v) const { v = v && val; }
282};
283
284}
285
286
287template<typename TreeT>
288void
289setValueOnMin(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
290{
291 tree.modifyValue(xyz, valxform::MinOp<typename TreeT::ValueType>(value));
292}
293
294
295template<typename TreeT>
296void
297setValueOnMax(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
298{
299 tree.modifyValue(xyz, valxform::MaxOp<typename TreeT::ValueType>(value));
300}
301
302
303template<typename TreeT>
304void
305setValueOnSum(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
306{
307 tree.modifyValue(xyz, valxform::SumOp<typename TreeT::ValueType>(value));
308}
309
310
311template<typename TreeT>
312void
313setValueOnMult(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
314{
315 tree.modifyValue(xyz, valxform::MultOp<typename TreeT::ValueType>(value));
316}
317
318
319////////////////////////////////////////
320
321
322namespace valxform {
323
324template<typename IterT, typename OpT>
326{
327public:
329
330 SharedOpApplier(const IterT& iter, OpT& op): mIter(iter), mOp(op) {}
331
332 void process(bool threaded = true)
333 {
334 IterRange range(mIter);
335 if (threaded) {
336 tbb::parallel_for(range, *this);
337 } else {
338 (*this)(range);
339 }
340 }
341
342 void operator()(IterRange& r) const { for ( ; r; ++r) mOp(r.iterator()); }
343
344private:
345 IterT mIter;
346 OpT& mOp;
347};
348
349
350template<typename IterT, typename OpT>
352{
353public:
355
356 CopyableOpApplier(const IterT& iter, const OpT& op): mIter(iter), mOp(op), mOrigOp(&op) {}
357
358 // When splitting this task, give the subtask a copy of the original functor,
359 // not of this task's functor, which might have been modified arbitrarily.
361 mIter(other.mIter), mOp(*other.mOrigOp), mOrigOp(other.mOrigOp) {}
362
363 void process(bool threaded = true)
364 {
365 IterRange range(mIter);
366 if (threaded) {
367 tbb::parallel_for(range, *this);
368 } else {
369 (*this)(range);
370 }
371 }
372
373 void operator()(IterRange& r) const { for ( ; r; ++r) mOp(r.iterator()); }
374
375private:
376 IterT mIter;
377 OpT mOp; // copy of original functor
378 OpT const * const mOrigOp; // pointer to original functor
379};
380
381} // namespace valxform
382
383
384template<typename IterT, typename XformOp>
385inline void
386foreach(const IterT& iter, XformOp& op, bool threaded, bool shared)
387{
388 if (shared) {
389 typename valxform::SharedOpApplier<IterT, XformOp> proc(iter, op);
390 proc.process(threaded);
391 } else {
392 using Processor = typename valxform::CopyableOpApplier<IterT, XformOp>;
393 Processor proc(iter, op);
394 proc.process(threaded);
395 }
396}
397
398template<typename IterT, typename XformOp>
399inline void
400foreach(const IterT& iter, const XformOp& op, bool threaded, bool /*shared*/)
401{
402 // Const ops are shared across threads, not copied.
404 proc.process(threaded);
405}
406
407
408////////////////////////////////////////
409
410
411namespace valxform {
412
413template<typename InIterT, typename OutTreeT, typename OpT>
415{
416public:
417 using InTreeT = typename InIterT::TreeT;
419 using OutValueT = typename OutTreeT::ValueType;
420
421 SharedOpTransformer(const InIterT& inIter, OutTreeT& outTree, OpT& op, MergePolicy merge):
422 mIsRoot(true),
423 mInputIter(inIter),
424 mInputTree(inIter.getTree()),
425 mOutputTree(&outTree),
426 mOp(op),
427 mMergePolicy(merge)
428 {
429 if (static_cast<const void*>(mInputTree) == static_cast<void*>(mOutputTree)) {
430 OPENVDB_LOG_INFO("use tools::foreach(), not transformValues(),"
431 " to transform a grid in place");
432 }
433 }
434
435 /// Splitting constructor
437 mIsRoot(false),
438 mInputIter(other.mInputIter),
439 mInputTree(other.mInputTree),
440 mOutputTree(new OutTreeT(zeroVal<OutValueT>())),
441 mOp(other.mOp),
442 mMergePolicy(other.mMergePolicy)
443 {}
444
446 {
447 // Delete the output tree only if it was allocated locally
448 // (the top-level output tree was supplied by the caller).
449 if (!mIsRoot) {
450 delete mOutputTree;
451 mOutputTree = nullptr;
452 }
453 }
454
455 void process(bool threaded = true)
456 {
457 if (!mInputTree || !mOutputTree) return;
458
459 IterRange range(mInputIter);
460
461 // Independently transform elements in the iterator range,
462 // either in parallel or serially.
463 if (threaded) {
464 tbb::parallel_reduce(range, *this);
465 } else {
466 (*this)(range);
467 }
468 }
469
470 /// Transform each element in the given range.
471 void operator()(const IterRange& range) const
472 {
473 if (!mOutputTree) return;
474 IterRange r(range);
475 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
476 for ( ; r; ++r) {
477 mOp(r.iterator(), outAccessor);
478 }
479 }
480
481 void join(const SharedOpTransformer& other)
482 {
483 if (mOutputTree && other.mOutputTree) {
484 mOutputTree->merge(*other.mOutputTree, mMergePolicy);
485 }
486 }
487
488private:
489 bool mIsRoot;
490 InIterT mInputIter;
491 const InTreeT* mInputTree;
492 OutTreeT* mOutputTree;
493 OpT& mOp;
494 MergePolicy mMergePolicy;
495}; // class SharedOpTransformer
496
497
498template<typename InIterT, typename OutTreeT, typename OpT>
500{
501public:
502 using InTreeT = typename InIterT::TreeT;
504 using OutValueT = typename OutTreeT::ValueType;
505
506 CopyableOpTransformer(const InIterT& inIter, OutTreeT& outTree,
507 const OpT& op, MergePolicy merge):
508 mIsRoot(true),
509 mInputIter(inIter),
510 mInputTree(inIter.getTree()),
511 mOutputTree(&outTree),
512 mOp(op),
513 mOrigOp(&op),
514 mMergePolicy(merge)
515 {
516 if (static_cast<const void*>(mInputTree) == static_cast<void*>(mOutputTree)) {
517 OPENVDB_LOG_INFO("use tools::foreach(), not transformValues(),"
518 " to transform a grid in place");
519 }
520 }
521
522 // When splitting this task, give the subtask a copy of the original functor,
523 // not of this task's functor, which might have been modified arbitrarily.
525 mIsRoot(false),
526 mInputIter(other.mInputIter),
527 mInputTree(other.mInputTree),
528 mOutputTree(new OutTreeT(zeroVal<OutValueT>())),
529 mOp(*other.mOrigOp),
530 mOrigOp(other.mOrigOp),
531 mMergePolicy(other.mMergePolicy)
532 {}
533
535 {
536 // Delete the output tree only if it was allocated locally
537 // (the top-level output tree was supplied by the caller).
538 if (!mIsRoot) {
539 delete mOutputTree;
540 mOutputTree = nullptr;
541 }
542 }
543
544 void process(bool threaded = true)
545 {
546 if (!mInputTree || !mOutputTree) return;
547
548 IterRange range(mInputIter);
549
550 // Independently transform elements in the iterator range,
551 // either in parallel or serially.
552 if (threaded) {
553 tbb::parallel_reduce(range, *this);
554 } else {
555 (*this)(range);
556 }
557 }
558
559 /// Transform each element in the given range.
560 void operator()(const IterRange& range)
561 {
562 if (!mOutputTree) return;
563 IterRange r(range);
564 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
565 for ( ; r; ++r) {
566 mOp(r.iterator(), outAccessor);
567 }
568 }
569
570 void join(const CopyableOpTransformer& other)
571 {
572 if (mOutputTree && other.mOutputTree) {
573 mOutputTree->merge(*other.mOutputTree, mMergePolicy);
574 }
575 }
576
577private:
578 bool mIsRoot;
579 InIterT mInputIter;
580 const InTreeT* mInputTree;
581 OutTreeT* mOutputTree;
582 OpT mOp; // copy of original functor
583 OpT const * const mOrigOp; // pointer to original functor
584 MergePolicy mMergePolicy;
585}; // class CopyableOpTransformer
586
587} // namespace valxform
588
589
590////////////////////////////////////////
591
592
593template<typename InIterT, typename OutGridT, typename XformOp>
594inline OPENVDB_UBSAN_SUPPRESS("undefined")
595void transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op,
596 bool threaded, bool shared, MergePolicy merge)
597{
598 using Adapter = TreeAdapter<OutGridT>;
599 using OutTreeT = typename Adapter::TreeType;
600 if (shared) {
602 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
603 proc.process(threaded);
604 } else {
606 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
607 proc.process(threaded);
608 }
609}
610
611template<typename InIterT, typename OutGridT, typename XformOp>
612inline OPENVDB_UBSAN_SUPPRESS("undefined")
613void transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op,
614 bool threaded, bool /*share*/, MergePolicy merge)
615{
616 using Adapter = TreeAdapter<OutGridT>;
617 using OutTreeT = typename Adapter::TreeType;
618 // Const ops are shared across threads, not copied.
620 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
621 proc.process(threaded);
622}
623
624
625////////////////////////////////////////
626
627
628namespace valxform {
629
630template<typename IterT, typename OpT>
632{
633public:
635
636 // The root task makes a const copy of the original functor (mOrigOp)
637 // and keeps a pointer to the original functor (mOp), which it then modifies.
638 // Each subtask keeps a const pointer to the root task's mOrigOp
639 // and makes and then modifies a non-const copy (mOp) of it.
640 OpAccumulator(const IterT& iter, OpT& op):
641 mIsRoot(true),
642 mIter(iter),
643 mOp(&op),
644 mOrigOp(new OpT(op))
645 {}
646
647 // When splitting this task, give the subtask a copy of the original functor,
648 // not of this task's functor, which might have been modified arbitrarily.
649 OpAccumulator(OpAccumulator& other, tbb::split):
650 mIsRoot(false),
651 mIter(other.mIter),
652 mOp(new OpT(*other.mOrigOp)),
653 mOrigOp(other.mOrigOp)
654 {}
655
656 ~OpAccumulator() { if (mIsRoot) delete mOrigOp; else delete mOp; }
657
658 void process(bool threaded = true)
659 {
660 IterRange range(mIter);
661 if (threaded) {
662 tbb::parallel_reduce(range, *this);
663 } else {
664 (*this)(range);
665 }
666 }
667
668 void operator()(const IterRange& r) { for (IterRange it(r); it.test(); ++it) (*mOp)(it.iterator()); }
669
670 void join(OpAccumulator& other) { mOp->join(*other.mOp); }
671
672private:
673 const bool mIsRoot;
674 const IterT mIter;
675 OpT* mOp; // pointer to original functor, which might get modified
676 OpT const * const mOrigOp; // const copy of original functor
677}; // class OpAccumulator
678
679} // namespace valxform
680
681
682////////////////////////////////////////
683
684
685template<typename IterT, typename XformOp>
686inline void
687accumulate(const IterT& iter, XformOp& op, bool threaded)
688{
689 typename valxform::OpAccumulator<IterT, XformOp> proc(iter, op);
690 proc.process(threaded);
691}
692
693
694////////////////////////////////////////
695
696
697// Explicit Template Instantiation
698
699#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
700
701#ifdef OPENVDB_INSTANTIATE_VALUETRANSFORMER
703#endif
704
705#define _FUNCTION(TreeT) \
706 void setValueOnMin(TreeT&, const Coord&, const TreeT::ValueType&)
708#undef _FUNCTION
709
710#define _FUNCTION(TreeT) \
711 void setValueOnMax(TreeT&, const Coord&, const TreeT::ValueType&)
713#undef _FUNCTION
714
715#define _FUNCTION(TreeT) \
716 void setValueOnSum(TreeT&, const Coord&, const TreeT::ValueType&)
718#undef _FUNCTION
719
720#define _FUNCTION(TreeT) \
721 void setValueOnMult(TreeT&, const Coord&, const TreeT::ValueType&)
723#undef _FUNCTION
724
725#endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
726
727
728} // namespace tools
729} // namespace OPENVDB_VERSION_NAME
730} // namespace openvdb
731
732#endif // OPENVDB_TOOLS_VALUETRANSFORMER_HAS_BEEN_INCLUDED
#define OPENVDB_UBSAN_SUPPRESS(X)
Windows defines.
Definition Platform.h:64
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
CopyableOpApplier(const CopyableOpApplier &other)
Definition ValueTransformer.h:360
typename tree::IteratorRange< IterT > IterRange
Definition ValueTransformer.h:354
CopyableOpApplier(const IterT &iter, const OpT &op)
Definition ValueTransformer.h:356
void process(bool threaded=true)
Definition ValueTransformer.h:363
void operator()(IterRange &r) const
Definition ValueTransformer.h:373
CopyableOpTransformer(CopyableOpTransformer &other, tbb::split)
Definition ValueTransformer.h:524
~CopyableOpTransformer()
Definition ValueTransformer.h:534
typename InIterT::TreeT InTreeT
Definition ValueTransformer.h:502
void join(const CopyableOpTransformer &other)
Definition ValueTransformer.h:570
typename OutTreeT::ValueType OutValueT
Definition ValueTransformer.h:504
void process(bool threaded=true)
Definition ValueTransformer.h:544
CopyableOpTransformer(const InIterT &inIter, OutTreeT &outTree, const OpT &op, MergePolicy merge)
Definition ValueTransformer.h:506
void operator()(const IterRange &range)
Transform each element in the given range.
Definition ValueTransformer.h:560
typename tree::IteratorRange< InIterT > IterRange
Definition ValueTransformer.h:503
Definition ValueTransformer.h:632
typename tree::IteratorRange< IterT > IterRange
Definition ValueTransformer.h:634
OpAccumulator(const IterT &iter, OpT &op)
Definition ValueTransformer.h:640
void join(OpAccumulator &other)
Definition ValueTransformer.h:670
OpAccumulator(OpAccumulator &other, tbb::split)
Definition ValueTransformer.h:649
void process(bool threaded=true)
Definition ValueTransformer.h:658
~OpAccumulator()
Definition ValueTransformer.h:656
void operator()(const IterRange &r)
Definition ValueTransformer.h:668
Definition ValueTransformer.h:326
typename tree::IteratorRange< IterT > IterRange
Definition ValueTransformer.h:328
SharedOpApplier(const IterT &iter, OpT &op)
Definition ValueTransformer.h:330
void process(bool threaded=true)
Definition ValueTransformer.h:332
void operator()(IterRange &r) const
Definition ValueTransformer.h:342
SharedOpTransformer(SharedOpTransformer &other, tbb::split)
Splitting constructor.
Definition ValueTransformer.h:436
SharedOpTransformer(const InIterT &inIter, OutTreeT &outTree, OpT &op, MergePolicy merge)
Definition ValueTransformer.h:421
void operator()(const IterRange &range) const
Transform each element in the given range.
Definition ValueTransformer.h:471
typename InIterT::TreeT InTreeT
Definition ValueTransformer.h:417
typename OutTreeT::ValueType OutValueT
Definition ValueTransformer.h:419
void process(bool threaded=true)
Definition ValueTransformer.h:455
~SharedOpTransformer()
Definition ValueTransformer.h:445
void join(const SharedOpTransformer &other)
Definition ValueTransformer.h:481
typename tree::IteratorRange< InIterT > IterRange
Definition ValueTransformer.h:418
Definition TreeIterator.h:1304
#define OPENVDB_LOG_INFO(message)
Log an info message of the form 'someVar << "some text" << ...'.
Definition logging.h:254
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition Mat.h:1015
bool cwiseGreaterThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition Mat.h:1029
Definition ValueTransformer.h:234
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:313
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:297
void accumulate(const IterT &iter, XformOp &op, bool threaded=true)
Definition ValueTransformer.h:687
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:305
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:289
undefined void transformValues(const InIterT &inIter, OutGridT &outGrid, XformOp &op, bool threaded=true, bool shareOp=true, MergePolicy merge=MERGE_ACTIVE_STATES)
Iterate over a grid and at each step call op(iter, accessor) to populate (via the accessor) the given...
Definition ValueTransformer.h:595
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:71
MergePolicy
Definition Types.h:577
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:1058
Definition ValueTransformer.h:246
MaxOp(const ValueType &v)
Definition ValueTransformer.h:248
void operator()(ValueType &v) const
Definition ValueTransformer.h:249
const ValueType val
Definition ValueTransformer.h:247
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:280
void operator()(ValueType &v) const
Definition ValueTransformer.h:281
const ValueType val
Definition ValueTransformer.h:279
bool ValueType
Definition ValueTransformer.h:278
Definition ValueTransformer.h:270
MultOp(const ValueType &v)
Definition ValueTransformer.h:272
void operator()(ValueType &v) const
Definition ValueTransformer.h:273
const ValueType val
Definition ValueTransformer.h:271
void operator()(ValueType &v) const
Definition ValueTransformer.h:266
const ValueType val
Definition ValueTransformer.h:264
bool ValueType
Definition ValueTransformer.h:263
SumOp(const ValueType &v)
Definition ValueTransformer.h:265
Definition ValueTransformer.h:255
void operator()(ValueType &v) const
Definition ValueTransformer.h:258
const ValueType val
Definition ValueTransformer.h:256
SumOp(const ValueType &v)
Definition ValueTransformer.h:257
#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:284
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition version.h.in:231