6 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
22 #include <tbb/concurrent_hash_map.h>
48 virtual const Name& type()
const = 0;
51 virtual Name valueType()
const = 0;
70 virtual bool evalLeafBoundingBox(
CoordBBox& bbox)
const = 0;
75 virtual bool evalLeafDim(
Coord& dim)
const = 0;
84 virtual bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const = 0;
89 virtual bool evalActiveVoxelDim(
Coord& dim)
const = 0;
91 virtual void getIndexRange(
CoordBBox& bbox)
const = 0;
98 virtual void clipUnallocatedNodes() = 0;
100 virtual Index32 unallocatedLeafCount()
const = 0;
109 virtual Index treeDepth()
const = 0;
111 virtual Index32 leafCount()
const = 0;
112 #if OPENVDB_ABI_VERSION_NUMBER >= 7
113 virtual std::vector<Index32> nodeCount()
const = 0;
118 virtual Index32 nonLeafCount()
const = 0;
121 virtual Index64 activeLeafVoxelCount()
const = 0;
123 virtual Index64 inactiveLeafVoxelCount()
const = 0;
125 virtual Index64 activeVoxelCount()
const = 0;
127 virtual Index64 inactiveVoxelCount()
const = 0;
129 virtual Index64 activeTileCount()
const = 0;
141 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
145 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
148 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
150 virtual void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false) = 0;
156 virtual void readNonresidentBuffers()
const = 0;
158 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
167 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
174 template<
typename _RootNodeType>
186 static const Index DEPTH = RootNodeType::LEVEL + 1;
194 template<
typename OtherValueType>
202 Tree& operator=(
const Tree&) =
delete;
215 template<
typename OtherRootType>
230 template<
typename OtherTreeType>
231 Tree(
const OtherTreeType& other,
236 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
251 template<
typename OtherTreeType>
261 ~Tree()
override { this->clear(); releaseAllAccessors(); }
270 static const Name& treeType();
272 const Name&
type()
const override {
return this->treeType(); }
278 RootNodeType& root() {
return mRoot; }
289 template<
typename OtherRootNodeType>
292 bool evalLeafBoundingBox(
CoordBBox& bbox)
const override;
293 bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const override;
294 bool evalActiveVoxelDim(
Coord& dim)
const override;
295 bool evalLeafDim(
Coord& dim)
const override;
300 static void getNodeLog2Dims(std::vector<Index>& dims);
309 void readTopology(std::istream&,
bool saveFloatAsHalf =
false)
override;
313 void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
315 void readBuffers(std::istream&,
bool saveFloatAsHalf =
false)
override;
317 void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false)
override;
323 void readNonresidentBuffers()
const override;
325 void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
327 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const override;
339 #if OPENVDB_ABI_VERSION_NUMBER >= 7
340 std::vector<Index32> nodeCount()
const override
345 std::vector<Index32> vec(DEPTH, 0);
346 mRoot.nodeCount( vec );
350 Index32 nonLeafCount()
const override {
return mRoot.nonLeafCount(); }
359 Index64 inactiveVoxelCount()
const override;
364 void evalMinMax(ValueType &
min, ValueType &
max)
const;
373 const ValueType& getValue(
const Coord& xyz)
const;
376 template<
typename AccessT>
const ValueType& getValue(
const Coord& xyz, AccessT&)
const;
381 int getValueDepth(
const Coord& xyz)
const;
384 void setActiveState(
const Coord& xyz,
bool on);
386 void setValueOnly(
const Coord& xyz,
const ValueType& value);
388 void setValueOn(
const Coord& xyz);
390 void setValueOn(
const Coord& xyz,
const ValueType& value);
392 void setValue(
const Coord& xyz,
const ValueType& value);
395 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
397 void setValueOff(
const Coord& xyz);
399 void setValueOff(
const Coord& xyz,
const ValueType& value);
419 template<
typename ModifyOp>
420 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
441 template<
typename ModifyOp>
442 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
446 bool probeValue(
const Coord& xyz, ValueType& value)
const;
462 void clipUnallocatedNodes()
override;
465 Index32 unallocatedLeafCount()
const override;
468 void sparseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
479 this->sparseFill(bbox, value, active);
490 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
500 void voxelizeActiveTiles(
bool threaded =
true);
508 this->clearAllAccessors();
509 mRoot.prune(tolerance);
523 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
529 template<
typename NodeT>
530 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
537 LeafNodeType* touchLeaf(
const Coord& xyz);
540 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
543 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
544 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
548 LeafNodeType* probeLeaf(
const Coord& xyz);
551 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
556 template<
typename ArrayT>
void getNodes(ArrayT& array) { mRoot.getNodes(array); }
579 template<
typename ArrayT>
void getNodes(ArrayT& array)
const { mRoot.getNodes(array); }
605 template<
typename ArrayT>
606 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
607 template<
typename ArrayT>
610 this->clearAllAccessors();
611 mRoot.stealNodes(array, value, state);
619 bool empty()
const {
return mRoot.empty(); }
625 void clearAllAccessors();
691 template<
typename OtherRootNodeType>
707 template<
typename OtherRootNodeType>
720 template<
typename OtherRootNodeType>
767 template<
typename CombineOp>
770 template<
typename CombineOp>
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&,
936 template<
typename BBoxOp>
938 void visitActiveBBox(BBoxOp& op)
const { mRoot.visitActiveBBox(op); }
940 template<
typename VisitorOp>
942 void visit(VisitorOp& op);
943 template<typename VisitorOp>
945 void visit(const VisitorOp& op);
947 template<typename VisitorOp>
949 void visit(VisitorOp& op) const;
950 template<typename VisitorOp>
952 void visit(const VisitorOp& op) const;
954 template<typename OtherTreeType, typename VisitorOp>
956 void visit2(OtherTreeType& other, VisitorOp& op);
957 template<typename OtherTreeType, typename VisitorOp>
959 void visit2(OtherTreeType& other, const VisitorOp& op);
961 template<typename OtherTreeType, typename VisitorOp>
963 void visit2(OtherTreeType& other, VisitorOp& op) const;
964 template<typename OtherTreeType, typename VisitorOp>
966 void visit2(OtherTreeType& other, const VisitorOp& op) const;
973 typename RootNodeType::ChildOnCIter beginRootChildren()
const {
return mRoot.cbeginChildOn(); }
980 typename RootNodeType::ChildOffCIter beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
982 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
983 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
987 typename RootNodeType::ChildAllCIter beginRootDense()
const {
return mRoot.cbeginChildAll(); }
989 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
990 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1014 LeafIter beginLeaf() {
return LeafIter(*
this); }
1034 ValueOnIter beginValueOn() {
return ValueOnIter(*
this); }
1040 ValueOffIter beginValueOff() {
return ValueOffIter(*
this); }
1048 template<
typename IterT> IterT begin();
1051 template<
typename CIterT> CIterT cbegin()
const;
1060 void releaseAllAccessors();
1063 template<
typename NodeType>
1066 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1068 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
1069 delete mNodes[n]; mNodes[n] =
nullptr;
1085 template<
typename _RootNodeType>
1093 template<
typename T, Index N1=4, Index N2=3>
1103 template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1112 template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1123 TreeBase::readTopology(std::istream& is,
bool )
1125 int32_t bufferCount;
1126 is.read(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1127 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1132 TreeBase::writeTopology(std::ostream& os,
bool )
const
1134 int32_t bufferCount = 1;
1135 os.write(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1142 os <<
" Tree Type: " << type()
1143 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1144 <<
" Active tile Count: " << activeTileCount() << std::endl
1145 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1146 <<
" Leaf Node Count: " << leafCount() << std::endl
1147 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1162 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1163 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1164 return tree.beginRootChildren();
1168 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1169 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1170 return tree.cbeginRootChildren();
1174 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1175 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1176 return tree.beginRootTiles();
1180 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1181 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1182 return tree.cbeginRootTiles();
1186 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1187 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1188 return tree.beginRootDense();
1192 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1193 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1194 return tree.cbeginRootDense();
1199 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1203 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1207 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1211 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1215 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1218 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1219 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1222 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1223 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1226 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1227 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1230 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1231 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1234 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1235 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1239 template<
typename RootNodeType>
1240 template<
typename IterT>
1248 template<
typename RootNodeType>
1249 template<
typename IterT>
1260 template<
typename RootNodeType>
1264 this->clearAllAccessors();
1265 TreeBase::readTopology(is, saveFloatAsHalf);
1266 mRoot.readTopology(is, saveFloatAsHalf);
1270 template<
typename RootNodeType>
1274 TreeBase::writeTopology(os, saveFloatAsHalf);
1275 mRoot.writeTopology(os, saveFloatAsHalf);
1279 template<
typename RootNodeType>
1283 this->clearAllAccessors();
1284 mRoot.readBuffers(is, saveFloatAsHalf);
1288 template<
typename RootNodeType>
1292 this->clearAllAccessors();
1293 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1297 template<
typename RootNodeType>
1301 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1308 template<
typename RootNodeType>
1316 template<
typename RootNodeType>
1320 std::vector<LeafNodeType*> leafnodes;
1321 this->stealNodes(leafnodes);
1323 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1326 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1327 this->stealNodes(internalNodes);
1329 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1334 this->clearAllAccessors();
1341 template<
typename RootNodeType>
1345 typename AccessorRegistry::accessor a;
1346 mAccessorRegistry.insert(a, &accessor);
1350 template<
typename RootNodeType>
1354 typename ConstAccessorRegistry::accessor a;
1355 mConstAccessorRegistry.insert(a, &accessor);
1359 template<
typename RootNodeType>
1363 mAccessorRegistry.erase(&accessor);
1367 template<
typename RootNodeType>
1371 mConstAccessorRegistry.erase(&accessor);
1375 template<
typename RootNodeType>
1379 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1380 it != mAccessorRegistry.end(); ++it)
1382 if (it->first) it->first->
clear();
1385 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1386 it != mConstAccessorRegistry.end(); ++it)
1388 if (it->first) it->first->clear();
1393 template<
typename RootNodeType>
1397 mAccessorRegistry.erase(
nullptr);
1398 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1399 it != mAccessorRegistry.end(); ++it)
1401 it->first->release();
1403 mAccessorRegistry.
clear();
1405 mAccessorRegistry.erase(
nullptr);
1406 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1407 it != mConstAccessorRegistry.end(); ++it)
1409 it->first->release();
1411 mConstAccessorRegistry.clear();
1418 template<
typename RootNodeType>
1419 inline const typename RootNodeType::ValueType&
1426 template<
typename RootNodeType>
1427 template<
typename AccessT>
1428 inline const typename RootNodeType::ValueType&
1435 template<
typename RootNodeType>
1443 template<
typename RootNodeType>
1451 template<
typename RootNodeType>
1459 template<
typename RootNodeType>
1467 template<
typename RootNodeType>
1474 template<
typename RootNodeType>
1481 template<
typename RootNodeType>
1482 template<
typename AccessT>
1490 template<
typename RootNodeType>
1498 template<
typename RootNodeType>
1506 template<
typename RootNodeType>
1507 template<
typename ModifyOp>
1515 template<
typename RootNodeType>
1516 template<
typename ModifyOp>
1524 template<
typename RootNodeType>
1535 template<
typename RootNodeType>
1540 mRoot.
addTile(level, xyz, value, active);
1544 template<
typename RootNodeType>
1545 template<
typename NodeT>
1549 this->clearAllAccessors();
1550 return mRoot.template stealNode<NodeT>(xyz, value, active);
1554 template<
typename RootNodeType>
1555 inline typename RootNodeType::LeafNodeType*
1562 template<
typename RootNodeType>
1563 inline typename RootNodeType::LeafNodeType*
1570 template<
typename RootNodeType>
1571 inline const typename RootNodeType::LeafNodeType*
1578 template<
typename RootNodeType>
1579 template<
typename NodeType>
1583 return mRoot.template probeNode<NodeType>(xyz);
1587 template<
typename RootNodeType>
1588 template<
typename NodeType>
1589 inline const NodeType*
1592 return this->
template probeConstNode<NodeType>(xyz);
1596 template<
typename RootNodeType>
1597 template<
typename NodeType>
1598 inline const NodeType*
1601 return mRoot.template probeConstNode<NodeType>(xyz);
1608 template<
typename RootNodeType>
1612 this->clearAllAccessors();
1613 return mRoot.clip(bbox);
1617 template<
typename RootNodeType>
1621 this->clearAllAccessors();
1622 for (
LeafIter it = this->beginLeaf(); it; ) {
1625 if (!leaf->isAllocated()) {
1626 this->addTile(0, leaf->origin(), this->background(),
false);
1631 template<
typename RootNodeType>
1636 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1641 template<
typename RootNodeType>
1645 this->clearAllAccessors();
1646 return mRoot.sparseFill(bbox, value, active);
1650 template<
typename RootNodeType>
1654 this->clearAllAccessors();
1655 return mRoot.denseFill(bbox, value, active);
1659 template<
typename RootNodeType>
1663 this->clearAllAccessors();
1664 mRoot.voxelizeActiveTiles(threaded);
1668 template<
typename RootNodeType>
1673 if (Metadata::isRegisteredType(valueType())) {
1675 result = Metadata::createMetadata(valueType());
1676 if (result->typeName() == MetadataT::staticTypeName()) {
1677 MetadataT* m =
static_cast<MetadataT*
>(result.get());
1678 m->value() = mRoot.background();
1688 template<
typename RootNodeType>
1692 this->clearAllAccessors();
1696 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1698 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1700 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1705 template<
typename RootNodeType>
1706 template<
typename OtherRootNodeType>
1710 this->clearAllAccessors();
1711 mRoot.topologyUnion(other.
root(), preserveTiles);
1714 template<
typename RootNodeType>
1715 template<
typename OtherRootNodeType>
1719 this->clearAllAccessors();
1720 mRoot.topologyIntersection(other.
root());
1723 template<
typename RootNodeType>
1724 template<
typename OtherRootNodeType>
1728 this->clearAllAccessors();
1729 mRoot.topologyDifference(other.
root());
1737 template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1743 op(args.
a(), args.
b(), args.
result());
1750 template<
typename RootNodeType>
1751 template<
typename CombineOp>
1756 this->combineExtended(other, extendedOp,
prune);
1763 template<
typename RootNodeType>
1764 template<
typename CombineOp>
1769 this->combineExtended(other, extendedOp,
prune);
1774 template<
typename RootNodeType>
1775 template<
typename ExtendedCombineOp>
1779 this->clearAllAccessors();
1787 template<
typename RootNodeType>
1788 template<
typename ExtendedCombineOp>
1792 this->clearAllAccessors();
1793 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op,
prune);
1798 template<
typename RootNodeType>
1799 template<
typename CombineOp,
typename OtherTreeType>
1804 this->combine2Extended(a, b, extendedOp,
prune);
1811 template<
typename RootNodeType>
1812 template<
typename CombineOp,
typename OtherTreeType>
1817 this->combine2Extended(a, b, extendedOp,
prune);
1822 template<
typename RootNodeType>
1823 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1826 ExtendedCombineOp& op,
bool prune)
1828 this->clearAllAccessors();
1829 mRoot.combine2(a.
root(), b.root(), op,
prune);
1837 template<
typename RootNodeType>
1838 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1841 const ExtendedCombineOp& op,
bool prune)
1843 this->clearAllAccessors();
1844 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op,
prune);
1852 template<
typename RootNodeType>
1853 template<
typename VisitorOp>
1857 this->clearAllAccessors();
1858 mRoot.template visit<VisitorOp>(op);
1862 template<
typename RootNodeType>
1863 template<
typename VisitorOp>
1867 mRoot.template visit<VisitorOp>(op);
1873 template<
typename RootNodeType>
1874 template<
typename VisitorOp>
1878 this->clearAllAccessors();
1879 mRoot.template visit<const VisitorOp>(op);
1885 template<
typename RootNodeType>
1886 template<
typename VisitorOp>
1890 mRoot.template visit<const VisitorOp>(op);
1897 template<
typename RootNodeType>
1898 template<
typename OtherTreeType,
typename VisitorOp>
1902 this->clearAllAccessors();
1903 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
1904 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
1908 template<
typename RootNodeType>
1909 template<
typename OtherTreeType,
typename VisitorOp>
1913 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
1914 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
1920 template<
typename RootNodeType>
1921 template<
typename OtherTreeType,
typename VisitorOp>
1925 this->clearAllAccessors();
1926 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
1927 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
1933 template<
typename RootNodeType>
1934 template<
typename OtherTreeType,
typename VisitorOp>
1938 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
1939 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
1946 template<
typename RootNodeType>
1950 static std::once_flag once;
1951 std::call_once(once, []()
1953 std::vector<Index> dims;
1954 Tree::getNodeLog2Dims(dims);
1955 std::ostringstream ostr;
1956 ostr <<
"Tree_" << typeNameAsString<BuildType>();
1957 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
1958 ostr <<
"_" << dims[i];
1960 sTreeTypeName.reset(
new Name(ostr.str()));
1962 return *sTreeTypeName;
1966 template<
typename RootNodeType>
1967 template<
typename OtherRootNodeType>
1975 template<
typename RootNodeType>
1980 this->evalActiveVoxelDim(dim);
1982 totalVoxels = dim.
x() * dim.
y() * dim.
z(),
1983 activeVoxels = this->activeVoxelCount();
1984 assert(totalVoxels >= activeVoxels);
1985 return totalVoxels - activeVoxels;
1989 template<
typename RootNodeType>
1995 if (this->empty())
return false;
1997 mRoot.evalActiveBoundingBox(bbox,
false);
1999 return !bbox.
empty();
2002 template<
typename RootNodeType>
2008 if (this->empty())
return false;
2010 mRoot.evalActiveBoundingBox(bbox,
true);
2012 return !bbox.
empty();
2016 template<
typename RootNodeType>
2021 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2027 template<
typename RootNodeType>
2032 bool notEmpty = this->evalLeafBoundingBox(bbox);
2038 template<
typename RootNodeType>
2043 minVal = maxVal = zeroVal<ValueType>();
2045 minVal = maxVal = *iter;
2046 for (++iter; iter; ++iter) {
2055 template<
typename RootNodeType>
2060 RootNodeType::getNodeLog2Dims(dims);
2064 template<
typename RootNodeType>
2068 if (verboseLevel <= 0)
return;
2073 std::streamsize savedPrecision;
2074 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2075 ~OnExit() { os.precision(savedPrecision); }
2077 OnExit restorePrecision(os);
2079 std::vector<Index> dims;
2080 Tree::getNodeLog2Dims(dims);
2082 os <<
"Information about Tree:\n"
2083 <<
" Type: " << this->type() <<
"\n";
2085 os <<
" Configuration:\n";
2087 if (verboseLevel <= 1) {
2089 os <<
" Root(" << mRoot.getTableSize() <<
")";
2090 if (dims.size() > 1) {
2091 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2092 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
2094 os <<
", Leaf(" << (1 << dims.back()) <<
"^3)\n";
2096 os <<
" Background value: " << mRoot.background() <<
"\n";
2102 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2103 if (verboseLevel > 3) {
2105 this->evalMinMax(minVal, maxVal);
2108 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2109 const auto nodeCount = this->nodeCount();
2110 const Index32 leafCount = nodeCount.front();
2112 std::vector<Index64> nodeCount(dims.size());
2113 for (
NodeCIter it = cbeginNode(); it; ++it) ++(nodeCount[it.getDepth()]);
2114 const Index64 leafCount = *nodeCount.rbegin();
2116 assert(dims.size() == nodeCount.size());
2119 for (
size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2122 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
2123 if (dims.size() >= 2) {
2124 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2125 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2130 os <<
" x " << (1 << dims[i]) <<
"^3)";
2133 os <<
" x " << (1 << dims.back()) <<
"^3)\n";
2135 os <<
" Background value: " << mRoot.background() <<
"\n";
2139 if (verboseLevel > 3) {
2140 os <<
" Min value: " << minVal <<
"\n";
2141 os <<
" Max value: " << maxVal <<
"\n";
2145 numActiveVoxels = this->activeVoxelCount(),
2146 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2147 numActiveTiles = this->activeTileCount();
2154 if (numActiveVoxels) {
2156 this->evalActiveVoxelBoundingBox(bbox);
2158 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
2160 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
2161 os <<
" Dimensions of active voxels: "
2162 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
2164 const double activeRatio = (100.0 * double(numActiveVoxels)) /
double(totalVoxels);
2165 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
2167 if (leafCount > 0) {
2168 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2169 / (
double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2170 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
2173 if (verboseLevel > 2) {
2175 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
2176 os <<
" Number of unallocated nodes: "
2178 << (100.0 * double(sum) / double(totalNodeCount)) <<
"%)\n";
2181 os <<
" Tree is empty!\n";
2185 if (verboseLevel == 2)
return;
2190 denseMem =
sizeof(
ValueType) * totalVoxels,
2191 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
2194 os <<
"Memory footprint:\n";
2198 if (numActiveVoxels) {
2200 os <<
" Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2201 <<
"% of an equivalent dense volume\n";
2202 os <<
" Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2203 <<
"% of actual footprint\n";
2211 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED