33 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
34 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
48 #include <tbb/atomic.h>
49 #include <tbb/concurrent_hash_map.h>
74 virtual const Name& type()
const = 0;
77 virtual Name valueType()
const = 0;
96 virtual bool evalLeafBoundingBox(
CoordBBox& bbox)
const = 0;
101 virtual bool evalLeafDim(
Coord& dim)
const = 0;
110 virtual bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const = 0;
115 virtual bool evalActiveVoxelDim(
Coord& dim)
const = 0;
117 virtual void getIndexRange(
CoordBBox& bbox)
const = 0;
119 #if OPENVDB_ABI_VERSION_NUMBER >= 3
120 virtual void clipUnallocatedNodes() = 0;
127 #if OPENVDB_ABI_VERSION_NUMBER >= 4
128 virtual Index32 unallocatedLeafCount()
const = 0;
139 virtual Index treeDepth()
const = 0;
141 virtual Index32 leafCount()
const = 0;
143 virtual Index32 nonLeafCount()
const = 0;
145 virtual Index64 activeLeafVoxelCount()
const = 0;
147 virtual Index64 inactiveLeafVoxelCount()
const = 0;
149 virtual Index64 activeVoxelCount()
const = 0;
151 virtual Index64 inactiveVoxelCount()
const = 0;
152 #if OPENVDB_ABI_VERSION_NUMBER >= 3
153 virtual Index64 activeTileCount()
const = 0;
167 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
171 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
174 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
175 #if OPENVDB_ABI_VERSION_NUMBER >= 3
176 virtual void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false) = 0;
183 virtual void readNonresidentBuffers()
const = 0;
185 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
195 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
202 template<
typename _RootNodeType>
214 static const Index DEPTH = RootNodeType::LEVEL + 1;
222 template<
typename OtherValueType>
230 Tree& operator=(
const Tree&) =
delete;
243 template<
typename OtherRootType>
258 template<
typename OtherTreeType>
259 Tree(
const OtherTreeType& other,
264 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
279 template<
typename OtherTreeType>
289 ~Tree()
override { this->clear(); releaseAllAccessors(); }
298 static const Name& treeType();
300 const Name&
type()
const override {
return this->treeType(); }
306 RootNodeType& root() {
return mRoot; }
317 template<
typename OtherRootNodeType>
320 bool evalLeafBoundingBox(
CoordBBox& bbox)
const override;
321 bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const override;
322 bool evalActiveVoxelDim(
Coord& dim)
const override;
323 bool evalLeafDim(
Coord& dim)
const override;
328 static void getNodeLog2Dims(std::vector<Index>& dims);
337 void readTopology(std::istream&,
bool saveFloatAsHalf =
false)
override;
341 void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
343 void readBuffers(std::istream&,
bool saveFloatAsHalf =
false)
override;
344 #if OPENVDB_ABI_VERSION_NUMBER >= 3
345 void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false)
override;
352 void readNonresidentBuffers()
const override;
354 void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
357 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const override;
378 Index64 inactiveVoxelCount()
const override;
379 #if OPENVDB_ABI_VERSION_NUMBER >= 3
380 Index64 activeTileCount()
const override {
return mRoot.onTileCount(); }
383 Index64 activeTileCount()
const {
return mRoot.onTileCount(); }
387 void evalMinMax(ValueType &
min, ValueType &
max)
const;
396 const ValueType& getValue(
const Coord& xyz)
const;
399 template<
typename AccessT>
const ValueType& getValue(
const Coord& xyz, AccessT&)
const;
404 int getValueDepth(
const Coord& xyz)
const;
407 void setActiveState(
const Coord& xyz,
bool on);
409 void setValueOnly(
const Coord& xyz,
const ValueType& value);
411 void setValueOn(
const Coord& xyz);
413 void setValueOn(
const Coord& xyz,
const ValueType& value);
415 void setValue(
const Coord& xyz,
const ValueType& value);
418 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
420 void setValueOff(
const Coord& xyz);
422 void setValueOff(
const Coord& xyz,
const ValueType& value);
442 template<
typename ModifyOp>
443 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
464 template<
typename ModifyOp>
465 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
469 bool probeValue(
const Coord& xyz, ValueType& value)
const;
481 #if OPENVDB_ABI_VERSION_NUMBER >= 3
482 void clipUnallocatedNodes()
override;
489 #if OPENVDB_ABI_VERSION_NUMBER >= 4
490 Index32 unallocatedLeafCount()
const override;
495 void sparseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
506 this->sparseFill(bbox, value, active);
517 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
527 void voxelizeActiveTiles(
bool threaded =
true);
535 this->clearAllAccessors();
536 mRoot.prune(tolerance);
550 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
556 template<
typename NodeT>
557 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
564 LeafNodeType* touchLeaf(
const Coord& xyz);
567 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
570 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
571 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
575 LeafNodeType* probeLeaf(
const Coord& xyz);
578 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
583 template<
typename ArrayT>
void getNodes(ArrayT& array) { mRoot.getNodes(array); }
606 template<
typename ArrayT>
void getNodes(ArrayT& array)
const { mRoot.getNodes(array); }
632 template<
typename ArrayT>
633 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
634 template<
typename ArrayT>
637 this->clearAllAccessors();
638 mRoot.stealNodes(array, value, state);
646 bool empty()
const {
return mRoot.empty(); }
652 void clearAllAccessors();
715 template<
typename OtherRootNodeType>
731 template<
typename OtherRootNodeType>
744 template<
typename OtherRootNodeType>
791 template<
typename CombineOp>
792 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
794 template<
typename CombineOp>
795 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
836 template<
typename ExtendedCombineOp>
837 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
839 template<
typename ExtendedCombineOp>
840 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
871 template<
typename CombineOp,
typename OtherTreeType >
872 void combine2(
const Tree& a,
const OtherTreeType& b, CombineOp& op,
bool prune =
false);
874 template<
typename CombineOp,
typename OtherTreeType >
875 void combine2(
const Tree& a,
const OtherTreeType& b,
const CombineOp& op,
bool prune =
false);
951 template<
typename ExtendedCombineOp,
typename OtherTreeType >
952 void combine2Extended(
const Tree& a,
const OtherTreeType& b, ExtendedCombineOp& op,
955 template<
typename ExtendedCombineOp,
typename OtherTreeType >
956 void combine2Extended(
const Tree& a,
const OtherTreeType& b,
const ExtendedCombineOp&,
1000 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp& op)
const { mRoot.visitActiveBBox(op); }
1055 template<
typename VisitorOp>
void visit(VisitorOp& op);
1056 template<
typename VisitorOp>
void visit(
const VisitorOp& op);
1062 template<
typename VisitorOp>
void visit(VisitorOp& op)
const;
1063 template<
typename VisitorOp>
void visit(
const VisitorOp& op)
const;
1112 template<
typename OtherTreeType,
typename VisitorOp>
1113 void visit2(OtherTreeType& other, VisitorOp& op);
1114 template<
typename OtherTreeType,
typename VisitorOp>
1115 void visit2(OtherTreeType& other,
const VisitorOp& op);
1127 template<
typename OtherTreeType,
typename VisitorOp>
1128 void visit2(OtherTreeType& other, VisitorOp& op)
const;
1129 template<
typename OtherTreeType,
typename VisitorOp>
1130 void visit2(OtherTreeType& other,
const VisitorOp& op)
const;
1137 typename RootNodeType::ChildOnCIter beginRootChildren()
const {
return mRoot.cbeginChildOn(); }
1144 typename RootNodeType::ChildOffCIter beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1146 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1147 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
1151 typename RootNodeType::ChildAllCIter beginRootDense()
const {
return mRoot.cbeginChildAll(); }
1153 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
1154 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1178 LeafIter beginLeaf() {
return LeafIter(*
this); }
1198 ValueOnIter beginValueOn() {
return ValueOnIter(*
this); }
1204 ValueOffIter beginValueOff() {
return ValueOffIter(*
this); }
1212 template<
typename IterT> IterT begin();
1215 template<
typename CIterT> CIterT cbegin()
const;
1224 void releaseAllAccessors();
1227 template<
typename NodeType>
1230 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1232 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
1233 delete mNodes[n]; mNodes[n] =
nullptr;
1249 template<
typename _RootNodeType>
1257 template<
typename T, Index N1=4, Index N2=3>
1267 template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1276 template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1289 int32_t bufferCount;
1290 is.read(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1291 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1298 int32_t bufferCount = 1;
1299 os.write(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1306 os <<
" Tree Type: " << type()
1307 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1308 #if OPENVDB_ABI_VERSION_NUMBER >= 3
1309 <<
" Active tile Count: " << activeTileCount() << std::endl
1311 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1312 <<
" Leaf Node Count: " << leafCount() << std::endl
1313 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1328 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1329 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1330 return tree.beginRootChildren();
1334 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1335 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1336 return tree.cbeginRootChildren();
1340 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1341 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1342 return tree.beginRootTiles();
1346 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1347 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1348 return tree.cbeginRootTiles();
1352 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1353 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1354 return tree.beginRootDense();
1358 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1359 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1360 return tree.cbeginRootDense();
1365 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1369 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1373 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1377 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1381 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1384 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1385 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1388 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1389 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1392 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1393 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1396 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1397 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1400 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1401 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1405 template<
typename RootNodeType>
1406 template<
typename IterT>
1414 template<
typename RootNodeType>
1415 template<
typename IterT>
1426 template<
typename RootNodeType>
1430 this->clearAllAccessors();
1432 mRoot.readTopology(is, saveFloatAsHalf);
1436 template<
typename RootNodeType>
1441 mRoot.writeTopology(os, saveFloatAsHalf);
1445 template<
typename RootNodeType>
1449 this->clearAllAccessors();
1450 mRoot.readBuffers(is, saveFloatAsHalf);
1454 #if OPENVDB_ABI_VERSION_NUMBER >= 3
1456 template<
typename RootNodeType>
1460 this->clearAllAccessors();
1461 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1465 template<
typename RootNodeType>
1469 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1478 template<
typename RootNodeType>
1486 template<
typename RootNodeType>
1490 std::vector<LeafNodeType*> leafnodes;
1491 this->stealNodes(leafnodes);
1493 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1496 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1497 this->stealNodes(internalNodes);
1499 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1504 this->clearAllAccessors();
1511 template<
typename RootNodeType>
1515 typename AccessorRegistry::accessor a;
1516 mAccessorRegistry.insert(a, &accessor);
1520 template<
typename RootNodeType>
1524 typename ConstAccessorRegistry::accessor a;
1525 mConstAccessorRegistry.insert(a, &accessor);
1529 template<
typename RootNodeType>
1533 mAccessorRegistry.erase(&accessor);
1537 template<
typename RootNodeType>
1541 mConstAccessorRegistry.erase(&accessor);
1545 template<
typename RootNodeType>
1549 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1550 it != mAccessorRegistry.end(); ++it)
1552 if (it->first) it->first->
clear();
1555 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1556 it != mConstAccessorRegistry.end(); ++it)
1558 if (it->first) it->first->clear();
1563 template<
typename RootNodeType>
1567 mAccessorRegistry.erase(
nullptr);
1568 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1569 it != mAccessorRegistry.end(); ++it)
1571 it->first->release();
1573 mAccessorRegistry.
clear();
1575 mAccessorRegistry.erase(
nullptr);
1576 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1577 it != mConstAccessorRegistry.end(); ++it)
1579 it->first->release();
1581 mConstAccessorRegistry.clear();
1588 template<
typename RootNodeType>
1589 inline const typename RootNodeType::ValueType&
1596 template<
typename RootNodeType>
1597 template<
typename AccessT>
1598 inline const typename RootNodeType::ValueType&
1605 template<
typename RootNodeType>
1613 template<
typename RootNodeType>
1621 template<
typename RootNodeType>
1629 template<
typename RootNodeType>
1637 template<
typename RootNodeType>
1644 template<
typename RootNodeType>
1651 template<
typename RootNodeType>
1652 template<
typename AccessT>
1660 template<
typename RootNodeType>
1668 template<
typename RootNodeType>
1676 template<
typename RootNodeType>
1677 template<
typename ModifyOp>
1685 template<
typename RootNodeType>
1686 template<
typename ModifyOp>
1694 template<
typename RootNodeType>
1705 template<
typename RootNodeType>
1710 mRoot.
addTile(level, xyz, value, active);
1714 template<
typename RootNodeType>
1715 template<
typename NodeT>
1719 this->clearAllAccessors();
1720 return mRoot.template stealNode<NodeT>(xyz, value, active);
1724 template<
typename RootNodeType>
1725 inline typename RootNodeType::LeafNodeType*
1732 template<
typename RootNodeType>
1733 inline typename RootNodeType::LeafNodeType*
1740 template<
typename RootNodeType>
1741 inline const typename RootNodeType::LeafNodeType*
1748 template<
typename RootNodeType>
1749 template<
typename NodeType>
1753 return mRoot.template probeNode<NodeType>(xyz);
1757 template<
typename RootNodeType>
1758 template<
typename NodeType>
1759 inline const NodeType*
1762 return this->
template probeConstNode<NodeType>(xyz);
1766 template<
typename RootNodeType>
1767 template<
typename NodeType>
1768 inline const NodeType*
1771 return mRoot.template probeConstNode<NodeType>(xyz);
1778 template<
typename RootNodeType>
1782 this->clearAllAccessors();
1783 return mRoot.clip(bbox);
1787 #if OPENVDB_ABI_VERSION_NUMBER >= 3
1788 template<
typename RootNodeType>
1792 this->clearAllAccessors();
1793 for (
LeafIter it = this->beginLeaf(); it; ) {
1796 if (!leaf->isAllocated()) {
1797 this->addTile(0, leaf->origin(), this->background(),
false);
1803 #if OPENVDB_ABI_VERSION_NUMBER >= 4
1804 template<
typename RootNodeType>
1809 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1815 template<
typename RootNodeType>
1819 this->clearAllAccessors();
1820 return mRoot.sparseFill(bbox, value, active);
1824 template<
typename RootNodeType>
1828 this->clearAllAccessors();
1829 return mRoot.denseFill(bbox, value, active);
1833 template<
typename RootNodeType>
1837 this->clearAllAccessors();
1838 mRoot.voxelizeActiveTiles(threaded);
1842 template<
typename RootNodeType>
1850 if (result->typeName() == MetadataT::staticTypeName()) {
1851 MetadataT* m = static_cast<MetadataT*>(result.get());
1852 m->value() = mRoot.background();
1862 template<
typename RootNodeType>
1866 this->clearAllAccessors();
1870 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1872 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1874 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1879 template<
typename RootNodeType>
1880 template<
typename OtherRootNodeType>
1884 this->clearAllAccessors();
1885 mRoot.topologyUnion(other.
root());
1888 template<
typename RootNodeType>
1889 template<
typename OtherRootNodeType>
1893 this->clearAllAccessors();
1894 mRoot.topologyIntersection(other.
root());
1897 template<
typename RootNodeType>
1898 template<
typename OtherRootNodeType>
1902 this->clearAllAccessors();
1903 mRoot.topologyDifference(other.
root());
1911 template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1917 op(args.
a(), args.
b(), args.
result());
1924 template<
typename RootNodeType>
1925 template<
typename CombineOp>
1930 this->combineExtended(other, extendedOp,
prune);
1937 template<
typename RootNodeType>
1938 template<
typename CombineOp>
1943 this->combineExtended(other, extendedOp,
prune);
1948 template<
typename RootNodeType>
1949 template<
typename ExtendedCombineOp>
1953 this->clearAllAccessors();
1961 template<
typename RootNodeType>
1962 template<
typename ExtendedCombineOp>
1966 this->clearAllAccessors();
1967 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op,
prune);
1972 template<
typename RootNodeType>
1973 template<
typename CombineOp,
typename OtherTreeType>
1978 this->combine2Extended(a, b, extendedOp,
prune);
1985 template<
typename RootNodeType>
1986 template<
typename CombineOp,
typename OtherTreeType>
1991 this->combine2Extended(a, b, extendedOp,
prune);
1996 template<
typename RootNodeType>
1997 template<
typename ExtendedCombineOp,
typename OtherTreeType>
2000 ExtendedCombineOp& op,
bool prune)
2002 this->clearAllAccessors();
2003 mRoot.combine2(a.
root(), b.root(), op,
prune);
2011 template<
typename RootNodeType>
2012 template<
typename ExtendedCombineOp,
typename OtherTreeType>
2015 const ExtendedCombineOp& op,
bool prune)
2017 this->clearAllAccessors();
2018 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op,
prune);
2026 template<
typename RootNodeType>
2027 template<
typename VisitorOp>
2031 this->clearAllAccessors();
2032 mRoot.template visit<VisitorOp>(op);
2036 template<
typename RootNodeType>
2037 template<
typename VisitorOp>
2041 mRoot.template visit<VisitorOp>(op);
2047 template<
typename RootNodeType>
2048 template<
typename VisitorOp>
2052 this->clearAllAccessors();
2053 mRoot.template visit<const VisitorOp>(op);
2059 template<
typename RootNodeType>
2060 template<
typename VisitorOp>
2064 mRoot.template visit<const VisitorOp>(op);
2071 template<
typename RootNodeType>
2072 template<
typename OtherTreeType,
typename VisitorOp>
2076 this->clearAllAccessors();
2077 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2078 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2082 template<
typename RootNodeType>
2083 template<
typename OtherTreeType,
typename VisitorOp>
2087 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2088 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2094 template<
typename RootNodeType>
2095 template<
typename OtherTreeType,
typename VisitorOp>
2099 this->clearAllAccessors();
2100 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2101 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2107 template<
typename RootNodeType>
2108 template<
typename OtherTreeType,
typename VisitorOp>
2112 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2113 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2120 template<
typename RootNodeType>
2124 if (sTreeTypeName ==
nullptr) {
2125 std::vector<Index> dims;
2126 Tree::getNodeLog2Dims(dims);
2127 std::ostringstream ostr;
2128 ostr <<
"Tree_" << typeNameAsString<BuildType>();
2129 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
2130 ostr <<
"_" << dims[i];
2133 if (sTreeTypeName.compare_and_swap(s,
nullptr) !=
nullptr)
delete s;
2135 return *sTreeTypeName;
2139 template<
typename RootNodeType>
2140 template<
typename OtherRootNodeType>
2148 template<
typename RootNodeType>
2153 this->evalActiveVoxelDim(dim);
2155 totalVoxels = dim.
x() * dim.
y() * dim.
z(),
2156 activeVoxels = this->activeVoxelCount();
2157 assert(totalVoxels >= activeVoxels);
2158 return totalVoxels - activeVoxels;
2162 template<
typename RootNodeType>
2168 if (this->empty())
return false;
2170 mRoot.evalActiveBoundingBox(bbox,
false);
2175 template<
typename RootNodeType>
2181 if (this->empty())
return false;
2183 mRoot.evalActiveBoundingBox(bbox,
true);
2189 template<
typename RootNodeType>
2194 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2200 template<
typename RootNodeType>
2205 bool notEmpty = this->evalLeafBoundingBox(bbox);
2211 template<
typename RootNodeType>
2216 minVal = maxVal = zeroVal<ValueType>();
2218 minVal = maxVal = *iter;
2219 for (++iter; iter; ++iter) {
2221 if (val < minVal) minVal = val;
2222 if (val > maxVal) maxVal = val;
2228 template<
typename RootNodeType>
2233 RootNodeType::getNodeLog2Dims(dims);
2237 template<
typename RootNodeType>
2241 if (verboseLevel <= 0)
return;
2246 std::streamsize savedPrecision;
2247 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2248 ~OnExit() { os.precision(savedPrecision); }
2250 OnExit restorePrecision(os);
2252 std::vector<Index> dims;
2253 Tree::getNodeLog2Dims(dims);
2255 os <<
"Information about Tree:\n"
2256 <<
" Type: " << this->type() <<
"\n";
2258 os <<
" Configuration:\n";
2260 if (verboseLevel <= 1) {
2262 os <<
" Root(" << mRoot.getTableSize() <<
")";
2263 if (dims.size() > 1) {
2264 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2265 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
2267 os <<
", Leaf(" << (1 << *dims.rbegin()) <<
"^3)\n";
2269 os <<
" Background value: " << mRoot.background() <<
"\n";
2275 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2276 if (verboseLevel > 3) {
2278 this->evalMinMax(minVal, maxVal);
2281 std::vector<Index64> nodeCount(dims.size());
2282 for (
NodeCIter it = cbeginNode(); it; ++it) ++(nodeCount[it.getDepth()]);
2285 for (
size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2288 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
2289 if (dims.size() > 1) {
2290 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2292 os <<
" x " << (1 << dims[i]) <<
"^3)";
2295 os <<
" x " << (1 << *dims.rbegin()) <<
"^3)\n";
2297 os <<
" Background value: " << mRoot.background() <<
"\n";
2301 if (verboseLevel > 3) {
2302 os <<
" Min value: " << minVal <<
"\n";
2303 os <<
" Max value: " << maxVal <<
"\n";
2307 leafCount = *nodeCount.rbegin(),
2308 numActiveVoxels = this->activeVoxelCount(),
2309 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2310 numActiveTiles = this->activeTileCount();
2317 if (numActiveVoxels) {
2319 this->evalActiveVoxelBoundingBox(bbox);
2321 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
2323 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
2324 os <<
" Dimensions of active voxels: "
2325 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
2327 const double activeRatio = (100.0 * double(numActiveVoxels)) /
double(totalVoxels);
2328 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
2330 if (leafCount > 0) {
2331 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2332 / (
double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2333 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
2336 #if OPENVDB_ABI_VERSION_NUMBER >= 3
2337 if (verboseLevel > 2) {
2339 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
2340 os <<
" Number of unallocated nodes: "
2342 << (100.0 * double(sum) / double(totalNodeCount)) <<
"%)\n";
2346 os <<
" Tree is empty!\n";
2350 if (verboseLevel == 2)
return;
2354 actualMem = this->memUsage(),
2355 denseMem =
sizeof(
ValueType) * totalVoxels,
2356 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
2359 os <<
"Memory footprint:\n";
2363 if (numActiveVoxels) {
2365 os <<
" Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2366 <<
"% of an equivalent dense volume\n";
2367 os <<
" Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2368 <<
"% of actual footprint\n";
2376 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED