6#ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7#define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
22#include <tbb/concurrent_hash_map.h>
54 template<
typename TreeType>
55 bool isType()
const {
return (this->type() == TreeType::treeType()); }
143 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
147 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
150 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
160 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
169 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
176template<
typename _RootNodeType>
188 static const Index DEPTH = RootNodeType::LEVEL + 1;
196 template<
typename OtherValueType>
217 template<
typename OtherRootType>
232 template<
typename OtherTreeType>
233 Tree(
const OtherTreeType& other,
238 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
253 template<
typename OtherTreeType>
263 ~Tree()
override { this->clear(); releaseAllAccessors(); }
272 static const Name& treeType();
274 const Name&
type()
const override {
return this->treeType(); }
291 template<
typename OtherRootNodeType>
294 bool evalLeafBoundingBox(
CoordBBox& bbox)
const override;
295 bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const override;
296 bool evalActiveVoxelDim(
Coord& dim)
const override;
297 bool evalLeafDim(
Coord& dim)
const override;
302 static void getNodeLog2Dims(std::vector<Index>& dims);
311 void readTopology(std::istream&,
bool saveFloatAsHalf =
false)
override;
315 void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
317 void readBuffers(std::istream&,
bool saveFloatAsHalf =
false)
override;
319 void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false)
override;
325 void readNonresidentBuffers()
const override;
327 void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
329 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const override;
346 std::vector<Index32> vec(DEPTH, 0);
347 mRoot.nodeCount( vec );
365 void evalMinMax(ValueType &min, ValueType &max) const;
367 Index64 memUsage()
const override {
return tools::memUsage(*
this); }
374 const ValueType& getValue(
const Coord& xyz)
const;
382 int getValueDepth(
const Coord& xyz)
const;
385 void setActiveState(
const Coord& xyz,
bool on);
389 void setValueOn(
const Coord& xyz);
396 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType&
value, AccessT&);
398 void setValueOff(
const Coord& xyz);
420 template<
typename ModifyOp>
421 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
442 template<
typename ModifyOp>
443 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
463 void clipUnallocatedNodes()
override;
466 Index32 unallocatedLeafCount()
const override;
477 void sparseFill(
const CoordBBox& bbox,
const ValueType&
value,
bool active =
true);
480 this->sparseFill(bbox,
value, active);
491 void denseFill(
const CoordBBox& bbox,
const ValueType&
value,
bool active =
true);
501 void voxelizeActiveTiles(
bool threaded =
true);
509 this->clearAllAccessors();
510 mRoot.prune(tolerance);
524 void addTile(
Index level,
const Coord& xyz,
const ValueType&
value,
bool active);
530 template<
typename NodeT>
531 NodeT* stealNode(
const Coord& xyz,
const ValueType&
value,
bool active);
538 LeafNodeType* touchLeaf(
const Coord& xyz);
543 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
544 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
545 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
551 LeafNodeType* probeLeaf(
const Coord& xyz);
552 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
579 template<
typename ArrayT>
void getNodes(ArrayT& array) { mRoot.getNodes(array); }
580 template<
typename ArrayT>
void getNodes(ArrayT& array)
const { mRoot.getNodes(array); }
606 template<
typename ArrayT>
607 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
608 template<
typename ArrayT>
611 this->clearAllAccessors();
612 mRoot.stealNodes(array,
value, state);
620 bool empty()
const {
return mRoot.empty(); }
626 void clearAllAccessors();
692 template<
typename OtherRootNodeType>
708 template<
typename OtherRootNodeType>
721 template<
typename OtherRootNodeType>
768 template<
typename CombineOp>
769 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
770 template<
typename CombineOp>
771 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
811 template<
typename ExtendedCombineOp>
812 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
813 template<
typename ExtendedCombineOp>
814 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
844 template<
typename CombineOp,
typename OtherTreeType >
845 void combine2(
const Tree& a,
const OtherTreeType& b, CombineOp& op,
bool prune =
false);
846 template<
typename CombineOp,
typename OtherTreeType >
847 void combine2(
const Tree& a,
const OtherTreeType& b,
const CombineOp& op,
bool prune =
false);
922 template<
typename ExtendedCombineOp,
typename OtherTreeType >
923 void combine2Extended(
const Tree& a,
const OtherTreeType& b, ExtendedCombineOp& op,
925 template<
typename ExtendedCombineOp,
typename OtherTreeType >
926 void combine2Extended(
const Tree& a,
const OtherTreeType& b,
const ExtendedCombineOp&,
941 typename RootNodeType::ChildOffCIter
beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
942 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
943 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
948 typename RootNodeType::ChildAllCIter
beginRootDense()
const {
return mRoot.cbeginChildAll(); }
949 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
950 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1008 template<
typename IterT> IterT begin();
1011 template<
typename CIterT> CIterT
cbegin()
const;
1020 void releaseAllAccessors();
1023 template<
typename NodeType>
1026 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1028 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
1029 delete mNodes[n]; mNodes[n] =
nullptr;
1045template<
typename _RootNodeType>
1053template<
typename T, Index N1=4, Index N2=3>
1063template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1072template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1083TreeBase::readTopology(std::istream& is,
bool )
1085 int32_t bufferCount;
1086 is.read(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1087 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1092TreeBase::writeTopology(std::ostream& os,
bool )
const
1094 int32_t bufferCount = 1;
1095 os.write(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1100TreeBase::print(std::ostream& os,
int )
const
1102 os <<
" Tree Type: " << type()
1103 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1104 <<
" Active tile Count: " << activeTileCount() << std::endl
1105 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1106 <<
" Leaf Node Count: " << leafCount() << std::endl
1107 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1122template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1123 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1124 return tree.beginRootChildren();
1128template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1129 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1130 return tree.cbeginRootChildren();
1134template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1135 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1136 return tree.beginRootTiles();
1140template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1141 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1142 return tree.cbeginRootTiles();
1146template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1147 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1148 return tree.beginRootDense();
1152template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1153 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1154 return tree.cbeginRootDense();
1159 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1163 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1167 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1171 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1175 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1179 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1183 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1186template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1187 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1191 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1194template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1195 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1199template<
typename RootNodeType>
1200template<
typename IterT>
1208template<
typename RootNodeType>
1209template<
typename IterT>
1220template<
typename RootNodeType>
1224 this->clearAllAccessors();
1225 TreeBase::readTopology(is, saveFloatAsHalf);
1226 mRoot.readTopology(is, saveFloatAsHalf);
1230template<
typename RootNodeType>
1234 TreeBase::writeTopology(os, saveFloatAsHalf);
1235 mRoot.writeTopology(os, saveFloatAsHalf);
1239template<
typename RootNodeType>
1243 this->clearAllAccessors();
1244 mRoot.readBuffers(is, saveFloatAsHalf);
1248template<
typename RootNodeType>
1252 this->clearAllAccessors();
1253 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1257template<
typename RootNodeType>
1261 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1268template<
typename RootNodeType>
1276template<
typename RootNodeType>
1280 std::vector<LeafNodeType*> leafnodes;
1281 this->stealNodes(leafnodes);
1283 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1286 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1287 this->stealNodes(internalNodes);
1289 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1294 this->clearAllAccessors();
1301template<
typename RootNodeType>
1305 typename AccessorRegistry::accessor a;
1306 mAccessorRegistry.insert(a, &accessor);
1310template<
typename RootNodeType>
1314 typename ConstAccessorRegistry::accessor a;
1315 mConstAccessorRegistry.insert(a, &accessor);
1319template<
typename RootNodeType>
1323 mAccessorRegistry.erase(&accessor);
1327template<
typename RootNodeType>
1331 mConstAccessorRegistry.erase(&accessor);
1335template<
typename RootNodeType>
1339 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1340 it != mAccessorRegistry.end(); ++it)
1342 if (it->first) it->first->
clear();
1345 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1346 it != mConstAccessorRegistry.end(); ++it)
1348 if (it->first) it->first->clear();
1353template<
typename RootNodeType>
1357 mAccessorRegistry.erase(
nullptr);
1358 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1359 it != mAccessorRegistry.end(); ++it)
1361 it->first->release();
1363 mAccessorRegistry.
clear();
1365 mAccessorRegistry.erase(
nullptr);
1366 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1367 it != mConstAccessorRegistry.end(); ++it)
1369 it->first->release();
1371 mConstAccessorRegistry.clear();
1378template<
typename RootNodeType>
1379inline const typename RootNodeType::ValueType&
1386template<
typename RootNodeType>
1387template<
typename AccessT>
1388inline const typename RootNodeType::ValueType&
1395template<
typename RootNodeType>
1403template<
typename RootNodeType>
1411template<
typename RootNodeType>
1419template<
typename RootNodeType>
1427template<
typename RootNodeType>
1434template<
typename RootNodeType>
1441template<
typename RootNodeType>
1442template<
typename AccessT>
1450template<
typename RootNodeType>
1458template<
typename RootNodeType>
1466template<
typename RootNodeType>
1467template<
typename ModifyOp>
1475template<
typename RootNodeType>
1476template<
typename ModifyOp>
1484template<
typename RootNodeType>
1495template<
typename RootNodeType>
1504template<
typename RootNodeType>
1505template<
typename NodeT>
1509 this->clearAllAccessors();
1510 return mRoot.template stealNode<NodeT>(xyz,
value, active);
1514template<
typename RootNodeType>
1515inline typename RootNodeType::LeafNodeType*
1522template<
typename RootNodeType>
1523inline typename RootNodeType::LeafNodeType*
1530template<
typename RootNodeType>
1531inline const typename RootNodeType::LeafNodeType*
1538template<
typename RootNodeType>
1539template<
typename NodeType>
1543 return mRoot.template probeNode<NodeType>(xyz);
1547template<
typename RootNodeType>
1548template<
typename NodeType>
1549inline const NodeType*
1552 return this->
template probeConstNode<NodeType>(xyz);
1556template<
typename RootNodeType>
1557template<
typename NodeType>
1558inline const NodeType*
1561 return mRoot.template probeConstNode<NodeType>(xyz);
1568template<
typename RootNodeType>
1572 this->clearAllAccessors();
1573 return mRoot.clip(bbox);
1577template<
typename RootNodeType>
1581 this->clearAllAccessors();
1582 for (
LeafIter it = this->beginLeaf(); it; ) {
1585 if (!leaf->isAllocated()) {
1586 this->addTile(0, leaf->origin(), this->background(),
false);
1591template<
typename RootNodeType>
1596 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1601template<
typename RootNodeType>
1605 this->clearAllAccessors();
1606 return mRoot.sparseFill(bbox,
value, active);
1610template<
typename RootNodeType>
1614 this->clearAllAccessors();
1615 return mRoot.denseFill(bbox,
value, active);
1619template<
typename RootNodeType>
1623 this->clearAllAccessors();
1624 mRoot.voxelizeActiveTiles(threaded);
1628template<
typename RootNodeType>
1633 if (Metadata::isRegisteredType(valueType())) {
1635 result = Metadata::createMetadata(valueType());
1636 if (result->typeName() == MetadataT::staticTypeName()) {
1637 MetadataT* m =
static_cast<MetadataT*
>(result.get());
1638 m->value() = mRoot.background();
1648template<
typename RootNodeType>
1652 this->clearAllAccessors();
1656 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1658 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1660 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1665template<
typename RootNodeType>
1666template<
typename OtherRootNodeType>
1670 this->clearAllAccessors();
1671 mRoot.topologyUnion(other.
root(), preserveTiles);
1674template<
typename RootNodeType>
1675template<
typename OtherRootNodeType>
1679 this->clearAllAccessors();
1680 mRoot.topologyIntersection(other.
root());
1683template<
typename RootNodeType>
1684template<
typename OtherRootNodeType>
1688 this->clearAllAccessors();
1689 mRoot.topologyDifference(other.
root());
1697template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1703 op(args.
a(), args.
b(), args.
result());
1710template<
typename RootNodeType>
1711template<
typename CombineOp>
1716 this->combineExtended(other, extendedOp, prune);
1722template<
typename RootNodeType>
1723template<
typename CombineOp>
1728 this->combineExtended(other, extendedOp, prune);
1732template<
typename RootNodeType>
1733template<
typename ExtendedCombineOp>
1737 this->clearAllAccessors();
1738 mRoot.combine(other.
root(), op, prune);
1744template<
typename RootNodeType>
1745template<
typename ExtendedCombineOp>
1749 this->clearAllAccessors();
1750 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op, prune);
1754template<
typename RootNodeType>
1755template<
typename CombineOp,
typename OtherTreeType>
1760 this->combine2Extended(a, b, extendedOp, prune);
1766template<
typename RootNodeType>
1767template<
typename CombineOp,
typename OtherTreeType>
1772 this->combine2Extended(a, b, extendedOp, prune);
1776template<
typename RootNodeType>
1777template<
typename ExtendedCombineOp,
typename OtherTreeType>
1780 ExtendedCombineOp& op,
bool prune)
1782 this->clearAllAccessors();
1783 mRoot.combine2(a.
root(), b.root(), op, prune);
1790template<
typename RootNodeType>
1791template<
typename ExtendedCombineOp,
typename OtherTreeType>
1794 const ExtendedCombineOp& op,
bool prune)
1796 this->clearAllAccessors();
1797 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op, prune);
1804template<
typename RootNodeType>
1808 static std::once_flag once;
1809 std::call_once(once, []()
1811 std::vector<Index> dims;
1812 Tree::getNodeLog2Dims(dims);
1813 std::ostringstream ostr;
1814 ostr <<
"Tree_" << typeNameAsString<BuildType>();
1815 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
1816 ostr <<
"_" << dims[i];
1818 sTreeTypeName.reset(
new Name(ostr.str()));
1820 return *sTreeTypeName;
1824template<
typename RootNodeType>
1825template<
typename OtherRootNodeType>
1833template<
typename RootNodeType>
1839 if (this->empty())
return false;
1841 mRoot.evalActiveBoundingBox(bbox,
false);
1843 return !bbox.
empty();
1846template<
typename RootNodeType>
1852 if (this->empty())
return false;
1854 mRoot.evalActiveBoundingBox(bbox,
true);
1856 return !bbox.
empty();
1860template<
typename RootNodeType>
1865 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
1871template<
typename RootNodeType>
1876 bool notEmpty = this->evalLeafBoundingBox(bbox);
1882template<
typename RootNodeType>
1886 minVal = maxVal = zeroVal<ValueType>();
1888 minVal = maxVal = *iter;
1889 for (++iter; iter; ++iter) {
1891 if (math::cwiseLessThan(val, minVal)) minVal = val;
1892 if (math::cwiseGreaterThan(val, maxVal)) maxVal = val;
1898template<
typename RootNodeType>
1903 RootNodeType::getNodeLog2Dims(dims);
1907template<
typename RootNodeType>
1911 if (verboseLevel <= 0)
return;
1916 std::streamsize savedPrecision;
1917 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
1918 ~OnExit() { os.precision(savedPrecision); }
1920 OnExit restorePrecision(os);
1922 std::vector<Index> dims;
1923 Tree::getNodeLog2Dims(dims);
1925 os <<
"Information about Tree:\n"
1926 <<
" Type: " << this->type() <<
"\n";
1928 os <<
" Configuration:\n";
1930 if (verboseLevel <= 1) {
1932 os <<
" Root(" << mRoot.getTableSize() <<
")";
1933 if (dims.size() > 1) {
1934 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1935 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
1937 os <<
", Leaf(" << (1 << dims.back()) <<
"^3)\n";
1939 os <<
" Background value: " << mRoot.background() <<
"\n";
1945 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
1946 if (verboseLevel > 3) {
1949 minVal = extrema.
min();
1950 maxVal = extrema.
max();
1953 const auto nodeCount = this->nodeCount();
1954 const Index32 leafCount = nodeCount.front();
1955 assert(dims.size() == nodeCount.size());
1958 for (
size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
1961 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
1962 if (dims.size() >= 2) {
1963 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1964 os <<
", Internal(" << util::formattedInt(nodeCount[N - i]);
1965 os <<
" x " << (1 << dims[i]) <<
"^3)";
1967 os <<
", Leaf(" << util::formattedInt(leafCount);
1968 os <<
" x " << (1 << dims.back()) <<
"^3)\n";
1970 os <<
" Background value: " << mRoot.background() <<
"\n";
1974 if (verboseLevel > 3) {
1975 os <<
" Min value: " << minVal <<
"\n";
1976 os <<
" Max value: " << maxVal <<
"\n";
1980 numActiveVoxels = this->activeVoxelCount(),
1981 numActiveLeafVoxels = this->activeLeafVoxelCount(),
1982 numActiveTiles = this->activeTileCount();
1984 os <<
" Number of active voxels: " << util::formattedInt(numActiveVoxels) <<
"\n";
1985 os <<
" Number of active tiles: " << util::formattedInt(numActiveTiles) <<
"\n";
1989 if (numActiveVoxels) {
1991 this->evalActiveVoxelBoundingBox(bbox);
1993 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
1995 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
1996 os <<
" Dimensions of active voxels: "
1997 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
1999 const double activeRatio = (100.0 * double(numActiveVoxels)) /
double(totalVoxels);
2000 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
2002 if (leafCount > 0) {
2003 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2004 / (
double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2005 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
2008 if (verboseLevel > 2) {
2010 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
2011 os <<
" Number of unallocated nodes: "
2012 << util::formattedInt(sum) <<
" ("
2013 << (100.0 * double(sum) / double(totalNodeCount)) <<
"%)\n";
2016 os <<
" Tree is empty!\n";
2020 if (verboseLevel == 2)
return;
2024 actualMem = this->memUsage(),
2025 denseMem =
sizeof(
ValueType) * totalVoxels,
2026 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
2029 os <<
"Memory footprint:\n";
2030 util::printBytes(os, actualMem,
" Actual: ");
2031 util::printBytes(os, voxelsMem,
" Active leaf voxels: ");
2033 if (numActiveVoxels) {
2034 util::printBytes(os, denseMem,
" Dense equivalent: ");
2035 os <<
" Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2036 <<
"% of an equivalent dense volume\n";
2037 os <<
" Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2038 <<
"% of actual footprint\n";
Functions to count tiles, nodes or voxels in a grid.
ValueT value
Definition: GridBuilder.h:1290
Internal table nodes for OpenVDB trees.
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
The root node of an OpenVDB tree.
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:530
const AValueType & result() const
Get the output value.
Definition: Types.h:574
const BValueType & b() const
Get the B input value.
Definition: Types.h:571
const AValueType & a() const
Get the A input value.
Definition: Types.h:569
Definition: Exceptions.h:61
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:644
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:249
Coord extents() const
Definition: Coord.h:382
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:356
void reset()
Definition: Coord.h:327
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
Int32 y() const
Definition: Coord.h:131
Int32 x() const
Definition: Coord.h:130
Int32 z() const
Definition: Coord.h:132
double min() const
Return the minimum value.
Definition: Stats.h:125
double max() const
Return the maximum value.
Definition: Stats.h:128
Templated class to compute the minimum and maximum values.
Definition: Stats.h:31
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels)
Definition: TreeIterator.h:1187
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:936
Base class for typed trees.
Definition: Tree.h:37
virtual Name valueType() const =0
Return the name of the type of a voxel's value (e.g., "float" or "vec3d").
virtual const Name & type() const =0
Return the name of this tree's type.
virtual std::vector< Index32 > nodeCount() const =0
virtual Index32 nonLeafCount() const =0
Return the number of non-leaf nodes.
virtual ~TreeBase()=default
virtual Index64 activeLeafVoxelCount() const =0
Return the number of active voxels stored in leaf nodes.
virtual void readBuffers(std::istream &, bool saveFloatAsHalf=false)=0
Read all data buffers for this tree.
bool isType() const
Return true if this tree is of the same type as the template parameter.
Definition: Tree.h:55
virtual void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const =0
Write out all the data buffers for this tree.
virtual Metadata::Ptr getBackgroundValue() const
Return this tree's background value wrapped as metadata.
Definition: Tree.h:65
virtual void readBuffers(std::istream &, const CoordBBox &, bool saveFloatAsHalf=false)=0
Read all of this tree's data buffers that intersect the given bounding box.
virtual void getIndexRange(CoordBBox &bbox) const =0
virtual Index32 leafCount() const =0
Return the number of leaf nodes.
virtual Index32 unallocatedLeafCount() const =0
Return the total number of unallocated leaf nodes residing in this tree.
virtual Index64 activeVoxelCount() const =0
Return the total number of active voxels.
virtual Index64 inactiveVoxelCount() const =0
Return the number of inactive voxels within the bounding box of all active voxels.
virtual void clipUnallocatedNodes()=0
Replace with background tiles any nodes whose voxel buffers have not yet been allocated.
virtual void readNonresidentBuffers() const =0
Read all of this tree's data buffers that are not yet resident in memory (because delayed loading is ...
virtual Index64 inactiveLeafVoxelCount() const =0
Return the number of inactive voxels stored in leaf nodes.
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:134
virtual TreeBase::Ptr copy() const =0
Return a pointer to a deep copy of this tree.
SharedPtr< TreeBase > Ptr
Definition: Tree.h:39
virtual bool evalLeafDim(Coord &dim) const =0
Return in dim the dimensions of the axis-aligned bounding box of all leaf nodes.
virtual bool evalActiveVoxelBoundingBox(CoordBBox &bbox) const =0
Return in bbox the axis-aligned bounding box of all active voxels and tiles.
virtual Index treeDepth() const =0
Return the depth of this tree.
virtual Index64 activeTileCount() const =0
Return the total number of active tiles.
SharedPtr< const TreeBase > ConstPtr
Definition: Tree.h:40
virtual bool evalActiveVoxelDim(Coord &dim) const =0
Return in dim the dimensions of the axis-aligned bounding box of all active voxels....
virtual bool evalLeafBoundingBox(CoordBBox &bbox) const =0
Return in bbox the axis-aligned bounding box of all active tiles and leaf nodes with active values.
TreeBase & operator=(const TreeBase &)=delete
TreeBase(const TreeBase &)=default
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:617
RootNodeType::ChildAllCIter beginRootDense() const
Return an iterator over all entries of the root node's table.
Definition: Tree.h:948
int getValueDepth(const Coord &xyz) const
Return the tree depth (0 = root) at which the value of voxel (x, y, z) resides.
Definition: Tree.h:1397
bool hasSameTopology(const Tree< OtherRootNodeType > &other) const
Return true if the given tree has the same node and active value topology as this tree,...
Definition: Tree.h:1827
CIterT cbegin() const
Return a const iterator of type CIterT (for example, cbegin<ValueOnCIter>() is equivalent to cbeginVa...
void releaseAccessor(ValueAccessorBase< Tree, false > &) const
Dummy implementations.
Definition: Tree.h:649
const ValueType & getValue(const Coord &xyz, AccessT &) const
Return the value of the voxel at the given coordinates and update the given accessor's node cache.
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:650
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1040
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:450
RootNodeType & root()
Return this tree's root node.
Definition: Tree.h:281
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:207
RootNodeType::ChildOffCIter cbeginRootTiles() const
Definition: Tree.h:942
LeafCIter beginLeaf() const
Definition: Tree.h:976
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition: Tree.h:1270
ValueOffCIter cbeginValueOff() const
Definition: Tree.h:1003
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:218
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition: Tree.h:1532
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1337
_RootNodeType RootNodeType
Definition: Tree.h:183
RootNodeType::ChildAllIter beginRootDense()
Definition: Tree.h:950
LeafCIter cbeginLeaf() const
Definition: Tree.h:977
const Name & type() const override
Return the name of this type of tree.
Definition: Tree.h:274
RootNodeType::ChildOffIter beginRootTiles()
Definition: Tree.h:943
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: Tree.h:579
RootNodeType::ChildOnCIter beginRootChildren() const
Return an iterator over children of the root node.
Definition: Tree.h:934
bool operator!=(const Tree &) const
Definition: Tree.h:277
Tree()
Definition: Tree.h:202
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1039
RootNodeType mRoot
Definition: Tree.h:1038
ValueAllCIter cbeginValueAll() const
Definition: Tree.h:991
void prune(const ValueType &tolerance=zeroVal< ValueType >())
Reduce the memory footprint of this tree by replacing with tiles any nodes whose values are all the s...
Definition: Tree.h:507
static std::unique_ptr< const Name > sTreeTypeName
Definition: Tree.h:1042
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition: Tree.h:1524
LeafNodeType * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition: Tree.h:1516
RootNodeType::ChildOnIter beginRootChildren()
Definition: Tree.h:936
ValueOnCIter beginValueOn() const
Definition: Tree.h:996
bool operator==(const Tree &) const
Definition: Tree.h:276
SharedPtr< Tree > Ptr
Definition: Tree.h:180
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:353
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1478
Index32 leafCount() const override
Return the number of leaf nodes.
Definition: Tree.h:340
Index64 inactiveVoxelCount() const override
Return the number of inactive voxels within the bounding box of all active voxels.
Definition: Tree.h:359
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: Tree.h:1436
bool empty() const
Return true if this tree contains no nodes other than the root node and no tiles other than backgroun...
Definition: Tree.h:620
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Definition: Tree.h:357
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:355
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Definition: Tree.h:478
ValueOffCIter beginValueOff() const
Definition: Tree.h:1002
void addLeaf(LeafNodeType *leaf)
Add the given leaf node to this tree, creating a new branch if necessary. If a leaf node with the sam...
Definition: Tree.h:518
RootNodeType::ChildOffCIter beginRootTiles() const
Return an iterator over non-child entries of the root node's table.
Definition: Tree.h:941
std::vector< Index32 > nodeCount() const override
Definition: Tree.h:344
void addTile(Index level, const Coord &xyz, const ValueType &value, bool active)
Add a tile containing voxel (x, y, z) at the specified tree level, creating a new branch if necessary...
Definition: Tree.h:1497
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1486
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: Tree.h:1421
ValueOnIter beginValueOn()
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:995
typename RootNodeType::BuildType BuildType
Definition: Tree.h:185
void setValue(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active.
Definition: Tree.h:1429
Index64 activeTileCount() const override
Return the total number of active tiles.
Definition: Tree.h:361
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: Tree.h:1405
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1016
ValueOnCIter cbeginValueOn() const
Definition: Tree.h:997
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition: Tree.h:266
typename RootNodeType::ValueType ValueType
Definition: Tree.h:184
void attachAccessor(ValueAccessorBase< Tree, false > &) const
Dummy implementations.
Definition: Tree.h:637
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1380
const LeafNodeType * probeLeaf(const Coord &xyz) const
Definition: Tree.h:553
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:638
NodeCIter beginNode() const
Definition: Tree.h:969
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: Tree.h:1469
SharedPtr< const Tree > ConstPtr
Definition: Tree.h:181
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:254
RootNodeType::ChildAllCIter cbeginRootDense() const
Definition: Tree.h:949
void getNodes(ArrayT &array) const
Definition: Tree.h:580
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:609
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1278
RootNodeType::ChildOnCIter cbeginRootChildren() const
Definition: Tree.h:935
NodeCIter cbeginNode() const
Definition: Tree.h:970
const ValueType & background() const
Return this tree's background value.
Definition: Tree.h:662
Tree & operator=(const Tree &)=delete
ValueOffIter beginValueOff()
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1001
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition: Tree.h:665
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:186
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: Tree.h:1452
LeafIter beginLeaf()
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:975
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:233
~Tree() override
Definition: Tree.h:263
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:454
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:261
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:452
void stealNodes(ArrayT &array)
Steals all nodes of a certain type from the tree and adds them to a container with the following API:
Definition: Tree.h:607
Index32 nonLeafCount() const override
Return the number of non-leaf nodes.
Definition: Tree.h:351
Name valueType() const override
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
Definition: Tree.h:269
Index treeDepth() const override
Return the depth of this tree.
Definition: Tree.h:338
const RootNodeType & root() const
Definition: Tree.h:282
ValueAllCIter beginValueAll() const
Definition: Tree.h:990
NodeIter beginNode()
Return an iterator over all nodes in this tree.
Definition: Tree.h:968
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1015
ValueAllIter beginValueAll()
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:989
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:93
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:256
std::string Name
Definition: Name.h:17
Index32 Index
Definition: Types.h:54
uint32_t Index32
Definition: Types.h:52
uint64_t Index64
Definition: Types.h:53
std::shared_ptr< T > SharedPtr
Definition: Types.h:114
MergePolicy
Definition: Types.h:467
@ MERGE_ACTIVE_STATES
Definition: Types.h:468
@ MERGE_NODES
Definition: Types.h:469
@ MERGE_ACTIVE_STATES_AND_NODES
Definition: Types.h:470
Definition: Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1699
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1702
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1700
CombineOp & op
Definition: Tree.h:1706
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition: Tree.h:1054
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal,...
Definition: Tree.h:1064
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal,...
Definition: Tree.h:1073
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1171
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1167
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1163
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1159
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1153
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1147
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1141
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1135
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1129
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1123
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1195
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1191
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1187
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1183
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1179
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1175
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1120
DeallocateNodes(std::vector< NodeType * > &nodes)
Definition: Tree.h:1025
NodeType **const mNodes
Definition: Tree.h:1032
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1027
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition: Tree.h:197
#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:212