6#ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7#define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
23#include <tbb/concurrent_hash_map.h>
55 template<
typename TreeType>
56 bool isType()
const {
return (this->type() == TreeType::treeType()); }
105#if OPENVDB_ABI_VERSION_NUMBER >= 12
108 virtual Index32 unallocatedLeafCount()
const = 0;
120#if OPENVDB_ABI_VERSION_NUMBER >= 12
123 virtual Index32 leafCount()
const = 0;
128#if OPENVDB_ABI_VERSION_NUMBER >= 12
131 virtual std::vector<Index32> nodeCount()
const = 0;
134#if OPENVDB_ABI_VERSION_NUMBER >= 12
137 virtual Index32 nonLeafCount()
const = 0;
160 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
164 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
167 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
177 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
186 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
193template<
typename _RootNodeType>
205 static const Index DEPTH = RootNodeType::LEVEL + 1;
218 template<
typename OtherValueType>
239 template<
typename OtherRootType>
254 template<
typename OtherTreeType>
255 Tree(
const OtherTreeType& other,
260 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
275 template<
typename OtherTreeType>
285 ~Tree()
override { this->clear(); releaseAllAccessors(); }
294 static const Name& treeType();
296 const Name&
type()
const override {
return this->treeType(); }
313 template<
typename OtherRootNodeType>
316 bool evalLeafBoundingBox(
CoordBBox& bbox)
const override;
317 bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const override;
318 bool evalActiveVoxelDim(
Coord& dim)
const override;
319 bool evalLeafDim(
Coord& dim)
const override;
324 static void getNodeLog2Dims(std::vector<Index>& dims);
333 void readTopology(std::istream&,
bool saveFloatAsHalf =
false)
override;
337 void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
339 void readBuffers(std::istream&,
bool saveFloatAsHalf =
false)
override;
341 void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false)
override;
347 void readNonresidentBuffers()
const override;
349 void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
351 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const override;
362#if OPENVDB_ABI_VERSION_NUMBER >= 12
365 Index32 leafCount()
const override {
return static_cast<Index32>(mRoot.leafCount()); }
370#if OPENVDB_ABI_VERSION_NUMBER >= 12
373 std::vector<Index64> vec(DEPTH, 0);
374 mRoot.nodeCount( vec );
378 std::vector<Index32> nodeCount()
const override
380 std::vector<Index32> vec(DEPTH, 0);
382 mRoot.nodeCount( vec );
388#if OPENVDB_ABI_VERSION_NUMBER >= 12
391 Index32 nonLeafCount()
const override {
return static_cast<Index32>(mRoot.nonLeafCount()); }
406 void evalMinMax(ValueType &min, ValueType &max) const;
408 Index64 memUsage()
const override {
return tools::memUsage(*
this); }
415 const ValueType& getValue(
const Coord& xyz)
const;
423 int getValueDepth(
const Coord& xyz)
const;
426 void setActiveState(
const Coord& xyz,
bool on);
430 void setValueOn(
const Coord& xyz);
437 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
439 void setValueOff(
const Coord& xyz);
461 template<
typename ModifyOp>
462 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
483 template<
typename ModifyOp>
484 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
504 void clipUnallocatedNodes()
override;
507#if OPENVDB_ABI_VERSION_NUMBER >= 12
508 Index64 unallocatedLeafCount()
const override;
510 Index32 unallocatedLeafCount()
const override;
522 void sparseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
525 this->sparseFill(bbox, value, active);
536 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
546 void voxelizeActiveTiles(
bool threaded =
true);
554 this->clearAllAccessors();
555 mRoot.prune(tolerance);
569 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
575 template<
typename NodeT>
576 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
583 LeafNodeType* touchLeaf(
const Coord& xyz);
588 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
589 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
590 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
596 LeafNodeType* probeLeaf(
const Coord& xyz);
597 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
624 template<
typename ArrayT>
void getNodes(ArrayT& array);
625 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
651 template<
typename ArrayT>
652 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
653 template<
typename ArrayT>
656 this->clearAllAccessors();
657 mRoot.stealNodes(array, value, state);
665 bool empty()
const {
return mRoot.empty(); }
673 Accessor getAccessor();
681 UnsafeAccessor getUnsafeAccessor();
683 ConstAccessor getAccessor()
const;
685 ConstAccessor getConstAccessor()
const;
693 ConstUnsafeAccessor getConstUnsafeAccessor();
696 void clearAllAccessors();
762 template<
typename OtherRootNodeType>
778 template<
typename OtherRootNodeType>
791 template<
typename OtherRootNodeType>
838 template<
typename CombineOp>
839 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
840 template<
typename CombineOp>
841 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
881 template<
typename ExtendedCombineOp>
882 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
883 template<
typename ExtendedCombineOp>
884 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
914 template<
typename CombineOp,
typename OtherTreeType >
915 void combine2(
const Tree& a,
const OtherTreeType& b, CombineOp& op,
bool prune =
false);
916 template<
typename CombineOp,
typename OtherTreeType >
917 void combine2(
const Tree& a,
const OtherTreeType& b,
const CombineOp& op,
bool prune =
false);
992 template<
typename ExtendedCombineOp,
typename OtherTreeType >
993 void combine2Extended(
const Tree& a,
const OtherTreeType& b, ExtendedCombineOp& op,
995 template<
typename ExtendedCombineOp,
typename OtherTreeType >
996 void combine2Extended(
const Tree& a,
const OtherTreeType& b,
const ExtendedCombineOp&,
1011 typename RootNodeType::ChildOffCIter
beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1012 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1013 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
1018 typename RootNodeType::ChildAllCIter
beginRootDense()
const {
return mRoot.cbeginChildAll(); }
1019 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
1020 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1078 template<
typename IterT> IterT begin();
1081 template<
typename CIterT> CIterT
cbegin()
const;
1090 void releaseAllAccessors();
1093 template<
typename NodeType>
1096 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1098 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
1099 delete mNodes[n]; mNodes[n] =
nullptr;
1118template<
typename T, Index N1=4, Index N2=3>
1128template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1137template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1148TreeBase::readTopology(std::istream& is,
bool )
1150 int32_t bufferCount;
1151 is.read(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1152 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1157TreeBase::writeTopology(std::ostream& os,
bool )
const
1159 int32_t bufferCount = 1;
1160 os.write(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1165TreeBase::print(std::ostream& os,
int )
const
1167 os <<
" Tree Type: " << type()
1168 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1169 <<
" Active tile Count: " << activeTileCount() << std::endl
1170 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1171 <<
" Leaf Node Count: " << leafCount() << std::endl
1172 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1187template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1188 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1189 return tree.beginRootChildren();
1193template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1194 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1195 return tree.cbeginRootChildren();
1199template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1200 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1201 return tree.beginRootTiles();
1205template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1206 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1207 return tree.cbeginRootTiles();
1211template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1212 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1213 return tree.beginRootDense();
1217template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1218 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1219 return tree.cbeginRootDense();
1224 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1228 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1232 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1236 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1240 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1244 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1248 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1251template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1252 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1256 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1259template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1260 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1264template<
typename RootNodeType>
1265template<
typename IterT>
1273template<
typename RootNodeType>
1274template<
typename IterT>
1285template<
typename RootNodeType>
1289 this->clearAllAccessors();
1290 TreeBase::readTopology(is, saveFloatAsHalf);
1291 mRoot.readTopology(is, saveFloatAsHalf);
1295template<
typename RootNodeType>
1299 TreeBase::writeTopology(os, saveFloatAsHalf);
1300 mRoot.writeTopology(os, saveFloatAsHalf);
1304template<
typename RootNodeType>
1308 this->clearAllAccessors();
1309 mRoot.readBuffers(is, saveFloatAsHalf);
1313template<
typename RootNodeType>
1317 this->clearAllAccessors();
1318 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1322template<
typename RootNodeType>
1326 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1328 it->getValue(
Index(0));
1333template<
typename RootNodeType>
1341template<
typename RootNodeType>
1342template<
typename ArrayT>
1346 using NodeT =
typename std::remove_pointer<typename ArrayT::value_type>::type;
1347 static_assert(!std::is_same<NodeT, RootNodeType>::value,
1348 "getNodes() does not work for the RootNode. Use Tree::root()");
1353template<
typename RootNodeType>
1354template<
typename ArrayT>
1358 using NodeT =
typename std::remove_pointer<typename ArrayT::value_type>::type;
1359 static_assert(!std::is_same<NodeT, const RootNodeType>::value,
1360 "getNodes() does not work for the RootNode. Use Tree::root()");
1365template<
typename RootNodeType>
1369 std::vector<LeafNodeType*> leafnodes;
1370 this->stealNodes(leafnodes);
1372 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1375 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1376 this->stealNodes(internalNodes);
1378 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1383 this->clearAllAccessors();
1390template<
typename RootNodeType>
1397template<
typename RootNodeType>
1404template<
typename RootNodeType>
1411template<
typename RootNodeType>
1418template<
typename RootNodeType>
1425template<
typename RootNodeType>
1429 typename AccessorRegistry::accessor a;
1430 mAccessorRegistry.insert(a, &accessor);
1434template<
typename RootNodeType>
1438 typename ConstAccessorRegistry::accessor a;
1439 mConstAccessorRegistry.insert(a, &accessor);
1443template<
typename RootNodeType>
1447 mAccessorRegistry.erase(&accessor);
1451template<
typename RootNodeType>
1455 mConstAccessorRegistry.erase(&accessor);
1459template<
typename RootNodeType>
1463 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1464 it != mAccessorRegistry.end(); ++it)
1466 if (it->first) it->first->clear();
1469 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1470 it != mConstAccessorRegistry.end(); ++it)
1472 if (it->first) it->first->clear();
1477template<
typename RootNodeType>
1481 mAccessorRegistry.erase(
nullptr);
1482 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1483 it != mAccessorRegistry.end(); ++it)
1485 it->first->release();
1487 mAccessorRegistry.
clear();
1489 mAccessorRegistry.erase(
nullptr);
1490 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1491 it != mConstAccessorRegistry.end(); ++it)
1493 it->first->release();
1495 mConstAccessorRegistry.clear();
1502template<
typename RootNodeType>
1503inline const typename RootNodeType::ValueType&
1510template<
typename RootNodeType>
1511template<
typename AccessT>
1512inline const typename RootNodeType::ValueType&
1519template<
typename RootNodeType>
1527template<
typename RootNodeType>
1535template<
typename RootNodeType>
1543template<
typename RootNodeType>
1551template<
typename RootNodeType>
1558template<
typename RootNodeType>
1565template<
typename RootNodeType>
1566template<
typename AccessT>
1574template<
typename RootNodeType>
1582template<
typename RootNodeType>
1590template<
typename RootNodeType>
1591template<
typename ModifyOp>
1599template<
typename RootNodeType>
1600template<
typename ModifyOp>
1608template<
typename RootNodeType>
1619template<
typename RootNodeType>
1624 mRoot.
addTile(level, xyz, value, active);
1628template<
typename RootNodeType>
1629template<
typename NodeT>
1633 this->clearAllAccessors();
1634 return mRoot.template stealNode<NodeT>(xyz, value, active);
1638template<
typename RootNodeType>
1639inline typename RootNodeType::LeafNodeType*
1646template<
typename RootNodeType>
1647inline typename RootNodeType::LeafNodeType*
1654template<
typename RootNodeType>
1655inline const typename RootNodeType::LeafNodeType*
1662template<
typename RootNodeType>
1663template<
typename NodeType>
1667 return mRoot.template probeNode<NodeType>(xyz);
1671template<
typename RootNodeType>
1672template<
typename NodeType>
1673inline const NodeType*
1676 return this->
template probeConstNode<NodeType>(xyz);
1680template<
typename RootNodeType>
1681template<
typename NodeType>
1682inline const NodeType*
1685 return mRoot.template probeConstNode<NodeType>(xyz);
1692template<
typename RootNodeType>
1696 this->clearAllAccessors();
1697 return mRoot.clip(bbox);
1701template<
typename RootNodeType>
1705 this->clearAllAccessors();
1706 for (
LeafIter it = this->beginLeaf(); it; ) {
1709 if (!leaf->isAllocated()) {
1710 this->addTile(0, leaf->origin(), this->background(),
false);
1715#if OPENVDB_ABI_VERSION_NUMBER >= 12
1716template<
typename RootNodeType>
1721 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1725template<
typename RootNodeType>
1730 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1736template<
typename RootNodeType>
1740 this->clearAllAccessors();
1741 return mRoot.sparseFill(bbox, value, active);
1745template<
typename RootNodeType>
1749 this->clearAllAccessors();
1750 return mRoot.denseFill(bbox, value, active);
1754template<
typename RootNodeType>
1758 this->clearAllAccessors();
1759 mRoot.voxelizeActiveTiles(threaded);
1763template<
typename RootNodeType>
1768 if (Metadata::isRegisteredType(valueType())) {
1770 result = Metadata::createMetadata(valueType());
1771 if (result->typeName() == MetadataT::staticTypeName()) {
1772 MetadataT* m =
static_cast<MetadataT*
>(result.get());
1773 m->value() = mRoot.background();
1783template<
typename RootNodeType>
1787 this->clearAllAccessors();
1791 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1793 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1795 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1800template<
typename RootNodeType>
1801template<
typename OtherRootNodeType>
1805 this->clearAllAccessors();
1806 mRoot.topologyUnion(other.
root(), preserveTiles);
1809template<
typename RootNodeType>
1810template<
typename OtherRootNodeType>
1814 this->clearAllAccessors();
1815 mRoot.topologyIntersection(other.
root());
1818template<
typename RootNodeType>
1819template<
typename OtherRootNodeType>
1823 this->clearAllAccessors();
1824 mRoot.topologyDifference(other.
root());
1832template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1838 op(args.
a(), args.
b(), args.
result());
1845template<
typename RootNodeType>
1846template<
typename CombineOp>
1851 this->combineExtended(other, extendedOp, prune);
1857template<
typename RootNodeType>
1858template<
typename CombineOp>
1863 this->combineExtended(other, extendedOp, prune);
1867template<
typename RootNodeType>
1868template<
typename ExtendedCombineOp>
1872 this->clearAllAccessors();
1873 mRoot.combine(other.
root(), op, prune);
1879template<
typename RootNodeType>
1880template<
typename ExtendedCombineOp>
1884 this->clearAllAccessors();
1885 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op, prune);
1889template<
typename RootNodeType>
1890template<
typename CombineOp,
typename OtherTreeType>
1895 this->combine2Extended(a, b, extendedOp, prune);
1901template<
typename RootNodeType>
1902template<
typename CombineOp,
typename OtherTreeType>
1907 this->combine2Extended(a, b, extendedOp, prune);
1911template<
typename RootNodeType>
1912template<
typename ExtendedCombineOp,
typename OtherTreeType>
1915 ExtendedCombineOp& op,
bool prune)
1917 this->clearAllAccessors();
1918 mRoot.combine2(a.
root(), b.root(), op, prune);
1925template<
typename RootNodeType>
1926template<
typename ExtendedCombineOp,
typename OtherTreeType>
1929 const ExtendedCombineOp& op,
bool prune)
1931 this->clearAllAccessors();
1932 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op, prune);
1939template<
typename RootNodeType>
1943 static std::string sTreeTypeName = []()
1946 std::vector<Index> dims;
1947 Tree::getNodeLog2Dims(dims);
1948 std::ostringstream ostr;
1949 ostr <<
"Tree_" << typeNameAsString<BuildType>();
1950 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
1951 ostr <<
"_" << dims[i];
1955 return sTreeTypeName;
1959template<
typename RootNodeType>
1960template<
typename OtherRootNodeType>
1968template<
typename RootNodeType>
1974 if (this->empty())
return false;
1976 mRoot.evalActiveBoundingBox(bbox,
false);
1978 return !bbox.
empty();
1981template<
typename RootNodeType>
1987 if (this->empty())
return false;
1989 mRoot.evalActiveBoundingBox(bbox,
true);
1991 return !bbox.
empty();
1995template<
typename RootNodeType>
2000 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2006template<
typename RootNodeType>
2011 bool notEmpty = this->evalLeafBoundingBox(bbox);
2017template<
typename RootNodeType>
2021 minVal = maxVal = zeroVal<ValueType>();
2023 minVal = maxVal = *iter;
2024 for (++iter; iter; ++iter) {
2026 if (math::cwiseLessThan(val, minVal)) minVal = val;
2027 if (math::cwiseGreaterThan(val, maxVal)) maxVal = val;
2033template<
typename RootNodeType>
2038 RootNodeType::getNodeLog2Dims(dims);
2042template<
typename RootNodeType>
2046 if (verboseLevel <= 0)
return;
2051 std::streamsize savedPrecision;
2052 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2053 ~OnExit() { os.precision(savedPrecision); }
2055 OnExit restorePrecision(os);
2057 std::vector<Index> dims;
2058 Tree::getNodeLog2Dims(dims);
2060 os <<
"Information about Tree:\n"
2061 <<
" Type: " << this->type() <<
"\n";
2063 os <<
" Configuration:\n";
2065 if (verboseLevel <= 1) {
2067 os <<
" Root(" << mRoot.getTableSize() <<
")";
2068 if (dims.size() > 1) {
2069 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2070 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
2072 os <<
", Leaf(" << (1 << dims.back()) <<
"^3)\n";
2074 os <<
" Background value: " << mRoot.background() <<
"\n";
2080 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2081 if (verboseLevel > 3) {
2084 minVal = extrema.
min();
2085 maxVal = extrema.
max();
2088 const auto nodeCount = this->nodeCount();
2089 const Index64 leafCount = nodeCount.front();
2093 for (
size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2096 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
2097 if (dims.size() >= 2) {
2098 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2099 os <<
", Internal(" << util::formattedInt(nodeCount[N - i]);
2100 os <<
" x " << (1 << dims[i]) <<
"^3)";
2102 os <<
", Leaf(" << util::formattedInt(leafCount);
2103 os <<
" x " << (1 << dims.back()) <<
"^3)\n";
2105 os <<
" Background value: " << mRoot.background() <<
"\n";
2109 if (verboseLevel > 3) {
2110 os <<
" Min value: " << minVal <<
"\n";
2111 os <<
" Max value: " << maxVal <<
"\n";
2115 numActiveVoxels = this->activeVoxelCount(),
2116 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2117 numActiveTiles = this->activeTileCount();
2119 os <<
" Number of active voxels: " << util::formattedInt(numActiveVoxels) <<
"\n";
2120 os <<
" Number of active tiles: " << util::formattedInt(numActiveTiles) <<
"\n";
2124 if (numActiveVoxels) {
2126 this->evalActiveVoxelBoundingBox(bbox);
2128 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
2130 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
2131 os <<
" Dimensions of active voxels: "
2132 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
2134 const double activeRatio = (100.0 * double(numActiveVoxels)) /
double(totalVoxels);
2135 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
2137 if (leafCount > 0) {
2138 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2139 / (
double(leafCount) *
double(LeafNodeType::NUM_VOXELS));
2140 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
2143 if (verboseLevel > 2) {
2145 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
2146 os <<
" Number of unallocated nodes: "
2147 << util::formattedInt(sum) <<
" ("
2148 << (100.0 * double(sum) / double(totalNodeCount)) <<
"%)\n";
2151 os <<
" Tree is empty!\n";
2155 if (verboseLevel == 2)
return;
2159 actualMem = this->memUsage(),
2160 denseMem =
sizeof(
ValueType) * totalVoxels,
2161 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
2164 os <<
"Memory footprint:\n";
2165 util::printBytes(os, actualMem,
" Actual: ");
2166 util::printBytes(os, voxelsMem,
" Active leaf voxels: ");
2168 if (numActiveVoxels) {
2169 util::printBytes(os, denseMem,
" Dense equivalent: ");
2170 os <<
" Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2171 <<
"% of an equivalent dense volume\n";
2172 os <<
" Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2173 <<
"% of actual footprint\n";
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Functions to count tiles, nodes or voxels in a grid.
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.
ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing c...
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition Types.h:569
const AValueType & result() const
Get the output value.
Definition Types.h:613
const BValueType & b() const
Get the B input value.
Definition Types.h:610
const AValueType & a() const
Get the A input value.
Definition Types.h:608
Definition Exceptions.h:61
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition Types.h:683
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:252
Coord extents() const
Definition Coord.h:385
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition Coord.h:359
void reset()
Definition Coord.h:330
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Int32 y() const
Definition Coord.h:132
Int32 x() const
Definition Coord.h:131
Int32 z() const
Definition Coord.h:133
double min() const
Return the minimum value.
Definition Stats.h:122
double max() const
Return the maximum value.
Definition Stats.h:125
Templated class to compute the minimum and maximum values.
Definition Stats.h:32
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels)
Definition TreeIterator.h:1188
Base class for tree-traversal iterators over all nodes.
Definition TreeIterator.h:937
Base class for typed trees.
Definition Tree.h:38
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 Index64 unallocatedLeafCount() const =0
Return the total number of unallocated leaf nodes residing in this tree.
virtual ~TreeBase()=default
virtual Index64 activeLeafVoxelCount() const =0
Return the number of active voxels stored in leaf nodes.
virtual std::vector< Index64 > nodeCount() const =0
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:56
virtual void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const =0
Write out all the data buffers for this tree.
virtual Index64 leafCount() const =0
Return the number of leaf nodes.
virtual Metadata::Ptr getBackgroundValue() const
Return this tree's background value wrapped as metadata.
Definition Tree.h:66
virtual Index64 nonLeafCount() const =0
Return the number of non-leaf nodes.
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 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:151
virtual TreeBase::Ptr copy() const =0
Return a pointer to a deep copy of this tree.
SharedPtr< TreeBase > Ptr
Definition Tree.h:40
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:41
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
RootNodeType::ChildAllCIter beginRootDense() const
Return an iterator over all entries of the root node's table.
Definition Tree.h:1018
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:1521
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:1962
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:719
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:720
ConstAccessorRegistry mConstAccessorRegistry
Definition Tree.h:1110
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition Tree.h:491
RootNodeType & root()
Return this tree's root node.
Definition Tree.h:303
Tree(const Tree &other)
Deep copy constructor.
Definition Tree.h:229
RootNodeType::ChildOffCIter cbeginRootTiles() const
Definition Tree.h:1012
LeafCIter beginLeaf() const
Definition Tree.h:1046
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition Tree.h:1335
ValueOffCIter cbeginValueOff() const
Definition Tree.h:1073
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition Tree.h:240
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition Tree.h:1656
void clearAllAccessors()
Clear all registered accessors.
Definition Tree.h:1461
_RootNodeType RootNodeType
Definition Tree.h:200
RootNodeType::ChildAllIter beginRootDense()
Definition Tree.h:1020
LeafCIter cbeginLeaf() const
Definition Tree.h:1047
const Name & type() const override
Return the name of this type of tree.
Definition Tree.h:296
RootNodeType::ChildOffIter beginRootTiles()
Definition Tree.h:1013
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition Tree.h:1344
RootNodeType::ChildOnCIter beginRootChildren() const
Return an iterator over children of the root node.
Definition Tree.h:1004
bool operator!=(const Tree &) const
Definition Tree.h:299
Tree()
Definition Tree.h:224
AccessorRegistry mAccessorRegistry
Definition Tree.h:1109
RootNodeType mRoot
Definition Tree.h:1108
ValueAllCIter cbeginValueAll() const
Definition Tree.h:1061
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:552
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:1648
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:1640
RootNodeType::ChildOnIter beginRootChildren()
Definition Tree.h:1006
Index64 leafCount() const override
Return the number of leaf nodes.
Definition Tree.h:363
ValueOnCIter beginValueOn() const
Definition Tree.h:1066
bool operator==(const Tree &) const
Definition Tree.h:298
SharedPtr< Tree > Ptr
Definition Tree.h:197
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
Definition Tree.h:394
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition Tree.h:1602
Index64 inactiveVoxelCount() const override
Return the number of inactive voxels within the bounding box of all active voxels.
Definition Tree.h:400
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:1560
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:665
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Definition Tree.h:398
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
Definition Tree.h:396
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Definition Tree.h:523
ValueOffCIter beginValueOff() const
Definition Tree.h:1072
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:563
RootNodeType::ChildOffCIter beginRootTiles() const
Return an iterator over non-child entries of the root node's table.
Definition Tree.h:1011
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:1621
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition Tree.h:1610
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:1545
ValueOnIter beginValueOn()
Return an iterator over active values (tile and voxel) across all nodes.
Definition Tree.h:1065
typename RootNodeType::BuildType BuildType
Definition Tree.h:202
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:1553
Index64 activeTileCount() const override
Return the total number of active tiles.
Definition Tree.h:402
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition Tree.h:1529
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition Tree.h:1086
ValueOnCIter cbeginValueOn() const
Definition Tree.h:1067
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition Tree.h:288
typename RootNodeType::ValueType ValueType
Definition Tree.h:201
void attachAccessor(ValueAccessorBase< Tree, false > &) const
Dummy implementations.
Definition Tree.h:707
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition Tree.h:1504
const LeafNodeType * probeLeaf(const Coord &xyz) const
Definition Tree.h:598
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Definition Tree.h:708
NodeCIter beginNode() const
Definition Tree.h:1039
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:1593
SharedPtr< const Tree > ConstPtr
Definition Tree.h:198
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition Tree.h:276
RootNodeType::ChildAllCIter cbeginRootDense() const
Definition Tree.h:1019
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition Tree.h:654
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition Tree.h:1367
RootNodeType::ChildOnCIter cbeginRootChildren() const
Definition Tree.h:1005
std::vector< Index64 > nodeCount() const override
Definition Tree.h:371
NodeCIter cbeginNode() const
Definition Tree.h:1040
const ValueType & background() const
Return this tree's background value.
Definition Tree.h:732
Tree & operator=(const Tree &)=delete
ValueOffIter beginValueOff()
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition Tree.h:1071
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition Tree.h:735
typename RootNodeType::LeafNodeType LeafNodeType
Definition Tree.h:203
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition Tree.h:1576
LeafIter beginLeaf()
Return an iterator over all leaf nodes in this tree.
Definition Tree.h:1045
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition Tree.h:255
~Tree() override
Definition Tree.h:285
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition Tree.h:495
Tree(const ValueType &background)
Empty tree constructor.
Definition Tree.h:283
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition Tree.h:493
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:652
Name valueType() const override
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
Definition Tree.h:291
Index treeDepth() const override
Return the depth of this tree.
Definition Tree.h:360
const RootNodeType & root() const
Definition Tree.h:304
ValueAllCIter beginValueAll() const
Definition Tree.h:1060
NodeIter beginNode()
Return an iterator over all nodes in this tree.
Definition Tree.h:1038
Index64 nonLeafCount() const override
Return the number of non-leaf nodes.
Definition Tree.h:389
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition Tree.h:1085
ValueAllIter beginValueAll()
Return an iterator over all values (tile and voxel) across all nodes.
Definition Tree.h:1059
Base class for tree-traversal iterators over tile and voxel values.
Definition TreeIterator.h:618
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition ValueAccessor.h:152
The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compa...
Definition ValueAccessor.h:367
#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:19
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:506
@ MERGE_ACTIVE_STATES
Definition Types.h:507
@ MERGE_NODES
Definition Types.h:508
@ MERGE_ACTIVE_STATES_AND_NODES
Definition Types.h:509
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:1834
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition Tree.h:1837
CombineOpAdapter(CombineOp &_op)
Definition Tree.h:1835
CombineOp & op
Definition Tree.h:1841
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition Tree.h:1119
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal,...
Definition Tree.h:1129
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal,...
Definition Tree.h:1138
DeallocateNodes(std::vector< NodeType * > &nodes)
Definition Tree.h:1095
NodeType **const mNodes
Definition Tree.h:1102
void operator()(const tbb::blocked_range< size_t > &range) const
Definition Tree.h:1097
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition Tree.h:219
static TreeT::LeafCIter begin(const TreeT &tree)
Definition Tree.h:1236
static TreeT::LeafIter begin(TreeT &tree)
Definition Tree.h:1232
static TreeT::NodeCIter begin(const TreeT &tree)
Definition Tree.h:1228
static TreeT::NodeIter begin(TreeT &tree)
Definition Tree.h:1224
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition Tree.h:1200
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition Tree.h:1188
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition Tree.h:1212
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition Tree.h:1218
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition Tree.h:1194
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition Tree.h:1206
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition Tree.h:1260
static TreeT::ValueAllIter begin(TreeT &tree)
Definition Tree.h:1256
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition Tree.h:1252
static TreeT::ValueOffIter begin(TreeT &tree)
Definition Tree.h:1248
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition Tree.h:1244
static TreeT::ValueOnIter begin(TreeT &tree)
Definition Tree.h:1240
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition Tree.h:1185
#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:218