6 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
22 #include <tbb/concurrent_hash_map.h>
112 #if OPENVDB_ABI_VERSION_NUMBER >= 7
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;
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>
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
345 std::vector<Index32> vec(DEPTH, 0);
346 mRoot.nodeCount( vec );
359 Index64 inactiveVoxelCount()
const override;
364 void evalMinMax(ValueType &
min, ValueType &
max)
const;
373 const ValueType& getValue(
const Coord& xyz)
const;
381 int getValueDepth(
const Coord& xyz)
const;
384 void setActiveState(
const Coord& xyz,
bool on);
388 void setValueOn(
const Coord& xyz);
395 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
397 void setValueOff(
const Coord& xyz);
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);
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>
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");
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();
1266 mRoot.readTopology(is, saveFloatAsHalf);
1270 template<
typename RootNodeType>
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>
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";
Functions to count tiles, nodes or voxels in a grid.
Internal table nodes for OpenVDB trees.
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
The root node of an OpenVDB tree.
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: openvdb/Types.h:447
const AValueType & a() const
Get the A input value.
Definition: openvdb/Types.h:486
const BValueType & b() const
Get the B input value.
Definition: openvdb/Types.h:488
const AValueType & result() const
Get the output value.
Definition: openvdb/Types.h:491
Definition: openvdb/Exceptions.h:61
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: openvdb/Types.h:560
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:249
Coord extents() const
Definition: Coord.h:382
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:356
void reset()
Definition: Coord.h:327
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:26
Int32 y() const
Definition: Coord.h:132
Int32 x() const
Definition: Coord.h:131
Int32 z() const
Definition: Coord.h:133
Definition: NodeManager.h:884
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels)
Definition: TreeIterator.h:1187
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:936
Base class for typed trees.
Definition: Tree.h:37
virtual Name valueType() const =0
Return the name of the type of a voxel's value (e.g., "float" or "vec3d").
virtual Index32 nonLeafCount() const =0
Return the number of non-leaf nodes.
virtual void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const
Write the tree topology to a stream.
Definition: Tree.h:1132
virtual ~TreeBase()=default
virtual Index64 activeLeafVoxelCount() const =0
Return the number of active voxels stored in leaf nodes.
virtual std::vector< Index32 > nodeCount() const =0
virtual void readBuffers(std::istream &, bool saveFloatAsHalf=false)=0
Read all data buffers for this tree.
virtual void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const =0
Write out all the data buffers for this tree.
virtual Metadata::Ptr getBackgroundValue() const
Return this tree's background value wrapped as metadata.
Definition: Tree.h:61
virtual const Name & type() const =0
Return the name of this tree's type.
TreeBase & operator=(const TreeBase &)=delete
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:1140
virtual void readBuffers(std::istream &, const CoordBBox &, bool saveFloatAsHalf=false)=0
Read all of this tree's data buffers that intersect the given bounding box.
virtual void getIndexRange(CoordBBox &bbox) const =0
virtual Index32 leafCount() const =0
Return the number of leaf nodes.
virtual Index32 unallocatedLeafCount() const =0
Return the total number of unallocated leaf nodes residing in this tree.
virtual Index64 activeVoxelCount() const =0
Return the total number of active voxels.
virtual Index64 inactiveVoxelCount() const =0
Return the number of inactive voxels within the bounding box of all active voxels.
virtual void clipUnallocatedNodes()=0
Replace with background tiles any nodes whose voxel buffers have not yet been allocated.
virtual void readNonresidentBuffers() const =0
Read all of this tree's data buffers that are not yet resident in memory (because delayed loading is ...
virtual Index64 inactiveLeafVoxelCount() const =0
Return the number of inactive voxels stored in leaf nodes.
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:132
virtual TreeBase::Ptr copy() const =0
Return a pointer to a deep copy of this tree.
SharedPtr< TreeBase > Ptr
Definition: Tree.h:39
virtual bool evalLeafDim(Coord &dim) const =0
Return in dim the dimensions of the axis-aligned bounding box of all leaf nodes.
virtual bool evalActiveVoxelBoundingBox(CoordBBox &bbox) const =0
Return in bbox the axis-aligned bounding box of all active voxels and tiles.
virtual Index treeDepth() const =0
Return the depth of this tree.
virtual Index64 activeTileCount() const =0
Return the total number of active tiles.
SharedPtr< const TreeBase > ConstPtr
Definition: Tree.h:40
virtual bool evalActiveVoxelDim(Coord &dim) const =0
Return in dim the dimensions of the axis-aligned bounding box of all active voxels....
virtual bool evalLeafBoundingBox(CoordBBox &bbox) const =0
Return in bbox the axis-aligned bounding box of all active tiles and leaf nodes with active values.
TreeBase(const TreeBase &)=default
virtual void readTopology(std::istream &, bool saveFloatAsHalf=false)
Read the tree topology from a stream.
Definition: Tree.h:1123
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:617
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:1437
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:1969
CIterT cbegin() const
Return a const iterator of type CIterT (for example, cbegin<ValueOnCIter>() is equivalent to cbeginVa...
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:649
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1080
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:449
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:205
RootNodeType::ChildOffCIter cbeginRootTiles() const
Definition: Tree.h:982
LeafCIter beginLeaf() const
Definition: Tree.h:1016
RootNodeType & root()
Return this tree's root node.
Definition: Tree.h:279
const ValueType & background() const
Return this tree's background value.
Definition: Tree.h:661
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition: Tree.h:1310
ValueOffCIter cbeginValueOff() const
Definition: Tree.h:1043
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:216
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition: Tree.h:1572
Index64 memUsage() const override
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:366
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1377
_RootNodeType RootNodeType
Definition: Tree.h:181
RootNodeType::ChildAllIter beginRootDense()
Definition: Tree.h:990
LeafCIter cbeginLeaf() const
Definition: Tree.h:1017
RootNodeType::ChildOffIter beginRootTiles()
Definition: Tree.h:983
bool operator!=(const Tree &) const
Definition: Tree.h:275
Tree()
Definition: Tree.h:200
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1079
RootNodeType mRoot
Definition: Tree.h:1078
ValueAllCIter cbeginValueAll() const
Definition: Tree.h:1031
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:506
static std::unique_ptr< const Name > sTreeTypeName
Definition: Tree.h:1082
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition: Tree.h:1564
LeafNodeType * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition: Tree.h:1556
RootNodeType::ChildOnIter beginRootChildren()
Definition: Tree.h:976
Tree & operator=(const Tree &)=delete
ValueOnCIter beginValueOn() const
Definition: Tree.h:1036
bool operator==(const Tree &) const
Definition: Tree.h:274
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:353
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1518
Index32 leafCount() const override
Return the number of leaf nodes.
Definition: Tree.h:338
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:1476
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:619
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Definition: Tree.h:357
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:355
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Definition: Tree.h:477
ValueOffCIter beginValueOff() const
Definition: Tree.h:1042
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:517
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:1537
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1526
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:1461
std::vector< Index32 > nodeCount() const override
Definition: Tree.h:343
typename RootNodeType::BuildType BuildType
Definition: Tree.h:183
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:1469
const ValueType & getValue(const Coord &xyz, AccessT &) const
Return the value of the voxel at the given coordinates and update the given accessor's node cache.
Index64 activeTileCount() const override
Return the total number of active tiles.
Definition: Tree.h:361
const Name & type() const override
Return the name of this type of tree.
Definition: Tree.h:272
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: Tree.h:1445
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1056
ValueOnCIter cbeginValueOn() const
Definition: Tree.h:1037
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition: Tree.h:264
typename RootNodeType::ValueType ValueType
Definition: Tree.h:182
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1420
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:637
NodeCIter beginNode() const
Definition: Tree.h:1009
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:1509
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:252
RootNodeType::ChildAllCIter cbeginRootDense() const
Definition: Tree.h:989
void getNodes(ArrayT &array) const
Definition: Tree.h:579
const LeafNodeType * probeLeaf(const Coord &xyz) const
Definition: Tree.h:552
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:608
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1318
RootNodeType::ChildOnCIter cbeginRootChildren() const
Definition: Tree.h:975
NodeCIter cbeginNode() const
Definition: Tree.h:1010
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition: Tree.h:664
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:184
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: Tree.h:1492
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:231
~Tree() override
Definition: Tree.h:261
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:453
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:259
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:451
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:606
Index32 nonLeafCount() const override
Return the number of non-leaf nodes.
Definition: Tree.h:351
Name valueType() const override
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
Definition: Tree.h:267
const RootNodeType & root() const
Definition: Tree.h:280
Index treeDepth() const override
Return the depth of this tree.
Definition: Tree.h:336
ValueAllCIter beginValueAll() const
Definition: Tree.h:1030
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1055
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:85
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:253
void print(const ast::Node &node, const bool numberStatements=true, std::ostream &os=std::cout, const char *indent=" ")
Writes a descriptive printout of a Node hierarchy into a target stream.
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition: Mat.h:1037
bool cwiseGreaterThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition: Mat.h:1051
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:118
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)
std::string Name
Definition: Name.h:17
Index32 Index
Definition: openvdb/Types.h:50
uint32_t Index32
Definition: openvdb/Types.h:48
uint64_t Index64
Definition: openvdb/Types.h:49
std::shared_ptr< T > SharedPtr
Definition: openvdb/Types.h:110
MergePolicy
Definition: openvdb/Types.h:384
@ MERGE_ACTIVE_STATES
Definition: openvdb/Types.h:385
@ MERGE_NODES
Definition: openvdb/Types.h:386
@ MERGE_ACTIVE_STATES_AND_NODES
Definition: openvdb/Types.h:387
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:140
Definition: openvdb/Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1739
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1742
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1740
CombineOp & op
Definition: Tree.h:1746
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition: Tree.h:1094
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal,...
Definition: Tree.h:1104
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal,...
Definition: Tree.h:1113
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1211
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1207
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1203
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1199
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1193
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1187
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1181
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1175
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1169
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1163
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1235
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1231
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1227
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1223
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1219
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1215
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1160
DeallocateNodes(std::vector< NodeType * > &nodes)
Definition: Tree.h:1065
NodeType **const mNodes
Definition: Tree.h:1072
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1067
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition: Tree.h:195
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178