35 #ifndef OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 36 #define OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 38 #include <openvdb/Platform.h> 39 #include <openvdb/util/NodeMasks.h> 40 #include <openvdb/io/Compression.h> 41 #include <openvdb/math/Math.h> 42 #include <openvdb/version.h> 43 #include <openvdb/Types.h> 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 =
111 #if OPENVDB_ABI_VERSION_NUMBER >= 3 123 template<
typename OtherChildNodeType>
129 template<
typename OtherChildNodeType>
136 template<
typename OtherChildNodeType>
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;
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;
379 void setActiveState(
const Coord& xyz,
bool on);
383 void setValueOn(
const Coord& xyz);
387 void setValueOff(
const Coord& xyz);
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);
515 void voxelizeActiveTiles(
bool threaded =
true);
524 template<
typename DenseT>
529 template<MergePolicy Policy>
534 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
548 template<
typename OtherChildNodeType>
564 template<
typename OtherChildNodeType>
579 template<
typename OtherChildNodeType>
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;
628 template<
typename AccessorT>
639 template<
typename NodeT>
640 NodeT* stealNode(
const Coord& xyz,
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;
679 template<
typename AccessorT>
683 template<
typename AccessorT>
684 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
685 template<
typename AccessorT>
699 template<
typename 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);
763 template<
typename OtherChildNodeType, Index OtherLog2Dim>
768 friend class IteratorBase<MaskOnIterator, InternalNode>;
777 template<
typename, Index>
friend class InternalNode;
800 void setValueMask(
Index n,
bool on) { mValueMask.set(n, mChildMask.isOn(n) ? false : on); }
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);
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>
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>
935 template<
typename ChildT, Index Log2Dim>
936 template<
typename OtherChildNodeType>
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>
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>
1020 template<
typename ChildT, Index Log2Dim>
1033 template<
typename ChildT, Index Log2Dim>
1040 sum += iter->leafCount();
1046 template<
typename ChildT, Index Log2Dim>
1053 sum += iter->nonLeafCount();
1059 template<
typename ChildT, Index Log2Dim>
1065 sum += iter->onVoxelCount();
1071 template<
typename ChildT, Index Log2Dim>
1077 sum += iter->offVoxelCount();
1083 template<
typename ChildT, Index Log2Dim>
1095 template<
typename ChildT, Index Log2Dim>
1106 template<
typename ChildT, Index Log2Dim>
1112 sum += iter->onTileCount();
1117 template<
typename ChildT, Index Log2Dim>
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>
1155 const Index i = iter.pos();
1157 child->prune(tolerance);
1158 if (child->isConstant(value, state, tolerance)) {
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;
1182 if (std::is_same<NodeT, ChildT>::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;
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;
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;
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;
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*
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();
1327 ChildT* child =
nullptr;
1329 if (ChildT::LEVEL>0) {
1332 child =
reinterpret_cast<ChildT*
>(leaf);
1336 if (ChildT::LEVEL>0) {
1340 child =
reinterpret_cast<ChildT*
>(leaf);
1344 child->addLeaf(leaf);
1348 template<
typename ChildT, Index Log2Dim>
1349 template<
typename AccessorT>
1353 assert(leaf !=
nullptr);
1354 const Coord& xyz = leaf->origin();
1356 ChildT* child =
nullptr;
1358 if (ChildT::LEVEL>0) {
1360 acc.insert(xyz, child);
1362 child =
reinterpret_cast<ChildT*
>(leaf);
1366 if (ChildT::LEVEL>0) {
1368 acc.insert(xyz, child);
1371 child =
reinterpret_cast<ChildT*
>(leaf);
1375 child->addLeafAndCache(leaf, acc);
1382 template<
typename ChildT, Index Log2Dim>
1392 template<
typename ChildT, Index Log2Dim>
1397 if (
LEVEL >= level) {
1400 if (
LEVEL > level) {
1403 child->addTile(level, xyz, value, state);
1410 if (
LEVEL > level) {
1411 child->addTile(level, xyz, value, state);
1423 template<
typename ChildT, Index Log2Dim>
1424 template<
typename AccessorT>
1427 const ValueType& value,
bool state, AccessorT& acc)
1429 if (
LEVEL >= level) {
1432 if (
LEVEL > level) {
1435 acc.insert(xyz, child);
1436 child->addTileAndCache(level, xyz, value, state, acc);
1443 if (
LEVEL > level) {
1444 acc.insert(xyz, child);
1445 child->addTileAndCache(level, xyz, value, state, acc);
1460 template<
typename ChildT, Index Log2Dim>
1461 inline typename ChildT::LeafNodeType*
1465 ChildT* child =
nullptr;
1472 return child->touchLeaf(xyz);
1476 template<
typename ChildT, Index Log2Dim>
1477 template<
typename AccessorT>
1478 inline typename ChildT::LeafNodeType*
1485 acc.insert(xyz,
mNodes[n].getChild());
1493 template<
typename ChildT, Index Log2Dim>
1513 template<
typename ChildT, Index Log2Dim>
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>
1546 if (
LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1548 if (iter->hasActiveTiles())
return true;
1555 template<
typename ChildT, Index Log2Dim>
1564 template<
typename ChildT, Index Log2Dim>
1565 template<
typename AccessorT>
1571 acc.insert(xyz,
mNodes[n].getChild());
1576 template<
typename ChildT, Index Log2Dim>
1577 inline const typename ChildT::ValueType&
1585 template<
typename ChildT, Index Log2Dim>
1586 template<
typename AccessorT>
1587 inline const typename ChildT::ValueType&
1592 acc.insert(xyz,
mNodes[n].getChild());
1599 template<
typename ChildT, Index Log2Dim>
1607 template<
typename ChildT, Index Log2Dim>
1608 template<
typename AccessorT>
1614 acc.insert(xyz,
mNodes[n].getChild());
1621 template<
typename ChildT, Index Log2Dim>
1633 template<
typename ChildT, Index Log2Dim>
1634 template<
typename AccessorT>
1641 acc.insert(xyz,
mNodes[n].getChild());
1642 return mNodes[n].
getChild()->probeValueAndCache(xyz, value, acc);
1649 template<
typename ChildT, Index Log2Dim>
1665 template<
typename ChildT, Index Log2Dim>
1681 template<
typename ChildT, Index Log2Dim>
1700 template<
typename ChildT, Index Log2Dim>
1701 template<
typename AccessorT>
1720 acc.insert(xyz, child);
1721 child->setValueOffAndCache(xyz, value, acc);
1726 template<
typename ChildT, Index Log2Dim>
1745 template<
typename ChildT, Index Log2Dim>
1746 template<
typename AccessorT>
1764 acc.insert(xyz,
mNodes[n].getChild());
1770 template<
typename ChildT, Index Log2Dim>
1786 template<
typename ChildT, Index Log2Dim>
1787 template<
typename AccessorT>
1802 acc.insert(xyz,
mNodes[n].getChild());
1808 template<
typename ChildT, Index Log2Dim>
1826 template<
typename ChildT, Index Log2Dim>
1827 template<
typename AccessorT>
1844 acc.insert(xyz, child);
1845 child->setActiveStateAndCache(xyz, on, acc);
1850 template<
typename ChildT, Index Log2Dim>
1861 template<
typename ChildT, Index Log2Dim>
1862 template<
typename ModifyOp>
1872 bool createChild = !active;
1889 template<
typename ChildT, Index Log2Dim>
1890 template<
typename ModifyOp,
typename AccessorT>
1901 bool createChild = !active;
1917 acc.insert(xyz, child);
1918 child->modifyValueAndCache(xyz, op, acc);
1923 template<
typename ChildT, Index Log2Dim>
1924 template<
typename ModifyOp>
1933 bool modifiedState = !tileState;
1935 op(modifiedVal, modifiedState);
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)
1957 bool modifiedState = !tileState;
1959 op(modifiedVal, modifiedState);
1969 acc.insert(xyz, child);
1970 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1978 template<
typename ChildT, Index Log2Dim>
1985 this->
fill(nodeBBox, background,
false);
1986 }
else if (clipBBox.
isInside(nodeBBox)) {
2003 }
else if (!clipBBox.
isInside(tileBBox)) {
2011 tileBBox.intersect(clipBBox);
2016 this->
fill(tileBBox, val, on);
2028 template<
typename ChildT, Index Log2Dim>
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) {
2049 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2055 ChildT* child =
nullptr;
2068 child->fill(
CoordBBox(xyz, tmp), value, active);
2084 template<
typename ChildT, Index Log2Dim>
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) {
2106 ChildT* child =
nullptr;
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) {
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>
2188 const ValueType zero = zeroVal<ValueType>();
2197 iter->writeTopology(os, toHalf);
2202 template<
typename ChildT, Index Log2Dim>
2206 #if OPENVDB_ABI_VERSION_NUMBER >= 3 2218 #if OPENVDB_ABI_VERSION_NUMBER <= 2 2224 child->readTopology(is);
2227 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2232 const bool oldVersion =
2238 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[numValues]);
2248 assert(n == numValues);
2257 #if OPENVDB_ABI_VERSION_NUMBER <= 2 2263 child->readTopology(is, fromHalf);
2272 template<
typename ChildT, Index Log2Dim>
2273 inline const typename ChildT::ValueType&
2280 template<
typename ChildT, Index Log2Dim>
2281 inline const typename ChildT::ValueType&
2292 template<
typename ChildT, Index Log2Dim>
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>
2348 iter->voxelizeActiveTiles(
false);
2356 template<
typename ChildT, Index Log2Dim>
2357 template<MergePolicy Policy>
2370 const Index n = iter.pos();
2374 background, otherBackground);
2382 child->resetBackground(otherBackground, background);
2389 const Index n = iter.pos();
2402 const Index n = iter.pos();
2405 mNodes[n].
getChild()->template merge<Policy>(*iter, background, otherBackground);
2413 child->resetBackground(otherBackground, background);
2424 const Index n = iter.pos();
2427 mNodes[n].
getChild()->template merge<Policy>(*iter, background, otherBackground);
2434 child->resetBackground(otherBackground, background);
2447 const Index n = iter.pos();
2450 mNodes[n].
getChild()->template merge<Policy>(iter.getValue(),
true);
2465 template<
typename ChildT, Index Log2Dim>
2466 template<MergePolicy Policy>
2475 if (!tileActive)
return;
2479 const Index n = iter.pos();
2485 iter.setValue(tileValue);
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());
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>
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)) {
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>
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)) {
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);
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>();
2706 if (child && otherChild) {
2707 child->combine(*otherChild, op);
2714 template<
typename ChildT, Index Log2Dim>
2715 template<
typename CombineOp>
2727 .setBIsActive(valueIsActive));
2734 if (child) child->combine(value, valueIsActive, op);
2743 template<
typename ChildT, Index Log2Dim>
2744 template<
typename CombineOp,
typename OtherNodeType>
2755 .setBRef(other1.mNodes[i].getValue())
2756 .setBIsActive(other1.isValueMaskOn(i)));
2765 : other1.mNodes[i].getChild()->origin();
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)
2799 if (other.isChildMaskOff(i)) {
2801 .setAIsActive(valueIsActive)
2802 .setBRef(other.mNodes[i].getValue())
2803 .setBIsActive(other.isValueMaskOn(i)));
2808 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[i].getChild();
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)
2836 .setBIsActive(valueIsActive));
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>()) {
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>
3039 iter->writeBuffers(os, toHalf);
3044 template<
typename ChildT, Index Log2Dim>
3049 iter->readBuffers(is, fromHalf);
3054 template<
typename ChildT, Index Log2Dim>
3057 const CoordBBox& clipBBox,
bool fromHalf)
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>
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;
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");
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;
3179 const Index n = iter.pos();
3180 if (std::is_same<T, ArrayChildT*>::value) {
3181 array.push_back(reinterpret_cast<T>(
mNodes[n].getChild()));
3185 iter->stealNodes(array, value, state);
3196 template<
typename ChildT, Index Log2Dim>
3204 mNodes[i].
getChild()->resetBackground(oldBackground, newBackground);
3215 template<
typename ChildT, Index Log2Dim>
3216 template<
typename OtherChildNodeType, Index OtherLog2Dim>
3224 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
3230 template<
typename ChildT, Index Log2Dim>
3244 template<
typename ChildT, Index Log2Dim>
3256 template<
typename ChildT, Index Log2Dim>
3271 template<
typename ChildT, Index Log2Dim>
3278 template<
typename ChildT, Index Log2Dim>
3287 template<
typename ChildT, Index Log2Dim>
3288 inline const ChildT*
3299 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 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
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2179
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:783
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
Int32 x() const
Definition: Coord.h:157
const ValueType & b
Definition: InternalNode.h:2580
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1949
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:205
void topologyDifference(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &background)
Difference this node's set of active values with the active values of the other node, whose ValueType may be different. So a resulting voxel will be active only if the original voxel is active in this node and inactive in the other node.
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:504
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:257
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
TopologyCopy2(const OtherInternalNode *source, InternalNode *target, const ValueType &offValue, const ValueType &onValue)
Definition: InternalNode.h:986
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:329
Index64 onVoxelCount() const
Definition: InternalNode.h:1061
typename NodeMaskType::Word W
Definition: InternalNode.h:2500
Index64 Word
Definition: NodeMasks.h:318
ChildIter()
Definition: InternalNode.h:163
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1789
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 operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2597
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: InternalNode.h:3127
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
TopologyUnion(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:2504
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:395
_ChildNodeType ChildNodeType
Definition: InternalNode.h:63
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:188
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 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...
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() const
Definition: InternalNode.h:787
Definition: InternalNode.h:835
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:1097
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...
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition: InternalNode.h:3280
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2617
DenseIter()
Definition: InternalNode.h:209
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1852
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
Definition: InternalNode.h:833
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:255
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
ValueAllIter beginValueAll()
Definition: InternalNode.h:274
const UnionType * getTable() const
Definition: InternalNode.h:797
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:210
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:191
bool resultIsActive() const
Definition: Types.h:450
static const Index NUM_VALUES
Definition: InternalNode.h:74
InternalNode * t
Definition: InternalNode.h:966
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:416
DenseIter< const InternalNode, const ChildNodeType, ValueType, ChildAll > ChildAllCIter
Definition: InternalNode.h:244
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:785
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:73
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1495
static void doVisit2Node(NodeT &, OtherNodeT &, VisitorOp &)
Definition: InternalNode.h:2949
const Coord & min() const
Definition: Coord.h:337
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
Definition: InternalNode.h:153
void save(std::ostream &os) const
Definition: NodeMasks.h:567
ChildT & getItem(Index pos) const
Definition: InternalNode.h:167
Level getLevel()
Return the current logging level.
Definition: logging.h:165
void setChild(ChildT *child)
Definition: NodeUnion.h:70
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:108
Definition: InternalNode.h:152
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:786
InternalNode * t
Definition: InternalNode.h:2639
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:82
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2514
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
NodeUnion< ValueType, ChildNodeType > UnionType
Definition: InternalNode.h:67
const ValueType & b
Definition: InternalNode.h:2640
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2204
Definition: InternalNode.h:2501
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:256
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:485
TopologyDifference(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2603
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:955
static void doVisit(NodeT &, VisitorOp &)
Definition: InternalNode.h:2906
Definition: InternalNode.h:2597
ValueOnIter beginValueOn()
Definition: InternalNode.h:271
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:141
Index64 onTileCount() const
Definition: InternalNode.h:1108
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
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:56
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
static Index dim()
Definition: InternalNode.h:279
Definition: NodeMasks.h:241
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:267
Coord & setY(Int32 y)
Definition: Coord.h:107
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
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:164
Definition: version.h:229
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2338
static const Index LEVEL
Definition: InternalNode.h:75
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...
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
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:843
ChildT * getChild() const
Definition: NodeUnion.h:69
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:462
Definition: InternalNode.h:152
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
TopologyCopy1(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:950
VoxelizeActiveTiles(InternalNode &node)
Definition: InternalNode.h:2313
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:510
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
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes ...
Definition: InternalNode.h:2862
typename BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:207
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
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
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:422
InternalNode * t
Definition: InternalNode.h:2531
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 setValue(const ValueT &val)
Definition: NodeUnion.h:74
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
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
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:3258
Definition: InternalNode.h:2547
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:202
~InternalNode()
Definition: InternalNode.h:1022
Definition: InternalNode.h:832
Definition: InternalNode.h:160
typename ChildNodeType::BuildType BuildType
Definition: InternalNode.h:66
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
static const Index DIM
Definition: InternalNode.h:73
typename ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:64
Definition: InternalNode.h:153
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:837
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:235
Definition: InternalNode.h:56
int32_t Int32
Definition: Types.h:63
Int32 z() const
Definition: Coord.h:159
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:443
Definition: InternalNode.h:2600
void operator()(W &tV, const W &sC, const W &sV, const W &tC) const
Definition: InternalNode.h:2600
Definition: InternalNode.h:836
ValueOffIter beginValueOff()
Definition: InternalNode.h:273
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
DeepCopy(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:906
typename NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:147
Definition: InternalNode.h:203
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:3036
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
const OtherInternalNode * s
Definition: InternalNode.h:1001
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:910
Definition: InternalNode.h:60
Definition: Exceptions.h:40
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
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of an Intern...
Definition: InternalNode.h:91
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:3112
Definition: InternalNode.h:152
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:118
InternalNode * mNode
Definition: InternalNode.h:2333
typename ChildNodeType::ValueType ValueType
Definition: InternalNode.h:65
InternalNode * t
Definition: InternalNode.h:1002
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1748
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
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:3046
InternalNode()
Default constructor.
Definition: InternalNode.h:99
const ValueT & getValue() const
Definition: NodeUnion.h:72
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
NodeMaskType mChildMask
Definition: InternalNode.h:841
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
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:254
Coord & setZ(Int32 z)
Definition: Coord.h:108
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:445
Definition: version.h:220
const OtherInternalNode * s
Definition: InternalNode.h:2638
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:386
Index32 Index
Definition: Types.h:61
Definition: InternalNode.h:2311
const AValueType & result() const
Get the output value.
Definition: Types.h:431
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition: InternalNode.h:2746
Definition: InternalNode.h:153
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:459
void operator()(W &tV, const W &sV, const W &tC) const
Definition: InternalNode.h:2501
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1703
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:269
InternalNode * t
Definition: InternalNode.h:920
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:454
Int32 y() const
Definition: Coord.h:158
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:302
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:781
Definition: NodeMasks.h:210
uint64_t Index64
Definition: Types.h:60
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:174
bool isValueMaskOn() const
Definition: InternalNode.h:782
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
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
ChildOffIter beginChildOff()
Definition: InternalNode.h:260
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:359
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:991
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:439
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
typename NodeMaskType::Word W
Definition: InternalNode.h:2596
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
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:266
Coord & setX(Int32 x)
Definition: Coord.h:106
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:1119
const OtherInternalNode * s
Definition: InternalNode.h:2530
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:270
NodeMaskType getValueOffMask() const
Definition: InternalNode.h:790
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:1085
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:263
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1542
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition: NodeMasks.h:464
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1578
Definition: InternalNode.h:837
const ValueType & onV
Definition: InternalNode.h:1003
void load(std::istream &is)
Definition: NodeMasks.h:571
typename std::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:211
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:185
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
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:231
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:149
const Coord & max() const
Definition: Coord.h:338
bool isValueMaskOff() const
Definition: InternalNode.h:784
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:265
static Index getLevel()
Definition: InternalNode.h:282
bool isEmpty() const
Definition: InternalNode.h:326
static void doVisit2(NodeT &, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: InternalNode.h:3011
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
Index32 leafCount() const
Definition: InternalNode.h:1035
const OtherInternalNode * s
Definition: InternalNode.h:2578
ValueIter()
Definition: InternalNode.h:184
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 operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2562
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
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1623
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2547
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:404
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:213
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2320
void translate(const Coord &t)
Definition: Coord.h:462
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1651
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2659
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1567
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:195
typename NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:148
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.
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
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:452
Index32 nonLeafCount() const
Definition: InternalNode.h:1048
typename NodeMaskType::Word W
Definition: InternalNode.h:2546
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
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:339
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
InternalNode * t
Definition: InternalNode.h:2579
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:520
const OtherInternalNode * s
Definition: InternalNode.h:919
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:3273
const ValueType & b
Definition: InternalNode.h:967
const NodeMaskType & getValueMask() const
Definition: InternalNode.h:788
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:518
DenseIter< InternalNode, ChildNodeType, ValueType, ChildAll > ChildAllIter
Definition: InternalNode.h:243
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:225
Definition: InternalNode.h:834
Definition: InternalNode.h:181
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1829
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
const OtherInternalNode * s
Definition: InternalNode.h:965
Definition: NodeMasks.h:272
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:253
TopologyIntersection(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2550
uint32_t Index32
Definition: Types.h:59
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:528
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:309
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1667
Index64 offVoxelCount() const
Definition: InternalNode.h:1073