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>
30template<
typename, Index,
typename>
struct SameInternalConfig;
33template<
typename _ChildNodeType, Index Log2Dim>
39 using ValueType =
typename ChildNodeType::ValueType;
40 using BuildType =
typename ChildNodeType::BuildType;
46 TOTAL = Log2Dim + ChildNodeType::TOTAL,
49 LEVEL = 1 + ChildNodeType::LEVEL;
55 template<
typename OtherValueType>
58 OtherValueType>
::Type, Log2Dim>;
64 template<
typename OtherNodeType>
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>
138 return *(this->
parent().getChildNode(
pos));
148 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
150 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
162 template<
typename ModifyOp>
170 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
172 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
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);
207 using ChildOnIter = ChildIter<InternalNode, ChildNodeType, MaskOnIterator, ChildOn>;
208 using ChildOnCIter = ChildIter<const InternalNode,const ChildNodeType,MaskOnIterator,ChildOn>;
209 using ChildOffIter = ValueIter<InternalNode, const ValueType, MaskOffIterator, ChildOff>;
210 using ChildOffCIter = ValueIter<const InternalNode,const ValueType,MaskOffIterator,ChildOff>;
211 using ChildAllIter = DenseIter<InternalNode, ChildNodeType, ValueType, ChildAll>;
212 using ChildAllCIter = DenseIter<const InternalNode,const ChildNodeType, ValueType, ChildAll>;
214 using ValueOnIter = ValueIter<InternalNode, const ValueType, MaskOnIterator, ValueOn>;
215 using ValueOnCIter = ValueIter<const InternalNode, const ValueType, MaskOnIterator, ValueOn>;
216 using ValueOffIter = ValueIter<InternalNode, const ValueType, MaskOffIterator, ValueOff>;
217 using ValueOffCIter = ValueIter<const InternalNode,const ValueType,MaskOffIterator,ValueOff>;
218 using ValueAllIter = ValueIter<InternalNode, const ValueType, MaskOffIterator, ValueAll>;
219 using ValueAllCIter = ValueIter<const InternalNode,const ValueType,MaskOffIterator,ValueAll>;
374 template<
typename ModifyOp>
377 template<
typename ModifyOp>
384 template<
typename AccessorT>
391 template<
typename AccessorT>
398 template<
typename AccessorT>
405 template<
typename AccessorT>
413 template<
typename ModifyOp,
typename AccessorT>
420 template<
typename ModifyOp,
typename AccessorT>
427 template<
typename AccessorT>
434 template<
typename AccessorT>
442 template<
typename AccessorT>
451 template<
typename AccessorT>
583 template<
typename DenseT>
588 template<MergePolicy Policy>
593 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
607 template<
typename OtherChildNodeType>
623 template<
typename OtherChildNodeType>
638 template<
typename OtherChildNodeType>
642 template<
typename CombineOp>
644 template<
typename CombineOp>
647 template<
typename CombineOp,
typename OtherNodeType >
649 template<
typename CombineOp,
typename OtherNodeType >
650 void combine2(
const ValueType& value,
const OtherNodeType& other,
bool valIsActive, CombineOp&);
651 template<
typename CombineOp,
typename OtherValueType>
668 template<
typename AccessorT>
679 template<
typename NodeT>
699 template<
typename AccessorT>
749 template<
typename NodeType,
typename AccessorT>
751 template<
typename NodeType,
typename AccessorT>
766 template<
typename AccessorT>
768 template<
typename AccessorT>
770 template<
typename AccessorT>
784 template<
typename AccessorT>
810 template<
typename ArrayT>
812 template<
typename ArrayT>
839 template<
typename ArrayT>
848 template<
typename OtherChildNodeType, Index OtherLog2Dim>
905 struct VoxelizeActiveTiles;
906 template<
typename OtherInternalNode>
struct DeepCopy;
907 template<
typename OtherInternalNode>
struct TopologyCopy1;
908 template<
typename OtherInternalNode>
struct TopologyCopy2;
909 template<
typename OtherInternalNode>
struct TopologyUnion;
910 template<
typename OtherInternalNode>
struct TopologyDifference;
911 template<
typename OtherInternalNode>
struct TopologyIntersection;
929template<
typename ChildT1, Index Dim1,
typename NodeT2>
934template<
typename ChildT1, Index Dim1,
typename ChildT2>
936 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
944template<
typename ChildT, Index Log2Dim>
952template<
typename ChildT, Index Log2Dim>
966template<
typename ChildT, Index Log2Dim>
976template<
typename ChildT, Index Log2Dim>
977template<
typename OtherInternalNode>
981 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
985 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
986 if (
s->mChildMask.isOff(i)) {
987 t->mNodes[i].setValue(
ValueType(
s->mNodes[i].getValue()));
993 const OtherInternalNode*
s;
997template<
typename ChildT, Index Log2Dim>
1010template<
typename ChildT, Index Log2Dim>
1011template<
typename OtherChildNodeType>
1022template<
typename ChildT, Index Log2Dim>
1023template<
typename OtherInternalNode>
1027 const ValueType& background) :
s(source),
t(target),
b(background) {
1028 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
1032 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
1033 if (
s->isChildMaskOn(i)) {
1037 t->mNodes[i].setValue(
b);
1041 const OtherInternalNode*
s;
1046template<
typename ChildT, Index Log2Dim>
1047template<
typename OtherChildNodeType>
1059template<
typename ChildT, Index Log2Dim>
1060template<
typename OtherInternalNode>
1065 :
s(source),
t(target),
offV(offValue),
onV(onValue) {
1066 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
1069 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
1070 if (
s->isChildMaskOn(i)) {
1074 t->mNodes[i].setValue(
s->isValueMaskOn(i) ?
onV :
offV);
1078 const OtherInternalNode*
s;
1083template<
typename ChildT, Index Log2Dim>
1084template<
typename OtherChildNodeType>
1098template<
typename ChildT, Index Log2Dim>
1111template<
typename ChildT, Index Log2Dim>
1115 if (ChildNodeType::getLevel() == 0)
return mChildMask.countOn();
1118 sum +=
iter->leafCount();
1123template<
typename ChildT, Index Log2Dim>
1129 if (ChildNodeType::LEVEL > 0 && count > 0) {
1132 vec[ChildNodeType::LEVEL] += count;
1135template<
typename ChildT, Index Log2Dim>
1141 if (ChildNodeType::LEVEL > 0 && count > 0) {
1144 iter->nodeCount(vec);
1148 vec[ChildNodeType::LEVEL] += count;
1152template<
typename ChildT, Index Log2Dim>
1157 if (ChildNodeType::getLevel() == 0)
return sum;
1159 sum +=
iter->nonLeafCount();
1165template<
typename ChildT, Index Log2Dim>
1173template<
typename ChildT, Index Log2Dim>
1179 sum +=
iter->onVoxelCount();
1185template<
typename ChildT, Index Log2Dim>
1191 sum +=
iter->offVoxelCount();
1197template<
typename ChildT, Index Log2Dim>
1203 sum +=
mNodes[
iter.pos()].getChild()->onLeafVoxelCount();
1209template<
typename ChildT, Index Log2Dim>
1215 sum +=
mNodes[
iter.pos()].getChild()->offLeafVoxelCount();
1220template<
typename ChildT, Index Log2Dim>
1226 sum +=
iter->onTileCount();
1231template<
typename ChildT, Index Log2Dim>
1238 sum +=
iter->memUsage();
1244template<
typename ChildT, Index Log2Dim>
1248 if (bbox.
isInside(this->getNodeBoundingBox()))
return;
1251 bbox.
expand(i.getCoord(), ChildT::DIM);
1254 i->evalActiveBoundingBox(bbox, visitVoxels);
1262template<
typename ChildT, Index Log2Dim>
1270 ChildT* child =
mNodes[i].getChild();
1271 child->prune(tolerance);
1272 if (child->isConstant(value, state, tolerance)) {
1276 mNodes[i].setValue(value);
1285template<
typename ChildT, Index Log2Dim>
1286template<
typename NodeT>
1290 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1291 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1295 ChildT* child =
mNodes[n].getChild();
1296 if (std::is_same<NodeT, ChildT>::value) {
1299 mNodes[n].setValue(value);
1301 return (std::is_same<NodeT, ChildT>::value)
1302 ?
reinterpret_cast<NodeT*
>(child)
1311template<
typename ChildT, Index Log2Dim>
1312template<
typename NodeT>
1316 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1317 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1321 ChildT* child =
mNodes[n].getChild();
1322 return (std::is_same<NodeT, ChildT>::value)
1323 ?
reinterpret_cast<NodeT*
>(child)
1329template<
typename ChildT, Index Log2Dim>
1330template<
typename NodeT,
typename AccessorT>
1334 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1335 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1339 ChildT* child =
mNodes[n].getChild();
1340 acc.insert(xyz, child);
1341 return (std::is_same<NodeT, ChildT>::value)
1342 ?
reinterpret_cast<NodeT*
>(child)
1348template<
typename ChildT, Index Log2Dim>
1349template<
typename NodeT>
1353 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1354 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1358 const ChildT* child =
mNodes[n].getChild();
1359 return (std::is_same<NodeT, ChildT>::value)
1360 ?
reinterpret_cast<const NodeT*
>(child)
1366template<
typename ChildT, Index Log2Dim>
1367template<
typename NodeT,
typename AccessorT>
1371 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1372 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1376 const ChildT* child =
mNodes[n].getChild();
1377 acc.insert(xyz, child);
1378 return (std::is_same<NodeT, ChildT>::value)
1379 ?
reinterpret_cast<const NodeT*
>(child)
1388template<
typename ChildT, Index Log2Dim>
1396template<
typename ChildT, Index Log2Dim>
1404template<
typename ChildT, Index Log2Dim>
1412template<
typename ChildT, Index Log2Dim>
1420template<
typename ChildT, Index Log2Dim>
1429template<
typename ChildT, Index Log2Dim>
1438template<
typename ChildT, Index Log2Dim>
1444 value =
mNodes[offset].getValue();
1449template<
typename ChildT, Index Log2Dim>
1455 value =
mNodes[offset].getValue();
1464template<
typename ChildT, Index Log2Dim>
1465inline typename ChildT::LeafNodeType*
1472template<
typename ChildT, Index Log2Dim>
1473template<
typename AccessorT>
1474inline typename ChildT::LeafNodeType*
1481template<
typename ChildT, Index Log2Dim>
1482template<
typename AccessorT>
1483inline const typename ChildT::LeafNodeType*
1490template<
typename ChildT, Index Log2Dim>
1491inline const typename ChildT::LeafNodeType*
1498template<
typename ChildT, Index Log2Dim>
1499template<
typename AccessorT>
1500inline const typename ChildT::LeafNodeType*
1510template<
typename ChildT, Index Log2Dim>
1515 const Coord& xyz = leaf->origin();
1517 ChildT* child =
nullptr;
1519 if (ChildT::LEVEL>0) {
1522 child =
reinterpret_cast<ChildT*
>(leaf);
1526 if (ChildT::LEVEL>0) {
1527 child =
mNodes[n].getChild();
1529 delete mNodes[n].getChild();
1530 child =
reinterpret_cast<ChildT*
>(leaf);
1531 mNodes[n].setChild(child);
1534 child->addLeaf(leaf);
1538template<
typename ChildT, Index Log2Dim>
1539template<
typename AccessorT>
1544 const Coord& xyz = leaf->origin();
1546 ChildT* child =
nullptr;
1548 if (ChildT::LEVEL>0) {
1550 acc.insert(xyz, child);
1552 child =
reinterpret_cast<ChildT*
>(leaf);
1556 if (ChildT::LEVEL>0) {
1557 child =
mNodes[n].getChild();
1558 acc.insert(xyz, child);
1560 delete mNodes[n].getChild();
1561 child =
reinterpret_cast<ChildT*
>(leaf);
1562 mNodes[n].setChild(child);
1565 child->addLeafAndCache(leaf, acc);
1572template<
typename ChildT, Index Log2Dim>
1577 const Coord& xyz = child->origin();
1588template<
typename ChildT, Index Log2Dim>
1598template<
typename ChildT, Index Log2Dim>
1603 if (
LEVEL >= level) {
1606 if (
LEVEL > level) {
1609 child->addTile(level, xyz, value, state);
1612 mNodes[n].setValue(value);
1615 ChildT* child =
mNodes[n].getChild();
1616 if (
LEVEL > level) {
1617 child->addTile(level, xyz, value, state);
1622 mNodes[n].setValue(value);
1629template<
typename ChildT, Index Log2Dim>
1630template<
typename AccessorT>
1633 const ValueType& value,
bool state, AccessorT& acc)
1635 if (
LEVEL >= level) {
1638 if (
LEVEL > level) {
1641 acc.insert(xyz, child);
1642 child->addTileAndCache(level, xyz, value, state, acc);
1645 mNodes[n].setValue(value);
1648 ChildT* child =
mNodes[n].getChild();
1649 if (
LEVEL > level) {
1650 acc.insert(xyz, child);
1651 child->addTileAndCache(level, xyz, value, state, acc);
1656 mNodes[n].setValue(value);
1666template<
typename ChildT, Index Log2Dim>
1667inline typename ChildT::LeafNodeType*
1671 ChildT* child =
nullptr;
1676 child =
mNodes[n].getChild();
1678 return child->touchLeaf(xyz);
1682template<
typename ChildT, Index Log2Dim>
1683template<
typename AccessorT>
1684inline typename ChildT::LeafNodeType*
1691 acc.insert(xyz,
mNodes[n].getChild());
1692 return mNodes[n].getChild()->touchLeafAndCache(xyz, acc);
1699template<
typename ChildT, Index Log2Dim>
1706 firstValue =
mNodes[0].getValue();
1719template<
typename ChildT, Index Log2Dim>
1727 minValue = maxValue =
mNodes[0].getValue();
1745template<
typename ChildT, Index Log2Dim>
1750 const bool anyActiveTiles = !
mValueMask.isOff();
1751 if (
LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1753 if (
iter->hasActiveTiles())
return true;
1760template<
typename ChildT, Index Log2Dim>
1766 :
mNodes[n].getChild()->isValueOn(xyz);
1769template<
typename ChildT, Index Log2Dim>
1775 :
mNodes[n].getChild()->isValueOff(xyz);
1778template<
typename ChildT, Index Log2Dim>
1779template<
typename AccessorT>
1785 acc.insert(xyz,
mNodes[n].getChild());
1786 return mNodes[n].getChild()->isValueOnAndCache(xyz, acc);
1790template<
typename ChildT, Index Log2Dim>
1791inline const typename ChildT::ValueType&
1796 :
mNodes[n].getChild()->getValue(xyz);
1799template<
typename ChildT, Index Log2Dim>
1800template<
typename AccessorT>
1801inline const typename ChildT::ValueType&
1806 acc.insert(xyz,
mNodes[n].getChild());
1807 return mNodes[n].getChild()->getValueAndCache(xyz, acc);
1809 return mNodes[n].getValue();
1813template<
typename ChildT, Index Log2Dim>
1821template<
typename ChildT, Index Log2Dim>
1822template<
typename AccessorT>
1828 acc.insert(xyz,
mNodes[n].getChild());
1829 return mNodes[n].getChild()->getValueLevelAndCache(xyz, acc);
1835template<
typename ChildT, Index Log2Dim>
1841 value =
mNodes[n].getValue();
1844 return mNodes[n].getChild()->probeValue(xyz, value);
1847template<
typename ChildT, Index Log2Dim>
1848template<
typename AccessorT>
1855 acc.insert(xyz,
mNodes[n].getChild());
1856 return mNodes[n].getChild()->probeValueAndCache(xyz, value, acc);
1858 value =
mNodes[n].getValue();
1863template<
typename ChildT, Index Log2Dim>
1875 if (hasChild)
mNodes[n].getChild()->setValueOff(xyz);
1879template<
typename ChildT, Index Log2Dim>
1891 if (hasChild)
mNodes[n].getChild()->setValueOn(xyz);
1895template<
typename ChildT, Index Log2Dim>
1911 if (hasChild)
mNodes[n].getChild()->setValueOff(xyz, value);
1914template<
typename ChildT, Index Log2Dim>
1915template<
typename AccessorT>
1933 ChildT* child =
mNodes[n].getChild();
1934 acc.insert(xyz, child);
1935 child->setValueOffAndCache(xyz, value, acc);
1940template<
typename ChildT, Index Log2Dim>
1956 if (hasChild)
mNodes[n].getChild()->setValueOn(xyz, value);
1959template<
typename ChildT, Index Log2Dim>
1960template<
typename AccessorT>
1978 acc.insert(xyz,
mNodes[n].getChild());
1979 mNodes[n].getChild()->setValueAndCache(xyz, value, acc);
1984template<
typename ChildT, Index Log2Dim>
1997 if (hasChild)
mNodes[n].getChild()->setValueOnly(xyz, value);
2000template<
typename ChildT, Index Log2Dim>
2001template<
typename AccessorT>
2016 acc.insert(xyz,
mNodes[n].getChild());
2017 mNodes[n].getChild()->setValueOnlyAndCache(xyz, value, acc);
2022template<
typename ChildT, Index Log2Dim>
2037 if (hasChild)
mNodes[n].getChild()->setActiveState(xyz, on);
2040template<
typename ChildT, Index Log2Dim>
2041template<
typename AccessorT>
2057 ChildT* child =
mNodes[n].getChild();
2058 acc.insert(xyz, child);
2059 child->setActiveStateAndCache(xyz, on, acc);
2064template<
typename ChildT, Index Log2Dim>
2070 mNodes[
iter.pos()].getChild()->setValuesOn();
2075template<
typename ChildT, Index Log2Dim>
2076template<
typename ModifyOp>
2086 bool createChild = !active;
2100 if (hasChild)
mNodes[n].getChild()->modifyValue(xyz, op);
2103template<
typename ChildT, Index Log2Dim>
2104template<
typename ModifyOp,
typename AccessorT>
2115 bool createChild = !active;
2131 acc.insert(xyz, child);
2132 child->modifyValueAndCache(xyz, op, acc);
2137template<
typename ChildT, Index Log2Dim>
2138template<
typename ModifyOp>
2147 bool modifiedState = !tileState;
2149 op(modifiedVal, modifiedState);
2157 if (hasChild)
mNodes[n].getChild()->modifyValueAndActiveState(xyz, op);
2160template<
typename ChildT, Index Log2Dim>
2161template<
typename ModifyOp,
typename AccessorT>
2164 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
2171 bool modifiedState = !tileState;
2173 op(modifiedVal, modifiedState);
2183 acc.insert(xyz, child);
2184 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
2192template<
typename ChildT, Index Log2Dim>
2199 this->
fill(nodeBBox, background,
false);
2200 }
else if (clipBBox.
isInside(nodeBBox)) {
2217 }
else if (!clipBBox.
isInside(tileBBox)) {
2221 mNodes[pos].getChild()->clip(clipBBox, background);
2228 mNodes[pos].setValue(background);
2230 this->
fill(tileBBox, val, on);
2242template<
typename ChildT, Index Log2Dim>
2247 clippedBBox.intersect(bbox);
2248 if (!clippedBBox)
return;
2252 Coord xyz, tileMin, tileMax;
2253 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2255 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2257 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2263 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2269 ChildT* child =
nullptr;
2276 child =
mNodes[n].getChild();
2282 child->fill(
CoordBBox(xyz, tmp), value, active);
2298template<
typename ChildT, Index Log2Dim>
2303 clippedBBox.intersect(bbox);
2304 if (!clippedBBox)
return;
2308 Coord xyz, tileMin, tileMax;
2309 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.
x() + 1) {
2311 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.
y() + 1) {
2313 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.
z() + 1) {
2320 ChildT* child =
nullptr;
2322 child =
mNodes[n].getChild();
2332 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2335 child->denseFill(
CoordBBox{xyz, clippedBBox.
max()}, value, active);
2345template<
typename ChildT, Index Log2Dim>
2346template<
typename DenseT>
2350 using DenseValueType =
typename DenseT::ValueType;
2352 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2353 const Coord& min = dense.bbox().min();
2354 for (
Coord xyz = bbox.
min(), max; xyz[0] <= bbox.
max()[0]; xyz[0] = max[0] + 1) {
2355 for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] = max[1] + 1) {
2356 for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] = max[2] + 1) {
2365 mNodes[n].getChild()->copyToDense(sub, dense);
2369 DenseValueType* a0 = dense.data() + zStride*sub.
min()[2];
2370 for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
2371 DenseValueType* a1 = a0 + x*xStride;
2372 for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
2373 DenseValueType* a2 = a1 + y*yStride;
2375 z < ez; ++z, a2 += zStride)
2377 *a2 = DenseValueType(value);
2391template<
typename ChildT, Index Log2Dim>
2411 iter->writeTopology(os, toHalf);
2416template<
typename ChildT, Index Log2Dim>
2428 const bool oldVersion =
2434 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[numValues]);
2456 child->readTopology(is, fromHalf);
2464template<
typename ChildT, Index Log2Dim>
2465inline const typename ChildT::ValueType&
2472template<
typename ChildT, Index Log2Dim>
2473inline const typename ChildT::ValueType&
2484template<
typename ChildT, Index Log2Dim>
2485inline const typename ChildT::ValueType&
2490 return mNodes[n].getValue();
2493template<
typename ChildT, Index Log2Dim>
2499 value =
mNodes[n].getValue();
2503template<
typename ChildT, Index Log2Dim>
2509 return mNodes[n].getChild();
2512template<
typename ChildT, Index Log2Dim>
2518 return mNodes[n].getChild();
2521template<
typename ChildT, Index Log2Dim>
2528template<
typename ChildT, Index Log2Dim>
2537template<
typename ChildT, Index Log2Dim>
2543 mNodes[n].setValue(value);
2546template<
typename ChildT, Index Log2Dim>
2555template<
typename ChildT, Index Log2Dim>
2561 mNodes[n].setValue(value);
2565template<
typename ChildT, Index Log2Dim>
2574template<
typename ChildT, Index Log2Dim>
2580 mNodes[n].setValue(value);
2584template<
typename ChildT, Index Log2Dim>
2592template<
typename ChildT, Index Log2Dim>
2599 mNodes[n].setChild(child);
2604template<
typename ChildT, Index Log2Dim>
2612 delete mNodes[n].getChild();
2613 mNodes[n].setChild(child);
2616template<
typename ChildT, Index Log2Dim>
2623 auto* child =
mNodes[n].getChild();
2626 mNodes[n].setValue(value);
2630template<
typename ChildT, Index Log2Dim>
2642template<
typename ChildT, Index Log2Dim>
2648 mNodes[i].getChild()->negate();
2660template<
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);
2686template<
typename ChildT, Index Log2Dim>
2698 iter->voxelizeActiveTiles(
false);
2706template<
typename ChildT, Index Log2Dim>
2707template<MergePolicy Policy>
2724 background, otherBackground);
2732 child->resetBackground(otherBackground, background);
2763 child->resetBackground(otherBackground, background);
2784 child->resetBackground(otherBackground, background);
2791 mNodes[n].setChild(child);
2815template<
typename ChildT, Index Log2Dim>
2816template<MergePolicy Policy>
2825 if (!tileActive)
return;
2835 iter.setValue(tileValue);
2846template<
typename ChildT, Index Log2Dim>
2847template<
typename OtherInternalNode>
2852 { tV = (tV | sV) & ~tC; }
2857 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
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)) {
2875 ChildT* child =
new ChildT(other,
t->mNodes[i].getValue(),
TopologyCopy());
2876 if (
t->mValueMask.isOn(i)) child->setValuesOn();
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;
2890template<
typename ChildT, Index Log2Dim>
2891template<
typename OtherChildT>
2895 TopologyUnion<InternalNode<OtherChildT, Log2Dim> > tmp(&other,
this, preserveTiles);
2898template<
typename ChildT, Index Log2Dim>
2899template<
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)) {
2921 ChildT* child =
t->mNodes[i].getChild();
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;
2939template<
typename ChildT, Index Log2Dim>
2940template<
typename OtherChildT>
2945 TopologyIntersection<InternalNode<OtherChildT, Log2Dim> > tmp(&other,
this, background);
2948template<
typename ChildT, Index Log2Dim>
2949template<
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)) {
2976 ChildT* child =
t->mNodes[i].getChild();
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);
2988 child->topologyDifference(other,
b);
2989 t->mNodes[i].setChild(child);
2994 const OtherInternalNode*
s;
2999template<
typename ChildT, Index Log2Dim>
3000template<
typename OtherChildT>
3005 TopologyDifference<InternalNode<OtherChildT, Log2Dim> > tmp(&other,
this, background);
3012template<
typename ChildT, Index Log2Dim>
3013template<
typename CombineOp>
3058 *child =
mNodes[i].getChild(),
3062 if (child && otherChild) {
3063 child->combine(*otherChild, op);
3070template<
typename ChildT, Index Log2Dim>
3071template<
typename CombineOp>
3083 .setBIsActive(valueIsActive));
3090 if (child) child->combine(value, valueIsActive, op);
3099template<
typename ChildT, Index Log2Dim>
3100template<
typename CombineOp,
typename OtherNodeType>
3111 .
setBRef(other1.mNodes[i].getValue())
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);
3146template<
typename ChildT, Index Log2Dim>
3147template<
typename CombineOp,
typename OtherNodeType>
3150 bool valueIsActive, CombineOp& op)
3155 if (other.isChildMaskOff(i)) {
3158 .
setBRef(other.mNodes[i].getValue())
3164 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[i].getChild();
3173 mNodes[i].getChild()->combine2(value, *otherChild, valueIsActive, op);
3179template<
typename ChildT, Index Log2Dim>
3180template<
typename CombineOp,
typename OtherValueType>
3183 bool valueIsActive, CombineOp& op)
3206 mNodes[i].getChild()->combine2(*otherChild, value, valueIsActive, op);
3215template<
typename ChildT, Index Log2Dim>
3220 iter->writeBuffers(os, toHalf);
3225template<
typename ChildT, Index Log2Dim>
3230 iter->readBuffers(is, fromHalf);
3235template<
typename ChildT, Index Log2Dim>
3238 const CoordBBox& clipBBox,
bool fromHalf)
3245 iter->readBuffers(is, clipBBox, fromHalf);
3251 background = *
static_cast<const ValueType*
>(bgPtr);
3253 this->
clip(clipBBox, background);
3260template<
typename ChildT, Index Log2Dim>
3264 dims.push_back(Log2Dim);
3265 ChildNodeType::getNodeLog2Dims(dims);
3269template<
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));
3281template<
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);
3291template<
typename ChildT, Index Log2Dim>
3297 local <<= ChildT::TOTAL;
3298 return local + this->
origin();
3305template<
typename ChildT, Index Log2Dim>
3306template<
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);
3325template<
typename ChildT, Index Log2Dim>
3326template<
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);
3349template<
typename ChildT, Index Log2Dim>
3350template<
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;
3361 if (std::is_same<T, ArrayChildT*>::value) {
3362 array.push_back(
reinterpret_cast<T
>(
mNodes[n].getChild()));
3364 mNodes[n].setValue(value);
3366 iter->stealNodes(array, value, state);
3369 if (std::is_same<T, ArrayChildT*>::value)
mChildMask.setOff();
3377template<
typename ChildT, Index Log2Dim>
3385 mNodes[i].getChild()->resetBackground(oldBackground, newBackground);
3388 mNodes[i].setValue(newBackground);
3396template<
typename ChildT, Index Log2Dim>
3397template<
typename OtherChildNodeType, Index OtherLog2Dim>
3411template<
typename ChildT, Index Log2Dim>
3417 delete mNodes[i].getChild();
3422 mNodes[i].setChild(child);
3425template<
typename ChildT, Index Log2Dim>
3433 mNodes[i].setChild(child);
3437template<
typename ChildT, Index Log2Dim>
3442 mNodes[i].setValue(value);
3447 mNodes[i].setValue(value);
3452template<
typename ChildT, Index Log2Dim>
3459template<
typename ChildT, Index Log2Dim>
3464 return mNodes[n].getChild();
3468template<
typename ChildT, Index Log2Dim>
3473 return mNodes[n].getChild();
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition Types.h:640
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition Types.h:692
const AValueType & result() const
Get the output value.
Definition Types.h:684
CombineArgs & setBIsActive(bool b)
Set the active state of the B value.
Definition Types.h:708
CombineArgs & setBRef(const BValueType &b)
Redirect the B value to a new external source.
Definition Types.h:694
bool resultIsActive() const
Definition Types.h:703
CombineArgs & setAIsActive(bool b)
Set the active state of the A value.
Definition Types.h:706
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition Coord.h:316
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition Coord.h:176
static bool lessThan(const Coord &a, const Coord &b)
Definition Coord.h:209
Tag dispatch class that distinguishes constructors during file input.
Definition Types.h:760
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition Types.h:754
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:252
void translate(const Coord &t)
Translate this bounding box by (tx, ty, tz).
Definition Coord.h:461
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition Coord.h:421
const Coord & min() const
Definition Coord.h:324
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition Coord.h:415
const Coord & max() const
Definition Coord.h:325
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition Coord.h:403
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition Coord.h:447
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Int32 y() const
Definition Coord.h:132
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition Coord.h:92
Int32 x() const
Definition Coord.h:131
Coord & setZ(Int32 z)
Definition Coord.h:82
Coord & setY(Int32 y)
Definition Coord.h:81
static Coord max()
Return the largest possible coordinate.
Definition Coord.h:47
Int32 z() const
Definition Coord.h:133
Coord & setX(Int32 x)
Definition Coord.h:80
Definition InternalNode.h:35
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition InternalNode.h:1962
ChildNodeType * getChildUnsafe(Index offset)
Return the child node at offset.
Definition InternalNode.h:2505
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition InternalNode.h:336
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
ChildOnCIter cbeginChildOn() const
Definition InternalNode.h:221
const ValueType & getFirstValue() const
If the first entry in this node's table is a tile, return the tile's value. Otherwise,...
Definition InternalNode.h:2466
CoordBBox getNodeBoundingBox() const
Definition InternalNode.h:300
bool isConstant(ValueType &minValue, ValueType &maxValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition InternalNode.h:1721
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffCIter
Definition InternalNode.h:217
ChildNodeType * probeChildUnsafe(Index offset, ValueType &value, bool &active)
Return a pointer to the child node for a specific offset. If no such node exists, return nullptr.
Definition InternalNode.h:1440
ChildOnCIter beginChildOn() const
Definition InternalNode.h:224
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllIter
Definition InternalNode.h:218
const ChildNodeType * probeConstChildUnsafe(Index offset) const
Definition InternalNode.h:1431
ChildOnIter beginChildOn()
Definition InternalNode.h:227
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists,...
const NodeType * probeNode(const Coord &xyz) const
Definition InternalNode.h:707
bool isChildMaskOff(Index n) const
Definition InternalNode.h:871
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition InternalNode.h:1762
const ValueType & getValueUnsafe(Index offset) const
Return the tile value at offset.
Definition InternalNode.h:2486
const ChildNodeType * probeChildUnsafe(Index offset, ValueType &value, bool &active) const
Definition InternalNode.h:743
void writeTopology(std::ostream &, bool toHalf=false) const
Definition InternalNode.h:2393
util::NodeMask< Log2Dim > NodeMaskType
Definition InternalNode.h:42
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:2348
void setChildNode(Index i, ChildNodeType *child)
Definition InternalNode.h:3427
bool isChildMaskOff() const
Definition InternalNode.h:872
ValueOffCIter cbeginValueOff() const
Definition InternalNode.h:233
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 transientData() const
Return the transient data value.
Definition InternalNode.h:273
InternalNode(const InternalNode< OtherChildNodeType, Log2Dim > &other)
Value conversion copy constructor.
Definition InternalNode.h:1013
InternalNode(const Coord &origin, const ValueType &fillValue, bool active=false)
Constructs an InternalNode with dense tiles.
Definition InternalNode.h:954
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:1541
static Index getChildDim()
Definition InternalNode.h:257
const NodeMaskType & getChildMask() const
Definition InternalNode.h:874
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,...
NodeUnion< ValueType, ChildNodeType > UnionType
Definition InternalNode.h:41
NodeMaskType mChildMask
Definition InternalNode.h:915
bool isValueMaskOff() const
Definition InternalNode.h:869
InternalNode(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &offValue, const ValueType &onValue, TopologyCopy)
Topology copy constructor.
Definition InternalNode.h:1086
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition InternalNode.h:3308
bool isValueMaskOn() const
Definition InternalNode.h:867
Index64 nonLeafCount() const
Definition InternalNode.h:1154
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:1288
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition InternalNode.h:2688
NodeMaskType mValueMask
Definition InternalNode.h:915
InternalNode()
Default constructor.
Definition InternalNode.h:73
bool isChildMaskOn(Index n) const
Definition InternalNode.h:870
~InternalNode()
Definition InternalNode.h:1100
Index64 onLeafVoxelCount() const
const LeafNodeType * probeConstLeafAndCache(const Coord &xyz, AccessorT &acc) const
NodeMaskType getValueOffMask() const
Definition InternalNode.h:875
void merge(const ValueType &tileValue, bool tileActive)
Merge, using one of several schemes, this node (and its descendants) with a tile of the same dimensio...
Definition InternalNode.h:2818
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition InternalNode.h:1466
bool getValueUnsafe(Index offset, ValueType &value) const
Return the tile value and active state at offset.
Definition InternalNode.h:2495
ValueAllCIter cbeginValueAll() const
Definition InternalNode.h:234
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:1264
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ValueAll > ValueAllCIter
Definition InternalNode.h:219
ValueOnCIter beginValueOn() const
Definition InternalNode.h:235
void setValueOnlyUnsafe(Index offset, const ValueType &value)
Set the tile value at offset but don't change its value.
Definition InternalNode.h:2539
Index64 offLeafVoxelCount() const
const ChildNodeType * probeConstChild(const Coord &xyz, ValueType &value, bool &active) const
Definition InternalNode.h:1414
void combine2(const InternalNode &other, const OtherValueType &, bool valIsActive, CombineOp &)
Definition InternalNode.h:3182
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
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:1600
void combine2(const ValueType &value, const OtherNodeType &other, bool valIsActive, CombineOp &)
Definition InternalNode.h:3149
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition InternalNode.h:270
const Coord & origin() const
Definition InternalNode.h:268
const ChildNodeType * probeConstChildUnsafe(Index offset, ValueType &value, bool &active) const
Definition InternalNode.h:1451
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition InternalNode.h:331
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition InternalNode.h:2140
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition InternalNode.h:2003
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition InternalNode.h:3102
friend class InternalNode
During topology-only construction, access is needed to protected/private members of other template in...
Definition InternalNode.h:862
bool isValueMaskOff(Index n) const
Definition InternalNode.h:868
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:1986
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition InternalNode.h:1492
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
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:1390
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:1824
const NodeType * probeConstNodeAndCache(const Coord &xyz, AccessorT &) const
void setActiveStateUnsafe(Index offset, bool on)
Set the tile active state at offset but don't change its value.
Definition InternalNode.h:2530
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:2244
ValueOffCIter beginValueOff() const
Definition InternalNode.h:237
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition InternalNode.h:1917
void addLeaf(LeafNodeType *leaf)
Add the specified leaf to this node, possibly creating a child branch in the process....
Definition InternalNode.h:1512
InternalNode(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &background, TopologyCopy)
Topology copy constructor.
Definition InternalNode.h:1049
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
ChildAllCIter cbeginChildAll() const
Definition InternalNode.h:223
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition InternalNode.h:2194
Index64 leafCount() const
Definition InternalNode.h:1113
ChildAllIter beginChildAll()
Definition InternalNode.h:229
ValueIter< InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnIter
Definition InternalNode.h:214
static Index getLevel()
Definition InternalNode.h:250
void setValueOff(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as inactive.
Definition InternalNode.h:1897
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition InternalNode.h:1781
const ChildNodeType * probeChildUnsafe(Index offset) const
Definition InternalNode.h:733
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,...
static const Index DIM
Definition InternalNode.h:47
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
bool probeValue(const Coord &xyz, ValueType &value) const
Definition InternalNode.h:1837
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:2024
ValueOnIter beginValueOn()
Definition InternalNode.h:239
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:2106
static const Index LEVEL
Definition InternalNode.h:49
void setValueMaskUnsafe(const NodeMaskType &mask)
Set the active/inactive value mask.
Definition InternalNode.h:2586
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...
void resetChildUnsafe(Index offset, ChildNodeType *child)
Replace a child node at offset with the given child node.
Definition InternalNode.h:2606
ChildOffCIter cbeginChildOff() const
Definition InternalNode.h:222
ChildOffIter beginChildOff()
Definition InternalNode.h:228
ChildIter< InternalNode, ChildNodeType, MaskOnIterator, ChildOn > ChildOnIter
Definition InternalNode.h:207
Index64 onVoxelCount() const
ChildOffCIter beginChildOff() const
Definition InternalNode.h:225
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition InternalNode.h:3283
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:1632
typename ChildNodeType::LeafNodeType LeafNodeType
Definition InternalNode.h:38
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition InternalNode.h:1865
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition InternalNode.h:3217
void nodeCount(std::vector< Index64 > &vec) const
Definition InternalNode.h:1125
ValueOnCIter cbeginValueOn() const
Definition InternalNode.h:231
typename ChildNodeType::ValueType ValueType
Definition InternalNode.h:39
const LeafNodeType * probeLeaf(const Coord &xyz) const
void setValueOnUnsafe(Index offset)
Mark the tile active at offset but don't change its value.
Definition InternalNode.h:2548
void setValueOnUnsafe(Index offset, const ValueType &value)
Set the tile value at offset and mark the voxel as active.
Definition InternalNode.h:2557
void resetChildNode(Index i, ChildNodeType *child)
Definition InternalNode.h:3413
void readBuffers(std::istream &, const CoordBBox &, bool fromHalf=false)
Definition InternalNode.h:3237
Index32 childCount() const
DenseIter< const InternalNode, const ChildNodeType, ValueType, ChildAll > ChildAllCIter
Definition InternalNode.h:212
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:1815
Index64 onTileCount() const
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:2078
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 setValueMask(Index n, bool on)
Definition InternalNode.h:887
const ChildNodeType * getChildUnsafe(Index offset) const
Return the child node at offset.
Definition InternalNode.h:2523
Index64 offVoxelCount() const
typename NodeMaskType::OffIterator MaskOffIterator
Definition InternalNode.h:116
ChildIter< const InternalNode, const ChildNodeType, MaskOnIterator, ChildOn > ChildOnCIter
Definition InternalNode.h:208
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition InternalNode.h:1701
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:1668
void getNodes(ArrayT &array) const
Definition InternalNode.h:3328
const ChildNodeType * getConstChildUnsafe(Index offset) const
Return the child node at offset.
Definition InternalNode.h:2514
Index32 mTransientData
Definition InternalNode.h:919
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:2300
static const Index NUM_VALUES
Definition InternalNode.h:48
ValueIter< InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffIter
Definition InternalNode.h:209
UnionType mNodes[NUM_VALUES]
Definition InternalNode.h:914
void negate()
Change the sign of all the values represented in this node and its child nodes.
Definition InternalNode.h:2644
void readTopology(std::istream &, bool fromHalf=false)
Definition InternalNode.h:2418
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition InternalNode.h:3293
ValueIter< const InternalNode, const ValueType, MaskOffIterator, ChildOff > ChildOffCIter
Definition InternalNode.h:210
ChildAllCIter beginChildAll() const
Definition InternalNode.h:226
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition InternalNode.h:2043
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition InternalNode.h:2066
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition InternalNode.h:3454
void setTransientData(Index32 transientData)
Set the transient data value.
Definition InternalNode.h:275
typename ChildNodeType::BuildType BuildType
Definition InternalNode.h:40
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
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
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition InternalNode.h:3461
typename NodeMaskType::OnIterator MaskOnIterator
Definition InternalNode.h:115
const LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc) const
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition InternalNode.h:1850
static const Index LOG2DIM
Definition InternalNode.h:45
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:1574
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:1422
DenseIter< InternalNode, ChildNodeType, ValueType, ChildAll > ChildAllIter
Definition InternalNode.h:211
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
ValueIter< const InternalNode, const ValueType, MaskOnIterator, ValueOn > ValueOnCIter
Definition InternalNode.h:215
const ChildNodeType * probeChild(const Coord &xyz) const
Definition InternalNode.h:715
bool isEmpty() const
Definition InternalNode.h:303
InternalNode(const ValueType &offValue)
Constructor of an InternalNode with dense inactive tiles of the specified value.
Definition InternalNode.h:946
const UnionType * getTable() const
Definition InternalNode.h:882
ChildNodeType * probeChild(const Coord &xyz, ValueType &value, bool &active)
Return a pointer to the child node that contains voxel (x, y, z). If no such node exists,...
Definition InternalNode.h:1406
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
ValueOffIter beginValueOff()
Definition InternalNode.h:241
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition InternalNode.h:1881
ValueIter< InternalNode, const ValueType, MaskOffIterator, ValueOff > ValueOffIter
Definition InternalNode.h:216
const ChildNodeType * probeConstChild(const Coord &xyz) const
Definition InternalNode.h:1398
typename SubtreeT::Back ChildNodeType
Definition InternalNode.h:37
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
const NodeMaskType & getValueMask() const
Definition InternalNode.h:873
static const Index TOTAL
Definition InternalNode.h:46
const ChildNodeType * getChildNode(Index n) const
Returns a pointer to the child node at the linear offset n.
Definition InternalNode.h:3470
const NodeType * probeConstNode(const Coord &xyz) const
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition InternalNode.h:1747
void combine(InternalNode &other, CombineOp &)
Definition InternalNode.h:3015
InternalNode(const InternalNode &)
Deep copy constructor.
Definition InternalNode.h:999
void setChildUnsafe(Index offset, ChildNodeType *child)
Replace a tile at offset with the given child node.
Definition InternalNode.h:2594
const ValueType & getValue(const Coord &xyz) const
Definition InternalNode.h:1792
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active.
Definition InternalNode.h:1942
bool isValueOff(const Coord &xyz) const
Return true if the voxel at the given coordinates is inactive.
Definition InternalNode.h:1771
static const Index64 NUM_VOXELS
Definition InternalNode.h:51
void setValueOffUnsafe(Index offset)
Mark the tile inactive at offset but don't change its value.
Definition InternalNode.h:2567
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition InternalNode.h:3439
const ChildNodeType * probeChild(const Coord &xyz, ValueType &value, bool &active) const
Definition InternalNode.h:723
void readBuffers(std::istream &, bool fromHalf=false)
Definition InternalNode.h:3227
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition InternalNode.h:117
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition InternalNode.h:2163
bool isValueOff(Index offset) const
Return true if the voxel at the given offset is inactive.
Definition InternalNode.h:340
ValueAllCIter beginValueAll() const
Definition InternalNode.h:238
Coord mOrigin
Definition InternalNode.h:917
static Index dim()
Definition InternalNode.h:247
void setValueOffUnsafe(Index offset, const ValueType &value)
Set the tile value at offset and mark the voxel as inactive.
Definition InternalNode.h:2576
InternalNode(PartialCreate, const Coord &, const ValueType &fillValue, bool active=false)
Definition InternalNode.h:968
void addTile(Index offset, const ValueType &value, bool state)
Delete any existing child branch at the specified offset and add a tile.
Definition InternalNode.h:1590
bool isValueMaskOn(Index n) const
Definition InternalNode.h:866
ValueAllIter beginValueAll()
Definition InternalNode.h:242
void combine(const ValueType &value, bool valueIsActive, CombineOp &)
Definition InternalNode.h:3073
const ValueType & getLastValue() const
If the last entry in this node's table is a tile, return the tile's value. Otherwise,...
Definition InternalNode.h:2474
Base class for iterators over internal and leaf nodes.
Definition Iterator.h:30
Index pos() const
Definition Iterator.h:60
InternalNode & parent() const
Definition Iterator.h:50
Default implementation of a NodeUnion that stores the child pointer and the value separately (i....
Definition NodeUnion.h:32
const ValueT & getValue() const
Definition NodeUnion.h:43
ChildT * getChild() const
Definition NodeUnion.h:40
void setValue(const ValueT &val)
Definition NodeUnion.h:45
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation.
Definition NodeMasks.h:309
Index64 Word
Definition NodeMasks.h:317
DenseMaskIterator< NodeMask > DenseIterator
Definition NodeMasks.h:351
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition NodeMasks.h:484
OnMaskIterator< NodeMask > OnIterator
Definition NodeMasks.h:349
void setOff(Index32 n)
Set the nth bit off.
Definition NodeMasks.h:458
OffMaskIterator< NodeMask > OffIterator
Definition NodeMasks.h:350
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition Compression.h:466
void checkFormatVersion(std::ios_base &)
Throws an IoError if the file format version number is not supported.
uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
const void * getGridBackgroundValuePtr(std::ios_base &)
Return a pointer to the background value of the grid currently being read from or written to the give...
void writeCompressedValues(std::ostream &os, const ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition Compression.h:648
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition Mat.h:1015
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:428
T negative(const T &val)
Return the unary negation of the given value.
Definition Math.h:139
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition Math.h:465
bool cwiseGreaterThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition Mat.h:1029
Definition TreeIterator.h:30
Index32 Index
Definition Types.h:34
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:71
@ OPENVDB_FILE_VERSION_NODE_MASK_COMPRESSION
Definition version.h.in:328
uint32_t Index32
Definition Types.h:32
int32_t Int32
Definition Types.h:36
uint64_t Index64
Definition Types.h:33
@ MERGE_ACTIVE_STATES
Definition Types.h:578
@ MERGE_NODES
Definition Types.h:579
@ MERGE_ACTIVE_STATES_AND_NODES
Definition Types.h:580
Definition Exceptions.h:13
typename std::remove_const< ValueT >::type NonConstValueType
Definition Iterator.h:184
DenseIteratorBase()
Definition Iterator.h:188
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition InternalNode.h:132
ChildIter()
Definition InternalNode.h:131
ChildT & getItem(Index pos) const
Definition InternalNode.h:135
void setItem(Index pos, const ChildT &c) const
Definition InternalNode.h:142
Definition InternalNode.h:121
Definition InternalNode.h:121
Definition InternalNode.h:979
DeepCopy(const OtherInternalNode *source, InternalNode *target)
Definition InternalNode.h:980
InternalNode * t
Definition InternalNode.h:994
const OtherInternalNode * s
Definition InternalNode.h:993
void operator()(const tbb::blocked_range< Index > &r) const
Definition InternalNode.h:984
DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT > BaseT
Definition InternalNode.h:174
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition InternalNode.h:178
void unsetItem(Index pos, const ValueT &value) const
Definition InternalNode.h:199
void setItem(Index pos, ChildT *child) const
Definition InternalNode.h:193
DenseIter()
Definition InternalNode.h:177
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition InternalNode.h:181
typename BaseT::NonConstValueType NonConstValueT
Definition InternalNode.h:175
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of an Intern...
Definition InternalNode.h:65
static const bool value
Definition InternalNode.h:66
Definition InternalNode.h:1025
TopologyCopy1(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition InternalNode.h:1026
InternalNode * t
Definition InternalNode.h:1042
const OtherInternalNode * s
Definition InternalNode.h:1041
const ValueType & b
Definition InternalNode.h:1043
void operator()(const tbb::blocked_range< Index > &r) const
Definition InternalNode.h:1031
Definition InternalNode.h:1062
const ValueType & offV
Definition InternalNode.h:1080
TopologyCopy2(const OtherInternalNode *source, InternalNode *target, const ValueType &offValue, const ValueType &onValue)
Definition InternalNode.h:1063
InternalNode * t
Definition InternalNode.h:1079
const OtherInternalNode * s
Definition InternalNode.h:1078
const ValueType & onV
Definition InternalNode.h:1080
void operator()(const tbb::blocked_range< Index > &r) const
Definition InternalNode.h:1068
Definition InternalNode.h:2953
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition InternalNode.h:2953
Definition InternalNode.h:2956
void operator()(W &tV, const W &sC, const W &sV, const W &tC) const
Definition InternalNode.h:2956
TopologyDifference(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition InternalNode.h:2959
typename NodeMaskType::Word W
Definition InternalNode.h:2952
InternalNode * t
Definition InternalNode.h:2995
const OtherInternalNode * s
Definition InternalNode.h:2994
const ValueType & b
Definition InternalNode.h:2996
void operator()(const tbb::blocked_range< Index > &r) const
Definition InternalNode.h:2973
Definition InternalNode.h:2903
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition InternalNode.h:2903
TopologyIntersection(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition InternalNode.h:2906
typename NodeMaskType::Word W
Definition InternalNode.h:2902
InternalNode * t
Definition InternalNode.h:2935
const OtherInternalNode * s
Definition InternalNode.h:2934
const ValueType & b
Definition InternalNode.h:2936
void operator()(const tbb::blocked_range< Index > &r) const
Definition InternalNode.h:2918
Definition InternalNode.h:2851
void operator()(W &tV, const W &sV, const W &tC) const
Definition InternalNode.h:2851
Definition InternalNode.h:2849
typename NodeMaskType::Word W
Definition InternalNode.h:2850
InternalNode * t
Definition InternalNode.h:2886
const bool mPreserveTiles
Definition InternalNode.h:2887
const OtherInternalNode * s
Definition InternalNode.h:2885
void operator()(const tbb::blocked_range< Index > &r) const
Definition InternalNode.h:2867
TopologyUnion(const OtherInternalNode *source, InternalNode *target, const bool preserveTiles)
Definition InternalNode.h:2854
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition InternalNode.h:56
InternalNode< typename ChildNodeType::template ValueConverter< OtherValueType >::Type, Log2Dim > Type
Definition InternalNode.h:57
void modifyItem(Index pos, const ModifyOp &op) const
Definition InternalNode.h:163
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition InternalNode.h:153
const ValueT & getItem(Index pos) const
Definition InternalNode.h:156
ValueIter()
Definition InternalNode.h:152
void setItem(Index pos, const ValueT &v) const
Definition InternalNode.h:159
Definition InternalNode.h:120
Definition InternalNode.h:120
Definition InternalNode.h:2662
InternalNode * mNode
Definition InternalNode.h:2683
void operator()(const tbb::blocked_range< Index > &r) const
Definition InternalNode.h:2670
VoxelizeActiveTiles(InternalNode &node)
Definition InternalNode.h:2663
static const bool value
Definition InternalNode.h:936
Definition InternalNode.h:930
static const bool value
Definition InternalNode.h:931
SparseIteratorBase()
Definition Iterator.h:122
const ValueType & getValue() const
Definition Iterator.h:139
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:284