37 #ifndef OPENVDB_TOOLS_COMPOSITE_HAS_BEEN_INCLUDED 38 #define OPENVDB_TOOLS_COMPOSITE_HAS_BEEN_INCLUDED 48 #include <boost/utility/enable_if.hpp> 50 #include <tbb/blocked_range.h> 51 #include <tbb/parallel_for.h> 52 #include <tbb/parallel_reduce.h> 53 #include <tbb/task_group.h> 54 #include <tbb/task_scheduler_init.h> 66 inline void csgUnion(GridOrTreeT& a, GridOrTreeT& b,
bool prune =
true);
82 inline typename GridOrTreeT::Ptr
csgUnionCopy(
const GridOrTreeT& a,
const GridOrTreeT& b);
87 inline typename GridOrTreeT::Ptr
csgIntersectionCopy(
const GridOrTreeT& a,
const GridOrTreeT& b);
92 inline typename GridOrTreeT::Ptr
csgDifferenceCopy(
const GridOrTreeT& a,
const GridOrTreeT& b);
97 inline void compMax(GridOrTreeT& a, GridOrTreeT& b);
101 inline void compMin(GridOrTreeT& a, GridOrTreeT& b);
105 inline void compSum(GridOrTreeT& a, GridOrTreeT& b);
109 inline void compMul(GridOrTreeT& a, GridOrTreeT& b);
113 inline void compDiv(GridOrTreeT& a, GridOrTreeT& b);
117 inline void compReplace(GridOrTreeT& a,
const GridOrTreeT& b);
123 namespace composite {
126 template<
typename T>
inline 127 const typename boost::disable_if_c<VecTraits<T>::IsVec, T>::type&
130 template<
typename T>
inline 131 const typename boost::disable_if_c<VecTraits<T>::IsVec, T>::type&
136 template<
typename T>
inline 137 const typename boost::enable_if_c<VecTraits<T>::IsVec, T>::type&
138 min(
const T& a,
const T& b)
140 const typename T::ValueType aMag = a.lengthSqr(), bMag = b.lengthSqr();
141 return (aMag < bMag ? a : (bMag < aMag ? b :
std::min(a, b)));
144 template<
typename T>
inline 145 const typename boost::enable_if_c<VecTraits<T>::IsVec, T>::type&
146 max(
const T& a,
const T& b)
148 const typename T::ValueType aMag = a.lengthSqr(), bMag = b.lengthSqr();
149 return (aMag < bMag ? b : (bMag < aMag ? a :
std::max(a, b)));
153 template<
typename T>
inline 154 typename boost::disable_if<boost::is_integral<T>, T>::type
155 divide(
const T& a,
const T& b) {
return a / b; }
157 template<
typename T>
inline 158 typename boost::enable_if<boost::is_integral<T>, T>::type
162 if (b != zero)
return a / b;
163 if (a == zero)
return 0;
170 inline bool divide(
bool a,
bool ) {
return a; }
175 template<
typename TreeType, CSGOperation Operation>
184 typedef typename boost::mpl::at<NodeChainType, boost::mpl::int_<1> >::type
InternalNodeType;
187 : mSegment(new TreeType(lhs.background()))
195 std::vector<const LeafNodeType*> leafNodes;
198 std::vector<const InternalNodeType*> internalNodes;
199 mLhsTree->getNodes(internalNodes);
201 ProcessInternalNodes op(internalNodes, *mRhsTree, *mSegment, leafNodes);
202 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, internalNodes.size()), op);
205 ProcessLeafNodes op(leafNodes, *mRhsTree, *mSegment);
206 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, leafNodes.size()), op);
213 struct ProcessInternalNodes {
215 ProcessInternalNodes(std::vector<const InternalNodeType*>& lhsNodes,
const TreeType& rhsTree,
216 TreeType& outputTree, std::vector<const LeafNodeType*>& outputLeafNodes)
217 : mLhsNodes(lhsNodes.empty() ? NULL : &lhsNodes.front())
219 , mLocalTree(mRhsTree->background())
220 , mOutputTree(&outputTree)
222 , mOutputLeafNodes(&outputLeafNodes)
226 ProcessInternalNodes(ProcessInternalNodes& other, tbb::split)
227 : mLhsNodes(other.mLhsNodes)
228 , mRhsTree(other.mRhsTree)
229 , mLocalTree(mRhsTree->background())
230 , mOutputTree(&mLocalTree)
232 , mOutputLeafNodes(&mLocalLeafNodes)
236 void join(ProcessInternalNodes& other)
238 mOutputTree->merge(*other.mOutputTree);
239 mOutputLeafNodes->insert(mOutputLeafNodes->end(),
240 other.mOutputLeafNodes->begin(), other.mOutputLeafNodes->end());
243 void operator()(
const tbb::blocked_range<size_t>& range)
248 std::vector<const LeafNodeType*> tmpLeafNodes;
250 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
252 const InternalNodeType& lhsNode = *mLhsNodes[n];
253 const Coord& ijk = lhsNode.origin();
254 const InternalNodeType * rhsNode = rhsAcc.template probeConstNode<InternalNodeType>(ijk);
257 lhsNode.getNodes(*mOutputLeafNodes);
260 if (rhsAcc.
getValue(ijk) < ValueType(0.0)) {
261 tmpLeafNodes.
clear();
262 lhsNode.getNodes(tmpLeafNodes);
263 for (
size_t i = 0, I = tmpLeafNodes.size(); i < I; ++i) {
264 outputAcc.
addLeaf(
new LeafNodeType(*tmpLeafNodes[i]));
268 if (!(rhsAcc.
getValue(ijk) < ValueType(0.0))) {
269 tmpLeafNodes.clear();
270 lhsNode.getNodes(tmpLeafNodes);
271 for (
size_t i = 0, I = tmpLeafNodes.size(); i < I; ++i) {
272 outputAcc.
addLeaf(
new LeafNodeType(*tmpLeafNodes[i]));
280 InternalNodeType
const *
const *
const mLhsNodes;
281 TreeType
const *
const mRhsTree;
283 TreeType *
const mOutputTree;
285 std::vector<const LeafNodeType*> mLocalLeafNodes;
286 std::vector<const LeafNodeType*> *
const mOutputLeafNodes;
289 struct ProcessLeafNodes {
291 ProcessLeafNodes(std::vector<const LeafNodeType*>& lhsNodes,
const TreeType& rhsTree, TreeType& output)
292 : mLhsNodes(lhsNodes.empty() ? NULL : &lhsNodes.front())
294 , mLocalTree(mRhsTree->background())
295 , mOutputTree(&output)
299 ProcessLeafNodes(ProcessLeafNodes& other, tbb::split)
300 : mLhsNodes(other.mLhsNodes)
301 , mRhsTree(other.mRhsTree)
302 , mLocalTree(mRhsTree->background())
303 , mOutputTree(&mLocalTree)
307 void join(ProcessLeafNodes& rhs) { mOutputTree->merge(*rhs.mOutputTree); }
309 void operator()(
const tbb::blocked_range<size_t>& range)
314 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
316 const LeafNodeType& lhsNode = *mLhsNodes[n];
317 const Coord& ijk = lhsNode.origin();
323 LeafNodeType* outputNode = outputAcc.
touchLeaf(ijk);
324 ValueType * outputData = outputNode->buffer().data();
325 NodeMaskType& outputMask = outputNode->getValueMask();
327 const ValueType * lhsData = lhsNode.buffer().data();
328 const NodeMaskType& lhsMask = lhsNode.getValueMask();
330 const ValueType * rhsData = rhsNodePt->buffer().data();
331 const NodeMaskType& rhsMask = rhsNodePt->getValueMask();
334 for (
Index pos = 0; pos < LeafNodeType::SIZE; ++pos) {
335 const bool fromRhs = lhsData[pos] < rhsData[pos];
336 outputData[pos] = fromRhs ? rhsData[pos] : lhsData[pos];
337 outputMask.set(pos, fromRhs ? rhsMask.isOn(pos) : lhsMask.isOn(pos));
339 }
else if (Operation == CSG_DIFFERENCE){
340 for (
Index pos = 0; pos < LeafNodeType::SIZE; ++pos) {
342 const bool fromRhs = lhsData[pos] < rhsVal;
343 outputData[pos] = fromRhs ? rhsVal : lhsData[pos];
344 outputMask.set(pos, fromRhs ? rhsMask.isOn(pos) : lhsMask.isOn(pos));
347 for (
Index pos = 0; pos < LeafNodeType::SIZE; ++pos) {
348 const bool fromRhs = lhsData[pos] > rhsData[pos];
349 outputData[pos] = fromRhs ? rhsData[pos] : lhsData[pos];
350 outputMask.set(pos, fromRhs ? rhsMask.isOn(pos) : lhsMask.isOn(pos));
356 if (rhsAcc.
getValue(ijk) < ValueType(0.0)) {
357 outputAcc.
addLeaf(
new LeafNodeType(lhsNode));
360 if (!(rhsAcc.
getValue(ijk) < ValueType(0.0))) {
361 outputAcc.
addLeaf(
new LeafNodeType(lhsNode));
368 LeafNodeType
const *
const *
const mLhsNodes;
369 TreeType
const *
const mRhsTree;
371 TreeType *
const mOutputTree;
374 TreePtrType mSegment;
375 TreeType
const *
const mLhsTree;
376 TreeType
const *
const mRhsTree;
380 template<
typename TreeType, CSGOperation Operation>
389 typedef typename boost::mpl::at<NodeChainType, boost::mpl::int_<1> >::type
InternalNodeType;
392 : mSegment(new TreeType(lhs.background()))
400 std::vector<const LeafNodeType*> leafNodes;
403 std::vector<const InternalNodeType*> internalNodes;
404 mRhsTree->getNodes(internalNodes);
406 ProcessInternalNodes op(internalNodes, *mLhsTree, *mSegment, leafNodes);
407 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, internalNodes.size()), op);
410 ProcessLeafNodes op(leafNodes, *mLhsTree, *mSegment);
411 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, leafNodes.size()), op);
418 struct ProcessInternalNodes {
420 ProcessInternalNodes(std::vector<const InternalNodeType*>& rhsNodes,
const TreeType& lhsTree,
421 TreeType& outputTree, std::vector<const LeafNodeType*>& outputLeafNodes)
422 : mRhsNodes(rhsNodes.empty() ? NULL : &rhsNodes.front())
424 , mLocalTree(mLhsTree->background())
425 , mOutputTree(&outputTree)
427 , mOutputLeafNodes(&outputLeafNodes)
431 ProcessInternalNodes(ProcessInternalNodes& other, tbb::split)
432 : mRhsNodes(other.mRhsNodes)
433 , mLhsTree(other.mLhsTree)
434 , mLocalTree(mLhsTree->background())
435 , mOutputTree(&mLocalTree)
437 , mOutputLeafNodes(&mLocalLeafNodes)
441 void join(ProcessInternalNodes& other)
443 mOutputTree->merge(*other.mOutputTree);
444 mOutputLeafNodes->insert(mOutputLeafNodes->end(),
445 other.mOutputLeafNodes->begin(), other.mOutputLeafNodes->end());
448 void operator()(
const tbb::blocked_range<size_t>& range)
453 std::vector<const LeafNodeType*> tmpLeafNodes;
455 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
457 const InternalNodeType& rhsNode = *mRhsNodes[n];
458 const Coord& ijk = rhsNode.origin();
459 const InternalNodeType * lhsNode = lhsAcc.template probeConstNode<InternalNodeType>(ijk);
462 rhsNode.getNodes(*mOutputLeafNodes);
465 if (lhsAcc.
getValue(ijk) < ValueType(0.0)) {
466 tmpLeafNodes.
clear();
467 rhsNode.getNodes(tmpLeafNodes);
468 for (
size_t i = 0, I = tmpLeafNodes.size(); i < I; ++i) {
469 outputAcc.
addLeaf(
new LeafNodeType(*tmpLeafNodes[i]));
472 }
else if (Operation == CSG_DIFFERENCE) {
473 if (lhsAcc.
getValue(ijk) < ValueType(0.0)) {
474 tmpLeafNodes.clear();
475 rhsNode.getNodes(tmpLeafNodes);
476 for (
size_t i = 0, I = tmpLeafNodes.size(); i < I; ++i) {
477 LeafNodeType* outputNode =
new LeafNodeType(*tmpLeafNodes[i]);
478 outputNode->negate();
483 if (!(lhsAcc.
getValue(ijk) < ValueType(0.0))) {
484 tmpLeafNodes.clear();
485 rhsNode.getNodes(tmpLeafNodes);
486 for (
size_t i = 0, I = tmpLeafNodes.size(); i < I; ++i) {
487 outputAcc.
addLeaf(
new LeafNodeType(*tmpLeafNodes[i]));
495 InternalNodeType
const *
const *
const mRhsNodes;
496 TreeType
const *
const mLhsTree;
498 TreeType *
const mOutputTree;
500 std::vector<const LeafNodeType*> mLocalLeafNodes;
501 std::vector<const LeafNodeType*> *
const mOutputLeafNodes;
504 struct ProcessLeafNodes {
506 ProcessLeafNodes(std::vector<const LeafNodeType*>& rhsNodes,
const TreeType& lhsTree, TreeType& output)
507 : mRhsNodes(rhsNodes.empty() ? NULL : &rhsNodes.front())
509 , mLocalTree(mLhsTree->background())
510 , mOutputTree(&output)
514 ProcessLeafNodes(ProcessLeafNodes& rhs, tbb::split)
515 : mRhsNodes(rhs.mRhsNodes)
516 , mLhsTree(rhs.mLhsTree)
517 , mLocalTree(mLhsTree->background())
518 , mOutputTree(&mLocalTree)
522 void join(ProcessLeafNodes& rhs) { mOutputTree->merge(*rhs.mOutputTree); }
524 void operator()(
const tbb::blocked_range<size_t>& range)
529 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
531 const LeafNodeType& rhsNode = *mRhsNodes[n];
532 const Coord& ijk = rhsNode.origin();
538 if (lhsAcc.
getValue(ijk) < ValueType(0.0)) {
539 outputAcc.
addLeaf(
new LeafNodeType(rhsNode));
541 }
else if (Operation == CSG_DIFFERENCE) {
542 if (lhsAcc.
getValue(ijk) < ValueType(0.0)) {
543 LeafNodeType* outputNode =
new LeafNodeType(rhsNode);
544 outputNode->negate();
548 if (!(lhsAcc.
getValue(ijk) < ValueType(0.0))) {
549 outputAcc.
addLeaf(
new LeafNodeType(rhsNode));
556 LeafNodeType
const *
const *
const mRhsNodes;
557 TreeType
const *
const mLhsTree;
559 TreeType *
const mOutputTree;
562 TreePtrType mSegment;
563 TreeType
const *
const mLhsTree;
564 TreeType
const *
const mRhsTree;
568 template<CSGOperation Operation,
typename TreeType>
569 inline typename TreeType::Ptr
576 tbb::task_group tasks;
578 tasks.run(secondary);
593 template<
typename TreeType>
597 static TreeTypePtr
construct(
const TreeType&, TreeTypePtr& tree) {
return tree; }
601 template<
typename TreeType>
608 static GridTypePtr
construct(
const GridType& grid, TreeTypePtr& tree) {
609 GridTypePtr maskGrid(GridType::create(tree));
611 maskGrid->insertMeta(grid);
623 template<
typename Gr
idOrTreeT>
625 compMax(GridOrTreeT& aTree, GridOrTreeT& bTree)
628 typedef typename Adapter::TreeType TreeT;
629 typedef typename TreeT::ValueType ValueT;
635 Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op,
false);
639 template<
typename Gr
idOrTreeT>
641 compMin(GridOrTreeT& aTree, GridOrTreeT& bTree)
644 typedef typename Adapter::TreeType TreeT;
645 typedef typename TreeT::ValueType ValueT;
651 Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op,
false);
655 template<
typename Gr
idOrTreeT>
657 compSum(GridOrTreeT& aTree, GridOrTreeT& bTree)
660 typedef typename Adapter::TreeType TreeT;
666 Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op,
false);
670 template<
typename Gr
idOrTreeT>
672 compMul(GridOrTreeT& aTree, GridOrTreeT& bTree)
675 typedef typename Adapter::TreeType TreeT;
681 Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op,
false);
685 template<
typename Gr
idOrTreeT>
687 compDiv(GridOrTreeT& aTree, GridOrTreeT& bTree)
690 typedef typename Adapter::TreeType TreeT;
696 Adapter::tree(aTree).combineExtended(Adapter::tree(bTree), Local::op,
false);
703 template<
typename TreeT>
711 void operator()(
const typename TreeT::ValueOnCIter& iter)
const 714 iter.getBoundingBox(bbox);
715 aTree->fill(bbox, *iter);
718 void operator()(
const typename TreeT::LeafCIter& leafIter)
const 721 for (
typename TreeT::LeafCIter::LeafNodeT::ValueOnCIter iter =
722 leafIter->cbeginValueOn(); iter; ++iter)
724 acc.
setValue(iter.getCoord(), *iter);
730 template<
typename Gr
idOrTreeT>
735 typedef typename Adapter::TreeType TreeT;
736 typedef typename TreeT::ValueOnCIter ValueOnCIterT;
739 Adapter::tree(aTree).topologyUnion(Adapter::tree(bTree));
744 ValueOnCIterT iter = bTree.cbeginValueOn();
745 iter.setMaxDepth(iter.getLeafDepth() - 1);
746 foreach(iter, op,
false);
749 foreach(Adapter::tree(bTree).cbeginLeaf(), op);
758 template<
typename TreeType>
763 typedef typename TreeT::ValueType
ValueT;
764 typedef typename TreeT::LeafNodeType::ChildAllIter
ChildIterT;
769 mAOutside(aTree.background()),
770 mAInside(math::
negative(mAOutside)),
771 mBOutside(bTree.background()),
774 const ValueT zero = zeroVal<ValueT>();
775 if (!(mAOutside > zero)) {
777 "expected grid A outside value > 0, got " << mAOutside);
779 if (!(mAInside < zero)) {
781 "expected grid A inside value < 0, got " << mAInside);
783 if (!(mBOutside > zero)) {
785 "expected grid B outside value > 0, got " << mBOutside);
787 if (!(mBInside < zero)) {
789 "expected grid B outside value < 0, got " << mBOutside);
801 template<
typename TreeType>
805 typedef typename TreeT::ValueType
ValueT;
806 typedef typename TreeT::LeafNodeType::ChildAllIter
ChildIterT;
813 template<
typename AIterT,
typename BIterT>
817 template<
typename IterT>
820 ValueT aValue = zeroVal<ValueT>();
821 typename IterT::ChildNodeType* aChild = aIter.probeChild(aValue);
822 if (!aChild && aValue < zeroVal<ValueT>()) {
827 ValueT bValue = zeroVal<ValueT>();
828 typename IterT::ChildNodeType* bChild = bIter.probeChild(bValue);
829 if (!bChild && bValue < zeroVal<ValueT>()) {
831 aIter.setValue(this->mAInside);
832 aIter.setValueOn(bIter.isValueOn());
837 if (!aChild && aValue > zeroVal<ValueT>()) {
841 bIter.setValue(this->mBOutside);
843 bChild->resetBackground(this->mBOutside, this->mAOutside);
844 aIter.setChild(bChild);
852 return (aChild && bChild) ? 0 : STOP;
858 ValueT aValue, bValue;
859 aIter.probeValue(aValue);
860 bIter.probeValue(bValue);
861 if (aValue > bValue) {
862 aIter.setValue(bValue);
863 aIter.setValueOn(bIter.isValueOn());
874 template<
typename TreeType>
878 typedef typename TreeT::ValueType
ValueT;
879 typedef typename TreeT::LeafNodeType::ChildAllIter
ChildIterT;
886 template<
typename AIterT,
typename BIterT>
890 template<
typename IterT>
893 ValueT aValue = zeroVal<ValueT>();
894 typename IterT::ChildNodeType* aChild = aIter.probeChild(aValue);
895 if (!aChild && !(aValue < zeroVal<ValueT>())) {
900 ValueT bValue = zeroVal<ValueT>();
901 typename IterT::ChildNodeType* bChild = bIter.probeChild(bValue);
902 if (!bChild && !(bValue < zeroVal<ValueT>())) {
904 aIter.setValue(this->mAOutside);
905 aIter.setValueOn(bIter.isValueOn());
910 if (!aChild && aValue < zeroVal<ValueT>()) {
914 bIter.setValue(this->mBOutside);
916 bChild->resetBackground(this->mBOutside, this->mAOutside);
917 aIter.setChild(bChild);
925 return (aChild && bChild) ? 0 : STOP;
931 ValueT aValue, bValue;
932 aIter.probeValue(aValue);
933 bIter.probeValue(bValue);
934 if (aValue < bValue) {
935 aIter.setValue(bValue);
936 aIter.setValueOn(bIter.isValueOn());
946 template<
typename TreeType>
950 typedef typename TreeT::ValueType
ValueT;
951 typedef typename TreeT::LeafNodeType::ChildAllIter
ChildIterT;
958 template<
typename AIterT,
typename BIterT>
962 template<
typename IterT>
965 ValueT aValue = zeroVal<ValueT>();
966 typename IterT::ChildNodeType* aChild = aIter.probeChild(aValue);
967 if (!aChild && !(aValue < zeroVal<ValueT>())) {
972 ValueT bValue = zeroVal<ValueT>();
973 typename IterT::ChildNodeType* bChild = bIter.probeChild(bValue);
974 if (!bChild && bValue < zeroVal<ValueT>()) {
976 aIter.setValue(this->mAOutside);
977 aIter.setValueOn(bIter.isValueOn());
982 if (!aChild && aValue < zeroVal<ValueT>()) {
986 bIter.setValue(this->mBOutside);
988 bChild->resetBackground(this->mBOutside, this->mAOutside);
989 aIter.setChild(bChild);
998 return (aChild && bChild) ? 0 : STOP;
1004 ValueT aValue, bValue;
1005 aIter.probeValue(aValue);
1006 bIter.probeValue(bValue);
1008 if (aValue < bValue) {
1009 aIter.setValue(bValue);
1010 aIter.setValueOn(bIter.isValueOn());
1020 template<
typename Gr
idOrTreeT>
1025 typedef typename Adapter::TreeType TreeT;
1026 TreeT &aTree = Adapter::tree(a), &bTree = Adapter::tree(b);
1028 aTree.visit2(bTree, visitor);
1032 template<
typename Gr
idOrTreeT>
1037 typedef typename Adapter::TreeType TreeT;
1038 TreeT &aTree = Adapter::tree(a), &bTree = Adapter::tree(b);
1040 aTree.visit2(bTree, visitor);
1044 template<
typename Gr
idOrTreeT>
1049 typedef typename Adapter::TreeType TreeT;
1050 TreeT &aTree = Adapter::tree(a), &bTree = Adapter::tree(b);
1052 aTree.visit2(bTree, visitor);
1057 template<
typename Gr
idOrTreeT>
1062 typedef typename Adapter::TreeType::Ptr TreePtrT;
1064 TreePtrT output = composite::doCSGCopy<composite::CSG_UNION>(
1065 Adapter::tree(a), Adapter::tree(b));
1071 template<
typename Gr
idOrTreeT>
1076 typedef typename Adapter::TreeType::Ptr TreePtrT;
1078 TreePtrT output = composite::doCSGCopy<composite::CSG_INTERSECTION>(
1079 Adapter::tree(a), Adapter::tree(b));
1085 template<
typename Gr
idOrTreeT>
1090 typedef typename Adapter::TreeType::Ptr TreePtrT;
1092 TreePtrT output = composite::doCSGCopy<composite::CSG_DIFFERENCE>(
1093 Adapter::tree(a), Adapter::tree(b));
1103 #endif // OPENVDB_TOOLS_COMPOSITE_HAS_BEEN_INCLUDED
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: ValueAccessor.h:374
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
math::Transform & transform()
Return a reference to this grid's transform, which might be shared with other grids.
Definition: Grid.h:346
Defined various multi-threaded utility functions for trees.
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:256
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Propagates the sign of distance values from the active voxels in the narrow band to the inactive valu...
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:371
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z), or nullptr if no such node exists...
Definition: ValueAccessor.h:429
CombineArgs & setResult(const AValueType &val)
Set the output value.
Definition: Types.h:421
Definition: Exceptions.h:39
const AValueType & a() const
Get the A input value.
Definition: Types.h:411
virtual void clear()
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:438
LeafNodeT * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, create one, but preserve the values and active states of all voxels.
Definition: ValueAccessor.h:393
Definition: Exceptions.h:92
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:116
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:935
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Index32 Index
Definition: Types.h:57
SharedPtr< Grid > Ptr
Definition: Grid.h:501
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:287
const BValueType & b() const
Get the B input value.
Definition: Types.h:413