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>
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().setChildNode(pos, &c); }
132 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
134 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
138 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
140 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
143 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
146 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
148 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
159 child = this->parent().getChildNode(pos);
160 if (!child) value = this->parent().mNodes[pos].getValue();
161 return (child != NULL);
167 this->parent().setChildNode(pos, child);
173 this->parent().unsetChildNode(pos, value);
216 static void getNodeLog2Dims(std::vector<Index>& dims);
220 static void offset2coord(
Index n,
Coord& xyz);
229 Index64 onLeafVoxelCount()
const;
230 Index64 offLeafVoxelCount()
const;
237 void evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const;
243 bool isEmpty()
const {
return mChildMask.isOff(); }
248 bool isConstant(ValueType& constValue,
bool& state,
249 const ValueType&
tolerance = zeroVal<ValueType>())
const;
251 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
254 bool isValueOn(
const Coord& xyz)
const;
259 bool hasActiveTiles()
const;
261 const ValueType& getValue(
const Coord& xyz)
const;
262 bool probeValue(
const Coord& xyz, ValueType& value)
const;
270 const ValueType& getFirstValue()
const;
273 const ValueType& getLastValue()
const;
276 void setActiveState(
const Coord& xyz,
bool on);
279 void setValueOff(
const Coord& xyz);
281 void setValueOff(
const Coord& xyz,
const ValueType& value);
283 void setValueOn(
const Coord& xyz);
284 void setValueOn(
const Coord& xyz,
const ValueType& value);
285 void setValueOnly(
const Coord& xyz,
const ValueType& value);
286 void setValueOnMin(
const Coord& xyz,
const ValueType& value);
287 void setValueOnMax(
const Coord& xyz,
const ValueType& value);
288 void setValueOnSum(
const Coord& xyz,
const ValueType& value);
292 void fill(
const CoordBBox& bbox,
const ValueType&,
bool active =
true);
303 template<
typename DenseT>
310 template<
typename AccessorT>
311 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
317 template<
typename AccessorT>
318 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
324 template<
typename AccessorT>
325 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
331 template<
typename AccessorT>
332 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
339 template<
typename AccessorT>
340 void setValueOnSumAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
346 template<
typename AccessorT>
347 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
353 template<
typename AccessorT>
354 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
360 template<
typename AccessorT>
361 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
369 template<
typename AccessorT>
370 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
378 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
379 void readTopology(std::istream&,
bool fromHalf =
false);
380 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
381 void readBuffers(std::istream&,
bool fromHalf =
false);
393 void signedFloodFill(
const ValueType& background);
401 void signedFloodFill(
const ValueType& outside,
const ValueType& inside);
408 void voxelizeActiveTiles();
414 void merge(
InternalNode& other,
const ValueType& background,
const ValueType& otherBackground);
428 template<
typename OtherChildNodeType>
431 template<
typename CombineOp>
433 template<
typename CombineOp>
434 void combine(
const ValueType& value,
bool valueIsActive, CombineOp&);
436 template<
typename CombineOp>
438 template<
typename CombineOp>
439 void combine2(
const ValueType& value,
const InternalNode& other,
440 bool valueIsActive, CombineOp&);
441 template<
typename CombineOp>
442 void combine2(
const InternalNode& other,
const ValueType& value,
443 bool valueIsActive, CombineOp&);
450 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
452 template<
typename VisitorOp>
void visit(VisitorOp&);
453 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
455 template<
typename OtherNodeType,
typename VisitorOp>
456 void visit2Node(OtherNodeType& other, VisitorOp&);
457 template<
typename OtherNodeType,
typename VisitorOp>
458 void visit2Node(OtherNodeType& other, VisitorOp&)
const;
459 template<
typename IterT,
typename VisitorOp>
460 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false);
461 template<
typename IterT,
typename VisitorOp>
462 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false)
const;
470 template<
typename PruneOp>
void pruneOp(PruneOp&);
475 void prune(
const ValueType&
tolerance = zeroVal<ValueType>());
479 void pruneInactive(
const ValueType&);
483 void pruneInactive();
487 void addLeaf(LeafNodeType* leaf);
491 template<
typename AccessorT>
492 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
502 template<
typename NodeT>
503 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
507 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
511 template<
typename AccessorT>
512 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType& value,
513 bool state, AccessorT&);
517 template <
typename NodeType>
518 NodeType* probeNode(
const Coord& xyz);
519 template <
typename NodeType>
520 const NodeType* probeConstNode(
const Coord& xyz)
const;
521 template<
typename NodeType,
typename AccessorT>
522 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
523 template<
typename NodeType,
typename AccessorT>
524 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
530 return this->
template probeNode<LeafNodeType>(xyz);
537 return this->
template probeConstNode<LeafNodeType>(xyz);
543 template<
typename AccessorT>
546 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
551 template<
typename AccessorT>
554 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
557 template<
typename AccessorT>
560 return this->probeConstLeafAndCache(xyz, acc);
569 LeafNodeType* touchLeaf(
const Coord& xyz);
573 template<
typename AccessorT>
574 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
578 void resetBackground(
const ValueType& oldBackground,
const ValueType& newBackground);
582 template<
typename OtherChildNodeType, Index OtherLog2Dim>
586 template<
typename NodeT>
587 static bool hasNodeType();
613 void setValueMask(
Index n,
bool on) { mValueMask.set(n, mChildMask.isOn(n) ?
false : on); }
618 void makeChildNodeEmpty(
Index n,
const ValueType& value);
619 void setChildNode(
Index i, ChildNodeType* child);
620 ChildNodeType* unsetChildNode(
Index i,
const ValueType& value);
622 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
623 static inline void doVisit(NodeT&, VisitorOp&);
625 template<
typename NodeT,
typename OtherNodeT,
typename VisitorOp,
626 typename ChildAllIterT,
typename OtherChildAllIterT>
627 static inline void doVisit2Node(NodeT&, OtherNodeT&, VisitorOp&);
629 template<
typename NodeT,
typename VisitorOp,
630 typename ChildAllIterT,
typename OtherChildAllIterT>
631 static inline void doVisit2(NodeT&, OtherChildAllIterT&, VisitorOp&,
bool otherIsLHS);
633 ChildNodeType* getChildNode(
Index n);
634 const ChildNodeType* getChildNode(
Index n)
const;
647 template<
typename ChildT, Index Log2Dim>
651 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(background);
655 template<
typename ChildT, Index Log2Dim>
658 mOrigin(origin[0] & ~(DIM - 1),
659 origin[1] & ~(DIM - 1),
660 origin[2] & ~(DIM - 1))
667 template<
typename ChildT, Index Log2Dim>
670 mChildMask(other.mChildMask),
671 mValueMask(other.mValueMask),
672 mOrigin(other.mOrigin)
683 template<
typename ChildT, Index Log2Dim>
684 template<
typename OtherChildNodeType>
688 mChildMask(other.mChildMask),
689 mValueMask(other.mValueMask),
690 mOrigin(other.mOrigin)
702 template<
typename ChildT, Index Log2Dim>
703 template<
typename OtherChildNodeType>
707 mChildMask(other.mChildMask),
708 mValueMask(other.mValueMask),
709 mOrigin(other.mOrigin)
719 template<
typename ChildT, Index Log2Dim>
723 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
724 delete mNodes[iter.pos()].getChild();
732 template<
typename ChildT, Index Log2Dim>
736 if (ChildNodeType::getLevel() == 0)
return mChildMask.countOn();
738 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
739 sum += iter->leafCount();
745 template<
typename ChildT, Index Log2Dim>
750 if (ChildNodeType::getLevel() == 0)
return sum;
751 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
752 sum += iter->nonLeafCount();
758 template<
typename ChildT, Index Log2Dim>
763 for (
Index i = 0; i < NUM_VALUES; ++i) {
764 if (isChildMaskOff(i)) {
765 if (isValueMaskOn(i)) sum += ChildT::NUM_VOXELS;
767 sum += mNodes[i].getChild()->onVoxelCount();
774 template<
typename ChildT, Index Log2Dim>
779 for (
Index i = 0; i < NUM_VALUES; ++i) {
780 if (isChildMaskOff(i)) {
781 if (isValueMaskOff(i)) sum += ChildT::NUM_VOXELS;
783 sum += mNodes[i].getChild()->offVoxelCount();
790 template<
typename ChildT, Index Log2Dim>
795 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
796 sum += mNodes[iter.pos()].getChild()->onLeafVoxelCount();
802 template<
typename ChildT, Index Log2Dim>
807 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
808 sum += mNodes[iter.pos()].getChild()->offLeafVoxelCount();
814 template<
typename ChildT, Index Log2Dim>
819 + mValueMask.memUsage() +
sizeof(mOrigin);
820 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
821 sum += iter->memUsage();
827 template<
typename ChildT, Index Log2Dim>
831 if (bbox.
isInside(this->getNodeBoundingBox()))
return;
834 for (
ChildAllCIter iter = this->cbeginChildAll(); iter; ++iter) {
835 if (
const ChildT* child = iter.probeChild(dummy)) {
836 child->evalActiveVoxelBoundingBox(bbox);
837 }
else if (iter.isValueOn()) {
838 bbox.
expand(iter.getCoord(), ChildT::DIM);
847 template<
typename ChildT, Index Log2Dim>
848 template<
typename PruneOp>
852 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
853 const Index i = iter.pos();
854 ChildT* child = mNodes[i].getChild();
855 if (!op(*child))
continue;
857 mChildMask.setOff(i);
858 mValueMask.set(i, op.state);
859 mNodes[i].setValue(op.value);
865 template<
typename ChildT, Index Log2Dim>
874 template<
typename ChildT, Index Log2Dim>
883 template<
typename ChildT, Index Log2Dim>
887 this->pruneInactive(this->getBackground());
893 template<
typename ChildT, Index Log2Dim>
894 template<
typename NodeT>
898 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
899 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
901 const Index n = this->coord2offset(xyz);
902 if (mChildMask.isOff(n))
return NULL;
903 ChildT* child = mNodes[n].getChild();
904 if (boost::is_same<NodeT, ChildT>::value) {
905 mChildMask.setOff(n);
906 mValueMask.set(n, state);
907 mNodes[n].setValue(value);
909 return (boost::is_same<NodeT, ChildT>::value)
910 ?
reinterpret_cast<NodeT*
>(child)
911 : child->template stealNode<NodeT>(xyz, value, state);
917 template<
typename ChildT, Index Log2Dim>
918 template<
typename NodeT>
922 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
923 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
925 const Index n = this->coord2offset(xyz);
926 if (mChildMask.isOff(n))
return NULL;
927 ChildT* child = mNodes[n].getChild();
928 return (boost::is_same<NodeT, ChildT>::value)
929 ?
reinterpret_cast<NodeT*
>(child)
930 : child->template probeNode<NodeT>(xyz);
934 template<
typename ChildT, Index Log2Dim>
935 template<
typename NodeT,
typename AccessorT>
939 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
940 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
942 const Index n = this->coord2offset(xyz);
943 if (mChildMask.isOff(n))
return NULL;
944 ChildT* child = mNodes[n].getChild();
945 acc.insert(xyz, child);
946 return (boost::is_same<NodeT, ChildT>::value)
947 ?
reinterpret_cast<NodeT*
>(child)
948 : child->template probeNodeAndCache<NodeT>(xyz, acc);
952 template<
typename ChildT, Index Log2Dim>
953 template<
typename NodeT>
957 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
958 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
960 const Index n = this->coord2offset(xyz);
961 if (mChildMask.isOff(n))
return NULL;
962 const ChildT* child = mNodes[n].getChild();
963 return (boost::is_same<NodeT, ChildT>::value)
964 ?
reinterpret_cast<const NodeT*
>(child)
965 : child->template probeConstNode<NodeT>(xyz);
969 template<
typename ChildT, Index Log2Dim>
970 template<
typename NodeT,
typename AccessorT>
974 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
975 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
977 const Index n = this->coord2offset(xyz);
978 if (mChildMask.isOff(n))
return NULL;
979 const ChildT* child = mNodes[n].getChild();
980 acc.insert(xyz, child);
981 return (boost::is_same<NodeT, ChildT>::value)
982 ?
reinterpret_cast<const NodeT*
>(child)
983 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
990 template<
typename ChildT, Index Log2Dim>
991 template<
typename NodeT>
995 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
996 NodeT::LEVEL > ChildT::LEVEL)
return false;
998 return ChildT::template hasNodeType<NodeT>();
1004 template<
typename ChildT, Index Log2Dim>
1008 assert(leaf != NULL);
1009 const Coord& xyz = leaf->origin();
1010 const Index n = this->coord2offset(xyz);
1011 ChildT* child = NULL;
1012 if (mChildMask.isOff(n)) {
1013 if (ChildT::LEVEL>0) {
1014 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1016 child =
reinterpret_cast<ChildT*
>(leaf);
1018 mNodes[n].setChild(child);
1019 mChildMask.setOn(n);
1020 mValueMask.setOff(n);
1022 if (ChildT::LEVEL>0) {
1023 child = mNodes[n].getChild();
1025 delete mNodes[n].getChild();
1026 child =
reinterpret_cast<ChildT*
>(leaf);
1027 mNodes[n].setChild(child);
1030 child->addLeaf(leaf);
1034 template<
typename ChildT, Index Log2Dim>
1035 template<
typename AccessorT>
1039 assert(leaf != NULL);
1040 const Coord& xyz = leaf->origin();
1041 const Index n = this->coord2offset(xyz);
1042 ChildT* child = NULL;
1043 if (mChildMask.isOff(n)) {
1044 if (ChildT::LEVEL>0) {
1045 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1046 acc.insert(xyz, child);
1048 child =
reinterpret_cast<ChildT*
>(leaf);
1050 mNodes[n].setChild(child);
1051 mChildMask.setOn(n);
1052 mValueMask.setOff(n);
1054 if (ChildT::LEVEL>0) {
1055 child = mNodes[n].getChild();
1056 acc.insert(xyz, child);
1058 delete mNodes[n].getChild();
1059 child =
reinterpret_cast<ChildT*
>(leaf);
1060 mNodes[n].setChild(child);
1063 child->addLeafAndCache(leaf, acc);
1070 template<
typename ChildT, Index Log2Dim>
1076 if (LEVEL >= level) {
1077 const Index n = this->coord2offset(xyz);
1078 if (mChildMask.isOff(n)) {
1079 if (LEVEL > level) {
1080 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1081 mNodes[n].setChild(child);
1082 mChildMask.setOn(n);
1083 mValueMask.setOff(n);
1084 child->addTile(level, xyz, value, state);
1086 mValueMask.set(n, state);
1087 mNodes[n].setValue(value);
1090 ChildT* child = mNodes[n].getChild();
1091 if (LEVEL > level) {
1092 child->addTile(level, xyz, value, state);
1095 mChildMask.setOff(n);
1096 mValueMask.set(n, state);
1097 mNodes[n].setValue(value);
1104 template<
typename ChildT, Index Log2Dim>
1105 template<
typename AccessorT>
1108 const ValueType& value,
bool state, AccessorT& acc)
1111 if (LEVEL >= level) {
1112 const Index n = this->coord2offset(xyz);
1113 if (mChildMask.isOff(n)) {
1114 if (LEVEL > level) {
1115 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1116 mNodes[n].setChild(child);
1117 mChildMask.setOn(n);
1118 mValueMask.setOff(n);
1119 acc.insert(xyz, child);
1120 child->addTileAndCache(level, xyz, value, state, acc);
1122 mValueMask.set(n, state);
1123 mNodes[n].setValue(value);
1126 ChildT* child = mNodes[n].getChild();
1127 if (LEVEL > level) {
1128 acc.insert(xyz, child);
1129 child->addTileAndCache(level, xyz, value, state, acc);
1132 mChildMask.setOff(n);
1133 mValueMask.set(n, state);
1134 mNodes[n].setValue(value);
1144 template<
typename ChildT, Index Log2Dim>
1145 inline typename ChildT::LeafNodeType*
1148 const Index n = this->coord2offset(xyz);
1149 ChildT* child = NULL;
1150 if (mChildMask.isOff(n)) {
1151 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1152 mNodes[n].setChild(child);
1153 mChildMask.setOn(n);
1154 mValueMask.setOff(n);
1156 child = mNodes[n].getChild();
1158 return child->touchLeaf(xyz);
1162 template<
typename ChildT, Index Log2Dim>
1163 template<
typename AccessorT>
1164 inline typename ChildT::LeafNodeType*
1167 const Index n = this->coord2offset(xyz);
1168 if (mChildMask.isOff(n)) {
1169 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), mValueMask.isOn(n)));
1170 mChildMask.setOn(n);
1171 mValueMask.setOff(n);
1173 acc.insert(xyz, mNodes[n].getChild());
1174 return mNodes[n].getChild()->touchLeafAndCache(xyz, acc);
1181 template<
typename ChildT, Index Log2Dim>
1186 bool allEqual =
true, firstValue =
true, valueState =
true;
1188 for (
Index i = 0; allEqual && i < NUM_VALUES; ++i) {
1189 if (this->isChildMaskOff(i)) {
1194 valueState = isValueMaskOn(i);
1195 value = mNodes[i].getValue();
1197 allEqual = (isValueMaskOn(i) == valueState)
1203 ValueType childValue = zeroVal<ValueType>();
1204 bool isChildOn =
false;
1205 if (mNodes[i].getChild()->isConstant(childValue, isChildOn, tolerance)) {
1208 valueState = isChildOn;
1211 allEqual = (isChildOn == valueState)
1230 template<
typename ChildT, Index Log2Dim>
1234 const bool anyActiveTiles = !mValueMask.isOff();
1235 if (LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1236 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1237 if (iter->hasActiveTiles())
return true;
1243 template<
typename ChildT, Index Log2Dim>
1247 const Index n = this->coord2offset(xyz);
1248 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1249 return mNodes[n].getChild()->isValueOn(xyz);
1252 template<
typename ChildT, Index Log2Dim>
1253 template<
typename AccessorT>
1257 const Index n = this->coord2offset(xyz);
1258 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1259 acc.insert(xyz, mNodes[n].getChild());
1260 return mNodes[n].getChild()->isValueOnAndCache(xyz, acc);
1264 template<
typename ChildT, Index Log2Dim>
1265 inline const typename ChildT::ValueType&
1268 const Index n = this->coord2offset(xyz);
1269 return this->isChildMaskOff(n) ? mNodes[n].getValue()
1270 : mNodes[n].getChild()->getValue(xyz);
1273 template<
typename ChildT, Index Log2Dim>
1274 template<
typename AccessorT>
1275 inline const typename ChildT::ValueType&
1278 const Index n = this->coord2offset(xyz);
1279 if (this->isChildMaskOn(n)) {
1280 acc.insert(xyz, mNodes[n].getChild());
1281 return mNodes[n].getChild()->getValueAndCache(xyz, acc);
1283 return mNodes[n].getValue();
1287 template<
typename ChildT, Index Log2Dim>
1291 const Index n = this->coord2offset(xyz);
1292 return this->isChildMaskOff(n) ? LEVEL : mNodes[n].getChild()->getValueLevel(xyz);
1295 template<
typename ChildT, Index Log2Dim>
1296 template<
typename AccessorT>
1300 const Index n = this->coord2offset(xyz);
1301 if (this->isChildMaskOn(n)) {
1302 acc.insert(xyz, mNodes[n].getChild());
1303 return mNodes[n].getChild()->getValueLevelAndCache(xyz, acc);
1309 template<
typename ChildT, Index Log2Dim>
1313 const Index n = this->coord2offset(xyz);
1314 if (this->isChildMaskOff(n)) {
1315 value = mNodes[n].getValue();
1316 return this->isValueMaskOn(n);
1318 return mNodes[n].getChild()->probeValue(xyz, value);
1321 template<
typename ChildT, Index Log2Dim>
1322 template<
typename AccessorT>
1327 const Index n = this->coord2offset(xyz);
1328 if (this->isChildMaskOn(n)) {
1329 acc.insert(xyz, mNodes[n].getChild());
1330 return mNodes[n].getChild()->probeValueAndCache(xyz, value, acc);
1332 value = mNodes[n].getValue();
1333 return this->isValueMaskOn(n);
1337 template<
typename ChildT, Index Log2Dim>
1341 const Index n = this->coord2offset(xyz);
1342 bool hasChild = this->isChildMaskOn(n);
1343 if (!hasChild && this->isValueMaskOn(n)) {
1346 mChildMask.setOn(n);
1347 mValueMask.setOff(n);
1349 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(),
true));
1351 if (hasChild) mNodes[n].getChild()->setValueOff(xyz);
1355 template<
typename ChildT, Index Log2Dim>
1359 const Index n = this->coord2offset(xyz);
1360 bool hasChild = this->isChildMaskOn(n);
1361 if (!hasChild && !this->isValueMaskOn(n)) {
1364 mChildMask.setOn(n);
1365 mValueMask.setOff(n);
1367 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(),
false));
1369 if (hasChild) mNodes[n].getChild()->setValueOn(xyz);
1373 template<
typename ChildT, Index Log2Dim>
1378 bool hasChild = this->isChildMaskOn(n);
1380 const bool active = this->isValueMaskOn(n);
1385 mChildMask.setOn(n);
1386 mValueMask.setOff(n);
1388 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1391 if (hasChild) mNodes[n].getChild()->setValueOff(xyz, value);
1394 template<
typename ChildT, Index Log2Dim>
1395 template<
typename AccessorT>
1401 bool hasChild = this->isChildMaskOn(n);
1403 const bool active = this->isValueMaskOn(n);
1408 mChildMask.setOn(n);
1409 mValueMask.setOff(n);
1411 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1415 ChildT* child = mNodes[n].getChild();
1416 acc.insert(xyz, child);
1417 child->setValueOffAndCache(xyz, value, acc);
1422 template<
typename ChildT, Index Log2Dim>
1426 const Index n = this->coord2offset(xyz);
1427 bool hasChild = this->isChildMaskOn(n);
1429 const bool active = this->isValueMaskOn(n);
1434 mChildMask.setOn(n);
1435 mValueMask.setOff(n);
1437 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1440 if (hasChild) mNodes[n].getChild()->setValueOn(xyz, value);
1443 template<
typename ChildT, Index Log2Dim>
1444 template<
typename AccessorT>
1449 const Index n = this->coord2offset(xyz);
1450 bool hasChild = this->isChildMaskOn(n);
1452 const bool active = this->isValueMaskOn(n);
1457 mChildMask.setOn(n);
1458 mValueMask.setOff(n);
1460 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1464 acc.insert(xyz, mNodes[n].getChild());
1465 mNodes[n].getChild()->setValueAndCache(xyz, value, acc);
1470 template<
typename ChildT, Index Log2Dim>
1474 const Index n = this->coord2offset(xyz);
1475 bool hasChild = this->isChildMaskOn(n);
1479 const bool active = this->isValueMaskOn(n);
1480 mChildMask.setOn(n);
1481 mValueMask.setOff(n);
1483 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1485 if (hasChild) mNodes[n].getChild()->setValueOnly(xyz, value);
1488 template<
typename ChildT, Index Log2Dim>
1489 template<
typename AccessorT>
1494 const Index n = this->coord2offset(xyz);
1495 bool hasChild = this->isChildMaskOn(n);
1499 const bool active = this->isValueMaskOn(n);
1500 mChildMask.setOn(n);
1501 mValueMask.setOff(n);
1503 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1506 acc.insert(xyz, mNodes[n].getChild());
1507 mNodes[n].getChild()->setValueOnlyAndCache(xyz, value, acc);
1512 template<
typename ChildT, Index Log2Dim>
1516 const Index n = this->coord2offset(xyz);
1517 bool hasChild = this->isChildMaskOn(n);
1519 if (on != this->isValueMaskOn(n)) {
1522 mChildMask.setOn(n);
1523 mValueMask.setOff(n);
1524 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1529 if (hasChild) mNodes[n].getChild()->setActiveState(xyz, on);
1532 template<
typename ChildT, Index Log2Dim>
1533 template<
typename AccessorT>
1537 const Index n = this->coord2offset(xyz);
1538 bool hasChild = this->isChildMaskOn(n);
1540 if (on != this->isValueMaskOn(n)) {
1543 mChildMask.setOn(n);
1544 mValueMask.setOff(n);
1545 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1551 ChildT* child = mNodes[n].getChild();
1552 acc.insert(xyz, child);
1553 child->setActiveStateAndCache(xyz, on, acc);
1558 template<
typename ChildT, Index Log2Dim>
1562 mValueMask = !mChildMask;
1563 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1564 mNodes[iter.pos()].getChild()->setValuesOn();
1569 template<
typename ChildT, Index Log2Dim>
1574 bool hasChild = this->isChildMaskOn(n);
1576 const bool active = this->isValueMaskOn(n);
1577 if (!active || (mNodes[n].getValue() > value)) {
1581 mChildMask.setOn(n);
1582 mValueMask.setOff(n);
1584 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1587 if (hasChild) mNodes[n].getChild()->setValueOnMin(xyz, value);
1591 template<
typename ChildT, Index Log2Dim>
1596 bool hasChild = this->isChildMaskOn(n);
1598 const bool active = this->isValueMaskOn(n);
1599 if (!active || (value > mNodes[n].getValue())) {
1603 mChildMask.setOn(n);
1604 mValueMask.setOff(n);
1606 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1609 if (hasChild) mNodes[n].getChild()->setValueOnMax(xyz, value);
1613 template<
typename ChildT, Index Log2Dim>
1618 bool hasChild = this->isChildMaskOn(n);
1620 const bool active = this->isValueMaskOn(n);
1624 mChildMask.setOn(n);
1625 mValueMask.setOff(n);
1627 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1630 if (hasChild) mNodes[n].getChild()->setValueOnSum(xyz, addend);
1633 template<
typename ChildT, Index Log2Dim>
1634 template<
typename AccessorT>
1637 const ValueType& addend, AccessorT& acc)
1639 const Index n = this->coord2offset(xyz);
1640 bool hasChild = this->isChildMaskOn(n);
1642 const bool active = this->isValueMaskOn(n);
1646 mChildMask.setOn(n);
1647 mValueMask.setOff(n);
1649 mNodes[n].setChild(
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1653 acc.insert(xyz, mNodes[n].getChild());
1654 mNodes[n].getChild()->setValueOnSumAndCache(xyz, addend, acc);
1662 template<
typename ChildT, Index Log2Dim>
1666 Coord xyz, tileMin, tileMax;
1667 for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
1669 for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
1671 for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
1675 const Index n = this->coord2offset(xyz);
1676 tileMin = this->offset2globalCoord(n);
1677 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
1683 ChildT* child = NULL;
1684 if (this->isChildMaskOff(n)) {
1687 child =
new ChildT(xyz, mNodes[n].getValue(), this->isValueMaskOn(n));
1688 mChildMask.setOn(n);
1689 mValueMask.setOff(n);
1690 mNodes[n].setChild(child);
1692 child = mNodes[n].getChild();
1705 this->makeChildNodeEmpty(n, value);
1706 mValueMask.set(n, active);
1717 template<
typename ChildT, Index Log2Dim>
1718 template<
typename DenseT>
1722 const size_t xStride = dense.xStride(), yStride = dense.yStride();
1723 const Coord&
min = dense.bbox().min();
1724 for (
Coord xyz = bbox.
min(),
max; xyz[0] <= bbox.
max()[0]; xyz[0] =
max[0] + 1) {
1725 for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] =
max[1] + 1) {
1726 for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] =
max[2] + 1) {
1727 const Index n = this->coord2offset(xyz);
1729 max = this->offset2globalCoord(n).offsetBy(ChildT::DIM-1);
1734 if (this->isChildMaskOn(n)) {
1735 mNodes[n].getChild()->copyToDense(sub, dense);
1737 const ValueType value = mNodes[n].getValue();
1740 for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
1742 for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
1744 for (
Int32 z=sub.
min()[2], ez=sub.
max()[2]+1; z<ez; ++z) *a2++ = value;
1757 template<
typename ChildT, Index Log2Dim>
1761 mChildMask.save(os);
1762 mValueMask.save(os);
1766 boost::shared_array<ValueType> values(
new ValueType[NUM_VALUES]);
1767 const ValueType zero = zeroVal<ValueType>();
1768 for (
Index i = 0; i < NUM_VALUES; ++i) {
1769 values[i] = (mChildMask.isOff(i) ? mNodes[i].getValue() : zero);
1775 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1776 iter->writeTopology(os, toHalf);
1781 template<
typename ChildT, Index Log2Dim>
1785 mChildMask.load(is);
1786 mValueMask.load(is);
1789 for (
Index i = 0; i < NUM_VALUES; ++i) {
1790 if (this->isChildMaskOn(i)) {
1792 new ChildNodeType(offset2globalCoord(i), zeroVal<ValueType>());
1793 mNodes[i].setChild(child);
1794 child->readTopology(is);
1797 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
1798 mNodes[i].setValue(value);
1802 const bool oldVersion =
1804 const Index numValues = (oldVersion ? mChildMask.countOff() : NUM_VALUES);
1808 boost::shared_array<ValueType> values(
new ValueType[numValues]);
1814 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
1815 mNodes[iter.pos()].setValue(values[n++]);
1817 assert(n == numValues);
1819 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
1820 mNodes[iter.pos()].setValue(values[iter.pos()]);
1825 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1827 mNodes[iter.pos()].setChild(child);
1828 child->readTopology(is, fromHalf);
1837 template<
typename ChildT, Index Log2Dim>
1838 inline const typename ChildT::ValueType&
1841 return (this->isChildMaskOn(0) ? mNodes[0].getChild()->getFirstValue() : mNodes[0].getValue());
1845 template<
typename ChildT, Index Log2Dim>
1846 inline const typename ChildT::ValueType&
1849 const Index n = NUM_VALUES - 1;
1850 return (this->isChildMaskOn(n) ? mNodes[n].getChild()->getLastValue() : mNodes[n].getValue());
1857 template<
typename ChildT, Index Log2Dim>
1861 this->signedFloodFill(background,
negative(background));
1865 template<
typename ChildT, Index Log2Dim>
1871 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1872 iter->signedFloodFill(outsideValue, insideValue);
1874 const Index first = mChildMask.findFirstOn();
1875 if (first < NUM_VALUES) {
1876 bool xInside =
math::isNegative(mNodes[first].getChild()->getFirstValue()),
1877 yInside = xInside, zInside = xInside;
1878 for (
Index x = 0; x != (1 << Log2Dim); ++x) {
1879 const int x00 = x << (2 * Log2Dim);
1880 if (isChildMaskOn(x00)) {
1884 for (
Index y = 0; y != (1 << Log2Dim); ++y) {
1885 const Index xy0 = x00 + (y << Log2Dim);
1886 if (isChildMaskOn(xy0)) {
1890 for (
Index z = 0; z != (1 << Log2Dim); ++z) {
1891 const Index xyz = xy0 + z;
1892 if (isChildMaskOn(xyz)) {
1895 mNodes[xyz].setValue(zInside ? insideValue : outsideValue);
1902 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(v);
1907 template<
typename ChildT, Index Log2Dim>
1911 for (
Index i = 0; i < NUM_VALUES; ++i) {
1912 if (this->isChildMaskOn(i)) {
1913 mNodes[i].getChild()->negate();
1915 mNodes[i].setValue(
negative(mNodes[i].getValue()));
1922 template<
typename ChildT, Index Log2Dim>
1926 for (
ValueOnIter iter = this->beginValueOn(); iter; ++iter) {
1927 const Index n = iter.pos();
1929 mValueMask.setOff(n);
1930 mChildMask.setOn(n);
1931 mNodes[n].setChild(child);
1933 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) iter->voxelizeActiveTiles();
1937 template<
typename ChildT, Index Log2Dim>
1943 const Index n = iter.pos();
1944 if (mChildMask.isOff(n)) {
1949 child->resetBackground(otherBackground, background);
1950 mChildMask.setOn(n);
1951 mValueMask.setOff(n);
1952 mNodes[n].setChild(child);
1954 mNodes[n].getChild()->merge(*iter, background, otherBackground);
1960 const Index n = iter.pos();
1961 if (mChildMask.isOff(n) && mValueMask.isOff(n)) {
1962 mNodes[n].setValue(iter.getValue());
1963 mValueMask.setOn(n);
1969 template<
typename ChildT, Index Log2Dim>
1970 template<
typename OtherChildT>
1977 for (OtherChildIter iter = other.
cbeginChildOn(); iter; ++iter) {
1979 if (mChildMask.isOn(i)) {
1980 mNodes[i].getChild()->topologyUnion(*iter);
1983 if (mValueMask.isOn(i)) {
1984 mValueMask.isOff(i);
1985 child->setValuesOn();
1987 mChildMask.setOn(i);
1988 mNodes[i].setChild(child);
1991 for (OtherValueIter iter = other.
cbeginValueOn(); iter; ++iter) {
1992 const Index i = iter.pos();
1993 if (mChildMask.isOn(i)) {
1994 mNodes[i].getChild()->setValuesOn();
1995 }
else if (mValueMask.isOff(i)) {
1996 mValueMask.setOn(i);
2005 template<
typename ChildT, Index Log2Dim>
2006 template<
typename CombineOp>
2010 const ValueType zero = zeroVal<ValueType>();
2014 for (
Index i = 0; i < NUM_VALUES; ++i) {
2018 op(args.setARef(mNodes[i].getValue())
2019 .setAIsActive(isValueMaskOn(i))
2020 .setBRef(other.
mNodes[i].getValue())
2022 mNodes[i].setValue(args.result());
2023 mValueMask.set(i, args.resultIsActive());
2031 }
else if (this->isChildMaskOff(i) && other.
isChildMaskOn(i)) {
2040 child->combine(mNodes[i].getValue(), isValueMaskOn(i), swappedOp);
2044 other.
mNodes[i].setValue(zero);
2045 mChildMask.setOn(i);
2046 mValueMask.setOff(i);
2047 mNodes[i].setChild(child);
2053 *child = mNodes[i].getChild(),
2054 *otherChild = other.
mNodes[i].getChild();
2057 if (child && otherChild) {
2058 child->combine(*otherChild, op);
2065 template<
typename ChildT, Index Log2Dim>
2066 template<
typename CombineOp>
2072 for (
Index i = 0; i < NUM_VALUES; ++i) {
2073 if (this->isChildMaskOff(i)) {
2075 op(args.
setARef(mNodes[i].getValue())
2076 .setAIsActive(isValueMaskOn(i))
2078 .setBIsActive(valueIsActive));
2079 mNodes[i].setValue(args.
result());
2085 if (child) child->combine(value, valueIsActive, op);
2094 template<
typename ChildT, Index Log2Dim>
2095 template<
typename CombineOp>
2102 for (
Index i = 0; i < NUM_VALUES; ++i) {
2106 .setBRef(other1.
mNodes[i].getValue())
2109 this->makeChildNodeEmpty(i, args.
result());
2113 ? other0.
mNodes[i].getChild() : other1.
mNodes[i].getChild();
2115 if (this->isChildMaskOff(i)) {
2118 mChildMask.setOn(i);
2119 mValueMask.setOff(i);
2120 mNodes[i].setChild(
new ChildNodeType(otherChild->getOrigin(),
2121 mNodes[i].getValue()));
2127 mNodes[i].getChild()->combine2(other0.
mNodes[i].getValue(),
2132 mNodes[i].getChild()->combine2(*other0.
mNodes[i].getChild(),
2137 mNodes[i].getChild()->combine2(*other0.
mNodes[i].getChild(),
2138 *other1.
mNodes[i].getChild(), op);
2145 template<
typename ChildT, Index Log2Dim>
2146 template<
typename CombineOp>
2149 bool valueIsActive, CombineOp& op)
2153 for (
Index i = 0; i < NUM_VALUES; ++i) {
2156 .setAIsActive(valueIsActive)
2157 .setBRef(other.
mNodes[i].getValue())
2160 this->makeChildNodeEmpty(i, args.
result());
2165 if (this->isChildMaskOff(i)) {
2169 mChildMask.setOn(i);
2170 mValueMask.setOff(i);
2175 mNodes[i].getChild()->combine2(value, *otherChild, valueIsActive, op);
2181 template<
typename ChildT, Index Log2Dim>
2182 template<
typename CombineOp>
2185 bool valueIsActive, CombineOp& op)
2189 for (
Index i = 0; i < NUM_VALUES; ++i) {
2194 .setBIsActive(valueIsActive));
2196 this->makeChildNodeEmpty(i, args.
result());
2201 if (this->isChildMaskOff(i)) {
2204 mChildMask.setOn(i);
2205 mValueMask.setOff(i);
2206 mNodes[i].setChild(
new ChildNodeType(otherChild->getOrigin(),
2207 mNodes[i].getValue()));
2211 mNodes[i].getChild()->combine2(*otherChild, value, valueIsActive, op);
2220 template<
typename ChildT, Index Log2Dim>
2221 template<
typename BBoxOp>
2232 if (op.template descent<LEVEL>()) {
2233 for (
ChildOnCIter i = this->cbeginChildOn(); i; ++i) i->visitActiveBBox(op);
2237 op.operator()<LEVEL>(i->getNodeBoundingBox());
2239 op.template operator()<LEVEL>(i->getNodeBoundingBox());
2246 template<
typename ChildT, Index Log2Dim>
2247 template<
typename VisitorOp>
2251 doVisit<InternalNode, VisitorOp, ChildAllIter>(*
this, op);
2255 template<
typename ChildT, Index Log2Dim>
2256 template<
typename VisitorOp>
2260 doVisit<const InternalNode, VisitorOp, ChildAllCIter>(*
this, op);
2264 template<
typename ChildT, Index Log2Dim>
2265 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
2269 typename NodeT::ValueType val;
2270 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2271 if (op(iter))
continue;
2272 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2282 template<
typename ChildT, Index Log2Dim>
2283 template<
typename OtherNodeType,
typename VisitorOp>
2288 typename OtherNodeType::ChildAllIter>(*
this, other, op);
2292 template<
typename ChildT, Index Log2Dim>
2293 template<
typename OtherNodeType,
typename VisitorOp>
2298 typename OtherNodeType::ChildAllCIter>(*
this, other, op);
2302 template<
typename ChildT, Index Log2Dim>
2305 typename OtherNodeT,
2307 typename ChildAllIterT,
2308 typename OtherChildAllIterT>
2313 BOOST_STATIC_ASSERT(OtherNodeT::NUM_VALUES == NodeT::NUM_VALUES);
2314 BOOST_STATIC_ASSERT(OtherNodeT::LEVEL == NodeT::LEVEL);
2316 typename NodeT::ValueType val;
2317 typename OtherNodeT::ValueType otherVal;
2319 ChildAllIterT iter =
self.beginChildAll();
2320 OtherChildAllIterT otherIter = other.beginChildAll();
2322 for ( ; iter && otherIter; ++iter, ++otherIter)
2324 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2326 typename ChildAllIterT::ChildNodeType* child =
2327 (skipBranch & 1U) ? NULL : iter.probeChild(val);
2328 typename OtherChildAllIterT::ChildNodeType* otherChild =
2329 (skipBranch & 2U) ? NULL : otherIter.probeChild(otherVal);
2331 if (child != NULL && otherChild != NULL) {
2332 child->visit2Node(*otherChild, op);
2333 }
else if (child != NULL) {
2334 child->visit2(otherIter, op);
2335 }
else if (otherChild != NULL) {
2336 otherChild->visit2(iter, op,
true);
2345 template<
typename ChildT, Index Log2Dim>
2346 template<
typename OtherChildAllIterType,
typename VisitorOp>
2349 VisitorOp& op,
bool otherIsLHS)
2351 doVisit2<InternalNode, VisitorOp, ChildAllIter, OtherChildAllIterType>(
2352 *
this, otherIter, op, otherIsLHS);
2356 template<
typename ChildT, Index Log2Dim>
2357 template<
typename OtherChildAllIterType,
typename VisitorOp>
2360 VisitorOp& op,
bool otherIsLHS)
const
2362 doVisit2<const InternalNode, VisitorOp, ChildAllCIter, OtherChildAllIterType>(
2363 *
this, otherIter, op, otherIsLHS);
2367 template<
typename ChildT, Index Log2Dim>
2368 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT,
typename OtherChildAllIterT>
2371 VisitorOp& op,
bool otherIsLHS)
2373 if (!otherIter)
return;
2375 const size_t skipBitMask = (otherIsLHS ? 2U : 1U);
2377 typename NodeT::ValueType val;
2378 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2379 const size_t skipBranch =
static_cast<size_t>(
2380 otherIsLHS ? op(otherIter, iter) : op(iter, otherIter));
2382 typename ChildAllIterT::ChildNodeType* child =
2383 (skipBranch & skipBitMask) ? NULL : iter.probeChild(val);
2385 if (child != NULL) child->visit2(otherIter, op, otherIsLHS);
2393 template<
typename ChildT, Index Log2Dim>
2397 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2398 iter->writeBuffers(os, toHalf);
2403 template<
typename ChildT, Index Log2Dim>
2407 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2408 iter->readBuffers(is, fromHalf);
2416 template<
typename ChildT, Index Log2Dim>
2420 dims.push_back(Log2Dim);
2421 ChildNodeType::getNodeLog2Dims(dims);
2425 template<
typename ChildT, Index Log2Dim>
2429 assert(n<(1<<3*Log2Dim));
2430 xyz.
setX(n >> 2*Log2Dim);
2431 n &= ((1<<2*Log2Dim)-1);
2432 xyz.
setY(n >> Log2Dim);
2433 xyz.
setZ(n & ((1<<Log2Dim)-1));
2437 template<
typename ChildT, Index Log2Dim>
2441 return (((xyz[0]&DIM-1u)>>ChildNodeType::TOTAL)<<2*Log2Dim)
2442 + (((xyz[1]&DIM-1u)>>ChildNodeType::TOTAL)<< Log2Dim)
2443 + ((xyz[2]&DIM-1u)>>ChildNodeType::TOTAL);
2447 template<
typename ChildT, Index Log2Dim>
2452 this->offset2coord(n, local);
2453 local <<= ChildT::TOTAL;
2454 return local + this->getOrigin();
2461 template<
typename ChildT, Index Log2Dim>
2467 for (
Index i = 0; i < NUM_VALUES; ++i) {
2468 if (this->isChildMaskOn(i)) {
2469 mNodes[i].getChild()->resetBackground(oldBackground, newBackground);
2470 }
else if (this->isValueMaskOff(i)) {
2472 mNodes[i].setValue(newBackground);
2474 mNodes[i].setValue(
negative(newBackground));
2481 template<
typename ChildT, Index Log2Dim>
2482 template<
typename OtherChildNodeType, Index OtherLog2Dim>
2487 if (Log2Dim != OtherLog2Dim || mChildMask != other->
mChildMask ||
2488 mValueMask != other->
mValueMask)
return false;
2489 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2490 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
2496 template<
typename ChildT, Index Log2Dim>
2501 if (this->isChildMaskOn(i)) {
2502 delete mNodes[i].getChild();
2504 mChildMask.setOn(i);
2505 mValueMask.setOff(i);
2507 mNodes[i].setChild(child);
2511 template<
typename ChildT, Index Log2Dim>
2515 if (this->isChildMaskOff(i)) {
2516 mNodes[i].setValue(value);
2520 mChildMask.setOff(i);
2521 mNodes[i].setValue(value);
2526 template<
typename ChildT, Index Log2Dim>
2530 delete this->unsetChildNode(n, value);
2533 template<
typename ChildT, Index Log2Dim>
2537 return (this->isChildMaskOn(n) ? mNodes[n].getChild() : NULL);
2541 template<
typename ChildT, Index Log2Dim>
2542 inline const ChildT*
2545 return (this->isChildMaskOn(n) ? mNodes[n].getChild() : NULL);
2552 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED