35 #ifndef OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED
36 #define OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED
38 #include <boost/shared_array.hpp>
39 #include <boost/static_assert.hpp>
40 #include <boost/mpl/if.hpp>
41 #include <boost/type_traits/is_const.hpp>
42 #include <boost/type_traits/is_pointer.hpp>
43 #include <boost/type_traits/remove_pointer.hpp>
44 #include <openvdb/Platform.h>
45 #include <openvdb/util/NodeMasks.h>
46 #include <openvdb/io/Compression.h>
47 #include <openvdb/math/Math.h>
48 #include <openvdb/version.h>
49 #include <openvdb/Types.h>
62 template<
typename _ChildNodeType, Index Log2Dim>
68 typedef typename ChildNodeType::ValueType
ValueType;
74 TOTAL = Log2Dim + ChildNodeType::TOTAL,
76 NUM_VALUES = 1 << (3 * Log2Dim),
77 LEVEL = 1 + ChildNodeType::LEVEL;
79 NUM_VOXELS = uint64_t(1) << (3 * TOTAL);
83 template<
typename OtherValueType>
92 template<
typename OtherNodeType>
94 static const bool value =
103 InternalNode(
const Coord&,
const ValueType& fillValue,
bool active =
false);
105 #ifndef OPENVDB_2_ABI_COMPATIBLE
113 template<
typename OtherChildNodeType>
117 template<
typename OtherChildNodeType>
122 template<
typename OtherChildNodeType>
124 const ValueType& offValue,
const ValueType& onValue,
TopologyCopy);
140 template<
typename NodeT,
typename ChildT,
typename MaskIterT,
typename TagT>
142 MaskIterT, ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>
146 MaskIterT,
ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>(iter, parent) {}
150 assert(this->parent().isChildMaskOn(pos));
151 return *(this->parent().getChildNode(pos));
155 void setItem(
Index pos,
const ChildT& c)
const { this->parent().resetChildNode(pos, &c); }
160 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
162 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
166 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
168 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
171 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
174 template<
typename ModifyOp>
177 op(this->parent().mNodes[pos].getValue());
181 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
183 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
189 DenseIter(
const MaskDenseIterator& iter, NodeT* parent):
194 if (this->parent().isChildMaskOn(pos)) {
195 child = this->parent().getChildNode(pos);
199 value = this->parent().mNodes[pos].getValue();
206 this->parent().resetChildNode(pos, child);
212 this->parent().unsetChildNode(pos, value);
232 ChildOnCIter
cbeginChildOn()
const {
return ChildOnCIter(mChildMask.beginOn(),
this); }
233 ChildOffCIter
cbeginChildOff()
const {
return ChildOffCIter(mChildMask.beginOff(),
this); }
234 ChildAllCIter
cbeginChildAll()
const {
return ChildAllCIter(mChildMask.beginDense(),
this); }
238 ChildOnIter
beginChildOn() {
return ChildOnIter(mChildMask.beginOn(),
this); }
239 ChildOffIter
beginChildOff() {
return ChildOffIter(mChildMask.beginOff(),
this); }
240 ChildAllIter
beginChildAll() {
return ChildAllIter(mChildMask.beginDense(),
this); }
242 ValueOnCIter
cbeginValueOn()
const {
return ValueOnCIter(mValueMask.beginOn(),
this); }
244 ValueOffCIter
cbeginValueOff()
const {
return ValueOffCIter(mValueMask.beginOff(),
this); }
245 ValueAllCIter
cbeginValueAll()
const {
return ValueAllCIter(mChildMask.beginOff(),
this); }
250 ValueOnIter
beginValueOn() {
return ValueOnIter(mValueMask.beginOn(),
this); }
252 ValueOffIter
beginValueOff() {
return ValueOffIter(mValueMask.beginOff(),
this); }
253 ValueAllIter
beginValueAll() {
return ValueAllIter(mChildMask.beginOff(),
this); }
258 static void getNodeLog2Dims(std::vector<Index>& dims);
262 static Index coordToOffset(
const Coord& xyz);
265 static void offsetToLocalCoord(
Index n, Coord& xyz);
267 Coord offsetToGlobalCoord(
Index n)
const;
270 const Coord&
origin()
const {
return mOrigin; }
272 void setOrigin(
const Coord& origin) { mOrigin = origin; }
278 Index64 onLeafVoxelCount()
const;
279 Index64 offLeafVoxelCount()
const;
289 void evalActiveBoundingBox(CoordBBox& bbox,
bool visitVoxels =
true)
const;
295 bool isEmpty()
const {
return mChildMask.isOff(); }
300 bool isConstant(ValueType& constValue,
bool& state,
301 const ValueType& tolerance = zeroVal<ValueType>())
const;
303 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
306 bool isValueOn(
const Coord& xyz)
const;
311 bool hasActiveTiles()
const;
313 const ValueType& getValue(
const Coord& xyz)
const;
314 bool probeValue(
const Coord& xyz, ValueType& value)
const;
318 Index getValueLevel(
const Coord& xyz)
const;
322 const ValueType& getFirstValue()
const;
325 const ValueType& getLastValue()
const;
328 void setActiveState(
const Coord& xyz,
bool on);
330 void setValueOnly(
const Coord& xyz,
const ValueType& value);
332 void setValueOn(
const Coord& xyz);
334 void setValueOn(
const Coord& xyz,
const ValueType& value);
336 void setValueOff(
const Coord& xyz);
338 void setValueOff(
const Coord& xyz,
const ValueType& value);
342 template<
typename ModifyOp>
343 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
345 template<
typename ModifyOp>
346 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
352 template<
typename AccessorT>
353 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
359 template<
typename AccessorT>
360 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
366 template<
typename AccessorT>
367 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
373 template<
typename AccessorT>
374 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
381 template<
typename ModifyOp,
typename AccessorT>
382 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
388 template<
typename ModifyOp,
typename AccessorT>
389 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
395 template<
typename AccessorT>
396 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
402 template<
typename AccessorT>
403 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
410 template<
typename AccessorT>
411 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
419 template<
typename AccessorT>
420 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
428 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
429 void readTopology(std::istream&,
bool fromHalf =
false);
430 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
431 void readBuffers(std::istream&,
bool fromHalf =
false);
432 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
440 void fill(
const CoordBBox& bbox,
const ValueType&,
bool active =
true);
447 void voxelizeActiveTiles();
456 template<
typename DenseT>
457 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
461 template<MergePolicy Policy>
462 void merge(
InternalNode& other,
const ValueType& background,
const ValueType& otherBackground);
466 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
480 template<
typename OtherChildNodeType>
496 template<
typename OtherChildNodeType>
498 const ValueType& background);
511 template<
typename OtherChildNodeType>
513 const ValueType& background);
515 template<
typename CombineOp>
517 template<
typename CombineOp>
518 void combine(
const ValueType& value,
bool valueIsActive, CombineOp&);
520 template<
typename CombineOp,
typename OtherNodeType >
521 void combine2(
const InternalNode& other0,
const OtherNodeType& other1, CombineOp&);
522 template<
typename CombineOp,
typename OtherNodeType >
523 void combine2(
const ValueType& value,
const OtherNodeType& other,
bool valIsActive, CombineOp&);
524 template<
typename CombineOp,
typename OtherValueType>
525 void combine2(
const InternalNode& other,
const OtherValueType&,
bool valIsActive, CombineOp&);
532 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
534 template<
typename VisitorOp>
void visit(VisitorOp&);
535 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
537 template<
typename OtherNodeType,
typename VisitorOp>
538 void visit2Node(OtherNodeType& other, VisitorOp&);
539 template<
typename OtherNodeType,
typename VisitorOp>
540 void visit2Node(OtherNodeType& other, VisitorOp&)
const;
541 template<
typename IterT,
typename VisitorOp>
542 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false);
543 template<
typename IterT,
typename VisitorOp>
544 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false)
const;
547 void clip(
const CoordBBox&,
const ValueType& background);
552 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
556 void addLeaf(LeafNodeType* leaf);
560 template<
typename AccessorT>
561 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
571 template<
typename NodeT>
572 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
576 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
579 void addTile(
Index offset,
const ValueType& value,
bool state);
583 template<
typename AccessorT>
584 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
587 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
590 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
594 template<
typename NodeType,
typename AccessorT>
597 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
598 template<
typename NodeType,
typename AccessorT>
599 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
603 LeafNodeType* probeLeaf(
const Coord& xyz);
606 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
607 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
611 template<
typename AccessorT>
614 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
615 template<
typename AccessorT>
616 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
617 template<
typename AccessorT>
618 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
627 LeafNodeType* touchLeaf(
const Coord& xyz);
631 template<
typename AccessorT>
632 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
635 template<
typename ArrayT>
void getNodes(ArrayT& array);
658 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
663 void resetBackground(
const ValueType& oldBackground,
const ValueType& newBackground);
667 template<
typename OtherChildNodeType, Index OtherLog2Dim>
696 NodeMaskType mask = mValueMask;
701 const UnionType*
getTable()
const {
return mNodes; }
704 void setValueMask(
Index n,
bool on) { mValueMask.set(n, mChildMask.isOn(n) ?
false : on); }
709 void makeChildNodeEmpty(
Index n,
const ValueType& value);
710 void setChildNode(
Index i, ChildNodeType* child);
711 void resetChildNode(
Index i, ChildNodeType* child);
712 ChildNodeType* unsetChildNode(
Index i,
const ValueType& value);
714 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
715 static inline void doVisit(NodeT&, VisitorOp&);
717 template<
typename NodeT,
typename OtherNodeT,
typename VisitorOp,
718 typename ChildAllIterT,
typename OtherChildAllIterT>
719 static inline void doVisit2Node(NodeT&, OtherNodeT&, VisitorOp&);
721 template<
typename NodeT,
typename VisitorOp,
722 typename ChildAllIterT,
typename OtherChildAllIterT>
723 static inline void doVisit2(NodeT&, OtherChildAllIterT&, VisitorOp&,
bool otherIsLHS);
729 ChildNodeType* getChildNode(
Index n);
730 const ChildNodeType* getChildNode(
Index n)
const;
734 UnionType mNodes[NUM_VALUES];
745 template<
typename ChildT1, Index Dim1,
typename NodeT2>
749 static const bool value =
false;
752 template<
typename ChildT1, Index Dim1,
typename ChildT2>
754 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
762 template<
typename ChildT, Index Log2Dim>
766 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(background);
770 template<
typename ChildT, Index Log2Dim>
773 mOrigin(origin[0] & ~(DIM - 1),
774 origin[1] & ~(DIM - 1),
775 origin[2] & ~(DIM - 1))
782 #ifndef OPENVDB_2_ABI_COMPATIBLE
785 template<
typename ChildT, Index Log2Dim>
788 const Coord& origin,
const ValueType& val,
bool active)
789 : mOrigin(origin[0] & ~(DIM-1), origin[1] & ~(DIM-1), origin[2] & ~(DIM-1))
797 template<
typename ChildT, Index Log2Dim>
800 mChildMask(other.mChildMask),
801 mValueMask(other.mValueMask),
802 mOrigin(other.mOrigin)
815 template<
typename ChildT, Index Log2Dim>
816 template<
typename OtherChildNodeType>
819 : mChildMask(other.mChildMask)
820 , mValueMask(other.mValueMask)
821 , mOrigin(other.mOrigin)
825 static inline ValueType
826 convertValue(
const typename OtherChildNodeType::ValueType& val) {
return ValueType(val); }
831 mNodes[i].setValue(Local::convertValue(other.
mNodes[i].getValue()));
839 template<
typename ChildT, Index Log2Dim>
840 template<
typename OtherChildNodeType>
843 const ValueType& offValue,
const ValueType& onValue,
TopologyCopy):
844 mChildMask(other.mChildMask),
845 mValueMask(other.mValueMask),
846 mOrigin(other.mOrigin)
858 template<
typename ChildT, Index Log2Dim>
859 template<
typename OtherChildNodeType>
863 mChildMask(other.mChildMask),
864 mValueMask(other.mValueMask),
865 mOrigin(other.mOrigin)
868 for (ChildOnIter iter = this->
beginChildOn(); iter; ++iter) {
875 template<
typename ChildT, Index Log2Dim>
879 for (ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
880 delete mNodes[iter.pos()].getChild();
888 template<
typename ChildT, Index Log2Dim>
892 if (ChildNodeType::getLevel() == 0)
return mChildMask.countOn();
894 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
895 sum += iter->leafCount();
901 template<
typename ChildT, Index Log2Dim>
906 if (ChildNodeType::getLevel() == 0)
return sum;
907 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
908 sum += iter->nonLeafCount();
914 template<
typename ChildT, Index Log2Dim>
918 Index64 sum = ChildT::NUM_VOXELS * mValueMask.countOn();
919 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
920 sum += iter->onVoxelCount();
926 template<
typename ChildT, Index Log2Dim>
930 Index64 sum = ChildT::NUM_VOXELS * (NUM_VALUES-mValueMask.countOn()-mChildMask.countOn());
931 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
932 sum += iter->offVoxelCount();
938 template<
typename ChildT, Index Log2Dim>
943 for (ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
944 sum += mNodes[iter.pos()].getChild()->onLeafVoxelCount();
950 template<
typename ChildT, Index Log2Dim>
955 for (ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
956 sum += mNodes[iter.pos()].getChild()->offLeafVoxelCount();
961 template<
typename ChildT, Index Log2Dim>
965 Index64 sum = mValueMask.countOn();
966 for (ChildOnCIter iter = this->cbeginChildOn(); LEVEL>1 && iter; ++iter) {
967 sum += iter->onTileCount();
972 template<
typename ChildT, Index Log2Dim>
976 Index64 sum = NUM_VALUES *
sizeof(UnionType) + mChildMask.memUsage()
977 + mValueMask.memUsage() +
sizeof(mOrigin);
978 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
979 sum += iter->memUsage();
985 template<
typename ChildT, Index Log2Dim>
989 if (bbox.isInside(this->getNodeBoundingBox()))
return;
991 for (ValueOnCIter i = this->cbeginValueOn(); i; ++i) {
992 bbox.expand(i.getCoord(), ChildT::DIM);
994 for (ChildOnCIter i = this->cbeginChildOn(); i; ++i) {
995 i->evalActiveBoundingBox(bbox, visitVoxels);
1003 template<
typename ChildT, Index Log2Dim>
1008 ValueType value = zeroVal<ValueType>();
1009 for (ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1010 const Index i = iter.pos();
1011 ChildT* child = mNodes[i].getChild();
1012 child->prune(tolerance);
1013 if (child->isConstant(value, state, tolerance)) {
1015 mChildMask.setOff(i);
1016 mValueMask.set(i, state);
1017 mNodes[i].setValue(value);
1026 template<
typename ChildT, Index Log2Dim>
1027 template<
typename NodeT>
1031 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1032 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1034 const Index n = this->coordToOffset(xyz);
1035 if (mChildMask.isOff(n))
return NULL;
1036 ChildT* child = mNodes[n].getChild();
1037 if (boost::is_same<NodeT, ChildT>::value) {
1038 mChildMask.setOff(n);
1039 mValueMask.set(n, state);
1040 mNodes[n].setValue(value);
1042 return (boost::is_same<NodeT, ChildT>::value)
1043 ?
reinterpret_cast<NodeT*
>(child)
1044 : child->template stealNode<NodeT>(xyz, value, state);
1052 template<
typename ChildT, Index Log2Dim>
1053 template<
typename NodeT>
1057 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1058 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1060 const Index n = this->coordToOffset(xyz);
1061 if (mChildMask.isOff(n))
return NULL;
1062 ChildT* child = mNodes[n].getChild();
1063 return (boost::is_same<NodeT, ChildT>::value)
1064 ?
reinterpret_cast<NodeT*
>(child)
1065 : child->template probeNode<NodeT>(xyz);
1070 template<
typename ChildT, Index Log2Dim>
1071 template<
typename NodeT,
typename AccessorT>
1075 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1076 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1078 const Index n = this->coordToOffset(xyz);
1079 if (mChildMask.isOff(n))
return NULL;
1080 ChildT* child = mNodes[n].getChild();
1081 acc.insert(xyz, child);
1082 return (boost::is_same<NodeT, ChildT>::value)
1083 ?
reinterpret_cast<NodeT*
>(child)
1084 : child->template probeNodeAndCache<NodeT>(xyz, acc);
1089 template<
typename ChildT, Index Log2Dim>
1090 template<
typename NodeT>
1094 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1095 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1097 const Index n = this->coordToOffset(xyz);
1098 if (mChildMask.isOff(n))
return NULL;
1099 const ChildT* child = mNodes[n].getChild();
1100 return (boost::is_same<NodeT, ChildT>::value)
1101 ?
reinterpret_cast<const NodeT*
>(child)
1102 : child->template probeConstNode<NodeT>(xyz);
1107 template<
typename ChildT, Index Log2Dim>
1108 template<
typename NodeT,
typename AccessorT>
1112 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1113 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1115 const Index n = this->coordToOffset(xyz);
1116 if (mChildMask.isOff(n))
return NULL;
1117 const ChildT* child = mNodes[n].getChild();
1118 acc.insert(xyz, child);
1119 return (boost::is_same<NodeT, ChildT>::value)
1120 ?
reinterpret_cast<const NodeT*
>(child)
1121 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
1129 template<
typename ChildT, Index Log2Dim>
1130 inline typename ChildT::LeafNodeType*
1133 return this->
template probeNode<LeafNodeType>(xyz);
1137 template<
typename ChildT, Index Log2Dim>
1138 template<
typename AccessorT>
1139 inline typename ChildT::LeafNodeType*
1142 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
1146 template<
typename ChildT, Index Log2Dim>
1147 template<
typename AccessorT>
1148 inline const typename ChildT::LeafNodeType*
1151 return this->probeConstLeafAndCache(xyz, acc);
1155 template<
typename ChildT, Index Log2Dim>
1156 inline const typename ChildT::LeafNodeType*
1159 return this->
template probeConstNode<LeafNodeType>(xyz);
1163 template<
typename ChildT, Index Log2Dim>
1164 template<
typename AccessorT>
1165 inline const typename ChildT::LeafNodeType*
1168 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
1175 template<
typename ChildT, Index Log2Dim>
1179 assert(leaf != NULL);
1180 const Coord& xyz = leaf->origin();
1181 const Index n = this->coordToOffset(xyz);
1182 ChildT* child = NULL;
1183 if (mChildMask.isOff(n)) {
1184 if (ChildT::LEVEL>0) {
1185 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1187 child =
reinterpret_cast<ChildT*
>(leaf);
1189 this->setChildNode(n, child);
1191 if (ChildT::LEVEL>0) {
1192 child = mNodes[n].getChild();
1194 delete mNodes[n].getChild();
1195 child =
reinterpret_cast<ChildT*
>(leaf);
1196 mNodes[n].setChild(child);
1199 child->addLeaf(leaf);
1203 template<
typename ChildT, Index Log2Dim>
1204 template<
typename AccessorT>
1208 assert(leaf != NULL);
1209 const Coord& xyz = leaf->origin();
1210 const Index n = this->coordToOffset(xyz);
1211 ChildT* child = NULL;
1212 if (mChildMask.isOff(n)) {
1213 if (ChildT::LEVEL>0) {
1214 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1215 acc.insert(xyz, child);
1217 child =
reinterpret_cast<ChildT*
>(leaf);
1219 this->setChildNode(n, child);
1221 if (ChildT::LEVEL>0) {
1222 child = mNodes[n].getChild();
1223 acc.insert(xyz, child);
1225 delete mNodes[n].getChild();
1226 child =
reinterpret_cast<ChildT*
>(leaf);
1227 mNodes[n].setChild(child);
1230 child->addLeafAndCache(leaf, acc);
1237 template<
typename ChildT, Index Log2Dim>
1241 assert(n < NUM_VALUES);
1242 this->makeChildNodeEmpty(n, value);
1243 mValueMask.set(n, state);
1247 template<
typename ChildT, Index Log2Dim>
1250 const ValueType& value,
bool state)
1252 if (LEVEL >= level) {
1253 const Index n = this->coordToOffset(xyz);
1254 if (mChildMask.isOff(n)) {
1255 if (LEVEL > level) {
1256 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1257 this->setChildNode(n, child);
1258 child->addTile(level, xyz, value, state);
1260 mValueMask.set(n, state);
1261 mNodes[n].setValue(value);
1264 ChildT* child = mNodes[n].getChild();
1265 if (LEVEL > level) {
1266 child->addTile(level, xyz, value, state);
1269 mChildMask.setOff(n);
1270 mValueMask.set(n, state);
1271 mNodes[n].setValue(value);
1278 template<
typename ChildT, Index Log2Dim>
1279 template<
typename AccessorT>
1282 const ValueType& value,
bool state, AccessorT& acc)
1284 if (LEVEL >= level) {
1285 const Index n = this->coordToOffset(xyz);
1286 if (mChildMask.isOff(n)) {
1287 if (LEVEL > level) {
1288 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1289 this->setChildNode(n, child);
1290 acc.insert(xyz, child);
1291 child->addTileAndCache(level, xyz, value, state, acc);
1293 mValueMask.set(n, state);
1294 mNodes[n].setValue(value);
1297 ChildT* child = mNodes[n].getChild();
1298 if (LEVEL > level) {
1299 acc.insert(xyz, child);
1300 child->addTileAndCache(level, xyz, value, state, acc);
1303 mChildMask.setOff(n);
1304 mValueMask.set(n, state);
1305 mNodes[n].setValue(value);
1315 template<
typename ChildT, Index Log2Dim>
1316 inline typename ChildT::LeafNodeType*
1319 const Index n = this->coordToOffset(xyz);
1320 ChildT* child = NULL;
1321 if (mChildMask.isOff(n)) {
1322 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1323 this->setChildNode(n, child);
1325 child = mNodes[n].getChild();
1327 return child->touchLeaf(xyz);
1331 template<
typename ChildT, Index Log2Dim>
1332 template<
typename AccessorT>
1333 inline typename ChildT::LeafNodeType*
1336 const Index n = this->coordToOffset(xyz);
1337 if (mChildMask.isOff(n)) {
1338 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), mValueMask.isOn(n)));
1340 acc.insert(xyz, mNodes[n].getChild());
1341 return mNodes[n].getChild()->touchLeafAndCache(xyz, acc);
1348 template<
typename ChildT, Index Log2Dim>
1351 const ValueType& tolerance)
const
1353 bool allEqual =
true, firstValue =
true, valueState =
true;
1354 ValueType value = zeroVal<ValueType>();
1355 for (
Index i = 0; allEqual && i < NUM_VALUES; ++i) {
1356 if (this->isChildMaskOff(i)) {
1361 valueState = isValueMaskOn(i);
1362 value = mNodes[i].getValue();
1364 allEqual = (isValueMaskOn(i) == valueState)
1370 ValueType childValue = zeroVal<ValueType>();
1371 bool isChildOn =
false;
1372 if (mNodes[i].getChild()->isConstant(childValue, isChildOn, tolerance)) {
1375 valueState = isChildOn;
1378 allEqual = (isChildOn == valueState)
1397 template<
typename ChildT, Index Log2Dim>
1402 const bool anyActiveTiles = !mValueMask.isOff();
1403 if (LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1404 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1405 if (iter->hasActiveTiles())
return true;
1412 template<
typename ChildT, Index Log2Dim>
1416 const Index n = this->coordToOffset(xyz);
1417 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1418 return mNodes[n].getChild()->isValueOn(xyz);
1421 template<
typename ChildT, Index Log2Dim>
1422 template<
typename AccessorT>
1426 const Index n = this->coordToOffset(xyz);
1427 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1428 acc.insert(xyz, mNodes[n].getChild());
1429 return mNodes[n].getChild()->isValueOnAndCache(xyz, acc);
1433 template<
typename ChildT, Index Log2Dim>
1434 inline const typename ChildT::ValueType&
1437 const Index n = this->coordToOffset(xyz);
1438 return this->isChildMaskOff(n) ? mNodes[n].getValue()
1439 : mNodes[n].getChild()->getValue(xyz);
1442 template<
typename ChildT, Index Log2Dim>
1443 template<
typename AccessorT>
1444 inline const typename ChildT::ValueType&
1447 const Index n = this->coordToOffset(xyz);
1448 if (this->isChildMaskOn(n)) {
1449 acc.insert(xyz, mNodes[n].getChild());
1450 return mNodes[n].getChild()->getValueAndCache(xyz, acc);
1452 return mNodes[n].getValue();
1456 template<
typename ChildT, Index Log2Dim>
1460 const Index n = this->coordToOffset(xyz);
1461 return this->isChildMaskOff(n) ? LEVEL : mNodes[n].getChild()->getValueLevel(xyz);
1464 template<
typename ChildT, Index Log2Dim>
1465 template<
typename AccessorT>
1469 const Index n = this->coordToOffset(xyz);
1470 if (this->isChildMaskOn(n)) {
1471 acc.insert(xyz, mNodes[n].getChild());
1472 return mNodes[n].getChild()->getValueLevelAndCache(xyz, acc);
1478 template<
typename ChildT, Index Log2Dim>
1482 const Index n = this->coordToOffset(xyz);
1483 if (this->isChildMaskOff(n)) {
1484 value = mNodes[n].getValue();
1485 return this->isValueMaskOn(n);
1487 return mNodes[n].getChild()->probeValue(xyz, value);
1490 template<
typename ChildT, Index Log2Dim>
1491 template<
typename AccessorT>
1494 ValueType& value, AccessorT& acc)
const
1496 const Index n = this->coordToOffset(xyz);
1497 if (this->isChildMaskOn(n)) {
1498 acc.insert(xyz, mNodes[n].getChild());
1499 return mNodes[n].getChild()->probeValueAndCache(xyz, value, acc);
1501 value = mNodes[n].getValue();
1502 return this->isValueMaskOn(n);
1506 template<
typename ChildT, Index Log2Dim>
1510 const Index n = this->coordToOffset(xyz);
1511 bool hasChild = this->isChildMaskOn(n);
1512 if (!hasChild && this->isValueMaskOn(n)) {
1516 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
true));
1518 if (hasChild) mNodes[n].getChild()->setValueOff(xyz);
1522 template<
typename ChildT, Index Log2Dim>
1526 const Index n = this->coordToOffset(xyz);
1527 bool hasChild = this->isChildMaskOn(n);
1528 if (!hasChild && !this->isValueMaskOn(n)) {
1532 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
false));
1534 if (hasChild) mNodes[n].getChild()->setValueOn(xyz);
1538 template<
typename ChildT, Index Log2Dim>
1543 bool hasChild = this->isChildMaskOn(n);
1545 const bool active = this->isValueMaskOn(n);
1551 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1554 if (hasChild) mNodes[n].getChild()->setValueOff(xyz, value);
1557 template<
typename ChildT, Index Log2Dim>
1558 template<
typename AccessorT>
1561 const ValueType& value, AccessorT& acc)
1564 bool hasChild = this->isChildMaskOn(n);
1566 const bool active = this->isValueMaskOn(n);
1572 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1576 ChildT* child = mNodes[n].getChild();
1577 acc.insert(xyz, child);
1578 child->setValueOffAndCache(xyz, value, acc);
1583 template<
typename ChildT, Index Log2Dim>
1587 const Index n = this->coordToOffset(xyz);
1588 bool hasChild = this->isChildMaskOn(n);
1590 const bool active = this->isValueMaskOn(n);
1596 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1599 if (hasChild) mNodes[n].getChild()->setValueOn(xyz, value);
1602 template<
typename ChildT, Index Log2Dim>
1603 template<
typename AccessorT>
1606 const ValueType& value, AccessorT& acc)
1608 const Index n = this->coordToOffset(xyz);
1609 bool hasChild = this->isChildMaskOn(n);
1611 const bool active = this->isValueMaskOn(n);
1617 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1621 acc.insert(xyz, mNodes[n].getChild());
1622 mNodes[n].getChild()->setValueAndCache(xyz, value, acc);
1627 template<
typename ChildT, Index Log2Dim>
1631 const Index n = this->coordToOffset(xyz);
1632 bool hasChild = this->isChildMaskOn(n);
1636 const bool active = this->isValueMaskOn(n);
1638 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1640 if (hasChild) mNodes[n].getChild()->setValueOnly(xyz, value);
1643 template<
typename ChildT, Index Log2Dim>
1644 template<
typename AccessorT>
1647 const ValueType& value, AccessorT& acc)
1649 const Index n = this->coordToOffset(xyz);
1650 bool hasChild = this->isChildMaskOn(n);
1654 const bool active = this->isValueMaskOn(n);
1656 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1659 acc.insert(xyz, mNodes[n].getChild());
1660 mNodes[n].getChild()->setValueOnlyAndCache(xyz, value, acc);
1665 template<
typename ChildT, Index Log2Dim>
1669 const Index n = this->coordToOffset(xyz);
1670 bool hasChild = this->isChildMaskOn(n);
1672 if (on != this->isValueMaskOn(n)) {
1677 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1680 if (hasChild) mNodes[n].getChild()->setActiveState(xyz, on);
1683 template<
typename ChildT, Index Log2Dim>
1684 template<
typename AccessorT>
1688 const Index n = this->coordToOffset(xyz);
1689 bool hasChild = this->isChildMaskOn(n);
1691 if (on != this->isValueMaskOn(n)) {
1696 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1700 ChildT* child = mNodes[n].getChild();
1701 acc.insert(xyz, child);
1702 child->setActiveStateAndCache(xyz, on, acc);
1707 template<
typename ChildT, Index Log2Dim>
1711 mValueMask = !mChildMask;
1712 for (ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1713 mNodes[iter.pos()].getChild()->setValuesOn();
1718 template<
typename ChildT, Index Log2Dim>
1719 template<
typename ModifyOp>
1724 bool hasChild = this->isChildMaskOn(n);
1728 const bool active = this->isValueMaskOn(n);
1729 bool createChild = !active;
1733 const ValueType& tileVal = mNodes[n].getValue();
1734 ValueType modifiedVal = tileVal;
1740 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1743 if (hasChild) mNodes[n].getChild()->modifyValue(xyz, op);
1746 template<
typename ChildT, Index Log2Dim>
1747 template<
typename ModifyOp,
typename AccessorT>
1753 bool hasChild = this->isChildMaskOn(n);
1757 const bool active = this->isValueMaskOn(n);
1758 bool createChild = !active;
1762 const ValueType& tileVal = mNodes[n].getValue();
1763 ValueType modifiedVal = tileVal;
1769 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1773 ChildNodeType* child = mNodes[n].getChild();
1774 acc.insert(xyz, child);
1775 child->modifyValueAndCache(xyz, op, acc);
1780 template<
typename ChildT, Index Log2Dim>
1781 template<
typename ModifyOp>
1786 bool hasChild = this->isChildMaskOn(n);
1788 const bool tileState = this->isValueMaskOn(n);
1789 const ValueType& tileVal = mNodes[n].getValue();
1790 bool modifiedState = !tileState;
1791 ValueType modifiedVal = tileVal;
1792 op(modifiedVal, modifiedState);
1797 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1800 if (hasChild) mNodes[n].getChild()->modifyValueAndActiveState(xyz, op);
1803 template<
typename ChildT, Index Log2Dim>
1804 template<
typename ModifyOp,
typename AccessorT>
1807 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1810 bool hasChild = this->isChildMaskOn(n);
1812 const bool tileState = this->isValueMaskOn(n);
1813 const ValueType& tileVal = mNodes[n].getValue();
1814 bool modifiedState = !tileState;
1815 ValueType modifiedVal = tileVal;
1816 op(modifiedVal, modifiedState);
1821 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1825 ChildNodeType* child = mNodes[n].getChild();
1826 acc.insert(xyz, child);
1827 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1835 template<
typename ChildT, Index Log2Dim>
1839 CoordBBox nodeBBox = this->getNodeBoundingBox();
1840 if (!clipBBox.hasOverlap(nodeBBox)) {
1842 this->fill(nodeBBox, background,
false);
1843 }
else if (clipBBox.isInside(nodeBBox)) {
1852 for (
Index pos = 0; pos < NUM_VALUES; ++pos) {
1853 const Coord xyz = this->offsetToGlobalCoord(pos);
1854 CoordBBox tileBBox(xyz, xyz.offsetBy(ChildT::DIM - 1));
1855 if (!clipBBox.hasOverlap(tileBBox)) {
1858 this->makeChildNodeEmpty(pos, background);
1859 mValueMask.setOff(pos);
1860 }
else if (!clipBBox.isInside(tileBBox)) {
1863 if (this->isChildMaskOn(pos)) {
1864 mNodes[pos].getChild()->clip(clipBBox, background);
1868 tileBBox.intersect(clipBBox);
1869 const ValueType val = mNodes[pos].getValue();
1870 const bool on = this->isValueMaskOn(pos);
1871 mNodes[pos].setValue(background);
1872 mValueMask.setOff(pos);
1873 this->fill(tileBBox, val, on);
1885 template<
typename ChildT, Index Log2Dim>
1889 Coord xyz, tileMin, tileMax;
1890 for (
int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
1892 for (
int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
1894 for (
int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
1898 const Index n = this->coordToOffset(xyz);
1899 tileMin = this->offsetToGlobalCoord(n);
1900 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
1902 if (xyz != tileMin || Coord::lessThan(bbox.max(), tileMax)) {
1906 ChildT* child = NULL;
1907 if (this->isChildMaskOff(n)) {
1910 child =
new ChildT(xyz, mNodes[n].getValue(), this->isValueMaskOn(n));
1911 this->setChildNode(n, child);
1913 child = mNodes[n].getChild();
1926 this->makeChildNodeEmpty(n, value);
1927 mValueMask.set(n, active);
1938 template<
typename ChildT, Index Log2Dim>
1939 template<
typename DenseT>
1943 typedef typename DenseT::ValueType DenseValueType;
1945 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1946 const Coord&
min = dense.bbox().min();
1947 for (Coord xyz = bbox.min(),
max; xyz[0] <= bbox.max()[0]; xyz[0] =
max[0] + 1) {
1948 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] =
max[1] + 1) {
1949 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] =
max[2] + 1) {
1950 const Index n = this->coordToOffset(xyz);
1952 max = this->offsetToGlobalCoord(n).offsetBy(ChildT::DIM-1);
1957 if (this->isChildMaskOn(n)) {
1958 mNodes[n].getChild()->copyToDense(sub, dense);
1960 const ValueType value = mNodes[n].getValue();
1961 sub.translate(-min);
1962 DenseValueType* a0 = dense.data() + zStride*sub.min()[2];
1963 for (
Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
1964 DenseValueType* a1 = a0 + x*xStride;
1965 for (
Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
1966 DenseValueType* a2 = a1 + y*yStride;
1967 for (
Int32 z=sub.min()[2], ez=sub.max()[2]+1; z<ez; ++z, a2 += zStride) {
1968 *a2 = DenseValueType(value);
1982 template<
typename ChildT, Index Log2Dim>
1986 mChildMask.save(os);
1987 mValueMask.save(os);
1991 boost::shared_array<ValueType> values(
new ValueType[NUM_VALUES]);
1992 const ValueType zero = zeroVal<ValueType>();
1993 for (
Index i = 0; i < NUM_VALUES; ++i) {
1994 values[i] = (mChildMask.isOff(i) ? mNodes[i].getValue() : zero);
2000 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2001 iter->writeTopology(os, toHalf);
2006 template<
typename ChildT, Index Log2Dim>
2010 #ifndef OPENVDB_2_ABI_COMPATIBLE
2015 mChildMask.load(is);
2016 mValueMask.load(is);
2019 for (
Index i = 0; i < NUM_VALUES; ++i) {
2020 if (this->isChildMaskOn(i)) {
2021 ChildNodeType* child =
2022 #ifdef OPENVDB_2_ABI_COMPATIBLE
2023 new ChildNodeType(offsetToGlobalCoord(i), zeroVal<ValueType>());
2025 new ChildNodeType(
PartialCreate(), offsetToGlobalCoord(i), background);
2027 mNodes[i].setChild(child);
2028 child->readTopology(is);
2031 is.read(reinterpret_cast<char*>(&value),
sizeof(ValueType));
2032 mNodes[i].setValue(value);
2036 const bool oldVersion =
2038 const Index numValues = (oldVersion ? mChildMask.countOff() : NUM_VALUES);
2042 boost::shared_array<ValueType> values(
new ValueType[numValues]);
2048 for (ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
2049 mNodes[iter.pos()].setValue(values[n++]);
2051 assert(n == numValues);
2053 for (ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
2054 mNodes[iter.pos()].setValue(values[iter.pos()]);
2059 for (ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2060 #ifdef OPENVDB_2_ABI_COMPATIBLE
2061 ChildNodeType* child =
new ChildNodeType(iter.getCoord(), zeroVal<ValueType>());
2063 ChildNodeType* child =
new ChildNodeType(
PartialCreate(), iter.getCoord(), background);
2065 mNodes[iter.pos()].setChild(child);
2066 child->readTopology(is, fromHalf);
2075 template<
typename ChildT, Index Log2Dim>
2076 inline const typename ChildT::ValueType&
2079 return (this->isChildMaskOn(0) ? mNodes[0].getChild()->getFirstValue() : mNodes[0].getValue());
2083 template<
typename ChildT, Index Log2Dim>
2084 inline const typename ChildT::ValueType&
2087 const Index n = NUM_VALUES - 1;
2088 return (this->isChildMaskOn(n) ? mNodes[n].getChild()->getLastValue() : mNodes[n].getValue());
2095 template<
typename ChildT, Index Log2Dim>
2099 for (
Index i = 0; i < NUM_VALUES; ++i) {
2100 if (this->isChildMaskOn(i)) {
2101 mNodes[i].getChild()->negate();
2110 template<
typename ChildT, Index Log2Dim>
2114 for (ValueOnIter iter = this->beginValueOn(); iter; ++iter) {
2115 this->setChildNode(iter.pos(),
new ChildNodeType(iter.getCoord(), iter.getValue(),
true));
2117 for (ChildOnIter iter = this->beginChildOn(); iter; ++iter) iter->voxelizeActiveTiles();
2124 template<
typename ChildT, Index Log2Dim>
2125 template<MergePolicy Policy>
2128 const ValueType& background,
const ValueType& otherBackground)
2137 for (ChildOnIter iter = other.
beginChildOn(); iter; ++iter) {
2138 const Index n = iter.pos();
2139 if (mChildMask.isOn(n)) {
2141 mNodes[n].getChild()->template merge<MERGE_ACTIVE_STATES>(*iter,
2142 background, otherBackground);
2143 }
else if (mValueMask.isOff(n)) {
2148 ChildNodeType* child = other.
mNodes[n].getChild();
2150 child->resetBackground(otherBackground, background);
2151 this->setChildNode(n, child);
2156 for (ValueOnCIter iter = other.
cbeginValueOn(); iter; ++iter) {
2157 const Index n = iter.pos();
2158 if (mValueMask.isOff(n)) {
2160 this->makeChildNodeEmpty(n, iter.getValue());
2161 mValueMask.setOn(n);
2169 for (ChildOnIter iter = other.
beginChildOn(); iter; ++iter) {
2170 const Index n = iter.pos();
2171 if (mChildMask.isOn(n)) {
2173 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2179 ChildNodeType* child = other.
mNodes[n].getChild();
2181 child->resetBackground(otherBackground, background);
2182 this->setChildNode(n, child);
2191 for (ChildOnIter iter = other.
beginChildOn(); iter; ++iter) {
2192 const Index n = iter.pos();
2193 if (mChildMask.isOn(n)) {
2195 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2200 ChildNodeType* child = other.
mNodes[n].getChild();
2202 child->resetBackground(otherBackground, background);
2203 if (mValueMask.isOn(n)) {
2205 child->template merge<Policy>(mNodes[n].getValue(),
true);
2206 mValueMask.setOff(n);
2208 mChildMask.setOn(n);
2209 mNodes[n].setChild(child);
2214 for (ValueOnCIter iter = other.
cbeginValueOn(); iter; ++iter) {
2215 const Index n = iter.pos();
2216 if (mChildMask.isOn(n)) {
2218 mNodes[n].getChild()->template merge<Policy>(iter.getValue(),
true);
2219 }
else if (mValueMask.isOff(n)) {
2221 mNodes[n].setValue(iter.getValue());
2222 mValueMask.setOn(n);
2233 template<
typename ChildT, Index Log2Dim>
2234 template<MergePolicy Policy>
2243 if (!tileActive)
return;
2246 for (ValueOffIter iter = this->beginValueOff(); iter; ++iter) {
2247 const Index n = iter.pos();
2248 if (mChildMask.isOn(n)) {
2250 mNodes[n].getChild()->template merge<Policy>(tileValue,
true);
2253 iter.setValue(tileValue);
2254 mValueMask.setOn(n);
2264 template<
typename ChildT, Index Log2Dim>
2265 template<
typename OtherChildT>
2273 for (OtherChildIter iter = other.
cbeginChildOn(); iter; ++iter) {
2275 if (mChildMask.isOn(i)) {
2276 mNodes[i].getChild()->topologyUnion(*iter);
2278 ChildNodeType* child =
new ChildNodeType(*iter, mNodes[i].getValue(),
TopologyCopy());
2279 if (mValueMask.isOn(i)) {
2280 mValueMask.isOff(i);
2281 child->setValuesOn();
2283 mChildMask.setOn(i);
2284 mNodes[i].setChild(child);
2288 for (OtherValueIter iter = other.
cbeginValueOn(); iter; ++iter) {
2289 const Index i = iter.pos();
2290 if (mChildMask.isOn(i)) {
2291 mNodes[i].getChild()->setValuesOn();
2292 }
else if (mValueMask.isOff(i)) {
2293 mValueMask.setOn(i);
2298 template<
typename ChildT, Index Log2Dim>
2299 template<
typename OtherChildT>
2302 const ValueType& background)
2305 for (ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2306 const Index i = iter.pos();
2308 iter->topologyIntersection(*(other.
mNodes[i].getChild()), background);
2310 delete mNodes[i].getChild();
2311 mNodes[i].setValue(background);
2312 mChildMask.setOff(i);
2313 mValueMask.setOff(i);
2318 for (ValueOnCIter iter = this->cbeginValueOn(); iter; ++iter) {
2319 const Index i = iter.pos();
2321 ChildNodeType* child =
new ChildNodeType(*(other.
mNodes[i].getChild()),
2323 this->setChildNode(i, child);
2325 mValueMask.setOff(i);
2330 template<
typename ChildT, Index Log2Dim>
2331 template<
typename OtherChildT>
2334 const ValueType& background)
2340 for (OtherChildIter iter = other.
cbeginChildOn(); iter; ++iter) {
2342 if (mChildMask.isOn(i)) {
2343 mNodes[i].getChild()->topologyDifference(*iter, background);
2344 }
else if (mValueMask.isOn(i)) {
2345 ChildNodeType* child =
new ChildNodeType(iter.getCoord(), mNodes[i].getValue(),
true);
2346 child->topologyDifference(*iter, background);
2347 this->setChildNode(i, child);
2352 for (OtherValueIter iter = other.
cbeginValueOn(); iter; ++iter) {
2353 const Index i = iter.pos();
2354 if (mChildMask.isOn(i)) {
2355 delete mNodes[i].getChild();
2356 mNodes[i].setValue(background);
2357 mChildMask.setOff(i);
2358 mValueMask.setOff(i);
2359 }
else if (mValueMask.isOn(i)) {
2360 mValueMask.setOff(i);
2368 template<
typename ChildT, Index Log2Dim>
2369 template<
typename CombineOp>
2373 const ValueType zero = zeroVal<ValueType>();
2377 for (
Index i = 0; i < NUM_VALUES; ++i) {
2381 op(args.setARef(mNodes[i].getValue())
2382 .setAIsActive(isValueMaskOn(i))
2383 .setBRef(other.
mNodes[i].getValue())
2385 mNodes[i].setValue(args.result());
2386 mValueMask.set(i, args.resultIsActive());
2389 ChildNodeType* child = mNodes[i].getChild();
2394 }
else if (this->isChildMaskOff(i) && other.
isChildMaskOn(i)) {
2396 ChildNodeType* child = other.
mNodes[i].getChild();
2403 child->combine(mNodes[i].getValue(), isValueMaskOn(i), swappedOp);
2407 other.
mNodes[i].setValue(zero);
2408 this->setChildNode(i, child);
2414 *child = mNodes[i].getChild(),
2415 *otherChild = other.
mNodes[i].getChild();
2418 if (child && otherChild) {
2419 child->combine(*otherChild, op);
2426 template<
typename ChildT, Index Log2Dim>
2427 template<
typename CombineOp>
2433 for (
Index i = 0; i < NUM_VALUES; ++i) {
2434 if (this->isChildMaskOff(i)) {
2436 op(args.
setARef(mNodes[i].getValue())
2437 .setAIsActive(isValueMaskOn(i))
2439 .setBIsActive(valueIsActive));
2440 mNodes[i].setValue(args.
result());
2444 ChildNodeType* child = mNodes[i].getChild();
2446 if (child) child->combine(value, valueIsActive, op);
2455 template<
typename ChildT, Index Log2Dim>
2456 template<
typename CombineOp,
typename OtherNodeType>
2463 for (
Index i = 0; i < NUM_VALUES; ++i) {
2467 .setBRef(other1.mNodes[i].getValue())
2468 .setBIsActive(other1.isValueMaskOn(i)));
2470 this->makeChildNodeEmpty(i, args.
result());
2473 if (this->isChildMaskOff(i)) {
2476 ? other0.
mNodes[i].getChild()->origin()
2477 : other1.mNodes[i].getChild()->origin();
2478 this->setChildNode(i,
new ChildNodeType(childOrigin, mNodes[i].getValue()));
2484 mNodes[i].getChild()->combine2(other0.
mNodes[i].getValue(),
2486 }
else if (other1.isChildMaskOff(i)) {
2489 mNodes[i].getChild()->combine2(*other0.
mNodes[i].getChild(),
2490 other1.mNodes[i].getValue(), other1.isValueMaskOn(i), op);
2494 mNodes[i].getChild()->combine2(*other0.
mNodes[i].getChild(),
2495 *other1.mNodes[i].getChild(), op);
2502 template<
typename ChildT, Index Log2Dim>
2503 template<
typename CombineOp,
typename OtherNodeType>
2506 bool valueIsActive, CombineOp& op)
2510 for (
Index i = 0; i < NUM_VALUES; ++i) {
2511 if (other.isChildMaskOff(i)) {
2513 .setAIsActive(valueIsActive)
2514 .setBRef(other.mNodes[i].getValue())
2515 .setBIsActive(other.isValueMaskOn(i)));
2517 this->makeChildNodeEmpty(i, args.
result());
2520 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[i].getChild();
2522 if (this->isChildMaskOff(i)) {
2525 this->setChildNode(i,
new ChildNodeType(*otherChild));
2529 mNodes[i].getChild()->combine2(value, *otherChild, valueIsActive, op);
2535 template<
typename ChildT, Index Log2Dim>
2536 template<
typename CombineOp,
typename OtherValueType>
2539 bool valueIsActive, CombineOp& op)
2543 for (
Index i = 0; i < NUM_VALUES; ++i) {
2548 .setBIsActive(valueIsActive));
2550 this->makeChildNodeEmpty(i, args.
result());
2553 ChildNodeType* otherChild = other.
mNodes[i].getChild();
2555 if (this->isChildMaskOff(i)) {
2557 this->setChildNode(i,
2558 new ChildNodeType(otherChild->origin(), mNodes[i].getValue()));
2562 mNodes[i].getChild()->combine2(*otherChild, value, valueIsActive, op);
2571 template<
typename ChildT, Index Log2Dim>
2572 template<
typename BBoxOp>
2576 for (ValueOnCIter i = this->cbeginValueOn(); i; ++i) {
2578 op.operator()<LEVEL>(CoordBBox::createCube(i.getCoord(), ChildNodeType::DIM));
2580 op.template operator()<LEVEL>(CoordBBox::createCube(i.getCoord(), ChildNodeType::DIM));
2583 if (op.template descent<LEVEL>()) {
2584 for (ChildOnCIter i = this->cbeginChildOn(); i; ++i) i->visitActiveBBox(op);
2586 for (ChildOnCIter i = this->cbeginChildOn(); i; ++i) {
2588 op.operator()<LEVEL>(i->getNodeBoundingBox());
2590 op.template operator()<LEVEL>(i->getNodeBoundingBox());
2597 template<
typename ChildT, Index Log2Dim>
2598 template<
typename VisitorOp>
2602 doVisit<InternalNode, VisitorOp, ChildAllIter>(*
this, op);
2606 template<
typename ChildT, Index Log2Dim>
2607 template<
typename VisitorOp>
2611 doVisit<const InternalNode, VisitorOp, ChildAllCIter>(*
this, op);
2615 template<
typename ChildT, Index Log2Dim>
2616 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
2620 typename NodeT::ValueType val;
2621 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2622 if (op(iter))
continue;
2623 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2633 template<
typename ChildT, Index Log2Dim>
2634 template<
typename OtherNodeType,
typename VisitorOp>
2638 doVisit2Node<
InternalNode, OtherNodeType, VisitorOp, ChildAllIter,
2639 typename OtherNodeType::ChildAllIter>(*
this, other, op);
2643 template<
typename ChildT, Index Log2Dim>
2644 template<
typename OtherNodeType,
typename VisitorOp>
2648 doVisit2Node<
const InternalNode, OtherNodeType, VisitorOp, ChildAllCIter,
2649 typename OtherNodeType::ChildAllCIter>(*
this, other, op);
2653 template<
typename ChildT, Index Log2Dim>
2656 typename OtherNodeT,
2658 typename ChildAllIterT,
2659 typename OtherChildAllIterT>
2664 BOOST_STATIC_ASSERT(OtherNodeT::NUM_VALUES == NodeT::NUM_VALUES);
2665 BOOST_STATIC_ASSERT(OtherNodeT::LEVEL == NodeT::LEVEL);
2667 typename NodeT::ValueType val;
2668 typename OtherNodeT::ValueType otherVal;
2670 ChildAllIterT iter =
self.beginChildAll();
2671 OtherChildAllIterT otherIter = other.beginChildAll();
2673 for ( ; iter && otherIter; ++iter, ++otherIter)
2675 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2677 typename ChildAllIterT::ChildNodeType* child =
2678 (skipBranch & 1U) ? NULL : iter.probeChild(val);
2679 typename OtherChildAllIterT::ChildNodeType* otherChild =
2680 (skipBranch & 2U) ? NULL : otherIter.probeChild(otherVal);
2682 if (child != NULL && otherChild != NULL) {
2683 child->visit2Node(*otherChild, op);
2684 }
else if (child != NULL) {
2685 child->visit2(otherIter, op);
2686 }
else if (otherChild != NULL) {
2687 otherChild->visit2(iter, op,
true);
2696 template<
typename ChildT, Index Log2Dim>
2697 template<
typename OtherChildAllIterType,
typename VisitorOp>
2700 VisitorOp& op,
bool otherIsLHS)
2702 doVisit2<InternalNode, VisitorOp, ChildAllIter, OtherChildAllIterType>(
2703 *
this, otherIter, op, otherIsLHS);
2707 template<
typename ChildT, Index Log2Dim>
2708 template<
typename OtherChildAllIterType,
typename VisitorOp>
2711 VisitorOp& op,
bool otherIsLHS)
const
2713 doVisit2<const InternalNode, VisitorOp, ChildAllCIter, OtherChildAllIterType>(
2714 *
this, otherIter, op, otherIsLHS);
2718 template<
typename ChildT, Index Log2Dim>
2719 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT,
typename OtherChildAllIterT>
2722 VisitorOp& op,
bool otherIsLHS)
2724 if (!otherIter)
return;
2726 const size_t skipBitMask = (otherIsLHS ? 2U : 1U);
2728 typename NodeT::ValueType val;
2729 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2730 const size_t skipBranch =
static_cast<size_t>(
2731 otherIsLHS ? op(otherIter, iter) : op(iter, otherIter));
2733 typename ChildAllIterT::ChildNodeType* child =
2734 (skipBranch & skipBitMask) ? NULL : iter.probeChild(val);
2736 if (child != NULL) child->visit2(otherIter, op, otherIsLHS);
2744 template<
typename ChildT, Index Log2Dim>
2748 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2749 iter->writeBuffers(os, toHalf);
2754 template<
typename ChildT, Index Log2Dim>
2758 for (ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2759 iter->readBuffers(is, fromHalf);
2764 template<
typename ChildT, Index Log2Dim>
2767 const CoordBBox& clipBBox,
bool fromHalf)
2769 for (ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2774 iter->readBuffers(is, clipBBox, fromHalf);
2778 ValueType background = zeroVal<ValueType>();
2780 background = *
static_cast<const ValueType*
>(bgPtr);
2782 this->
clip(clipBBox, background);
2789 template<
typename ChildT, Index Log2Dim>
2793 dims.push_back(Log2Dim);
2794 ChildNodeType::getNodeLog2Dims(dims);
2798 template<
typename ChildT, Index Log2Dim>
2802 assert(n<(1<<3*Log2Dim));
2803 xyz.setX(n >> 2*Log2Dim);
2804 n &= ((1<<2*Log2Dim)-1);
2805 xyz.setY(n >> Log2Dim);
2806 xyz.setZ(n & ((1<<Log2Dim)-1));
2810 template<
typename ChildT, Index Log2Dim>
2814 return (((xyz[0] & (DIM-1u)) >> ChildNodeType::TOTAL) << 2*Log2Dim)
2815 + (((xyz[1] & (DIM-1u)) >> ChildNodeType::TOTAL) << Log2Dim)
2816 + ((xyz[2] & (DIM-1u)) >> ChildNodeType::TOTAL);
2820 template<
typename ChildT, Index Log2Dim>
2825 this->offsetToLocalCoord(n, local);
2826 local <<= ChildT::TOTAL;
2827 return local + this->origin();
2832 template<
typename ChildT, Index Log2Dim>
2833 template<
typename ArrayT>
2837 typedef typename ArrayT::value_type T;
2838 BOOST_STATIC_ASSERT(boost::is_pointer<T>::value);
2839 typedef typename boost::mpl::if_<boost::is_const<typename boost::remove_pointer<T>::type>,
2840 const ChildT, ChildT>::type ArrayChildT;
2841 for (ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2843 if (boost::is_same<T, ArrayChildT*>::value) {
2844 array.push_back(reinterpret_cast<T>(mNodes[iter.pos()].getChild()));
2846 iter->getNodes(array);
2852 template<
typename ChildT, Index Log2Dim>
2853 template<
typename ArrayT>
2857 typedef typename ArrayT::value_type T;
2858 BOOST_STATIC_ASSERT(boost::is_pointer<T>::value);
2859 BOOST_STATIC_ASSERT(boost::is_const<
typename boost::remove_pointer<T>::type>::value);
2860 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2862 if (boost::is_same<T, const ChildT*>::value) {
2863 array.push_back(reinterpret_cast<T>(mNodes[iter.pos()].getChild()));
2865 iter->getNodes(array);
2874 template<
typename ChildT, Index Log2Dim>
2877 const ValueType& newBackground)
2880 for (
Index i = 0; i < NUM_VALUES; ++i) {
2881 if (this->isChildMaskOn(i)) {
2882 mNodes[i].getChild()->resetBackground(oldBackground, newBackground);
2883 }
else if (this->isValueMaskOff(i)) {
2885 mNodes[i].setValue(newBackground);
2893 template<
typename ChildT, Index Log2Dim>
2894 template<
typename OtherChildNodeType, Index OtherLog2Dim>
2899 if (Log2Dim != OtherLog2Dim || mChildMask != other->
mChildMask ||
2900 mValueMask != other->
mValueMask)
return false;
2901 for (ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2902 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
2908 template<
typename ChildT, Index Log2Dim>
2913 if (this->isChildMaskOn(i)) {
2914 delete mNodes[i].getChild();
2916 mChildMask.setOn(i);
2917 mValueMask.setOff(i);
2919 mNodes[i].setChild(child);
2922 template<
typename ChildT, Index Log2Dim>
2927 assert(mChildMask.isOff(i));
2928 mChildMask.setOn(i);
2929 mValueMask.setOff(i);
2930 mNodes[i].setChild(child);
2934 template<
typename ChildT, Index Log2Dim>
2938 if (this->isChildMaskOff(i)) {
2939 mNodes[i].setValue(value);
2942 ChildNodeType* child = mNodes[i].getChild();
2943 mChildMask.setOff(i);
2944 mNodes[i].setValue(value);
2949 template<
typename ChildT, Index Log2Dim>
2953 delete this->unsetChildNode(n, value);
2956 template<
typename ChildT, Index Log2Dim>
2960 assert(this->isChildMaskOn(n));
2961 return mNodes[n].getChild();
2965 template<
typename ChildT, Index Log2Dim>
2966 inline const ChildT*
2969 assert(this->isChildMaskOn(n));
2970 return mNodes[n].getChild();
2977 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:974
static Index getChildDim()
Definition: InternalNode.h:259
Definition: InternalNode.h:135
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:685
virtual ~InternalNode()
Definition: InternalNode.h:877
Index getValueLevel(const Coord &xyz) const
Return the level of the tree (0 = leaf) at which the value at the given coordinates resides...
Definition: InternalNode.h:1458
Definition: InternalNode.h:161
void topologyIntersection(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &background)
Intersects this tree's set of active values with the active values of the other tree, whose ValueType may be different.
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1646
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:497
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:270
ChildIter< InternalNode, ChildNodeType, MaskOnIterator, ChildOn > ChildOnIter
Definition: InternalNode.h:218
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition: InternalNode.h:2458
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:308
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:232
Index32 leafCount() const
Definition: InternalNode.h:890
ValueAllIter beginValueAll()
Definition: InternalNode.h:253
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:2936
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:233
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:236
NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:129
NodeUnion< ValueType, ChildNodeType > UnionType
Definition: InternalNode.h:69
ChildIter< const InternalNode, const ChildNodeType, MaskOnIterator, ChildOn > ChildOnCIter
Definition: InternalNode.h:219
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2746
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1493
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1435
uint64_t Index64
Definition: Types.h:58
static void doVisit(NodeT &, VisitorOp &)
Definition: InternalNode.h:2618
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return NULL.
void visit(VisitorOp &)
Definition: InternalNode.h:2600
const LeafNodeType * probeConstLeafAndCache(const Coord &xyz, AccessorT &acc) const
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1424
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffCIter
Definition: InternalNode.h:221
Index32 nonLeafCount() const
Definition: InternalNode.h:903
Index pos() const
Identical to offset.
Definition: Iterator.h:94
ValueIter< InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffIter
Definition: InternalNode.h:220
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: InternalNode.h:1837
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates but don't change its active state.
Definition: InternalNode.h:1629
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1686
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1524
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllCIter
Definition: InternalNode.h:230
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:242
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:235
bool resultIsActive() const
Definition: Types.h:358
CoordBBox getNodeBoundingBox() const
Return the bounding box of this node, i.e., the full index space spanned by the node regardless of it...
Definition: InternalNode.h:293
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:145
ValueOnIter beginValueOn()
Definition: InternalNode.h:250
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:436
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
Expand the specified bounding box so that it includes the active tiles of this internal node as well ...
Definition: InternalNode.h:987
static const Index NUM_VALUES
Definition: InternalNode.h:76
static void offsetToLocalCoord(Index n, Coord &xyz)
Return the local coordinates for a linear table offset, where offset 0 has coordinates (0...
Definition: InternalNode.h:2800
NodeMaskType getValueOffMask() const
Definition: InternalNode.h:694
void fill(const CoordBBox &bbox, const ValueType &, bool active=true)
Set all voxels within an axis-aligned box to a constant value. (The min and max coordinates are inclu...
Definition: InternalNode.h:1887
static void doVisit2(NodeT &, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: InternalNode.h:2721
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:347
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2371
void addTileAndCache(Index level, const Coord &xyz, const ValueType &, bool state, AccessorT &)
Same as addTile() except, if necessary, update the accessor with pointers to the nodes along the path...
Definition: InternalNode.h:1281
NodeT * stealNode(const Coord &xyz, const ValueType &value, bool state)
Return a pointer to the node of type NodeT that contains voxel (x, y, z) and replace it with a tile o...
Definition: InternalNode.h:1029
const NodeType * probeConstNodeAndCache(const Coord &xyz, AccessorT &) const
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:2951
ValueIter()
Definition: InternalNode.h:164
int32_t Int32
Definition: Types.h:61
DenseIter()
Definition: InternalNode.h:188
void visit2Node(OtherNodeType &other, VisitorOp &)
Definition: InternalNode.h:2636
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:687
DenseIter< const InternalNode, const ChildNodeType, ValueType, ChildAll > ChildAllCIter
Definition: InternalNode.h:223
bool isChildMaskOff() const
Definition: InternalNode.h:691
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: InternalNode.h:1667
const NodeMaskType & getValueMask() const
Definition: InternalNode.h:692
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition: InternalNode.h:2958
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: InternalNode.h:2791
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:690
const ValueType & getLastValue() const
If the last entry in this node's table is a tile, return the tile's value. Otherwise, return the result of calling getLastValue() on the child.
Definition: InternalNode.h:2085
InternalNode()
Definition: InternalNode.h:99
void negate()
Definition: InternalNode.h:2097
Definition: InternalNode.h:134
bool isEmpty() const
Definition: InternalNode.h:295
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile at the specified tree level that contains voxel (x, y, z), possibly creating a parent bran...
Definition: InternalNode.h:1249
util::NodeMask< Log2Dim > NodeMaskType
Definition: InternalNode.h:70
bool isConstant(ValueType &constValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1350
ValueIter< const InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnCIter
Definition: InternalNode.h:226
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: InternalNode.h:1157
bool hasSameTopology(const InternalNode< OtherChildNodeType, OtherLog2Dim > *other) const
Return true if the given tree branch has the same node and active value topology as this tree branch ...
Definition: InternalNode.h:2896
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:411
DenseIter< InternalNode, ChildNodeType, ValueType, ChildAll > ChildAllIter
Definition: InternalNode.h:222
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:171
#define OPENVDB_VERSION_NAME
Definition: version.h:43
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1508
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:168
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1605
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:1984
Index32 Index
Definition: Types.h:59
static Index getLevel()
Definition: InternalNode.h:257
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:2924
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:461
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:249
void addLeaf(LeafNodeType *leaf)
Add the specified leaf to this node, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: InternalNode.h:1177
Definition: InternalNode.h:141
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:309
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:272
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:237
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: InternalNode.h:2835
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:309
NodeMaskType mChildMask
Definition: InternalNode.h:735
Definition: NodeMasks.h:236
ChildNodeType::ValueType ValueType
Definition: InternalNode.h:68
Definition: Exceptions.h:39
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:737
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:303
Definition: InternalNode.h:182
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:67
bool isApproxEqual(const Hermite &lhs, const Hermite &rhs)
Definition: Hermite.h:470
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:210
SameConfiguration::value is true if and only if OtherNodeType is the type of an Intern...
Definition: InternalNode.h:93
const UnionType * getTable() const
Definition: InternalNode.h:701
ChildIter()
Definition: InternalNode.h:144
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:155
ChildAllIter beginChildAll()
Definition: InternalNode.h:240
DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT > BaseT
Definition: InternalNode.h:185
Index64 offVoxelCount() const
Definition: InternalNode.h:928
const AValueType & result() const
Get the output value.
Definition: Types.h:339
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:211
ValueConverter::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:84
ValueIter< InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnIter
Definition: InternalNode.h:225
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:107
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1560
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
Definition: NodeMasks.h:267
Definition: version.h:101
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: InternalNode.h:1749
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:148
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:245
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:2910
ChildOnIter beginChildOn()
Definition: InternalNode.h:238
OPENVDB_API const void * getGridBackgroundValuePtr(std::ios_base &)
Return a pointer to the background value of the grid currently being read from or written to the give...
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:131
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2756
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:234
Definition: InternalNode.h:63
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1709
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:410
NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:130
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:405
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:192
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:244
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:2812
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:246
Definition: NodeMasks.h:205
void addLeafAndCache(LeafNodeType *leaf, AccessorT &)
Same as addLeaf() except, if necessary, update the accessor with pointers to the nodes along the path...
Definition: InternalNode.h:1206
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:204
Index64 onTileCount() const
Definition: InternalNode.h:963
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: InternalNode.h:1131
const NodeType * probeConstNode(const Coord &xyz) const
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return NULL.
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:175
Definition: InternalNode.h:59
Definition: InternalNode.h:135
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffIter
Definition: InternalNode.h:227
ChildOffIter beginChildOff()
Definition: InternalNode.h:239
static void doVisit2Node(NodeT &, OtherNodeT &, VisitorOp &)
Definition: InternalNode.h:2661
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: InternalNode.h:1721
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:952
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:391
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:940
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:1783
_ChildNodeType ChildNodeType
Definition: InternalNode.h:66
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes ...
Definition: InternalNode.h:2574
Index64 onVoxelCount() const
Definition: InternalNode.h:916
LeafNodeType * touchLeaf(const Coord &xyz)
Return the leaf node that contains voxel (x, y, z). If no such node exists, create one...
Definition: InternalNode.h:1317
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:189
const ValueType & getFirstValue() const
If the first entry in this node's table is a tile, return the tile's value. Otherwise, return the result of calling getFirstValue() on the child.
Definition: InternalNode.h:2077
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:304
void voxelizeActiveTiles()
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2112
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:248
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1399
BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:186
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:734
uint32_t Index32
Definition: Types.h:57
void topologyDifference(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &background)
Difference this node's set of active values with the active values of the other node, whose ValueType may be different. So a resulting voxel will be active only if the original voxel is active in this node and inactive in the other node.
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
void prune(const ValueType &tolerance=zeroVal< ValueType >())
Reduce the memory footprint of this tree by replacing with tiles any nodes whose values are all the s...
Definition: InternalNode.h:1005
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:165
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffCIter
Definition: InternalNode.h:228
Index getValueLevelAndCache(const Coord &xyz, AccessorT &) const
Return the level of the tree (0 = leaf) at which the value at the given coordinates resides...
Definition: InternalNode.h:1467
boost::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:217
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllIter
Definition: InternalNode.h:229
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2008
NodeMaskType mValueMask
Definition: InternalNode.h:735
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:2822
InternalNode< typename ChildNodeType::template ValueConverter< OtherValueType >::Type, Log2Dim > Type
Definition: InternalNode.h:86
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:58
static Index dim()
Definition: InternalNode.h:256
ChildT & getItem(Index pos) const
Definition: InternalNode.h:148
Definition: InternalNode.h:134
void topologyUnion(const InternalNode< OtherChildNodeType, Log2Dim > &other)
Union this branch's set of active values with the other branch's active values. The value type of the...
void merge(InternalNode &other, const ValueType &background, const ValueType &otherBackground)
Efficiently merge another tree into this tree using one of several schemes.
Definition: InternalNode.h:2127
bool isValueMaskOn() const
Definition: InternalNode.h:686
void resetBackground(const ValueType &oldBackground, const ValueType &newBackground)
Change inactive tiles or voxels with value oldBackground to newBackground or -oldBackground to -newBa...
Definition: InternalNode.h:2876
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1414
void copyToDense(const CoordBBox &bbox, DenseT &dense) const
Copy into a dense grid the values of the voxels that lie within a given bounding box.
Definition: InternalNode.h:1941
ValueOffIter beginValueOff()
Definition: InternalNode.h:252
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:689
const NodeMaskType & getChildMask() const
Definition: InternalNode.h:693
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1480
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1806
bool isValueMaskOff() const
Definition: InternalNode.h:688
Definition: version.h:110