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
CombineArgs & setResult(const AValueType &val)
Set the output value.
Definition: Types.h:362
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:47
boost::shared_ptr< Grid > Ptr
Definition: Grid.h:485
math::Transform & transform()
Return a reference to this grid's transform, which might be shared with other grids.
Definition: Grid.h:335
Defined various multi-threaded utility functions for trees.
const AValueType & a() const
Get the A input value.
Definition: Types.h:352
Index32 Index
Definition: Types.h:58
#define OPENVDB_VERSION_NAME
Definition: version.h:43
const BValueType & b() const
Get the B input value.
Definition: Types.h:354
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:256
Propagates the sign of distance values from the active voxels in the narrow band to the inactive valu...
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:898
Definition: Exceptions.h:39
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
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:259
Definition: Exceptions.h:88
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z), or NULL if no such node exists...
Definition: ValueAccessor.h:429
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:312
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54
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