8 #ifndef OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 9 #define OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 16 #include <openvdb/version.h> 20 #include <tbb/parallel_for.h> 22 #include <type_traits> 33 template<
typename _ChildNodeType, Index Log2Dim>
39 using ValueType =
typename ChildNodeType::ValueType;
40 using BuildType =
typename ChildNodeType::BuildType;
46 TOTAL = Log2Dim + ChildNodeType::TOTAL,
48 NUM_VALUES = 1 << (3 * Log2Dim),
49 LEVEL = 1 + ChildNodeType::LEVEL;
51 NUM_VOXELS = uint64_t(1) << (3 * TOTAL);
55 template<
typename OtherValueType>
64 template<
typename OtherNodeType>
66 static const bool value =
95 template<
typename OtherChildNodeType>
101 template<
typename OtherChildNodeType>
108 template<
typename OtherChildNodeType>
127 template<
typename NodeT,
typename ChildT,
typename MaskIterT,
typename TagT>
129 MaskIterT, ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>
133 MaskIterT,
ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>(iter, parent) {}
138 return *(this->parent().getChildNode(pos));
142 void setItem(
Index pos,
const ChildT& c)
const { this->parent().resetChildNode(pos, &c); }
148 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
150 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
154 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
156 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
159 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
162 template<
typename ModifyOp>
165 op(this->parent().mNodes[pos].getValue());
170 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
172 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
183 if (this->parent().isChildMaskOn(pos)) {
184 child = this->parent().getChildNode(pos);
188 value = this->parent().mNodes[pos].getValue();
195 this->parent().resetChildNode(pos, child);
201 this->parent().unsetChildNode(pos, value);
253 static void getNodeLog2Dims(std::vector<Index>& dims);
260 static Index coordToOffset(
const Coord& xyz);
263 static void offsetToLocalCoord(
Index n, Coord& xyz);
265 Coord offsetToGlobalCoord(
Index n)
const;
268 const Coord&
origin()
const {
return mOrigin; }
270 void setOrigin(
const Coord& origin) { mOrigin = origin; }
279 void nodeCount(std::vector<Index64> &vec)
const;
281 void nodeCount(std::vector<Index32> &vec)
const;
285 Index64 onLeafVoxelCount()
const;
286 Index64 offLeafVoxelCount()
const;
296 void evalActiveBoundingBox(CoordBBox& bbox,
bool visitVoxels =
true)
const;
303 bool isEmpty()
const {
return mChildMask.isOff(); }
310 bool isConstant(
ValueType& firstValue,
bool& state,
311 const ValueType& tolerance = zeroVal<ValueType>())
const;
328 bool& state,
const ValueType& tolerance = zeroVal<ValueType>())
const;
331 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
334 bool isValueOn(
const Coord& xyz)
const;
338 bool isValueOff(
const Coord& xyz)
const;
343 bool hasActiveTiles()
const;
345 const ValueType& getValue(
const Coord& xyz)
const;
346 bool probeValue(
const Coord& xyz,
ValueType& value)
const;
350 Index getValueLevel(
const Coord& xyz)
const;
360 void setActiveState(
const Coord& xyz,
bool on);
362 void setValueOnly(
const Coord& xyz,
const ValueType& value);
364 void setValueOn(
const Coord& xyz);
366 void setValueOn(
const Coord& xyz,
const ValueType& value);
368 void setValueOff(
const Coord& xyz);
370 void setValueOff(
const Coord& xyz,
const ValueType& value);
374 template<
typename ModifyOp>
375 void modifyValue(
const Coord& xyz,
const ModifyOp&
op);
377 template<
typename ModifyOp>
378 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
384 template<
typename AccessorT>
385 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
391 template<
typename AccessorT>
392 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
398 template<
typename AccessorT>
399 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
405 template<
typename AccessorT>
406 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
413 template<
typename ModifyOp,
typename AccessorT>
414 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
420 template<
typename ModifyOp,
typename AccessorT>
421 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
427 template<
typename AccessorT>
428 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
434 template<
typename AccessorT>
435 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
442 template<
typename AccessorT>
443 bool probeValueAndCache(
const Coord& xyz,
ValueType& value, AccessorT&)
const;
451 template<
typename AccessorT>
452 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
460 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
461 void readTopology(std::istream&,
bool fromHalf =
false);
462 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
463 void readBuffers(std::istream&,
bool fromHalf =
false);
464 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
501 void setActiveStateUnsafe(
Index offset,
bool on);
509 void setValueOnUnsafe(
Index offset);
517 void setValueOffUnsafe(
Index offset);
538 void deleteChildUnsafe(
Index offset,
const ValueType& value,
bool active);
555 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
564 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
569 void voxelizeActiveTiles(
bool threaded =
true);
578 template<
typename DenseT>
579 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
583 template<MergePolicy Policy>
588 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
602 template<
typename OtherChildNodeType>
618 template<
typename OtherChildNodeType>
633 template<
typename OtherChildNodeType>
637 template<
typename CombineOp>
639 template<
typename CombineOp>
642 template<
typename CombineOp,
typename OtherNodeType >
643 void combine2(
const InternalNode& other0,
const OtherNodeType& other1, CombineOp&);
644 template<
typename CombineOp,
typename OtherNodeType >
645 void combine2(
const ValueType& value,
const OtherNodeType& other,
bool valIsActive, CombineOp&);
646 template<
typename CombineOp,
typename OtherValueType>
647 void combine2(
const InternalNode& other,
const OtherValueType&,
bool valIsActive, CombineOp&);
663 template<
typename AccessorT>
674 template<
typename NodeT>
675 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
687 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
694 template<
typename AccessorT>
695 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
700 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
701 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
702 template<
typename NodeType>
const NodeType*
probeNode(
const Coord& xyz)
const {
return this->probeConstNode<NodeType>(xyz); }
709 const ChildNodeType* probeConstChild(
const Coord& xyz)
const;
744 template<
typename NodeType,
typename AccessorT>
745 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
746 template<
typename NodeType,
typename AccessorT>
747 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
754 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
761 template<
typename AccessorT>
762 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
763 template<
typename AccessorT>
764 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
765 template<
typename AccessorT>
766 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
779 template<
typename AccessorT>
780 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
805 template<
typename ArrayT>
806 void getNodes(ArrayT& array);
807 template<
typename ArrayT>
808 void getNodes(ArrayT& array)
const;
834 template<
typename ArrayT>
835 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
843 template<
typename OtherChildNodeType, Index OtherLog2Dim>
901 template<
typename OtherInternalNode>
struct DeepCopy;
924 template<
typename ChildT1, Index Dim1,
typename NodeT2>
926 static const bool value =
false;
929 template<
typename ChildT1, Index Dim1,
typename ChildT2>
931 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
939 template<
typename ChildT, Index Log2Dim>
943 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(background);
947 template<
typename ChildT, Index Log2Dim>
950 mOrigin(origin[0] & ~(DIM - 1),
951 origin[1] & ~(DIM - 1),
952 origin[2] & ~(DIM - 1))
961 template<
typename ChildT, Index Log2Dim>
971 template<
typename ChildT, Index Log2Dim>
972 template<
typename OtherInternalNode>
976 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
980 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
981 if (s->mChildMask.isOff(i)) {
982 t->mNodes[i].setValue(
ValueType(s->mNodes[i].getValue()));
984 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild())));
988 const OtherInternalNode*
s;
992 template<
typename ChildT, Index Log2Dim>
1005 template<
typename ChildT, Index Log2Dim>
1006 template<
typename OtherChildNodeType>
1017 template<
typename ChildT, Index Log2Dim>
1018 template<
typename OtherInternalNode>
1022 const ValueType& background) : s(source), t(target), b(background) {
1023 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
1027 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
1028 if (s->isChildMaskOn(i)) {
1029 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
1032 t->mNodes[i].setValue(b);
1036 const OtherInternalNode*
s;
1041 template<
typename ChildT, Index Log2Dim>
1042 template<
typename OtherChildNodeType>
1054 template<
typename ChildT, Index Log2Dim>
1055 template<
typename OtherInternalNode>
1060 : s(source), t(target), offV(offValue), onV(onValue) {
1061 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
1064 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
1065 if (s->isChildMaskOn(i)) {
1066 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
1069 t->mNodes[i].setValue(s->isValueMaskOn(i) ? onV : offV);
1073 const OtherInternalNode*
s;
1078 template<
typename ChildT, Index Log2Dim>
1079 template<
typename OtherChildNodeType>
1093 template<
typename ChildT, Index Log2Dim>
1106 template<
typename ChildT, Index Log2Dim>
1113 sum += iter->leafCount();
1118 template<
typename ChildT, Index Log2Dim>
1124 if (ChildNodeType::LEVEL > 0 && count > 0) {
1125 for (
auto iter = this->
cbeginChildOn(); iter; ++iter) iter->nodeCount(vec);
1127 vec[ChildNodeType::LEVEL] += count;
1130 template<
typename ChildT, Index Log2Dim>
1136 if (ChildNodeType::LEVEL > 0 && count > 0) {
1139 iter->nodeCount(vec);
1143 vec[ChildNodeType::LEVEL] += count;
1147 template<
typename ChildT, Index Log2Dim>
1154 sum += iter->nonLeafCount();
1160 template<
typename ChildT, Index Log2Dim>
1168 template<
typename ChildT, Index Log2Dim>
1174 sum += iter->onVoxelCount();
1180 template<
typename ChildT, Index Log2Dim>
1186 sum += iter->offVoxelCount();
1192 template<
typename ChildT, Index Log2Dim>
1204 template<
typename ChildT, Index Log2Dim>
1215 template<
typename ChildT, Index Log2Dim>
1221 sum += iter->onTileCount();
1226 template<
typename ChildT, Index Log2Dim>
1233 sum += iter->memUsage();
1239 template<
typename ChildT, Index Log2Dim>
1243 if (bbox.isInside(this->getNodeBoundingBox()))
return;
1246 bbox.expand(i.getCoord(), ChildT::DIM);
1249 i->evalActiveBoundingBox(bbox, visitVoxels);
1257 template<
typename ChildT, Index Log2Dim>
1264 const Index i = iter.pos();
1266 child->prune(tolerance);
1267 if (child->isConstant(value, state, tolerance)) {
1280 template<
typename ChildT, Index Log2Dim>
1281 template<
typename NodeT>
1285 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1286 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1291 if (std::is_same<NodeT, ChildT>::value) {
1296 return (std::is_same<NodeT, ChildT>::value)
1297 ?
reinterpret_cast<NodeT*
>(child)
1298 : child->template stealNode<NodeT>(xyz, value, state);
1306 template<
typename ChildT, Index Log2Dim>
1307 template<
typename NodeT>
1311 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1312 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1317 return (std::is_same<NodeT, ChildT>::value)
1318 ?
reinterpret_cast<NodeT*
>(child)
1319 : child->template probeNode<NodeT>(xyz);
1324 template<
typename ChildT, Index Log2Dim>
1325 template<
typename NodeT,
typename AccessorT>
1329 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1330 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1335 acc.insert(xyz, child);
1336 return (std::is_same<NodeT, ChildT>::value)
1337 ?
reinterpret_cast<NodeT*
>(child)
1338 : child->template probeNodeAndCache<NodeT>(xyz, acc);
1343 template<
typename ChildT, Index Log2Dim>
1344 template<
typename NodeT>
1348 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1349 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1354 return (std::is_same<NodeT, ChildT>::value)
1355 ?
reinterpret_cast<const NodeT*
>(child)
1356 : child->template probeConstNode<NodeT>(xyz);
1361 template<
typename ChildT, Index Log2Dim>
1362 template<
typename NodeT,
typename AccessorT>
1366 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1367 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1372 acc.insert(xyz, child);
1373 return (std::is_same<NodeT, ChildT>::value)
1374 ?
reinterpret_cast<const NodeT*
>(child)
1375 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
1383 template<
typename ChildT, Index Log2Dim>
1391 template<
typename ChildT, Index Log2Dim>
1392 inline const ChildT*
1399 template<
typename ChildT, Index Log2Dim>
1407 template<
typename ChildT, Index Log2Dim>
1408 inline const ChildT*
1415 template<
typename ChildT, Index Log2Dim>
1424 template<
typename ChildT, Index Log2Dim>
1425 inline const ChildT*
1433 template<
typename ChildT, Index Log2Dim>
1444 template<
typename ChildT, Index Log2Dim>
1445 inline const ChildT*
1459 template<
typename ChildT, Index Log2Dim>
1460 inline typename ChildT::LeafNodeType*
1463 return this->
template probeNode<LeafNodeType>(xyz);
1467 template<
typename ChildT, Index Log2Dim>
1468 template<
typename AccessorT>
1469 inline typename ChildT::LeafNodeType*
1472 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
1476 template<
typename ChildT, Index Log2Dim>
1477 template<
typename AccessorT>
1478 inline const typename ChildT::LeafNodeType*
1485 template<
typename ChildT, Index Log2Dim>
1486 inline const typename ChildT::LeafNodeType*
1489 return this->
template probeConstNode<LeafNodeType>(xyz);
1493 template<
typename ChildT, Index Log2Dim>
1494 template<
typename AccessorT>
1495 inline const typename ChildT::LeafNodeType*
1498 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
1505 template<
typename ChildT, Index Log2Dim>
1510 const Coord& xyz = leaf->origin();
1512 ChildT* child =
nullptr;
1514 if (ChildT::LEVEL>0) {
1517 child =
reinterpret_cast<ChildT*
>(leaf);
1521 if (ChildT::LEVEL>0) {
1525 child =
reinterpret_cast<ChildT*
>(leaf);
1529 child->addLeaf(leaf);
1533 template<
typename ChildT, Index Log2Dim>
1534 template<
typename AccessorT>
1539 const Coord& xyz = leaf->origin();
1541 ChildT* child =
nullptr;
1543 if (ChildT::LEVEL>0) {
1545 acc.insert(xyz, child);
1547 child =
reinterpret_cast<ChildT*
>(leaf);
1551 if (ChildT::LEVEL>0) {
1553 acc.insert(xyz, child);
1556 child =
reinterpret_cast<ChildT*
>(leaf);
1560 child->addLeafAndCache(leaf, acc);
1567 template<
typename ChildT, Index Log2Dim>
1572 const Coord& xyz = child->origin();
1574 if (Coord((xyz & ~(
DIM-1))) != this->
origin())
return false;
1583 template<
typename ChildT, Index Log2Dim>
1593 template<
typename ChildT, Index Log2Dim>
1598 if (
LEVEL >= level) {
1601 if (
LEVEL > level) {
1604 child->addTile(level, xyz, value, state);
1611 if (
LEVEL > level) {
1612 child->addTile(level, xyz, value, state);
1624 template<
typename ChildT, Index Log2Dim>
1625 template<
typename AccessorT>
1628 const ValueType& value,
bool state, AccessorT& acc)
1630 if (
LEVEL >= level) {
1633 if (
LEVEL > level) {
1636 acc.insert(xyz, child);
1637 child->addTileAndCache(level, xyz, value, state, acc);
1644 if (
LEVEL > level) {
1645 acc.insert(xyz, child);
1646 child->addTileAndCache(level, xyz, value, state, acc);
1661 template<
typename ChildT, Index Log2Dim>
1662 inline typename ChildT::LeafNodeType*
1666 ChildT* child =
nullptr;
1673 return child->touchLeaf(xyz);
1677 template<
typename ChildT, Index Log2Dim>
1678 template<
typename AccessorT>
1679 inline typename ChildT::LeafNodeType*
1686 acc.insert(xyz,
mNodes[n].getChild());
1694 template<
typename ChildT, Index Log2Dim>
1714 template<
typename ChildT, Index Log2Dim>
1727 if ((maxValue - v) > tolerance)
return false;
1729 }
else if (v > maxValue) {
1730 if ((v - minValue) > tolerance)
return false;
1741 template<
typename ChildT, Index Log2Dim>
1749 if (iter->hasActiveTiles())
return true;
1756 template<
typename ChildT, Index Log2Dim>
1765 template<
typename ChildT, Index Log2Dim>
1774 template<
typename ChildT, Index Log2Dim>
1775 template<
typename AccessorT>
1781 acc.insert(xyz,
mNodes[n].getChild());
1786 template<
typename ChildT, Index Log2Dim>
1787 inline const typename ChildT::ValueType&
1795 template<
typename ChildT, Index Log2Dim>
1796 template<
typename AccessorT>
1797 inline const typename ChildT::ValueType&
1802 acc.insert(xyz,
mNodes[n].getChild());
1809 template<
typename ChildT, Index Log2Dim>
1817 template<
typename ChildT, Index Log2Dim>
1818 template<
typename AccessorT>
1824 acc.insert(xyz,
mNodes[n].getChild());
1831 template<
typename ChildT, Index Log2Dim>
1843 template<
typename ChildT, Index Log2Dim>
1844 template<
typename AccessorT>
1851 acc.insert(xyz,
mNodes[n].getChild());
1852 return mNodes[n].
getChild()->probeValueAndCache(xyz, value, acc);
1859 template<
typename ChildT, Index Log2Dim>
1875 template<
typename ChildT, Index Log2Dim>
1891 template<
typename ChildT, Index Log2Dim>
1910 template<
typename ChildT, Index Log2Dim>
1911 template<
typename AccessorT>
1930 acc.insert(xyz, child);
1931 child->setValueOffAndCache(xyz, value, acc);
1936 template<
typename ChildT, Index Log2Dim>
1955 template<
typename ChildT, Index Log2Dim>
1956 template<
typename AccessorT>
1974 acc.insert(xyz,
mNodes[n].getChild());
1980 template<
typename ChildT, Index Log2Dim>
1996 template<
typename ChildT, Index Log2Dim>
1997 template<
typename AccessorT>
2012 acc.insert(xyz,
mNodes[n].getChild());
2018 template<
typename ChildT, Index Log2Dim>
2036 template<
typename ChildT, Index Log2Dim>
2037 template<
typename AccessorT>
2054 acc.insert(xyz, child);
2055 child->setActiveStateAndCache(xyz, on, acc);
2060 template<
typename ChildT, Index Log2Dim>
2071 template<
typename ChildT, Index Log2Dim>
2072 template<
typename ModifyOp>
2082 bool createChild = !active;
2099 template<
typename ChildT, Index Log2Dim>
2100 template<
typename ModifyOp,
typename AccessorT>
2111 bool createChild = !active;
2127 acc.insert(xyz, child);
2128 child->modifyValueAndCache(xyz, op, acc);
2133 template<
typename ChildT, Index Log2Dim>
2134 template<
typename ModifyOp>
2143 bool modifiedState = !tileState;
2145 op(modifiedVal, modifiedState);
2153 if (hasChild)
mNodes[n].
getChild()->modifyValueAndActiveState(xyz, op);
2156 template<
typename ChildT, Index Log2Dim>
2157 template<
typename ModifyOp,
typename AccessorT>
2160 const Coord& xyz,
const ModifyOp&
op, AccessorT& acc)
2167 bool modifiedState = !tileState;
2169 op(modifiedVal, modifiedState);
2179 acc.insert(xyz, child);
2180 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
2188 template<
typename ChildT, Index Log2Dim>
2193 if (!clipBBox.hasOverlap(nodeBBox)) {
2195 this->
fill(nodeBBox, background,
false);
2196 }
else if (clipBBox.isInside(nodeBBox)) {
2207 CoordBBox tileBBox(xyz, xyz.offsetBy(ChildT::DIM - 1));
2208 if (!clipBBox.hasOverlap(tileBBox)) {
2213 }
else if (!clipBBox.isInside(tileBBox)) {
2221 tileBBox.intersect(clipBBox);
2226 this->
fill(tileBBox, val, on);
2238 template<
typename ChildT, Index Log2Dim>
2243 clippedBBox.intersect(bbox);
2244 if (!clippedBBox)
return;
2248 Coord xyz, tileMin, tileMax;
2249 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.x() + 1) {
2251 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.y() + 1) {
2253 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.z() + 1) {
2259 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2261 if (xyz != tileMin || Coord::lessThan(clippedBBox.max(), tileMax)) {
2265 ChildT* child =
nullptr;
2278 child->fill(CoordBBox(xyz, tmp), value, active);
2294 template<
typename ChildT, Index Log2Dim>
2299 clippedBBox.intersect(bbox);
2300 if (!clippedBBox)
return;
2304 Coord xyz, tileMin, tileMax;
2305 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.x() + 1) {
2307 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.y() + 1) {
2309 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.z() + 1) {
2316 ChildT* child =
nullptr;
2328 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2331 child->denseFill(CoordBBox{xyz, clippedBBox.max()}, value, active);
2341 template<
typename ChildT, Index Log2Dim>
2342 template<
typename DenseT>
2346 using DenseValueType =
typename DenseT::ValueType;
2348 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2349 const Coord&
min = dense.bbox().min();
2350 for (Coord xyz = bbox.min(),
max; xyz[0] <= bbox.max()[0]; xyz[0] =
max[0] + 1) {
2351 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] =
max[1] + 1) {
2352 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] =
max[2] + 1) {
2364 sub.translate(-min);
2365 DenseValueType* a0 = dense.data() + zStride*sub.min()[2];
2366 for (
Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
2367 DenseValueType* a1 = a0 + x*xStride;
2368 for (
Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
2369 DenseValueType* a2 = a1 + y*yStride;
2370 for (
Int32 z = sub.min()[2], ez = sub.max()[2]+1;
2371 z < ez; ++z, a2 += zStride)
2373 *a2 = DenseValueType(value);
2387 template<
typename ChildT, Index Log2Dim>
2398 const ValueType zero = zeroVal<ValueType>();
2407 iter->writeTopology(os, toHalf);
2412 template<
typename ChildT, Index Log2Dim>
2428 child->readTopology(is);
2431 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2436 const bool oldVersion =
2442 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[numValues]);
2463 child->readTopology(is, fromHalf);
2472 template<
typename ChildT, Index Log2Dim>
2473 inline const typename ChildT::ValueType&
2480 template<
typename ChildT, Index Log2Dim>
2481 inline const typename ChildT::ValueType&
2492 template<
typename ChildT, Index Log2Dim>
2493 inline const typename ChildT::ValueType&
2501 template<
typename ChildT, Index Log2Dim>
2511 template<
typename ChildT, Index Log2Dim>
2520 template<
typename ChildT, Index Log2Dim>
2521 inline const ChildT*
2529 template<
typename ChildT, Index Log2Dim>
2530 inline const ChildT*
2536 template<
typename ChildT, Index Log2Dim>
2545 template<
typename ChildT, Index Log2Dim>
2554 template<
typename ChildT, Index Log2Dim>
2563 template<
typename ChildT, Index Log2Dim>
2573 template<
typename ChildT, Index Log2Dim>
2582 template<
typename ChildT, Index Log2Dim>
2592 template<
typename ChildT, Index Log2Dim>
2604 template<
typename ChildT, Index Log2Dim>
2616 template<
typename ChildT, Index Log2Dim>
2630 template<
typename ChildT, Index Log2Dim>
2642 template<
typename ChildT, Index Log2Dim>
2660 template<
typename ChildT, Index Log2Dim>
2665 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2672 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2673 if (mNode->mChildMask.isOn(i)) {
2674 mNode->mNodes[i].getChild()->voxelizeActiveTiles(
true);
2675 }
else if (mNode->mValueMask.isOn(i)) {
2676 const Coord &ijk = mNode->offsetToGlobalCoord(i);
2678 child->voxelizeActiveTiles(
true);
2679 mNode->mNodes[i].setChild(child);
2686 template<
typename ChildT, Index Log2Dim>
2698 iter->voxelizeActiveTiles(
false);
2706 template<
typename ChildT, Index Log2Dim>
2707 template<MergePolicy Policy>
2720 const Index n = iter.pos();
2724 background, otherBackground);
2732 child->resetBackground(otherBackground, background);
2739 const Index n = iter.pos();
2752 const Index n = iter.pos();
2755 mNodes[n].
getChild()->template merge<Policy>(*iter, background, otherBackground);
2763 child->resetBackground(otherBackground, background);
2774 const Index n = iter.pos();
2777 mNodes[n].
getChild()->template merge<Policy>(*iter, background, otherBackground);
2784 child->resetBackground(otherBackground, background);
2797 const Index n = iter.pos();
2800 mNodes[n].
getChild()->template merge<Policy>(iter.getValue(),
true);
2815 template<
typename ChildT, Index Log2Dim>
2816 template<MergePolicy Policy>
2825 if (!tileActive)
return;
2829 const Index n = iter.pos();
2835 iter.setValue(tileValue);
2846 template<
typename ChildT, Index Log2Dim>
2847 template<
typename OtherInternalNode>
2852 { tV = (tV | sV) & ~tC; }
2855 : s(source), t(target), mPreserveTiles(preserveTiles) {
2857 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2860 if (!mPreserveTiles) t->mChildMask |= s->mChildMask;
2861 else t->mChildMask |= (s->mChildMask & !t->mValueMask);
2864 t->mValueMask.foreach(s->mValueMask, t->mChildMask, op);
2868 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2869 if (s->mChildMask.isOn(i)) {
2870 const typename OtherInternalNode::ChildNodeType& other = *(s->mNodes[i].getChild());
2871 if (t->mChildMask.isOn(i)) {
2872 t->mNodes[i].getChild()->topologyUnion(other, mPreserveTiles);
2874 if (!mPreserveTiles || t->mValueMask.isOff(i)) {
2875 ChildT* child =
new ChildT(other, t->mNodes[i].getValue(),
TopologyCopy());
2877 t->mNodes[i].setChild(child);
2880 }
else if (s->mValueMask.isOn(i) && t->mChildMask.isOn(i)) {
2881 t->mNodes[i].getChild()->setValuesOn();
2885 const OtherInternalNode*
s;
2890 template<
typename ChildT, Index Log2Dim>
2891 template<
typename OtherChildT>
2898 template<
typename ChildT, Index Log2Dim>
2899 template<
typename OtherInternalNode>
2904 { tC = (tC & (sC | sV)) | (tV & sC); }
2907 const ValueType& background) : s(source), t(target), b(background) {
2909 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2913 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op);
2915 t->mValueMask &= s->mValueMask;
2919 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2920 if (t->mChildMask.isOn(i)) {
2922 if (s->mChildMask.isOn(i)) {
2923 child->topologyIntersection(*(s->mNodes[i].getChild()), b);
2924 }
else if (s->mValueMask.isOff(i)) {
2926 t->mNodes[i].setValue(b);
2928 }
else if (t->mValueMask.isOn(i) && s->mChildMask.isOn(i)) {
2929 t->mNodes[i].setChild(
new ChildT(*(s->mNodes[i].getChild()),
2934 const OtherInternalNode*
s;
2939 template<
typename ChildT, Index Log2Dim>
2940 template<
typename OtherChildT>
2948 template<
typename ChildT, Index Log2Dim>
2949 template<
typename OtherInternalNode>
2954 { tC = (tC & (sC | ~sV)) | (tV & sC); }
2957 { tV &= ~((tC & sV) | (sC | sV)); }
2960 const ValueType& background) : s(source), t(target), b(background) {
2962 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2967 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op1);
2970 t->mValueMask.foreach(t->mChildMask, s->mValueMask, oldChildMask, op2);
2974 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2975 if (t->mChildMask.isOn(i)) {
2977 if (s->mChildMask.isOn(i)) {
2978 child->topologyDifference(*(s->mNodes[i].getChild()), b);
2979 }
else if (s->mValueMask.isOn(i)) {
2981 t->mNodes[i].setValue(b);
2983 }
else if (t->mValueMask.isOn(i)) {
2984 if (s->mChildMask.isOn(i)) {
2985 const typename OtherInternalNode::ChildNodeType& other =
2986 *(s->mNodes[i].getChild());
2987 ChildT* child =
new ChildT(other.origin(), t->mNodes[i].getValue(),
true);
2989 t->mNodes[i].setChild(child);
2994 const OtherInternalNode*
s;
2999 template<
typename ChildT, Index Log2Dim>
3000 template<
typename OtherChildT>
3012 template<
typename ChildT, Index Log2Dim>
3013 template<
typename CombineOp>
3017 const ValueType zero = zeroVal<ValueType>();
3062 if (child && otherChild) {
3063 child->combine(*otherChild, op);
3070 template<
typename ChildT, Index Log2Dim>
3071 template<
typename CombineOp>
3083 .setBIsActive(valueIsActive));
3090 if (child) child->combine(value, valueIsActive, op);
3099 template<
typename ChildT, Index Log2Dim>
3100 template<
typename CombineOp,
typename OtherNodeType>
3111 .setBRef(other1.mNodes[i].getValue())
3112 .setBIsActive(other1.isValueMaskOn(i)));
3121 : other1.mNodes[i].getChild()->origin();
3130 }
else if (other1.isChildMaskOff(i)) {
3134 other1.mNodes[i].getValue(), other1.isValueMaskOn(i),
op);
3139 *other1.mNodes[i].getChild(),
op);
3146 template<
typename ChildT, Index Log2Dim>
3147 template<
typename CombineOp,
typename OtherNodeType>
3150 bool valueIsActive, CombineOp&
op)
3155 if (other.isChildMaskOff(i)) {
3157 .setAIsActive(valueIsActive)
3158 .setBRef(other.mNodes[i].getValue())
3159 .setBIsActive(other.isValueMaskOn(i)));
3164 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[i].getChild();
3173 mNodes[i].
getChild()->combine2(value, *otherChild, valueIsActive, op);
3179 template<
typename ChildT, Index Log2Dim>
3180 template<
typename CombineOp,
typename OtherValueType>
3183 bool valueIsActive, CombineOp&
op)
3192 .setBIsActive(valueIsActive));
3206 mNodes[i].
getChild()->combine2(*otherChild, value, valueIsActive, op);
3215 template<
typename ChildT, Index Log2Dim>
3220 iter->writeBuffers(os, toHalf);
3225 template<
typename ChildT, Index Log2Dim>
3230 iter->readBuffers(is, fromHalf);
3235 template<
typename ChildT, Index Log2Dim>
3238 const CoordBBox& clipBBox,
bool fromHalf)
3245 iter->readBuffers(is, clipBBox, fromHalf);
3249 ValueType background = zeroVal<ValueType>();
3251 background = *
static_cast<const ValueType*
>(bgPtr);
3253 this->
clip(clipBBox, background);
3260 template<
typename ChildT, Index Log2Dim>
3264 dims.push_back(Log2Dim);
3265 ChildNodeType::getNodeLog2Dims(dims);
3269 template<
typename ChildT, Index Log2Dim>
3274 xyz.setX(n >> 2*Log2Dim);
3275 n &= ((1<<2*Log2Dim)-1);
3276 xyz.setY(n >> Log2Dim);
3277 xyz.setZ(n & ((1<<Log2Dim)-1));
3281 template<
typename ChildT, Index Log2Dim>
3285 return (((xyz[0] & (
DIM-1u)) >> ChildNodeType::TOTAL) << 2*Log2Dim)
3286 + (((xyz[1] & (
DIM-1u)) >> ChildNodeType::TOTAL) << Log2Dim)
3287 + ((xyz[2] & (
DIM-1u)) >> ChildNodeType::TOTAL);
3291 template<
typename ChildT, Index Log2Dim>
3297 local <<= ChildT::TOTAL;
3298 return local + this->
origin();
3305 template<
typename ChildT, Index Log2Dim>
3306 template<
typename ArrayT>
3310 using T =
typename ArrayT::value_type;
3311 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3312 using ArrayChildT =
typename std::conditional<
3313 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3316 if (std::is_same<T, ArrayChildT*>::value) {
3317 array.push_back(reinterpret_cast<T>(
mNodes[iter.pos()].
getChild()));
3319 iter->getNodes(array);
3325 template<
typename ChildT, Index Log2Dim>
3326 template<
typename ArrayT>
3330 using T =
typename ArrayT::value_type;
3331 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3332 static_assert(std::is_const<
typename std::remove_pointer<T>::type>::value,
3333 "argument to getNodes() must be an array of const node pointers");
3336 if (std::is_same<T, const ChildT*>::value) {
3337 array.push_back(reinterpret_cast<T>(
mNodes[iter.pos()].
getChild()));
3339 iter->getNodes(array);
3349 template<
typename ChildT, Index Log2Dim>
3350 template<
typename ArrayT>
3354 using T =
typename ArrayT::value_type;
3355 static_assert(std::is_pointer<T>::value,
"argument to stealNodes() must be a pointer array");
3356 using ArrayChildT =
typename std::conditional<
3357 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3360 const Index n = iter.pos();
3361 if (std::is_same<T, ArrayChildT*>::value) {
3362 array.push_back(reinterpret_cast<T>(
mNodes[n].getChild()));
3366 iter->stealNodes(array, value, state);
3377 template<
typename ChildT, Index Log2Dim>
3385 mNodes[i].
getChild()->resetBackground(oldBackground, newBackground);
3396 template<
typename ChildT, Index Log2Dim>
3397 template<
typename OtherChildNodeType, Index OtherLog2Dim>
3405 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
3411 template<
typename ChildT, Index Log2Dim>
3425 template<
typename ChildT, Index Log2Dim>
3437 template<
typename ChildT, Index Log2Dim>
3452 template<
typename ChildT, Index Log2Dim>
3459 template<
typename ChildT, Index Log2Dim>
3468 template<
typename ChildT, Index Log2Dim>
3469 inline const ChildT*
3480 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED const ChildNodeType * probeConstChildUnsafe(Index offset) const
Return a pointer to the child node for a specific offset. If no such node exists, return nullptr...
Definition: InternalNode.h:1426
const OtherInternalNode * s
Definition: InternalNode.h:2994
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:443
void topologyUnion(const InternalNode< OtherChildNodeType, Log2Dim > &other, const bool preserveTiles=false)
Union this branch's set of active values with the other branch's active values. The value type of the...
TopologyIntersection(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2906
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:2344
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:159
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:2240
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:231
InternalNode * mNode
Definition: InternalNode.h:2683
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:2102
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:865
typename NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:116
Definition: InternalNode.h:906
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:1595
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1758
const OtherInternalNode * s
Definition: InternalNode.h:988
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...
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:568
const ChildNodeType * probeChildUnsafe(Index offset, ValueType &value, bool &active) const
Return a pointer to the child node for a specific offset. If no such node exists, return nullptr...
Definition: InternalNode.h:738
void setValueMask(Index n, bool on)
Definition: InternalNode.h:882
ChildNodeType * getChildUnsafe(Index offset)
Return the child node at offset.
Definition: InternalNode.h:2513
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:29
Definition: InternalNode.h:121
void deleteChildUnsafe(Index offset, const ValueType &value, bool active)
Delete a child node at offset and replace with the given value and active state.
Definition: InternalNode.h:2632
NodeMaskType mChildMask
Definition: InternalNode.h:910
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1743
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:1663
Definition: InternalNode.h:903
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:3293
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of an Intern...
Definition: InternalNode.h:65
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
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:2074
const ValueT & getValue() const
Definition: NodeUnion.h:43
typename NodeMaskType::Word W
Definition: InternalNode.h:2902
ChildNodeType * stealChildUnsafe(Index offset, const ValueType &value, bool active)
Replace a child node at offset with the given value and active state.
Definition: InternalNode.h:2618
const bool mPreserveTiles
Definition: InternalNode.h:2887
uint64_t Index64
Definition: Types.h:53
const NodeMaskType & getChildMask() const
Definition: InternalNode.h:869
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:199
Definition: InternalNode.h:2851
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1833
bool resultIsActive() const
Definition: Types.h:632
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1913
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:452
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:441
const ChildNodeType * probeConstChild(const Coord &xyz) const
Return a pointer to the child node that contains voxel (x, y, z). If no such node exists...
Definition: InternalNode.h:1393
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: InternalNode.h:3308
ChildAllIter beginChildAll()
Definition: InternalNode.h:229
InternalNode * t
Definition: InternalNode.h:2886
typename BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:175
ChildNodeType * probeChildUnsafe(Index offset)
Return a pointer to the child node for a specific offset. If no such node exists, return nullptr...
Definition: InternalNode.h:1417
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:270
Definition: InternalNode.h:128
void setActiveStateUnsafe(Index offset, bool on)
Set the tile active state at offset but don't change its value.
Definition: InternalNode.h:2538
Definition: InternalNode.h:171
bool isValueOff(const Coord &xyz) const
Return true if the voxel at the given coordinates is inactive.
Definition: InternalNode.h:1767
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:307
Definition: InternalNode.h:121
Definition: NodeMasks.h:270
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:1241
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:268
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:234
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2670
Definition: NodeMasks.h:239
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
InternalNode * t
Definition: InternalNode.h:2995
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:406
DeepCopy(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:975
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:237
Definition: InternalNode.h:120
TopologyCopy1(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:1021
bool isValueMaskOff() const
Definition: InternalNode.h:864
const ValueType & b
Definition: InternalNode.h:2996
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 isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:331
void resetChildUnsafe(Index offset, ChildNodeType *child)
Replace a child node at offset with the given child node.
Definition: InternalNode.h:2606
ChildT * getChild() const
Definition: NodeUnion.h:40
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:2136
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:1283
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:163
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:1536
void setValue(const ValueT &val)
Definition: NodeUnion.h:45
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:1206
bool isValueOff(Index offset) const
Return true if the voxel at the given offset is inactive.
Definition: InternalNode.h:340
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:300
ChildT & getItem(Index pos) const
Definition: InternalNode.h:135
int32_t Int32
Definition: Types.h:56
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:153
Index32 Index
Definition: Types.h:54
Definition: InternalNode.h:902
Index32 transientData() const
Return the transient data value.
Definition: InternalNode.h:273
typename NodeMaskType::Word W
Definition: InternalNode.h:2952
ValueOffIter beginValueOff()
Definition: InternalNode.h:241
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:3379
Index64 Word
Definition: NodeMasks.h:316
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:2482
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1777
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:225
const ChildNodeType * getConstChildUnsafe(Index offset) const
Return the child node at offset.
Definition: InternalNode.h:2522
void setChildUnsafe(Index offset, ChildNodeType *child)
Replace a tile at offset with the given child node.
Definition: InternalNode.h:2594
Definition: InternalNode.h:2661
TopologyUnion(const OtherInternalNode *source, InternalNode *target, const bool preserveTiles)
Definition: InternalNode.h:2854
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3427
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:226
ChildOffIter beginChildOff()
Definition: InternalNode.h:228
const NodeType * probeNode(const Coord &xyz) const
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: InternalNode.h:702
_ChildNodeType ChildNodeType
Definition: InternalNode.h:37
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:142
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:3399
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition: NodeMasks.h:462
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2918
ChildOnIter beginChildOn()
Definition: InternalNode.h:227
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:1811
Definition: InternalNode.h:904
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:128
bool addChild(ChildNodeType *child)
Add the given child node at this level deducing the offset from it's origin. If a child node with thi...
Definition: InternalNode.h:1569
ValueIter()
Definition: InternalNode.h:152
Index64 leafCount() const
Definition: InternalNode.h:1108
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:2709
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:132
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:979
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.
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:224
Definition: NodeMasks.h:208
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:1487
const NodeMaskType & getValueMask() const
Definition: InternalNode.h:868
const AValueType & result() const
Get the output value.
Definition: Types.h:613
DenseIter()
Definition: InternalNode.h:177
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:466
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:621
void setChild(ChildT *child)
Definition: NodeUnion.h:41
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:1259
Definition: InternalNode.h:34
void operator()(W &tV, const W &sV, const W &tC) const
Definition: InternalNode.h:2851
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
const ValueType & b
Definition: InternalNode.h:2936
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:861
const ChildNodeType * probeChildUnsafe(Index offset) const
Return a pointer to the child node for a specific offset. If no such node exists, return nullptr...
Definition: InternalNode.h:728
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:1228
ChildNodeType * probeChild(const Coord &xyz)
Return a pointer to the child node that contains voxel (x, y, z). If no such node exists...
Definition: InternalNode.h:1385
NodeMaskType mValueMask
Definition: InternalNode.h:910
Definition: InternalNode.h:905
void setValueOnlyUnsafe(Index offset, const ValueType &value)
Set the tile value at offset but don't change its value.
Definition: InternalNode.h:2547
Definition: InternalNode.h:901
void setValueOffUnsafe(Index offset)
Mark the tile inactive at offset but don't change its value.
Definition: InternalNode.h:2575
Definition: InternalNode.h:30
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:1982
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2867
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:3352
static const Index LEVEL
Definition: InternalNode.h:49
bool isValueMaskOn() const
Definition: InternalNode.h:862
Definition: Exceptions.h:13
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2903
Definition: InternalNode.h:2956
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2414
Index64 nonLeafCount() const
Definition: InternalNode.h:1149
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:3271
static const Index NUM_VALUES
Definition: InternalNode.h:48
ChildIter()
Definition: InternalNode.h:131
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:56
TopologyDifference(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2959
typename NodeMaskType::Word W
Definition: InternalNode.h:2850
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:443
InternalNode * t
Definition: InternalNode.h:989
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:1026
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2953
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
Level getLevel()
Return the current logging level.
Definition: logging.h:141
static void getNodeLog2Dims(std::vector< Index > &dims)
Populated an std::vector with the dimension of all the nodes in the branch starting with this node...
Definition: InternalNode.h:3262
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1958
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:156
ValueOnIter beginValueOn()
Definition: InternalNode.h:239
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:502
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:3227
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:912
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:526
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:483
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:3439
const OtherInternalNode * s
Definition: InternalNode.h:2934
Definition: InternalNode.h:120
const OtherInternalNode * s
Definition: InternalNode.h:1073
typename ChildNodeType::ValueType ValueType
Definition: InternalNode.h:39
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition: InternalNode.h:3102
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:233
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:2159
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:223
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:117
const ChildNodeType * probeChild(const Coord &xyz, ValueType &value, bool &active) const
Return a pointer to the child node that contains voxel (x, y, z). If no such node exists...
Definition: InternalNode.h:718
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:3217
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.
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:906
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:1507
uint32_t Index32
Definition: Types.h:52
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:336
static Index dim()
Definition: InternalNode.h:247
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: InternalNode.h:2190
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:1063
InternalNode * t
Definition: InternalNode.h:1037
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:3015
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:178
Index64 onVoxelCount() const
Definition: InternalNode.h:1170
const ValueType & b
Definition: InternalNode.h:1038
typename ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:38
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2973
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3413
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...
ValueAllIter beginValueAll()
Definition: InternalNode.h:242
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1999
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:1194
const UnionType * getTable() const
Definition: InternalNode.h:877
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:450
Definition: InternalNode.h:149
NodeUnion< ValueType, ChildNodeType > UnionType
Definition: InternalNode.h:41
void negate()
Change the sign of all the values represented in this node and its child nodes.
Definition: InternalNode.h:2644
Definition: InternalNode.h:2953
VoxelizeActiveTiles(InternalNode &node)
Definition: InternalNode.h:2663
typename std::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:184
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:2039
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:1461
Definition: InternalNode.h:2903
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:1627
Definition: version.h.in:262
const OtherInternalNode * s
Definition: InternalNode.h:1036
Index32 mTransientData
Transient data (not serialized)
Definition: InternalNode.h:914
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1788
typename ChildNodeType::BuildType BuildType
Definition: InternalNode.h:40
const ValueType & getValueUnsafe(Index offset) const
Return the tile value at offset.
Definition: InternalNode.h:2494
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1861
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:222
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:193
Definition: InternalNode.h:120
static Index getLevel()
Definition: InternalNode.h:250
static Index getChildDim()
Definition: InternalNode.h:257
InternalNode()
Default constructor.
Definition: InternalNode.h:73
void setTransientData(Index32 transientData)
Set the transient data value.
Definition: InternalNode.h:275
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 probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1846
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
const OtherInternalNode * s
Definition: InternalNode.h:2885
InternalNode * t
Definition: InternalNode.h:1074
bool isChildMaskOff() const
Definition: InternalNode.h:867
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:504
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:683
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:3283
const ValueType & onV
Definition: InternalNode.h:1075
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1696
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition: InternalNode.h:3461
void nodeCount(std::vector< Index64 > &vec) const
Definition: InternalNode.h:1120
const ChildNodeType * probeChild(const Coord &xyz) const
Return a pointer to the child node that contains voxel (x, y, z). If no such node exists...
Definition: InternalNode.h:710
void load(std::istream &is)
Definition: NodeMasks.h:569
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:235
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:221
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
TopologyCopy2(const OtherInternalNode *source, InternalNode *target, const ValueType &offValue, const ValueType &onValue)
Definition: InternalNode.h:1058
void operator()(W &tV, const W &sC, const W &sV, const W &tC) const
Definition: InternalNode.h:2956
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2389
NodeMaskType getValueOffMask() const
Definition: InternalNode.h:870
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
Definition: InternalNode.h:121
void save(std::ostream &os) const
Definition: NodeMasks.h:565
Index32 childCount() const
Definition: InternalNode.h:1162
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:457
Index64 onTileCount() const
Definition: InternalNode.h:1217
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:141
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:238
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:181
InternalNode * t
Definition: InternalNode.h:2935
static const Index DIM
Definition: InternalNode.h:47
~InternalNode()
Definition: InternalNode.h:1095
typename NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:115
Definition: version.h.in:253
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:2062
Index64 offVoxelCount() const
Definition: InternalNode.h:1182
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:3454
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:866
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:1820
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:178
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1877
bool isEmpty() const
Definition: InternalNode.h:303
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:863
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:646
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:2474
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:2296
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:508
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2688
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218
void setValueOnUnsafe(Index offset)
Mark the tile active at offset but don't change its value.
Definition: InternalNode.h:2556
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:114
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:2020
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:689