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 <openvdb/Platform.h>
41 #include <openvdb/util/NodeMasks.h>
42 #include <openvdb/io/Compression.h>
43 #include <openvdb/math/Math.h>
44 #include <openvdb/version.h>
45 #include <openvdb/Types.h>
56 template<
typename _ChildNodeType, Index Log2Dim>
62 typedef typename ChildNodeType::ValueType
ValueType;
68 TOTAL = Log2Dim + ChildNodeType::TOTAL,
70 NUM_VALUES = 1 << (3 * Log2Dim),
71 LEVEL = 1 + ChildNodeType::LEVEL;
73 NUM_VOXELS = uint64_t(1) << (3 * TOTAL);
77 template<
typename OtherValueType>
88 InternalNode(
const Coord&,
const ValueType& value,
bool active =
false);
94 template<
typename OtherChildNodeType>
99 template<
typename OtherChildNodeType>
101 const ValueType& offValue,
const ValueType& onValue,
118 template<
typename NodeT,
typename ChildT,
typename MaskIterT,
typename TagT>
120 MaskIterT, ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>
124 MaskIterT,
ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>(iter, parent) {}
126 ChildT&
getItem(
Index pos)
const {
return *(this->parent().getChildNode(pos)); }
129 void setItem(
Index pos,
const ChildT& c)
const { this->parent().resetChildNode(pos, &c); }
134 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
136 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
140 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
142 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
145 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
148 template<
typename ModifyOp>
151 op(this->parent().mNodes[pos].getValue());
155 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
157 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
168 child = this->parent().getChildNode(pos);
169 if (!child) value = this->parent().mNodes[pos].getValue();
170 return (child != NULL);
176 this->parent().resetChildNode(pos, child);
182 this->parent().unsetChildNode(pos, value);
225 static void getNodeLog2Dims(std::vector<Index>& dims);
229 static Index coordToOffset(
const Coord& xyz);
232 static void offsetToLocalCoord(
Index n, Coord& xyz);
234 Coord offsetToGlobalCoord(
Index n)
const;
237 const Coord&
origin()
const {
return mOrigin; }
242 void setOrigin(
const Coord& origin) { mOrigin = origin; }
248 Index64 onLeafVoxelCount()
const;
249 Index64 offLeafVoxelCount()
const;
259 void evalActiveBoundingBox(CoordBBox& bbox,
bool visitVoxels =
true)
const;
266 bool isEmpty()
const {
return mChildMask.isOff(); }
271 bool isConstant(ValueType& constValue,
bool& state,
272 const ValueType& tolerance = zeroVal<ValueType>())
const;
274 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
277 bool isValueOn(
const Coord& xyz)
const;
282 bool hasActiveTiles()
const;
284 const ValueType& getValue(
const Coord& xyz)
const;
285 bool probeValue(
const Coord& xyz, ValueType& value)
const;
289 Index getValueLevel(
const Coord& xyz)
const;
293 const ValueType& getFirstValue()
const;
296 const ValueType& getLastValue()
const;
299 void setActiveState(
const Coord& xyz,
bool on);
301 void setValueOnly(
const Coord& xyz,
const ValueType& value);
303 void setValueOn(
const Coord& xyz);
305 void setValueOn(
const Coord& xyz,
const ValueType& value);
307 void setValueOff(
const Coord& xyz);
309 void setValueOff(
const Coord& xyz,
const ValueType& value);
313 template<
typename ModifyOp>
314 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
316 template<
typename ModifyOp>
317 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
323 template<
typename AccessorT>
324 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
330 template<
typename AccessorT>
331 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
337 template<
typename AccessorT>
338 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
344 template<
typename AccessorT>
345 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
352 template<
typename ModifyOp,
typename AccessorT>
353 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
359 template<
typename ModifyOp,
typename AccessorT>
360 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
366 template<
typename AccessorT>
367 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
373 template<
typename AccessorT>
374 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
381 template<
typename AccessorT>
382 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
390 template<
typename AccessorT>
391 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
400 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
401 void readTopology(std::istream&,
bool fromHalf =
false);
402 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
403 void readBuffers(std::istream&,
bool fromHalf =
false);
411 void fill(
const CoordBBox& bbox,
const ValueType&,
bool active =
true);
418 void signedFloodFill(
const ValueType& background);
425 void signedFloodFill(
const ValueType& outside,
const ValueType& inside);
432 void voxelizeActiveTiles();
441 template<
typename DenseT>
442 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
446 template<MergePolicy Policy>
447 void merge(
InternalNode& other,
const ValueType& background,
const ValueType& otherBackground);
451 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
465 template<
typename OtherChildNodeType>
481 template<
typename OtherChildNodeType>
483 const ValueType& background);
496 template<
typename OtherChildNodeType>
498 const ValueType& background);
500 template<
typename CombineOp>
502 template<
typename CombineOp>
503 void combine(
const ValueType& value,
bool valueIsActive, CombineOp&);
505 template<
typename CombineOp>
507 template<
typename CombineOp>
508 void combine2(
const ValueType& value,
const InternalNode& other,
bool valIsActive, CombineOp&);
509 template<
typename CombineOp>
510 void combine2(
const InternalNode& other,
const ValueType& val,
bool valIsActive, CombineOp&);
517 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
519 template<
typename VisitorOp>
void visit(VisitorOp&);
520 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
522 template<
typename OtherNodeType,
typename VisitorOp>
523 void visit2Node(OtherNodeType& other, VisitorOp&);
524 template<
typename OtherNodeType,
typename VisitorOp>
525 void visit2Node(OtherNodeType& other, VisitorOp&)
const;
526 template<
typename IterT,
typename VisitorOp>
527 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false);
528 template<
typename IterT,
typename VisitorOp>
529 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false)
const;
537 template<
typename PruneOp>
void pruneOp(PruneOp&);
542 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
546 void pruneInactive(
const ValueType&);
550 void pruneInactive();
554 void addLeaf(LeafNodeType* leaf);
558 template<
typename AccessorT>
559 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
569 template<
typename NodeT>
570 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
574 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
577 void addTile(
Index offset,
const ValueType& value,
bool state);
581 template<
typename AccessorT>
582 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
585 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
588 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
592 template<
typename NodeType,
typename AccessorT>
595 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
596 template<
typename NodeType,
typename AccessorT>
597 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
601 LeafNodeType* probeLeaf(
const Coord& xyz);
604 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
605 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
609 template<
typename AccessorT>
612 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
613 template<
typename AccessorT>
614 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
615 template<
typename AccessorT>
616 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
625 LeafNodeType* touchLeaf(
const Coord& xyz);
629 template<
typename AccessorT>
630 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
634 void resetBackground(
const ValueType& oldBackground,
const ValueType& newBackground);
638 template<
typename OtherChildNodeType, Index OtherLog2Dim>
665 void setValueMask(
Index n,
bool on) { mValueMask.set(n, mChildMask.isOn(n) ?
false : on); }
670 void makeChildNodeEmpty(
Index n,
const ValueType& value);
671 void setChildNode(
Index i, ChildNodeType* child);
672 void resetChildNode(
Index i, ChildNodeType* child);
673 ChildNodeType* unsetChildNode(
Index i,
const ValueType& value);
675 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
676 static inline void doVisit(NodeT&, VisitorOp&);
678 template<
typename NodeT,
typename OtherNodeT,
typename VisitorOp,
679 typename ChildAllIterT,
typename OtherChildAllIterT>
680 static inline void doVisit2Node(NodeT&, OtherNodeT&, VisitorOp&);
682 template<
typename NodeT,
typename VisitorOp,
683 typename ChildAllIterT,
typename OtherChildAllIterT>
684 static inline void doVisit2(NodeT&, OtherChildAllIterT&, VisitorOp&,
bool otherIsLHS);
686 ChildNodeType* getChildNode(
Index n);
687 const ChildNodeType* getChildNode(
Index n)
const;
700 template<
typename ChildT, Index Log2Dim>
704 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(background);
708 template<
typename ChildT, Index Log2Dim>
711 mOrigin(origin[0] & ~(DIM - 1),
712 origin[1] & ~(DIM - 1),
713 origin[2] & ~(DIM - 1))
720 template<
typename ChildT, Index Log2Dim>
723 mChildMask(other.mChildMask),
724 mValueMask(other.mValueMask),
725 mOrigin(other.mOrigin)
736 template<
typename ChildT, Index Log2Dim>
737 template<
typename OtherChildNodeType>
741 mChildMask(other.mChildMask),
742 mValueMask(other.mValueMask),
743 mOrigin(other.mOrigin)
755 template<
typename ChildT, Index Log2Dim>
756 template<
typename OtherChildNodeType>
760 mChildMask(other.mChildMask),
761 mValueMask(other.mValueMask),
762 mOrigin(other.mOrigin)
772 template<
typename ChildT, Index Log2Dim>
776 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
777 delete mNodes[iter.pos()].getChild();
785 template<
typename ChildT, Index Log2Dim>
789 if (ChildNodeType::getLevel() == 0)
return mChildMask.countOn();
791 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
792 sum += iter->leafCount();
798 template<
typename ChildT, Index Log2Dim>
803 if (ChildNodeType::getLevel() == 0)
return sum;
804 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
805 sum += iter->nonLeafCount();
811 template<
typename ChildT, Index Log2Dim>
815 Index64 sum = ChildT::NUM_VOXELS * mValueMask.countOn();
816 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
817 sum += iter->onVoxelCount();
823 template<
typename ChildT, Index Log2Dim>
827 Index64 sum = ChildT::NUM_VOXELS * (NUM_VALUES-mValueMask.countOn()-mChildMask.countOn());
828 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
829 sum += iter->offVoxelCount();
835 template<
typename ChildT, Index Log2Dim>
840 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
841 sum += mNodes[iter.pos()].getChild()->onLeafVoxelCount();
847 template<
typename ChildT, Index Log2Dim>
852 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
853 sum += mNodes[iter.pos()].getChild()->offLeafVoxelCount();
858 template<
typename ChildT, Index Log2Dim>
862 Index64 sum = mValueMask.countOn();
863 for (
ChildOnCIter iter = this->cbeginChildOn(); LEVEL>1 && iter; ++iter) {
864 sum += iter->onTileCount();
869 template<
typename ChildT, Index Log2Dim>
874 + mValueMask.memUsage() +
sizeof(mOrigin);
875 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
876 sum += iter->memUsage();
882 template<
typename ChildT, Index Log2Dim>
886 if (bbox.isInside(this->getNodeBoundingBox()))
return;
888 for (
ValueOnCIter i = this->cbeginValueOn(); i; ++i) bbox.expand(i.getCoord(), ChildT::DIM);
890 for (
ChildOnCIter i = this->cbeginChildOn(); i; ++i) i->evalActiveVoxelBoundingBox(bbox);
893 template<
typename ChildT, Index Log2Dim>
897 if (bbox.isInside(this->getNodeBoundingBox()))
return;
899 for (
ValueOnCIter i = this->cbeginValueOn(); i; ++i) bbox.expand(i.getCoord(), ChildT::DIM);
901 for (
ChildOnCIter i = this->cbeginChildOn(); i; ++i) i->evalActiveBoundingBox(bbox, visitVoxels);
908 template<
typename ChildT, Index Log2Dim>
909 template<
typename PruneOp>
913 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
914 const Index i = iter.pos();
915 ChildT* child = mNodes[i].getChild();
916 if (!op(*child))
continue;
918 mChildMask.setOff(i);
919 mValueMask.set(i, op.state);
920 mNodes[i].setValue(op.value);
926 template<
typename ChildT, Index Log2Dim>
935 template<
typename ChildT, Index Log2Dim>
944 template<
typename ChildT, Index Log2Dim>
948 this->pruneInactive(this->getBackground());
955 template<
typename ChildT, Index Log2Dim>
956 template<
typename NodeT>
960 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
961 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
963 const Index n = this->coordToOffset(xyz);
964 if (mChildMask.isOff(n))
return NULL;
965 ChildT* child = mNodes[n].getChild();
966 if (boost::is_same<NodeT, ChildT>::value) {
967 mChildMask.setOff(n);
968 mValueMask.set(n, state);
969 mNodes[n].setValue(value);
971 return (boost::is_same<NodeT, ChildT>::value)
972 ?
reinterpret_cast<NodeT*
>(child)
973 : child->template stealNode<NodeT>(xyz, value, state);
981 template<
typename ChildT, Index Log2Dim>
982 template<
typename NodeT>
986 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
987 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
989 const Index n = this->coordToOffset(xyz);
990 if (mChildMask.isOff(n))
return NULL;
991 ChildT* child = mNodes[n].getChild();
992 return (boost::is_same<NodeT, ChildT>::value)
993 ?
reinterpret_cast<NodeT*
>(child)
994 : child->template probeNode<NodeT>(xyz);
999 template<
typename ChildT, Index Log2Dim>
1000 template<
typename NodeT,
typename AccessorT>
1004 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1005 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1007 const Index n = this->coordToOffset(xyz);
1008 if (mChildMask.isOff(n))
return NULL;
1009 ChildT* child = mNodes[n].getChild();
1010 acc.insert(xyz, child);
1011 return (boost::is_same<NodeT, ChildT>::value)
1012 ?
reinterpret_cast<NodeT*
>(child)
1013 : child->template probeNodeAndCache<NodeT>(xyz, acc);
1018 template<
typename ChildT, Index Log2Dim>
1019 template<
typename NodeT>
1023 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1024 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1026 const Index n = this->coordToOffset(xyz);
1027 if (mChildMask.isOff(n))
return NULL;
1028 const ChildT* child = mNodes[n].getChild();
1029 return (boost::is_same<NodeT, ChildT>::value)
1030 ?
reinterpret_cast<const NodeT*
>(child)
1031 : child->template probeConstNode<NodeT>(xyz);
1036 template<
typename ChildT, Index Log2Dim>
1037 template<
typename NodeT,
typename AccessorT>
1041 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1042 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1044 const Index n = this->coordToOffset(xyz);
1045 if (mChildMask.isOff(n))
return NULL;
1046 const ChildT* child = mNodes[n].getChild();
1047 acc.insert(xyz, child);
1048 return (boost::is_same<NodeT, ChildT>::value)
1049 ?
reinterpret_cast<const NodeT*
>(child)
1050 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
1058 template<
typename ChildT, Index Log2Dim>
1059 inline typename ChildT::LeafNodeType*
1062 return this->
template probeNode<LeafNodeType>(xyz);
1066 template<
typename ChildT, Index Log2Dim>
1067 template<
typename AccessorT>
1068 inline typename ChildT::LeafNodeType*
1071 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
1075 template<
typename ChildT, Index Log2Dim>
1076 template<
typename AccessorT>
1077 inline const typename ChildT::LeafNodeType*
1080 return this->probeConstLeafAndCache(xyz, acc);
1084 template<
typename ChildT, Index Log2Dim>
1085 inline const typename ChildT::LeafNodeType*
1088 return this->
template probeConstNode<LeafNodeType>(xyz);
1092 template<
typename ChildT, Index Log2Dim>
1093 template<
typename AccessorT>
1094 inline const typename ChildT::LeafNodeType*
1097 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
1104 template<
typename ChildT, Index Log2Dim>
1108 assert(leaf != NULL);
1109 const Coord& xyz = leaf->origin();
1110 const Index n = this->coordToOffset(xyz);
1111 ChildT* child = NULL;
1112 if (mChildMask.isOff(n)) {
1113 if (ChildT::LEVEL>0) {
1114 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1116 child =
reinterpret_cast<ChildT*
>(leaf);
1118 this->setChildNode(n, child);
1120 if (ChildT::LEVEL>0) {
1121 child = mNodes[n].getChild();
1123 delete mNodes[n].getChild();
1124 child =
reinterpret_cast<ChildT*
>(leaf);
1125 mNodes[n].setChild(child);
1128 child->addLeaf(leaf);
1132 template<
typename ChildT, Index Log2Dim>
1133 template<
typename AccessorT>
1137 assert(leaf != NULL);
1138 const Coord& xyz = leaf->origin();
1139 const Index n = this->coordToOffset(xyz);
1140 ChildT* child = NULL;
1141 if (mChildMask.isOff(n)) {
1142 if (ChildT::LEVEL>0) {
1143 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1144 acc.insert(xyz, child);
1146 child =
reinterpret_cast<ChildT*
>(leaf);
1148 this->setChildNode(n, child);
1150 if (ChildT::LEVEL>0) {
1151 child = mNodes[n].getChild();
1152 acc.insert(xyz, child);
1154 delete mNodes[n].getChild();
1155 child =
reinterpret_cast<ChildT*
>(leaf);
1156 mNodes[n].setChild(child);
1159 child->addLeafAndCache(leaf, acc);
1166 template<
typename ChildT, Index Log2Dim>
1170 assert(n < NUM_VALUES);
1171 this->makeChildNodeEmpty(n, value);
1172 mValueMask.set(n, state);
1176 template<
typename ChildT, Index Log2Dim>
1181 if (LEVEL >= level) {
1182 const Index n = this->coordToOffset(xyz);
1183 if (mChildMask.isOff(n)) {
1184 if (LEVEL > level) {
1185 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1186 this->setChildNode(n, child);
1187 child->addTile(level, xyz, value, state);
1189 mValueMask.set(n, state);
1190 mNodes[n].setValue(value);
1193 ChildT* child = mNodes[n].getChild();
1194 if (LEVEL > level) {
1195 child->addTile(level, xyz, value, state);
1198 mChildMask.setOff(n);
1199 mValueMask.set(n, state);
1200 mNodes[n].setValue(value);
1207 template<
typename ChildT, Index Log2Dim>
1208 template<
typename AccessorT>
1211 const ValueType& value,
bool state, AccessorT& acc)
1213 if (LEVEL >= level) {
1214 const Index n = this->coordToOffset(xyz);
1215 if (mChildMask.isOff(n)) {
1216 if (LEVEL > level) {
1217 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1218 this->setChildNode(n, child);
1219 acc.insert(xyz, child);
1220 child->addTileAndCache(level, xyz, value, state, acc);
1222 mValueMask.set(n, state);
1223 mNodes[n].setValue(value);
1226 ChildT* child = mNodes[n].getChild();
1227 if (LEVEL > level) {
1228 acc.insert(xyz, child);
1229 child->addTileAndCache(level, xyz, value, state, acc);
1232 mChildMask.setOff(n);
1233 mValueMask.set(n, state);
1234 mNodes[n].setValue(value);
1244 template<
typename ChildT, Index Log2Dim>
1245 inline typename ChildT::LeafNodeType*
1248 const Index n = this->coordToOffset(xyz);
1249 ChildT* child = NULL;
1250 if (mChildMask.isOff(n)) {
1251 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1252 this->setChildNode(n, child);
1254 child = mNodes[n].getChild();
1256 return child->touchLeaf(xyz);
1260 template<
typename ChildT, Index Log2Dim>
1261 template<
typename AccessorT>
1262 inline typename ChildT::LeafNodeType*
1265 const Index n = this->coordToOffset(xyz);
1266 if (mChildMask.isOff(n)) {
1267 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), mValueMask.isOn(n)));
1269 acc.insert(xyz, mNodes[n].getChild());
1270 return mNodes[n].getChild()->touchLeafAndCache(xyz, acc);
1277 template<
typename ChildT, Index Log2Dim>
1282 bool allEqual =
true, firstValue =
true, valueState =
true;
1284 for (
Index i = 0; allEqual && i < NUM_VALUES; ++i) {
1285 if (this->isChildMaskOff(i)) {
1290 valueState = isValueMaskOn(i);
1291 value = mNodes[i].getValue();
1293 allEqual = (isValueMaskOn(i) == valueState)
1299 ValueType childValue = zeroVal<ValueType>();
1300 bool isChildOn =
false;
1301 if (mNodes[i].getChild()->isConstant(childValue, isChildOn, tolerance)) {
1304 valueState = isChildOn;
1307 allEqual = (isChildOn == valueState)
1326 template<
typename ChildT, Index Log2Dim>
1330 const bool anyActiveTiles = !mValueMask.isOff();
1331 if (LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1332 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1333 if (iter->hasActiveTiles())
return true;
1339 template<
typename ChildT, Index Log2Dim>
1343 const Index n = this->coordToOffset(xyz);
1344 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1345 return mNodes[n].getChild()->isValueOn(xyz);
1348 template<
typename ChildT, Index Log2Dim>
1349 template<
typename AccessorT>
1353 const Index n = this->coordToOffset(xyz);
1354 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1355 acc.insert(xyz, mNodes[n].getChild());
1356 return mNodes[n].getChild()->isValueOnAndCache(xyz, acc);
1360 template<
typename ChildT, Index Log2Dim>
1361 inline const typename ChildT::ValueType&
1364 const Index n = this->coordToOffset(xyz);
1365 return this->isChildMaskOff(n) ? mNodes[n].getValue()
1366 : mNodes[n].getChild()->getValue(xyz);
1369 template<
typename ChildT, Index Log2Dim>
1370 template<
typename AccessorT>
1371 inline const typename ChildT::ValueType&
1374 const Index n = this->coordToOffset(xyz);
1375 if (this->isChildMaskOn(n)) {
1376 acc.insert(xyz, mNodes[n].getChild());
1377 return mNodes[n].getChild()->getValueAndCache(xyz, acc);
1379 return mNodes[n].getValue();
1383 template<
typename ChildT, Index Log2Dim>
1387 const Index n = this->coordToOffset(xyz);
1388 return this->isChildMaskOff(n) ? LEVEL : mNodes[n].getChild()->getValueLevel(xyz);
1391 template<
typename ChildT, Index Log2Dim>
1392 template<
typename AccessorT>
1396 const Index n = this->coordToOffset(xyz);
1397 if (this->isChildMaskOn(n)) {
1398 acc.insert(xyz, mNodes[n].getChild());
1399 return mNodes[n].getChild()->getValueLevelAndCache(xyz, acc);
1405 template<
typename ChildT, Index Log2Dim>
1409 const Index n = this->coordToOffset(xyz);
1410 if (this->isChildMaskOff(n)) {
1411 value = mNodes[n].getValue();
1412 return this->isValueMaskOn(n);
1414 return mNodes[n].getChild()->probeValue(xyz, value);
1417 template<
typename ChildT, Index Log2Dim>
1418 template<
typename AccessorT>
1423 const Index n = this->coordToOffset(xyz);
1424 if (this->isChildMaskOn(n)) {
1425 acc.insert(xyz, mNodes[n].getChild());
1426 return mNodes[n].getChild()->probeValueAndCache(xyz, value, acc);
1428 value = mNodes[n].getValue();
1429 return this->isValueMaskOn(n);
1433 template<
typename ChildT, Index Log2Dim>
1437 const Index n = this->coordToOffset(xyz);
1438 bool hasChild = this->isChildMaskOn(n);
1439 if (!hasChild && this->isValueMaskOn(n)) {
1443 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
true));
1445 if (hasChild) mNodes[n].getChild()->setValueOff(xyz);
1449 template<
typename ChildT, Index Log2Dim>
1453 const Index n = this->coordToOffset(xyz);
1454 bool hasChild = this->isChildMaskOn(n);
1455 if (!hasChild && !this->isValueMaskOn(n)) {
1459 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
false));
1461 if (hasChild) mNodes[n].getChild()->setValueOn(xyz);
1465 template<
typename ChildT, Index Log2Dim>
1470 bool hasChild = this->isChildMaskOn(n);
1472 const bool active = this->isValueMaskOn(n);
1478 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1481 if (hasChild) mNodes[n].getChild()->setValueOff(xyz, value);
1484 template<
typename ChildT, Index Log2Dim>
1485 template<
typename AccessorT>
1491 bool hasChild = this->isChildMaskOn(n);
1493 const bool active = this->isValueMaskOn(n);
1499 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1503 ChildT* child = mNodes[n].getChild();
1504 acc.insert(xyz, child);
1505 child->setValueOffAndCache(xyz, value, acc);
1510 template<
typename ChildT, Index Log2Dim>
1514 const Index n = this->coordToOffset(xyz);
1515 bool hasChild = this->isChildMaskOn(n);
1517 const bool active = this->isValueMaskOn(n);
1523 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1526 if (hasChild) mNodes[n].getChild()->setValueOn(xyz, value);
1529 template<
typename ChildT, Index Log2Dim>
1530 template<
typename AccessorT>
1535 const Index n = this->coordToOffset(xyz);
1536 bool hasChild = this->isChildMaskOn(n);
1538 const bool active = this->isValueMaskOn(n);
1544 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1548 acc.insert(xyz, mNodes[n].getChild());
1549 mNodes[n].getChild()->setValueAndCache(xyz, value, acc);
1554 template<
typename ChildT, Index Log2Dim>
1558 const Index n = this->coordToOffset(xyz);
1559 bool hasChild = this->isChildMaskOn(n);
1563 const bool active = this->isValueMaskOn(n);
1565 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1567 if (hasChild) mNodes[n].getChild()->setValueOnly(xyz, value);
1570 template<
typename ChildT, Index Log2Dim>
1571 template<
typename AccessorT>
1576 const Index n = this->coordToOffset(xyz);
1577 bool hasChild = this->isChildMaskOn(n);
1581 const bool active = this->isValueMaskOn(n);
1583 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1586 acc.insert(xyz, mNodes[n].getChild());
1587 mNodes[n].getChild()->setValueOnlyAndCache(xyz, value, acc);
1592 template<
typename ChildT, Index Log2Dim>
1596 const Index n = this->coordToOffset(xyz);
1597 bool hasChild = this->isChildMaskOn(n);
1599 if (on != this->isValueMaskOn(n)) {
1604 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1607 if (hasChild) mNodes[n].getChild()->setActiveState(xyz, on);
1610 template<
typename ChildT, Index Log2Dim>
1611 template<
typename AccessorT>
1615 const Index n = this->coordToOffset(xyz);
1616 bool hasChild = this->isChildMaskOn(n);
1618 if (on != this->isValueMaskOn(n)) {
1623 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1627 ChildT* child = mNodes[n].getChild();
1628 acc.insert(xyz, child);
1629 child->setActiveStateAndCache(xyz, on, acc);
1634 template<
typename ChildT, Index Log2Dim>
1638 mValueMask = !mChildMask;
1639 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1640 mNodes[iter.pos()].getChild()->setValuesOn();
1645 template<
typename ChildT, Index Log2Dim>
1646 template<
typename ModifyOp>
1651 bool hasChild = this->isChildMaskOn(n);
1655 const bool active = this->isValueMaskOn(n);
1656 bool createChild = !active;
1660 const ValueType& tileVal = mNodes[n].getValue();
1667 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1670 if (hasChild) mNodes[n].getChild()->modifyValue(xyz, op);
1673 template<
typename ChildT, Index Log2Dim>
1674 template<
typename ModifyOp,
typename AccessorT>
1680 bool hasChild = this->isChildMaskOn(n);
1684 const bool active = this->isValueMaskOn(n);
1685 bool createChild = !active;
1689 const ValueType& tileVal = mNodes[n].getValue();
1696 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1701 acc.insert(xyz, child);
1702 child->modifyValueAndCache(xyz, op, acc);
1707 template<
typename ChildT, Index Log2Dim>
1708 template<
typename ModifyOp>
1713 bool hasChild = this->isChildMaskOn(n);
1715 const bool tileState = this->isValueMaskOn(n);
1716 const ValueType& tileVal = mNodes[n].getValue();
1717 bool modifiedState = !tileState;
1719 op(modifiedVal, modifiedState);
1724 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1727 if (hasChild) mNodes[n].getChild()->modifyValueAndActiveState(xyz, op);
1730 template<
typename ChildT, Index Log2Dim>
1731 template<
typename ModifyOp,
typename AccessorT>
1734 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1737 bool hasChild = this->isChildMaskOn(n);
1739 const bool tileState = this->isValueMaskOn(n);
1740 const ValueType& tileVal = mNodes[n].getValue();
1741 bool modifiedState = !tileState;
1743 op(modifiedVal, modifiedState);
1748 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1753 acc.insert(xyz, child);
1754 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1762 template<
typename ChildT, Index Log2Dim>
1766 Coord xyz, tileMin, tileMax;
1767 for (
int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
1769 for (
int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
1771 for (
int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
1775 const Index n = this->coordToOffset(xyz);
1776 tileMin = this->offsetToGlobalCoord(n);
1777 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
1779 if (xyz != tileMin || Coord::lessThan(bbox.max(), tileMax)) {
1783 ChildT* child = NULL;
1784 if (this->isChildMaskOff(n)) {
1787 child =
new ChildT(xyz, mNodes[n].getValue(), this->isValueMaskOn(n));
1788 this->setChildNode(n, child);
1790 child = mNodes[n].getChild();
1803 this->makeChildNodeEmpty(n, value);
1804 mValueMask.set(n, active);
1815 template<
typename ChildT, Index Log2Dim>
1816 template<
typename DenseT>
1820 typedef typename DenseT::ValueType DenseValueType;
1822 const size_t xStride = dense.xStride(), yStride = dense.yStride();
1823 const Coord&
min = dense.bbox().min();
1824 for (Coord xyz = bbox.min(),
max; xyz[0] <= bbox.max()[0]; xyz[0] =
max[0] + 1) {
1825 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] =
max[1] + 1) {
1826 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] =
max[2] + 1) {
1827 const Index n = this->coordToOffset(xyz);
1829 max = this->offsetToGlobalCoord(n).offsetBy(ChildT::DIM-1);
1834 if (this->isChildMaskOn(n)) {
1835 mNodes[n].getChild()->copyToDense(sub, dense);
1837 const ValueType value = mNodes[n].getValue();
1838 sub.translate(-min);
1839 DenseValueType* a0 = dense.data() + sub.min()[2];
1840 for (
Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
1841 DenseValueType* a1 = a0 + x*xStride;
1842 for (
Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
1843 DenseValueType* a2 = a1 + y*yStride;
1844 for (
Int32 z=sub.min()[2], ez=sub.max()[2]+1; z<ez; ++z) {
1845 *a2++ = DenseValueType(value);
1859 template<
typename ChildT, Index Log2Dim>
1863 mChildMask.save(os);
1864 mValueMask.save(os);
1868 boost::shared_array<ValueType> values(
new ValueType[NUM_VALUES]);
1869 const ValueType zero = zeroVal<ValueType>();
1870 for (
Index i = 0; i < NUM_VALUES; ++i) {
1871 values[i] = (mChildMask.isOff(i) ? mNodes[i].getValue() : zero);
1877 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1878 iter->writeTopology(os, toHalf);
1883 template<
typename ChildT, Index Log2Dim>
1887 mChildMask.load(is);
1888 mValueMask.load(is);
1891 for (
Index i = 0; i < NUM_VALUES; ++i) {
1892 if (this->isChildMaskOn(i)) {
1894 new ChildNodeType(offsetToGlobalCoord(i), zeroVal<ValueType>());
1895 mNodes[i].setChild(child);
1896 child->readTopology(is);
1899 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
1900 mNodes[i].setValue(value);
1904 const bool oldVersion =
1906 const Index numValues = (oldVersion ? mChildMask.countOff() : NUM_VALUES);
1910 boost::shared_array<ValueType> values(
new ValueType[numValues]);
1916 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
1917 mNodes[iter.pos()].setValue(values[n++]);
1919 assert(n == numValues);
1921 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
1922 mNodes[iter.pos()].setValue(values[iter.pos()]);
1927 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1929 mNodes[iter.pos()].setChild(child);
1930 child->readTopology(is, fromHalf);
1939 template<
typename ChildT, Index Log2Dim>
1940 inline const typename ChildT::ValueType&
1943 return (this->isChildMaskOn(0) ? mNodes[0].getChild()->getFirstValue() : mNodes[0].getValue());
1947 template<
typename ChildT, Index Log2Dim>
1948 inline const typename ChildT::ValueType&
1951 const Index n = NUM_VALUES - 1;
1952 return (this->isChildMaskOn(n) ? mNodes[n].getChild()->getLastValue() : mNodes[n].getValue());
1959 template<
typename ChildT, Index Log2Dim>
1967 template<
typename ChildT, Index Log2Dim>
1973 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1974 iter->signedFloodFill(outsideValue, insideValue);
1976 const Index first = mChildMask.findFirstOn();
1977 if (first < NUM_VALUES) {
1978 bool xInside =
math::isNegative(mNodes[first].getChild()->getFirstValue()),
1979 yInside = xInside, zInside = xInside;
1980 for (
Index x = 0; x != (1 << Log2Dim); ++x) {
1981 const int x00 = x << (2 * Log2Dim);
1982 if (isChildMaskOn(x00)) {
1986 for (
Index y = 0; y != (1 << Log2Dim); ++y) {
1987 const Index xy0 = x00 + (y << Log2Dim);
1988 if (isChildMaskOn(xy0)) {
1992 for (
Index z = 0; z != (1 << Log2Dim); ++z) {
1993 const Index xyz = xy0 + z;
1994 if (isChildMaskOn(xyz)) {
1997 mNodes[xyz].setValue(zInside ? insideValue : outsideValue);
2004 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(v);
2009 template<
typename ChildT, Index Log2Dim>
2013 for (
Index i = 0; i < NUM_VALUES; ++i) {
2014 if (this->isChildMaskOn(i)) {
2015 mNodes[i].getChild()->negate();
2024 template<
typename ChildT, Index Log2Dim>
2028 for (
ValueOnIter iter = this->beginValueOn(); iter; ++iter) {
2029 this->setChildNode(iter.pos(),
new ChildNodeType(iter.getCoord(), iter.getValue(),
true));
2031 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) iter->voxelizeActiveTiles();
2038 template<
typename ChildT, Index Log2Dim>
2039 template<MergePolicy Policy>
2052 const Index n = iter.pos();
2053 if (mChildMask.isOn(n)) {
2055 mNodes[n].getChild()->template merge<MERGE_ACTIVE_STATES>(*iter,
2056 background, otherBackground);
2057 }
else if (mValueMask.isOff(n)) {
2064 child->resetBackground(otherBackground, background);
2065 this->setChildNode(n, child);
2071 const Index n = iter.pos();
2072 if (mValueMask.isOff(n)) {
2074 this->makeChildNodeEmpty(n, iter.getValue());
2075 mValueMask.setOn(n);
2084 const Index n = iter.pos();
2085 if (mChildMask.isOn(n)) {
2087 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2095 child->resetBackground(otherBackground, background);
2096 this->setChildNode(n, child);
2106 const Index n = iter.pos();
2107 if (mChildMask.isOn(n)) {
2109 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2116 child->resetBackground(otherBackground, background);
2117 if (mValueMask.isOn(n)) {
2119 child->template merge<Policy>(mNodes[n].getValue(),
true);
2120 mValueMask.setOff(n);
2122 mChildMask.setOn(n);
2123 mNodes[n].setChild(child);
2129 const Index n = iter.pos();
2130 if (mChildMask.isOn(n)) {
2132 mNodes[n].getChild()->template merge<Policy>(iter.getValue(),
true);
2133 }
else if (mValueMask.isOff(n)) {
2135 mNodes[n].setValue(iter.getValue());
2136 mValueMask.setOn(n);
2147 template<
typename ChildT, Index Log2Dim>
2148 template<MergePolicy Policy>
2157 if (!tileActive)
return;
2160 for (
ValueOffIter iter = this->beginValueOff(); iter; ++iter) {
2161 const Index n = iter.pos();
2162 if (mChildMask.isOn(n)) {
2164 mNodes[n].getChild()->template merge<Policy>(tileValue,
true);
2167 iter.setValue(tileValue);
2168 mValueMask.setOn(n);
2178 template<
typename ChildT, Index Log2Dim>
2179 template<
typename OtherChildT>
2187 for (OtherChildIter iter = other.
cbeginChildOn(); iter; ++iter) {
2189 if (mChildMask.isOn(i)) {
2190 mNodes[i].getChild()->topologyUnion(*iter);
2193 if (mValueMask.isOn(i)) {
2194 mValueMask.isOff(i);
2195 child->setValuesOn();
2197 mChildMask.setOn(i);
2198 mNodes[i].setChild(child);
2202 for (OtherValueIter iter = other.
cbeginValueOn(); iter; ++iter) {
2203 const Index i = iter.pos();
2204 if (mChildMask.isOn(i)) {
2205 mNodes[i].getChild()->setValuesOn();
2206 }
else if (mValueMask.isOff(i)) {
2207 mValueMask.setOn(i);
2212 template<
typename ChildT, Index Log2Dim>
2213 template<
typename OtherChildT>
2219 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2220 const Index i = iter.pos();
2222 iter->topologyIntersection(*(other.
mNodes[i].getChild()), background);
2224 delete mNodes[i].getChild();
2225 mNodes[i].setValue(background);
2226 mChildMask.setOff(i);
2227 mValueMask.setOff(i);
2232 for (
ValueOnCIter iter = this->cbeginValueOn(); iter; ++iter) {
2233 const Index i = iter.pos();
2237 this->setChildNode(i, child);
2239 mValueMask.setOff(i);
2244 template<
typename ChildT, Index Log2Dim>
2245 template<
typename OtherChildT>
2254 for (OtherChildIter iter = other.
cbeginChildOn(); iter; ++iter) {
2256 if (mChildMask.isOn(i)) {
2257 mNodes[i].getChild()->topologyDifference(*iter, background);
2258 }
else if (mValueMask.isOn(i)) {
2260 child->topologyDifference(*iter, background);
2261 this->setChildNode(i, child);
2266 for (OtherValueIter iter = other.
cbeginValueOn(); iter; ++iter) {
2267 const Index i = iter.pos();
2268 if (mChildMask.isOn(i)) {
2269 delete mNodes[i].getChild();
2270 mNodes[i].setValue(background);
2271 mChildMask.setOff(i);
2272 mValueMask.setOff(i);
2273 }
else if (mValueMask.isOn(i)) {
2274 mValueMask.setOff(i);
2282 template<
typename ChildT, Index Log2Dim>
2283 template<
typename CombineOp>
2287 const ValueType zero = zeroVal<ValueType>();
2291 for (
Index i = 0; i < NUM_VALUES; ++i) {
2295 op(args.setARef(mNodes[i].getValue())
2296 .setAIsActive(isValueMaskOn(i))
2297 .setBRef(other.
mNodes[i].getValue())
2299 mNodes[i].setValue(args.result());
2300 mValueMask.set(i, args.resultIsActive());
2308 }
else if (this->isChildMaskOff(i) && other.
isChildMaskOn(i)) {
2317 child->combine(mNodes[i].getValue(), isValueMaskOn(i), swappedOp);
2321 other.
mNodes[i].setValue(zero);
2322 this->setChildNode(i, child);
2328 *child = mNodes[i].getChild(),
2329 *otherChild = other.
mNodes[i].getChild();
2332 if (child && otherChild) {
2333 child->combine(*otherChild, op);
2340 template<
typename ChildT, Index Log2Dim>
2341 template<
typename CombineOp>
2347 for (
Index i = 0; i < NUM_VALUES; ++i) {
2348 if (this->isChildMaskOff(i)) {
2350 op(args.
setARef(mNodes[i].getValue())
2351 .setAIsActive(isValueMaskOn(i))
2353 .setBIsActive(valueIsActive));
2354 mNodes[i].setValue(args.
result());
2360 if (child) child->combine(value, valueIsActive, op);
2369 template<
typename ChildT, Index Log2Dim>
2370 template<
typename CombineOp>
2377 for (
Index i = 0; i < NUM_VALUES; ++i) {
2381 .setBRef(other1.
mNodes[i].getValue())
2384 this->makeChildNodeEmpty(i, args.
result());
2388 ? other0.
mNodes[i].getChild() : other1.
mNodes[i].getChild();
2390 if (this->isChildMaskOff(i)) {
2392 this->setChildNode(i,
new ChildNodeType(otherChild->origin(), mNodes[i].getValue()));
2398 mNodes[i].getChild()->combine2(other0.
mNodes[i].getValue(),
2403 mNodes[i].getChild()->combine2(*other0.
mNodes[i].getChild(),
2408 mNodes[i].getChild()->combine2(*other0.
mNodes[i].getChild(),
2409 *other1.
mNodes[i].getChild(), op);
2416 template<
typename ChildT, Index Log2Dim>
2417 template<
typename CombineOp>
2420 bool valueIsActive, CombineOp& op)
2424 for (
Index i = 0; i < NUM_VALUES; ++i) {
2427 .setAIsActive(valueIsActive)
2428 .setBRef(other.
mNodes[i].getValue())
2431 this->makeChildNodeEmpty(i, args.
result());
2436 if (this->isChildMaskOff(i)) {
2444 mNodes[i].getChild()->combine2(value, *otherChild, valueIsActive, op);
2450 template<
typename ChildT, Index Log2Dim>
2451 template<
typename CombineOp>
2454 bool valueIsActive, CombineOp& op)
2458 for (
Index i = 0; i < NUM_VALUES; ++i) {
2463 .setBIsActive(valueIsActive));
2465 this->makeChildNodeEmpty(i, args.
result());
2470 if (this->isChildMaskOff(i)) {
2472 this->setChildNode(i,
new ChildNodeType(otherChild->origin(), mNodes[i].getValue()));
2476 mNodes[i].getChild()->combine2(*otherChild, value, valueIsActive, op);
2485 template<
typename ChildT, Index Log2Dim>
2486 template<
typename BBoxOp>
2492 op.operator()<LEVEL>(CoordBBox::createCube(i.getCoord(), ChildNodeType::DIM));
2494 op.template operator()<LEVEL>(CoordBBox::createCube(i.getCoord(), ChildNodeType::DIM));
2497 if (op.template descent<LEVEL>()) {
2498 for (
ChildOnCIter i = this->cbeginChildOn(); i; ++i) i->visitActiveBBox(op);
2502 op.operator()<LEVEL>(i->getNodeBoundingBox());
2504 op.template operator()<LEVEL>(i->getNodeBoundingBox());
2511 template<
typename ChildT, Index Log2Dim>
2512 template<
typename VisitorOp>
2516 doVisit<InternalNode, VisitorOp, ChildAllIter>(*
this, op);
2520 template<
typename ChildT, Index Log2Dim>
2521 template<
typename VisitorOp>
2525 doVisit<const InternalNode, VisitorOp, ChildAllCIter>(*
this, op);
2529 template<
typename ChildT, Index Log2Dim>
2530 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
2534 typename NodeT::ValueType val;
2535 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2536 if (op(iter))
continue;
2537 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2547 template<
typename ChildT, Index Log2Dim>
2548 template<
typename OtherNodeType,
typename VisitorOp>
2553 typename OtherNodeType::ChildAllIter>(*
this, other, op);
2557 template<
typename ChildT, Index Log2Dim>
2558 template<
typename OtherNodeType,
typename VisitorOp>
2563 typename OtherNodeType::ChildAllCIter>(*
this, other, op);
2567 template<
typename ChildT, Index Log2Dim>
2570 typename OtherNodeT,
2572 typename ChildAllIterT,
2573 typename OtherChildAllIterT>
2578 BOOST_STATIC_ASSERT(OtherNodeT::NUM_VALUES == NodeT::NUM_VALUES);
2579 BOOST_STATIC_ASSERT(OtherNodeT::LEVEL == NodeT::LEVEL);
2581 typename NodeT::ValueType val;
2582 typename OtherNodeT::ValueType otherVal;
2584 ChildAllIterT iter =
self.beginChildAll();
2585 OtherChildAllIterT otherIter = other.beginChildAll();
2587 for ( ; iter && otherIter; ++iter, ++otherIter)
2589 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2591 typename ChildAllIterT::ChildNodeType* child =
2592 (skipBranch & 1U) ? NULL : iter.probeChild(val);
2593 typename OtherChildAllIterT::ChildNodeType* otherChild =
2594 (skipBranch & 2U) ? NULL : otherIter.probeChild(otherVal);
2596 if (child != NULL && otherChild != NULL) {
2597 child->visit2Node(*otherChild, op);
2598 }
else if (child != NULL) {
2599 child->visit2(otherIter, op);
2600 }
else if (otherChild != NULL) {
2601 otherChild->visit2(iter, op,
true);
2610 template<
typename ChildT, Index Log2Dim>
2611 template<
typename OtherChildAllIterType,
typename VisitorOp>
2614 VisitorOp& op,
bool otherIsLHS)
2616 doVisit2<InternalNode, VisitorOp, ChildAllIter, OtherChildAllIterType>(
2617 *
this, otherIter, op, otherIsLHS);
2621 template<
typename ChildT, Index Log2Dim>
2622 template<
typename OtherChildAllIterType,
typename VisitorOp>
2625 VisitorOp& op,
bool otherIsLHS)
const
2627 doVisit2<const InternalNode, VisitorOp, ChildAllCIter, OtherChildAllIterType>(
2628 *
this, otherIter, op, otherIsLHS);
2632 template<
typename ChildT, Index Log2Dim>
2633 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT,
typename OtherChildAllIterT>
2636 VisitorOp& op,
bool otherIsLHS)
2638 if (!otherIter)
return;
2640 const size_t skipBitMask = (otherIsLHS ? 2U : 1U);
2642 typename NodeT::ValueType val;
2643 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2644 const size_t skipBranch =
static_cast<size_t>(
2645 otherIsLHS ? op(otherIter, iter) : op(iter, otherIter));
2647 typename ChildAllIterT::ChildNodeType* child =
2648 (skipBranch & skipBitMask) ? NULL : iter.probeChild(val);
2650 if (child != NULL) child->visit2(otherIter, op, otherIsLHS);
2658 template<
typename ChildT, Index Log2Dim>
2662 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2663 iter->writeBuffers(os, toHalf);
2668 template<
typename ChildT, Index Log2Dim>
2672 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2673 iter->readBuffers(is, fromHalf);
2681 template<
typename ChildT, Index Log2Dim>
2685 dims.push_back(Log2Dim);
2686 ChildNodeType::getNodeLog2Dims(dims);
2690 template<
typename ChildT, Index Log2Dim>
2694 assert(n<(1<<3*Log2Dim));
2695 xyz.setX(n >> 2*Log2Dim);
2696 n &= ((1<<2*Log2Dim)-1);
2697 xyz.setY(n >> Log2Dim);
2698 xyz.setZ(n & ((1<<Log2Dim)-1));
2702 template<
typename ChildT, Index Log2Dim>
2706 return (((xyz[0]&DIM-1u)>>ChildNodeType::TOTAL)<<2*Log2Dim)
2707 + (((xyz[1]&DIM-1u)>>ChildNodeType::TOTAL)<< Log2Dim)
2708 + ((xyz[2]&DIM-1u)>>ChildNodeType::TOTAL);
2712 template<
typename ChildT, Index Log2Dim>
2717 this->offsetToLocalCoord(n, local);
2718 local <<= ChildT::TOTAL;
2719 return local + this->origin();
2726 template<
typename ChildT, Index Log2Dim>
2732 for (
Index i = 0; i < NUM_VALUES; ++i) {
2733 if (this->isChildMaskOn(i)) {
2734 mNodes[i].getChild()->resetBackground(oldBackground, newBackground);
2735 }
else if (this->isValueMaskOff(i)) {
2737 mNodes[i].setValue(newBackground);
2746 template<
typename ChildT, Index Log2Dim>
2747 template<
typename OtherChildNodeType, Index OtherLog2Dim>
2752 if (Log2Dim != OtherLog2Dim || mChildMask != other->
mChildMask ||
2753 mValueMask != other->
mValueMask)
return false;
2754 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2755 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
2761 template<
typename ChildT, Index Log2Dim>
2766 if (this->isChildMaskOn(i)) {
2767 delete mNodes[i].getChild();
2769 mChildMask.setOn(i);
2770 mValueMask.setOff(i);
2772 mNodes[i].setChild(child);
2775 template<
typename ChildT, Index Log2Dim>
2780 assert(mChildMask.isOff(i));
2781 mChildMask.setOn(i);
2782 mValueMask.setOff(i);
2783 mNodes[i].setChild(child);
2787 template<
typename ChildT, Index Log2Dim>
2791 if (this->isChildMaskOff(i)) {
2792 mNodes[i].setValue(value);
2796 mChildMask.setOff(i);
2797 mNodes[i].setValue(value);
2802 template<
typename ChildT, Index Log2Dim>
2806 delete this->unsetChildNode(n, value);
2809 template<
typename ChildT, Index Log2Dim>
2813 return (this->isChildMaskOn(n) ? mNodes[n].getChild() : NULL);
2817 template<
typename ChildT, Index Log2Dim>
2818 inline const ChildT*
2821 return (this->isChildMaskOn(n) ? mNodes[n].getChild() : NULL);
2828 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:139
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:1060
OPENVDB_DEPRECATED Coord getOrigin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:240
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...
bool isValueMaskOn() const
Definition: InternalNode.h:657
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:180
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:237
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:2789
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes ...
Definition: InternalNode.h:2488
NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:107
ChildIter< const InternalNode, const ChildNodeType, MaskOnIterator, ChildOn > ChildOnCIter
Definition: InternalNode.h:189
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:203
void signedFloodFill(const ValueType &background)
Overwrite each inactive value in this node and in any child nodes with a new value whose magnitude is...
Definition: InternalNode.h:1961
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1451
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:1385
Definition: InternalNode.h:113
int32_t Int32
Definition: Types.h:58
ChildT & getItem(Index pos) const
Definition: InternalNode.h:126
ValueOffIter beginValueOff()
Definition: InternalNode.h:219
ChildNodeType * getChildNode(Index n)
Definition: InternalNode.h:2811
bool isValueMaskOff() const
Definition: InternalNode.h:659
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...
ValueAllIter beginValueAll()
Definition: InternalNode.h:220
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:661
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffCIter
Definition: InternalNode.h:191
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:202
Index pos() const
Identical to offset.
Definition: Iterator.h:94
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:206
NodeUnion< ValueType, ChildNodeType > UnionType
Definition: InternalNode.h:63
InternalNode()
Definition: InternalNode.h:84
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...
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:205
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:1556
Definition: NodeMasks.h:220
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:232
uint32_t Index32
Definition: Types.h:54
DenseIter< const InternalNode, const ChildNodeType, ValueType, ChildAll > ChildAllCIter
Definition: InternalNode.h:193
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: InternalNode.h:135
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:1764
void visit(VisitorOp &)
Definition: InternalNode.h:2514
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1351
ValueIter< InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffIter
Definition: InternalNode.h:190
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2285
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:1210
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:2804
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:212
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:174
void negate()
Definition: InternalNode.h:2011
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:656
virtual ~InternalNode()
Definition: InternalNode.h:774
void visit2Node(OtherNodeType &other, VisitorOp &)
Definition: InternalNode.h:2550
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1613
bool isEmpty() const
Definition: InternalNode.h:266
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.
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:2692
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:148
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:395
bool isChildMaskOff() const
Definition: InternalNode.h:662
ChildIter< InternalNode, ChildNodeType, MaskOnIterator, ChildOn > ChildOnIter
Definition: InternalNode.h:188
static void doVisit2(NodeT &, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: InternalNode.h:2635
Index32 leafCount() const
Definition: InternalNode.h:787
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:693
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1532
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:958
DenseIter()
Definition: InternalNode.h:162
Definition: InternalNode.h:112
Definition: InternalNode.h:119
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:482
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:276
static Index getLevel()
Definition: InternalNode.h:224
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:2777
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllCIter
Definition: InternalNode.h:200
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:264
util::NodeMask< Log2Dim > NodeMaskType
Definition: InternalNode.h:64
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1362
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:107
Definition: InternalNode.h:57
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:2749
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:306
OPENVDB_IMPORT uint32_t getFormatVersion(std::istream &)
Return the file format version number associated with the given input stream.
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:145
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: InternalNode.h:2683
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:1949
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:1861
#define OPENVDB_VERSION_NAME
Definition: version.h:45
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:1178
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:242
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:123
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:207
static const Index NUM_VALUES
Definition: InternalNode.h:70
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1435
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:58
Definition: InternalNode.h:156
Index64 onTileCount() const
Definition: InternalNode.h:860
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:274
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:217
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:2763
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:129
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:78
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:658
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:849
ValueIter< const InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnCIter
Definition: InternalNode.h:196
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:204
NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:108
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:211
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:1594
void voxelizeActiveTiles()
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2026
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:215
ChildNodeType::ValueType ValueType
Definition: InternalNode.h:62
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.
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:149
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
Helper class for use with Tree::pruneOp() to replace inactive branches with more memory-efficient ina...
Definition: tree/Util.h:74
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:1394
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:353
bool isConstant(ValueType &constValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1279
NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:109
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:837
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:1086
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
DenseIter< InternalNode, ChildNodeType, ValueType, ChildAll > ChildAllIter
Definition: InternalNode.h:192
InternalNode< typename ChildNodeType::template ValueConverter< OtherValueType >::Type, Log2Dim > Type
Definition: InternalNode.h:80
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:1941
ValueIter< InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnIter
Definition: InternalNode.h:195
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:213
Definition: NodeMasks.h:189
Index32 Index
Definition: Types.h:56
OPENVDB_DEPRECATED void evalActiveVoxelBoundingBox(CoordBBox &bbox) const
Definition: InternalNode.h:884
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1341
Helper class for use with Tree::pruneOp() to replace constant branches (to within the provided tolera...
Definition: tree/Util.h:47
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 setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:390
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:214
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffCIter
Definition: InternalNode.h:198
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:1106
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1407
static void doVisit2Node(NodeT &, OtherNodeT &, VisitorOp &)
Definition: InternalNode.h:2575
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllIter
Definition: InternalNode.h:199
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:166
void pruneOp(PruneOp &)
Call the PruneOp functor for each child node and, if the functor returns true, prune the node and rep...
Definition: InternalNode.h:911
boost::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:217
NodeMaskType mValueMask
Definition: InternalNode.h:691
Index64 offVoxelCount() const
Definition: InternalNode.h:825
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2670
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:1710
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:871
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:2714
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1487
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:216
DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT > BaseT
Definition: InternalNode.h:159
const ValueType & result() const
Get the output value.
Definition: Types.h:261
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
NodeMaskType mChildMask
Definition: InternalNode.h:691
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1328
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:1676
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:142
BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:160
CombineArgs & setARef(const ValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:269
ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:61
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:660
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:1648
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffIter
Definition: InternalNode.h:197
ChildOffIter beginChildOff()
Definition: InternalNode.h:209
ChildAllIter beginChildAll()
Definition: InternalNode.h:210
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1636
bool resultIsActive() const
Definition: Types.h:280
Definition: NodeMasks.h:251
ChildIter()
Definition: InternalNode.h:122
_ChildNodeType ChildNodeType
Definition: InternalNode.h:60
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:56
static Index getChildDim()
Definition: InternalNode.h:226
bool isApproxEqual(const Hermite &lhs, const Hermite &rhs)
Definition: Hermite.h:470
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:1246
void pruneInactive()
Reduce the memory footprint of this tree by replacing with background tiles any nodes whose values ar...
Definition: InternalNode.h:946
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2660
uint64_t Index64
Definition: Types.h:55
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:2728
void combine2(const InternalNode &other0, const InternalNode &other1, CombineOp &)
Definition: InternalNode.h:2372
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:288
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:690
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:2041
ChildOnIter beginChildOn()
Definition: InternalNode.h:208
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:1818
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:928
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:378
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:1885
Definition: InternalNode.h:113
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1733
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:279
Index32 nonLeafCount() const
Definition: InternalNode.h:800
Index64 onVoxelCount() const
Definition: InternalNode.h:813
ValueIter()
Definition: InternalNode.h:138
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:2704
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:163
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1420
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:1135
Definition: InternalNode.h:112
ValueOnIter beginValueOn()
Definition: InternalNode.h:218
static Index dim()
Definition: InternalNode.h:223
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:895
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1573
static void doVisit(NodeT &, VisitorOp &)
Definition: InternalNode.h:2532