OpenVDB  3.0.0
Composite.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2014 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 //
36 
37 #ifndef OPENVDB_TOOLS_COMPOSITE_HAS_BEEN_INCLUDED
38 #define OPENVDB_TOOLS_COMPOSITE_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/Platform.h>
41 #include <openvdb/Exceptions.h>
42 #include <openvdb/Types.h>
43 #include <openvdb/Grid.h>
44 #include <openvdb/math/Math.h> // for isExactlyEqual()
45 #include "ValueTransformer.h" // for transformValues()
46 #include "Prune.h"// for prune
47 #include <boost/utility/enable_if.hpp>
48 
49 
50 namespace openvdb {
52 namespace OPENVDB_VERSION_NAME {
53 namespace tools {
54 
58 template<typename GridOrTreeT> OPENVDB_STATIC_SPECIALIZATION
59 inline void csgUnion(GridOrTreeT& a, GridOrTreeT& b, bool prune = true);
63 template<typename GridOrTreeT> OPENVDB_STATIC_SPECIALIZATION
64 inline void csgIntersection(GridOrTreeT& a, GridOrTreeT& b, bool prune = true);
68 template<typename GridOrTreeT> OPENVDB_STATIC_SPECIALIZATION
69 inline void csgDifference(GridOrTreeT& a, GridOrTreeT& b, bool prune = true);
70 
73 template<typename GridOrTreeT> OPENVDB_STATIC_SPECIALIZATION
74 inline void compMax(GridOrTreeT& a, GridOrTreeT& b);
77 template<typename GridOrTreeT> OPENVDB_STATIC_SPECIALIZATION
78 inline void compMin(GridOrTreeT& a, GridOrTreeT& b);
81 template<typename GridOrTreeT> OPENVDB_STATIC_SPECIALIZATION
82 inline void compSum(GridOrTreeT& a, GridOrTreeT& b);
85 template<typename GridOrTreeT> OPENVDB_STATIC_SPECIALIZATION
86 inline void compMul(GridOrTreeT& a, GridOrTreeT& b);
89 template<typename GridOrTreeT> OPENVDB_STATIC_SPECIALIZATION
90 inline void compDiv(GridOrTreeT& a, GridOrTreeT& b);
91 
93 template<typename GridOrTreeT> OPENVDB_STATIC_SPECIALIZATION
94 inline void compReplace(GridOrTreeT& a, const GridOrTreeT& b);
95 
96 
98 
99 
100 namespace composite {
101 
102 // composite::min() and composite::max() for non-vector types compare with operator<().
103 template<typename T> inline
104 const typename boost::disable_if_c<VecTraits<T>::IsVec, T>::type& // = T if T is not a vector type
105 min(const T& a, const T& b) { return std::min(a, b); }
106 
107 template<typename T> inline
108 const typename boost::disable_if_c<VecTraits<T>::IsVec, T>::type&
109 max(const T& a, const T& b) { return std::max(a, b); }
110 
111 
112 // composite::min() and composite::max() for OpenVDB vector types compare by magnitude.
113 template<typename T> inline
114 const typename boost::enable_if_c<VecTraits<T>::IsVec, T>::type& // = T if T is a vector type
115 min(const T& a, const T& b)
116 {
117  const typename T::ValueType aMag = a.lengthSqr(), bMag = b.lengthSqr();
118  return (aMag < bMag ? a : (bMag < aMag ? b : std::min(a, b)));
119 }
120 
121 template<typename T> inline
122 const typename boost::enable_if_c<VecTraits<T>::IsVec, T>::type&
123 max(const T& a, const T& b)
124 {
125  const typename T::ValueType aMag = a.lengthSqr(), bMag = b.lengthSqr();
126  return (aMag < bMag ? b : (bMag < aMag ? a : std::max(a, b)));
127 }
128 
129 
130 template<typename T> inline
131 typename boost::disable_if<boost::is_integral<T>, T>::type // = T if T is not an integer type
132 divide(const T& a, const T& b) { return a / b; }
133 
134 template<typename T> inline
135 typename boost::enable_if<boost::is_integral<T>, T>::type // = T if T is an integer type
136 divide(const T& a, const T& b)
137 {
138  const T zero(0);
139  if (b != zero) return a / b;
140  if (a == zero) return 0;
142 }
143 
144 // If b is true, return a / 1 = a.
145 // If b is false and a is true, return 1 / 0 = inf = MAX_BOOL = 1 = a.
146 // If b is false and a is false, return 0 / 0 = NaN = 0 = a.
147 inline bool divide(bool a, bool /*b*/) { return a; }
148 
149 } // namespace composite
150 
151 
152 template<typename GridOrTreeT>
154 compMax(GridOrTreeT& aTree, GridOrTreeT& bTree)
155 {
156  typedef TreeAdapter<GridOrTreeT> Adapter;
157  typedef typename Adapter::TreeType TreeT;
158  typedef typename TreeT::ValueType ValueT;
159  struct Local {
160  static inline void op(CombineArgs<ValueT>& args) {
161  args.setResult(composite::max(args.a(), args.b()));
162  }
163  };
164  Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op, /*prune=*/false);
165 }
166 
167 
168 template<typename GridOrTreeT>
170 compMin(GridOrTreeT& aTree, GridOrTreeT& bTree)
171 {
172  typedef TreeAdapter<GridOrTreeT> Adapter;
173  typedef typename Adapter::TreeType TreeT;
174  typedef typename TreeT::ValueType ValueT;
175  struct Local {
176  static inline void op(CombineArgs<ValueT>& args) {
177  args.setResult(composite::min(args.a(), args.b()));
178  }
179  };
180  Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op, /*prune=*/false);
181 }
182 
183 
184 template<typename GridOrTreeT>
186 compSum(GridOrTreeT& aTree, GridOrTreeT& bTree)
187 {
188  typedef TreeAdapter<GridOrTreeT> Adapter;
189  typedef typename Adapter::TreeType TreeT;
190  struct Local {
191  static inline void op(CombineArgs<typename TreeT::ValueType>& args) {
192  args.setResult(args.a() + args.b());
193  }
194  };
195  Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op, /*prune=*/false);
196 }
197 
198 
199 template<typename GridOrTreeT>
201 compMul(GridOrTreeT& aTree, GridOrTreeT& bTree)
202 {
203  typedef TreeAdapter<GridOrTreeT> Adapter;
204  typedef typename Adapter::TreeType TreeT;
205  struct Local {
206  static inline void op(CombineArgs<typename TreeT::ValueType>& args) {
207  args.setResult(args.a() * args.b());
208  }
209  };
210  Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op, /*prune=*/false);
211 }
212 
213 
214 template<typename GridOrTreeT>
216 compDiv(GridOrTreeT& aTree, GridOrTreeT& bTree)
217 {
218  typedef TreeAdapter<GridOrTreeT> Adapter;
219  typedef typename Adapter::TreeType TreeT;
220  struct Local {
221  static inline void op(CombineArgs<typename TreeT::ValueType>& args) {
222  args.setResult(composite::divide(args.a(), args.b()));
223  }
224  };
225  Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op, /*prune=*/false);
226 }
227 
228 
230 
231 
232 template<typename TreeT>
234 {
235  TreeT* const aTree;
236 
237  CompReplaceOp(TreeT& _aTree): aTree(&_aTree) {}
238 
239  void operator()(const typename TreeT::ValueOnCIter& iter) const
240  {
241  CoordBBox bbox;
242  iter.getBoundingBox(bbox);
243  aTree->fill(bbox, *iter);
244  }
245 
246  void operator()(const typename TreeT::LeafCIter& leafIter) const
247  {
248  tree::ValueAccessor<TreeT> acc(*aTree);
249  for (typename TreeT::LeafCIter::LeafNodeT::ValueOnCIter iter =
250  leafIter->cbeginValueOn(); iter; ++iter)
251  {
252  acc.setValue(iter.getCoord(), *iter);
253  }
254  }
255 };
256 
257 
258 template<typename GridOrTreeT>
260 compReplace(GridOrTreeT& aTree, const GridOrTreeT& bTree)
261 {
262  typedef TreeAdapter<GridOrTreeT> Adapter;
263  typedef typename Adapter::TreeType TreeT;
264  typedef typename TreeT::ValueOnCIter ValueOnCIterT;
265 
266  // Copy active states (but not values) from B to A.
267  Adapter::tree(aTree).topologyUnion(Adapter::tree(bTree));
268 
269  CompReplaceOp<TreeT> op(Adapter::tree(aTree));
270 
271  // Copy all active tile values from B to A.
272  ValueOnCIterT iter = bTree.cbeginValueOn();
273  iter.setMaxDepth(iter.getLeafDepth() - 1); // don't descend into leaf nodes
274  foreach(iter, op);
275 
276  // Copy all active voxel values from B to A.
277  foreach(Adapter::tree(bTree).cbeginLeaf(), op);
278 }
279 
280 
282 
283 
286 template<typename TreeType>
288 {
289 public:
290  typedef TreeType TreeT;
291  typedef typename TreeT::ValueType ValueT;
292  typedef typename TreeT::LeafNodeType::ChildAllIter ChildIterT;
293 
294  enum { STOP = 3 };
295 
296  CsgVisitorBase(const TreeT& aTree, const TreeT& bTree):
297  mAOutside(aTree.background()),
298  mAInside(math::negative(mAOutside)),
299  mBOutside(bTree.background()),
300  mBInside(math::negative(mBOutside))
301  {
302  const ValueT zero = zeroVal<ValueT>();
303  if (!(mAOutside > zero)) {
305  "expected grid A outside value > 0, got " << mAOutside);
306  }
307  if (!(mAInside < zero)) {
309  "expected grid A inside value < 0, got " << mAInside);
310  }
311  if (!(mBOutside > zero)) {
313  "expected grid B outside value > 0, got " << mBOutside);
314  }
315  if (!(mBInside < zero)) {
317  "expected grid B outside value < 0, got " << mBOutside);
318  }
319  }
320 
321 protected:
322  ValueT mAOutside, mAInside, mBOutside, mBInside;
323 };
324 
325 
327 
328 
329 template<typename TreeType>
330 struct CsgUnionVisitor: public CsgVisitorBase<TreeType>
331 {
332  typedef TreeType TreeT;
333  typedef typename TreeT::ValueType ValueT;
334  typedef typename TreeT::LeafNodeType::ChildAllIter ChildIterT;
335 
337 
338  CsgUnionVisitor(const TreeT& a, const TreeT& b): CsgVisitorBase<TreeT>(a, b) {}
339 
341  template<typename AIterT, typename BIterT>
342  inline int operator()(AIterT&, BIterT&) { return 0; }
343 
345  template<typename IterT>
346  inline int operator()(IterT& aIter, IterT& bIter)
347  {
348  ValueT aValue = zeroVal<ValueT>();
349  typename IterT::ChildNodeType* aChild = aIter.probeChild(aValue);
350  if (!aChild && aValue < zeroVal<ValueT>()) {
351  // A is an inside tile. Leave it alone and stop traversing this branch.
352  return STOP;
353  }
354 
355  ValueT bValue = zeroVal<ValueT>();
356  typename IterT::ChildNodeType* bChild = bIter.probeChild(bValue);
357  if (!bChild && bValue < zeroVal<ValueT>()) {
358  // B is an inside tile. Make A an inside tile and stop traversing this branch.
359  aIter.setValue(this->mAInside);
360  aIter.setValueOn(bIter.isValueOn());
361  delete aChild;
362  return STOP;
363  }
364 
365  if (!aChild && aValue > zeroVal<ValueT>()) {
366  // A is an outside tile. If B has a child, transfer it to A,
367  // otherwise leave A alone.
368  if (bChild) {
369  bIter.setValue(this->mBOutside);
370  bIter.setValueOff();
371  bChild->resetBackground(this->mBOutside, this->mAOutside);
372  aIter.setChild(bChild); // transfer child
373  delete aChild;
374  }
375  return STOP;
376  }
377 
378  // If A has a child and B is an outside tile, stop traversing this branch.
379  // Continue traversal only if A and B both have children.
380  return (aChild && bChild) ? 0 : STOP;
381  }
382 
384  inline int operator()(ChildIterT& aIter, ChildIterT& bIter)
385  {
386  ValueT aValue, bValue;
387  aIter.probeValue(aValue);
388  bIter.probeValue(bValue);
389  if (aValue > bValue) { // a = min(a, b)
390  aIter.setValue(bValue);
391  aIter.setValueOn(bIter.isValueOn());
392  }
393  return 0;
394  }
395 };
396 
397 
398 
400 
401 
402 template<typename TreeType>
403 struct CsgIntersectVisitor: public CsgVisitorBase<TreeType>
404 {
405  typedef TreeType TreeT;
406  typedef typename TreeT::ValueType ValueT;
407  typedef typename TreeT::LeafNodeType::ChildAllIter ChildIterT;
408 
410 
411  CsgIntersectVisitor(const TreeT& a, const TreeT& b): CsgVisitorBase<TreeT>(a, b) {}
412 
414  template<typename AIterT, typename BIterT>
415  inline int operator()(AIterT&, BIterT&) { return 0; }
416 
418  template<typename IterT>
419  inline int operator()(IterT& aIter, IterT& bIter)
420  {
421  ValueT aValue = zeroVal<ValueT>();
422  typename IterT::ChildNodeType* aChild = aIter.probeChild(aValue);
423  if (!aChild && !(aValue < zeroVal<ValueT>())) {
424  // A is an outside tile. Leave it alone and stop traversing this branch.
425  return STOP;
426  }
427 
428  ValueT bValue = zeroVal<ValueT>();
429  typename IterT::ChildNodeType* bChild = bIter.probeChild(bValue);
430  if (!bChild && !(bValue < zeroVal<ValueT>())) {
431  // B is an outside tile. Make A an outside tile and stop traversing this branch.
432  aIter.setValue(this->mAOutside);
433  aIter.setValueOn(bIter.isValueOn());
434  delete aChild;
435  return STOP;
436  }
437 
438  if (!aChild && aValue < zeroVal<ValueT>()) {
439  // A is an inside tile. If B has a child, transfer it to A,
440  // otherwise leave A alone.
441  if (bChild) {
442  bIter.setValue(this->mBOutside);
443  bIter.setValueOff();
444  bChild->resetBackground(this->mBOutside, this->mAOutside);
445  aIter.setChild(bChild); // transfer child
446  delete aChild;
447  }
448  return STOP;
449  }
450 
451  // If A has a child and B is an outside tile, stop traversing this branch.
452  // Continue traversal only if A and B both have children.
453  return (aChild && bChild) ? 0 : STOP;
454  }
455 
457  inline int operator()(ChildIterT& aIter, ChildIterT& bIter)
458  {
459  ValueT aValue, bValue;
460  aIter.probeValue(aValue);
461  bIter.probeValue(bValue);
462  if (aValue < bValue) { // a = max(a, b)
463  aIter.setValue(bValue);
464  aIter.setValueOn(bIter.isValueOn());
465  }
466  return 0;
467  }
468 };
469 
470 
472 
473 
474 template<typename TreeType>
475 struct CsgDiffVisitor: public CsgVisitorBase<TreeType>
476 {
477  typedef TreeType TreeT;
478  typedef typename TreeT::ValueType ValueT;
479  typedef typename TreeT::LeafNodeType::ChildAllIter ChildIterT;
480 
482 
483  CsgDiffVisitor(const TreeT& a, const TreeT& b): CsgVisitorBase<TreeT>(a, b) {}
484 
486  template<typename AIterT, typename BIterT>
487  inline int operator()(AIterT&, BIterT&) { return 0; }
488 
490  template<typename IterT>
491  inline int operator()(IterT& aIter, IterT& bIter)
492  {
493  ValueT aValue = zeroVal<ValueT>();
494  typename IterT::ChildNodeType* aChild = aIter.probeChild(aValue);
495  if (!aChild && !(aValue < zeroVal<ValueT>())) {
496  // A is an outside tile. Leave it alone and stop traversing this branch.
497  return STOP;
498  }
499 
500  ValueT bValue = zeroVal<ValueT>();
501  typename IterT::ChildNodeType* bChild = bIter.probeChild(bValue);
502  if (!bChild && bValue < zeroVal<ValueT>()) {
503  // B is an inside tile. Make A an inside tile and stop traversing this branch.
504  aIter.setValue(this->mAOutside);
505  aIter.setValueOn(bIter.isValueOn());
506  delete aChild;
507  return STOP;
508  }
509 
510  if (!aChild && aValue < zeroVal<ValueT>()) {
511  // A is an inside tile. If B has a child, transfer it to A,
512  // otherwise leave A alone.
513  if (bChild) {
514  bIter.setValue(this->mBOutside);
515  bIter.setValueOff();
516  bChild->resetBackground(this->mBOutside, this->mAOutside);
517  aIter.setChild(bChild); // transfer child
518  bChild->negate();
519  delete aChild;
520  }
521  return STOP;
522  }
523 
524  // If A has a child and B is an outside tile, stop traversing this branch.
525  // Continue traversal only if A and B both have children.
526  return (aChild && bChild) ? 0 : STOP;
527  }
528 
530  inline int operator()(ChildIterT& aIter, ChildIterT& bIter)
531  {
532  ValueT aValue, bValue;
533  aIter.probeValue(aValue);
534  bIter.probeValue(bValue);
535  bValue = math::negative(bValue);
536  if (aValue < bValue) { // a = max(a, -b)
537  aIter.setValue(bValue);
538  aIter.setValueOn(bIter.isValueOn());
539  }
540  return 0;
541  }
542 };
543 
544 
546 
547 
548 template<typename GridOrTreeT>
550 csgUnion(GridOrTreeT& a, GridOrTreeT& b, bool prune)
551 {
552  typedef TreeAdapter<GridOrTreeT> Adapter;
553  typedef typename Adapter::TreeType TreeT;
554  TreeT &aTree = Adapter::tree(a), &bTree = Adapter::tree(b);
555  CsgUnionVisitor<TreeT> visitor(aTree, bTree);
556  aTree.visit2(bTree, visitor);
557  if (prune) tools::pruneLevelSet(aTree);
558 }
559 
560 template<typename GridOrTreeT>
562 csgIntersection(GridOrTreeT& a, GridOrTreeT& b, bool prune)
563 {
564  typedef TreeAdapter<GridOrTreeT> Adapter;
565  typedef typename Adapter::TreeType TreeT;
566  TreeT &aTree = Adapter::tree(a), &bTree = Adapter::tree(b);
567  CsgIntersectVisitor<TreeT> visitor(aTree, bTree);
568  aTree.visit2(bTree, visitor);
569  if (prune) tools::pruneLevelSet(aTree);
570 }
571 
572 template<typename GridOrTreeT>
574 csgDifference(GridOrTreeT& a, GridOrTreeT& b, bool prune)
575 {
576  typedef TreeAdapter<GridOrTreeT> Adapter;
577  typedef typename Adapter::TreeType TreeT;
578  TreeT &aTree = Adapter::tree(a), &bTree = Adapter::tree(b);
579  CsgDiffVisitor<TreeT> visitor(aTree, bTree);
580  aTree.visit2(bTree, visitor);
581  if (prune) tools::pruneLevelSet(aTree);
582 }
583 
584 } // namespace tools
585 } // namespace OPENVDB_VERSION_NAME
586 } // namespace openvdb
587 
588 #endif // OPENVDB_TOOLS_COMPOSITE_HAS_BEEN_INCLUDED
589 
590 // Copyright (c) 2012-2014 DreamWorks Animation LLC
591 // All rights reserved. This software is distributed under the
592 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
CompReplaceOp(TreeT &_aTree)
Definition: Composite.h:237
void operator()(const typename TreeT::ValueOnCIter &iter) const
Definition: Composite.h:239
TreeT::ValueType ValueT
Definition: Composite.h:478
TreeT::ValueType ValueT
Definition: Composite.h:291
TreeType TreeT
Definition: Composite.h:405
CsgVisitorBase(const TreeT &aTree, const TreeT &bTree)
Definition: Composite.h:296
CsgIntersectVisitor(const TreeT &a, const TreeT &b)
Definition: Composite.h:411
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
int operator()(ChildIterT &aIter, ChildIterT &bIter)
Process leaf node values.
Definition: Composite.h:384
OPENVDB_STATIC_SPECIALIZATION void compMin(GridOrTreeT &a, GridOrTreeT &b)
Given grids A and B, compute min(a, b) per voxel (using sparse traversal). Store the result in the A ...
Definition: Composite.h:170
TreeT::LeafNodeType::ChildAllIter ChildIterT
Definition: Composite.h:334
OPENVDB_STATIC_SPECIALIZATION void csgDifference(GridOrTreeT &a, GridOrTreeT &b, bool prune=true)
Given two level set grids, replace the A grid with the difference A / B.
Definition: Composite.h:574
TreeT::ValueType ValueT
Definition: Composite.h:333
OPENVDB_STATIC_SPECIALIZATION void csgIntersection(GridOrTreeT &a, GridOrTreeT &b, bool prune=true)
Given two level set grids, replace the A grid with the intersection of A and B.
Definition: Composite.h:562
Definition: Composite.h:330
const boost::enable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:123
int operator()(ChildIterT &aIter, ChildIterT &bIter)
Process leaf node values.
Definition: Composite.h:457
OPENVDB_STATIC_SPECIALIZATION void csgUnion(GridOrTreeT &a, GridOrTreeT &b, bool prune=true)
Given two level set grids, replace the A grid with the union of A and B.
Definition: Composite.h:550
int operator()(AIterT &, BIterT &)
Don't process nodes that are at different tree levels.
Definition: Composite.h:342
Definition: Composite.h:233
Defined various multi-threaded utility functions for trees.
int operator()(IterT &aIter, IterT &bIter)
Process root and internal nodes.
Definition: Composite.h:346
void operator()(const typename TreeT::LeafCIter &leafIter) const
Definition: Composite.h:246
int operator()(IterT &aIter, IterT &bIter)
Process root and internal nodes.
Definition: Composite.h:419
Definition: Composite.h:475
#define OPENVDB_VERSION_NAME
Definition: version.h:43
TreeType TreeT
Definition: Composite.h:332
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:309
Definition: Composite.h:287
int operator()(AIterT &, BIterT &)
Don't process nodes that are at different tree levels.
Definition: Composite.h:415
CombineArgs & setResult(const AValueType &val)
Set the output value.
Definition: Types.h:344
Definition: Exceptions.h:39
CsgUnionVisitor(const TreeT &a, const TreeT &b)
Definition: Composite.h:338
const AValueType & a() const
Get the A input value.
Definition: Types.h:334
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:107
ValueT mBOutside
Definition: Composite.h:322
int operator()(AIterT &, BIterT &)
Don't process nodes that are at different tree levels.
Definition: Composite.h:487
int operator()(IterT &aIter, IterT &bIter)
Process root and internal nodes.
Definition: Composite.h:491
const boost::enable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:115
Definition: Exceptions.h:88
TreeT::ValueType ValueT
Definition: Composite.h:406
TreeT::LeafNodeType::ChildAllIter ChildIterT
Definition: Composite.h:292
OPENVDB_STATIC_SPECIALIZATION void compMax(GridOrTreeT &a, GridOrTreeT &b)
Given grids A and B, compute max(a, b) per voxel (using sparse traversal). Store the result in the A ...
Definition: Composite.h:154
OPENVDB_STATIC_SPECIALIZATION void compSum(GridOrTreeT &a, GridOrTreeT &b)
Given grids A and B, compute a + b per voxel (using sparse traversal). Store the result in the A grid...
Definition: Composite.h:186
OPENVDB_STATIC_SPECIALIZATION void compMul(GridOrTreeT &a, GridOrTreeT &b)
Given grids A and B, compute a * b per voxel (using sparse traversal). Store the result in the A grid...
Definition: Composite.h:201
#define OPENVDB_STATIC_SPECIALIZATION
Macro for determining if there are sufficient C++0x/C++11 features.
Definition: Platform.h:89
void pruneLevelSet(TreeT &tree, bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing nodes whose values are all inactive with inactive ...
Definition: Prune.h:369
TreeT::LeafNodeType::ChildAllIter ChildIterT
Definition: Composite.h:407
OPENVDB_STATIC_SPECIALIZATION void compDiv(GridOrTreeT &a, GridOrTreeT &b)
Given grids A and B, compute a / b per voxel (using sparse traversal). Store the result in the A grid...
Definition: Composite.h:216
CsgDiffVisitor(const TreeT &a, const TreeT &b)
Definition: Composite.h:483
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:858
OPENVDB_STATIC_SPECIALIZATION void compReplace(GridOrTreeT &a, const GridOrTreeT &b)
Copy the active voxels of B into A.
Definition: Composite.h:260
bool divide(bool a, bool)
Definition: Composite.h:147
int operator()(ChildIterT &aIter, ChildIterT &bIter)
Process leaf node values.
Definition: Composite.h:530
TreeType TreeT
Definition: Composite.h:290
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
TreeT::LeafNodeType::ChildAllIter ChildIterT
Definition: Composite.h:479
void setValue(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: ValueAccessor.h:241
const BValueType & b() const
Get the B input value.
Definition: Types.h:336
void prune(TreeT &tree, typename TreeT::ValueType tolerance=zeroVal< typename TreeT::ValueType >(), bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing with tiles any nodes whose values are all the same...
Definition: Prune.h:314
TreeType TreeT
Definition: Composite.h:477
TreeT *const aTree
Definition: Composite.h:235