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>
59 template<
typename _ChildNodeType, Index Log2Dim>
65 typedef typename ChildNodeType::ValueType
ValueType;
71 TOTAL = Log2Dim + ChildNodeType::TOTAL,
73 NUM_VALUES = 1 << (3 * Log2Dim),
74 LEVEL = 1 + ChildNodeType::LEVEL;
76 NUM_VOXELS = uint64_t(1) << (3 * TOTAL);
80 template<
typename OtherValueType>
89 template<
typename OtherNodeType>
91 static const bool value =
100 InternalNode(
const Coord&,
const ValueType& value,
bool active =
false);
106 template<
typename OtherChildNodeType>
110 template<
typename OtherChildNodeType>
115 template<
typename OtherChildNodeType>
117 const ValueType& offValue,
const ValueType& onValue,
TopologyCopy);
133 template<
typename NodeT,
typename ChildT,
typename MaskIterT,
typename TagT>
135 MaskIterT, ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>
139 MaskIterT,
ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>(iter, parent) {}
143 assert(this->parent().isChildMaskOn(pos));
144 return *(this->parent().getChildNode(pos));
148 void setItem(
Index pos,
const ChildT& c)
const { this->parent().resetChildNode(pos, &c); }
153 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
155 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
159 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
161 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
164 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
167 template<
typename ModifyOp>
170 op(this->parent().mNodes[pos].getValue());
174 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
176 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
187 if (this->parent().isChildMaskOn(pos)) {
188 child = this->parent().getChildNode(pos);
192 value = this->parent().mNodes[pos].getValue();
199 this->parent().resetChildNode(pos, child);
205 this->parent().unsetChildNode(pos, value);
248 static void getNodeLog2Dims(std::vector<Index>& dims);
252 static Index coordToOffset(
const Coord& xyz);
255 static void offsetToLocalCoord(
Index n, Coord& xyz);
257 Coord offsetToGlobalCoord(
Index n)
const;
260 const Coord&
origin()
const {
return mOrigin; }
262 void setOrigin(
const Coord& origin) { mOrigin = origin; }
268 Index64 onLeafVoxelCount()
const;
269 Index64 offLeafVoxelCount()
const;
279 void evalActiveBoundingBox(CoordBBox& bbox,
bool visitVoxels =
true)
const;
285 bool isEmpty()
const {
return mChildMask.isOff(); }
290 bool isConstant(ValueType& constValue,
bool& state,
291 const ValueType& tolerance = zeroVal<ValueType>())
const;
293 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
296 bool isValueOn(
const Coord& xyz)
const;
301 bool hasActiveTiles()
const;
303 const ValueType& getValue(
const Coord& xyz)
const;
304 bool probeValue(
const Coord& xyz, ValueType& value)
const;
308 Index getValueLevel(
const Coord& xyz)
const;
312 const ValueType& getFirstValue()
const;
315 const ValueType& getLastValue()
const;
318 void setActiveState(
const Coord& xyz,
bool on);
320 void setValueOnly(
const Coord& xyz,
const ValueType& value);
322 void setValueOn(
const Coord& xyz);
324 void setValueOn(
const Coord& xyz,
const ValueType& value);
326 void setValueOff(
const Coord& xyz);
328 void setValueOff(
const Coord& xyz,
const ValueType& value);
332 template<
typename ModifyOp>
333 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
335 template<
typename ModifyOp>
336 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
342 template<
typename AccessorT>
343 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
349 template<
typename AccessorT>
350 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
356 template<
typename AccessorT>
357 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
363 template<
typename AccessorT>
364 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
371 template<
typename ModifyOp,
typename AccessorT>
372 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
378 template<
typename ModifyOp,
typename AccessorT>
379 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
385 template<
typename AccessorT>
386 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
392 template<
typename AccessorT>
393 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
400 template<
typename AccessorT>
401 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
409 template<
typename AccessorT>
410 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
419 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
420 void readTopology(std::istream&,
bool fromHalf =
false);
421 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
422 void readBuffers(std::istream&,
bool fromHalf =
false);
430 void fill(
const CoordBBox& bbox,
const ValueType&,
bool active =
true);
437 void signedFloodFill(
const ValueType& background);
444 void signedFloodFill(
const ValueType& outside,
const ValueType& inside);
451 void voxelizeActiveTiles();
460 template<
typename DenseT>
461 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
465 template<MergePolicy Policy>
466 void merge(
InternalNode& other,
const ValueType& background,
const ValueType& otherBackground);
470 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
484 template<
typename OtherChildNodeType>
500 template<
typename OtherChildNodeType>
502 const ValueType& background);
515 template<
typename OtherChildNodeType>
517 const ValueType& background);
519 template<
typename CombineOp>
521 template<
typename CombineOp>
522 void combine(
const ValueType& value,
bool valueIsActive, CombineOp&);
524 template<
typename CombineOp,
typename OtherNodeType >
525 void combine2(
const InternalNode& other0,
const OtherNodeType& other1, CombineOp&);
526 template<
typename CombineOp,
typename OtherNodeType >
527 void combine2(
const ValueType& value,
const OtherNodeType& other,
bool valIsActive, CombineOp&);
528 template<
typename CombineOp,
typename OtherValueType>
529 void combine2(
const InternalNode& other,
const OtherValueType&,
bool valIsActive, CombineOp&);
536 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
538 template<
typename VisitorOp>
void visit(VisitorOp&);
539 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
541 template<
typename OtherNodeType,
typename VisitorOp>
542 void visit2Node(OtherNodeType& other, VisitorOp&);
543 template<
typename OtherNodeType,
typename VisitorOp>
544 void visit2Node(OtherNodeType& other, VisitorOp&)
const;
545 template<
typename IterT,
typename VisitorOp>
546 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false);
547 template<
typename IterT,
typename VisitorOp>
548 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false)
const;
556 template<
typename PruneOp>
void pruneOp(PruneOp&);
561 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
565 void pruneInactive(
const ValueType&);
569 void pruneInactive();
573 void addLeaf(LeafNodeType* leaf);
577 template<
typename AccessorT>
578 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
588 template<
typename NodeT>
589 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
593 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
596 void addTile(
Index offset,
const ValueType& value,
bool state);
600 template<
typename AccessorT>
601 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
604 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
607 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
611 template<
typename NodeType,
typename AccessorT>
614 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
615 template<
typename NodeType,
typename AccessorT>
616 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
620 LeafNodeType* probeLeaf(
const Coord& xyz);
623 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
624 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
628 template<
typename AccessorT>
631 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
632 template<
typename AccessorT>
633 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
634 template<
typename AccessorT>
635 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
644 LeafNodeType* touchLeaf(
const Coord& xyz);
648 template<
typename AccessorT>
649 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
653 void resetBackground(
const ValueType& oldBackground,
const ValueType& newBackground);
657 template<
typename OtherChildNodeType, Index OtherLog2Dim>
684 void setValueMask(
Index n,
bool on) { mValueMask.set(n, mChildMask.isOn(n) ?
false : on); }
689 void makeChildNodeEmpty(
Index n,
const ValueType& value);
690 void setChildNode(
Index i, ChildNodeType* child);
691 void resetChildNode(
Index i, ChildNodeType* child);
692 ChildNodeType* unsetChildNode(
Index i,
const ValueType& value);
694 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
695 static inline void doVisit(NodeT&, VisitorOp&);
697 template<
typename NodeT,
typename OtherNodeT,
typename VisitorOp,
698 typename ChildAllIterT,
typename OtherChildAllIterT>
699 static inline void doVisit2Node(NodeT&, OtherNodeT&, VisitorOp&);
701 template<
typename NodeT,
typename VisitorOp,
702 typename ChildAllIterT,
typename OtherChildAllIterT>
703 static inline void doVisit2(NodeT&, OtherChildAllIterT&, VisitorOp&,
bool otherIsLHS);
709 ChildNodeType* getChildNode(
Index n);
710 const ChildNodeType* getChildNode(
Index n)
const;
725 template<
typename ChildT1, Index Dim1,
typename NodeT2>
729 static const bool value =
false;
732 template<
typename ChildT1, Index Dim1,
typename ChildT2>
734 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
742 template<
typename ChildT, Index Log2Dim>
746 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(background);
750 template<
typename ChildT, Index Log2Dim>
753 mOrigin(origin[0] & ~(DIM - 1),
754 origin[1] & ~(DIM - 1),
755 origin[2] & ~(DIM - 1))
762 template<
typename ChildT, Index Log2Dim>
765 mChildMask(other.mChildMask),
766 mValueMask(other.mValueMask),
767 mOrigin(other.mOrigin)
780 template<
typename ChildT, Index Log2Dim>
781 template<
typename OtherChildNodeType>
784 : mChildMask(other.mChildMask)
785 , mValueMask(other.mValueMask)
786 , mOrigin(other.mOrigin)
791 convertValue(
const typename OtherChildNodeType::ValueType& val) {
return ValueType(val); }
796 mNodes[i].setValue(Local::convertValue(other.
mNodes[i].getValue()));
804 template<
typename ChildT, Index Log2Dim>
805 template<
typename OtherChildNodeType>
809 mChildMask(other.mChildMask),
810 mValueMask(other.mValueMask),
811 mOrigin(other.mOrigin)
823 template<
typename ChildT, Index Log2Dim>
824 template<
typename OtherChildNodeType>
828 mChildMask(other.mChildMask),
829 mValueMask(other.mValueMask),
830 mOrigin(other.mOrigin)
840 template<
typename ChildT, Index Log2Dim>
844 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
845 delete mNodes[iter.pos()].getChild();
853 template<
typename ChildT, Index Log2Dim>
857 if (ChildNodeType::getLevel() == 0)
return mChildMask.countOn();
859 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
860 sum += iter->leafCount();
866 template<
typename ChildT, Index Log2Dim>
871 if (ChildNodeType::getLevel() == 0)
return sum;
872 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
873 sum += iter->nonLeafCount();
879 template<
typename ChildT, Index Log2Dim>
883 Index64 sum = ChildT::NUM_VOXELS * mValueMask.countOn();
884 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
885 sum += iter->onVoxelCount();
891 template<
typename ChildT, Index Log2Dim>
895 Index64 sum = ChildT::NUM_VOXELS * (NUM_VALUES-mValueMask.countOn()-mChildMask.countOn());
896 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
897 sum += iter->offVoxelCount();
903 template<
typename ChildT, Index Log2Dim>
908 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
909 sum += mNodes[iter.pos()].getChild()->onLeafVoxelCount();
915 template<
typename ChildT, Index Log2Dim>
920 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
921 sum += mNodes[iter.pos()].getChild()->offLeafVoxelCount();
926 template<
typename ChildT, Index Log2Dim>
930 Index64 sum = mValueMask.countOn();
931 for (
ChildOnCIter iter = this->cbeginChildOn(); LEVEL>1 && iter; ++iter) {
932 sum += iter->onTileCount();
937 template<
typename ChildT, Index Log2Dim>
942 + mValueMask.memUsage() +
sizeof(mOrigin);
943 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
944 sum += iter->memUsage();
950 template<
typename ChildT, Index Log2Dim>
954 if (bbox.isInside(this->getNodeBoundingBox()))
return;
957 bbox.expand(i.getCoord(), ChildT::DIM);
960 i->evalActiveBoundingBox(bbox, visitVoxels);
968 template<
typename ChildT, Index Log2Dim>
969 template<
typename PruneOp>
973 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
974 const Index i = iter.pos();
975 ChildT* child = mNodes[i].getChild();
976 if (!op(*child))
continue;
978 mChildMask.setOff(i);
979 mValueMask.set(i, op.state);
980 mNodes[i].setValue(op.value);
986 template<
typename ChildT, Index Log2Dim>
995 template<
typename ChildT, Index Log2Dim>
1004 template<
typename ChildT, Index Log2Dim>
1008 this->pruneInactive(this->getBackground());
1015 template<
typename ChildT, Index Log2Dim>
1016 template<
typename NodeT>
1020 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1021 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1023 const Index n = this->coordToOffset(xyz);
1024 if (mChildMask.isOff(n))
return NULL;
1025 ChildT* child = mNodes[n].getChild();
1026 if (boost::is_same<NodeT, ChildT>::value) {
1027 mChildMask.setOff(n);
1028 mValueMask.set(n, state);
1029 mNodes[n].setValue(value);
1031 return (boost::is_same<NodeT, ChildT>::value)
1032 ?
reinterpret_cast<NodeT*
>(child)
1033 : child->template stealNode<NodeT>(xyz, value, state);
1041 template<
typename ChildT, Index Log2Dim>
1042 template<
typename NodeT>
1046 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1047 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1049 const Index n = this->coordToOffset(xyz);
1050 if (mChildMask.isOff(n))
return NULL;
1051 ChildT* child = mNodes[n].getChild();
1052 return (boost::is_same<NodeT, ChildT>::value)
1053 ?
reinterpret_cast<NodeT*
>(child)
1054 : child->template probeNode<NodeT>(xyz);
1059 template<
typename ChildT, Index Log2Dim>
1060 template<
typename NodeT,
typename AccessorT>
1064 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1065 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1067 const Index n = this->coordToOffset(xyz);
1068 if (mChildMask.isOff(n))
return NULL;
1069 ChildT* child = mNodes[n].getChild();
1070 acc.insert(xyz, child);
1071 return (boost::is_same<NodeT, ChildT>::value)
1072 ?
reinterpret_cast<NodeT*
>(child)
1073 : child->template probeNodeAndCache<NodeT>(xyz, acc);
1078 template<
typename ChildT, Index Log2Dim>
1079 template<
typename NodeT>
1083 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1084 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1086 const Index n = this->coordToOffset(xyz);
1087 if (mChildMask.isOff(n))
return NULL;
1088 const ChildT* child = mNodes[n].getChild();
1089 return (boost::is_same<NodeT, ChildT>::value)
1090 ?
reinterpret_cast<const NodeT*
>(child)
1091 : child->template probeConstNode<NodeT>(xyz);
1096 template<
typename ChildT, Index Log2Dim>
1097 template<
typename NodeT,
typename AccessorT>
1101 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
1102 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
1104 const Index n = this->coordToOffset(xyz);
1105 if (mChildMask.isOff(n))
return NULL;
1106 const ChildT* child = mNodes[n].getChild();
1107 acc.insert(xyz, child);
1108 return (boost::is_same<NodeT, ChildT>::value)
1109 ?
reinterpret_cast<const NodeT*
>(child)
1110 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
1118 template<
typename ChildT, Index Log2Dim>
1119 inline typename ChildT::LeafNodeType*
1122 return this->
template probeNode<LeafNodeType>(xyz);
1126 template<
typename ChildT, Index Log2Dim>
1127 template<
typename AccessorT>
1128 inline typename ChildT::LeafNodeType*
1131 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
1135 template<
typename ChildT, Index Log2Dim>
1136 template<
typename AccessorT>
1137 inline const typename ChildT::LeafNodeType*
1140 return this->probeConstLeafAndCache(xyz, acc);
1144 template<
typename ChildT, Index Log2Dim>
1145 inline const typename ChildT::LeafNodeType*
1148 return this->
template probeConstNode<LeafNodeType>(xyz);
1152 template<
typename ChildT, Index Log2Dim>
1153 template<
typename AccessorT>
1154 inline const typename ChildT::LeafNodeType*
1157 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
1164 template<
typename ChildT, Index Log2Dim>
1168 assert(leaf != NULL);
1169 const Coord& xyz = leaf->origin();
1170 const Index n = this->coordToOffset(xyz);
1171 ChildT* child = NULL;
1172 if (mChildMask.isOff(n)) {
1173 if (ChildT::LEVEL>0) {
1174 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1176 child =
reinterpret_cast<ChildT*
>(leaf);
1178 this->setChildNode(n, child);
1180 if (ChildT::LEVEL>0) {
1181 child = mNodes[n].getChild();
1183 delete mNodes[n].getChild();
1184 child =
reinterpret_cast<ChildT*
>(leaf);
1185 mNodes[n].setChild(child);
1188 child->addLeaf(leaf);
1192 template<
typename ChildT, Index Log2Dim>
1193 template<
typename AccessorT>
1197 assert(leaf != NULL);
1198 const Coord& xyz = leaf->origin();
1199 const Index n = this->coordToOffset(xyz);
1200 ChildT* child = NULL;
1201 if (mChildMask.isOff(n)) {
1202 if (ChildT::LEVEL>0) {
1203 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1204 acc.insert(xyz, child);
1206 child =
reinterpret_cast<ChildT*
>(leaf);
1208 this->setChildNode(n, child);
1210 if (ChildT::LEVEL>0) {
1211 child = mNodes[n].getChild();
1212 acc.insert(xyz, child);
1214 delete mNodes[n].getChild();
1215 child =
reinterpret_cast<ChildT*
>(leaf);
1216 mNodes[n].setChild(child);
1219 child->addLeafAndCache(leaf, acc);
1226 template<
typename ChildT, Index Log2Dim>
1230 assert(n < NUM_VALUES);
1231 this->makeChildNodeEmpty(n, value);
1232 mValueMask.set(n, state);
1236 template<
typename ChildT, Index Log2Dim>
1241 if (LEVEL >= level) {
1242 const Index n = this->coordToOffset(xyz);
1243 if (mChildMask.isOff(n)) {
1244 if (LEVEL > level) {
1245 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1246 this->setChildNode(n, child);
1247 child->addTile(level, xyz, value, state);
1249 mValueMask.set(n, state);
1250 mNodes[n].setValue(value);
1253 ChildT* child = mNodes[n].getChild();
1254 if (LEVEL > level) {
1255 child->addTile(level, xyz, value, state);
1258 mChildMask.setOff(n);
1259 mValueMask.set(n, state);
1260 mNodes[n].setValue(value);
1267 template<
typename ChildT, Index Log2Dim>
1268 template<
typename AccessorT>
1271 const ValueType& value,
bool state, AccessorT& acc)
1273 if (LEVEL >= level) {
1274 const Index n = this->coordToOffset(xyz);
1275 if (mChildMask.isOff(n)) {
1276 if (LEVEL > level) {
1277 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1278 this->setChildNode(n, child);
1279 acc.insert(xyz, child);
1280 child->addTileAndCache(level, xyz, value, state, acc);
1282 mValueMask.set(n, state);
1283 mNodes[n].setValue(value);
1286 ChildT* child = mNodes[n].getChild();
1287 if (LEVEL > level) {
1288 acc.insert(xyz, child);
1289 child->addTileAndCache(level, xyz, value, state, acc);
1292 mChildMask.setOff(n);
1293 mValueMask.set(n, state);
1294 mNodes[n].setValue(value);
1304 template<
typename ChildT, Index Log2Dim>
1305 inline typename ChildT::LeafNodeType*
1308 const Index n = this->coordToOffset(xyz);
1309 ChildT* child = NULL;
1310 if (mChildMask.isOff(n)) {
1311 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1312 this->setChildNode(n, child);
1314 child = mNodes[n].getChild();
1316 return child->touchLeaf(xyz);
1320 template<
typename ChildT, Index Log2Dim>
1321 template<
typename AccessorT>
1322 inline typename ChildT::LeafNodeType*
1325 const Index n = this->coordToOffset(xyz);
1326 if (mChildMask.isOff(n)) {
1327 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), mValueMask.isOn(n)));
1329 acc.insert(xyz, mNodes[n].getChild());
1330 return mNodes[n].getChild()->touchLeafAndCache(xyz, acc);
1337 template<
typename ChildT, Index Log2Dim>
1342 bool allEqual =
true, firstValue =
true, valueState =
true;
1344 for (
Index i = 0; allEqual && i < NUM_VALUES; ++i) {
1345 if (this->isChildMaskOff(i)) {
1350 valueState = isValueMaskOn(i);
1351 value = mNodes[i].getValue();
1353 allEqual = (isValueMaskOn(i) == valueState)
1359 ValueType childValue = zeroVal<ValueType>();
1360 bool isChildOn =
false;
1361 if (mNodes[i].getChild()->isConstant(childValue, isChildOn, tolerance)) {
1364 valueState = isChildOn;
1367 allEqual = (isChildOn == valueState)
1386 template<
typename ChildT, Index Log2Dim>
1390 const bool anyActiveTiles = !mValueMask.isOff();
1391 if (LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1392 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1393 if (iter->hasActiveTiles())
return true;
1399 template<
typename ChildT, Index Log2Dim>
1403 const Index n = this->coordToOffset(xyz);
1404 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1405 return mNodes[n].getChild()->isValueOn(xyz);
1408 template<
typename ChildT, Index Log2Dim>
1409 template<
typename AccessorT>
1413 const Index n = this->coordToOffset(xyz);
1414 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1415 acc.insert(xyz, mNodes[n].getChild());
1416 return mNodes[n].getChild()->isValueOnAndCache(xyz, acc);
1420 template<
typename ChildT, Index Log2Dim>
1421 inline const typename ChildT::ValueType&
1424 const Index n = this->coordToOffset(xyz);
1425 return this->isChildMaskOff(n) ? mNodes[n].getValue()
1426 : mNodes[n].getChild()->getValue(xyz);
1429 template<
typename ChildT, Index Log2Dim>
1430 template<
typename AccessorT>
1431 inline const typename ChildT::ValueType&
1434 const Index n = this->coordToOffset(xyz);
1435 if (this->isChildMaskOn(n)) {
1436 acc.insert(xyz, mNodes[n].getChild());
1437 return mNodes[n].getChild()->getValueAndCache(xyz, acc);
1439 return mNodes[n].getValue();
1443 template<
typename ChildT, Index Log2Dim>
1447 const Index n = this->coordToOffset(xyz);
1448 return this->isChildMaskOff(n) ? LEVEL : mNodes[n].getChild()->getValueLevel(xyz);
1451 template<
typename ChildT, Index Log2Dim>
1452 template<
typename AccessorT>
1456 const Index n = this->coordToOffset(xyz);
1457 if (this->isChildMaskOn(n)) {
1458 acc.insert(xyz, mNodes[n].getChild());
1459 return mNodes[n].getChild()->getValueLevelAndCache(xyz, acc);
1465 template<
typename ChildT, Index Log2Dim>
1469 const Index n = this->coordToOffset(xyz);
1470 if (this->isChildMaskOff(n)) {
1471 value = mNodes[n].getValue();
1472 return this->isValueMaskOn(n);
1474 return mNodes[n].getChild()->probeValue(xyz, value);
1477 template<
typename ChildT, Index Log2Dim>
1478 template<
typename AccessorT>
1483 const Index n = this->coordToOffset(xyz);
1484 if (this->isChildMaskOn(n)) {
1485 acc.insert(xyz, mNodes[n].getChild());
1486 return mNodes[n].getChild()->probeValueAndCache(xyz, value, acc);
1488 value = mNodes[n].getValue();
1489 return this->isValueMaskOn(n);
1493 template<
typename ChildT, Index Log2Dim>
1497 const Index n = this->coordToOffset(xyz);
1498 bool hasChild = this->isChildMaskOn(n);
1499 if (!hasChild && this->isValueMaskOn(n)) {
1503 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
true));
1505 if (hasChild) mNodes[n].getChild()->setValueOff(xyz);
1509 template<
typename ChildT, Index Log2Dim>
1513 const Index n = this->coordToOffset(xyz);
1514 bool hasChild = this->isChildMaskOn(n);
1515 if (!hasChild && !this->isValueMaskOn(n)) {
1519 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
false));
1521 if (hasChild) mNodes[n].getChild()->setValueOn(xyz);
1525 template<
typename ChildT, Index Log2Dim>
1530 bool hasChild = this->isChildMaskOn(n);
1532 const bool active = this->isValueMaskOn(n);
1538 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1541 if (hasChild) mNodes[n].getChild()->setValueOff(xyz, value);
1544 template<
typename ChildT, Index Log2Dim>
1545 template<
typename AccessorT>
1551 bool hasChild = this->isChildMaskOn(n);
1553 const bool active = this->isValueMaskOn(n);
1559 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1563 ChildT* child = mNodes[n].getChild();
1564 acc.insert(xyz, child);
1565 child->setValueOffAndCache(xyz, value, acc);
1570 template<
typename ChildT, Index Log2Dim>
1574 const Index n = this->coordToOffset(xyz);
1575 bool hasChild = this->isChildMaskOn(n);
1577 const bool active = this->isValueMaskOn(n);
1583 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1586 if (hasChild) mNodes[n].getChild()->setValueOn(xyz, value);
1589 template<
typename ChildT, Index Log2Dim>
1590 template<
typename AccessorT>
1595 const Index n = this->coordToOffset(xyz);
1596 bool hasChild = this->isChildMaskOn(n);
1598 const bool active = this->isValueMaskOn(n);
1604 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1608 acc.insert(xyz, mNodes[n].getChild());
1609 mNodes[n].getChild()->setValueAndCache(xyz, value, acc);
1614 template<
typename ChildT, Index Log2Dim>
1618 const Index n = this->coordToOffset(xyz);
1619 bool hasChild = this->isChildMaskOn(n);
1623 const bool active = this->isValueMaskOn(n);
1625 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1627 if (hasChild) mNodes[n].getChild()->setValueOnly(xyz, value);
1630 template<
typename ChildT, Index Log2Dim>
1631 template<
typename AccessorT>
1636 const Index n = this->coordToOffset(xyz);
1637 bool hasChild = this->isChildMaskOn(n);
1641 const bool active = this->isValueMaskOn(n);
1643 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1646 acc.insert(xyz, mNodes[n].getChild());
1647 mNodes[n].getChild()->setValueOnlyAndCache(xyz, value, acc);
1652 template<
typename ChildT, Index Log2Dim>
1656 const Index n = this->coordToOffset(xyz);
1657 bool hasChild = this->isChildMaskOn(n);
1659 if (on != this->isValueMaskOn(n)) {
1664 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1667 if (hasChild) mNodes[n].getChild()->setActiveState(xyz, on);
1670 template<
typename ChildT, Index Log2Dim>
1671 template<
typename AccessorT>
1675 const Index n = this->coordToOffset(xyz);
1676 bool hasChild = this->isChildMaskOn(n);
1678 if (on != this->isValueMaskOn(n)) {
1683 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1687 ChildT* child = mNodes[n].getChild();
1688 acc.insert(xyz, child);
1689 child->setActiveStateAndCache(xyz, on, acc);
1694 template<
typename ChildT, Index Log2Dim>
1698 mValueMask = !mChildMask;
1699 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1700 mNodes[iter.pos()].getChild()->setValuesOn();
1705 template<
typename ChildT, Index Log2Dim>
1706 template<
typename ModifyOp>
1711 bool hasChild = this->isChildMaskOn(n);
1715 const bool active = this->isValueMaskOn(n);
1716 bool createChild = !active;
1720 const ValueType& tileVal = mNodes[n].getValue();
1727 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1730 if (hasChild) mNodes[n].getChild()->modifyValue(xyz, op);
1733 template<
typename ChildT, Index Log2Dim>
1734 template<
typename ModifyOp,
typename AccessorT>
1740 bool hasChild = this->isChildMaskOn(n);
1744 const bool active = this->isValueMaskOn(n);
1745 bool createChild = !active;
1749 const ValueType& tileVal = mNodes[n].getValue();
1756 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1761 acc.insert(xyz, child);
1762 child->modifyValueAndCache(xyz, op, acc);
1767 template<
typename ChildT, Index Log2Dim>
1768 template<
typename ModifyOp>
1773 bool hasChild = this->isChildMaskOn(n);
1775 const bool tileState = this->isValueMaskOn(n);
1776 const ValueType& tileVal = mNodes[n].getValue();
1777 bool modifiedState = !tileState;
1779 op(modifiedVal, modifiedState);
1784 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1787 if (hasChild) mNodes[n].getChild()->modifyValueAndActiveState(xyz, op);
1790 template<
typename ChildT, Index Log2Dim>
1791 template<
typename ModifyOp,
typename AccessorT>
1794 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1797 bool hasChild = this->isChildMaskOn(n);
1799 const bool tileState = this->isValueMaskOn(n);
1800 const ValueType& tileVal = mNodes[n].getValue();
1801 bool modifiedState = !tileState;
1803 op(modifiedVal, modifiedState);
1808 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1813 acc.insert(xyz, child);
1814 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1822 template<
typename ChildT, Index Log2Dim>
1826 Coord xyz, tileMin, tileMax;
1827 for (
int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
1829 for (
int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
1831 for (
int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
1835 const Index n = this->coordToOffset(xyz);
1836 tileMin = this->offsetToGlobalCoord(n);
1837 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
1839 if (xyz != tileMin || Coord::lessThan(bbox.max(), tileMax)) {
1843 ChildT* child = NULL;
1844 if (this->isChildMaskOff(n)) {
1847 child =
new ChildT(xyz, mNodes[n].getValue(), this->isValueMaskOn(n));
1848 this->setChildNode(n, child);
1850 child = mNodes[n].getChild();
1863 this->makeChildNodeEmpty(n, value);
1864 mValueMask.set(n, active);
1875 template<
typename ChildT, Index Log2Dim>
1876 template<
typename DenseT>
1880 typedef typename DenseT::ValueType DenseValueType;
1882 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1883 const Coord&
min = dense.bbox().min();
1884 for (Coord xyz = bbox.min(),
max; xyz[0] <= bbox.max()[0]; xyz[0] =
max[0] + 1) {
1885 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] =
max[1] + 1) {
1886 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] =
max[2] + 1) {
1887 const Index n = this->coordToOffset(xyz);
1889 max = this->offsetToGlobalCoord(n).offsetBy(ChildT::DIM-1);
1894 if (this->isChildMaskOn(n)) {
1895 mNodes[n].getChild()->copyToDense(sub, dense);
1897 const ValueType value = mNodes[n].getValue();
1898 sub.translate(-min);
1899 DenseValueType* a0 = dense.data() + zStride*sub.min()[2];
1900 for (
Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
1901 DenseValueType* a1 = a0 + x*xStride;
1902 for (
Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
1903 DenseValueType* a2 = a1 + y*yStride;
1904 for (
Int32 z=sub.min()[2], ez=sub.max()[2]+1; z<ez; ++z, a2 += zStride) {
1905 *a2 = DenseValueType(value);
1919 template<
typename ChildT, Index Log2Dim>
1923 mChildMask.save(os);
1924 mValueMask.save(os);
1928 boost::shared_array<ValueType> values(
new ValueType[NUM_VALUES]);
1929 const ValueType zero = zeroVal<ValueType>();
1930 for (
Index i = 0; i < NUM_VALUES; ++i) {
1931 values[i] = (mChildMask.isOff(i) ? mNodes[i].getValue() : zero);
1937 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1938 iter->writeTopology(os, toHalf);
1943 template<
typename ChildT, Index Log2Dim>
1947 mChildMask.load(is);
1948 mValueMask.load(is);
1951 for (
Index i = 0; i < NUM_VALUES; ++i) {
1952 if (this->isChildMaskOn(i)) {
1954 new ChildNodeType(offsetToGlobalCoord(i), zeroVal<ValueType>());
1955 mNodes[i].setChild(child);
1956 child->readTopology(is);
1959 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
1960 mNodes[i].setValue(value);
1964 const bool oldVersion =
1966 const Index numValues = (oldVersion ? mChildMask.countOff() : NUM_VALUES);
1970 boost::shared_array<ValueType> values(
new ValueType[numValues]);
1976 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
1977 mNodes[iter.pos()].setValue(values[n++]);
1979 assert(n == numValues);
1981 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
1982 mNodes[iter.pos()].setValue(values[iter.pos()]);
1987 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1989 mNodes[iter.pos()].setChild(child);
1990 child->readTopology(is, fromHalf);
1999 template<
typename ChildT, Index Log2Dim>
2000 inline const typename ChildT::ValueType&
2003 return (this->isChildMaskOn(0) ? mNodes[0].getChild()->getFirstValue() : mNodes[0].getValue());
2007 template<
typename ChildT, Index Log2Dim>
2008 inline const typename ChildT::ValueType&
2011 const Index n = NUM_VALUES - 1;
2012 return (this->isChildMaskOn(n) ? mNodes[n].getChild()->getLastValue() : mNodes[n].getValue());
2019 template<
typename ChildT, Index Log2Dim>
2027 template<
typename ChildT, Index Log2Dim>
2033 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2034 iter->signedFloodFill(outsideValue, insideValue);
2036 const Index first = mChildMask.findFirstOn();
2037 if (first < NUM_VALUES) {
2038 bool xInside =
math::isNegative(mNodes[first].getChild()->getFirstValue()),
2039 yInside = xInside, zInside = xInside;
2040 for (
Index x = 0; x != (1 << Log2Dim); ++x) {
2041 const int x00 = x << (2 * Log2Dim);
2042 if (isChildMaskOn(x00)) {
2046 for (
Index y = 0; y != (1 << Log2Dim); ++y) {
2047 const Index xy0 = x00 + (y << Log2Dim);
2048 if (isChildMaskOn(xy0)) {
2052 for (
Index z = 0; z != (1 << Log2Dim); ++z) {
2053 const Index xyz = xy0 + z;
2054 if (isChildMaskOn(xyz)) {
2057 mNodes[xyz].setValue(zInside ? insideValue : outsideValue);
2064 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(v);
2069 template<
typename ChildT, Index Log2Dim>
2073 for (
Index i = 0; i < NUM_VALUES; ++i) {
2074 if (this->isChildMaskOn(i)) {
2075 mNodes[i].getChild()->negate();
2084 template<
typename ChildT, Index Log2Dim>
2088 for (
ValueOnIter iter = this->beginValueOn(); iter; ++iter) {
2089 this->setChildNode(iter.pos(),
new ChildNodeType(iter.getCoord(), iter.getValue(),
true));
2091 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) iter->voxelizeActiveTiles();
2098 template<
typename ChildT, Index Log2Dim>
2099 template<MergePolicy Policy>
2112 const Index n = iter.pos();
2113 if (mChildMask.isOn(n)) {
2115 mNodes[n].getChild()->template merge<MERGE_ACTIVE_STATES>(*iter,
2116 background, otherBackground);
2117 }
else if (mValueMask.isOff(n)) {
2124 child->resetBackground(otherBackground, background);
2125 this->setChildNode(n, child);
2131 const Index n = iter.pos();
2132 if (mValueMask.isOff(n)) {
2134 this->makeChildNodeEmpty(n, iter.getValue());
2135 mValueMask.setOn(n);
2144 const Index n = iter.pos();
2145 if (mChildMask.isOn(n)) {
2147 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2155 child->resetBackground(otherBackground, background);
2156 this->setChildNode(n, child);
2166 const Index n = iter.pos();
2167 if (mChildMask.isOn(n)) {
2169 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2176 child->resetBackground(otherBackground, background);
2177 if (mValueMask.isOn(n)) {
2179 child->template merge<Policy>(mNodes[n].getValue(),
true);
2180 mValueMask.setOff(n);
2182 mChildMask.setOn(n);
2183 mNodes[n].setChild(child);
2189 const Index n = iter.pos();
2190 if (mChildMask.isOn(n)) {
2192 mNodes[n].getChild()->template merge<Policy>(iter.getValue(),
true);
2193 }
else if (mValueMask.isOff(n)) {
2195 mNodes[n].setValue(iter.getValue());
2196 mValueMask.setOn(n);
2207 template<
typename ChildT, Index Log2Dim>
2208 template<MergePolicy Policy>
2217 if (!tileActive)
return;
2220 for (
ValueOffIter iter = this->beginValueOff(); iter; ++iter) {
2221 const Index n = iter.pos();
2222 if (mChildMask.isOn(n)) {
2224 mNodes[n].getChild()->template merge<Policy>(tileValue,
true);
2227 iter.setValue(tileValue);
2228 mValueMask.setOn(n);
2238 template<
typename ChildT, Index Log2Dim>
2239 template<
typename OtherChildT>
2247 for (OtherChildIter iter = other.
cbeginChildOn(); iter; ++iter) {
2249 if (mChildMask.isOn(i)) {
2250 mNodes[i].getChild()->topologyUnion(*iter);
2253 if (mValueMask.isOn(i)) {
2254 mValueMask.isOff(i);
2255 child->setValuesOn();
2257 mChildMask.setOn(i);
2258 mNodes[i].setChild(child);
2262 for (OtherValueIter iter = other.
cbeginValueOn(); iter; ++iter) {
2263 const Index i = iter.pos();
2264 if (mChildMask.isOn(i)) {
2265 mNodes[i].getChild()->setValuesOn();
2266 }
else if (mValueMask.isOff(i)) {
2267 mValueMask.setOn(i);
2272 template<
typename ChildT, Index Log2Dim>
2273 template<
typename OtherChildT>
2279 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2280 const Index i = iter.pos();
2282 iter->topologyIntersection(*(other.
mNodes[i].getChild()), background);
2284 delete mNodes[i].getChild();
2285 mNodes[i].setValue(background);
2286 mChildMask.setOff(i);
2287 mValueMask.setOff(i);
2292 for (
ValueOnCIter iter = this->cbeginValueOn(); iter; ++iter) {
2293 const Index i = iter.pos();
2297 this->setChildNode(i, child);
2299 mValueMask.setOff(i);
2304 template<
typename ChildT, Index Log2Dim>
2305 template<
typename OtherChildT>
2314 for (OtherChildIter iter = other.
cbeginChildOn(); iter; ++iter) {
2316 if (mChildMask.isOn(i)) {
2317 mNodes[i].getChild()->topologyDifference(*iter, background);
2318 }
else if (mValueMask.isOn(i)) {
2320 child->topologyDifference(*iter, background);
2321 this->setChildNode(i, child);
2326 for (OtherValueIter iter = other.
cbeginValueOn(); iter; ++iter) {
2327 const Index i = iter.pos();
2328 if (mChildMask.isOn(i)) {
2329 delete mNodes[i].getChild();
2330 mNodes[i].setValue(background);
2331 mChildMask.setOff(i);
2332 mValueMask.setOff(i);
2333 }
else if (mValueMask.isOn(i)) {
2334 mValueMask.setOff(i);
2342 template<
typename ChildT, Index Log2Dim>
2343 template<
typename CombineOp>
2347 const ValueType zero = zeroVal<ValueType>();
2351 for (
Index i = 0; i < NUM_VALUES; ++i) {
2355 op(args.setARef(mNodes[i].getValue())
2356 .setAIsActive(isValueMaskOn(i))
2357 .setBRef(other.
mNodes[i].getValue())
2359 mNodes[i].setValue(args.result());
2360 mValueMask.set(i, args.resultIsActive());
2368 }
else if (this->isChildMaskOff(i) && other.
isChildMaskOn(i)) {
2377 child->combine(mNodes[i].getValue(), isValueMaskOn(i), swappedOp);
2381 other.
mNodes[i].setValue(zero);
2382 this->setChildNode(i, child);
2388 *child = mNodes[i].getChild(),
2389 *otherChild = other.
mNodes[i].getChild();
2392 if (child && otherChild) {
2393 child->combine(*otherChild, op);
2400 template<
typename ChildT, Index Log2Dim>
2401 template<
typename CombineOp>
2407 for (
Index i = 0; i < NUM_VALUES; ++i) {
2408 if (this->isChildMaskOff(i)) {
2410 op(args.
setARef(mNodes[i].getValue())
2411 .setAIsActive(isValueMaskOn(i))
2413 .setBIsActive(valueIsActive));
2414 mNodes[i].setValue(args.
result());
2420 if (child) child->combine(value, valueIsActive, op);
2429 template<
typename ChildT, Index Log2Dim>
2430 template<
typename CombineOp,
typename OtherNodeType>
2437 for (
Index i = 0; i < NUM_VALUES; ++i) {
2441 .setBRef(other1.mNodes[i].getValue())
2442 .setBIsActive(other1.isValueMaskOn(i)));
2444 this->makeChildNodeEmpty(i, args.
result());
2447 if (this->isChildMaskOff(i)) {
2450 ? other0.
mNodes[i].getChild()->origin()
2451 : other1.mNodes[i].getChild()->origin();
2452 this->setChildNode(i,
new ChildNodeType(childOrigin, mNodes[i].getValue()));
2458 mNodes[i].getChild()->combine2(other0.
mNodes[i].getValue(),
2460 }
else if (other1.isChildMaskOff(i)) {
2463 mNodes[i].getChild()->combine2(*other0.
mNodes[i].getChild(),
2464 other1.mNodes[i].getValue(), other1.isValueMaskOn(i), op);
2468 mNodes[i].getChild()->combine2(*other0.
mNodes[i].getChild(),
2469 *other1.mNodes[i].getChild(), op);
2476 template<
typename ChildT, Index Log2Dim>
2477 template<
typename CombineOp,
typename OtherNodeType>
2480 bool valueIsActive, CombineOp& op)
2484 for (
Index i = 0; i < NUM_VALUES; ++i) {
2485 if (other.isChildMaskOff(i)) {
2487 .setAIsActive(valueIsActive)
2488 .setBRef(other.mNodes[i].getValue())
2489 .setBIsActive(other.isValueMaskOn(i)));
2491 this->makeChildNodeEmpty(i, args.
result());
2494 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[i].getChild();
2496 if (this->isChildMaskOff(i)) {
2503 mNodes[i].getChild()->combine2(value, *otherChild, valueIsActive, op);
2509 template<
typename ChildT, Index Log2Dim>
2510 template<
typename CombineOp,
typename OtherValueType>
2513 bool valueIsActive, CombineOp& op)
2517 for (
Index i = 0; i < NUM_VALUES; ++i) {
2522 .setBIsActive(valueIsActive));
2524 this->makeChildNodeEmpty(i, args.
result());
2529 if (this->isChildMaskOff(i)) {
2531 this->setChildNode(i,
2532 new ChildNodeType(otherChild->origin(), mNodes[i].getValue()));
2536 mNodes[i].getChild()->combine2(*otherChild, value, valueIsActive, op);
2545 template<
typename ChildT, Index Log2Dim>
2546 template<
typename BBoxOp>
2552 op.operator()<LEVEL>(CoordBBox::createCube(i.getCoord(), ChildNodeType::DIM));
2554 op.template operator()<LEVEL>(CoordBBox::createCube(i.getCoord(), ChildNodeType::DIM));
2557 if (op.template descent<LEVEL>()) {
2558 for (
ChildOnCIter i = this->cbeginChildOn(); i; ++i) i->visitActiveBBox(op);
2562 op.operator()<LEVEL>(i->getNodeBoundingBox());
2564 op.template operator()<LEVEL>(i->getNodeBoundingBox());
2571 template<
typename ChildT, Index Log2Dim>
2572 template<
typename VisitorOp>
2576 doVisit<InternalNode, VisitorOp, ChildAllIter>(*
this, op);
2580 template<
typename ChildT, Index Log2Dim>
2581 template<
typename VisitorOp>
2585 doVisit<const InternalNode, VisitorOp, ChildAllCIter>(*
this, op);
2589 template<
typename ChildT, Index Log2Dim>
2590 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
2594 typename NodeT::ValueType val;
2595 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2596 if (op(iter))
continue;
2597 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2607 template<
typename ChildT, Index Log2Dim>
2608 template<
typename OtherNodeType,
typename VisitorOp>
2613 typename OtherNodeType::ChildAllIter>(*
this, other, op);
2617 template<
typename ChildT, Index Log2Dim>
2618 template<
typename OtherNodeType,
typename VisitorOp>
2623 typename OtherNodeType::ChildAllCIter>(*
this, other, op);
2627 template<
typename ChildT, Index Log2Dim>
2630 typename OtherNodeT,
2632 typename ChildAllIterT,
2633 typename OtherChildAllIterT>
2638 BOOST_STATIC_ASSERT(OtherNodeT::NUM_VALUES == NodeT::NUM_VALUES);
2639 BOOST_STATIC_ASSERT(OtherNodeT::LEVEL == NodeT::LEVEL);
2641 typename NodeT::ValueType val;
2642 typename OtherNodeT::ValueType otherVal;
2644 ChildAllIterT iter =
self.beginChildAll();
2645 OtherChildAllIterT otherIter = other.beginChildAll();
2647 for ( ; iter && otherIter; ++iter, ++otherIter)
2649 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2651 typename ChildAllIterT::ChildNodeType* child =
2652 (skipBranch & 1U) ? NULL : iter.probeChild(val);
2653 typename OtherChildAllIterT::ChildNodeType* otherChild =
2654 (skipBranch & 2U) ? NULL : otherIter.probeChild(otherVal);
2656 if (child != NULL && otherChild != NULL) {
2657 child->visit2Node(*otherChild, op);
2658 }
else if (child != NULL) {
2659 child->visit2(otherIter, op);
2660 }
else if (otherChild != NULL) {
2661 otherChild->visit2(iter, op,
true);
2670 template<
typename ChildT, Index Log2Dim>
2671 template<
typename OtherChildAllIterType,
typename VisitorOp>
2674 VisitorOp& op,
bool otherIsLHS)
2676 doVisit2<InternalNode, VisitorOp, ChildAllIter, OtherChildAllIterType>(
2677 *
this, otherIter, op, otherIsLHS);
2681 template<
typename ChildT, Index Log2Dim>
2682 template<
typename OtherChildAllIterType,
typename VisitorOp>
2685 VisitorOp& op,
bool otherIsLHS)
const
2687 doVisit2<const InternalNode, VisitorOp, ChildAllCIter, OtherChildAllIterType>(
2688 *
this, otherIter, op, otherIsLHS);
2692 template<
typename ChildT, Index Log2Dim>
2693 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT,
typename OtherChildAllIterT>
2696 VisitorOp& op,
bool otherIsLHS)
2698 if (!otherIter)
return;
2700 const size_t skipBitMask = (otherIsLHS ? 2U : 1U);
2702 typename NodeT::ValueType val;
2703 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2704 const size_t skipBranch =
static_cast<size_t>(
2705 otherIsLHS ? op(otherIter, iter) : op(iter, otherIter));
2707 typename ChildAllIterT::ChildNodeType* child =
2708 (skipBranch & skipBitMask) ? NULL : iter.probeChild(val);
2710 if (child != NULL) child->visit2(otherIter, op, otherIsLHS);
2718 template<
typename ChildT, Index Log2Dim>
2722 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2723 iter->writeBuffers(os, toHalf);
2728 template<
typename ChildT, Index Log2Dim>
2732 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2733 iter->readBuffers(is, fromHalf);
2741 template<
typename ChildT, Index Log2Dim>
2745 dims.push_back(Log2Dim);
2746 ChildNodeType::getNodeLog2Dims(dims);
2750 template<
typename ChildT, Index Log2Dim>
2754 assert(n<(1<<3*Log2Dim));
2755 xyz.setX(n >> 2*Log2Dim);
2756 n &= ((1<<2*Log2Dim)-1);
2757 xyz.setY(n >> Log2Dim);
2758 xyz.setZ(n & ((1<<Log2Dim)-1));
2762 template<
typename ChildT, Index Log2Dim>
2766 return (((xyz[0] & (DIM-1u)) >> ChildNodeType::TOTAL) << 2*Log2Dim)
2767 + (((xyz[1] & (DIM-1u)) >> ChildNodeType::TOTAL) << Log2Dim)
2768 + ((xyz[2] & (DIM-1u)) >> ChildNodeType::TOTAL);
2772 template<
typename ChildT, Index Log2Dim>
2777 this->offsetToLocalCoord(n, local);
2778 local <<= ChildT::TOTAL;
2779 return local + this->origin();
2786 template<
typename ChildT, Index Log2Dim>
2792 for (
Index i = 0; i < NUM_VALUES; ++i) {
2793 if (this->isChildMaskOn(i)) {
2794 mNodes[i].getChild()->resetBackground(oldBackground, newBackground);
2795 }
else if (this->isValueMaskOff(i)) {
2797 mNodes[i].setValue(newBackground);
2806 template<
typename ChildT, Index Log2Dim>
2807 template<
typename OtherChildNodeType, Index OtherLog2Dim>
2812 if (Log2Dim != OtherLog2Dim || mChildMask != other->
mChildMask ||
2813 mValueMask != other->
mValueMask)
return false;
2814 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2815 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
2821 template<
typename ChildT, Index Log2Dim>
2826 if (this->isChildMaskOn(i)) {
2827 delete mNodes[i].getChild();
2829 mChildMask.setOn(i);
2830 mValueMask.setOff(i);
2832 mNodes[i].setChild(child);
2835 template<
typename ChildT, Index Log2Dim>
2840 assert(mChildMask.isOff(i));
2841 mChildMask.setOn(i);
2842 mValueMask.setOff(i);
2843 mNodes[i].setChild(child);
2847 template<
typename ChildT, Index Log2Dim>
2851 if (this->isChildMaskOff(i)) {
2852 mNodes[i].setValue(value);
2856 mChildMask.setOff(i);
2857 mNodes[i].setValue(value);
2862 template<
typename ChildT, Index Log2Dim>
2866 delete this->unsetChildNode(n, value);
2869 template<
typename ChildT, Index Log2Dim>
2873 assert(this->isChildMaskOn(n));
2874 return mNodes[n].getChild();
2878 template<
typename ChildT, Index Log2Dim>
2879 inline const ChildT*
2882 assert(this->isChildMaskOn(n));
2883 return mNodes[n].getChild();
2890 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED
bool resultIsActive() const
Definition: Types.h:314
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:283
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:158
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:203
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:262
static const Index NUM_VALUES
Definition: InternalNode.h:73
Definition: InternalNode.h:128
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:238
Definition: InternalNode.h:154
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:2009
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:293
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:148
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:381
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:393
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:1921
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:1166
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:1454
bool isConstant(ValueType &constValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1339
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllIter
Definition: InternalNode.h:222
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:227
NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:123
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:303
Index64 onTileCount() const
Definition: InternalNode.h:928
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:1736
Index32 Index
Definition: Types.h:57
ChildT & getItem(Index pos) const
Definition: InternalNode.h:141
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:64
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:679
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffIter
Definition: InternalNode.h:220
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:677
NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:124
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:917
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:971
ValueIter< const InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnCIter
Definition: InternalNode.h:219
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:1146
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2730
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:2774
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1547
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:239
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:2001
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:1654
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2720
ValueIter< InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnIter
Definition: InternalNode.h:218
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
void voxelizeActiveTiles()
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2086
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:236
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1388
Definition: NodeMasks.h:188
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.
Definition: InternalNode.h:127
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:197
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:714
Helper class for use with Tree::pruneOp() to replace constant branches (to within the provided tolera...
Definition: tree/Util.h:47
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:988
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffCIter
Definition: InternalNode.h:221
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:1945
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:1708
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:298
Index32 nonLeafCount() const
Definition: InternalNode.h:868
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:905
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
const AValueType & result() const
Get the output value.
Definition: Types.h:295
ValueConverter::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:81
static Index getChildDim()
Definition: InternalNode.h:249
DenseIter< InternalNode, ChildNodeType, ValueType, ChildAll > ChildAllIter
Definition: InternalNode.h:215
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:1306
DenseIter()
Definition: InternalNode.h:181
void pruneInactive()
Reduce the memory footprint of this tree by replacing with background tiles any nodes whose values ar...
Definition: InternalNode.h:1006
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:2764
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:952
static void doVisit(NodeT &, VisitorOp &)
Definition: InternalNode.h:2592
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:1120
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:287
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:2101
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1401
ChildOnIter beginChildOn()
Definition: InternalNode.h:231
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:1878
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.
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:237
Definition: InternalNode.h:175
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:2849
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1467
Definition: NodeMasks.h:219
ChildOffIter beginChildOff()
Definition: InternalNode.h:232
static void doVisit2Node(NodeT &, OtherNodeT &, VisitorOp &)
Definition: InternalNode.h:2635
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:265
ChildAllIter beginChildAll()
Definition: InternalNode.h:233
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:138
NodeMaskType mValueMask
Definition: InternalNode.h:715
Index64 offVoxelCount() const
Definition: InternalNode.h:893
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes ...
Definition: InternalNode.h:2548
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1696
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:164
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:1770
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:939
Definition: InternalNode.h:60
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:2021
NodeMaskType mChildMask
Definition: InternalNode.h:715
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1480
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:1195
Definition: version.h:106
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:444
uint64_t Index64
Definition: Types.h:56
#define OPENVDB_VERSION_NAME
Definition: version.h:45
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:260
bool isValueMaskOff() const
Definition: InternalNode.h:678
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1793
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffCIter
Definition: InternalNode.h:214
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:225
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:351
NodeUnion< ValueType, ChildNodeType > UnionType
Definition: InternalNode.h:66
InternalNode()
Definition: InternalNode.h:96
_ChildNodeType ChildNodeType
Definition: InternalNode.h:63
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...
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:226
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1511
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:148
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:58
ValueOnIter beginValueOn()
Definition: InternalNode.h:241
static Index dim()
Definition: InternalNode.h:246
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:497
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:2788
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 topologyUnion(const InternalNode< OtherChildNodeType, Log2Dim > &other)
Union this branch's set of active values with the other branch's active values. The value type of the...
bool isValueMaskOn() const
Definition: InternalNode.h:676
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:211
Definition: InternalNode.h:128
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:388
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2345
Index64 onVoxelCount() const
Definition: InternalNode.h:881
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:229
ChildIter< const InternalNode, const ChildNodeType, MaskOnIterator, ChildOn > ChildOnCIter
Definition: InternalNode.h:212
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:1616
void negate()
Definition: InternalNode.h:2071
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:1445
uint32_t Index32
Definition: Types.h:55
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:168
DenseIter< const InternalNode, const ChildNodeType, ValueType, ChildAll > ChildAllCIter
Definition: InternalNode.h:216
int32_t Int32
Definition: Types.h:59
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1633
OPENVDB_IMPORT uint32_t getFormatVersion(std::istream &)
Return the file format version number associated with the given input stream.
ValueOffIter beginValueOff()
Definition: InternalNode.h:242
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition: InternalNode.h:2871
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 isChildMaskOff(Index n) const
Definition: InternalNode.h:680
Helper class for use with Tree::pruneOp() to replace inactive branches with more memory-efficient ina...
Definition: tree/Util.h:74
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:717
NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:122
Index pos() const
Identical to offset.
Definition: Iterator.h:94
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:1270
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:2864
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:228
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:2837
InternalNode< typename ChildNodeType::template ValueConverter< OtherValueType >::Type, Log2Dim > Type
Definition: InternalNode.h:83
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:67
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1422
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:2809
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:185
ValueAllIter beginValueAll()
Definition: InternalNode.h:243
ValueIter< InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffIter
Definition: InternalNode.h:213
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1592
DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT > BaseT
Definition: InternalNode.h:178
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
bool isApproxEqual(const Hermite &lhs, const Hermite &rhs)
Definition: Hermite.h:470
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:1018
static Index getLevel()
Definition: InternalNode.h:247
SameConfiguration::value is true if and only if OtherNodeType is the type of an Intern...
Definition: InternalNode.h:90
void visit2Node(OtherNodeType &other, VisitorOp &)
Definition: InternalNode.h:2610
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1673
bool isEmpty() const
Definition: InternalNode.h:285
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:161
BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:179
Definition: InternalNode.h:134
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:2752
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:230
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:107
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1495
Definition: NodeMasks.h:250
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:1824
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition: InternalNode.h:2432
void visit(VisitorOp &)
Definition: InternalNode.h:2574
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
Index32 leafCount() const
Definition: InternalNode.h:855
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1411
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:304
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:235
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllCIter
Definition: InternalNode.h:223
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:1238
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:675
virtual ~InternalNode()
Definition: InternalNode.h:842
ChildIter()
Definition: InternalNode.h:137
ValueIter()
Definition: InternalNode.h:157
bool isChildMaskOff() const
Definition: InternalNode.h:681
ChildIter< InternalNode, ChildNodeType, MaskOnIterator, ChildOn > ChildOnIter
Definition: InternalNode.h:211
static void doVisit2(NodeT &, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: InternalNode.h:2695
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: InternalNode.h:2743
ChildNodeType::ValueType ValueType
Definition: InternalNode.h:65
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:182
Definition: InternalNode.h:56
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:277
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:240
Definition: InternalNode.h:127
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:2823
boost::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:217