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;
444 bool empty()
const {
return mRoot.empty(); }
447 void clear() { this->clearAllAccessors(); mRoot.clear(); }
450 void clearAllAccessors();
493 mRoot.signedFloodFill(outside, inside);
503 this->clearAllAccessors();
505 mRoot.merge(other.
mRoot);
509 void voxelizeActiveTiles()
511 this->clearAllAccessors();
512 mRoot.voxelizeActiveTiles();
529 template<
typename OtherRootNodeType>
532 this->clearAllAccessors();
581 template<
typename CombineOp>
582 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
584 template<
typename CombineOp>
585 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
627 template<
typename ExtendedCombineOp>
628 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
630 template<
typename ExtendedCombineOp>
631 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
659 template<
typename CombineOp>
660 void combine2(
const Tree& a,
const Tree& b, CombineOp& op,
bool prune =
false);
662 template<
typename CombineOp>
663 void combine2(
const Tree& a,
const Tree& b,
const CombineOp& op,
bool prune =
false);
705 template<
typename ExtendedCombineOp>
706 void combine2Extended(
const Tree& a,
const Tree& b, ExtendedCombineOp& op,
709 template<
typename ExtendedCombineOp>
710 void combine2Extended(
const Tree& a,
const Tree& b,
const ExtendedCombineOp&,
761 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp& op)
const
763 mRoot.visitActiveBBox(op);
821 template<
typename VisitorOp>
void visit(VisitorOp& op);
822 template<
typename VisitorOp>
void visit(
const VisitorOp& op);
828 template<
typename VisitorOp>
void visit(VisitorOp& op)
const;
829 template<
typename VisitorOp>
void visit(
const VisitorOp& op)
const;
879 template<
typename OtherTreeType,
typename VisitorOp>
880 void visit2(OtherTreeType& other, VisitorOp& op);
881 template<
typename OtherTreeType,
typename VisitorOp>
882 void visit2(OtherTreeType& other,
const VisitorOp& op);
894 template<
typename OtherTreeType,
typename VisitorOp>
895 void visit2(OtherTreeType& other, VisitorOp& op)
const;
896 template<
typename OtherTreeType,
typename VisitorOp>
897 void visit2(OtherTreeType& other,
const VisitorOp& op)
const;
912 typename RootNodeType::ChildOffCIter
beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
913 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
914 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
919 typename RootNodeType::ChildAllCIter
beginRootDense()
const {
return mRoot.cbeginChildAll(); }
920 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
921 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
979 template<
typename IterT> IterT begin();
982 template<
typename CIterT> CIterT cbegin()
const;
994 void releaseAllAccessors();
1010 template<
typename T, Index N1, Index N2, Index N3>
1022 int32_t bufferCount;
1023 is.read(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1024 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1031 int32_t bufferCount = 1;
1032 os.write(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1039 os <<
" Tree Type: " << type()
1040 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1041 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1042 <<
" Leaf Node Count: " << leafCount() << std::endl
1043 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1058 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1059 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1060 return tree.beginRootChildren();
1064 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1065 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1066 return tree.cbeginRootChildren();
1070 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1071 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1072 return tree.beginRootTiles();
1076 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1077 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1078 return tree.cbeginRootTiles();
1082 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1083 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1084 return tree.beginRootDense();
1088 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1089 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1090 return tree.cbeginRootDense();
1095 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1099 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1103 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1107 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1111 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1114 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1115 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1118 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1119 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1122 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1123 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1126 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1127 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1130 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1131 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1135 template<
typename RootNodeType>
1136 template<
typename IterT>
1144 template<
typename RootNodeType>
1145 template<
typename IterT>
1156 template<
typename RootNodeType>
1160 this->clearAllAccessors();
1162 mRoot.readTopology(is, saveFloatAsHalf);
1166 template<
typename RootNodeType>
1171 mRoot.writeTopology(os, saveFloatAsHalf);
1175 template<
typename RootNodeType>
1179 this->clearAllAccessors();
1180 mRoot.readBuffers(is, saveFloatAsHalf);
1184 template<
typename RootNodeType>
1195 template<
typename RootNodeType>
1199 typename AccessorRegistry::accessor a;
1200 mAccessorRegistry.insert(a, &accessor);
1204 template<
typename RootNodeType>
1208 typename ConstAccessorRegistry::accessor a;
1209 mConstAccessorRegistry.insert(a, &accessor);
1213 template<
typename RootNodeType>
1217 mAccessorRegistry.erase(&accessor);
1221 template<
typename RootNodeType>
1225 mConstAccessorRegistry.erase(&accessor);
1229 template<
typename RootNodeType>
1233 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1234 it != mAccessorRegistry.end(); ++it)
1236 if (it->first) it->first->
clear();
1239 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1240 it != mConstAccessorRegistry.end(); ++it)
1242 if (it->first) it->first->clear();
1247 template<
typename RootNodeType>
1251 mAccessorRegistry.erase(NULL);
1252 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1253 it != mAccessorRegistry.end(); ++it)
1255 it->first->release();
1257 mAccessorRegistry.
clear();
1259 mAccessorRegistry.erase(NULL);
1260 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1261 it != mConstAccessorRegistry.end(); ++it)
1263 it->first->release();
1265 mConstAccessorRegistry.clear();
1272 template<
typename RootNodeType>
1273 inline const typename RootNodeType::ValueType&
1280 template<
typename RootNodeType>
1281 template<
typename AccessT>
1282 inline const typename RootNodeType::ValueType&
1289 template<
typename RootNodeType>
1297 template<
typename RootNodeType>
1305 template<
typename RootNodeType>
1313 template<
typename RootNodeType>
1321 template<
typename RootNodeType>
1328 template<
typename RootNodeType>
1335 template<
typename RootNodeType>
1336 template<
typename AccessT>
1344 template<
typename RootNodeType>
1352 template<
typename RootNodeType>
1360 template<
typename RootNodeType>
1368 template<
typename RootNodeType>
1376 template<
typename RootNodeType>
1384 template<
typename RootNodeType>
1395 template<
typename RootNodeType>
1396 template<
typename PruneOp>
1400 this->clearAllAccessors();
1405 template<
typename RootNodeType>
1414 template<
typename RootNodeType>
1423 template<
typename RootNodeType>
1427 this->pruneInactive(this->background());
1430 template<
typename RootNodeType>
1438 template<
typename RootNodeType>
1439 inline typename RootNodeType::LeafNodeType*
1445 template<
typename RootNodeType>
1446 inline typename RootNodeType::LeafNodeType*
1452 template<
typename RootNodeType>
1453 inline const typename RootNodeType::LeafNodeType*
1462 template<
typename RootNodeType>
1466 this->clearAllAccessors();
1467 return mRoot.fill(bbox, value, active);
1471 template<
typename RootNodeType>
1479 if (MetadataT* m = dynamic_cast<MetadataT*>(result.get())) {
1480 m->value() = mRoot.background();
1492 template<
typename ValueT,
typename CombineOp>
1498 op(args.
a(), args.
b(), args.
result());
1505 template<
typename RootNodeType>
1506 template<
typename CombineOp>
1511 this->combineExtended(other, extendedOp, prune);
1518 template<
typename RootNodeType>
1519 template<
typename CombineOp>
1524 this->combineExtended(other, extendedOp, prune);
1529 template<
typename RootNodeType>
1530 template<
typename ExtendedCombineOp>
1534 this->clearAllAccessors();
1542 template<
typename RootNodeType>
1543 template<
typename ExtendedCombineOp>
1547 this->clearAllAccessors();
1548 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op, prune);
1553 template<
typename RootNodeType>
1554 template<
typename CombineOp>
1559 this->combine2Extended(a, b, extendedOp, prune);
1566 template<
typename RootNodeType>
1567 template<
typename CombineOp>
1572 this->combine2Extended(a, b, extendedOp, prune);
1577 template<
typename RootNodeType>
1578 template<
typename ExtendedCombineOp>
1581 ExtendedCombineOp& op,
bool prune)
1583 this->clearAllAccessors();
1591 template<
typename RootNodeType>
1592 template<
typename ExtendedCombineOp>
1595 const ExtendedCombineOp& op,
bool prune)
1597 this->clearAllAccessors();
1598 mRoot.template combine2<const ExtendedCombineOp>(a.
mRoot, b.
mRoot, op, prune);
1606 template<
typename RootNodeType>
1607 template<
typename VisitorOp>
1611 this->clearAllAccessors();
1612 mRoot.template visit<VisitorOp>(op);
1616 template<
typename RootNodeType>
1617 template<
typename VisitorOp>
1621 mRoot.template visit<VisitorOp>(op);
1627 template<
typename RootNodeType>
1628 template<
typename VisitorOp>
1632 this->clearAllAccessors();
1633 mRoot.template visit<const VisitorOp>(op);
1639 template<
typename RootNodeType>
1640 template<
typename VisitorOp>
1644 mRoot.template visit<const VisitorOp>(op);
1651 template<
typename RootNodeType>
1652 template<
typename OtherTreeType,
typename VisitorOp>
1656 this->clearAllAccessors();
1657 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1658 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.getRootNode(), op);
1662 template<
typename RootNodeType>
1663 template<
typename OtherTreeType,
typename VisitorOp>
1667 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1668 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.getRootNode(), op);
1674 template<
typename RootNodeType>
1675 template<
typename OtherTreeType,
typename VisitorOp>
1679 this->clearAllAccessors();
1680 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1681 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.getRootNode(), op);
1687 template<
typename RootNodeType>
1688 template<
typename OtherTreeType,
typename VisitorOp>
1692 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1693 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.getRootNode(), op);
1700 template<
typename RootNodeType>
1704 static tbb::atomic<const Name*> sTypeName;
1705 if (sTypeName == NULL) {
1706 std::vector<Index> dims;
1707 Tree::getNodeLog2Dims(dims);
1708 std::ostringstream ostr;
1709 ostr <<
"Tree_" << typeNameAsString<ValueType>();
1710 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
1711 ostr <<
"_" << dims[i];
1714 sTypeName.compare_and_swap(s, NULL);
1715 if (sTypeName != s)
delete s;
1721 template<
typename RootNodeType>
1722 template<
typename OtherRootNodeType>
1730 template<
typename RootNodeType>
1735 this->evalActiveVoxelDim(dim);
1737 totalVoxels = dim.
x() * dim.
y() * dim.
z(),
1738 activeVoxels = this->activeVoxelCount();
1739 assert(totalVoxels >= activeVoxels);
1740 return totalVoxels - activeVoxels;
1744 template<
typename RootNodeType>
1748 if (this->empty()) {
1757 for (
LeafCIter bIter(*
this); bIter; ++bIter) {
1758 bIter->getOrigin(ijk);
1761 bbox.
max() +=
Coord(LeafNodeType::dim()-1);
1765 template<
typename RootNodeType>
1770 if (this->empty())
return false;
1772 mRoot.evalActiveVoxelBoundingBox(bbox);
1778 template<
typename RootNodeType>
1783 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
1789 template<
typename RootNodeType>
1794 bool notEmpty = this->evalLeafBoundingBox(bbox);
1800 template<
typename RootNodeType>
1804 minVal = maxVal = zeroVal<ValueType>();
1806 minVal = maxVal = *iter;
1807 for (++iter; iter; ++iter) {
1809 if (val < minVal) minVal = val;
1810 if (val > maxVal) maxVal = val;
1816 template<
typename RootNodeType>
1821 RootNodeType::getNodeLog2Dims(dims);
1825 template<
typename RootNodeType>
1829 if (verboseLevel <= 0)
return;
1833 std::streamsize savedPrecision;
1834 OnExit(std::ostream& os): os(os), savedPrecision(os.precision()) {}
1835 ~OnExit() { os.precision(savedPrecision); }
1837 OnExit restorePrecision(os);
1839 std::vector<Index> dims;
1840 Tree::getNodeLog2Dims(dims);
1842 std::vector<Index64> nodeCount;
1844 os <<
"Information about Tree:\n"
1845 <<
" Type: " << this->type() <<
"\n";
1847 os <<
" Configuration:\n";
1848 if (verboseLevel <= 1) {
1850 os <<
" Root(" << mRoot.getTableSize() <<
")";
1851 if (dims.size() > 1) {
1852 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1853 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
1855 os <<
", Leaf(" << (1 << *dims.rbegin()) <<
"^3)\n";
1859 nodeCount.resize(dims.size());
1860 for (
NodeCIter it = cbeginNode(); it; ++it) {
1861 ++(nodeCount[it.getDepth()]);
1863 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
1864 if (dims.size() > 1) {
1865 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1867 os <<
" x " << (1 << dims[i]) <<
"^3)";
1870 os <<
" x " << (1 << *dims.rbegin()) <<
"^3)\n";
1873 os <<
" Background value: " << mRoot.background() <<
"\n";
1875 if (verboseLevel == 1)
return;
1879 if (nodeCount.empty()) {
1880 nodeCount.resize(dims.size());
1881 for (
NodeCIter it = cbeginNode(); it; ++it) {
1882 ++(nodeCount[it.getDepth()]);
1888 this->evalMinMax(minVal, maxVal);
1889 os <<
" Min value: " << minVal <<
"\n";
1890 os <<
" Max value: " << maxVal <<
"\n";
1893 leafCount = *nodeCount.rbegin(),
1894 numActiveVoxels = this->activeVoxelCount(),
1895 numActiveLeafVoxels = this->activeLeafVoxelCount();
1900 uint64_t totalVoxels = 0;
1901 if (numActiveVoxels) {
1903 this->evalActiveVoxelBoundingBox(bbox);
1905 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
1907 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
1908 os <<
" Dimensions of active voxels: "
1909 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
1911 const double activeRatio = (100.0 * numActiveVoxels) / totalVoxels;
1912 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
1915 const double fillRatio =
1916 (100.0 * numActiveLeafVoxels) / (leafCount * LeafNodeType::NUM_VOXELS);
1917 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
1920 os <<
" Tree is empty!\n";
1924 if (verboseLevel == 2)
return;
1928 actualMem = this->memUsage(),
1929 denseMem =
sizeof(
ValueType) * totalVoxels,
1930 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
1933 os <<
"Memory footprint:\n";
1937 if (numActiveVoxels) {
1939 os <<
" Actual footprint is " << (100.0 * actualMem / denseMem)
1940 <<
"% of dense* footprint\n";
1941 os <<
" Leaf voxel footprint is " << (100.0 * voxelsMem / actualMem)
1942 <<
"% of actual footprint\n";
1943 os <<
" *Dense refers to the smallest equivalent non-sparse volume" << std::endl;
1951 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED