37 #ifndef OPENVDB_TOOLS_COMPOSITE_HAS_BEEN_INCLUDED
38 #define OPENVDB_TOOLS_COMPOSITE_HAS_BEEN_INCLUDED
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>
46 #include <boost/utility/enable_if.hpp>
58 inline void csgUnion(GridOrTreeT& a, GridOrTreeT& b,
bool prune =
true);
63 inline void csgIntersection(GridOrTreeT& a, GridOrTreeT& b,
bool prune =
true);
68 inline void csgDifference(GridOrTreeT& a, GridOrTreeT& b,
bool prune =
true);
73 inline void compMax(GridOrTreeT& a, GridOrTreeT& b);
77 inline void compMin(GridOrTreeT& a, GridOrTreeT& b);
81 inline void compSum(GridOrTreeT& a, GridOrTreeT& b);
85 inline void compMul(GridOrTreeT& a, GridOrTreeT& b);
89 inline void compReplace(GridOrTreeT& a,
const GridOrTreeT& b);
98 template<
typename T>
inline
99 const typename boost::disable_if_c<VecTraits<T>::IsVec, T>::type&
102 template<
typename T>
inline
103 const typename boost::disable_if_c<VecTraits<T>::IsVec, T>::type&
108 template<
typename T>
inline
109 const typename boost::enable_if_c<VecTraits<T>::IsVec, T>::type&
110 min(
const T& a,
const T& b)
112 const typename T::ValueType aMag = a.lengthSqr(), bMag = b.lengthSqr();
113 return (aMag < bMag ? a : (bMag < aMag ? b :
std::min(a, b)));
116 template<
typename T>
inline
117 const typename boost::enable_if_c<VecTraits<T>::IsVec, T>::type&
118 max(
const T& a,
const T& b)
120 const typename T::ValueType aMag = a.lengthSqr(), bMag = b.lengthSqr();
121 return (aMag < bMag ? b : (bMag < aMag ? a :
std::max(a, b)));
127 template<
typename Gr
idOrTreeT>
129 compMax(GridOrTreeT& aTree, GridOrTreeT& bTree)
132 typedef typename Adapter::TreeType TreeT;
133 typedef typename TreeT::ValueType ValueT;
139 Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op,
false);
143 template<
typename Gr
idOrTreeT>
145 compMin(GridOrTreeT& aTree, GridOrTreeT& bTree)
148 typedef typename Adapter::TreeType TreeT;
149 typedef typename TreeT::ValueType ValueT;
155 Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op,
false);
159 template<
typename Gr
idOrTreeT>
161 compSum(GridOrTreeT& aTree, GridOrTreeT& bTree)
164 typedef typename Adapter::TreeType TreeT;
170 Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op,
false);
174 template<
typename Gr
idOrTreeT>
176 compMul(GridOrTreeT& aTree, GridOrTreeT& bTree)
179 typedef typename Adapter::TreeType TreeT;
185 Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op,
false);
192 template<
typename TreeT>
199 void operator()(
const typename TreeT::ValueOnCIter& iter)
const
202 iter.getBoundingBox(bbox);
203 aTree->fill(bbox, *iter);
206 void operator()(
const typename TreeT::LeafCIter& leafIter)
const
209 for (
typename TreeT::LeafCIter::LeafNodeT::ValueOnCIter iter =
210 leafIter->cbeginValueOn(); iter; ++iter)
212 acc.
setValue(iter.getCoord(), *iter);
218 template<
typename Gr
idOrTreeT>
223 typedef typename Adapter::TreeType TreeT;
224 typedef typename TreeT::ValueOnCIter ValueOnCIterT;
227 Adapter::tree(aTree).topologyUnion(Adapter::tree(bTree));
232 ValueOnCIterT iter = bTree.cbeginValueOn();
233 iter.setMaxDepth(iter.getLeafDepth() - 1);
237 foreach(Adapter::tree(bTree).cbeginLeaf(), op);
246 template<
typename TreeType>
251 typedef typename TreeT::ValueType
ValueT;
252 typedef typename TreeT::LeafNodeType::ChildAllIter
ChildIterT;
257 mAOutside(aTree.background()),
259 mBOutside(bTree.background()),
262 const ValueT zero = zeroVal<ValueT>();
263 if (!(mAOutside > zero)) {
265 "expected grid A outside value > 0, got " << mAOutside);
267 if (!(mAInside < zero)) {
269 "expected grid A inside value < 0, got " << mAInside);
271 if (!(mBOutside > zero)) {
273 "expected grid B outside value > 0, got " << mBOutside);
275 if (!(mBInside < zero)) {
277 "expected grid B outside value < 0, got " << mBOutside);
289 template<
typename TreeType>
293 typedef typename TreeT::ValueType
ValueT;
294 typedef typename TreeT::LeafNodeType::ChildAllIter
ChildIterT;
301 template<
typename AIterT,
typename BIterT>
305 template<
typename IterT>
308 ValueT aValue = zeroVal<ValueT>();
309 typename IterT::ChildNodeType* aChild = aIter.probeChild(aValue);
310 if (!aChild && aValue < zeroVal<ValueT>()) {
315 ValueT bValue = zeroVal<ValueT>();
316 typename IterT::ChildNodeType* bChild = bIter.probeChild(bValue);
317 if (!bChild && bValue < zeroVal<ValueT>()) {
319 aIter.setValue(this->mAInside);
320 aIter.setValueOn(bIter.isValueOn());
325 if (!aChild && aValue > zeroVal<ValueT>()) {
329 bIter.setValue(this->mBOutside);
331 bChild->resetBackground(this->mBOutside, this->mAOutside);
332 aIter.setChild(bChild);
340 return (aChild && bChild) ? 0 : STOP;
347 aIter.probeValue(aValue);
348 bIter.probeValue(bValue);
349 if (aValue > bValue) {
350 aIter.setValue(bValue);
351 aIter.setValueOn(bIter.isValueOn());
362 template<
typename TreeType>
366 typedef typename TreeT::ValueType
ValueT;
367 typedef typename TreeT::LeafNodeType::ChildAllIter
ChildIterT;
374 template<
typename AIterT,
typename BIterT>
378 template<
typename IterT>
381 ValueT aValue = zeroVal<ValueT>();
382 typename IterT::ChildNodeType* aChild = aIter.probeChild(aValue);
383 if (!aChild && !(aValue < zeroVal<ValueT>())) {
388 ValueT bValue = zeroVal<ValueT>();
389 typename IterT::ChildNodeType* bChild = bIter.probeChild(bValue);
390 if (!bChild && !(bValue < zeroVal<ValueT>())) {
392 aIter.setValue(this->mAOutside);
393 aIter.setValueOn(bIter.isValueOn());
398 if (!aChild && aValue < zeroVal<ValueT>()) {
402 bIter.setValue(this->mBOutside);
404 bChild->resetBackground(this->mBOutside, this->mAOutside);
405 aIter.setChild(bChild);
413 return (aChild && bChild) ? 0 : STOP;
420 aIter.probeValue(aValue);
421 bIter.probeValue(bValue);
422 if (aValue < bValue) {
423 aIter.setValue(bValue);
424 aIter.setValueOn(bIter.isValueOn());
434 template<
typename TreeType>
438 typedef typename TreeT::ValueType
ValueT;
439 typedef typename TreeT::LeafNodeType::ChildAllIter
ChildIterT;
446 template<
typename AIterT,
typename BIterT>
450 template<
typename IterT>
453 ValueT aValue = zeroVal<ValueT>();
454 typename IterT::ChildNodeType* aChild = aIter.probeChild(aValue);
455 if (!aChild && !(aValue < zeroVal<ValueT>())) {
460 ValueT bValue = zeroVal<ValueT>();
461 typename IterT::ChildNodeType* bChild = bIter.probeChild(bValue);
462 if (!bChild && bValue < zeroVal<ValueT>()) {
464 aIter.setValue(this->mAOutside);
465 aIter.setValueOn(bIter.isValueOn());
470 if (!aChild && aValue < zeroVal<ValueT>()) {
474 bIter.setValue(this->mBOutside);
476 bChild->resetBackground(this->mBOutside, this->mAOutside);
477 aIter.setChild(bChild);
486 return (aChild && bChild) ? 0 : STOP;
493 aIter.probeValue(aValue);
494 bIter.probeValue(bValue);
496 if (aValue < bValue) {
497 aIter.setValue(bValue);
498 aIter.setValueOn(bIter.isValueOn());
508 template<
typename Gr
idOrTreeT>
510 csgUnion(GridOrTreeT& a, GridOrTreeT& b,
bool prune)
513 typedef typename Adapter::TreeType TreeT;
514 TreeT &aTree = Adapter::tree(a), &bTree = Adapter::tree(b);
516 aTree.visit2(bTree, visitor);
517 if (prune) aTree.pruneLevelSet();
521 template<
typename Gr
idOrTreeT>
526 typedef typename Adapter::TreeType TreeT;
527 TreeT &aTree = Adapter::tree(a), &bTree = Adapter::tree(b);
529 aTree.visit2(bTree, visitor);
530 if (prune) aTree.pruneLevelSet();
534 template<
typename Gr
idOrTreeT>
539 typedef typename Adapter::TreeType TreeT;
540 TreeT &aTree = Adapter::tree(a), &bTree = Adapter::tree(b);
542 aTree.visit2(bTree, visitor);
543 if (prune) aTree.pruneLevelSet();
551 #endif // OPENVDB_TOOLS_COMPOSITE_HAS_BEEN_INCLUDED