33 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
34 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
39 #include <boost/shared_ptr.hpp>
40 #include <boost/cstdint.hpp>
41 #include <tbb/atomic.h>
42 #include <tbb/concurrent_hash_map.h>
43 #include <openvdb/Types.h>
44 #include <openvdb/metadata/Metadata.h>
45 #include <openvdb/math/Math.h>
46 #include <openvdb/math/BBox.h>
47 #include <openvdb/util/Formats.h>
48 #include <openvdb/util/logging.h>
49 #include <openvdb/Platform.h>
67 typedef boost::shared_ptr<TreeBase>
Ptr;
68 typedef boost::shared_ptr<const TreeBase>
ConstPtr;
74 virtual const Name& type()
const = 0;
76 virtual Name valueType()
const = 0;
92 virtual bool evalLeafBoundingBox(
CoordBBox& bbox)
const = 0;
96 virtual bool evalLeafDim(
Coord& dim)
const = 0;
103 virtual bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const = 0;
107 virtual bool evalActiveVoxelDim(
Coord& dim)
const = 0;
109 virtual void getIndexRange(
CoordBBox& bbox)
const = 0;
118 virtual Index treeDepth()
const = 0;
120 virtual Index32 leafCount()
const = 0;
122 virtual Index32 nonLeafCount()
const = 0;
124 virtual Index64 activeLeafVoxelCount()
const = 0;
126 virtual Index64 inactiveLeafVoxelCount()
const = 0;
128 virtual Index64 activeVoxelCount()
const = 0;
130 virtual Index64 inactiveVoxelCount()
const = 0;
142 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
146 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
149 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
151 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
157 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
169 template<
typename _RootNodeType>
173 typedef boost::shared_ptr<Tree>
Ptr;
180 static const Index DEPTH = RootNodeType::LEVEL + 1;
188 template<
typename OtherValueType>
210 template<
typename OtherTreeType>
211 Tree(
const OtherTreeType& other,
216 mRoot(other.getRootNode(), inactiveValue, activeValue,
TopologyCopy())
230 template<
typename OtherTreeType>
240 virtual ~Tree() { releaseAllAccessors(); }
249 static const Name& treeType();
251 virtual const Name&
type()
const {
return treeType(); }
268 template<
typename OtherRootNodeType>
271 virtual bool evalLeafBoundingBox(
CoordBBox& bbox)
const;
272 virtual bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const;
273 virtual bool evalActiveVoxelDim(
Coord& dim)
const;
274 virtual bool evalLeafDim(
Coord& dim)
const;
279 static void getNodeLog2Dims(std::vector<Index>& dims);
288 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
292 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
294 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false);
296 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const;
298 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
319 virtual Index64 inactiveVoxelCount()
const;
322 void evalMinMax(ValueType &
min, ValueType &
max)
const;
331 const ValueType& getValue(
const Coord& xyz)
const;
334 template<
typename AccessT>
const ValueType& getValue(
const Coord& xyz, AccessT&)
const;
340 int getValueDepth(
const Coord& xyz)
const;
343 void setValue(
const Coord& xyz,
const ValueType& value);
345 void setValueOnly(
const Coord& xyz,
const ValueType& value);
348 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
350 void setValueOn(
const Coord& xyz);
352 void setValueOn(
const Coord& xyz,
const ValueType& value);
355 void setValueOnMin(
const Coord& xyz,
const ValueType& value);
358 void setValueOnMax(
const Coord& xyz,
const ValueType& value);
361 void setValueOnSum(
const Coord& xyz,
const ValueType& value);
364 void setValueOff(
const Coord& xyz);
366 void setValueOff(
const Coord& xyz,
const ValueType& value);
369 void setActiveState(
const Coord& xyz,
bool on);
373 bool probeValue(
const Coord& xyz, ValueType& value)
const;
391 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
399 template<
typename PruneOp>
void pruneOp(PruneOp&);
404 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
408 void pruneInactive(
const ValueType&);
412 void pruneInactive();
421 void pruneLevelSet();
429 LeafNodeType* touchLeaf(
const Coord& xyz);
433 LeafNodeType* probeLeaf(
const Coord& xyz);
436 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
447 bool empty()
const {
return mRoot.empty(); }
450 void clear() { this->clearAllAccessors(); mRoot.clear(); }
453 void clearAllAccessors();
495 this->clearAllAccessors();
497 mRoot.merge(other.
mRoot);
501 void voxelizeActiveTiles()
503 this->clearAllAccessors();
504 mRoot.voxelizeActiveTiles();
515 template<
typename OtherRootNodeType>
518 this->clearAllAccessors();
567 template<
typename CombineOp>
568 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
570 template<
typename CombineOp>
571 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
613 template<
typename ExtendedCombineOp>
614 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
616 template<
typename ExtendedCombineOp>
617 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
645 template<
typename CombineOp>
646 void combine2(
const Tree& a,
const Tree& b, CombineOp& op,
bool prune =
false);
648 template<
typename CombineOp>
649 void combine2(
const Tree& a,
const Tree& b,
const CombineOp& op,
bool prune =
false);
691 template<
typename ExtendedCombineOp>
692 void combine2Extended(
const Tree& a,
const Tree& b, ExtendedCombineOp& op,
695 template<
typename ExtendedCombineOp>
696 void combine2Extended(
const Tree& a,
const Tree& b,
const ExtendedCombineOp&,
747 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp& op)
const
749 mRoot.visitActiveBBox(op);
807 template<
typename VisitorOp>
void visit(VisitorOp& op);
808 template<
typename VisitorOp>
void visit(
const VisitorOp& op);
814 template<
typename VisitorOp>
void visit(VisitorOp& op)
const;
815 template<
typename VisitorOp>
void visit(
const VisitorOp& op)
const;
865 template<
typename OtherTreeType,
typename VisitorOp>
866 void visit2(OtherTreeType& other, VisitorOp& op);
867 template<
typename OtherTreeType,
typename VisitorOp>
868 void visit2(OtherTreeType& other,
const VisitorOp& op);
880 template<
typename OtherTreeType,
typename VisitorOp>
881 void visit2(OtherTreeType& other, VisitorOp& op)
const;
882 template<
typename OtherTreeType,
typename VisitorOp>
883 void visit2(OtherTreeType& other,
const VisitorOp& op)
const;
898 typename RootNodeType::ChildOffCIter
beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
899 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
900 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
905 typename RootNodeType::ChildAllCIter
beginRootDense()
const {
return mRoot.cbeginChildAll(); }
906 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
907 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
965 template<
typename IterT> IterT begin();
968 template<
typename CIterT> CIterT cbegin()
const;
980 void releaseAllAccessors();
996 template<
typename T, Index N1, Index N2, Index N3>
1008 int32_t bufferCount;
1009 is.read(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1010 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1017 int32_t bufferCount = 1;
1018 os.write(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1025 os <<
" Tree Type: " << type()
1026 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1027 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1028 <<
" Leaf Node Count: " << leafCount() << std::endl
1029 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1044 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1045 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1046 return tree.beginRootChildren();
1050 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1051 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1052 return tree.cbeginRootChildren();
1056 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1057 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1058 return tree.beginRootTiles();
1062 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1063 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1064 return tree.cbeginRootTiles();
1068 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1069 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1070 return tree.beginRootDense();
1074 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1075 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1076 return tree.cbeginRootDense();
1081 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1085 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1089 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1093 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1097 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1100 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1101 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1104 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1105 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1108 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1109 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1112 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1113 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1116 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1117 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1121 template<
typename RootNodeType>
1122 template<
typename IterT>
1130 template<
typename RootNodeType>
1131 template<
typename IterT>
1142 template<
typename RootNodeType>
1146 this->clearAllAccessors();
1148 mRoot.readTopology(is, saveFloatAsHalf);
1152 template<
typename RootNodeType>
1157 mRoot.writeTopology(os, saveFloatAsHalf);
1161 template<
typename RootNodeType>
1165 this->clearAllAccessors();
1166 mRoot.readBuffers(is, saveFloatAsHalf);
1170 template<
typename RootNodeType>
1181 template<
typename RootNodeType>
1185 typename AccessorRegistry::accessor a;
1186 mAccessorRegistry.insert(a, &accessor);
1190 template<
typename RootNodeType>
1194 typename ConstAccessorRegistry::accessor a;
1195 mConstAccessorRegistry.insert(a, &accessor);
1199 template<
typename RootNodeType>
1203 mAccessorRegistry.erase(&accessor);
1207 template<
typename RootNodeType>
1211 mConstAccessorRegistry.erase(&accessor);
1215 template<
typename RootNodeType>
1219 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1220 it != mAccessorRegistry.end(); ++it)
1222 if (it->first) it->first->
clear();
1225 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1226 it != mConstAccessorRegistry.end(); ++it)
1228 if (it->first) it->first->clear();
1233 template<
typename RootNodeType>
1237 mAccessorRegistry.erase(NULL);
1238 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1239 it != mAccessorRegistry.end(); ++it)
1241 it->first->release();
1243 mAccessorRegistry.
clear();
1245 mAccessorRegistry.erase(NULL);
1246 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1247 it != mConstAccessorRegistry.end(); ++it)
1249 it->first->release();
1251 mConstAccessorRegistry.clear();
1258 template<
typename RootNodeType>
1259 inline const typename RootNodeType::ValueType&
1266 template<
typename RootNodeType>
1267 template<
typename AccessT>
1268 inline const typename RootNodeType::ValueType&
1275 template<
typename RootNodeType>
1283 template<
typename RootNodeType>
1291 template<
typename RootNodeType>
1299 template<
typename RootNodeType>
1307 template<
typename RootNodeType>
1314 template<
typename RootNodeType>
1321 template<
typename RootNodeType>
1322 template<
typename AccessT>
1330 template<
typename RootNodeType>
1338 template<
typename RootNodeType>
1346 template<
typename RootNodeType>
1354 template<
typename RootNodeType>
1362 template<
typename RootNodeType>
1370 template<
typename RootNodeType>
1381 template<
typename RootNodeType>
1382 template<
typename PruneOp>
1386 this->clearAllAccessors();
1391 template<
typename RootNodeType>
1400 template<
typename RootNodeType>
1409 template<
typename RootNodeType>
1413 this->pruneInactive(this->getBackground());
1416 template<
typename RootNodeType>
1424 template<
typename RootNodeType>
1425 inline typename RootNodeType::LeafNodeType*
1431 template<
typename RootNodeType>
1432 inline typename RootNodeType::LeafNodeType*
1438 template<
typename RootNodeType>
1439 inline const typename RootNodeType::LeafNodeType*
1448 template<
typename RootNodeType>
1452 this->clearAllAccessors();
1453 return mRoot.fill(bbox, value, active);
1457 template<
typename RootNodeType>
1465 if (MetadataT* m = dynamic_cast<MetadataT*>(result.get())) {
1466 m->value() = mRoot.getBackground();
1478 template<
typename ValueT,
typename CombineOp>
1484 op(args.
a(), args.
b(), args.
result());
1491 template<
typename RootNodeType>
1492 template<
typename CombineOp>
1497 this->combineExtended(other, extendedOp, prune);
1504 template<
typename RootNodeType>
1505 template<
typename CombineOp>
1510 this->combineExtended(other, extendedOp, prune);
1515 template<
typename RootNodeType>
1516 template<
typename ExtendedCombineOp>
1520 this->clearAllAccessors();
1528 template<
typename RootNodeType>
1529 template<
typename ExtendedCombineOp>
1533 this->clearAllAccessors();
1534 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op, prune);
1539 template<
typename RootNodeType>
1540 template<
typename CombineOp>
1545 this->combine2Extended(a, b, extendedOp, prune);
1552 template<
typename RootNodeType>
1553 template<
typename CombineOp>
1558 this->combine2Extended(a, b, extendedOp, prune);
1563 template<
typename RootNodeType>
1564 template<
typename ExtendedCombineOp>
1567 ExtendedCombineOp& op,
bool prune)
1569 this->clearAllAccessors();
1577 template<
typename RootNodeType>
1578 template<
typename ExtendedCombineOp>
1581 const ExtendedCombineOp& op,
bool prune)
1583 this->clearAllAccessors();
1584 mRoot.template combine2<const ExtendedCombineOp>(a.
mRoot, b.
mRoot, op, prune);
1592 template<
typename RootNodeType>
1593 template<
typename VisitorOp>
1597 this->clearAllAccessors();
1598 mRoot.template visit<VisitorOp>(op);
1602 template<
typename RootNodeType>
1603 template<
typename VisitorOp>
1607 mRoot.template visit<VisitorOp>(op);
1613 template<
typename RootNodeType>
1614 template<
typename VisitorOp>
1618 this->clearAllAccessors();
1619 mRoot.template visit<const VisitorOp>(op);
1625 template<
typename RootNodeType>
1626 template<
typename VisitorOp>
1630 mRoot.template visit<const VisitorOp>(op);
1637 template<
typename RootNodeType>
1638 template<
typename OtherTreeType,
typename VisitorOp>
1642 this->clearAllAccessors();
1643 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1644 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.getRootNode(), op);
1648 template<
typename RootNodeType>
1649 template<
typename OtherTreeType,
typename VisitorOp>
1653 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1654 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.getRootNode(), op);
1660 template<
typename RootNodeType>
1661 template<
typename OtherTreeType,
typename VisitorOp>
1665 this->clearAllAccessors();
1666 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1667 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.getRootNode(), op);
1673 template<
typename RootNodeType>
1674 template<
typename OtherTreeType,
typename VisitorOp>
1678 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1679 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.getRootNode(), op);
1686 template<
typename RootNodeType>
1690 static tbb::atomic<const Name*> sTypeName;
1691 if (sTypeName == NULL) {
1692 std::vector<Index> dims;
1693 Tree::getNodeLog2Dims(dims);
1694 std::ostringstream ostr;
1695 ostr <<
"Tree_" << typeNameAsString<ValueType>();
1696 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
1697 ostr <<
"_" << dims[i];
1700 sTypeName.compare_and_swap(s, NULL);
1701 if (sTypeName != s)
delete s;
1707 template<
typename RootNodeType>
1708 template<
typename OtherRootNodeType>
1716 template<
typename RootNodeType>
1721 this->evalActiveVoxelDim(dim);
1723 totalVoxels = dim.
x() * dim.
y() * dim.
z(),
1724 activeVoxels = this->activeVoxelCount();
1725 assert(totalVoxels >= activeVoxels);
1726 return totalVoxels - activeVoxels;
1730 template<
typename RootNodeType>
1734 if (this->empty()) {
1743 for (
LeafCIter bIter(*
this); bIter; ++bIter) {
1744 bIter->getOrigin(ijk);
1747 bbox.
max() +=
Coord(LeafNodeType::dim()-1);
1751 template<
typename RootNodeType>
1756 if (this->empty())
return false;
1758 mRoot.evalActiveVoxelBoundingBox(bbox);
1764 template<
typename RootNodeType>
1769 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
1775 template<
typename RootNodeType>
1780 bool notEmpty = this->evalLeafBoundingBox(bbox);
1786 template<
typename RootNodeType>
1790 minVal = maxVal = zeroVal<ValueType>();
1792 minVal = maxVal = *iter;
1793 for (++iter; iter; ++iter) {
1795 if (val < minVal) minVal = val;
1796 if (val > maxVal) maxVal = val;
1802 template<
typename RootNodeType>
1807 RootNodeType::getNodeLog2Dims(dims);
1811 template<
typename RootNodeType>
1815 if (verboseLevel <= 0)
return;
1819 std::streamsize savedPrecision;
1820 OnExit(std::ostream& os): os(os), savedPrecision(os.precision()) {}
1821 ~OnExit() { os.precision(savedPrecision); }
1823 OnExit restorePrecision(os);
1825 std::vector<Index> dims;
1826 Tree::getNodeLog2Dims(dims);
1828 std::vector<Index64> nodeCount;
1830 os <<
"Information about Tree:\n"
1831 <<
" Type: " << this->type() <<
"\n";
1833 os <<
" Configuration:\n";
1834 if (verboseLevel <= 1) {
1836 os <<
" Root(" << mRoot.getTableSize() <<
")";
1837 if (dims.size() > 1) {
1838 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1839 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
1841 os <<
", Leaf(" << (1 << *dims.rbegin()) <<
"^3)\n";
1845 nodeCount.resize(dims.size());
1846 for (
NodeCIter it = cbeginNode(); it; ++it) {
1847 ++(nodeCount[it.getDepth()]);
1849 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
1850 if (dims.size() > 1) {
1851 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1853 os <<
" x " << (1 << dims[i]) <<
"^3)";
1856 os <<
" x " << (1 << *dims.rbegin()) <<
"^3)\n";
1859 os <<
" Background value: " << mRoot.getBackground() <<
"\n";
1861 if (verboseLevel == 1)
return;
1865 if (nodeCount.empty()) {
1866 nodeCount.resize(dims.size());
1867 for (
NodeCIter it = cbeginNode(); it; ++it) {
1868 ++(nodeCount[it.getDepth()]);
1874 this->evalMinMax(minVal, maxVal);
1875 os <<
" Min value: " << minVal <<
"\n";
1876 os <<
" Max value: " << maxVal <<
"\n";
1879 leafCount = *nodeCount.rbegin(),
1880 numActiveVoxels = this->activeVoxelCount(),
1881 numActiveLeafVoxels = this->activeLeafVoxelCount();
1886 uint64_t totalVoxels = 0;
1887 if (numActiveVoxels) {
1889 this->evalActiveVoxelBoundingBox(bbox);
1891 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
1893 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
1894 os <<
" Dimensions of active voxels: "
1895 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
1897 const double activeRatio = (100.0 * numActiveVoxels) / totalVoxels;
1898 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
1901 const double fillRatio =
1902 (100.0 * numActiveLeafVoxels) / (leafCount * LeafNodeType::NUM_VOXELS);
1903 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
1906 os <<
" Tree is empty!\n";
1910 if (verboseLevel == 2)
return;
1914 actualMem = this->memUsage(),
1915 denseMem =
sizeof(
ValueType) * totalVoxels,
1916 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
1919 os <<
"Memory footprint:\n";
1923 if (numActiveVoxels) {
1925 os <<
" Actual footprint is " << (100.0 * actualMem / denseMem)
1926 <<
"% of dense* footprint\n";
1927 os <<
" Leaf voxel footprint is " << (100.0 * voxelsMem / actualMem)
1928 <<
"% of actual footprint\n";
1929 os <<
" *Dense refers to the smallest equivalent non-sparse volume" << std::endl;
1937 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED