OpenVDB 11.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: 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{
285 tree.modifyValue(xyz, valxform::MinOp<typename TreeT::ValueType>(value));
286}
287
288
289template<typename TreeT>
290void
291setValueOnMax(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
292{
293 tree.modifyValue(xyz, valxform::MaxOp<typename TreeT::ValueType>(value));
294}
295
296
297template<typename TreeT>
298void
299setValueOnSum(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
300{
301 tree.modifyValue(xyz, valxform::SumOp<typename TreeT::ValueType>(value));
302}
303
304
305template<typename TreeT>
306void
307setValueOnMult(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
308{
309 tree.modifyValue(xyz, valxform::MultOp<typename TreeT::ValueType>(value));
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()(const IterRange& range) const
466 {
467 if (!mOutputTree) return;
468 IterRange r(range);
469 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
470 for ( ; r; ++r) {
471 mOp(r.iterator(), outAccessor);
472 }
473 }
474
475 void join(const SharedOpTransformer& other)
476 {
477 if (mOutputTree && other.mOutputTree) {
478 mOutputTree->merge(*other.mOutputTree, mMergePolicy);
479 }
480 }
481
482private:
483 bool mIsRoot;
484 InIterT mInputIter;
485 const InTreeT* mInputTree;
486 OutTreeT* mOutputTree;
487 OpT& mOp;
488 MergePolicy mMergePolicy;
489}; // class SharedOpTransformer
490
491
492template<typename InIterT, typename OutTreeT, typename OpT>
494{
495public:
496 using InTreeT = typename InIterT::TreeT;
498 using OutValueT = typename OutTreeT::ValueType;
499
500 CopyableOpTransformer(const InIterT& inIter, OutTreeT& outTree,
501 const OpT& op, MergePolicy merge):
502 mIsRoot(true),
503 mInputIter(inIter),
504 mInputTree(inIter.getTree()),
505 mOutputTree(&outTree),
506 mOp(op),
507 mOrigOp(&op),
508 mMergePolicy(merge)
509 {
510 if (static_cast<const void*>(mInputTree) == static_cast<void*>(mOutputTree)) {
511 OPENVDB_LOG_INFO("use tools::foreach(), not transformValues(),"
512 " to transform a grid in place");
513 }
514 }
515
516 // When splitting this task, give the subtask a copy of the original functor,
517 // not of this task's functor, which might have been modified arbitrarily.
519 mIsRoot(false),
520 mInputIter(other.mInputIter),
521 mInputTree(other.mInputTree),
522 mOutputTree(new OutTreeT(zeroVal<OutValueT>())),
523 mOp(*other.mOrigOp),
524 mOrigOp(other.mOrigOp),
525 mMergePolicy(other.mMergePolicy)
526 {}
527
529 {
530 // Delete the output tree only if it was allocated locally
531 // (the top-level output tree was supplied by the caller).
532 if (!mIsRoot) {
533 delete mOutputTree;
534 mOutputTree = nullptr;
535 }
536 }
537
538 void process(bool threaded = true)
539 {
540 if (!mInputTree || !mOutputTree) return;
541
542 IterRange range(mInputIter);
543
544 // Independently transform elements in the iterator range,
545 // either in parallel or serially.
546 if (threaded) {
547 tbb::parallel_reduce(range, *this);
548 } else {
549 (*this)(range);
550 }
551 }
552
553 /// Transform each element in the given range.
554 void operator()(const IterRange& range)
555 {
556 if (!mOutputTree) return;
557 IterRange r(range);
558 typename tree::ValueAccessor<OutTreeT> outAccessor(*mOutputTree);
559 for ( ; r; ++r) {
560 mOp(r.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
605template<typename InIterT, typename OutGridT, typename XformOp>
606inline void
607transformValues(const InIterT& inIter, OutGridT& outGrid, const XformOp& op,
608 bool threaded, bool /*share*/, MergePolicy merge)
609{
610 using Adapter = TreeAdapter<OutGridT>;
611 using OutTreeT = typename Adapter::TreeType;
612 // Const ops are shared across threads, not copied.
614 Processor proc(inIter, Adapter::tree(outGrid), op, merge);
615 proc.process(threaded);
616}
617
618
619////////////////////////////////////////
620
621
622namespace valxform {
623
624template<typename IterT, typename OpT>
626{
627public:
629
630 // The root task makes a const copy of the original functor (mOrigOp)
631 // and keeps a pointer to the original functor (mOp), which it then modifies.
632 // Each subtask keeps a const pointer to the root task's mOrigOp
633 // and makes and then modifies a non-const copy (mOp) of it.
634 OpAccumulator(const IterT& iter, OpT& op):
635 mIsRoot(true),
636 mIter(iter),
637 mOp(&op),
638 mOrigOp(new OpT(op))
639 {}
640
641 // When splitting this task, give the subtask a copy of the original functor,
642 // not of this task's functor, which might have been modified arbitrarily.
643 OpAccumulator(OpAccumulator& other, tbb::split):
644 mIsRoot(false),
645 mIter(other.mIter),
646 mOp(new OpT(*other.mOrigOp)),
647 mOrigOp(other.mOrigOp)
648 {}
649
650 ~OpAccumulator() { if (mIsRoot) delete mOrigOp; else delete mOp; }
651
652 void process(bool threaded = true)
653 {
654 IterRange range(mIter);
655 if (threaded) {
656 tbb::parallel_reduce(range, *this);
657 } else {
658 (*this)(range);
659 }
660 }
661
662 void operator()(const IterRange& r) { for (IterRange it(r); it.test(); ++it) (*mOp)(it.iterator()); }
663
664 void join(OpAccumulator& other) { mOp->join(*other.mOp); }
665
666private:
667 const bool mIsRoot;
668 const IterT mIter;
669 OpT* mOp; // pointer to original functor, which might get modified
670 OpT const * const mOrigOp; // const copy of original functor
671}; // class OpAccumulator
672
673} // namespace valxform
674
675
676////////////////////////////////////////
677
678
679template<typename IterT, typename XformOp>
680inline void
681accumulate(const IterT& iter, XformOp& op, bool threaded)
682{
683 typename valxform::OpAccumulator<IterT, XformOp> proc(iter, op);
684 proc.process(threaded);
685}
686
687
688////////////////////////////////////////
689
690
691// Explicit Template Instantiation
692
693#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
694
695#ifdef OPENVDB_INSTANTIATE_VALUETRANSFORMER
697#endif
698
699#define _FUNCTION(TreeT) \
700 void setValueOnMin(TreeT&, const Coord&, const TreeT::ValueType&)
702#undef _FUNCTION
703
704#define _FUNCTION(TreeT) \
705 void setValueOnMax(TreeT&, const Coord&, const TreeT::ValueType&)
707#undef _FUNCTION
708
709#define _FUNCTION(TreeT) \
710 void setValueOnSum(TreeT&, const Coord&, const TreeT::ValueType&)
712#undef _FUNCTION
713
714#define _FUNCTION(TreeT) \
715 void setValueOnMult(TreeT&, const Coord&, const TreeT::ValueType&)
717#undef _FUNCTION
718
719#endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
720
721
722} // namespace tools
723} // namespace OPENVDB_VERSION_NAME
724} // namespace openvdb
725
726#endif // OPENVDB_TOOLS_VALUETRANSFORMER_HAS_BEEN_INCLUDED
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
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:518
~CopyableOpTransformer()
Definition ValueTransformer.h:528
typename InIterT::TreeT InTreeT
Definition ValueTransformer.h:496
void join(const CopyableOpTransformer &other)
Definition ValueTransformer.h:564
typename OutTreeT::ValueType OutValueT
Definition ValueTransformer.h:498
void process(bool threaded=true)
Definition ValueTransformer.h:538
CopyableOpTransformer(const InIterT &inIter, OutTreeT &outTree, const OpT &op, MergePolicy merge)
Definition ValueTransformer.h:500
void operator()(const IterRange &range)
Transform each element in the given range.
Definition ValueTransformer.h:554
typename tree::IteratorRange< InIterT > IterRange
Definition ValueTransformer.h:497
Definition ValueTransformer.h:626
typename tree::IteratorRange< IterT > IterRange
Definition ValueTransformer.h:628
OpAccumulator(const IterT &iter, OpT &op)
Definition ValueTransformer.h:634
void join(OpAccumulator &other)
Definition ValueTransformer.h:664
OpAccumulator(OpAccumulator &other, tbb::split)
Definition ValueTransformer.h:643
void process(bool threaded=true)
Definition ValueTransformer.h:652
~OpAccumulator()
Definition ValueTransformer.h:650
void operator()(const IterRange &r)
Definition ValueTransformer.h:662
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
void operator()(const IterRange &range) const
Transform each element in the given range.
Definition ValueTransformer.h:465
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:475
typename tree::IteratorRange< InIterT > IterRange
Definition ValueTransformer.h:412
Definition TreeIterator.h:1303
The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compa...
Definition ValueAccessor.h:367
#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 PointStatisticsImpl.h:530
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:589
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
MergePolicy
Definition Types.h:506
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