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 =
111 #ifndef OPENVDB_2_ABI_COMPATIBLE 123 template<
typename OtherChildNodeType>
129 template<
typename OtherChildNodeType>
136 template<
typename OtherChildNodeType>
155 template<
typename NodeT,
typename ChildT,
typename MaskIterT,
typename TagT>
157 MaskIterT, ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>
161 MaskIterT,
ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>(iter, parent) {}
165 assert(this->parent().isChildMaskOn(pos));
166 return *(this->parent().getChildNode(pos));
170 void setItem(
Index pos,
const ChildT& c)
const { this->parent().resetChildNode(pos, &c); }
176 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
178 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
182 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
184 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
187 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
190 template<
typename ModifyOp>
193 op(this->parent().mNodes[pos].getValue());
198 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
200 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
211 if (this->parent().isChildMaskOn(pos)) {
212 child = this->parent().getChildNode(pos);
216 value = this->parent().mNodes[pos].getValue();
223 this->parent().resetChildNode(pos, child);
229 this->parent().unsetChildNode(pos, value);
281 static void getNodeLog2Dims(std::vector<Index>& dims);
291 static void offsetToLocalCoord(
Index n,
Coord& xyz);
304 Index64 onLeafVoxelCount()
const;
305 Index64 offLeafVoxelCount()
const;
315 void evalActiveBoundingBox(
CoordBBox& bbox,
bool visitVoxels =
true)
const;
322 bool isEmpty()
const {
return mChildMask.isOff(); }
329 bool isConstant(
ValueType& firstValue,
bool& state,
330 const ValueType& tolerance = zeroVal<ValueType>())
const;
347 bool& state,
const ValueType& tolerance = zeroVal<ValueType>())
const;
350 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
353 bool isValueOn(
const Coord& xyz)
const;
358 bool hasActiveTiles()
const;
375 void setActiveState(
const Coord& xyz,
bool on);
379 void setValueOn(
const Coord& xyz);
383 void setValueOff(
const Coord& xyz);
389 template<
typename ModifyOp>
390 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
392 template<
typename ModifyOp>
393 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
399 template<
typename AccessorT>
400 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
406 template<
typename AccessorT>
407 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
413 template<
typename AccessorT>
414 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
420 template<
typename AccessorT>
421 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
428 template<
typename ModifyOp,
typename AccessorT>
429 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
435 template<
typename ModifyOp,
typename AccessorT>
436 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
442 template<
typename AccessorT>
443 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
449 template<
typename AccessorT>
450 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
457 template<
typename AccessorT>
458 bool probeValueAndCache(
const Coord& xyz,
ValueType& value, AccessorT&)
const;
466 template<
typename AccessorT>
467 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
475 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
476 void readTopology(std::istream&,
bool fromHalf =
false);
477 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
478 void readBuffers(std::istream&,
bool fromHalf =
false);
479 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
511 void voxelizeActiveTiles(
bool threaded =
true);
520 template<
typename DenseT>
525 template<MergePolicy Policy>
530 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
544 template<
typename OtherChildNodeType>
560 template<
typename OtherChildNodeType>
575 template<
typename OtherChildNodeType>
579 template<
typename CombineOp>
581 template<
typename CombineOp>
582 void combine(
const ValueType& value,
bool valueIsActive, CombineOp&);
584 template<
typename CombineOp,
typename OtherNodeType >
585 void combine2(
const InternalNode& other0,
const OtherNodeType& other1, CombineOp&);
586 template<
typename CombineOp,
typename OtherNodeType >
587 void combine2(
const ValueType& value,
const OtherNodeType& other,
bool valIsActive, CombineOp&);
588 template<
typename CombineOp,
typename OtherValueType>
589 void combine2(
const InternalNode& other,
const OtherValueType&,
bool valIsActive, CombineOp&);
596 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
598 template<
typename VisitorOp>
void visit(VisitorOp&);
599 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
601 template<
typename OtherNodeType,
typename VisitorOp>
602 void visit2Node(OtherNodeType& other, VisitorOp&);
603 template<
typename OtherNodeType,
typename VisitorOp>
604 void visit2Node(OtherNodeType& other, VisitorOp&)
const;
605 template<
typename IterT,
typename VisitorOp>
606 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false);
607 template<
typename IterT,
typename VisitorOp>
608 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false)
const;
624 template<
typename AccessorT>
635 template<
typename NodeT>
636 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
647 template<
typename AccessorT>
648 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
651 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
654 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
658 template<
typename NodeType,
typename AccessorT>
661 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
662 template<
typename NodeType,
typename AccessorT>
663 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
675 template<
typename AccessorT>
679 template<
typename AccessorT>
680 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
681 template<
typename AccessorT>
695 template<
typename AccessorT>
699 template<
typename ArrayT>
722 void getNodes(ArrayT& array);
723 template<
typename ArrayT>
724 void getNodes(ArrayT& array)
const;
750 template<
typename ArrayT>
751 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
759 template<
typename OtherChildNodeType, Index OtherLog2Dim>
764 friend class IteratorBase<MaskOnIterator, InternalNode>;
773 template<
typename, Index>
friend class InternalNode;
796 void setValueMask(
Index n,
bool on) { mValueMask.set(n, mChildMask.isOn(n) ? false : on); }
806 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
807 static inline void doVisit(NodeT&, VisitorOp&);
809 template<
typename NodeT,
typename OtherNodeT,
typename VisitorOp,
810 typename ChildAllIterT,
typename OtherChildAllIterT>
811 static inline void doVisit2Node(NodeT&, OtherNodeT&, VisitorOp&);
813 template<
typename NodeT,
typename VisitorOp,
814 typename ChildAllIterT,
typename OtherChildAllIterT>
815 static inline void doVisit2(NodeT&, OtherChildAllIterT&, VisitorOp&,
bool otherIsLHS);
828 template<
typename OtherInternalNode>
struct DeepCopy;
847 template<
typename ChildT1, Index Dim1,
typename NodeT2>
851 static const bool value =
false;
854 template<
typename ChildT1, Index Dim1,
typename ChildT2>
856 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
864 template<
typename ChildT, Index Log2Dim>
868 for (
Index i = 0;
i < NUM_VALUES; ++
i) mNodes[
i].setValue(background);
872 template<
typename ChildT, Index Log2Dim>
875 mOrigin(origin[0] & ~(DIM - 1),
876 origin[1] & ~(DIM - 1),
877 origin[2] & ~(DIM - 1))
884 #ifndef OPENVDB_2_ABI_COMPATIBLE 887 template<
typename ChildT, Index Log2Dim>
898 template<
typename ChildT, Index Log2Dim>
899 template<
typename OtherInternalNode>
903 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
907 for (
Index i = r.begin(), end=r.end();
i!=end; ++
i) {
908 if (s->mChildMask.isOff(
i)) {
909 t->mNodes[
i].setValue(
ValueType(s->mNodes[
i].getValue()));
915 const OtherInternalNode*
s;
919 template<
typename ChildT, Index Log2Dim>
931 template<
typename ChildT, Index Log2Dim>
932 template<
typename OtherChildNodeType>
942 template<
typename ChildT, Index Log2Dim>
943 template<
typename OtherInternalNode>
947 const ValueType& background) : s(source), t(target), b(background) {
948 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
952 for (
Index i = r.begin(), end=r.end();
i!=end; ++
i) {
953 if (s->isChildMaskOn(
i)) {
957 t->mNodes[
i].setValue(b);
961 const OtherInternalNode*
s;
966 template<
typename ChildT, Index Log2Dim>
967 template<
typename OtherChildNodeType>
978 template<
typename ChildT, Index Log2Dim>
979 template<
typename OtherInternalNode>
984 : s(source), t(target), offV(offValue), onV(onValue) {
985 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
988 for (
Index i = r.begin(), end=r.end();
i!=end; ++
i) {
989 if (s->isChildMaskOn(
i)) {
993 t->mNodes[
i].setValue(s->isValueMaskOn(
i) ? onV : offV);
997 const OtherInternalNode*
s;
1002 template<
typename ChildT, Index Log2Dim>
1003 template<
typename OtherChildNodeType>
1016 template<
typename ChildT, Index Log2Dim>
1029 template<
typename ChildT, Index Log2Dim>
1036 sum += iter->leafCount();
1042 template<
typename ChildT, Index Log2Dim>
1049 sum += iter->nonLeafCount();
1055 template<
typename ChildT, Index Log2Dim>
1061 sum += iter->onVoxelCount();
1067 template<
typename ChildT, Index Log2Dim>
1073 sum += iter->offVoxelCount();
1079 template<
typename ChildT, Index Log2Dim>
1091 template<
typename ChildT, Index Log2Dim>
1102 template<
typename ChildT, Index Log2Dim>
1108 sum += iter->onTileCount();
1113 template<
typename ChildT, Index Log2Dim>
1120 sum += iter->memUsage();
1126 template<
typename ChildT, Index Log2Dim>
1130 if (bbox.
isInside(this->getNodeBoundingBox()))
return;
1133 bbox.
expand(
i.getCoord(), ChildT::DIM);
1136 i->evalActiveBoundingBox(bbox, visitVoxels);
1144 template<
typename ChildT, Index Log2Dim>
1151 const Index i = iter.pos();
1153 child->prune(tolerance);
1154 if (child->isConstant(value, state, tolerance)) {
1167 template<
typename ChildT, Index Log2Dim>
1168 template<
typename NodeT>
1172 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1173 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1178 if (std::is_same<NodeT, ChildT>::value) {
1183 return (std::is_same<NodeT, ChildT>::value)
1184 ?
reinterpret_cast<NodeT*
>(child)
1185 : child->template stealNode<NodeT>(xyz, value, state);
1193 template<
typename ChildT, Index Log2Dim>
1194 template<
typename NodeT>
1198 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1199 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1204 return (std::is_same<NodeT, ChildT>::value)
1205 ?
reinterpret_cast<NodeT*
>(child)
1206 : child->template probeNode<NodeT>(xyz);
1211 template<
typename ChildT, Index Log2Dim>
1212 template<
typename NodeT,
typename AccessorT>
1216 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1217 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1222 acc.insert(xyz, child);
1223 return (std::is_same<NodeT, ChildT>::value)
1224 ?
reinterpret_cast<NodeT*
>(child)
1225 : child->template probeNodeAndCache<NodeT>(xyz, acc);
1230 template<
typename ChildT, Index Log2Dim>
1231 template<
typename NodeT>
1235 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1236 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1241 return (std::is_same<NodeT, ChildT>::value)
1242 ?
reinterpret_cast<const NodeT*
>(child)
1243 : child->template probeConstNode<NodeT>(xyz);
1248 template<
typename ChildT, Index Log2Dim>
1249 template<
typename NodeT,
typename AccessorT>
1253 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1254 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1259 acc.insert(xyz, child);
1260 return (std::is_same<NodeT, ChildT>::value)
1261 ?
reinterpret_cast<const NodeT*
>(child)
1262 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
1270 template<
typename ChildT, Index Log2Dim>
1271 inline typename ChildT::LeafNodeType*
1274 return this->
template probeNode<LeafNodeType>(xyz);
1278 template<
typename ChildT, Index Log2Dim>
1279 template<
typename AccessorT>
1280 inline typename ChildT::LeafNodeType*
1283 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
1287 template<
typename ChildT, Index Log2Dim>
1288 template<
typename AccessorT>
1289 inline const typename ChildT::LeafNodeType*
1296 template<
typename ChildT, Index Log2Dim>
1297 inline const typename ChildT::LeafNodeType*
1300 return this->
template probeConstNode<LeafNodeType>(xyz);
1304 template<
typename ChildT, Index Log2Dim>
1305 template<
typename AccessorT>
1306 inline const typename ChildT::LeafNodeType*
1309 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
1316 template<
typename ChildT, Index Log2Dim>
1320 assert(leaf !=
nullptr);
1321 const Coord& xyz = leaf->origin();
1323 ChildT* child =
nullptr;
1325 if (ChildT::LEVEL>0) {
1328 child =
reinterpret_cast<ChildT*
>(leaf);
1332 if (ChildT::LEVEL>0) {
1336 child =
reinterpret_cast<ChildT*
>(leaf);
1340 child->addLeaf(leaf);
1344 template<
typename ChildT, Index Log2Dim>
1345 template<
typename AccessorT>
1349 assert(leaf !=
nullptr);
1350 const Coord& xyz = leaf->origin();
1352 ChildT* child =
nullptr;
1354 if (ChildT::LEVEL>0) {
1356 acc.insert(xyz, child);
1358 child =
reinterpret_cast<ChildT*
>(leaf);
1362 if (ChildT::LEVEL>0) {
1364 acc.insert(xyz, child);
1367 child =
reinterpret_cast<ChildT*
>(leaf);
1371 child->addLeafAndCache(leaf, acc);
1378 template<
typename ChildT, Index Log2Dim>
1388 template<
typename ChildT, Index Log2Dim>
1393 if (
LEVEL >= level) {
1396 if (
LEVEL > level) {
1399 child->addTile(level, xyz, value, state);
1406 if (
LEVEL > level) {
1407 child->addTile(level, xyz, value, state);
1419 template<
typename ChildT, Index Log2Dim>
1420 template<
typename AccessorT>
1423 const ValueType& value,
bool state, AccessorT& acc)
1425 if (
LEVEL >= level) {
1428 if (
LEVEL > level) {
1431 acc.insert(xyz, child);
1432 child->addTileAndCache(level, xyz, value, state, acc);
1439 if (
LEVEL > level) {
1440 acc.insert(xyz, child);
1441 child->addTileAndCache(level, xyz, value, state, acc);
1456 template<
typename ChildT, Index Log2Dim>
1457 inline typename ChildT::LeafNodeType*
1461 ChildT* child =
nullptr;
1468 return child->touchLeaf(xyz);
1472 template<
typename ChildT, Index Log2Dim>
1473 template<
typename AccessorT>
1474 inline typename ChildT::LeafNodeType*
1481 acc.insert(xyz,
mNodes[n].getChild());
1489 template<
typename ChildT, Index Log2Dim>
1509 template<
typename ChildT, Index Log2Dim>
1522 if ((maxValue - v) > tolerance)
return false;
1524 }
else if (v > maxValue) {
1525 if ((v - minValue) > tolerance)
return false;
1536 template<
typename ChildT, Index Log2Dim>
1542 if (
LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1544 if (iter->hasActiveTiles())
return true;
1551 template<
typename ChildT, Index Log2Dim>
1560 template<
typename ChildT, Index Log2Dim>
1561 template<
typename AccessorT>
1567 acc.insert(xyz,
mNodes[n].getChild());
1572 template<
typename ChildT, Index Log2Dim>
1573 inline const typename ChildT::ValueType&
1581 template<
typename ChildT, Index Log2Dim>
1582 template<
typename AccessorT>
1583 inline const typename ChildT::ValueType&
1588 acc.insert(xyz,
mNodes[n].getChild());
1595 template<
typename ChildT, Index Log2Dim>
1603 template<
typename ChildT, Index Log2Dim>
1604 template<
typename AccessorT>
1610 acc.insert(xyz,
mNodes[n].getChild());
1617 template<
typename ChildT, Index Log2Dim>
1629 template<
typename ChildT, Index Log2Dim>
1630 template<
typename AccessorT>
1637 acc.insert(xyz,
mNodes[n].getChild());
1638 return mNodes[n].
getChild()->probeValueAndCache(xyz, value, acc);
1645 template<
typename ChildT, Index Log2Dim>
1661 template<
typename ChildT, Index Log2Dim>
1677 template<
typename ChildT, Index Log2Dim>
1696 template<
typename ChildT, Index Log2Dim>
1697 template<
typename AccessorT>
1716 acc.insert(xyz, child);
1717 child->setValueOffAndCache(xyz, value, acc);
1722 template<
typename ChildT, Index Log2Dim>
1741 template<
typename ChildT, Index Log2Dim>
1742 template<
typename AccessorT>
1760 acc.insert(xyz,
mNodes[n].getChild());
1766 template<
typename ChildT, Index Log2Dim>
1782 template<
typename ChildT, Index Log2Dim>
1783 template<
typename AccessorT>
1798 acc.insert(xyz,
mNodes[n].getChild());
1804 template<
typename ChildT, Index Log2Dim>
1822 template<
typename ChildT, Index Log2Dim>
1823 template<
typename AccessorT>
1840 acc.insert(xyz, child);
1841 child->setActiveStateAndCache(xyz, on, acc);
1846 template<
typename ChildT, Index Log2Dim>
1857 template<
typename ChildT, Index Log2Dim>
1858 template<
typename ModifyOp>
1868 bool createChild = !active;
1885 template<
typename ChildT, Index Log2Dim>
1886 template<
typename ModifyOp,
typename AccessorT>
1897 bool createChild = !active;
1913 acc.insert(xyz, child);
1914 child->modifyValueAndCache(xyz, op, acc);
1919 template<
typename ChildT, Index Log2Dim>
1920 template<
typename ModifyOp>
1929 bool modifiedState = !tileState;
1931 op(modifiedVal, modifiedState);
1939 if (hasChild)
mNodes[n].
getChild()->modifyValueAndActiveState(xyz, op);
1942 template<
typename ChildT, Index Log2Dim>
1943 template<
typename ModifyOp,
typename AccessorT>
1946 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1953 bool modifiedState = !tileState;
1955 op(modifiedVal, modifiedState);
1965 acc.insert(xyz, child);
1966 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1974 template<
typename ChildT, Index Log2Dim>
1981 this->
fill(nodeBBox, background,
false);
1982 }
else if (clipBBox.
isInside(nodeBBox)) {
1999 }
else if (!clipBBox.
isInside(tileBBox)) {
2007 tileBBox.intersect(clipBBox);
2012 this->
fill(tileBBox, val, on);
2024 template<
typename ChildT, Index Log2Dim>
2029 clippedBBox.intersect(bbox);
2030 if (!clippedBBox)
return;
2034 Coord xyz, tileMin, tileMax;
2035 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2037 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2039 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2045 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2051 ChildT* child =
nullptr;
2064 child->fill(
CoordBBox(xyz, tmp), value, active);
2080 template<
typename ChildT, Index Log2Dim>
2085 clippedBBox.intersect(bbox);
2086 if (!clippedBBox)
return;
2090 Coord xyz, tileMin, tileMax;
2091 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2093 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2095 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2102 ChildT* child =
nullptr;
2114 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2117 child->denseFill(
CoordBBox{xyz, clippedBBox.
max()}, value, active);
2127 template<
typename ChildT, Index Log2Dim>
2128 template<
typename DenseT>
2132 using DenseValueType =
typename DenseT::ValueType;
2134 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2135 const Coord&
min = dense.bbox().min();
2136 for (
Coord xyz = bbox.
min(),
max; xyz[0] <= bbox.
max()[0]; xyz[0] =
max[0] + 1) {
2137 for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] =
max[1] + 1) {
2138 for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] =
max[2] + 1) {
2151 DenseValueType* a0 = dense.data() + zStride*sub.
min()[2];
2152 for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
2153 DenseValueType* a1 = a0 + x*xStride;
2154 for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
2155 DenseValueType* a2 = a1 + y*yStride;
2157 z < ez; ++z, a2 += zStride)
2159 *a2 = DenseValueType(value);
2173 template<
typename ChildT, Index Log2Dim>
2184 const ValueType zero = zeroVal<ValueType>();
2193 iter->writeTopology(os, toHalf);
2198 template<
typename ChildT, Index Log2Dim>
2202 #ifndef OPENVDB_2_ABI_COMPATIBLE 2214 #ifdef OPENVDB_2_ABI_COMPATIBLE 2220 child->readTopology(is);
2223 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2228 const bool oldVersion =
2234 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[numValues]);
2244 assert(n == numValues);
2253 #ifdef OPENVDB_2_ABI_COMPATIBLE 2259 child->readTopology(is, fromHalf);
2268 template<
typename ChildT, Index Log2Dim>
2269 inline const typename ChildT::ValueType&
2276 template<
typename ChildT, Index Log2Dim>
2277 inline const typename ChildT::ValueType&
2288 template<
typename ChildT, Index Log2Dim>
2306 template<
typename ChildT, Index Log2Dim>
2311 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2318 for (
Index i = r.begin(), end=r.end();
i!=end; ++
i) {
2319 if (mNode->mChildMask.isOn(
i)) {
2320 mNode->mNodes[
i].getChild()->voxelizeActiveTiles(
true);
2321 }
else if (mNode->mValueMask.isOn(
i)) {
2322 const Coord &ijk = mNode->offsetToGlobalCoord(
i);
2324 child->voxelizeActiveTiles(
true);
2325 mNode->mNodes[
i].setChild(child);
2332 template<
typename ChildT, Index Log2Dim>
2344 iter->voxelizeActiveTiles(
false);
2352 template<
typename ChildT, Index Log2Dim>
2353 template<MergePolicy Policy>
2366 const Index n = iter.pos();
2370 background, otherBackground);
2378 child->resetBackground(otherBackground, background);
2385 const Index n = iter.pos();
2398 const Index n = iter.pos();
2401 mNodes[n].
getChild()->template merge<Policy>(*iter, background, otherBackground);
2409 child->resetBackground(otherBackground, background);
2420 const Index n = iter.pos();
2423 mNodes[n].
getChild()->template merge<Policy>(*iter, background, otherBackground);
2430 child->resetBackground(otherBackground, background);
2443 const Index n = iter.pos();
2446 mNodes[n].
getChild()->template merge<Policy>(iter.getValue(),
true);
2461 template<
typename ChildT, Index Log2Dim>
2462 template<MergePolicy Policy>
2471 if (!tileActive)
return;
2475 const Index n = iter.pos();
2481 iter.setValue(tileValue);
2492 template<
typename ChildT, Index Log2Dim>
2493 template<
typename OtherInternalNode>
2498 { tV = (tV | sV) & ~tC; }
2502 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2505 t->mChildMask |= s->mChildMask;
2507 t->mValueMask.foreach(s->mValueMask, t->mChildMask, op);
2508 assert((t->mValueMask & t->mChildMask).isOff());
2511 for (
Index i = r.begin(), end=r.end();
i!=end; ++
i) {
2512 if (s->mChildMask.isOn(
i)) {
2513 const typename OtherInternalNode::ChildNodeType& other = *(s->mNodes[
i].getChild());
2514 if (t->mChildMask.isOn(
i)) {
2515 t->mNodes[
i].getChild()->topologyUnion(other);
2517 ChildT* child =
new ChildT(other, t->mNodes[
i].getValue(),
TopologyCopy());
2519 t->mNodes[
i].setChild(child);
2521 }
else if (s->mValueMask.isOn(
i) && t->mChildMask.isOn(
i)) {
2522 t->mNodes[
i].getChild()->setValuesOn();
2526 const OtherInternalNode*
s;
2530 template<
typename ChildT, Index Log2Dim>
2531 template<
typename OtherChildT>
2538 template<
typename ChildT, Index Log2Dim>
2539 template<
typename OtherInternalNode>
2544 { tC = (tC & (sC | sV)) | (tV & sC); }
2547 const ValueType& background) : s(source), t(target), b(background) {
2549 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2553 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op);
2555 t->mValueMask &= s->mValueMask;
2556 assert((t->mValueMask & t->mChildMask).isOff());
2559 for (
Index i = r.begin(), end=r.end();
i!=end; ++
i) {
2560 if (t->mChildMask.isOn(
i)) {
2562 if (s->mChildMask.isOn(
i)) {
2563 child->topologyIntersection(*(s->mNodes[
i].getChild()), b);
2564 }
else if (s->mValueMask.isOff(
i)) {
2566 t->mNodes[
i].setValue(b);
2568 }
else if (t->mValueMask.isOn(
i) && s->mChildMask.isOn(
i)) {
2569 t->mNodes[
i].setChild(
new ChildT(*(s->mNodes[
i].getChild()),
2574 const OtherInternalNode*
s;
2579 template<
typename ChildT, Index Log2Dim>
2580 template<
typename OtherChildT>
2588 template<
typename ChildT, Index Log2Dim>
2589 template<
typename OtherInternalNode>
2594 { tC = (tC & (sC | ~sV)) | (tV & sC); }
2597 { tV &= ~((tC & sV) | (sC | sV)); }
2600 const ValueType& background) : s(source), t(target), b(background) {
2602 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2607 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op1);
2610 t->mValueMask.foreach(t->mChildMask, s->mValueMask, oldChildMask, op2);
2611 assert((t->mValueMask & t->mChildMask).isOff());
2614 for (
Index i = r.begin(), end=r.end();
i!=end; ++
i) {
2615 if (t->mChildMask.isOn(
i)) {
2617 if (s->mChildMask.isOn(
i)) {
2618 child->topologyDifference(*(s->mNodes[
i].getChild()), b);
2619 }
else if (s->mValueMask.isOn(
i)) {
2621 t->mNodes[
i].setValue(b);
2623 }
else if (t->mValueMask.isOn(
i)) {
2624 if (s->mChildMask.isOn(
i)) {
2625 const typename OtherInternalNode::ChildNodeType& other =
2626 *(s->mNodes[
i].getChild());
2627 ChildT* child =
new ChildT(other.origin(), t->mNodes[
i].getValue(),
true);
2629 t->mNodes[
i].setChild(child);
2634 const OtherInternalNode*
s;
2639 template<
typename ChildT, Index Log2Dim>
2640 template<
typename OtherChildT>
2652 template<
typename ChildT, Index Log2Dim>
2653 template<
typename CombineOp>
2657 const ValueType zero = zeroVal<ValueType>();
2702 if (child && otherChild) {
2703 child->combine(*otherChild, op);
2710 template<
typename ChildT, Index Log2Dim>
2711 template<
typename CombineOp>
2723 .setBIsActive(valueIsActive));
2730 if (child) child->combine(value, valueIsActive, op);
2739 template<
typename ChildT, Index Log2Dim>
2740 template<
typename CombineOp,
typename OtherNodeType>
2751 .setBRef(other1.mNodes[
i].getValue())
2752 .setBIsActive(other1.isValueMaskOn(
i)));
2761 : other1.mNodes[
i].getChild()->origin();
2770 }
else if (other1.isChildMaskOff(
i)) {
2774 other1.mNodes[
i].getValue(), other1.isValueMaskOn(
i), op);
2779 *other1.mNodes[
i].getChild(), op);
2786 template<
typename ChildT, Index Log2Dim>
2787 template<
typename CombineOp,
typename OtherNodeType>
2790 bool valueIsActive, CombineOp& op)
2795 if (other.isChildMaskOff(
i)) {
2797 .setAIsActive(valueIsActive)
2798 .setBRef(other.mNodes[
i].getValue())
2799 .setBIsActive(other.isValueMaskOn(
i)));
2804 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[
i].getChild();
2813 mNodes[
i].
getChild()->combine2(value, *otherChild, valueIsActive, op);
2819 template<
typename ChildT, Index Log2Dim>
2820 template<
typename CombineOp,
typename OtherValueType>
2823 bool valueIsActive, CombineOp& op)
2832 .setBIsActive(valueIsActive));
2846 mNodes[
i].
getChild()->combine2(*otherChild, value, valueIsActive, op);
2855 template<
typename ChildT, Index Log2Dim>
2856 template<
typename BBoxOp>
2867 if (op.template descent<LEVEL>()) {
2872 op.operator()<
LEVEL>(
i->getNodeBoundingBox());
2874 op.template operator()<
LEVEL>(
i->getNodeBoundingBox());
2881 template<
typename ChildT, Index Log2Dim>
2882 template<
typename VisitorOp>
2886 doVisit<InternalNode, VisitorOp, ChildAllIter>(*
this, op);
2890 template<
typename ChildT, Index Log2Dim>
2891 template<
typename VisitorOp>
2895 doVisit<const InternalNode, VisitorOp, ChildAllCIter>(*
this, op);
2899 template<
typename ChildT, Index Log2Dim>
2900 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
2904 typename NodeT::ValueType val;
2905 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
2906 if (op(iter))
continue;
2907 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2917 template<
typename ChildT, Index Log2Dim>
2918 template<
typename OtherNodeType,
typename VisitorOp>
2923 typename OtherNodeType::ChildAllIter>(*
this, other, op);
2927 template<
typename ChildT, Index Log2Dim>
2928 template<
typename OtherNodeType,
typename VisitorOp>
2933 typename OtherNodeType::ChildAllCIter>(*
this, other, op);
2937 template<
typename ChildT, Index Log2Dim>
2940 typename OtherNodeT,
2942 typename ChildAllIterT,
2943 typename OtherChildAllIterT>
2948 static_assert(OtherNodeT::NUM_VALUES == NodeT::NUM_VALUES,
2949 "visit2() requires nodes to have the same dimensions");
2950 static_assert(OtherNodeT::LEVEL == NodeT::LEVEL,
2951 "visit2() requires nodes to be at the same tree level");
2953 typename NodeT::ValueType val;
2954 typename OtherNodeT::ValueType otherVal;
2956 ChildAllIterT iter =
self.beginChildAll();
2957 OtherChildAllIterT otherIter = other.beginChildAll();
2959 for ( ; iter && otherIter; ++iter, ++otherIter)
2961 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2963 typename ChildAllIterT::ChildNodeType* child =
2964 (skipBranch & 1U) ?
nullptr : iter.probeChild(val);
2965 typename OtherChildAllIterT::ChildNodeType* otherChild =
2966 (skipBranch & 2U) ?
nullptr : otherIter.probeChild(otherVal);
2968 if (child !=
nullptr && otherChild !=
nullptr) {
2969 child->visit2Node(*otherChild, op);
2970 }
else if (child !=
nullptr) {
2971 child->visit2(otherIter, op);
2972 }
else if (otherChild !=
nullptr) {
2973 otherChild->visit2(iter, op,
true);
2982 template<
typename ChildT, Index Log2Dim>
2983 template<
typename OtherChildAllIterType,
typename VisitorOp>
2986 VisitorOp& op,
bool otherIsLHS)
2988 doVisit2<InternalNode, VisitorOp, ChildAllIter, OtherChildAllIterType>(
2989 *
this, otherIter, op, otherIsLHS);
2993 template<
typename ChildT, Index Log2Dim>
2994 template<
typename OtherChildAllIterType,
typename VisitorOp>
2997 VisitorOp& op,
bool otherIsLHS)
const 2999 doVisit2<const InternalNode, VisitorOp, ChildAllCIter, OtherChildAllIterType>(
3000 *
this, otherIter, op, otherIsLHS);
3004 template<
typename ChildT, Index Log2Dim>
3005 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT,
typename OtherChildAllIterT>
3008 VisitorOp& op,
bool otherIsLHS)
3010 if (!otherIter)
return;
3012 const size_t skipBitMask = (otherIsLHS ? 2U : 1U);
3014 typename NodeT::ValueType val;
3015 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
3016 const size_t skipBranch =
static_cast<size_t>(
3017 otherIsLHS ? op(otherIter, iter) : op(iter, otherIter));
3019 typename ChildAllIterT::ChildNodeType* child =
3020 (skipBranch & skipBitMask) ?
nullptr : iter.probeChild(val);
3022 if (child !=
nullptr) child->visit2(otherIter, op, otherIsLHS);
3030 template<
typename ChildT, Index Log2Dim>
3035 iter->writeBuffers(os, toHalf);
3040 template<
typename ChildT, Index Log2Dim>
3045 iter->readBuffers(is, fromHalf);
3050 template<
typename ChildT, Index Log2Dim>
3053 const CoordBBox& clipBBox,
bool fromHalf)
3060 iter->readBuffers(is, clipBBox, fromHalf);
3064 ValueType background = zeroVal<ValueType>();
3066 background = *
static_cast<const ValueType*
>(bgPtr);
3068 this->
clip(clipBBox, background);
3075 template<
typename ChildT, Index Log2Dim>
3079 dims.push_back(Log2Dim);
3080 ChildNodeType::getNodeLog2Dims(dims);
3084 template<
typename ChildT, Index Log2Dim>
3088 assert(n<(1<<3*Log2Dim));
3089 xyz.
setX(n >> 2*Log2Dim);
3090 n &= ((1<<2*Log2Dim)-1);
3091 xyz.
setY(n >> Log2Dim);
3092 xyz.
setZ(n & ((1<<Log2Dim)-1));
3096 template<
typename ChildT, Index Log2Dim>
3100 return (((xyz[0] & (
DIM-1u)) >> ChildNodeType::TOTAL) << 2*Log2Dim)
3101 + (((xyz[1] & (
DIM-1u)) >> ChildNodeType::TOTAL) << Log2Dim)
3102 + ((xyz[2] & (
DIM-1u)) >> ChildNodeType::TOTAL);
3106 template<
typename ChildT, Index Log2Dim>
3112 local <<= ChildT::TOTAL;
3113 return local + this->
origin();
3120 template<
typename ChildT, Index Log2Dim>
3121 template<
typename ArrayT>
3125 using T =
typename ArrayT::value_type;
3126 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3127 using ArrayChildT =
typename std::conditional<
3128 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3131 if (std::is_same<T, ArrayChildT*>::value) {
3132 array.push_back(reinterpret_cast<T>(
mNodes[iter.pos()].
getChild()));
3134 iter->getNodes(array);
3140 template<
typename ChildT, Index Log2Dim>
3141 template<
typename ArrayT>
3145 using T =
typename ArrayT::value_type;
3146 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3147 static_assert(std::is_const<
typename std::remove_pointer<T>::type>::value,
3148 "argument to getNodes() must be an array of const node pointers");
3151 if (std::is_same<T, const ChildT*>::value) {
3152 array.push_back(reinterpret_cast<T>(
mNodes[iter.pos()].
getChild()));
3154 iter->getNodes(array);
3164 template<
typename ChildT, Index Log2Dim>
3165 template<
typename ArrayT>
3169 using T =
typename ArrayT::value_type;
3170 static_assert(std::is_pointer<T>::value,
"argument to stealNodes() must be a pointer array");
3171 using ArrayChildT =
typename std::conditional<
3172 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3175 const Index n = iter.pos();
3176 if (std::is_same<T, ArrayChildT*>::value) {
3177 array.push_back(reinterpret_cast<T>(
mNodes[n].getChild()));
3181 iter->stealNodes(array, value, state);
3192 template<
typename ChildT, Index Log2Dim>
3211 template<
typename ChildT, Index Log2Dim>
3212 template<
typename OtherChildNodeType, Index OtherLog2Dim>
3220 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
3226 template<
typename ChildT, Index Log2Dim>
3240 template<
typename ChildT, Index Log2Dim>
3252 template<
typename ChildT, Index Log2Dim>
3267 template<
typename ChildT, Index Log2Dim>
3274 template<
typename ChildT, Index Log2Dim>
3283 template<
typename ChildT, Index Log2Dim>
3284 inline const ChildT*
3295 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED void setChild(ChildT *child)
Definition: NodeUnion.h:69
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:115
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:779
Definition: InternalNode.h:149
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1538
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:1081
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:143
Level getLevel()
Return the current logging level.
Definition: logging.h:164
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1647
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2543
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...
TopologyDifference(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2599
const ValueT & getValue() const
Definition: NodeUnion.h:71
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
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:1318
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3228
TopologyCopy2(const OtherInternalNode *source, InternalNode *target, const ValueType &offValue, const ValueType &onValue)
Definition: InternalNode.h:982
Int32 z() const
Definition: Coord.h:156
_ChildNodeType ChildNodeType
Definition: InternalNode.h:63
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
TopologyUnion(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:2500
Coord & setZ(Int32 z)
Definition: Coord.h:105
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:3042
bool isEmpty() const
Definition: InternalNode.h:322
Definition: InternalNode.h:199
Definition: InternalNode.h:832
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:502
NodeMaskType mChildMask
Definition: InternalNode.h:837
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:261
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:58
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.
const ValueType & b
Definition: InternalNode.h:2636
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2613
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:987
DenseIter()
Definition: InternalNode.h:205
Int32 y() const
Definition: Coord.h:155
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:251
const OtherInternalNode * s
Definition: InternalNode.h:2634
uint32_t Index32
Definition: Types.h:55
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:391
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:3167
Definition: InternalNode.h:2497
ChildOffIter beginChildOff()
Definition: InternalNode.h:256
static void doVisit2Node(NodeT &, OtherNodeT &, VisitorOp &)
Definition: InternalNode.h:2945
const NodeMaskType & getChildMask() const
Definition: InternalNode.h:785
DenseIter< const InternalNode, const ChildNodeType, ValueType, ChildAll > ChildAllCIter
Definition: InternalNode.h:240
ChildAllIter beginChildAll()
Definition: InternalNode.h:257
tbb::atomic< Index32 > i
Definition: LeafBuffer.h:71
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
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:354
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:1922
ChildT & getItem(Index pos) const
Definition: InternalNode.h:163
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1699
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:191
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:1458
InternalNode * t
Definition: InternalNode.h:2635
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:1597
ChildIter()
Definition: InternalNode.h:159
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:261
static const Index DIM
Definition: InternalNode.h:73
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:1888
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:833
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:419
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.
ChildOnIter beginChildOn()
Definition: InternalNode.h:255
Definition: InternalNode.h:2307
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:82
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:1146
const OtherInternalNode * s
Definition: InternalNode.h:961
DenseIter< InternalNode, ChildNodeType, ValueType, ChildAll > ChildAllIter
Definition: InternalNode.h:239
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1619
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
Index32 nonLeafCount() const
Definition: InternalNode.h:1044
Definition: InternalNode.h:2593
Index32 Index
Definition: Types.h:57
Definition: NodeMasks.h:270
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:319
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:505
NodeMaskType mValueMask
Definition: InternalNode.h:837
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1848
InternalNode * t
Definition: InternalNode.h:916
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1563
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:2026
Definition: InternalNode.h:149
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:3098
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:1347
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:355
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:906
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:2270
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:1128
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:187
const ValueType & b
Definition: InternalNode.h:963
Definition: InternalNode.h:831
static Index dim()
Definition: InternalNode.h:275
const NodeMaskType & getValueMask() const
Definition: InternalNode.h:784
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1553
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:1272
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:2130
void topologyUnion(const InternalNode< OtherChildNodeType, Log2Dim > &other)
Union this branch's set of active values with the other branch's active values. The value type of the...
void merge(InternalNode &other, const ValueType &background, const ValueType &otherBackground)
Efficiently merge another tree into this tree using one of several schemes.
Definition: InternalNode.h:2355
NodeMaskType getValueOffMask() const
Definition: InternalNode.h:786
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:462
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:1860
void operator()(W &tV, const W &sC, const W &sV, const W &tC) const
Definition: InternalNode.h:2596
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1945
typename NodeMaskType::Word W
Definition: InternalNode.h:2496
const UnionType * getTable() const
Definition: InternalNode.h:793
typename ChildNodeType::ValueType ValueType
Definition: InternalNode.h:65
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:170
const AValueType & result() const
Get the output value.
Definition: Types.h:416
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:781
Definition: InternalNode.h:830
uint64_t Index64
Definition: Types.h:56
Definition: InternalNode.h:833
const ValueType & onV
Definition: InternalNode.h:999
NodeUnion< ValueType, ChildNodeType > UnionType
Definition: InternalNode.h:67
static Index getChildDim()
Definition: InternalNode.h:285
#define OPENVDB_VERSION_NAME
Definition: version.h:43
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:483
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1785
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2593
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:777
void translate(const Coord &t)
Translate this bounding box by .
Definition: Coord.h:458
bool isChildMaskOff() const
Definition: InternalNode.h:783
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:249
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:1298
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:108
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2200
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:1115
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:262
Index64 onTileCount() const
Definition: InternalNode.h:1104
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2510
Definition: InternalNode.h:828
typename ChildNodeType::BuildType BuildType
Definition: InternalNode.h:66
typename NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:144
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:1606
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...
Definition: InternalNode.h:2596
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1632
const OtherInternalNode * s
Definition: InternalNode.h:2574
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:339
InternalNode * t
Definition: InternalNode.h:2527
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:254
Index32 leafCount() const
Definition: InternalNode.h:1031
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of an Intern...
Definition: InternalNode.h:91
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2334
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:70
static void doVisit(NodeT &, VisitorOp &)
Definition: InternalNode.h:2902
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:3194
void save(std::ostream &os) const
Definition: NodeMasks.h:565
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:401
Definition: Exceptions.h:39
Coord & setX(Int32 x)
Definition: Coord.h:103
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:350
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:3214
ValueOffIter beginValueOff()
Definition: InternalNode.h:269
InternalNode * t
Definition: InternalNode.h:962
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:199
ValueIter()
Definition: InternalNode.h:180
Definition: version.h:110
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1491
void visit(VisitorOp &)
Definition: InternalNode.h:2884
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:443
const Coord & max() const
Definition: Coord.h:335
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:227
Definition: NodeMasks.h:239
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:259
Definition: InternalNode.h:177
bool resultIsActive() const
Definition: Types.h:435
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:209
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:371
Definition: version.h:101
typename NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:143
Definition: InternalNode.h:148
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: InternalNode.h:1976
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:181
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:1768
Definition: InternalNode.h:829
virtual ~InternalNode()
Definition: InternalNode.h:1018
Definition: InternalNode.h:148
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1825
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1663
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.
typename NodeMaskType::Word W
Definition: InternalNode.h:2592
typename BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:203
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2175
ValueOnIter beginValueOn()
Definition: InternalNode.h:267
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:424
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:221
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition: InternalNode.h:2742
static void doVisit2(NodeT &, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: InternalNode.h:3007
Index64 offVoxelCount() const
Definition: InternalNode.h:1069
ValueAllIter beginValueAll()
Definition: InternalNode.h:270
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:3254
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:326
typename NodeMaskType::Word W
Definition: InternalNode.h:2542
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:2082
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2655
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:1422
TopologyCopy1(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:946
VoxelizeActiveTiles(InternalNode &node)
Definition: InternalNode.h:2309
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:450
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...
Int32 x() const
Definition: Coord.h:154
Definition: InternalNode.h:148
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:253
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:263
Definition: NodeMasks.h:208
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
InternalNode * t
Definition: InternalNode.h:2575
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:265
TopologyIntersection(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2546
DeepCopy(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:902
Index64 Word
Definition: NodeMasks.h:316
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:526
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition: InternalNode.h:3276
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:3077
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:266
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:951
const ValueType & b
Definition: InternalNode.h:2576
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:1093
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:206
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:184
bool isValueMaskOff() const
Definition: InternalNode.h:780
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition: NodeMasks.h:462
InternalNode()
Default constructor.
Definition: InternalNode.h:99
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:503
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:48
Definition: InternalNode.h:149
void negate()
Change the sign of all the values represented in this node and its child nodes.
Definition: InternalNode.h:2290
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:2278
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:441
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
int32_t Int32
Definition: Types.h:59
static const Index NUM_VALUES
Definition: InternalNode.h:74
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:3086
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:307
InternalNode * mNode
Definition: InternalNode.h:2329
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2316
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:250
bool isValueMaskOn() const
Definition: InternalNode.h:778
void setValue(const ValueT &val)
Definition: NodeUnion.h:73
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
const OtherInternalNode * s
Definition: InternalNode.h:997
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:160
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2558
const OtherInternalNode * s
Definition: InternalNode.h:2526
Index64 onVoxelCount() const
Definition: InternalNode.h:1057
Coord & setY(Int32 y)
Definition: Coord.h:104
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1744
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:252
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:1170
void load(std::istream &is)
Definition: NodeMasks.h:569
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:232
const Coord & min() const
Definition: Coord.h:334
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:508
static Index getLevel()
Definition: InternalNode.h:278
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:3269
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3242
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:3108
void visit2Node(OtherNodeType &other, VisitorOp &)
Definition: InternalNode.h:2920
ChildT * getChild() const
Definition: NodeUnion.h:68
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:298
Definition: InternalNode.h:2543
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: InternalNode.h:3123
void operator()(W &tV, const W &sV, const W &tC) const
Definition: InternalNode.h:2497
Definition: InternalNode.h:60
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:457
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:413
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:145
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:1806
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:452
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:3032
Definition: InternalNode.h:156
boost::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:212
typename ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:64
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes ...
Definition: InternalNode.h:2858
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:296
InternalNode * t
Definition: InternalNode.h:998
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:839
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:206
static const Index LEVEL
Definition: InternalNode.h:75
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1574
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:782
Definition: InternalNode.h:56
const OtherInternalNode * s
Definition: InternalNode.h:915
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:1390