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(), zStride = dense.zStride();
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() + zStride*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, a2 += zStride) {
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
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:656
void pruneInactive()
Reduce the memory footprint of this tree by replacing with background tiles any nodes whose values ar...
Definition: InternalNode.h:946
bool isConstant(ValueType &constValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1279
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:139
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllIter
Definition: InternalNode.h:199
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:180
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffCIter
Definition: InternalNode.h:191
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:837
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:395
InternalNode()
Definition: InternalNode.h:84
NodeUnion< ValueType, ChildNodeType > UnionType
Definition: InternalNode.h:63
Definition: InternalNode.h:113
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...
DenseIter< InternalNode, ChildNodeType, ValueType, ChildAll > ChildAllIter
Definition: InternalNode.h:192
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1451
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1532
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
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
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.
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
ChildOffIter beginChildOff()
Definition: InternalNode.h:209
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1420
static void doVisit2Node(NodeT &, OtherNodeT &, VisitorOp &)
Definition: InternalNode.h:2575
Index64 offVoxelCount() const
Definition: InternalNode.h:825
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2670
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1636
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1573
static const Index NUM_VALUES
Definition: InternalNode.h:70
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:206
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:871
OPENVDB_DEPRECATED Coord getOrigin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:240
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:216
void negate()
Definition: InternalNode.h:2011
ValueOffIter beginValueOff()
Definition: InternalNode.h:219
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2660
bool isEmpty() const
Definition: InternalNode.h:266
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:237
boost::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:217
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:378
Definition: NodeMasks.h:189
ChildT & getItem(Index pos) const
Definition: InternalNode.h:126
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:690
Helper class for use with Tree::pruneOp() to replace constant branches (to within the provided tolera...
Definition: tree/Util.h:47
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
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
Index32 leafCount() const
Definition: InternalNode.h:787
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:204
static Index getChildDim()
Definition: InternalNode.h:226
Helper class for use with Tree::pruneOp() to replace inactive branches with more memory-efficient ina...
Definition: tree/Util.h:74
InternalNode< typename ChildNodeType::template ValueConverter< OtherValueType >::Type, Log2Dim > Type
Definition: InternalNode.h:80
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:2704
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.
util::NodeMask< Log2Dim > NodeMaskType
Definition: InternalNode.h:64
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1362
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:174
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:288
ValueIter< InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffIter
Definition: InternalNode.h:190
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
Index32 Index
Definition: Types.h:56
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2285
ChildOnIter beginChildOn()
Definition: InternalNode.h:208
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
ValueIter< const InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnCIter
Definition: InternalNode.h:196
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes ...
Definition: InternalNode.h:2488
DenseIter< const InternalNode, const ChildNodeType, ValueType, ChildAll > ChildAllCIter
Definition: InternalNode.h:193
ChildIter< const InternalNode, const ChildNodeType, MaskOnIterator, ChildOn > ChildOnCIter
Definition: InternalNode.h:189
Definition: InternalNode.h:112
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:148
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
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
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
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:213
void voxelizeActiveTiles()
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2026
DenseIter()
Definition: InternalNode.h:162
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1351
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:242
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:207
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
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:482
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1435
Definition: InternalNode.h:119
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:2804
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllCIter
Definition: InternalNode.h:200
bool isValueMaskOff() const
Definition: InternalNode.h:659
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:661
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:145
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:123
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:232
Definition: InternalNode.h:113
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:203
ChildIter< InternalNode, ChildNodeType, MaskOnIterator, ChildOn > ChildOnIter
Definition: InternalNode.h:188
#define OPENVDB_VERSION_NAME
Definition: version.h:45
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 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
OPENVDB_DEPRECATED void evalActiveVoxelBoundingBox(CoordBBox &bbox) const
Definition: InternalNode.h:884
Definition: InternalNode.h:57
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1407
ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:61
ValueAllIter beginValueAll()
Definition: InternalNode.h:220
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:58
Index64 onTileCount() const
Definition: InternalNode.h:860
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1487
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
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:360
uint32_t Index32
Definition: Types.h:54
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
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1328
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:276
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:129
uint64_t Index64
Definition: Types.h:55
int32_t Int32
Definition: Types.h:58
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:1861
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 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
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:78
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:1885
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:211
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1733
CombineArgs & setARef(const ValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:269
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
Definition: InternalNode.h:135
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:212
NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:108
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
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
virtual ~InternalNode()
Definition: InternalNode.h:774
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:149
static Index dim()
Definition: InternalNode.h:223
void combine2(const InternalNode &other0, const InternalNode &other1, CombineOp &)
Definition: InternalNode.h:2372
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
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:390
bool isValueMaskOn() const
Definition: InternalNode.h:657
Definition: version.h:106
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
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:217
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:2763
bool isChildMaskOff() const
Definition: InternalNode.h:662
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:2789
static void doVisit2(NodeT &, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: InternalNode.h:2635
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: InternalNode.h:2683
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:658
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1341
static Index getLevel()
Definition: InternalNode.h:224
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
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffIter
Definition: InternalNode.h:197
ValueIter< InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnIter
Definition: InternalNode.h:195
const ValueType & result() const
Get the output value.
Definition: Types.h:261
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:215
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:1710
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:2714
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.
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:166
ChildNodeType * getChildNode(Index n)
Definition: InternalNode.h:2811
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
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 isApproxEqual(const Hermite &lhs, const Hermite &rhs)
Definition: Hermite.h:470
DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT > BaseT
Definition: InternalNode.h:159
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:274
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
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:202
NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:107
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
Index pos() const
Identical to offset.
Definition: Iterator.h:94
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
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:205
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:313
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:142
BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:160
Definition: NodeMasks.h:220
bool resultIsActive() const
Definition: Types.h:280
Definition: NodeMasks.h:251
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:214
ValueOnIter beginValueOn()
Definition: InternalNode.h:218
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:660
ChildNodeType::ValueType ValueType
Definition: InternalNode.h:62
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 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
ChildAllIter beginChildAll()
Definition: InternalNode.h:210
static void doVisit(NodeT &, VisitorOp &)
Definition: InternalNode.h:2532
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
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:107
NodeMaskType mValueMask
Definition: InternalNode.h:691
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:2041
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1613
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
void visit2Node(OtherNodeType &other, VisitorOp &)
Definition: InternalNode.h:2550
NodeMaskType mChildMask
Definition: InternalNode.h:691
NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:109
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:849
Definition: InternalNode.h:156
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
Index64 onVoxelCount() const
Definition: InternalNode.h:813
ChildIter()
Definition: InternalNode.h:122
OPENVDB_IMPORT uint32_t getFormatVersion(std::istream &)
Return the file format version number associated with the given input stream.
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()
Definition: InternalNode.h:138
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:693
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:163
_ChildNodeType ChildNodeType
Definition: InternalNode.h:60
Definition: InternalNode.h:112
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffCIter
Definition: InternalNode.h:198
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:2777
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