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(); }
257 RootNodeType& root() {
return mRoot; }
271 template<
typename OtherRootNodeType>
274 virtual bool evalLeafBoundingBox(
CoordBBox& bbox)
const;
275 virtual bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const;
276 virtual bool evalActiveVoxelDim(
Coord& dim)
const;
277 virtual bool evalLeafDim(
Coord& dim)
const;
282 static void getNodeLog2Dims(std::vector<Index>& dims);
291 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
295 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
297 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false);
299 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const;
301 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
322 virtual Index64 inactiveVoxelCount()
const;
325 void evalMinMax(ValueType &
min, ValueType &
max)
const;
334 const ValueType& getValue(
const Coord& xyz)
const;
337 template<
typename AccessT>
const ValueType& getValue(
const Coord& xyz, AccessT&)
const;
343 int getValueDepth(
const Coord& xyz)
const;
346 void setValue(
const Coord& xyz,
const ValueType& value);
348 void setValueOnly(
const Coord& xyz,
const ValueType& value);
351 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
353 void setValueOn(
const Coord& xyz);
355 void setValueOn(
const Coord& xyz,
const ValueType& value);
358 void setValueOnMin(
const Coord& xyz,
const ValueType& value);
361 void setValueOnMax(
const Coord& xyz,
const ValueType& value);
364 void setValueOnSum(
const Coord& xyz,
const ValueType& value);
367 void setValueOff(
const Coord& xyz);
369 void setValueOff(
const Coord& xyz,
const ValueType& value);
372 void setActiveState(
const Coord& xyz,
bool on);
376 bool probeValue(
const Coord& xyz, ValueType& value)
const;
394 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
402 template<
typename PruneOp>
void pruneOp(PruneOp&);
407 void prune(
const ValueType&
tolerance = zeroVal<ValueType>());
411 void pruneInactive(
const ValueType&);
415 void pruneInactive();
424 void pruneLevelSet();
435 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
441 template<
typename NodeT>
442 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
450 LeafNodeType* touchLeaf(
const Coord& xyz);
454 LeafNodeType* probeLeaf(
const Coord& xyz);
458 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
466 bool empty()
const {
return mRoot.empty(); }
469 void clear() { this->clearAllAccessors(); mRoot.clear(); }
472 void clearAllAccessors();
513 void signedFloodFill(
const ValueType& outside,
const ValueType& inside);
520 void merge(
Tree& other);
523 void voxelizeActiveTiles();
538 template<
typename OtherRootNodeType>
586 template<
typename CombineOp>
587 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
589 template<
typename CombineOp>
590 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
632 template<
typename ExtendedCombineOp>
633 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
635 template<
typename ExtendedCombineOp>
636 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
664 template<
typename CombineOp>
665 void combine2(
const Tree& a,
const Tree& b, CombineOp& op,
bool prune =
false);
667 template<
typename CombineOp>
668 void combine2(
const Tree& a,
const Tree& b,
const CombineOp& op,
bool prune =
false);
710 template<
typename ExtendedCombineOp>
711 void combine2Extended(
const Tree& a,
const Tree& b, ExtendedCombineOp& op,
714 template<
typename ExtendedCombineOp>
715 void combine2Extended(
const Tree& a,
const Tree& b,
const ExtendedCombineOp&,
765 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp& op)
const { 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;
904 typename RootNodeType::ChildOnCIter beginRootChildren()
const {
return mRoot.cbeginChildOn(); }
911 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(); }
918 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(); }
945 LeafIter beginLeaf() {
return LeafIter(*
this); }
965 ValueOnIter beginValueOn() {
return ValueOnIter(*
this); }
971 ValueOffIter beginValueOff() {
return ValueOffIter(*
this); }
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());
1431 template<
typename RootNodeType>
1440 template<
typename RootNodeType>
1445 mRoot.
addTile(level, xyz, value, active);
1448 template<
typename RootNodeType>
1449 template<
typename NodeT>
1453 this->clearAllAccessors();
1454 return mRoot.template stealNode<NodeT>(xyz, value, active);
1457 template<
typename RootNodeType>
1458 inline typename RootNodeType::LeafNodeType*
1465 template<
typename RootNodeType>
1466 inline typename RootNodeType::LeafNodeType*
1473 template<
typename RootNodeType>
1474 inline const typename RootNodeType::LeafNodeType*
1484 template<
typename RootNodeType>
1488 this->clearAllAccessors();
1489 return mRoot.fill(bbox, value, active);
1493 template<
typename RootNodeType>
1501 template<
typename RootNodeType>
1509 if (MetadataT* m = dynamic_cast<MetadataT*>(result.get())) {
1510 m->value() = mRoot.background();
1520 template<
typename RootNodeType>
1524 this->clearAllAccessors();
1526 mRoot.merge(other.
mRoot);
1530 template<
typename RootNodeType>
1534 this->clearAllAccessors();
1535 mRoot.voxelizeActiveTiles();
1539 template<
typename RootNodeType>
1540 template<
typename OtherRootNodeType>
1544 this->clearAllAccessors();
1554 template<
typename ValueT,
typename CombineOp>
1560 op(args.
a(), args.
b(), args.
result());
1567 template<
typename RootNodeType>
1568 template<
typename CombineOp>
1573 this->combineExtended(other, extendedOp, prune);
1580 template<
typename RootNodeType>
1581 template<
typename CombineOp>
1586 this->combineExtended(other, extendedOp, prune);
1591 template<
typename RootNodeType>
1592 template<
typename ExtendedCombineOp>
1596 this->clearAllAccessors();
1604 template<
typename RootNodeType>
1605 template<
typename ExtendedCombineOp>
1609 this->clearAllAccessors();
1610 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op, prune);
1615 template<
typename RootNodeType>
1616 template<
typename CombineOp>
1621 this->combine2Extended(a, b, extendedOp, prune);
1628 template<
typename RootNodeType>
1629 template<
typename CombineOp>
1634 this->combine2Extended(a, b, extendedOp, prune);
1639 template<
typename RootNodeType>
1640 template<
typename ExtendedCombineOp>
1643 ExtendedCombineOp& op,
bool prune)
1645 this->clearAllAccessors();
1653 template<
typename RootNodeType>
1654 template<
typename ExtendedCombineOp>
1657 const ExtendedCombineOp& op,
bool prune)
1659 this->clearAllAccessors();
1660 mRoot.template combine2<const ExtendedCombineOp>(a.
mRoot, b.
mRoot, op, prune);
1668 template<
typename RootNodeType>
1669 template<
typename VisitorOp>
1673 this->clearAllAccessors();
1674 mRoot.template visit<VisitorOp>(op);
1678 template<
typename RootNodeType>
1679 template<
typename VisitorOp>
1683 mRoot.template visit<VisitorOp>(op);
1689 template<
typename RootNodeType>
1690 template<
typename VisitorOp>
1694 this->clearAllAccessors();
1695 mRoot.template visit<const VisitorOp>(op);
1701 template<
typename RootNodeType>
1702 template<
typename VisitorOp>
1706 mRoot.template visit<const VisitorOp>(op);
1713 template<
typename RootNodeType>
1714 template<
typename OtherTreeType,
typename VisitorOp>
1718 this->clearAllAccessors();
1719 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1720 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.getRootNode(), op);
1724 template<
typename RootNodeType>
1725 template<
typename OtherTreeType,
typename VisitorOp>
1729 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1730 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.getRootNode(), op);
1736 template<
typename RootNodeType>
1737 template<
typename OtherTreeType,
typename VisitorOp>
1741 this->clearAllAccessors();
1742 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1743 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.getRootNode(), op);
1749 template<
typename RootNodeType>
1750 template<
typename OtherTreeType,
typename VisitorOp>
1754 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1755 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.getRootNode(), op);
1762 template<
typename RootNodeType>
1766 static tbb::atomic<const Name*> sTypeName;
1767 if (sTypeName == NULL) {
1768 std::vector<Index> dims;
1769 Tree::getNodeLog2Dims(dims);
1770 std::ostringstream ostr;
1771 ostr <<
"Tree_" << typeNameAsString<ValueType>();
1772 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
1773 ostr <<
"_" << dims[i];
1776 sTypeName.compare_and_swap(s, NULL);
1777 if (sTypeName != s)
delete s;
1783 template<
typename RootNodeType>
1784 template<
typename OtherRootNodeType>
1792 template<
typename RootNodeType>
1797 this->evalActiveVoxelDim(dim);
1799 totalVoxels = dim.
x() * dim.
y() * dim.
z(),
1800 activeVoxels = this->activeVoxelCount();
1801 assert(totalVoxels >= activeVoxels);
1802 return totalVoxels - activeVoxels;
1806 template<
typename RootNodeType>
1810 if (this->empty()) {
1819 for (
LeafCIter bIter(*
this); bIter; ++bIter) {
1820 bIter->getOrigin(ijk);
1823 bbox.
max() +=
Coord(LeafNodeType::dim()-1);
1827 template<
typename RootNodeType>
1832 if (this->empty())
return false;
1834 mRoot.evalActiveVoxelBoundingBox(bbox);
1840 template<
typename RootNodeType>
1845 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
1851 template<
typename RootNodeType>
1856 bool notEmpty = this->evalLeafBoundingBox(bbox);
1862 template<
typename RootNodeType>
1866 minVal = maxVal = zeroVal<ValueType>();
1868 minVal = maxVal = *iter;
1869 for (++iter; iter; ++iter) {
1871 if (val < minVal) minVal = val;
1872 if (val > maxVal) maxVal = val;
1878 template<
typename RootNodeType>
1883 RootNodeType::getNodeLog2Dims(dims);
1887 template<
typename RootNodeType>
1891 if (verboseLevel <= 0)
return;
1895 std::streamsize savedPrecision;
1896 OnExit(std::ostream& os): os(os), savedPrecision(os.precision()) {}
1897 ~OnExit() { os.precision(savedPrecision); }
1899 OnExit restorePrecision(os);
1901 std::vector<Index> dims;
1902 Tree::getNodeLog2Dims(dims);
1904 std::vector<Index64> nodeCount;
1906 os <<
"Information about Tree:\n"
1907 <<
" Type: " << this->type() <<
"\n";
1909 os <<
" Configuration:\n";
1910 if (verboseLevel <= 1) {
1912 os <<
" Root(" << mRoot.getTableSize() <<
")";
1913 if (dims.size() > 1) {
1914 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1915 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
1917 os <<
", Leaf(" << (1 << *dims.rbegin()) <<
"^3)\n";
1921 nodeCount.resize(dims.size());
1922 for (
NodeCIter it = cbeginNode(); it; ++it) {
1923 ++(nodeCount[it.getDepth()]);
1925 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
1926 if (dims.size() > 1) {
1927 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1929 os <<
" x " << (1 << dims[i]) <<
"^3)";
1932 os <<
" x " << (1 << *dims.rbegin()) <<
"^3)\n";
1935 os <<
" Background value: " << mRoot.background() <<
"\n";
1937 if (verboseLevel == 1)
return;
1941 if (nodeCount.empty()) {
1942 nodeCount.resize(dims.size());
1943 for (
NodeCIter it = cbeginNode(); it; ++it) {
1944 ++(nodeCount[it.getDepth()]);
1950 this->evalMinMax(minVal, maxVal);
1951 os <<
" Min value: " << minVal <<
"\n";
1952 os <<
" Max value: " << maxVal <<
"\n";
1955 leafCount = *nodeCount.rbegin(),
1956 numActiveVoxels = this->activeVoxelCount(),
1957 numActiveLeafVoxels = this->activeLeafVoxelCount();
1962 uint64_t totalVoxels = 0;
1963 if (numActiveVoxels) {
1965 this->evalActiveVoxelBoundingBox(bbox);
1967 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
1969 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
1970 os <<
" Dimensions of active voxels: "
1971 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
1973 const double activeRatio = (100.0 * numActiveVoxels) / totalVoxels;
1974 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
1977 const double fillRatio =
1978 (100.0 * numActiveLeafVoxels) / (leafCount * LeafNodeType::NUM_VOXELS);
1979 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
1982 os <<
" Tree is empty!\n";
1986 if (verboseLevel == 2)
return;
1990 actualMem = this->memUsage(),
1991 denseMem =
sizeof(
ValueType) * totalVoxels,
1992 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
1995 os <<
"Memory footprint:\n";
1999 if (numActiveVoxels) {
2001 os <<
" Actual footprint is " << (100.0 * actualMem / denseMem)
2002 <<
"% of dense* footprint\n";
2003 os <<
" Leaf voxel footprint is " << (100.0 * voxelsMem / actualMem)
2004 <<
"% of actual footprint\n";
2005 os <<
" *Dense refers to the smallest equivalent non-sparse volume" << std::endl;
2013 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED