6 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
21 #include <tbb/concurrent_hash_map.h>
47 virtual const Name& type()
const = 0;
50 virtual Name valueType()
const = 0;
69 virtual bool evalLeafBoundingBox(
CoordBBox& bbox)
const = 0;
74 virtual bool evalLeafDim(
Coord& dim)
const = 0;
83 virtual bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const = 0;
88 virtual bool evalActiveVoxelDim(
Coord& dim)
const = 0;
90 virtual void getIndexRange(
CoordBBox& bbox)
const = 0;
97 virtual void clipUnallocatedNodes() = 0;
98 #if OPENVDB_ABI_VERSION_NUMBER >= 4
99 virtual Index32 unallocatedLeafCount()
const = 0;
110 virtual Index treeDepth()
const = 0;
112 virtual Index32 leafCount()
const = 0;
113 #if OPENVDB_ABI_VERSION_NUMBER >= 7
114 virtual std::vector<Index32> nodeCount()
const = 0;
119 virtual Index32 nonLeafCount()
const = 0;
122 virtual Index64 activeLeafVoxelCount()
const = 0;
124 virtual Index64 inactiveLeafVoxelCount()
const = 0;
126 virtual Index64 activeVoxelCount()
const = 0;
128 virtual Index64 inactiveVoxelCount()
const = 0;
130 virtual Index64 activeTileCount()
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 readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false) = 0;
157 virtual void readNonresidentBuffers()
const = 0;
159 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
168 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
175 template<
typename _RootNodeType>
187 static const Index DEPTH = RootNodeType::LEVEL + 1;
195 template<
typename OtherValueType>
203 Tree& operator=(
const Tree&) =
delete;
216 template<
typename OtherRootType>
231 template<
typename OtherTreeType>
232 Tree(
const OtherTreeType& other,
237 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
252 template<
typename OtherTreeType>
262 ~Tree()
override { this->clear(); releaseAllAccessors(); }
271 static const Name& treeType();
273 const Name&
type()
const override {
return this->treeType(); }
279 RootNodeType& root() {
return mRoot; }
290 template<
typename OtherRootNodeType>
293 bool evalLeafBoundingBox(
CoordBBox& bbox)
const override;
294 bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const override;
295 bool evalActiveVoxelDim(
Coord& dim)
const override;
296 bool evalLeafDim(
Coord& dim)
const override;
301 static void getNodeLog2Dims(std::vector<Index>& dims);
310 void readTopology(std::istream&,
bool saveFloatAsHalf =
false)
override;
314 void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
316 void readBuffers(std::istream&,
bool saveFloatAsHalf =
false)
override;
318 void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false)
override;
324 void readNonresidentBuffers()
const override;
326 void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
328 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const override;
340 #if OPENVDB_ABI_VERSION_NUMBER >= 7
341 std::vector<Index32> nodeCount()
const override
346 std::vector<Index32> vec(DEPTH, 0);
347 mRoot.nodeCount( vec );
351 Index32 nonLeafCount()
const override {
return mRoot.nonLeafCount(); }
360 Index64 inactiveVoxelCount()
const override;
365 void evalMinMax(ValueType &
min, ValueType &
max)
const;
374 const ValueType& getValue(
const Coord& xyz)
const;
377 template<
typename AccessT>
const ValueType& getValue(
const Coord& xyz, AccessT&)
const;
382 int getValueDepth(
const Coord& xyz)
const;
385 void setActiveState(
const Coord& xyz,
bool on);
387 void setValueOnly(
const Coord& xyz,
const ValueType& value);
389 void setValueOn(
const Coord& xyz);
391 void setValueOn(
const Coord& xyz,
const ValueType& value);
393 void setValue(
const Coord& xyz,
const ValueType& value);
396 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
398 void setValueOff(
const Coord& xyz);
400 void setValueOff(
const Coord& xyz,
const ValueType& value);
420 template<
typename ModifyOp>
421 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
442 template<
typename ModifyOp>
443 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
447 bool probeValue(
const Coord& xyz, ValueType& value)
const;
463 void clipUnallocatedNodes()
override;
465 #if OPENVDB_ABI_VERSION_NUMBER >= 4
466 Index32 unallocatedLeafCount()
const override;
471 void sparseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
482 this->sparseFill(bbox, value, active);
493 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
503 void voxelizeActiveTiles(
bool threaded =
true);
511 this->clearAllAccessors();
512 mRoot.prune(tolerance);
526 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
532 template<
typename NodeT>
533 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
540 LeafNodeType* touchLeaf(
const Coord& xyz);
543 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
546 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
547 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
551 LeafNodeType* probeLeaf(
const Coord& xyz);
554 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
559 template<
typename ArrayT>
void getNodes(ArrayT& array) { mRoot.getNodes(array); }
582 template<
typename ArrayT>
void getNodes(ArrayT& array)
const { mRoot.getNodes(array); }
608 template<
typename ArrayT>
609 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
610 template<
typename ArrayT>
613 this->clearAllAccessors();
614 mRoot.stealNodes(array, value, state);
622 bool empty()
const {
return mRoot.empty(); }
628 void clearAllAccessors();
691 template<
typename OtherRootNodeType>
707 template<
typename OtherRootNodeType>
720 template<
typename OtherRootNodeType>
767 template<
typename CombineOp>
768 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
770 template<
typename CombineOp>
771 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
812 template<
typename ExtendedCombineOp>
813 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
815 template<
typename ExtendedCombineOp>
816 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
847 template<
typename CombineOp,
typename OtherTreeType >
848 void combine2(
const Tree& a,
const OtherTreeType& b, CombineOp& op,
bool prune =
false);
850 template<
typename CombineOp,
typename OtherTreeType >
851 void combine2(
const Tree& a,
const OtherTreeType& b,
const CombineOp& op,
bool prune =
false);
927 template<
typename ExtendedCombineOp,
typename OtherTreeType >
928 void combine2Extended(
const Tree& a,
const OtherTreeType& b, ExtendedCombineOp& op,
931 template<
typename ExtendedCombineOp,
typename OtherTreeType >
932 void combine2Extended(
const Tree& a,
const OtherTreeType& b,
const ExtendedCombineOp&,
976 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp& op)
const { mRoot.visitActiveBBox(op); }
1031 template<
typename VisitorOp>
void visit(VisitorOp& op);
1032 template<
typename VisitorOp>
void visit(
const VisitorOp& op);
1038 template<
typename VisitorOp>
void visit(VisitorOp& op)
const;
1039 template<
typename VisitorOp>
void visit(
const VisitorOp& op)
const;
1088 template<
typename OtherTreeType,
typename VisitorOp>
1089 void visit2(OtherTreeType& other, VisitorOp& op);
1090 template<
typename OtherTreeType,
typename VisitorOp>
1091 void visit2(OtherTreeType& other,
const VisitorOp& op);
1103 template<
typename OtherTreeType,
typename VisitorOp>
1104 void visit2(OtherTreeType& other, VisitorOp& op)
const;
1105 template<
typename OtherTreeType,
typename VisitorOp>
1106 void visit2(OtherTreeType& other,
const VisitorOp& op)
const;
1113 typename RootNodeType::ChildOnCIter beginRootChildren()
const {
return mRoot.cbeginChildOn(); }
1120 typename RootNodeType::ChildOffCIter beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1122 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1123 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
1127 typename RootNodeType::ChildAllCIter beginRootDense()
const {
return mRoot.cbeginChildAll(); }
1129 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
1130 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1154 LeafIter beginLeaf() {
return LeafIter(*
this); }
1174 ValueOnIter beginValueOn() {
return ValueOnIter(*
this); }
1180 ValueOffIter beginValueOff() {
return ValueOffIter(*
this); }
1188 template<
typename IterT> IterT begin();
1191 template<
typename CIterT> CIterT cbegin()
const;
1200 void releaseAllAccessors();
1203 template<
typename NodeType>
1206 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1208 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
1209 delete mNodes[n]; mNodes[n] =
nullptr;
1225 template<
typename _RootNodeType>
1233 template<
typename T, Index N1=4, Index N2=3>
1243 template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1252 template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1263 TreeBase::readTopology(std::istream& is,
bool )
1265 int32_t bufferCount;
1266 is.read(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1267 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1272 TreeBase::writeTopology(std::ostream& os,
bool )
const
1274 int32_t bufferCount = 1;
1275 os.write(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1280 TreeBase::print(std::ostream& os,
int )
const
1282 os <<
" Tree Type: " << type()
1283 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1284 <<
" Active tile Count: " << activeTileCount() << std::endl
1285 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1286 <<
" Leaf Node Count: " << leafCount() << std::endl
1287 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1302 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1303 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1304 return tree.beginRootChildren();
1308 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1309 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1310 return tree.cbeginRootChildren();
1314 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1315 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1316 return tree.beginRootTiles();
1320 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1321 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1322 return tree.cbeginRootTiles();
1326 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1327 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1328 return tree.beginRootDense();
1332 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1333 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1334 return tree.cbeginRootDense();
1339 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1343 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1347 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1351 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1355 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1358 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1359 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1362 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1363 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1366 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1367 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1370 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1371 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1374 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1375 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1379 template<
typename RootNodeType>
1380 template<
typename IterT>
1388 template<
typename RootNodeType>
1389 template<
typename IterT>
1400 template<
typename RootNodeType>
1404 this->clearAllAccessors();
1405 TreeBase::readTopology(is, saveFloatAsHalf);
1406 mRoot.readTopology(is, saveFloatAsHalf);
1410 template<
typename RootNodeType>
1414 TreeBase::writeTopology(os, saveFloatAsHalf);
1415 mRoot.writeTopology(os, saveFloatAsHalf);
1419 template<
typename RootNodeType>
1423 this->clearAllAccessors();
1424 mRoot.readBuffers(is, saveFloatAsHalf);
1428 template<
typename RootNodeType>
1432 this->clearAllAccessors();
1433 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1437 template<
typename RootNodeType>
1441 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1448 template<
typename RootNodeType>
1456 template<
typename RootNodeType>
1460 std::vector<LeafNodeType*> leafnodes;
1461 this->stealNodes(leafnodes);
1463 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1466 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1467 this->stealNodes(internalNodes);
1469 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1474 this->clearAllAccessors();
1481 template<
typename RootNodeType>
1485 typename AccessorRegistry::accessor a;
1486 mAccessorRegistry.insert(a, &accessor);
1490 template<
typename RootNodeType>
1494 typename ConstAccessorRegistry::accessor a;
1495 mConstAccessorRegistry.insert(a, &accessor);
1499 template<
typename RootNodeType>
1503 mAccessorRegistry.erase(&accessor);
1507 template<
typename RootNodeType>
1511 mConstAccessorRegistry.erase(&accessor);
1515 template<
typename RootNodeType>
1519 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1520 it != mAccessorRegistry.end(); ++it)
1522 if (it->first) it->first->
clear();
1525 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1526 it != mConstAccessorRegistry.end(); ++it)
1528 if (it->first) it->first->clear();
1533 template<
typename RootNodeType>
1537 mAccessorRegistry.erase(
nullptr);
1538 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1539 it != mAccessorRegistry.end(); ++it)
1541 it->first->release();
1543 mAccessorRegistry.
clear();
1545 mAccessorRegistry.erase(
nullptr);
1546 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1547 it != mConstAccessorRegistry.end(); ++it)
1549 it->first->release();
1551 mConstAccessorRegistry.clear();
1558 template<
typename RootNodeType>
1559 inline const typename RootNodeType::ValueType&
1566 template<
typename RootNodeType>
1567 template<
typename AccessT>
1568 inline const typename RootNodeType::ValueType&
1575 template<
typename RootNodeType>
1583 template<
typename RootNodeType>
1591 template<
typename RootNodeType>
1599 template<
typename RootNodeType>
1607 template<
typename RootNodeType>
1614 template<
typename RootNodeType>
1621 template<
typename RootNodeType>
1622 template<
typename AccessT>
1630 template<
typename RootNodeType>
1638 template<
typename RootNodeType>
1646 template<
typename RootNodeType>
1647 template<
typename ModifyOp>
1655 template<
typename RootNodeType>
1656 template<
typename ModifyOp>
1664 template<
typename RootNodeType>
1675 template<
typename RootNodeType>
1680 mRoot.
addTile(level, xyz, value, active);
1684 template<
typename RootNodeType>
1685 template<
typename NodeT>
1689 this->clearAllAccessors();
1690 return mRoot.template stealNode<NodeT>(xyz, value, active);
1694 template<
typename RootNodeType>
1695 inline typename RootNodeType::LeafNodeType*
1702 template<
typename RootNodeType>
1703 inline typename RootNodeType::LeafNodeType*
1710 template<
typename RootNodeType>
1711 inline const typename RootNodeType::LeafNodeType*
1718 template<
typename RootNodeType>
1719 template<
typename NodeType>
1723 return mRoot.template probeNode<NodeType>(xyz);
1727 template<
typename RootNodeType>
1728 template<
typename NodeType>
1729 inline const NodeType*
1732 return this->
template probeConstNode<NodeType>(xyz);
1736 template<
typename RootNodeType>
1737 template<
typename NodeType>
1738 inline const NodeType*
1741 return mRoot.template probeConstNode<NodeType>(xyz);
1748 template<
typename RootNodeType>
1752 this->clearAllAccessors();
1753 return mRoot.clip(bbox);
1757 template<
typename RootNodeType>
1761 this->clearAllAccessors();
1762 for (
LeafIter it = this->beginLeaf(); it; ) {
1765 if (!leaf->isAllocated()) {
1766 this->addTile(0, leaf->origin(), this->background(),
false);
1771 #if OPENVDB_ABI_VERSION_NUMBER >= 4
1772 template<
typename RootNodeType>
1777 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1783 template<
typename RootNodeType>
1787 this->clearAllAccessors();
1788 return mRoot.sparseFill(bbox, value, active);
1792 template<
typename RootNodeType>
1796 this->clearAllAccessors();
1797 return mRoot.denseFill(bbox, value, active);
1801 template<
typename RootNodeType>
1805 this->clearAllAccessors();
1806 mRoot.voxelizeActiveTiles(threaded);
1810 template<
typename RootNodeType>
1815 if (Metadata::isRegisteredType(valueType())) {
1817 result = Metadata::createMetadata(valueType());
1818 if (result->typeName() == MetadataT::staticTypeName()) {
1819 MetadataT* m =
static_cast<MetadataT*
>(result.get());
1820 m->value() = mRoot.background();
1830 template<
typename RootNodeType>
1834 this->clearAllAccessors();
1838 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1840 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1842 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1847 template<
typename RootNodeType>
1848 template<
typename OtherRootNodeType>
1852 this->clearAllAccessors();
1853 mRoot.topologyUnion(other.
root());
1856 template<
typename RootNodeType>
1857 template<
typename OtherRootNodeType>
1861 this->clearAllAccessors();
1862 mRoot.topologyIntersection(other.
root());
1865 template<
typename RootNodeType>
1866 template<
typename OtherRootNodeType>
1870 this->clearAllAccessors();
1871 mRoot.topologyDifference(other.
root());
1879 template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1885 op(args.
a(), args.
b(), args.
result());
1892 template<
typename RootNodeType>
1893 template<
typename CombineOp>
1898 this->combineExtended(other, extendedOp,
prune);
1905 template<
typename RootNodeType>
1906 template<
typename CombineOp>
1911 this->combineExtended(other, extendedOp,
prune);
1916 template<
typename RootNodeType>
1917 template<
typename ExtendedCombineOp>
1921 this->clearAllAccessors();
1929 template<
typename RootNodeType>
1930 template<
typename ExtendedCombineOp>
1934 this->clearAllAccessors();
1935 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op,
prune);
1940 template<
typename RootNodeType>
1941 template<
typename CombineOp,
typename OtherTreeType>
1946 this->combine2Extended(a, b, extendedOp,
prune);
1953 template<
typename RootNodeType>
1954 template<
typename CombineOp,
typename OtherTreeType>
1959 this->combine2Extended(a, b, extendedOp,
prune);
1964 template<
typename RootNodeType>
1965 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1968 ExtendedCombineOp& op,
bool prune)
1970 this->clearAllAccessors();
1971 mRoot.combine2(a.
root(), b.root(), op,
prune);
1979 template<
typename RootNodeType>
1980 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1983 const ExtendedCombineOp& op,
bool prune)
1985 this->clearAllAccessors();
1986 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op,
prune);
1994 template<
typename RootNodeType>
1995 template<
typename VisitorOp>
1999 this->clearAllAccessors();
2000 mRoot.template visit<VisitorOp>(op);
2004 template<
typename RootNodeType>
2005 template<
typename VisitorOp>
2009 mRoot.template visit<VisitorOp>(op);
2015 template<
typename RootNodeType>
2016 template<
typename VisitorOp>
2020 this->clearAllAccessors();
2021 mRoot.template visit<const VisitorOp>(op);
2027 template<
typename RootNodeType>
2028 template<
typename VisitorOp>
2032 mRoot.template visit<const VisitorOp>(op);
2039 template<
typename RootNodeType>
2040 template<
typename OtherTreeType,
typename VisitorOp>
2044 this->clearAllAccessors();
2045 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2046 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2050 template<
typename RootNodeType>
2051 template<
typename OtherTreeType,
typename VisitorOp>
2055 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2056 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2062 template<
typename RootNodeType>
2063 template<
typename OtherTreeType,
typename VisitorOp>
2067 this->clearAllAccessors();
2068 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2069 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2075 template<
typename RootNodeType>
2076 template<
typename OtherTreeType,
typename VisitorOp>
2080 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2081 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2088 template<
typename RootNodeType>
2092 static std::once_flag once;
2093 std::call_once(once, []()
2095 std::vector<Index> dims;
2096 Tree::getNodeLog2Dims(dims);
2097 std::ostringstream ostr;
2098 ostr <<
"Tree_" << typeNameAsString<BuildType>();
2099 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
2100 ostr <<
"_" << dims[i];
2102 sTreeTypeName.reset(
new Name(ostr.str()));
2104 return *sTreeTypeName;
2108 template<
typename RootNodeType>
2109 template<
typename OtherRootNodeType>
2117 template<
typename RootNodeType>
2122 this->evalActiveVoxelDim(dim);
2124 totalVoxels = dim.
x() * dim.
y() * dim.
z(),
2125 activeVoxels = this->activeVoxelCount();
2126 assert(totalVoxels >= activeVoxels);
2127 return totalVoxels - activeVoxels;
2131 template<
typename RootNodeType>
2137 if (this->empty())
return false;
2139 mRoot.evalActiveBoundingBox(bbox,
false);
2144 template<
typename RootNodeType>
2150 if (this->empty())
return false;
2152 mRoot.evalActiveBoundingBox(bbox,
true);
2158 template<
typename RootNodeType>
2163 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2169 template<
typename RootNodeType>
2174 bool notEmpty = this->evalLeafBoundingBox(bbox);
2180 template<
typename RootNodeType>
2185 minVal = maxVal = zeroVal<ValueType>();
2187 minVal = maxVal = *iter;
2188 for (++iter; iter; ++iter) {
2190 if (val < minVal) minVal = val;
2191 if (val > maxVal) maxVal = val;
2197 template<
typename RootNodeType>
2202 RootNodeType::getNodeLog2Dims(dims);
2206 template<
typename RootNodeType>
2210 if (verboseLevel <= 0)
return;
2215 std::streamsize savedPrecision;
2216 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2217 ~OnExit() { os.precision(savedPrecision); }
2219 OnExit restorePrecision(os);
2221 std::vector<Index> dims;
2222 Tree::getNodeLog2Dims(dims);
2224 os <<
"Information about Tree:\n"
2225 <<
" Type: " << this->type() <<
"\n";
2227 os <<
" Configuration:\n";
2229 if (verboseLevel <= 1) {
2231 os <<
" Root(" << mRoot.getTableSize() <<
")";
2232 if (dims.size() > 1) {
2233 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2234 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
2236 os <<
", Leaf(" << (1 << dims.back()) <<
"^3)\n";
2238 os <<
" Background value: " << mRoot.background() <<
"\n";
2244 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2245 if (verboseLevel > 3) {
2247 this->evalMinMax(minVal, maxVal);
2250 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2251 const auto nodeCount = this->nodeCount();
2252 const Index32 leafCount = nodeCount.front();
2254 std::vector<Index64> nodeCount(dims.size());
2255 for (
NodeCIter it = cbeginNode(); it; ++it) ++(nodeCount[it.getDepth()]);
2256 const Index64 leafCount = *nodeCount.rbegin();
2258 assert(dims.size() == nodeCount.size());
2261 for (
size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2264 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
2265 if (dims.size() >= 2) {
2266 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2267 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2272 os <<
" x " << (1 << dims[i]) <<
"^3)";
2275 os <<
" x " << (1 << dims.back()) <<
"^3)\n";
2277 os <<
" Background value: " << mRoot.background() <<
"\n";
2281 if (verboseLevel > 3) {
2282 os <<
" Min value: " << minVal <<
"\n";
2283 os <<
" Max value: " << maxVal <<
"\n";
2287 numActiveVoxels = this->activeVoxelCount(),
2288 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2289 numActiveTiles = this->activeTileCount();
2296 if (numActiveVoxels) {
2298 this->evalActiveVoxelBoundingBox(bbox);
2300 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
2302 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
2303 os <<
" Dimensions of active voxels: "
2304 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
2306 const double activeRatio = (100.0 * double(numActiveVoxels)) /
double(totalVoxels);
2307 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
2309 if (leafCount > 0) {
2310 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2311 / (
double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2312 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
2315 if (verboseLevel > 2) {
2317 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
2318 os <<
" Number of unallocated nodes: "
2320 << (100.0 * double(sum) / double(totalNodeCount)) <<
"%)\n";
2323 os <<
" Tree is empty!\n";
2327 if (verboseLevel == 2)
return;
2331 actualMem = this->memUsage(),
2332 denseMem =
sizeof(
ValueType) * totalVoxels,
2333 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
2336 os <<
"Memory footprint:\n";
2340 if (numActiveVoxels) {
2342 os <<
" Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2343 <<
"% of an equivalent dense volume\n";
2344 os <<
" Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2345 <<
"% of actual footprint\n";
2353 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED