35 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED 36 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED 50 #include <tbb/atomic.h> 51 #include <tbb/concurrent_hash_map.h> 76 virtual const Name& type()
const = 0;
79 virtual Name valueType()
const = 0;
98 virtual bool evalLeafBoundingBox(CoordBBox& bbox)
const = 0;
103 virtual bool evalLeafDim(Coord& dim)
const = 0;
112 virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox)
const = 0;
117 virtual bool evalActiveVoxelDim(Coord& dim)
const = 0;
119 virtual void getIndexRange(CoordBBox& bbox)
const = 0;
121 #ifndef OPENVDB_2_ABI_COMPATIBLE 122 virtual void clipUnallocatedNodes() = 0;
128 #ifndef OPENVDB_3_ABI_COMPATIBLE 129 virtual Index32 unallocatedLeafCount()
const = 0;
141 virtual Index treeDepth()
const = 0;
143 virtual Index32 leafCount()
const = 0;
145 virtual Index32 nonLeafCount()
const = 0;
147 virtual Index64 activeLeafVoxelCount()
const = 0;
149 virtual Index64 inactiveLeafVoxelCount()
const = 0;
151 virtual Index64 activeVoxelCount()
const = 0;
153 virtual Index64 inactiveVoxelCount()
const = 0;
154 #ifndef OPENVDB_2_ABI_COMPATIBLE 155 virtual Index64 activeTileCount()
const = 0;
169 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
173 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
176 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
177 #ifndef OPENVDB_2_ABI_COMPATIBLE 178 virtual void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false) = 0;
185 virtual void readNonresidentBuffers()
const = 0;
187 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
197 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
204 template<
typename _RootNodeType>
216 static const Index DEPTH = RootNodeType::LEVEL + 1;
224 template<
typename OtherValueType>
232 Tree& operator=(
const Tree&) =
delete;
245 template<
typename OtherRootType>
260 template<
typename OtherTreeType>
261 Tree(
const OtherTreeType& other,
266 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
281 template<
typename OtherTreeType>
291 ~Tree()
override { this->clear(); releaseAllAccessors(); }
300 static const Name& treeType();
302 const Name&
type()
const override {
return this->treeType(); }
319 template<
typename OtherRootNodeType>
322 bool evalLeafBoundingBox(CoordBBox& bbox)
const override;
323 bool evalActiveVoxelBoundingBox(CoordBBox& bbox)
const override;
324 bool evalActiveVoxelDim(Coord& dim)
const override;
325 bool evalLeafDim(Coord& dim)
const override;
330 static void getNodeLog2Dims(std::vector<Index>& dims);
339 void readTopology(std::istream&,
bool saveFloatAsHalf =
false)
override;
343 void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
345 void readBuffers(std::istream&,
bool saveFloatAsHalf =
false)
override;
346 #ifndef OPENVDB_2_ABI_COMPATIBLE 347 void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false)
override;
354 void readNonresidentBuffers()
const override;
356 void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
359 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const override;
380 Index64 inactiveVoxelCount()
const override;
394 const ValueType& getValue(
const Coord& xyz)
const;
397 template<
typename AccessT>
const ValueType& getValue(
const Coord& xyz, AccessT&)
const;
402 int getValueDepth(
const Coord& xyz)
const;
405 void setActiveState(
const Coord& xyz,
bool on);
407 void setValueOnly(
const Coord& xyz,
const ValueType& value);
409 void setValueOn(
const Coord& xyz);
411 void setValueOn(
const Coord& xyz,
const ValueType& value);
413 void setValue(
const Coord& xyz,
const ValueType& value);
416 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
418 void setValueOff(
const Coord& xyz);
420 void setValueOff(
const Coord& xyz,
const ValueType& value);
440 template<
typename ModifyOp>
441 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
462 template<
typename ModifyOp>
463 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
467 bool probeValue(
const Coord& xyz,
ValueType& value)
const;
470 bool isValueOn(
const Coord& xyz)
const {
return mRoot.isValueOn(xyz); }
472 bool isValueOff(
const Coord& xyz)
const {
return !this->isValueOn(xyz); }
477 void clip(
const CoordBBox&);
479 #ifndef OPENVDB_2_ABI_COMPATIBLE 480 void clipUnallocatedNodes()
override;
486 #ifndef OPENVDB_3_ABI_COMPATIBLE 487 Index32 unallocatedLeafCount()
const override;
493 void sparseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
502 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true)
504 this->sparseFill(bbox, value, active);
515 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
525 void voxelizeActiveTiles(
bool threaded =
true);
533 this->clearAllAccessors();
534 mRoot.prune(tolerance);
538 void addLeaf(
LeafNodeType* leaf) { assert(leaf); mRoot.addLeaf(leaf); }
551 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
557 template<
typename NodeT>
558 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
568 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
571 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
572 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
579 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
584 template<
typename ArrayT>
void getNodes(ArrayT& array) { mRoot.getNodes(array); }
607 template<
typename ArrayT>
void getNodes(ArrayT& array)
const { mRoot.getNodes(array); }
633 template<
typename ArrayT>
634 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
635 template<
typename ArrayT>
638 this->clearAllAccessors();
639 mRoot.stealNodes(array, value, state);
647 bool empty()
const {
return mRoot.empty(); }
653 void clearAllAccessors();
692 void getIndexRange(CoordBBox& bbox)
const override { mRoot.getIndexRange(bbox); }
716 template<
typename OtherRootNodeType>
732 template<
typename OtherRootNodeType>
745 template<
typename OtherRootNodeType>
792 template<
typename CombineOp>
793 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
795 template<
typename CombineOp>
796 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
837 template<
typename ExtendedCombineOp>
838 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
840 template<
typename ExtendedCombineOp>
841 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
872 template<
typename CombineOp,
typename OtherTreeType >
873 void combine2(
const Tree& a,
const OtherTreeType& b, CombineOp& op,
bool prune =
false);
875 template<
typename CombineOp,
typename OtherTreeType >
876 void combine2(
const Tree& a,
const OtherTreeType& b,
const CombineOp& op,
bool prune =
false);
952 template<
typename ExtendedCombineOp,
typename OtherTreeType >
953 void combine2Extended(
const Tree& a,
const OtherTreeType& b, ExtendedCombineOp& op,
956 template<
typename ExtendedCombineOp,
typename OtherTreeType >
957 void combine2Extended(
const Tree& a,
const OtherTreeType& b,
const ExtendedCombineOp&,
1001 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp& op)
const { mRoot.visitActiveBBox(op); }
1056 template<
typename VisitorOp>
void visit(VisitorOp& op);
1057 template<
typename VisitorOp>
void visit(
const VisitorOp& op);
1063 template<
typename VisitorOp>
void visit(VisitorOp& op)
const;
1064 template<
typename VisitorOp>
void visit(
const VisitorOp& op)
const;
1113 template<
typename OtherTreeType,
typename VisitorOp>
1114 void visit2(OtherTreeType& other, VisitorOp& op);
1115 template<
typename OtherTreeType,
typename VisitorOp>
1116 void visit2(OtherTreeType& other,
const VisitorOp& op);
1128 template<
typename OtherTreeType,
typename VisitorOp>
1129 void visit2(OtherTreeType& other, VisitorOp& op)
const;
1130 template<
typename OtherTreeType,
typename VisitorOp>
1131 void visit2(OtherTreeType& other,
const VisitorOp& op)
const;
1138 typename RootNodeType::ChildOnCIter beginRootChildren()
const {
return mRoot.cbeginChildOn(); }
1145 typename RootNodeType::ChildOffCIter beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1147 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1148 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
1152 typename RootNodeType::ChildAllCIter beginRootDense()
const {
return mRoot.cbeginChildAll(); }
1154 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
1155 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1213 template<
typename IterT> IterT begin();
1216 template<
typename CIterT> CIterT cbegin()
const;
1225 void releaseAllAccessors();
1228 template<
typename NodeType>
1231 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1233 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
1234 delete mNodes[n]; mNodes[n] =
nullptr;
1250 template<
typename _RootNodeType>
1258 template<
typename T, Index N1=4, Index N2=3>
1268 template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1277 template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1290 int32_t bufferCount;
1291 is.read(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1292 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1299 int32_t bufferCount = 1;
1300 os.write(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1307 os <<
" Tree Type: " << type()
1308 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1309 #ifndef OPENVDB_2_ABI_COMPATIBLE 1310 <<
" Active tile Count: " << activeTileCount() << std::endl
1312 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1313 <<
" Leaf Node Count: " << leafCount() << std::endl
1314 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1329 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1330 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1331 return tree.beginRootChildren();
1335 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1336 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1337 return tree.cbeginRootChildren();
1341 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1342 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1343 return tree.beginRootTiles();
1347 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1348 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1349 return tree.cbeginRootTiles();
1353 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1354 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1355 return tree.beginRootDense();
1359 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1360 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1361 return tree.cbeginRootDense();
1366 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1370 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1374 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1378 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1382 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1385 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1386 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1389 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1390 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1393 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1394 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1397 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1398 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1401 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1402 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1406 template<
typename RootNodeType>
1407 template<
typename IterT>
1415 template<
typename RootNodeType>
1416 template<
typename IterT>
1427 template<
typename RootNodeType>
1431 this->clearAllAccessors();
1433 mRoot.readTopology(is, saveFloatAsHalf);
1437 template<
typename RootNodeType>
1442 mRoot.writeTopology(os, saveFloatAsHalf);
1446 template<
typename RootNodeType>
1450 this->clearAllAccessors();
1451 mRoot.readBuffers(is, saveFloatAsHalf);
1455 #ifndef OPENVDB_2_ABI_COMPATIBLE 1457 template<
typename RootNodeType>
1461 this->clearAllAccessors();
1462 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1466 template<
typename RootNodeType>
1470 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1476 #endif // !OPENVDB_2_ABI_COMPATIBLE 1479 template<
typename RootNodeType>
1487 template<
typename RootNodeType>
1491 std::vector<LeafNodeType*> leafnodes;
1492 this->stealNodes(leafnodes);
1494 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1497 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1498 this->stealNodes(internalNodes);
1500 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1505 this->clearAllAccessors();
1512 template<
typename RootNodeType>
1516 typename AccessorRegistry::accessor a;
1517 mAccessorRegistry.insert(a, &accessor);
1521 template<
typename RootNodeType>
1525 typename ConstAccessorRegistry::accessor a;
1526 mConstAccessorRegistry.insert(a, &accessor);
1530 template<
typename RootNodeType>
1534 mAccessorRegistry.erase(&accessor);
1538 template<
typename RootNodeType>
1542 mConstAccessorRegistry.erase(&accessor);
1546 template<
typename RootNodeType>
1550 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1551 it != mAccessorRegistry.end(); ++it)
1553 if (it->first) it->first->
clear();
1556 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1557 it != mConstAccessorRegistry.end(); ++it)
1559 if (it->first) it->first->clear();
1564 template<
typename RootNodeType>
1568 mAccessorRegistry.erase(
nullptr);
1569 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1570 it != mAccessorRegistry.end(); ++it)
1572 it->first->release();
1574 mAccessorRegistry.
clear();
1576 mAccessorRegistry.erase(
nullptr);
1577 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1578 it != mConstAccessorRegistry.end(); ++it)
1580 it->first->release();
1582 mConstAccessorRegistry.clear();
1589 template<
typename RootNodeType>
1590 inline const typename RootNodeType::ValueType&
1597 template<
typename RootNodeType>
1598 template<
typename AccessT>
1599 inline const typename RootNodeType::ValueType&
1606 template<
typename RootNodeType>
1614 template<
typename RootNodeType>
1622 template<
typename RootNodeType>
1630 template<
typename RootNodeType>
1638 template<
typename RootNodeType>
1645 template<
typename RootNodeType>
1652 template<
typename RootNodeType>
1653 template<
typename AccessT>
1661 template<
typename RootNodeType>
1669 template<
typename RootNodeType>
1677 template<
typename RootNodeType>
1678 template<
typename ModifyOp>
1686 template<
typename RootNodeType>
1687 template<
typename ModifyOp>
1695 template<
typename RootNodeType>
1706 template<
typename RootNodeType>
1711 mRoot.
addTile(level, xyz, value, active);
1715 template<
typename RootNodeType>
1716 template<
typename NodeT>
1720 this->clearAllAccessors();
1721 return mRoot.template stealNode<NodeT>(xyz, value, active);
1725 template<
typename RootNodeType>
1726 inline typename RootNodeType::LeafNodeType*
1733 template<
typename RootNodeType>
1734 inline typename RootNodeType::LeafNodeType*
1741 template<
typename RootNodeType>
1742 inline const typename RootNodeType::LeafNodeType*
1749 template<
typename RootNodeType>
1750 template<
typename NodeType>
1754 return mRoot.template probeNode<NodeType>(xyz);
1758 template<
typename RootNodeType>
1759 template<
typename NodeType>
1760 inline const NodeType*
1763 return this->
template probeConstNode<NodeType>(xyz);
1767 template<
typename RootNodeType>
1768 template<
typename NodeType>
1769 inline const NodeType*
1772 return mRoot.template probeConstNode<NodeType>(xyz);
1779 template<
typename RootNodeType>
1783 this->clearAllAccessors();
1784 return mRoot.clip(bbox);
1788 #ifndef OPENVDB_2_ABI_COMPATIBLE 1789 template<
typename RootNodeType>
1793 this->clearAllAccessors();
1794 for (
LeafIter it = this->beginLeaf(); it; ) {
1797 if (!leaf->isAllocated()) {
1798 this->addTile(0, leaf->origin(), this->background(),
false);
1803 #ifndef OPENVDB_3_ABI_COMPATIBLE 1804 template<
typename RootNodeType>
1809 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1816 template<
typename RootNodeType>
1820 this->clearAllAccessors();
1821 return mRoot.sparseFill(bbox, value, active);
1825 template<
typename RootNodeType>
1829 this->clearAllAccessors();
1830 return mRoot.denseFill(bbox, value, active);
1834 template<
typename RootNodeType>
1838 this->clearAllAccessors();
1839 mRoot.voxelizeActiveTiles(threaded);
1843 template<
typename RootNodeType>
1851 if (result->typeName() == MetadataT::staticTypeName()) {
1852 MetadataT* m =
static_cast<MetadataT*
>(result.get());
1853 m->value() = mRoot.background();
1863 template<
typename RootNodeType>
1867 this->clearAllAccessors();
1871 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1873 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1875 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1880 template<
typename RootNodeType>
1881 template<
typename OtherRootNodeType>
1885 this->clearAllAccessors();
1886 mRoot.topologyUnion(other.
root());
1889 template<
typename RootNodeType>
1890 template<
typename OtherRootNodeType>
1894 this->clearAllAccessors();
1895 mRoot.topologyIntersection(other.
root());
1898 template<
typename RootNodeType>
1899 template<
typename OtherRootNodeType>
1903 this->clearAllAccessors();
1904 mRoot.topologyDifference(other.
root());
1912 template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1918 op(args.
a(), args.
b(), args.
result());
1925 template<
typename RootNodeType>
1926 template<
typename CombineOp>
1931 this->combineExtended(other, extendedOp, prune);
1938 template<
typename RootNodeType>
1939 template<
typename CombineOp>
1944 this->combineExtended(other, extendedOp, prune);
1949 template<
typename RootNodeType>
1950 template<
typename ExtendedCombineOp>
1954 this->clearAllAccessors();
1962 template<
typename RootNodeType>
1963 template<
typename ExtendedCombineOp>
1967 this->clearAllAccessors();
1968 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op,
prune);
1973 template<
typename RootNodeType>
1974 template<
typename CombineOp,
typename OtherTreeType>
1979 this->combine2Extended(a, b, extendedOp, prune);
1986 template<
typename RootNodeType>
1987 template<
typename CombineOp,
typename OtherTreeType>
1992 this->combine2Extended(a, b, extendedOp, prune);
1997 template<
typename RootNodeType>
1998 template<
typename ExtendedCombineOp,
typename OtherTreeType>
2001 ExtendedCombineOp& op,
bool prune)
2003 this->clearAllAccessors();
2004 mRoot.combine2(a.
root(), b.root(), op,
prune);
2012 template<
typename RootNodeType>
2013 template<
typename ExtendedCombineOp,
typename OtherTreeType>
2016 const ExtendedCombineOp& op,
bool prune)
2018 this->clearAllAccessors();
2019 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op,
prune);
2027 template<
typename RootNodeType>
2028 template<
typename VisitorOp>
2032 this->clearAllAccessors();
2033 mRoot.template visit<VisitorOp>(op);
2037 template<
typename RootNodeType>
2038 template<
typename VisitorOp>
2042 mRoot.template visit<VisitorOp>(op);
2048 template<
typename RootNodeType>
2049 template<
typename VisitorOp>
2053 this->clearAllAccessors();
2054 mRoot.template visit<const VisitorOp>(op);
2060 template<
typename RootNodeType>
2061 template<
typename VisitorOp>
2065 mRoot.template visit<const VisitorOp>(op);
2072 template<
typename RootNodeType>
2073 template<
typename OtherTreeType,
typename VisitorOp>
2077 this->clearAllAccessors();
2078 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2079 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2083 template<
typename RootNodeType>
2084 template<
typename OtherTreeType,
typename VisitorOp>
2088 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2089 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2095 template<
typename RootNodeType>
2096 template<
typename OtherTreeType,
typename VisitorOp>
2100 this->clearAllAccessors();
2101 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2102 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2108 template<
typename RootNodeType>
2109 template<
typename OtherTreeType,
typename VisitorOp>
2113 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
2114 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2121 template<
typename RootNodeType>
2125 if (sTreeTypeName ==
nullptr) {
2126 std::vector<Index> dims;
2127 Tree::getNodeLog2Dims(dims);
2128 std::ostringstream ostr;
2129 ostr <<
"Tree_" << typeNameAsString<BuildType>();
2130 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
2131 ostr <<
"_" << dims[i];
2134 if (sTreeTypeName.compare_and_swap(s,
nullptr) !=
nullptr)
delete s;
2136 return *sTreeTypeName;
2140 template<
typename RootNodeType>
2141 template<
typename OtherRootNodeType>
2149 template<
typename RootNodeType>
2154 this->evalActiveVoxelDim(dim);
2156 totalVoxels = dim.x() * dim.y() * dim.z(),
2157 activeVoxels = this->activeVoxelCount();
2158 assert(totalVoxels >= activeVoxels);
2159 return totalVoxels - activeVoxels;
2163 template<
typename RootNodeType>
2169 if (this->empty())
return false;
2171 mRoot.evalActiveBoundingBox(bbox,
false);
2176 template<
typename RootNodeType>
2182 if (this->empty())
return false;
2184 mRoot.evalActiveBoundingBox(bbox,
true);
2190 template<
typename RootNodeType>
2195 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2196 dim = bbox.extents();
2201 template<
typename RootNodeType>
2206 bool notEmpty = this->evalLeafBoundingBox(bbox);
2207 dim = bbox.extents();
2212 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);
2320 dim = bbox.extents();
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 #ifndef OPENVDB_2_ABI_COMPATIBLE 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 virtual Metadata::Ptr getBackgroundValue() const
Return this tree's background value wrapped as metadata.
Definition: Tree.h:89
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal, Internal, Leaf) with value type T and internal and leaf node log dimensions N1, N2, N3 and N4, respectively.
Definition: Tree.h:1278
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:503
virtual void readTopology(std::istream &, bool saveFloatAsHalf=false)
Read the tree topology from a stream.
Definition: Tree.h:1288
uint32_t Index32
Definition: Types.h:55
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:160
OPENVDB_API int printBytes(std::ostream &os, uint64_t bytes, const std::string &head="", const std::string &tail="\n", bool exact=false, int width=8, int precision=3)
void stealNodes(ArrayT &array)
Steals all nodes of a certain type from the tree and adds them to a container with the following API:...
Definition: Tree.h:634
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1244
typename RootNodeType::ValueType ValueType
Definition: Tree.h:212
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1394
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:636
static tbb::atomic< const Name * > sTreeTypeName
Definition: Tree.h:1247
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1182
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
const LeafNodeType * probeLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: Tree.h:580
DeallocateNodes(std::vector< NodeType * > &nodes)
Definition: Tree.h:1230
OPENVDB_DEPRECATED void addLeaf(LeafNodeType &leaf)
Add the given leaf node to this tree, creating a new branch if necessary. If a leaf node with the sam...
Definition: Tree.h:544
Tree()
Definition: Tree.h:230
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: Tree.h:1616
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1402
SharedPtr< const TreeBase > ConstPtr
Definition: Tree.h:68
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:977
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1917
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1591
void prune(const ValueType &tolerance=zeroVal< ValueType >())
Reduce the memory footprint of this tree by replacing with tiles any nodes whose values are all the s...
Definition: Tree.h:531
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition: Tree.h:692
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition: Tree.h:1481
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
const ValueType & background() const
Return this tree's background value.
Definition: Tree.h:689
RootNodeType & root()
Return this tree's root node.
Definition: Tree.h:309
LeafCIter beginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1181
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1354
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
Definition: Tree.h:665
Index64 memUsage() const override
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:387
const RootNodeType & root() const
Return this tree's root node.
Definition: Tree.h:310
virtual void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const
Write the tree topology to a stream.
Definition: Tree.h:1297
void addTile(Index level, const Coord &xyz, const ValueType &value, bool active)
Add a tile containing voxel (x, y, z) at the specified tree level, creating a new branch if necessary...
Definition: Tree.h:1708
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:289
SharedPtr< TreeBase > Ptr
Definition: Tree.h:67
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition: Tree.h:225
void setValue(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: Tree.h:1640
ValueAllCIter cbeginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1196
ValueAllCIter beginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1195
void getNodes(ArrayT &array) const
Adds all nodes of a certain type to a container with the following API:
Definition: Tree.h:607
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1370
bool operator==(const Tree &) const
Definition: Tree.h:304
RootNodeType::ChildOffIter beginRootTiles()
Return an iterator over non-child entries of the root node's table.
Definition: Tree.h:1148
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1348
NodeCIter beginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1174
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates but don't change its active state.
Definition: Tree.h:1647
RootNodeType::ChildOffCIter cbeginRootTiles() const
Return an iterator over non-child entries of the root node's table.
Definition: Tree.h:1147
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1342
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1689
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal, Leaf) with value type T and internal and leaf node log dimensions N1, N2 and N3, respectively.
Definition: Tree.h:1269
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: Tree.h:1632
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1913
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:261
RootNodeType::ChildOnCIter cbeginRootChildren() const
Return an iterator over children of the root node.
Definition: Tree.h:1140
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1398
Internal table nodes for OpenVDB trees.
bool empty() const
Return true if this tree contains no nodes other than the root node and no tiles other than backgroun...
Definition: Tree.h:647
#define OPENVDB_VERSION_NAME
Definition: version.h:43
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1232
bool operator!=(const Tree &) const
Definition: Tree.h:305
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1378
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:371
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1360
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels) ...
Definition: TreeIterator.h:1228
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:470
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1245
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
Definition: Tree.h:677
ValueOffCIter beginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1207
RootNodeType::ChildAllIter beginRootDense()
Return an iterator over all entries of the root node's table.
Definition: Tree.h:1155
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:374
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1221
Definition: Exceptions.h:39
typename RootNodeType::BuildType BuildType
Definition: Tree.h:213
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition: Tree.h:1259
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1489
const AValueType & a() const
Get the A input value.
Definition: Types.h:411
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1327
ValueOnCIter cbeginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1202
const AValueType & result() const
Get the output value.
Definition: Types.h:416
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:214
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1548
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1330
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:130
void visitActiveBBox(BBoxOp &op) const
Use sparse traversal to call the given functor with bounding box information for all active tiles and...
Definition: Tree.h:1001
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:235
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1366
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1220
LeafNodeType * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, create one that preserves the values and active states of all voxels.
Definition: Tree.h:1727
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1374
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:282
CombineOp & op
Definition: Tree.h:1921
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:474
uint64_t Index64
Definition: Types.h:56
MergePolicy
Definition: Types.h:315
Index32 nonLeafCount() const override
Return the number of non-leaf nodes.
Definition: Tree.h:372
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:658
std::string Name
Definition: Name.h:44
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1336
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: Tree.h:1680
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:376
NodeCIter cbeginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1175
Definition: Exceptions.h:88
The root node of an OpenVDB tree.
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: Tree.h:1743
tree::TreeBase TreeBase
Definition: Grid.h:52
RootNodeType::ChildOnIter beginRootChildren()
Return an iterator over children of the root node.
Definition: Tree.h:1141
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition: Tree.h:294
RootNodeType::ChildAllCIter cbeginRootDense() const
Return an iterator over all entries of the root node's table.
Definition: Tree.h:1154
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:278
ValueOnCIter beginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1201
std::shared_ptr< T > SharedPtr
Definition: Types.h:130
RootNodeType mRoot
Definition: Tree.h:1243
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1386
~Tree() override
Definition: Tree.h:291
Index treeDepth() const override
Return the depth of this tree.
Definition: Tree.h:368
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:472
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1697
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: Tree.h:1735
int getValueDepth(const Coord &xyz) const
Return the tree depth (0 = root) at which the value of voxel (x, y, z) resides.
Definition: Tree.h:1608
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:121
const Name & type() const override
Return the name of this type of tree.
Definition: Tree.h:302
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: Tree.h:1663
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: Tree.h:502
ValueOffCIter cbeginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1208
Name valueType() const override
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
Definition: Tree.h:297
bool hasSameTopology(const Tree< OtherRootNodeType > &other) const
Return true if the given tree has the same node and active value topology as this tree...
Definition: Tree.h:2143
Index32 Index
Definition: Types.h:57
Index32 leafCount() const override
Return the number of leaf nodes.
Definition: Tree.h:370
virtual void print(std::ostream &os=std::cout, int verboseLevel=1) const
Print statistics, memory usage and other information about this tree.
Definition: Tree.h:1305
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Definition: Tree.h:378
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1390
Index64 activeTileCount() const override
Return the total number of active tiles.
Definition: Tree.h:382
Base class for typed trees.
Definition: Tree.h:64
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1382
NodeType **const mNodes
Definition: Tree.h:1237
_RootNodeType RootNodeType
Definition: Tree.h:211
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:246
const BValueType & b() const
Get the B input value.
Definition: Types.h:413
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1915