OpenVDB  12.0.0
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 
40 namespace openvdb {
42 namespace OPENVDB_VERSION_NAME {
43 namespace 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.
88 template<typename IterT, typename XformOp>
89 inline void foreach(const IterT& iter, XformOp& op,
90  bool threaded = true, bool shareOp = true);
91 
92 template<typename IterT, typename XformOp>
93 inline 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.
137 template<typename InIterT, typename OutGridT, typename XformOp>
138 inline OPENVDB_UBSAN_SUPPRESS("undefined")
139 void transformValues(const InIterT& inIter, OutGridT& outGrid,
140  XformOp& op, bool threaded = true, bool shareOp = true,
142 
143 template<typename InIterT, typename OutGridT, typename XformOp>
144 inline OPENVDB_UBSAN_SUPPRESS("undefined")
145 void 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.
194 template<typename IterT, typename XformOp>
195 inline 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.
203 template<typename TreeT>
204 void 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.
211 template<typename TreeT>
212 void 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.
219 template<typename TreeT>
220 void 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.
227 template<typename TreeT>
228 void setValueOnMult(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value);
229 
230 
231 ////////////////////////////////////////
232 
233 
234 namespace valxform {
235 
236 template<typename ValueType>
237 struct 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 
243 template<typename ValueType>
244 struct 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 
250 template<typename ValueType>
251 struct SumOp {
252  const ValueType val;
253  SumOp(const ValueType& v): val(v) {}
254  inline void operator()(ValueType& v) const { v += val; }
255 };
256 
257 template<>
258 struct SumOp<bool> {
259  using ValueType = bool;
260  const ValueType val;
261  SumOp(const ValueType& v): val(v) {}
262  inline void operator()(ValueType& v) const { v = v || val; }
263 };
264 
265 template<typename ValueType>
266 struct MultOp {
267  const ValueType val;
268  MultOp(const ValueType& v): val(v) {}
269  inline void operator()(ValueType& v) const { v *= val; }
270 };
271 
272 template<>
273 struct MultOp<bool> {
274  using ValueType = bool;
275  const ValueType val;
276  MultOp(const ValueType& v): val(v) {}
277  inline void operator()(ValueType& v) const { v = v && val; }
278 };
279 
280 }
281 
282 
283 template<typename TreeT>
284 void
285 setValueOnMin(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
286 {
287  tree.modifyValue(xyz, valxform::MinOp<typename TreeT::ValueType>(value));
288 }
289 
290 
291 template<typename TreeT>
292 void
293 setValueOnMax(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
294 {
295  tree.modifyValue(xyz, valxform::MaxOp<typename TreeT::ValueType>(value));
296 }
297 
298 
299 template<typename TreeT>
300 void
301 setValueOnSum(TreeT& tree, const Coord& xyz, const typename TreeT::ValueType& value)
302 {
303  tree.modifyValue(xyz, valxform::SumOp<typename TreeT::ValueType>(value));
304 }
305 
306 
307 template<typename TreeT>
308 void
309 setValueOnMult(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 
318 namespace valxform {
319 
320 template<typename IterT, typename OpT>
322 {
323 public:
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 
340 private:
341  IterT mIter;
342  OpT& mOp;
343 };
344 
345 
346 template<typename IterT, typename OpT>
348 {
349 public:
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 
371 private:
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 
380 template<typename IterT, typename XformOp>
381 inline void
382 foreach(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 
394 template<typename IterT, typename XformOp>
395 inline void
396 foreach(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 
407 namespace valxform {
408 
409 template<typename InIterT, typename OutTreeT, typename OpT>
411 {
412 public:
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 
484 private:
485  bool mIsRoot;
486  InIterT mInputIter;
487  const InTreeT* mInputTree;
488  OutTreeT* mOutputTree;
489  OpT& mOp;
490  MergePolicy mMergePolicy;
491 }; // class SharedOpTransformer
492 
493 
494 template<typename InIterT, typename OutTreeT, typename OpT>
496 {
497 public:
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 
573 private:
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 
589 template<typename InIterT, typename OutGridT, typename XformOp>
590 inline OPENVDB_UBSAN_SUPPRESS("undefined")
591 void transformValues(const InIterT& inIter, OutGridT& outGrid, XformOp& op,
592  bool threaded, bool shared, MergePolicy merge)
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 {
602  Processor proc(inIter, Adapter::tree(outGrid), op, merge);
603  proc.process(threaded);
604  }
605 }
606 
607 template<typename InIterT, typename OutGridT, typename XformOp>
608 inline OPENVDB_UBSAN_SUPPRESS("undefined")
609 void 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 
624 namespace valxform {
625 
626 template<typename IterT, typename OpT>
628 {
629 public:
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.
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 
668 private:
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 
681 template<typename IterT, typename XformOp>
682 inline void
683 accumulate(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_LOG_INFO(message)
Log an info message of the form &#39;someVar << "some text" << ...&#39;.
Definition: logging.h:254
void operator()(ValueType &v) const
Definition: ValueTransformer.h:240
const ValueType val
Definition: ValueTransformer.h:267
void operator()(IterRange &r) const
Definition: ValueTransformer.h:369
Definition: ValueTransformer.h:321
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition: version.h.in:165
The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compa...
Definition: ValueAccessor.h:68
SumOp(const ValueType &v)
Definition: ValueTransformer.h:261
#define OPENVDB_UBSAN_SUPPRESS(X)
SIMD Intrinsic Headers.
Definition: Platform.h:77
~CopyableOpTransformer()
Definition: ValueTransformer.h:530
typename OutTreeT::ValueType OutValueT
Definition: ValueTransformer.h:500
typename Adapter::TreeType OutTreeT
Definition: ValueTransformer.h:595
const ValueType val
Definition: ValueTransformer.h:245
CopyableOpTransformer(CopyableOpTransformer &other, tbb::split)
Definition: ValueTransformer.h:520
Processor proc(inIter, Adapter::tree(outGrid), op, merge)
typename InIterT::TreeT InTreeT
Definition: ValueTransformer.h:413
OpAccumulator(OpAccumulator &other, tbb::split)
Definition: ValueTransformer.h:645
OutGridT XformOp & op
Definition: ValueTransformer.h:139
typename InIterT::TreeT InTreeT
Definition: ValueTransformer.h:498
void operator()(ValueType &v) const
Definition: ValueTransformer.h:277
void join(OpAccumulator &other)
Definition: ValueTransformer.h:666
typename valxform::SharedOpTransformer< InIterT, OutTreeT, const XformOp > Processor
Definition: ValueTransformer.h:615
void process(bool threaded=true)
Definition: ValueTransformer.h:451
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
OutGridT XformOp bool bool shareOp
Definition: ValueTransformer.h:140
Definition: TreeIterator.h:1303
typename tree::IteratorRange< IterT > IterRange
Definition: ValueTransformer.h:324
void operator()(const IterRange &range)
Transform each element in the given range.
Definition: ValueTransformer.h:556
OutGridT XformOp bool bool MergePolicy merge
Definition: ValueTransformer.h:141
MaxOp(const ValueType &v)
Definition: ValueTransformer.h:246
~OpAccumulator()
Definition: ValueTransformer.h:652
void split(ContainerT &out, const std::string &in, const char delim)
Definition: Name.h:43
void setValueOnMult(TreeT &tree, const Coord &xyz, const typename TreeT::ValueType &value)
Set the value of the voxel at the given coordinates in tree to the product of its current value and v...
Definition: ValueTransformer.h:309
void join(const CopyableOpTransformer &other)
Definition: ValueTransformer.h:566
MultOp(const ValueType &v)
Definition: ValueTransformer.h:268
CopyableOpApplier(const CopyableOpApplier &other)
Definition: ValueTransformer.h:356
MultOp(const ValueType &v)
Definition: ValueTransformer.h:276
typename tree::IteratorRange< IterT > IterRange
Definition: ValueTransformer.h:630
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:1059
void process(bool threaded=true)
Definition: ValueTransformer.h:359
OutGridT XformOp bool threaded
Definition: ValueTransformer.h:140
void accumulate(const IterT &iter, XformOp &op, bool threaded=true)
Definition: ValueTransformer.h:683
void process(bool threaded=true)
Definition: ValueTransformer.h:540
Definition: Exceptions.h:13
void operator()(ValueType &v) const
Definition: ValueTransformer.h:262
OutGridT & outGrid
Definition: ValueTransformer.h:139
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:70
typename tree::IteratorRange< InIterT > IterRange
Definition: ValueTransformer.h:499
void operator()(const IterRange &range) const
Transform each element in the given range.
Definition: ValueTransformer.h:467
SumOp(const ValueType &v)
Definition: ValueTransformer.h:253
SharedOpTransformer(const InIterT &inIter, OutTreeT &outTree, OpT &op, MergePolicy merge)
Definition: ValueTransformer.h:417
OutGridT const XformOp bool bool
Definition: ValueTransformer.h:609
bool ValueType
Definition: ValueTransformer.h:274
Definition: ValueTransformer.h:347
const ValueType val
Definition: ValueTransformer.h:275
CopyableOpApplier(const IterT &iter, const OpT &op)
Definition: ValueTransformer.h:352
OpAccumulator(const IterT &iter, OpT &op)
Definition: ValueTransformer.h:636
Definition: ValueTransformer.h:237
Definition: ValueTransformer.h:266
const ValueType val
Definition: ValueTransformer.h:238
MergePolicy
Definition: Types.h:506
CopyableOpTransformer(const InIterT &inIter, OutTreeT &outTree, const OpT &op, MergePolicy merge)
Definition: ValueTransformer.h:502
void join(const SharedOpTransformer &other)
Definition: ValueTransformer.h:477
void operator()(ValueType &v) const
Definition: ValueTransformer.h:247
void setValueOnSum(TreeT &tree, const Coord &xyz, const typename TreeT::ValueType &value)
Set the value of the voxel at the given coordinates in tree to the sum of its current value and value...
Definition: ValueTransformer.h:301
void operator()(ValueType &v) const
Definition: ValueTransformer.h:254
Definition: ValueTransformer.h:244
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
Definition: ValueTransformer.h:251
bool ValueType
Definition: ValueTransformer.h:259
Definition: ValueTransformer.h:627
~SharedOpTransformer()
Definition: ValueTransformer.h:441
const ValueType val
Definition: ValueTransformer.h:252
typename OutTreeT::ValueType OutValueT
Definition: ValueTransformer.h:415
void process(bool threaded=true)
Definition: ValueTransformer.h:654
const ValueType val
Definition: ValueTransformer.h:260
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
void operator()(IterRange &r) const
Definition: ValueTransformer.h:338
SharedOpApplier(const IterT &iter, OpT &op)
Definition: ValueTransformer.h:326
void operator()(const IterRange &r)
Definition: ValueTransformer.h:664
typename tree::IteratorRange< IterT > IterRange
Definition: ValueTransformer.h:350
MinOp(const ValueType &v)
Definition: ValueTransformer.h:239
void process(bool threaded=true)
Definition: ValueTransformer.h:328
void operator()(ValueType &v) const
Definition: ValueTransformer.h:269
typename tree::IteratorRange< InIterT > IterRange
Definition: ValueTransformer.h:414
OutGridT XformOp bool bool shared
Definition: ValueTransformer.h:591
SharedOpTransformer(SharedOpTransformer &other, tbb::split)
Splitting constructor.
Definition: ValueTransformer.h:432
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218