35 #ifndef OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 36 #define OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 46 #include <tbb/parallel_for.h> 48 #include <type_traits> 59 template<
typename _ChildNodeType, Index Log2Dim>
65 using ValueType =
typename ChildNodeType::ValueType;
66 using BuildType =
typename ChildNodeType::BuildType;
72 TOTAL = Log2Dim + ChildNodeType::TOTAL,
74 NUM_VALUES = 1 << (3 * Log2Dim),
75 LEVEL = 1 + ChildNodeType::LEVEL;
77 NUM_VOXELS = uint64_t(1) << (3 * TOTAL);
81 template<
typename OtherValueType>
90 template<
typename OtherNodeType>
92 static const bool value =
109 InternalNode(
const Coord& origin,
const ValueType& fillValue,
bool active =
false);
111 #if OPENVDB_ABI_VERSION_NUMBER >= 3 123 template<
typename OtherChildNodeType>
129 template<
typename OtherChildNodeType>
136 template<
typename OtherChildNodeType>
138 const ValueType& offValue,
const ValueType& onValue,
TopologyCopy);
140 #if OPENVDB_ABI_VERSION_NUMBER < 5 159 template<
typename NodeT,
typename ChildT,
typename MaskIterT,
typename TagT>
161 MaskIterT, ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>
165 MaskIterT,
ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>(iter, parent) {}
169 assert(this->parent().isChildMaskOn(pos));
170 return *(this->parent().getChildNode(pos));
174 void setItem(
Index pos,
const ChildT& c)
const { this->parent().resetChildNode(pos, &c); }
180 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
182 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
186 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
188 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
191 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
194 template<
typename ModifyOp>
197 op(this->parent().mNodes[pos].getValue());
202 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
204 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
215 if (this->parent().isChildMaskOn(pos)) {
216 child = this->parent().getChildNode(pos);
220 value = this->parent().mNodes[pos].getValue();
227 this->parent().resetChildNode(pos, child);
233 this->parent().unsetChildNode(pos, value);
285 static void getNodeLog2Dims(std::vector<Index>& dims);
295 static void offsetToLocalCoord(
Index n,
Coord& xyz);
308 Index64 onLeafVoxelCount()
const;
309 Index64 offLeafVoxelCount()
const;
319 void evalActiveBoundingBox(
CoordBBox& bbox,
bool visitVoxels =
true)
const;
326 bool isEmpty()
const {
return mChildMask.isOff(); }
333 bool isConstant(ValueType& firstValue,
bool& state,
334 const ValueType& tolerance = zeroVal<ValueType>())
const;
350 bool isConstant(ValueType& minValue, ValueType& maxValue,
351 bool& state,
const ValueType& tolerance = zeroVal<ValueType>())
const;
354 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
357 bool isValueOn(
const Coord& xyz)
const;
362 bool hasActiveTiles()
const;
364 const ValueType& getValue(
const Coord& xyz)
const;
365 bool probeValue(
const Coord& xyz, ValueType& value)
const;
373 const ValueType& getFirstValue()
const;
376 const ValueType& getLastValue()
const;
379 void setActiveState(
const Coord& xyz,
bool on);
381 void setValueOnly(
const Coord& xyz,
const ValueType& value);
383 void setValueOn(
const Coord& xyz);
385 void setValueOn(
const Coord& xyz,
const ValueType& value);
387 void setValueOff(
const Coord& xyz);
389 void setValueOff(
const Coord& xyz,
const ValueType& value);
393 template<
typename ModifyOp>
394 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
396 template<
typename ModifyOp>
397 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
403 template<
typename AccessorT>
404 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
410 template<
typename AccessorT>
411 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
417 template<
typename AccessorT>
418 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
424 template<
typename AccessorT>
425 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
432 template<
typename ModifyOp,
typename AccessorT>
433 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
439 template<
typename ModifyOp,
typename AccessorT>
440 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
446 template<
typename AccessorT>
447 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
453 template<
typename AccessorT>
454 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
461 template<
typename AccessorT>
462 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
470 template<
typename AccessorT>
471 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
479 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
480 void readTopology(std::istream&,
bool fromHalf =
false);
481 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
482 void readBuffers(std::istream&,
bool fromHalf =
false);
483 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
501 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
510 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
515 void voxelizeActiveTiles(
bool threaded =
true);
524 template<
typename DenseT>
529 template<MergePolicy Policy>
530 void merge(
InternalNode& other,
const ValueType& background,
const ValueType& otherBackground);
534 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
548 template<
typename OtherChildNodeType>
564 template<
typename OtherChildNodeType>
566 const ValueType& background);
579 template<
typename OtherChildNodeType>
581 const ValueType& background);
583 template<
typename CombineOp>
585 template<
typename CombineOp>
586 void combine(
const ValueType& value,
bool valueIsActive, CombineOp&);
588 template<
typename CombineOp,
typename OtherNodeType >
589 void combine2(
const InternalNode& other0,
const OtherNodeType& other1, CombineOp&);
590 template<
typename CombineOp,
typename OtherNodeType >
591 void combine2(
const ValueType& value,
const OtherNodeType& other,
bool valIsActive, CombineOp&);
592 template<
typename CombineOp,
typename OtherValueType>
593 void combine2(
const InternalNode& other,
const OtherValueType&,
bool valIsActive, CombineOp&);
600 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
602 template<
typename VisitorOp>
void visit(VisitorOp&);
603 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
605 template<
typename OtherNodeType,
typename VisitorOp>
606 void visit2Node(OtherNodeType& other, VisitorOp&);
607 template<
typename OtherNodeType,
typename VisitorOp>
608 void visit2Node(OtherNodeType& other, VisitorOp&)
const;
609 template<
typename IterT,
typename VisitorOp>
610 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false);
611 template<
typename IterT,
typename VisitorOp>
612 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false)
const;
620 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
624 void addLeaf(LeafNodeType* leaf);
628 template<
typename AccessorT>
629 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
639 template<
typename NodeT>
640 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
644 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
647 void addTile(
Index offset,
const ValueType& value,
bool state);
651 template<
typename AccessorT>
652 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
655 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
658 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
662 template<
typename NodeType,
typename AccessorT>
665 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
666 template<
typename NodeType,
typename AccessorT>
667 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
671 LeafNodeType* probeLeaf(
const Coord& xyz);
674 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
675 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
679 template<
typename AccessorT>
682 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
683 template<
typename AccessorT>
684 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
685 template<
typename AccessorT>
686 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
695 LeafNodeType* touchLeaf(
const Coord& xyz);
699 template<
typename AccessorT>
700 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
703 template<
typename ArrayT>
726 void getNodes(ArrayT& array);
727 template<
typename ArrayT>
728 void getNodes(ArrayT& array)
const;
754 template<
typename ArrayT>
755 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
759 void resetBackground(
const ValueType& oldBackground,
const ValueType& newBackground);
763 template<
typename OtherChildNodeType, Index OtherLog2Dim>
800 void setValueMask(
Index n,
bool on) { mValueMask.set(n, mChildMask.isOn(n) ? false : on); }
805 void makeChildNodeEmpty(
Index n,
const ValueType& value);
806 void setChildNode(
Index i, ChildNodeType* child);
807 void resetChildNode(
Index i, ChildNodeType* child);
808 ChildNodeType* unsetChildNode(
Index i,
const ValueType& value);
810 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
811 static inline void doVisit(NodeT&, VisitorOp&);
813 template<
typename NodeT,
typename OtherNodeT,
typename VisitorOp,
814 typename ChildAllIterT,
typename OtherChildAllIterT>
815 static inline void doVisit2Node(NodeT&, OtherNodeT&, VisitorOp&);
817 template<
typename NodeT,
typename VisitorOp,
818 typename ChildAllIterT,
typename OtherChildAllIterT>
819 static inline void doVisit2(NodeT&, OtherChildAllIterT&, VisitorOp&,
bool otherIsLHS);
825 ChildNodeType* getChildNode(
Index n);
826 const ChildNodeType* getChildNode(
Index n)
const;
831 struct VoxelizeActiveTiles;
832 template<
typename OtherInternalNode>
struct DeepCopy;
851 template<
typename ChildT1, Index Dim1,
typename NodeT2>
855 static const bool value =
false;
858 template<
typename ChildT1, Index Dim1,
typename ChildT2>
860 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
868 template<
typename ChildT, Index Log2Dim>
872 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(background);
876 template<
typename ChildT, Index Log2Dim>
879 mOrigin(origin[0] & ~(DIM - 1),
880 origin[1] & ~(DIM - 1),
881 origin[2] & ~(DIM - 1))
888 #if OPENVDB_ABI_VERSION_NUMBER >= 3 891 template<
typename ChildT, Index Log2Dim>
895 : mOrigin(origin[0] & ~(DIM-1), origin[1] & ~(DIM-1), origin[2] & ~(DIM-1))
902 template<
typename ChildT, Index Log2Dim>
903 template<
typename OtherInternalNode>
907 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
911 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
912 if (s->mChildMask.isOff(i)) {
913 t->mNodes[i].setValue(
ValueType(s->mNodes[i].getValue()));
915 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild())));
919 const OtherInternalNode*
s;
923 template<
typename ChildT, Index Log2Dim>
926 mChildMask(other.mChildMask),
927 mValueMask(other.mValueMask),
928 mOrigin(other.mOrigin)
935 template<
typename ChildT, Index Log2Dim>
936 template<
typename OtherChildNodeType>
939 : mChildMask(other.mChildMask)
940 , mValueMask(other.mValueMask)
941 , mOrigin(other.mOrigin)
946 template<
typename ChildT, Index Log2Dim>
947 template<
typename OtherInternalNode>
951 const ValueType& background) : s(source), t(target), b(background) {
952 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
956 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
957 if (s->isChildMaskOn(i)) {
958 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
961 t->mNodes[i].setValue(b);
965 const OtherInternalNode*
s;
970 template<
typename ChildT, Index Log2Dim>
971 template<
typename OtherChildNodeType>
975 mChildMask(other.mChildMask),
976 mValueMask(other.mValueMask),
977 mOrigin(other.mOrigin)
982 template<
typename ChildT, Index Log2Dim>
983 template<
typename OtherInternalNode>
988 : s(source), t(target), offV(offValue), onV(onValue) {
989 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
992 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
993 if (s->isChildMaskOn(i)) {
994 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
997 t->mNodes[i].setValue(s->isValueMaskOn(i) ? onV : offV);
1001 const OtherInternalNode*
s;
1006 template<
typename ChildT, Index Log2Dim>
1007 template<
typename OtherChildNodeType>
1012 mChildMask(other.mChildMask),
1013 mValueMask(other.mValueMask),
1014 mOrigin(other.mOrigin)
1020 template<
typename ChildT, Index Log2Dim>
1024 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1025 delete mNodes[iter.pos()].getChild();
1033 template<
typename ChildT, Index Log2Dim>
1039 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1040 sum += iter->leafCount();
1046 template<
typename ChildT, Index Log2Dim>
1052 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1053 sum += iter->nonLeafCount();
1059 template<
typename ChildT, Index Log2Dim>
1063 Index64 sum = ChildT::NUM_VOXELS * mValueMask.countOn();
1064 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1065 sum += iter->onVoxelCount();
1071 template<
typename ChildT, Index Log2Dim>
1075 Index64 sum = ChildT::NUM_VOXELS * (NUM_VALUES-mValueMask.countOn()-mChildMask.countOn());
1076 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1077 sum += iter->offVoxelCount();
1083 template<
typename ChildT, Index Log2Dim>
1088 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
1089 sum += mNodes[iter.pos()].getChild()->onLeafVoxelCount();
1095 template<
typename ChildT, Index Log2Dim>
1100 for (
ChildOnCIter iter = this->beginChildOn(); iter; ++iter) {
1101 sum += mNodes[iter.pos()].getChild()->offLeafVoxelCount();
1106 template<
typename ChildT, Index Log2Dim>
1110 Index64 sum = mValueMask.countOn();
1111 for (
ChildOnCIter iter = this->cbeginChildOn(); LEVEL>1 && iter; ++iter) {
1112 sum += iter->onTileCount();
1117 template<
typename ChildT, Index Log2Dim>
1122 + mValueMask.memUsage() +
sizeof(mOrigin);
1123 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1124 sum += iter->memUsage();
1130 template<
typename ChildT, Index Log2Dim>
1134 if (bbox.
isInside(this->getNodeBoundingBox()))
return;
1137 bbox.
expand(i.getCoord(), ChildT::DIM);
1140 i->evalActiveBoundingBox(bbox, visitVoxels);
1148 template<
typename ChildT, Index Log2Dim>
1154 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1155 const Index i = iter.pos();
1156 ChildT* child = mNodes[i].getChild();
1157 child->prune(tolerance);
1158 if (child->isConstant(value, state, tolerance)) {
1160 mChildMask.setOff(i);
1161 mValueMask.set(i, state);
1162 mNodes[i].setValue(value);
1171 template<
typename ChildT, Index Log2Dim>
1172 template<
typename NodeT>
1176 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1177 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1179 const Index n = this->coordToOffset(xyz);
1180 if (mChildMask.isOff(n))
return nullptr;
1181 ChildT* child = mNodes[n].getChild();
1182 if (std::is_same<NodeT, ChildT>::value) {
1183 mChildMask.setOff(n);
1184 mValueMask.set(n, state);
1185 mNodes[n].setValue(value);
1187 return (std::is_same<NodeT, ChildT>::value)
1188 ?
reinterpret_cast<NodeT*
>(child)
1189 : child->template stealNode<NodeT>(xyz, value, state);
1197 template<
typename ChildT, Index Log2Dim>
1198 template<
typename NodeT>
1202 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1203 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1205 const Index n = this->coordToOffset(xyz);
1206 if (mChildMask.isOff(n))
return nullptr;
1207 ChildT* child = mNodes[n].getChild();
1208 return (std::is_same<NodeT, ChildT>::value)
1209 ?
reinterpret_cast<NodeT*
>(child)
1210 : child->template probeNode<NodeT>(xyz);
1215 template<
typename ChildT, Index Log2Dim>
1216 template<
typename NodeT,
typename AccessorT>
1220 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1221 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1223 const Index n = this->coordToOffset(xyz);
1224 if (mChildMask.isOff(n))
return nullptr;
1225 ChildT* child = mNodes[n].getChild();
1226 acc.insert(xyz, child);
1227 return (std::is_same<NodeT, ChildT>::value)
1228 ?
reinterpret_cast<NodeT*
>(child)
1229 : child->template probeNodeAndCache<NodeT>(xyz, acc);
1234 template<
typename ChildT, Index Log2Dim>
1235 template<
typename NodeT>
1239 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1240 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1242 const Index n = this->coordToOffset(xyz);
1243 if (mChildMask.isOff(n))
return nullptr;
1244 const ChildT* child = mNodes[n].getChild();
1245 return (std::is_same<NodeT, ChildT>::value)
1246 ?
reinterpret_cast<const NodeT*
>(child)
1247 : child->template probeConstNode<NodeT>(xyz);
1252 template<
typename ChildT, Index Log2Dim>
1253 template<
typename NodeT,
typename AccessorT>
1257 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1258 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1260 const Index n = this->coordToOffset(xyz);
1261 if (mChildMask.isOff(n))
return nullptr;
1262 const ChildT* child = mNodes[n].getChild();
1263 acc.insert(xyz, child);
1264 return (std::is_same<NodeT, ChildT>::value)
1265 ?
reinterpret_cast<const NodeT*
>(child)
1266 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
1274 template<
typename ChildT, Index Log2Dim>
1275 inline typename ChildT::LeafNodeType*
1278 return this->
template probeNode<LeafNodeType>(xyz);
1282 template<
typename ChildT, Index Log2Dim>
1283 template<
typename AccessorT>
1284 inline typename ChildT::LeafNodeType*
1287 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
1291 template<
typename ChildT, Index Log2Dim>
1292 template<
typename AccessorT>
1293 inline const typename ChildT::LeafNodeType*
1296 return this->probeConstLeafAndCache(xyz, acc);
1300 template<
typename ChildT, Index Log2Dim>
1301 inline const typename ChildT::LeafNodeType*
1304 return this->
template probeConstNode<LeafNodeType>(xyz);
1308 template<
typename ChildT, Index Log2Dim>
1309 template<
typename AccessorT>
1310 inline const typename ChildT::LeafNodeType*
1313 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
1320 template<
typename ChildT, Index Log2Dim>
1324 assert(leaf !=
nullptr);
1325 const Coord& xyz = leaf->origin();
1326 const Index n = this->coordToOffset(xyz);
1327 ChildT* child =
nullptr;
1328 if (mChildMask.isOff(n)) {
1329 if (ChildT::LEVEL>0) {
1330 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1332 child =
reinterpret_cast<ChildT*
>(leaf);
1334 this->setChildNode(n, child);
1336 if (ChildT::LEVEL>0) {
1337 child = mNodes[n].getChild();
1339 delete mNodes[n].getChild();
1340 child =
reinterpret_cast<ChildT*
>(leaf);
1341 mNodes[n].setChild(child);
1344 child->addLeaf(leaf);
1348 template<
typename ChildT, Index Log2Dim>
1349 template<
typename AccessorT>
1353 assert(leaf !=
nullptr);
1354 const Coord& xyz = leaf->origin();
1355 const Index n = this->coordToOffset(xyz);
1356 ChildT* child =
nullptr;
1357 if (mChildMask.isOff(n)) {
1358 if (ChildT::LEVEL>0) {
1359 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1360 acc.insert(xyz, child);
1362 child =
reinterpret_cast<ChildT*
>(leaf);
1364 this->setChildNode(n, child);
1366 if (ChildT::LEVEL>0) {
1367 child = mNodes[n].getChild();
1368 acc.insert(xyz, child);
1370 delete mNodes[n].getChild();
1371 child =
reinterpret_cast<ChildT*
>(leaf);
1372 mNodes[n].setChild(child);
1375 child->addLeafAndCache(leaf, acc);
1382 template<
typename ChildT, Index Log2Dim>
1386 assert(n < NUM_VALUES);
1387 this->makeChildNodeEmpty(n, value);
1388 mValueMask.set(n, state);
1392 template<
typename ChildT, Index Log2Dim>
1397 if (LEVEL >= level) {
1398 const Index n = this->coordToOffset(xyz);
1399 if (mChildMask.isOff(n)) {
1400 if (LEVEL > level) {
1401 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1402 this->setChildNode(n, child);
1403 child->addTile(level, xyz, value, state);
1405 mValueMask.set(n, state);
1406 mNodes[n].setValue(value);
1409 ChildT* child = mNodes[n].getChild();
1410 if (LEVEL > level) {
1411 child->addTile(level, xyz, value, state);
1414 mChildMask.setOff(n);
1415 mValueMask.set(n, state);
1416 mNodes[n].setValue(value);
1423 template<
typename ChildT, Index Log2Dim>
1424 template<
typename AccessorT>
1427 const ValueType& value,
bool state, AccessorT& acc)
1429 if (LEVEL >= level) {
1430 const Index n = this->coordToOffset(xyz);
1431 if (mChildMask.isOff(n)) {
1432 if (LEVEL > level) {
1433 ChildT* child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1434 this->setChildNode(n, child);
1435 acc.insert(xyz, child);
1436 child->addTileAndCache(level, xyz, value, state, acc);
1438 mValueMask.set(n, state);
1439 mNodes[n].setValue(value);
1442 ChildT* child = mNodes[n].getChild();
1443 if (LEVEL > level) {
1444 acc.insert(xyz, child);
1445 child->addTileAndCache(level, xyz, value, state, acc);
1448 mChildMask.setOff(n);
1449 mValueMask.set(n, state);
1450 mNodes[n].setValue(value);
1460 template<
typename ChildT, Index Log2Dim>
1461 inline typename ChildT::LeafNodeType*
1464 const Index n = this->coordToOffset(xyz);
1465 ChildT* child =
nullptr;
1466 if (mChildMask.isOff(n)) {
1467 child =
new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
1468 this->setChildNode(n, child);
1470 child = mNodes[n].getChild();
1472 return child->touchLeaf(xyz);
1476 template<
typename ChildT, Index Log2Dim>
1477 template<
typename AccessorT>
1478 inline typename ChildT::LeafNodeType*
1481 const Index n = this->coordToOffset(xyz);
1482 if (mChildMask.isOff(n)) {
1483 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), mValueMask.isOn(n)));
1485 acc.insert(xyz, mNodes[n].getChild());
1486 return mNodes[n].getChild()->touchLeafAndCache(xyz, acc);
1493 template<
typename ChildT, Index Log2Dim>
1498 if (!mChildMask.isOff() || !mValueMask.isConstant(state))
return false;
1500 firstValue = mNodes[0].getValue();
1501 for (
Index i = 1; i < NUM_VALUES; ++i) {
1513 template<
typename ChildT, Index Log2Dim>
1521 if (!mChildMask.isOff() || !mValueMask.isConstant(state))
return false;
1522 minValue = maxValue = mNodes[0].getValue();
1523 for (
Index i = 1; i < NUM_VALUES; ++i) {
1524 const ValueType& v = mNodes[i].getValue();
1526 if ((maxValue - v) > tolerance)
return false;
1528 }
else if (v > maxValue) {
1529 if ((v - minValue) > tolerance)
return false;
1540 template<
typename ChildT, Index Log2Dim>
1545 const bool anyActiveTiles = !mValueMask.isOff();
1546 if (LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1547 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
1548 if (iter->hasActiveTiles())
return true;
1555 template<
typename ChildT, Index Log2Dim>
1559 const Index n = this->coordToOffset(xyz);
1560 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1561 return mNodes[n].getChild()->isValueOn(xyz);
1564 template<
typename ChildT, Index Log2Dim>
1565 template<
typename AccessorT>
1569 const Index n = this->coordToOffset(xyz);
1570 if (this->isChildMaskOff(n))
return this->isValueMaskOn(n);
1571 acc.insert(xyz, mNodes[n].getChild());
1572 return mNodes[n].getChild()->isValueOnAndCache(xyz, acc);
1576 template<
typename ChildT, Index Log2Dim>
1577 inline const typename ChildT::ValueType&
1580 const Index n = this->coordToOffset(xyz);
1581 return this->isChildMaskOff(n) ? mNodes[n].getValue()
1582 : mNodes[n].getChild()->getValue(xyz);
1585 template<
typename ChildT, Index Log2Dim>
1586 template<
typename AccessorT>
1587 inline const typename ChildT::ValueType&
1590 const Index n = this->coordToOffset(xyz);
1591 if (this->isChildMaskOn(n)) {
1592 acc.insert(xyz, mNodes[n].getChild());
1593 return mNodes[n].getChild()->getValueAndCache(xyz, acc);
1595 return mNodes[n].getValue();
1599 template<
typename ChildT, Index Log2Dim>
1603 const Index n = this->coordToOffset(xyz);
1604 return this->isChildMaskOff(n) ? LEVEL : mNodes[n].getChild()->getValueLevel(xyz);
1607 template<
typename ChildT, Index Log2Dim>
1608 template<
typename AccessorT>
1612 const Index n = this->coordToOffset(xyz);
1613 if (this->isChildMaskOn(n)) {
1614 acc.insert(xyz, mNodes[n].getChild());
1615 return mNodes[n].getChild()->getValueLevelAndCache(xyz, acc);
1621 template<
typename ChildT, Index Log2Dim>
1625 const Index n = this->coordToOffset(xyz);
1626 if (this->isChildMaskOff(n)) {
1627 value = mNodes[n].getValue();
1628 return this->isValueMaskOn(n);
1630 return mNodes[n].getChild()->probeValue(xyz, value);
1633 template<
typename ChildT, Index Log2Dim>
1634 template<
typename AccessorT>
1639 const Index n = this->coordToOffset(xyz);
1640 if (this->isChildMaskOn(n)) {
1641 acc.insert(xyz, mNodes[n].getChild());
1642 return mNodes[n].getChild()->probeValueAndCache(xyz, value, acc);
1644 value = mNodes[n].getValue();
1645 return this->isValueMaskOn(n);
1649 template<
typename ChildT, Index Log2Dim>
1653 const Index n = this->coordToOffset(xyz);
1654 bool hasChild = this->isChildMaskOn(n);
1655 if (!hasChild && this->isValueMaskOn(n)) {
1659 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
true));
1661 if (hasChild) mNodes[n].getChild()->setValueOff(xyz);
1665 template<
typename ChildT, Index Log2Dim>
1669 const Index n = this->coordToOffset(xyz);
1670 bool hasChild = this->isChildMaskOn(n);
1671 if (!hasChild && !this->isValueMaskOn(n)) {
1675 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(),
false));
1677 if (hasChild) mNodes[n].getChild()->setValueOn(xyz);
1681 template<
typename ChildT, Index Log2Dim>
1686 bool hasChild = this->isChildMaskOn(n);
1688 const bool active = this->isValueMaskOn(n);
1694 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1697 if (hasChild) mNodes[n].getChild()->setValueOff(xyz, value);
1700 template<
typename ChildT, Index Log2Dim>
1701 template<
typename AccessorT>
1707 bool hasChild = this->isChildMaskOn(n);
1709 const bool active = this->isValueMaskOn(n);
1715 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1719 ChildT* child = mNodes[n].getChild();
1720 acc.insert(xyz, child);
1721 child->setValueOffAndCache(xyz, value, acc);
1726 template<
typename ChildT, Index Log2Dim>
1730 const Index n = this->coordToOffset(xyz);
1731 bool hasChild = this->isChildMaskOn(n);
1733 const bool active = this->isValueMaskOn(n);
1739 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1742 if (hasChild) mNodes[n].getChild()->setValueOn(xyz, value);
1745 template<
typename ChildT, Index Log2Dim>
1746 template<
typename AccessorT>
1751 const Index n = this->coordToOffset(xyz);
1752 bool hasChild = this->isChildMaskOn(n);
1754 const bool active = this->isValueMaskOn(n);
1760 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1764 acc.insert(xyz, mNodes[n].getChild());
1765 mNodes[n].getChild()->setValueAndCache(xyz, value, acc);
1770 template<
typename ChildT, Index Log2Dim>
1774 const Index n = this->coordToOffset(xyz);
1775 bool hasChild = this->isChildMaskOn(n);
1779 const bool active = this->isValueMaskOn(n);
1781 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1783 if (hasChild) mNodes[n].getChild()->setValueOnly(xyz, value);
1786 template<
typename ChildT, Index Log2Dim>
1787 template<
typename AccessorT>
1792 const Index n = this->coordToOffset(xyz);
1793 bool hasChild = this->isChildMaskOn(n);
1797 const bool active = this->isValueMaskOn(n);
1799 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1802 acc.insert(xyz, mNodes[n].getChild());
1803 mNodes[n].getChild()->setValueOnlyAndCache(xyz, value, acc);
1808 template<
typename ChildT, Index Log2Dim>
1812 const Index n = this->coordToOffset(xyz);
1813 bool hasChild = this->isChildMaskOn(n);
1815 if (on != this->isValueMaskOn(n)) {
1820 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1823 if (hasChild) mNodes[n].getChild()->setActiveState(xyz, on);
1826 template<
typename ChildT, Index Log2Dim>
1827 template<
typename AccessorT>
1831 const Index n = this->coordToOffset(xyz);
1832 bool hasChild = this->isChildMaskOn(n);
1834 if (on != this->isValueMaskOn(n)) {
1839 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), !on));
1843 ChildT* child = mNodes[n].getChild();
1844 acc.insert(xyz, child);
1845 child->setActiveStateAndCache(xyz, on, acc);
1850 template<
typename ChildT, Index Log2Dim>
1854 mValueMask = !mChildMask;
1855 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
1856 mNodes[iter.pos()].getChild()->setValuesOn();
1861 template<
typename ChildT, Index Log2Dim>
1862 template<
typename ModifyOp>
1867 bool hasChild = this->isChildMaskOn(n);
1871 const bool active = this->isValueMaskOn(n);
1872 bool createChild = !active;
1876 const ValueType& tileVal = mNodes[n].getValue();
1883 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1886 if (hasChild) mNodes[n].getChild()->modifyValue(xyz, op);
1889 template<
typename ChildT, Index Log2Dim>
1890 template<
typename ModifyOp,
typename AccessorT>
1896 bool hasChild = this->isChildMaskOn(n);
1900 const bool active = this->isValueMaskOn(n);
1901 bool createChild = !active;
1905 const ValueType& tileVal = mNodes[n].getValue();
1912 this->setChildNode(n,
new ChildNodeType(xyz, mNodes[n].getValue(), active));
1917 acc.insert(xyz, child);
1918 child->modifyValueAndCache(xyz, op, acc);
1923 template<
typename ChildT, Index Log2Dim>
1924 template<
typename ModifyOp>
1929 bool hasChild = this->isChildMaskOn(n);
1931 const bool tileState = this->isValueMaskOn(n);
1932 const ValueType& tileVal = mNodes[n].getValue();
1933 bool modifiedState = !tileState;
1935 op(modifiedVal, modifiedState);
1940 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1943 if (hasChild) mNodes[n].getChild()->modifyValueAndActiveState(xyz, op);
1946 template<
typename ChildT, Index Log2Dim>
1947 template<
typename ModifyOp,
typename AccessorT>
1950 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1953 bool hasChild = this->isChildMaskOn(n);
1955 const bool tileState = this->isValueMaskOn(n);
1956 const ValueType& tileVal = mNodes[n].getValue();
1957 bool modifiedState = !tileState;
1959 op(modifiedVal, modifiedState);
1964 this->setChildNode(n,
new ChildNodeType(xyz, tileVal, tileState));
1969 acc.insert(xyz, child);
1970 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1978 template<
typename ChildT, Index Log2Dim>
1982 CoordBBox nodeBBox = this->getNodeBoundingBox();
1985 this->fill(nodeBBox, background,
false);
1986 }
else if (clipBBox.
isInside(nodeBBox)) {
1995 for (
Index pos = 0; pos < NUM_VALUES; ++pos) {
1996 const Coord xyz = this->offsetToGlobalCoord(pos);
2001 this->makeChildNodeEmpty(pos, background);
2002 mValueMask.setOff(pos);
2003 }
else if (!clipBBox.
isInside(tileBBox)) {
2006 if (this->isChildMaskOn(pos)) {
2007 mNodes[pos].getChild()->clip(clipBBox, background);
2011 tileBBox.intersect(clipBBox);
2012 const ValueType val = mNodes[pos].getValue();
2013 const bool on = this->isValueMaskOn(pos);
2014 mNodes[pos].setValue(background);
2015 mValueMask.setOff(pos);
2016 this->fill(tileBBox, val, on);
2028 template<
typename ChildT, Index Log2Dim>
2032 auto clippedBBox = this->getNodeBoundingBox();
2033 clippedBBox.intersect(bbox);
2034 if (!clippedBBox)
return;
2038 Coord xyz, tileMin, tileMax;
2039 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2041 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2043 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2047 const Index n = this->coordToOffset(xyz);
2048 tileMin = this->offsetToGlobalCoord(n);
2049 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2055 ChildT* child =
nullptr;
2056 if (this->isChildMaskOff(n)) {
2059 child =
new ChildT{xyz, mNodes[n].getValue(), this->isValueMaskOn(n)};
2060 this->setChildNode(n, child);
2062 child = mNodes[n].getChild();
2068 child->fill(
CoordBBox(xyz, tmp), value, active);
2075 this->makeChildNodeEmpty(n, value);
2076 mValueMask.set(n, active);
2084 template<
typename ChildT, Index Log2Dim>
2088 auto clippedBBox = this->getNodeBoundingBox();
2089 clippedBBox.intersect(bbox);
2090 if (!clippedBBox)
return;
2094 Coord xyz, tileMin, tileMax;
2095 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2097 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2099 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2103 const auto n = this->coordToOffset(xyz);
2106 ChildT* child =
nullptr;
2107 if (this->isChildMaskOn(n)) {
2108 child = mNodes[n].getChild();
2112 child =
new ChildT{xyz, mNodes[n].getValue(), this->isValueMaskOn(n)};
2113 this->setChildNode(n, child);
2117 tileMin = this->offsetToGlobalCoord(n);
2118 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2121 child->denseFill(
CoordBBox{xyz, clippedBBox.
max()}, value, active);
2131 template<
typename ChildT, Index Log2Dim>
2132 template<
typename DenseT>
2136 using DenseValueType =
typename DenseT::ValueType;
2138 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2139 const Coord&
min = dense.bbox().min();
2140 for (
Coord xyz = bbox.
min(),
max; xyz[0] <= bbox.
max()[0]; xyz[0] =
max[0] + 1) {
2141 for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] =
max[1] + 1) {
2142 for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] =
max[2] + 1) {
2143 const Index n = this->coordToOffset(xyz);
2145 max = this->offsetToGlobalCoord(n).offsetBy(ChildT::DIM-1);
2150 if (this->isChildMaskOn(n)) {
2151 mNodes[n].getChild()->copyToDense(sub, dense);
2153 const ValueType value = mNodes[n].getValue();
2155 DenseValueType* a0 = dense.data() + zStride*sub.
min()[2];
2156 for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
2157 DenseValueType* a1 = a0 + x*xStride;
2158 for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
2159 DenseValueType* a2 = a1 + y*yStride;
2161 z < ez; ++z, a2 += zStride)
2163 *a2 = DenseValueType(value);
2177 template<
typename ChildT, Index Log2Dim>
2181 mChildMask.save(os);
2182 mValueMask.save(os);
2186 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[NUM_VALUES]);
2188 const ValueType zero = zeroVal<ValueType>();
2189 for (
Index i = 0; i < NUM_VALUES; ++i) {
2190 values[i] = (mChildMask.isOff(i) ? mNodes[i].getValue() : zero);
2196 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
2197 iter->writeTopology(os, toHalf);
2202 template<
typename ChildT, Index Log2Dim>
2206 #if OPENVDB_ABI_VERSION_NUMBER >= 3 2211 mChildMask.load(is);
2212 mValueMask.load(is);
2215 for (
Index i = 0; i < NUM_VALUES; ++i) {
2216 if (this->isChildMaskOn(i)) {
2218 #if OPENVDB_ABI_VERSION_NUMBER <= 2 2219 new ChildNodeType(offsetToGlobalCoord(i), zeroVal<ValueType>());
2223 mNodes[i].setChild(child);
2224 child->readTopology(is);
2227 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2228 mNodes[i].setValue(value);
2232 const bool oldVersion =
2234 const Index numValues = (oldVersion ? mChildMask.countOff() : NUM_VALUES);
2238 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[numValues]);
2245 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
2246 mNodes[iter.pos()].setValue(values[n++]);
2248 assert(n == numValues);
2250 for (
ValueAllIter iter = this->beginValueAll(); iter; ++iter) {
2251 mNodes[iter.pos()].setValue(values[iter.pos()]);
2256 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
2257 #if OPENVDB_ABI_VERSION_NUMBER <= 2 2262 mNodes[iter.pos()].setChild(child);
2263 child->readTopology(is, fromHalf);
2272 template<
typename ChildT, Index Log2Dim>
2273 inline const typename ChildT::ValueType&
2276 return (this->isChildMaskOn(0) ? mNodes[0].getChild()->getFirstValue() : mNodes[0].getValue());
2280 template<
typename ChildT, Index Log2Dim>
2281 inline const typename ChildT::ValueType&
2284 const Index n = NUM_VALUES - 1;
2285 return (this->isChildMaskOn(n) ? mNodes[n].getChild()->getLastValue() : mNodes[n].getValue());
2292 template<
typename ChildT, Index Log2Dim>
2296 for (
Index i = 0; i < NUM_VALUES; ++i) {
2297 if (this->isChildMaskOn(i)) {
2298 mNodes[i].getChild()->negate();
2310 template<
typename ChildT, Index Log2Dim>
2315 tbb::parallel_for(tbb::blocked_range<Index>(0, NUM_VALUES), *
this);
2322 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2323 if (mNode->mChildMask.isOn(i)) {
2324 mNode->mNodes[i].getChild()->voxelizeActiveTiles(
true);
2325 }
else if (mNode->mValueMask.isOn(i)) {
2326 const Coord &ijk = mNode->offsetToGlobalCoord(i);
2328 child->voxelizeActiveTiles(
true);
2329 mNode->mNodes[i].setChild(child);
2336 template<
typename ChildT, Index Log2Dim>
2343 for (
ValueOnIter iter = this->beginValueOn(); iter; ++iter) {
2344 this->setChildNode(iter.pos(),
2347 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter)
2348 iter->voxelizeActiveTiles(
false);
2356 template<
typename ChildT, Index Log2Dim>
2357 template<MergePolicy Policy>
2370 const Index n = iter.pos();
2371 if (mChildMask.isOn(n)) {
2373 mNodes[n].getChild()->template merge<MERGE_ACTIVE_STATES>(*iter,
2374 background, otherBackground);
2375 }
else if (mValueMask.isOff(n)) {
2382 child->resetBackground(otherBackground, background);
2383 this->setChildNode(n, child);
2389 const Index n = iter.pos();
2390 if (mValueMask.isOff(n)) {
2392 this->makeChildNodeEmpty(n, iter.getValue());
2393 mValueMask.setOn(n);
2402 const Index n = iter.pos();
2403 if (mChildMask.isOn(n)) {
2405 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2413 child->resetBackground(otherBackground, background);
2414 this->setChildNode(n, child);
2424 const Index n = iter.pos();
2425 if (mChildMask.isOn(n)) {
2427 mNodes[n].getChild()->template merge<Policy>(*iter, background, otherBackground);
2434 child->resetBackground(otherBackground, background);
2435 if (mValueMask.isOn(n)) {
2437 child->template merge<Policy>(mNodes[n].getValue(),
true);
2438 mValueMask.setOff(n);
2440 mChildMask.setOn(n);
2441 mNodes[n].setChild(child);
2447 const Index n = iter.pos();
2448 if (mChildMask.isOn(n)) {
2450 mNodes[n].getChild()->template merge<Policy>(iter.getValue(),
true);
2451 }
else if (mValueMask.isOff(n)) {
2453 mNodes[n].setValue(iter.getValue());
2454 mValueMask.setOn(n);
2465 template<
typename ChildT, Index Log2Dim>
2466 template<MergePolicy Policy>
2475 if (!tileActive)
return;
2478 for (
ValueOffIter iter = this->beginValueOff(); iter; ++iter) {
2479 const Index n = iter.pos();
2480 if (mChildMask.isOn(n)) {
2482 mNodes[n].getChild()->template merge<Policy>(tileValue,
true);
2485 iter.setValue(tileValue);
2486 mValueMask.setOn(n);
2496 template<
typename ChildT, Index Log2Dim>
2497 template<
typename OtherInternalNode>
2502 { tV = (tV | sV) & ~tC; }
2506 tbb::parallel_for(tbb::blocked_range<Index>(0, NUM_VALUES), *
this);
2509 t->mChildMask |= s->mChildMask;
2511 t->mValueMask.foreach(s->mValueMask, t->mChildMask, op);
2512 assert((t->mValueMask & t->mChildMask).isOff());
2515 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2516 if (s->mChildMask.isOn(i)) {
2517 const typename OtherInternalNode::ChildNodeType& other = *(s->mNodes[i].getChild());
2518 if (t->mChildMask.isOn(i)) {
2519 t->mNodes[i].getChild()->topologyUnion(other);
2521 ChildT* child =
new ChildT(other, t->mNodes[i].getValue(),
TopologyCopy());
2522 if (t->mValueMask.isOn(i)) child->setValuesOn();
2523 t->mNodes[i].setChild(child);
2525 }
else if (s->mValueMask.isOn(i) && t->mChildMask.isOn(i)) {
2526 t->mNodes[i].getChild()->setValuesOn();
2530 const OtherInternalNode*
s;
2534 template<
typename ChildT, Index Log2Dim>
2535 template<
typename OtherChildT>
2542 template<
typename ChildT, Index Log2Dim>
2543 template<
typename OtherInternalNode>
2544 struct InternalNode<ChildT, Log2Dim>::TopologyIntersection
2548 { tC = (tC & (sC | sV)) | (tV & sC); }
2551 const ValueType& background) : s(source), t(target), b(background) {
2553 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2557 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op);
2559 t->mValueMask &= s->mValueMask;
2560 assert((t->mValueMask & t->mChildMask).isOff());
2563 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2564 if (t->mChildMask.isOn(i)) {
2565 ChildT* child = t->mNodes[i].getChild();
2566 if (s->mChildMask.isOn(i)) {
2567 child->topologyIntersection(*(s->mNodes[i].getChild()), b);
2568 }
else if (s->mValueMask.isOff(i)) {
2570 t->mNodes[i].setValue(b);
2572 }
else if (t->mValueMask.isOn(i) && s->mChildMask.isOn(i)) {
2573 t->mNodes[i].setChild(
new ChildT(*(s->mNodes[i].getChild()),
2578 const OtherInternalNode*
s;
2583 template<
typename ChildT, Index Log2Dim>
2584 template<
typename OtherChildT>
2592 template<
typename ChildT, Index Log2Dim>
2593 template<
typename OtherInternalNode>
2594 struct InternalNode<ChildT, Log2Dim>::TopologyDifference
2598 { tC = (tC & (sC | ~sV)) | (tV & sC); }
2601 { tV &= ~((tC & sV) | (sC | sV)); }
2604 const ValueType& background) : s(source), t(target), b(background) {
2606 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2611 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op1);
2614 t->mValueMask.foreach(t->mChildMask, s->mValueMask, oldChildMask, op2);
2615 assert((t->mValueMask & t->mChildMask).isOff());
2618 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2619 if (t->mChildMask.isOn(i)) {
2620 ChildT* child = t->mNodes[i].getChild();
2621 if (s->mChildMask.isOn(i)) {
2622 child->topologyDifference(*(s->mNodes[i].getChild()), b);
2623 }
else if (s->mValueMask.isOn(i)) {
2625 t->mNodes[i].setValue(b);
2627 }
else if (t->mValueMask.isOn(i)) {
2628 if (s->mChildMask.isOn(i)) {
2629 const typename OtherInternalNode::ChildNodeType& other =
2630 *(s->mNodes[i].getChild());
2631 ChildT* child =
new ChildT(other.origin(), t->mNodes[i].getValue(),
true);
2632 child->topologyDifference(other, b);
2633 t->mNodes[i].setChild(child);
2638 const OtherInternalNode*
s;
2643 template<
typename ChildT, Index Log2Dim>
2644 template<
typename OtherChildT>
2656 template<
typename ChildT, Index Log2Dim>
2657 template<
typename CombineOp>
2661 const ValueType zero = zeroVal<ValueType>();
2665 for (
Index i = 0; i < NUM_VALUES; ++i) {
2669 op(args.setARef(mNodes[i].getValue())
2670 .setAIsActive(isValueMaskOn(i))
2673 mNodes[i].setValue(args.result());
2674 mValueMask.set(i, args.resultIsActive());
2682 }
else if (this->isChildMaskOff(i) && other.
isChildMaskOn(i)) {
2691 child->combine(mNodes[i].getValue(), isValueMaskOn(i), swappedOp);
2696 this->setChildNode(i, child);
2702 *child = mNodes[i].getChild(),
2706 if (child && otherChild) {
2707 child->combine(*otherChild, op);
2714 template<
typename ChildT, Index Log2Dim>
2715 template<
typename CombineOp>
2721 for (
Index i = 0; i < NUM_VALUES; ++i) {
2722 if (this->isChildMaskOff(i)) {
2724 op(args.
setARef(mNodes[i].getValue())
2725 .setAIsActive(isValueMaskOn(i))
2727 .setBIsActive(valueIsActive));
2728 mNodes[i].setValue(args.
result());
2734 if (child) child->combine(value, valueIsActive, op);
2743 template<
typename ChildT, Index Log2Dim>
2744 template<
typename CombineOp,
typename OtherNodeType>
2751 for (
Index i = 0; i < NUM_VALUES; ++i) {
2755 .setBRef(other1.mNodes[i].getValue())
2756 .setBIsActive(other1.isValueMaskOn(i)));
2758 this->makeChildNodeEmpty(i, args.
result());
2761 if (this->isChildMaskOff(i)) {
2765 : other1.mNodes[i].getChild()->origin();
2766 this->setChildNode(i,
new ChildNodeType(childOrigin, mNodes[i].getValue()));
2774 }
else if (other1.isChildMaskOff(i)) {
2778 other1.mNodes[i].getValue(), other1.isValueMaskOn(i), op);
2783 *other1.mNodes[i].getChild(), op);
2790 template<
typename ChildT, Index Log2Dim>
2791 template<
typename CombineOp,
typename OtherNodeType>
2794 bool valueIsActive, CombineOp& op)
2798 for (
Index i = 0; i < NUM_VALUES; ++i) {
2799 if (other.isChildMaskOff(i)) {
2801 .setAIsActive(valueIsActive)
2802 .setBRef(other.mNodes[i].getValue())
2803 .setBIsActive(other.isValueMaskOn(i)));
2805 this->makeChildNodeEmpty(i, args.
result());
2808 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[i].getChild();
2810 if (this->isChildMaskOff(i)) {
2817 mNodes[i].getChild()->combine2(value, *otherChild, valueIsActive, op);
2823 template<
typename ChildT, Index Log2Dim>
2824 template<
typename CombineOp,
typename OtherValueType>
2827 bool valueIsActive, CombineOp& op)
2831 for (
Index i = 0; i < NUM_VALUES; ++i) {
2836 .setBIsActive(valueIsActive));
2838 this->makeChildNodeEmpty(i, args.
result());
2843 if (this->isChildMaskOff(i)) {
2845 this->setChildNode(i,
2846 new ChildNodeType(otherChild->origin(), mNodes[i].getValue()));
2850 mNodes[i].getChild()->combine2(*otherChild, value, valueIsActive, op);
2859 template<
typename ChildT, Index Log2Dim>
2860 template<
typename BBoxOp>
2871 if (op.template descent<LEVEL>()) {
2872 for (
ChildOnCIter i = this->cbeginChildOn(); i; ++i) i->visitActiveBBox(op);
2876 op.operator()<LEVEL>(i->getNodeBoundingBox());
2878 op.template operator()<LEVEL>(i->getNodeBoundingBox());
2885 template<
typename ChildT, Index Log2Dim>
2886 template<
typename VisitorOp>
2890 doVisit<InternalNode, VisitorOp, ChildAllIter>(*
this, op);
2894 template<
typename ChildT, Index Log2Dim>
2895 template<
typename VisitorOp>
2899 doVisit<const InternalNode, VisitorOp, ChildAllCIter>(*
this, op);
2903 template<
typename ChildT, Index Log2Dim>
2904 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
2908 typename NodeT::ValueType val;
2909 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2910 if (op(iter))
continue;
2911 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2921 template<
typename ChildT, Index Log2Dim>
2922 template<
typename OtherNodeType,
typename VisitorOp>
2927 typename OtherNodeType::ChildAllIter>(*
this, other, op);
2931 template<
typename ChildT, Index Log2Dim>
2932 template<
typename OtherNodeType,
typename VisitorOp>
2937 typename OtherNodeType::ChildAllCIter>(*
this, other, op);
2941 template<
typename ChildT, Index Log2Dim>
2944 typename OtherNodeT,
2946 typename ChildAllIterT,
2947 typename OtherChildAllIterT>
2952 static_assert(OtherNodeT::NUM_VALUES == NodeT::NUM_VALUES,
2953 "visit2() requires nodes to have the same dimensions");
2954 static_assert(OtherNodeT::LEVEL == NodeT::LEVEL,
2955 "visit2() requires nodes to be at the same tree level");
2957 typename NodeT::ValueType val;
2958 typename OtherNodeT::ValueType otherVal;
2960 ChildAllIterT iter =
self.beginChildAll();
2961 OtherChildAllIterT otherIter = other.beginChildAll();
2963 for ( ; iter && otherIter; ++iter, ++otherIter)
2965 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2967 typename ChildAllIterT::ChildNodeType* child =
2968 (skipBranch & 1U) ?
nullptr : iter.probeChild(val);
2969 typename OtherChildAllIterT::ChildNodeType* otherChild =
2970 (skipBranch & 2U) ?
nullptr : otherIter.probeChild(otherVal);
2972 if (child !=
nullptr && otherChild !=
nullptr) {
2973 child->visit2Node(*otherChild, op);
2974 }
else if (child !=
nullptr) {
2975 child->visit2(otherIter, op);
2976 }
else if (otherChild !=
nullptr) {
2977 otherChild->visit2(iter, op,
true);
2986 template<
typename ChildT, Index Log2Dim>
2987 template<
typename OtherChildAllIterType,
typename VisitorOp>
2990 VisitorOp& op,
bool otherIsLHS)
2992 doVisit2<InternalNode, VisitorOp, ChildAllIter, OtherChildAllIterType>(
2993 *
this, otherIter, op, otherIsLHS);
2997 template<
typename ChildT, Index Log2Dim>
2998 template<
typename OtherChildAllIterType,
typename VisitorOp>
3001 VisitorOp& op,
bool otherIsLHS)
const 3003 doVisit2<const InternalNode, VisitorOp, ChildAllCIter, OtherChildAllIterType>(
3004 *
this, otherIter, op, otherIsLHS);
3008 template<
typename ChildT, Index Log2Dim>
3009 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT,
typename OtherChildAllIterT>
3012 VisitorOp& op,
bool otherIsLHS)
3014 if (!otherIter)
return;
3016 const size_t skipBitMask = (otherIsLHS ? 2U : 1U);
3018 typename NodeT::ValueType val;
3019 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
3020 const size_t skipBranch =
static_cast<size_t>(
3021 otherIsLHS ? op(otherIter, iter) : op(iter, otherIter));
3023 typename ChildAllIterT::ChildNodeType* child =
3024 (skipBranch & skipBitMask) ?
nullptr : iter.probeChild(val);
3026 if (child !=
nullptr) child->visit2(otherIter, op, otherIsLHS);
3034 template<
typename ChildT, Index Log2Dim>
3038 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
3039 iter->writeBuffers(os, toHalf);
3044 template<
typename ChildT, Index Log2Dim>
3048 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
3049 iter->readBuffers(is, fromHalf);
3054 template<
typename ChildT, Index Log2Dim>
3057 const CoordBBox& clipBBox,
bool fromHalf)
3059 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
3064 iter->readBuffers(is, clipBBox, fromHalf);
3068 ValueType background = zeroVal<ValueType>();
3070 background = *
static_cast<const ValueType*
>(bgPtr);
3072 this->
clip(clipBBox, background);
3079 template<
typename ChildT, Index Log2Dim>
3083 dims.push_back(Log2Dim);
3084 ChildNodeType::getNodeLog2Dims(dims);
3088 template<
typename ChildT, Index Log2Dim>
3092 assert(n<(1<<3*Log2Dim));
3093 xyz.
setX(n >> 2*Log2Dim);
3094 n &= ((1<<2*Log2Dim)-1);
3095 xyz.
setY(n >> Log2Dim);
3096 xyz.
setZ(n & ((1<<Log2Dim)-1));
3100 template<
typename ChildT, Index Log2Dim>
3104 return (((xyz[0] & (DIM-1u)) >> ChildNodeType::TOTAL) << 2*Log2Dim)
3105 + (((xyz[1] & (DIM-1u)) >> ChildNodeType::TOTAL) << Log2Dim)
3106 + ((xyz[2] & (DIM-1u)) >> ChildNodeType::TOTAL);
3110 template<
typename ChildT, Index Log2Dim>
3115 this->offsetToLocalCoord(n, local);
3116 local <<= ChildT::TOTAL;
3117 return local + this->origin();
3124 template<
typename ChildT, Index Log2Dim>
3125 template<
typename ArrayT>
3129 using T =
typename ArrayT::value_type;
3130 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3131 using ArrayChildT =
typename std::conditional<
3132 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3133 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
3135 if (std::is_same<T, ArrayChildT*>::value) {
3136 array.push_back(reinterpret_cast<T>(mNodes[iter.pos()].getChild()));
3138 iter->getNodes(array);
3144 template<
typename ChildT, Index Log2Dim>
3145 template<
typename ArrayT>
3149 using T =
typename ArrayT::value_type;
3150 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3151 static_assert(std::is_const<
typename std::remove_pointer<T>::type>::value,
3152 "argument to getNodes() must be an array of const node pointers");
3153 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
3155 if (std::is_same<T, const ChildT*>::value) {
3156 array.push_back(reinterpret_cast<T>(mNodes[iter.pos()].getChild()));
3158 iter->getNodes(array);
3168 template<
typename ChildT, Index Log2Dim>
3169 template<
typename ArrayT>
3173 using T =
typename ArrayT::value_type;
3174 static_assert(std::is_pointer<T>::value,
"argument to stealNodes() must be a pointer array");
3175 using ArrayChildT =
typename std::conditional<
3176 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3178 for (
ChildOnIter iter = this->beginChildOn(); iter; ++iter) {
3179 const Index n = iter.pos();
3180 if (std::is_same<T, ArrayChildT*>::value) {
3181 array.push_back(reinterpret_cast<T>(mNodes[n].getChild()));
3182 mValueMask.set(n, state);
3183 mNodes[n].setValue(value);
3185 iter->stealNodes(array, value, state);
3188 if (std::is_same<T, ArrayChildT*>::value) mChildMask.setOff();
3196 template<
typename ChildT, Index Log2Dim>
3202 for (
Index i = 0; i < NUM_VALUES; ++i) {
3203 if (this->isChildMaskOn(i)) {
3204 mNodes[i].getChild()->resetBackground(oldBackground, newBackground);
3205 }
else if (this->isValueMaskOff(i)) {
3207 mNodes[i].setValue(newBackground);
3215 template<
typename ChildT, Index Log2Dim>
3216 template<
typename OtherChildNodeType, Index OtherLog2Dim>
3221 if (Log2Dim != OtherLog2Dim || mChildMask != other->
mChildMask ||
3222 mValueMask != other->
mValueMask)
return false;
3223 for (
ChildOnCIter iter = this->cbeginChildOn(); iter; ++iter) {
3224 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
3230 template<
typename ChildT, Index Log2Dim>
3235 if (this->isChildMaskOn(i)) {
3236 delete mNodes[i].getChild();
3238 mChildMask.setOn(i);
3239 mValueMask.setOff(i);
3241 mNodes[i].setChild(child);
3244 template<
typename ChildT, Index Log2Dim>
3249 assert(mChildMask.isOff(i));
3250 mChildMask.setOn(i);
3251 mValueMask.setOff(i);
3252 mNodes[i].setChild(child);
3256 template<
typename ChildT, Index Log2Dim>
3260 if (this->isChildMaskOff(i)) {
3261 mNodes[i].setValue(value);
3265 mChildMask.setOff(i);
3266 mNodes[i].setValue(value);
3271 template<
typename ChildT, Index Log2Dim>
3275 delete this->unsetChildNode(n, value);
3278 template<
typename ChildT, Index Log2Dim>
3282 assert(this->isChildMaskOn(n));
3283 return mNodes[n].getChild();
3287 template<
typename ChildT, Index Log2Dim>
3288 inline const ChildT*
3291 assert(this->isChildMaskOn(n));
3292 return mNodes[n].getChild();
3299 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:395
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1748
Definition: InternalNode.h:2547
InternalNode * t
Definition: InternalNode.h:2531
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:3046
InternalNode()
Default constructor.
Definition: InternalNode.h:99
InternalNode * t
Definition: InternalNode.h:2639
const ValueType & b
Definition: InternalNode.h:967
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
VoxelizeActiveTiles(InternalNode &node)
Definition: InternalNode.h:2313
uint32_t Index32
Definition: Types.h:59
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 nullptr.
Definition: InternalNode.h:1302
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: InternalNode.h:1276
ChildAllIter beginChildAll()
Definition: InternalNode.h:261
DeepCopy(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:906
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:3258
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:339
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2514
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:436
~InternalNode()
Definition: InternalNode.h:1022
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:269
typename ChildNodeType::BuildType BuildType
Definition: InternalNode.h:66
const Coord & max() const
Definition: Coord.h:338
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:56
const AValueType & result() const
Get the output value.
Definition: Types.h:428
typename ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:64
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:302
Definition: InternalNode.h:833
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:781
Definition: version.h:220
bool isValueMaskOn() const
Definition: InternalNode.h:782
const ValueType & b
Definition: InternalNode.h:2580
TopologyDifference(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2603
const OtherInternalNode * s
Definition: InternalNode.h:965
ChildOffIter beginChildOff()
Definition: InternalNode.h:260
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
Definition: InternalNode.h:835
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:73
ValueOffIter beginValueOff()
Definition: InternalNode.h:273
void visit(VisitorOp &)
Definition: InternalNode.h:2888
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:2274
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:3218
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:82
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of an Intern...
Definition: InternalNode.h:91
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:422
Definition: InternalNode.h:2501
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2562
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1542
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.
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1557
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:1394
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:188
NodeMaskType mChildMask
Definition: InternalNode.h:841
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:254
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:323
bool isValueMaskOff() const
Definition: InternalNode.h:784
InternalNode * mNode
Definition: InternalNode.h:2333
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition: InternalNode.h:2746
static Index getLevel()
Definition: InternalNode.h:282
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:174
TopologyUnion(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:2504
static void doVisit2(NodeT &, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: InternalNode.h:3011
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1703
const OtherInternalNode * s
Definition: InternalNode.h:2530
Definition: InternalNode.h:153
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:108
void denseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value and ensure that those voxels are a...
Definition: InternalNode.h:2086
ChildOnIter beginChildOn()
Definition: InternalNode.h:259
const OtherInternalNode * s
Definition: InternalNode.h:1001
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:1462
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
Definition: InternalNode.h:56
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2659
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:359
typename NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:148
Index64 Word
Definition: NodeMasks.h:318
Definition: InternalNode.h:834
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:1892
TopologyIntersection(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2550
ChildT * getChild() const
Definition: NodeUnion.h:69
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
const NodeMaskType & getChildMask() const
Definition: InternalNode.h:789
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:1132
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:266
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: InternalNode.h:2030
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:1119
const NodeMaskType & getValueMask() const
Definition: InternalNode.h:788
Definition: NodeMasks.h:241
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:515
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:270
const ValueT & getValue() const
Definition: NodeUnion.h:72
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:231
NodeMaskType getValueOffMask() const
Definition: InternalNode.h:790
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1829
void operator()(W &tV, const W &sV, const W &tC) const
Definition: InternalNode.h:2501
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:1601
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3246
OPENVDB_API const void * getGridBackgroundValuePtr(std::ios_base &)
Return a pointer to the background value of the grid currently being read from or written to the give...
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:1085
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:263
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:517
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1578
const OtherInternalNode * s
Definition: InternalNode.h:2638
ChildIter()
Definition: InternalNode.h:163
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:149
Coord & setY(Int32 y)
Definition: Coord.h:107
Definition: InternalNode.h:181
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:185
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:265
Definition: InternalNode.h:160
const OtherInternalNode * s
Definition: InternalNode.h:919
InternalNode * t
Definition: InternalNode.h:966
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1667
Definition: InternalNode.h:836
bool isEmpty() const
Definition: InternalNode.h:326
InternalNode * t
Definition: InternalNode.h:920
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2179
const OtherInternalNode * s
Definition: InternalNode.h:2578
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
Index32 leafCount() const
Definition: InternalNode.h:1035
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:783
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:416
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1623
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1949
void topologyDifference(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &background)
Difference this node's set of active values with the active values of the other node, whose ValueType may be different. So a resulting voxel will be active only if the original voxel is active in this node and inactive in the other node.
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1651
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1567
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3232
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:1926
const Coord & min() const
Definition: Coord.h:337
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 nullptr.
Index64 onVoxelCount() const
Definition: InternalNode.h:1061
typename NodeMaskType::Word W
Definition: InternalNode.h:2500
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1789
Index32 nonLeafCount() const
Definition: InternalNode.h:1048
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:485
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:1772
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: InternalNode.h:3127
typename NodeMaskType::Word W
Definition: InternalNode.h:2546
NodeMaskType mValueMask
Definition: InternalNode.h:841
void negate()
Change the sign of all the values represented in this node and its child nodes.
Definition: InternalNode.h:2294
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:1810
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:404
_ChildNodeType ChildNodeType
Definition: InternalNode.h:63
Definition: InternalNode.h:832
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:3273
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:213
const ValueType & onV
Definition: InternalNode.h:1003
void topologyUnion(const InternalNode< OtherChildNodeType, Log2Dim > &other)
Union this branch's set of active values with the other branch's active values. The value type of the...
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2597
Int32 z() const
Definition: Coord.h:159
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...
uint64_t Index64
Definition: Types.h:60
bool isChildMaskOff() const
Definition: InternalNode.h:787
Definition: InternalNode.h:837
int32_t Int32
Definition: Types.h:63
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:202
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition: InternalNode.h:3280
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:253
Definition: Exceptions.h:40
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:255
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:235
Definition: InternalNode.h:2597
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:225
InternalNode * t
Definition: InternalNode.h:2579
Index64 offVoxelCount() const
Definition: InternalNode.h:1073
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:3090
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1636
Definition: NodeMasks.h:272
Definition: InternalNode.h:152
void translate(const Coord &t)
Definition: Coord.h:462
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
static void doVisit2Node(NodeT &, OtherNodeT &, VisitorOp &)
Definition: InternalNode.h:2949
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:118
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:383
Int32 y() const
Definition: Coord.h:158
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:257
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:164
TopologyCopy1(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:950
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:955
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:258
Definition: NodeMasks.h:210
Library and file format version numbers.
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:141
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:256
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2547
DenseIter()
Definition: InternalNode.h:209
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2320
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:205
void setValue(const ValueT &val)
Definition: NodeUnion.h:74
Coord & setZ(Int32 z)
Definition: Coord.h:108
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:3198
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:462
static void doVisit(NodeT &, VisitorOp &)
Definition: InternalNode.h:2906
ValueOnIter beginValueOn()
Definition: InternalNode.h:271
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:329
Index64 onTileCount() const
Definition: InternalNode.h:1108
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:1097
static Index dim()
Definition: InternalNode.h:279
Definition: InternalNode.h:152
const NodeType * probeConstNodeAndCache(const Coord &xyz, AccessorT &) const
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1852
bool resultIsActive() const
Definition: Types.h:447
typename BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:207
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2338
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:191
Coord & setX(Int32 x)
Definition: Coord.h:106
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:1864
void operator()(W &tV, const W &sC, const W &sV, const W &tC) const
Definition: InternalNode.h:2600
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
ValueAllIter beginValueAll()
Definition: InternalNode.h:274
const UnionType * getTable() const
Definition: InternalNode.h:797
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:910
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:843
Definition: InternalNode.h:60
static const Index NUM_VALUES
Definition: InternalNode.h:74
TopologyCopy2(const OtherInternalNode *source, InternalNode *target, const ValueType &offValue, const ValueType &onValue)
Definition: InternalNode.h:986
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:785
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:358
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:2359
Definition: InternalNode.h:2600
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1495
Definition: InternalNode.h:2311
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Steals all nodes of a certain type from the tree and adds them to a container with the following API:...
Definition: InternalNode.h:3171
ValueIter()
Definition: InternalNode.h:184
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:300
static Index getChildDim()
Definition: InternalNode.h:289
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:786
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:210
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:991
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:1150
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2204
Index32 Index
Definition: Types.h:61
static void getNodeLog2Dims(std::vector< Index > &dims)
Populated an stil::vector with the dimension of all the nodes in the branch starting with this node...
Definition: InternalNode.h:3081
InternalNode * t
Definition: InternalNode.h:1002
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:454
typename std::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:211
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:1426
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:837
void visit2Node(OtherNodeType &other, VisitorOp &)
Definition: InternalNode.h:2924
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:3102
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:1322
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:354
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:267
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:1610
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:195
Definition: InternalNode.h:153
Level getLevel()
Return the current logging level.
Definition: logging.h:165
typename NodeMaskType::Word W
Definition: InternalNode.h:2596
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: InternalNode.h:1980
ChildT & getItem(Index pos) const
Definition: InternalNode.h:167
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:1351
typename NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:147
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2617
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:3036
const ValueType & b
Definition: InternalNode.h:2640
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes ...
Definition: InternalNode.h:2862
Definition: version.h:229
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:2282
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:2134
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:1174
Definition: InternalNode.h:203
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:3112
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:459
Int32 x() const
Definition: Coord.h:157
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:309
typename ChildNodeType::ValueType ValueType
Definition: InternalNode.h:65