6 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
21 #include <tbb/concurrent_hash_map.h>
111 #if OPENVDB_ABI_VERSION_NUMBER >= 7
112 virtual std::vector<Index32> nodeCount()
const = 0;
117 virtual Index32 nonLeafCount()
const = 0;
140 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
144 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
147 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
157 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
166 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
173 template<
typename _RootNodeType>
185 static const Index DEPTH = RootNodeType::LEVEL + 1;
193 template<
typename OtherValueType>
214 template<
typename OtherRootType>
229 template<
typename OtherTreeType>
230 Tree(
const OtherTreeType& other,
235 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
250 template<
typename OtherTreeType>
260 ~Tree()
override { this->clear(); releaseAllAccessors(); }
269 static const Name& treeType();
271 const Name&
type()
const override {
return this->treeType(); }
277 RootNodeType& root() {
return mRoot; }
288 template<
typename OtherRootNodeType>
291 bool evalLeafBoundingBox(
CoordBBox& bbox)
const override;
292 bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const override;
293 bool evalActiveVoxelDim(
Coord& dim)
const override;
294 bool evalLeafDim(
Coord& dim)
const override;
299 static void getNodeLog2Dims(std::vector<Index>& dims);
308 void readTopology(std::istream&,
bool saveFloatAsHalf =
false)
override;
312 void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
314 void readBuffers(std::istream&,
bool saveFloatAsHalf =
false)
override;
316 void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false)
override;
322 void readNonresidentBuffers()
const override;
324 void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
326 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const override;
338 #if OPENVDB_ABI_VERSION_NUMBER >= 7
339 std::vector<Index32> nodeCount()
const override
344 std::vector<Index32> vec(DEPTH, 0);
345 mRoot.nodeCount( vec );
349 Index32 nonLeafCount()
const override {
return mRoot.nonLeafCount(); }
358 Index64 inactiveVoxelCount()
const override;
363 void evalMinMax(ValueType &
min, ValueType &
max)
const;
372 const ValueType& getValue(
const Coord& xyz)
const;
380 int getValueDepth(
const Coord& xyz)
const;
383 void setActiveState(
const Coord& xyz,
bool on);
387 void setValueOn(
const Coord& xyz);
394 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
396 void setValueOff(
const Coord& xyz);
418 template<
typename ModifyOp>
419 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
440 template<
typename ModifyOp>
441 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
461 void clipUnallocatedNodes()
override;
464 Index32 unallocatedLeafCount()
const override;
467 void sparseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
478 this->sparseFill(bbox, value, active);
489 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
499 void voxelizeActiveTiles(
bool threaded =
true);
507 this->clearAllAccessors();
508 mRoot.prune(tolerance);
522 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
528 template<
typename NodeT>
529 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
536 LeafNodeType* touchLeaf(
const Coord& xyz);
539 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
542 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
543 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
547 LeafNodeType* probeLeaf(
const Coord& xyz);
550 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
555 template<
typename ArrayT>
void getNodes(ArrayT& array) { mRoot.getNodes(array); }
578 template<
typename ArrayT>
void getNodes(ArrayT& array)
const { mRoot.getNodes(array); }
604 template<
typename ArrayT>
605 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
606 template<
typename ArrayT>
609 this->clearAllAccessors();
610 mRoot.stealNodes(array, value, state);
618 bool empty()
const {
return mRoot.empty(); }
624 void clearAllAccessors();
687 template<
typename OtherRootNodeType>
703 template<
typename OtherRootNodeType>
716 template<
typename OtherRootNodeType>
763 template<
typename CombineOp>
766 template<
typename CombineOp>
808 template<
typename ExtendedCombineOp>
809 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
811 template<
typename ExtendedCombineOp>
812 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
843 template<
typename CombineOp,
typename OtherTreeType >
844 void combine2(
const Tree& a,
const OtherTreeType& b, CombineOp& op,
bool prune =
false);
846 template<
typename CombineOp,
typename OtherTreeType >
847 void combine2(
const Tree& a,
const OtherTreeType& b,
const CombineOp& op,
bool prune =
false);
923 template<
typename ExtendedCombineOp,
typename OtherTreeType >
924 void combine2Extended(
const Tree& a,
const OtherTreeType& b, ExtendedCombineOp& op,
927 template<
typename ExtendedCombineOp,
typename OtherTreeType >
928 void combine2Extended(
const Tree& a,
const OtherTreeType& b,
const ExtendedCombineOp&,
972 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp& op)
const { mRoot.visitActiveBBox(op); }
1027 template<
typename VisitorOp>
void visit(VisitorOp& op);
1028 template<
typename VisitorOp>
void visit(
const VisitorOp& op);
1034 template<
typename VisitorOp>
void visit(VisitorOp& op)
const;
1035 template<
typename VisitorOp>
void visit(
const VisitorOp& op)
const;
1084 template<
typename OtherTreeType,
typename VisitorOp>
1085 void visit2(OtherTreeType& other, VisitorOp& op);
1086 template<
typename OtherTreeType,
typename VisitorOp>
1087 void visit2(OtherTreeType& other,
const VisitorOp& op);
1099 template<
typename OtherTreeType,
typename VisitorOp>
1100 void visit2(OtherTreeType& other, VisitorOp& op)
const;
1101 template<
typename OtherTreeType,
typename VisitorOp>
1102 void visit2(OtherTreeType& other,
const VisitorOp& op)
const;
1109 typename RootNodeType::ChildOnCIter beginRootChildren()
const {
return mRoot.cbeginChildOn(); }
1116 typename RootNodeType::ChildOffCIter beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1118 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1119 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
1123 typename RootNodeType::ChildAllCIter beginRootDense()
const {
return mRoot.cbeginChildAll(); }
1125 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
1126 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1150 LeafIter beginLeaf() {
return LeafIter(*
this); }
1170 ValueOnIter beginValueOn() {
return ValueOnIter(*
this); }
1176 ValueOffIter beginValueOff() {
return ValueOffIter(*
this); }
1184 template<
typename IterT> IterT begin();
1187 template<
typename CIterT> CIterT
cbegin()
const;
1196 void releaseAllAccessors();
1199 template<
typename NodeType>
1202 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1204 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
1205 delete mNodes[n]; mNodes[n] =
nullptr;
1221 template<
typename _RootNodeType>
1229 template<
typename T, Index N1=4, Index N2=3>
1239 template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1248 template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1261 int32_t bufferCount;
1262 is.read(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1263 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1270 int32_t bufferCount = 1;
1271 os.write(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1278 os <<
" Tree Type: " <<
type()
1279 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1280 <<
" Active tile Count: " << activeTileCount() << std::endl
1281 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1282 <<
" Leaf Node Count: " << leafCount() << std::endl
1283 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1298 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1299 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1300 return tree.beginRootChildren();
1304 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1305 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1306 return tree.cbeginRootChildren();
1310 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1311 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1312 return tree.beginRootTiles();
1316 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1317 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1318 return tree.cbeginRootTiles();
1322 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1323 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1324 return tree.beginRootDense();
1328 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1329 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1330 return tree.cbeginRootDense();
1335 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1339 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1343 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1347 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1351 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1354 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1355 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1358 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1359 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1362 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1363 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1366 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1367 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1370 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1371 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1375 template<
typename RootNodeType>
1376 template<
typename IterT>
1384 template<
typename RootNodeType>
1385 template<
typename IterT>
1396 template<
typename RootNodeType>
1400 this->clearAllAccessors();
1402 mRoot.readTopology(is, saveFloatAsHalf);
1406 template<
typename RootNodeType>
1411 mRoot.writeTopology(os, saveFloatAsHalf);
1415 template<
typename RootNodeType>
1419 this->clearAllAccessors();
1420 mRoot.readBuffers(is, saveFloatAsHalf);
1424 template<
typename RootNodeType>
1428 this->clearAllAccessors();
1429 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1433 template<
typename RootNodeType>
1437 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1444 template<
typename RootNodeType>
1452 template<
typename RootNodeType>
1456 std::vector<LeafNodeType*> leafnodes;
1457 this->stealNodes(leafnodes);
1459 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1462 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1463 this->stealNodes(internalNodes);
1465 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1470 this->clearAllAccessors();
1477 template<
typename RootNodeType>
1481 typename AccessorRegistry::accessor a;
1482 mAccessorRegistry.insert(a, &accessor);
1486 template<
typename RootNodeType>
1490 typename ConstAccessorRegistry::accessor a;
1491 mConstAccessorRegistry.insert(a, &accessor);
1495 template<
typename RootNodeType>
1499 mAccessorRegistry.erase(&accessor);
1503 template<
typename RootNodeType>
1507 mConstAccessorRegistry.erase(&accessor);
1511 template<
typename RootNodeType>
1515 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1516 it != mAccessorRegistry.end(); ++it)
1518 if (it->first) it->first->
clear();
1521 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1522 it != mConstAccessorRegistry.end(); ++it)
1524 if (it->first) it->first->clear();
1529 template<
typename RootNodeType>
1533 mAccessorRegistry.erase(
nullptr);
1534 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1535 it != mAccessorRegistry.end(); ++it)
1537 it->first->release();
1539 mAccessorRegistry.
clear();
1541 mAccessorRegistry.erase(
nullptr);
1542 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1543 it != mConstAccessorRegistry.end(); ++it)
1545 it->first->release();
1547 mConstAccessorRegistry.clear();
1554 template<
typename RootNodeType>
1555 inline const typename RootNodeType::ValueType&
1562 template<
typename RootNodeType>
1563 template<
typename AccessT>
1564 inline const typename RootNodeType::ValueType&
1571 template<
typename RootNodeType>
1579 template<
typename RootNodeType>
1587 template<
typename RootNodeType>
1595 template<
typename RootNodeType>
1603 template<
typename RootNodeType>
1610 template<
typename RootNodeType>
1617 template<
typename RootNodeType>
1618 template<
typename AccessT>
1626 template<
typename RootNodeType>
1634 template<
typename RootNodeType>
1642 template<
typename RootNodeType>
1643 template<
typename ModifyOp>
1651 template<
typename RootNodeType>
1652 template<
typename ModifyOp>
1660 template<
typename RootNodeType>
1671 template<
typename RootNodeType>
1676 mRoot.
addTile(level, xyz, value, active);
1680 template<
typename RootNodeType>
1681 template<
typename NodeT>
1685 this->clearAllAccessors();
1686 return mRoot.template stealNode<NodeT>(xyz, value, active);
1690 template<
typename RootNodeType>
1691 inline typename RootNodeType::LeafNodeType*
1698 template<
typename RootNodeType>
1699 inline typename RootNodeType::LeafNodeType*
1706 template<
typename RootNodeType>
1707 inline const typename RootNodeType::LeafNodeType*
1714 template<
typename RootNodeType>
1715 template<
typename NodeType>
1719 return mRoot.template probeNode<NodeType>(xyz);
1723 template<
typename RootNodeType>
1724 template<
typename NodeType>
1725 inline const NodeType*
1728 return this->
template probeConstNode<NodeType>(xyz);
1732 template<
typename RootNodeType>
1733 template<
typename NodeType>
1734 inline const NodeType*
1737 return mRoot.template probeConstNode<NodeType>(xyz);
1744 template<
typename RootNodeType>
1748 this->clearAllAccessors();
1749 return mRoot.clip(bbox);
1753 template<
typename RootNodeType>
1757 this->clearAllAccessors();
1758 for (
LeafIter it = this->beginLeaf(); it; ) {
1761 if (!leaf->isAllocated()) {
1762 this->addTile(0, leaf->origin(), this->background(),
false);
1767 template<
typename RootNodeType>
1772 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1777 template<
typename RootNodeType>
1781 this->clearAllAccessors();
1782 return mRoot.sparseFill(bbox, value, active);
1786 template<
typename RootNodeType>
1790 this->clearAllAccessors();
1791 return mRoot.denseFill(bbox, value, active);
1795 template<
typename RootNodeType>
1799 this->clearAllAccessors();
1800 mRoot.voxelizeActiveTiles(threaded);
1804 template<
typename RootNodeType>
1812 if (result->typeName() == MetadataT::staticTypeName()) {
1813 MetadataT* m =
static_cast<MetadataT*
>(result.get());
1814 m->value() = mRoot.background();
1824 template<
typename RootNodeType>
1828 this->clearAllAccessors();
1832 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1834 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1836 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1841 template<
typename RootNodeType>
1842 template<
typename OtherRootNodeType>
1846 this->clearAllAccessors();
1847 mRoot.topologyUnion(other.
root());
1850 template<
typename RootNodeType>
1851 template<
typename OtherRootNodeType>
1855 this->clearAllAccessors();
1856 mRoot.topologyIntersection(other.
root());
1859 template<
typename RootNodeType>
1860 template<
typename OtherRootNodeType>
1864 this->clearAllAccessors();
1865 mRoot.topologyDifference(other.
root());
1873 template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1879 op(args.
a(), args.
b(), args.
result());
1886 template<
typename RootNodeType>
1887 template<
typename CombineOp>
1892 this->combineExtended(other, extendedOp,
prune);
1899 template<
typename RootNodeType>
1900 template<
typename CombineOp>
1905 this->combineExtended(other, extendedOp,
prune);
1910 template<
typename RootNodeType>
1911 template<
typename ExtendedCombineOp>
1915 this->clearAllAccessors();
1923 template<
typename RootNodeType>
1924 template<
typename ExtendedCombineOp>
1928 this->clearAllAccessors();
1929 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op,
prune);
1934 template<
typename RootNodeType>
1935 template<
typename CombineOp,
typename OtherTreeType>
1940 this->combine2Extended(a, b, extendedOp,
prune);
1947 template<
typename RootNodeType>
1948 template<
typename CombineOp,
typename OtherTreeType>
1953 this->combine2Extended(a, b, extendedOp,
prune);
1958 template<
typename RootNodeType>
1959 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1962 ExtendedCombineOp& op,
bool prune)
1964 this->clearAllAccessors();
1965 mRoot.combine2(a.
root(), b.root(), op,
prune);
1973 template<
typename RootNodeType>
1974 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1977 const ExtendedCombineOp& op,
bool prune)
1979 this->clearAllAccessors();
1980 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op,
prune);
1988 template<
typename RootNodeType>
1989 template<
typename VisitorOp>
1993 this->clearAllAccessors();
1994 mRoot.template visit<VisitorOp>(op);
1998 template<
typename RootNodeType>
1999 template<
typename VisitorOp>
2003 mRoot.template visit<VisitorOp>(op);
2009 template<
typename RootNodeType>
2010 template<
typename VisitorOp>
2014 this->clearAllAccessors();
2015 mRoot.template visit<const VisitorOp>(op);
2021 template<
typename RootNodeType>
2022 template<
typename VisitorOp>
2026 mRoot.template visit<const VisitorOp>(op);
2033 template<
typename RootNodeType>
2034 template<
typename OtherTreeType,
typename VisitorOp>
2038 this->clearAllAccessors();
2039 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2040 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2044 template<
typename RootNodeType>
2045 template<
typename OtherTreeType,
typename VisitorOp>
2049 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2050 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2056 template<
typename RootNodeType>
2057 template<
typename OtherTreeType,
typename VisitorOp>
2061 this->clearAllAccessors();
2062 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2063 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2069 template<
typename RootNodeType>
2070 template<
typename OtherTreeType,
typename VisitorOp>
2074 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2075 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2082 template<
typename RootNodeType>
2086 static std::once_flag once;
2087 std::call_once(once, []()
2089 std::vector<Index> dims;
2090 Tree::getNodeLog2Dims(dims);
2091 std::ostringstream ostr;
2092 ostr <<
"Tree_" << typeNameAsString<BuildType>();
2093 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
2094 ostr <<
"_" << dims[i];
2096 sTreeTypeName.reset(
new Name(ostr.str()));
2098 return *sTreeTypeName;
2102 template<
typename RootNodeType>
2103 template<
typename OtherRootNodeType>
2111 template<
typename RootNodeType>
2116 this->evalActiveVoxelDim(dim);
2118 totalVoxels = dim.
x() * dim.
y() * dim.
z(),
2119 activeVoxels = this->activeVoxelCount();
2120 assert(totalVoxels >= activeVoxels);
2121 return totalVoxels - activeVoxels;
2125 template<
typename RootNodeType>
2131 if (this->empty())
return false;
2133 mRoot.evalActiveBoundingBox(bbox,
false);
2135 return !bbox.
empty();
2138 template<
typename RootNodeType>
2144 if (this->empty())
return false;
2146 mRoot.evalActiveBoundingBox(bbox,
true);
2148 return !bbox.
empty();
2152 template<
typename RootNodeType>
2157 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2163 template<
typename RootNodeType>
2168 bool notEmpty = this->evalLeafBoundingBox(bbox);
2174 template<
typename RootNodeType>
2179 minVal = maxVal = zeroVal<ValueType>();
2181 minVal = maxVal = *iter;
2182 for (++iter; iter; ++iter) {
2184 if (val < minVal) minVal = val;
2185 if (val > maxVal) maxVal = val;
2191 template<
typename RootNodeType>
2196 RootNodeType::getNodeLog2Dims(dims);
2200 template<
typename RootNodeType>
2204 if (verboseLevel <= 0)
return;
2209 std::streamsize savedPrecision;
2210 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2211 ~OnExit() { os.precision(savedPrecision); }
2213 OnExit restorePrecision(os);
2215 std::vector<Index> dims;
2216 Tree::getNodeLog2Dims(dims);
2218 os <<
"Information about Tree:\n"
2219 <<
" Type: " << this->
type() <<
"\n";
2221 os <<
" Configuration:\n";
2223 if (verboseLevel <= 1) {
2225 os <<
" Root(" << mRoot.getTableSize() <<
")";
2226 if (dims.size() > 1) {
2227 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2228 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
2230 os <<
", Leaf(" << (1 << dims.back()) <<
"^3)\n";
2232 os <<
" Background value: " << mRoot.background() <<
"\n";
2238 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2239 if (verboseLevel > 3) {
2241 this->evalMinMax(minVal, maxVal);
2244 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2245 const auto nodeCount = this->nodeCount();
2246 const Index32 leafCount = nodeCount.front();
2248 std::vector<Index64> nodeCount(dims.size());
2249 for (
NodeCIter it = cbeginNode(); it; ++it) ++(nodeCount[it.getDepth()]);
2250 const Index64 leafCount = *nodeCount.rbegin();
2252 assert(dims.size() == nodeCount.size());
2255 for (
size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2258 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
2259 if (dims.size() >= 2) {
2260 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2261 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2266 os <<
" x " << (1 << dims[i]) <<
"^3)";
2269 os <<
" x " << (1 << dims.back()) <<
"^3)\n";
2271 os <<
" Background value: " << mRoot.background() <<
"\n";
2275 if (verboseLevel > 3) {
2276 os <<
" Min value: " << minVal <<
"\n";
2277 os <<
" Max value: " << maxVal <<
"\n";
2281 numActiveVoxels = this->activeVoxelCount(),
2282 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2283 numActiveTiles = this->activeTileCount();
2290 if (numActiveVoxels) {
2292 this->evalActiveVoxelBoundingBox(bbox);
2294 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
2296 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
2297 os <<
" Dimensions of active voxels: "
2298 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
2300 const double activeRatio = (100.0 * double(numActiveVoxels)) /
double(totalVoxels);
2301 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
2303 if (leafCount > 0) {
2304 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2305 / (
double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2306 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
2309 if (verboseLevel > 2) {
2311 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
2312 os <<
" Number of unallocated nodes: "
2314 << (100.0 * double(sum) / double(totalNodeCount)) <<
"%)\n";
2317 os <<
" Tree is empty!\n";
2321 if (verboseLevel == 2)
return;
2325 actualMem = this->memUsage(),
2326 denseMem =
sizeof(
ValueType) * totalVoxels,
2327 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
2330 os <<
"Memory footprint:\n";
2334 if (numActiveVoxels) {
2336 os <<
" Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2337 <<
"% of an equivalent dense volume\n";
2338 os <<
" Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2339 <<
"% of actual footprint\n";
2347 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED