Go to the documentation of this file.
6 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
21 #include <tbb/concurrent_hash_map.h>
111 #if OPENVDB_ABI_VERSION_NUMBER >= 7
112 virtual std::vector<Index32> nodeCount()
const = 0;
117 virtual Index32 nonLeafCount()
const = 0;
140 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
144 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
147 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
157 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
166 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
173 template<
typename _RootNodeType>
185 static const Index DEPTH = RootNodeType::LEVEL + 1;
193 template<
typename OtherValueType>
214 template<
typename OtherRootType>
229 template<
typename OtherTreeType>
230 Tree(
const OtherTreeType& other,
235 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
250 template<
typename OtherTreeType>
260 ~Tree()
override { this->clear(); releaseAllAccessors(); }
269 static const Name& treeType();
271 const Name&
type()
const override {
return this->treeType(); }
277 RootNodeType& root() {
return mRoot; }
288 template<
typename OtherRootNodeType>
291 bool evalLeafBoundingBox(
CoordBBox& bbox)
const override;
292 bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const override;
293 bool evalActiveVoxelDim(
Coord& dim)
const override;
294 bool evalLeafDim(
Coord& dim)
const override;
299 static void getNodeLog2Dims(std::vector<Index>& dims);
308 void readTopology(std::istream&,
bool saveFloatAsHalf =
false)
override;
312 void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
314 void readBuffers(std::istream&,
bool saveFloatAsHalf =
false)
override;
316 void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false)
override;
322 void readNonresidentBuffers()
const override;
324 void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
326 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const override;
338 #if OPENVDB_ABI_VERSION_NUMBER >= 7
339 std::vector<Index32> nodeCount()
const override
344 std::vector<Index32> vec(DEPTH, 0);
345 mRoot.nodeCount( vec );
349 Index32 nonLeafCount()
const override {
return mRoot.nonLeafCount(); }
358 Index64 inactiveVoxelCount()
const override;
363 void evalMinMax(ValueType &
min, ValueType &
max)
const;
372 const ValueType& getValue(
const Coord& xyz)
const;
380 int getValueDepth(
const Coord& xyz)
const;
383 void setActiveState(
const Coord& xyz,
bool on);
387 void setValueOn(
const Coord& xyz);
394 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
396 void setValueOff(
const Coord& xyz);
418 template<
typename ModifyOp>
419 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
440 template<
typename ModifyOp>
441 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
461 void clipUnallocatedNodes()
override;
464 Index32 unallocatedLeafCount()
const override;
467 void sparseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
478 this->sparseFill(bbox, value, active);
489 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
499 void voxelizeActiveTiles(
bool threaded =
true);
507 this->clearAllAccessors();
508 mRoot.prune(tolerance);
522 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
528 template<
typename NodeT>
529 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
536 LeafNodeType* touchLeaf(
const Coord& xyz);
539 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
542 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
543 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
547 LeafNodeType* probeLeaf(
const Coord& xyz);
550 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
555 template<
typename ArrayT>
void getNodes(ArrayT& array) { mRoot.getNodes(array); }
578 template<
typename ArrayT>
void getNodes(ArrayT& array)
const { mRoot.getNodes(array); }
604 template<
typename ArrayT>
605 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
606 template<
typename ArrayT>
609 this->clearAllAccessors();
610 mRoot.stealNodes(array, value, state);
618 bool empty()
const {
return mRoot.empty(); }
624 void clearAllAccessors();
687 template<
typename OtherRootNodeType>
703 template<
typename OtherRootNodeType>
716 template<
typename OtherRootNodeType>
763 template<
typename CombineOp>
766 template<
typename CombineOp>
808 template<
typename ExtendedCombineOp>
809 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
811 template<
typename ExtendedCombineOp>
812 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
843 template<
typename CombineOp,
typename OtherTreeType >
844 void combine2(
const Tree& a,
const OtherTreeType& b, CombineOp& op,
bool prune =
false);
846 template<
typename CombineOp,
typename OtherTreeType >
847 void combine2(
const Tree& a,
const OtherTreeType& b,
const CombineOp& op,
bool prune =
false);
923 template<
typename ExtendedCombineOp,
typename OtherTreeType >
924 void combine2Extended(
const Tree& a,
const OtherTreeType& b, ExtendedCombineOp& op,
927 template<
typename ExtendedCombineOp,
typename OtherTreeType >
928 void combine2Extended(
const Tree& a,
const OtherTreeType& b,
const ExtendedCombineOp&,
932 template<
typename BBoxOp>
933 [[deprecated(
"Use DynamicNodeManager instead")]]
936 template<
typename VisitorOp>
937 [[deprecated(
"Use DynamicNodeManager instead")]]
938 void visit(VisitorOp& op);
939 template<
typename VisitorOp>
940 [[deprecated(
"Use DynamicNodeManager instead")]]
941 void visit(
const VisitorOp& op);
943 template<
typename VisitorOp>
944 [[deprecated(
"Use DynamicNodeManager instead")]]
945 void visit(VisitorOp& op)
const;
946 template<
typename VisitorOp>
947 [[deprecated(
"Use DynamicNodeManager instead")]]
948 void visit(
const VisitorOp& op)
const;
950 template<
typename OtherTreeType,
typename VisitorOp>
951 [[deprecated(
"Use DynamicNodeManager instead")]]
952 void visit2(OtherTreeType& other, VisitorOp& op);
953 template<
typename OtherTreeType,
typename VisitorOp>
954 [[deprecated(
"Use DynamicNodeManager instead")]]
955 void visit2(OtherTreeType& other,
const VisitorOp& op);
957 template<
typename OtherTreeType,
typename VisitorOp>
958 [[deprecated(
"Use DynamicNodeManager instead")]]
959 void visit2(OtherTreeType& other, VisitorOp& op)
const;
960 template<
typename OtherTreeType,
typename VisitorOp>
961 [[deprecated(
"Use DynamicNodeManager instead")]]
962 void visit2(OtherTreeType& other,
const VisitorOp& op)
const;
969 typename RootNodeType::ChildOnCIter beginRootChildren()
const {
return mRoot.cbeginChildOn(); }
976 typename RootNodeType::ChildOffCIter beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
978 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
979 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
983 typename RootNodeType::ChildAllCIter beginRootDense()
const {
return mRoot.cbeginChildAll(); }
985 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
986 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1010 LeafIter beginLeaf() {
return LeafIter(*
this); }
1030 ValueOnIter beginValueOn() {
return ValueOnIter(*
this); }
1036 ValueOffIter beginValueOff() {
return ValueOffIter(*
this); }
1044 template<
typename IterT> IterT begin();
1047 template<
typename CIterT> CIterT
cbegin()
const;
1056 void releaseAllAccessors();
1059 template<
typename NodeType>
1062 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1064 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
1065 delete mNodes[n]; mNodes[n] =
nullptr;
1081 template<
typename _RootNodeType>
1089 template<
typename T, Index N1=4, Index N2=3>
1099 template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1108 template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1121 int32_t bufferCount;
1122 is.read(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1123 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1130 int32_t bufferCount = 1;
1131 os.write(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1138 os <<
" Tree Type: " << type()
1139 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1140 <<
" Active tile Count: " << activeTileCount() << std::endl
1141 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1142 <<
" Leaf Node Count: " << leafCount() << std::endl
1143 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1158 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1159 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1160 return tree.beginRootChildren();
1164 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1165 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1166 return tree.cbeginRootChildren();
1170 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1171 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1172 return tree.beginRootTiles();
1176 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1177 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1178 return tree.cbeginRootTiles();
1182 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1183 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1184 return tree.beginRootDense();
1188 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1189 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1190 return tree.cbeginRootDense();
1195 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1199 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1203 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1207 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1211 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1214 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1215 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1218 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1219 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1222 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1223 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1226 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1227 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1230 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1231 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1235 template<
typename RootNodeType>
1236 template<
typename IterT>
1244 template<
typename RootNodeType>
1245 template<
typename IterT>
1256 template<
typename RootNodeType>
1260 this->clearAllAccessors();
1262 mRoot.readTopology(is, saveFloatAsHalf);
1266 template<
typename RootNodeType>
1271 mRoot.writeTopology(os, saveFloatAsHalf);
1275 template<
typename RootNodeType>
1279 this->clearAllAccessors();
1280 mRoot.readBuffers(is, saveFloatAsHalf);
1284 template<
typename RootNodeType>
1288 this->clearAllAccessors();
1289 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1293 template<
typename RootNodeType>
1297 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1304 template<
typename RootNodeType>
1312 template<
typename RootNodeType>
1316 std::vector<LeafNodeType*> leafnodes;
1317 this->stealNodes(leafnodes);
1319 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1322 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1323 this->stealNodes(internalNodes);
1325 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1330 this->clearAllAccessors();
1337 template<
typename RootNodeType>
1341 typename AccessorRegistry::accessor a;
1342 mAccessorRegistry.insert(a, &accessor);
1346 template<
typename RootNodeType>
1350 typename ConstAccessorRegistry::accessor a;
1351 mConstAccessorRegistry.insert(a, &accessor);
1355 template<
typename RootNodeType>
1359 mAccessorRegistry.erase(&accessor);
1363 template<
typename RootNodeType>
1367 mConstAccessorRegistry.erase(&accessor);
1371 template<
typename RootNodeType>
1375 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1376 it != mAccessorRegistry.end(); ++it)
1378 if (it->first) it->first->
clear();
1381 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1382 it != mConstAccessorRegistry.end(); ++it)
1384 if (it->first) it->first->clear();
1389 template<
typename RootNodeType>
1393 mAccessorRegistry.erase(
nullptr);
1394 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1395 it != mAccessorRegistry.end(); ++it)
1397 it->first->release();
1399 mAccessorRegistry.
clear();
1401 mAccessorRegistry.erase(
nullptr);
1402 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1403 it != mConstAccessorRegistry.end(); ++it)
1405 it->first->release();
1407 mConstAccessorRegistry.clear();
1414 template<
typename RootNodeType>
1415 inline const typename RootNodeType::ValueType&
1422 template<
typename RootNodeType>
1423 template<
typename AccessT>
1424 inline const typename RootNodeType::ValueType&
1431 template<
typename RootNodeType>
1439 template<
typename RootNodeType>
1447 template<
typename RootNodeType>
1455 template<
typename RootNodeType>
1463 template<
typename RootNodeType>
1470 template<
typename RootNodeType>
1477 template<
typename RootNodeType>
1478 template<
typename AccessT>
1486 template<
typename RootNodeType>
1494 template<
typename RootNodeType>
1502 template<
typename RootNodeType>
1503 template<
typename ModifyOp>
1511 template<
typename RootNodeType>
1512 template<
typename ModifyOp>
1520 template<
typename RootNodeType>
1531 template<
typename RootNodeType>
1536 mRoot.
addTile(level, xyz, value, active);
1540 template<
typename RootNodeType>
1541 template<
typename NodeT>
1545 this->clearAllAccessors();
1546 return mRoot.template stealNode<NodeT>(xyz, value, active);
1550 template<
typename RootNodeType>
1551 inline typename RootNodeType::LeafNodeType*
1558 template<
typename RootNodeType>
1559 inline typename RootNodeType::LeafNodeType*
1566 template<
typename RootNodeType>
1567 inline const typename RootNodeType::LeafNodeType*
1574 template<
typename RootNodeType>
1575 template<
typename NodeType>
1579 return mRoot.template probeNode<NodeType>(xyz);
1583 template<
typename RootNodeType>
1584 template<
typename NodeType>
1585 inline const NodeType*
1588 return this->
template probeConstNode<NodeType>(xyz);
1592 template<
typename RootNodeType>
1593 template<
typename NodeType>
1594 inline const NodeType*
1597 return mRoot.template probeConstNode<NodeType>(xyz);
1604 template<
typename RootNodeType>
1608 this->clearAllAccessors();
1609 return mRoot.clip(bbox);
1613 template<
typename RootNodeType>
1617 this->clearAllAccessors();
1618 for (
LeafIter it = this->beginLeaf(); it; ) {
1621 if (!leaf->isAllocated()) {
1622 this->addTile(0, leaf->origin(), this->background(),
false);
1627 template<
typename RootNodeType>
1632 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1637 template<
typename RootNodeType>
1641 this->clearAllAccessors();
1642 return mRoot.sparseFill(bbox, value, active);
1646 template<
typename RootNodeType>
1650 this->clearAllAccessors();
1651 return mRoot.denseFill(bbox, value, active);
1655 template<
typename RootNodeType>
1659 this->clearAllAccessors();
1660 mRoot.voxelizeActiveTiles(threaded);
1664 template<
typename RootNodeType>
1672 if (result->typeName() == MetadataT::staticTypeName()) {
1673 MetadataT* m =
static_cast<MetadataT*
>(result.get());
1674 m->value() = mRoot.background();
1684 template<
typename RootNodeType>
1688 this->clearAllAccessors();
1692 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1694 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1696 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1701 template<
typename RootNodeType>
1702 template<
typename OtherRootNodeType>
1706 this->clearAllAccessors();
1707 mRoot.topologyUnion(other.
root());
1710 template<
typename RootNodeType>
1711 template<
typename OtherRootNodeType>
1715 this->clearAllAccessors();
1716 mRoot.topologyIntersection(other.
root());
1719 template<
typename RootNodeType>
1720 template<
typename OtherRootNodeType>
1724 this->clearAllAccessors();
1725 mRoot.topologyDifference(other.
root());
1733 template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1739 op(args.
a(), args.
b(), args.
result());
1746 template<
typename RootNodeType>
1747 template<
typename CombineOp>
1752 this->combineExtended(other, extendedOp,
prune);
1759 template<
typename RootNodeType>
1760 template<
typename CombineOp>
1765 this->combineExtended(other, extendedOp,
prune);
1770 template<
typename RootNodeType>
1771 template<
typename ExtendedCombineOp>
1775 this->clearAllAccessors();
1783 template<
typename RootNodeType>
1784 template<
typename ExtendedCombineOp>
1788 this->clearAllAccessors();
1789 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op,
prune);
1794 template<
typename RootNodeType>
1795 template<
typename CombineOp,
typename OtherTreeType>
1800 this->combine2Extended(a, b, extendedOp,
prune);
1807 template<
typename RootNodeType>
1808 template<
typename CombineOp,
typename OtherTreeType>
1813 this->combine2Extended(a, b, extendedOp,
prune);
1818 template<
typename RootNodeType>
1819 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1822 ExtendedCombineOp& op,
bool prune)
1824 this->clearAllAccessors();
1825 mRoot.combine2(a.
root(), b.root(), op,
prune);
1833 template<
typename RootNodeType>
1834 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1837 const ExtendedCombineOp& op,
bool prune)
1839 this->clearAllAccessors();
1840 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op,
prune);
1848 template<
typename RootNodeType>
1849 template<
typename VisitorOp>
1853 this->clearAllAccessors();
1854 mRoot.template visit<VisitorOp>(op);
1858 template<
typename RootNodeType>
1859 template<
typename VisitorOp>
1863 mRoot.template visit<VisitorOp>(op);
1869 template<
typename RootNodeType>
1870 template<
typename VisitorOp>
1874 this->clearAllAccessors();
1875 mRoot.template visit<const VisitorOp>(op);
1881 template<
typename RootNodeType>
1882 template<
typename VisitorOp>
1886 mRoot.template visit<const VisitorOp>(op);
1893 template<
typename RootNodeType>
1894 template<
typename OtherTreeType,
typename VisitorOp>
1898 this->clearAllAccessors();
1899 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
1900 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
1904 template<
typename RootNodeType>
1905 template<
typename OtherTreeType,
typename VisitorOp>
1909 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
1910 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
1916 template<
typename RootNodeType>
1917 template<
typename OtherTreeType,
typename VisitorOp>
1921 this->clearAllAccessors();
1922 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
1923 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
1929 template<
typename RootNodeType>
1930 template<
typename OtherTreeType,
typename VisitorOp>
1934 using OtherRootNodeType =
typename OtherTreeType::RootNodeType;
1935 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
1942 template<
typename RootNodeType>
1946 static std::once_flag once;
1947 std::call_once(once, []()
1949 std::vector<Index> dims;
1950 Tree::getNodeLog2Dims(dims);
1951 std::ostringstream ostr;
1952 ostr <<
"Tree_" << typeNameAsString<BuildType>();
1953 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
1954 ostr <<
"_" << dims[i];
1956 sTreeTypeName.reset(
new Name(ostr.str()));
1958 return *sTreeTypeName;
1962 template<
typename RootNodeType>
1963 template<
typename OtherRootNodeType>
1971 template<
typename RootNodeType>
1976 this->evalActiveVoxelDim(dim);
1978 totalVoxels = dim.
x() * dim.
y() * dim.
z(),
1979 activeVoxels = this->activeVoxelCount();
1980 assert(totalVoxels >= activeVoxels);
1981 return totalVoxels - activeVoxels;
1985 template<
typename RootNodeType>
1991 if (this->empty())
return false;
1993 mRoot.evalActiveBoundingBox(bbox,
false);
1995 return !bbox.
empty();
1998 template<
typename RootNodeType>
2004 if (this->empty())
return false;
2006 mRoot.evalActiveBoundingBox(bbox,
true);
2008 return !bbox.
empty();
2012 template<
typename RootNodeType>
2017 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2023 template<
typename RootNodeType>
2028 bool notEmpty = this->evalLeafBoundingBox(bbox);
2034 template<
typename RootNodeType>
2039 minVal = maxVal = zeroVal<ValueType>();
2041 minVal = maxVal = *iter;
2042 for (++iter; iter; ++iter) {
2051 template<
typename RootNodeType>
2056 RootNodeType::getNodeLog2Dims(dims);
2060 template<
typename RootNodeType>
2064 if (verboseLevel <= 0)
return;
2069 std::streamsize savedPrecision;
2070 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2071 ~OnExit() { os.precision(savedPrecision); }
2073 OnExit restorePrecision(os);
2075 std::vector<Index> dims;
2076 Tree::getNodeLog2Dims(dims);
2078 os <<
"Information about Tree:\n"
2079 <<
" Type: " << this->type() <<
"\n";
2081 os <<
" Configuration:\n";
2083 if (verboseLevel <= 1) {
2085 os <<
" Root(" << mRoot.getTableSize() <<
")";
2086 if (dims.size() > 1) {
2087 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2088 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
2090 os <<
", Leaf(" << (1 << dims.back()) <<
"^3)\n";
2092 os <<
" Background value: " << mRoot.background() <<
"\n";
2098 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2099 if (verboseLevel > 3) {
2101 this->evalMinMax(minVal, maxVal);
2104 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2105 const auto nodeCount = this->nodeCount();
2106 const Index32 leafCount = nodeCount.front();
2108 std::vector<Index64> nodeCount(dims.size());
2109 for (
NodeCIter it = cbeginNode(); it; ++it) ++(nodeCount[it.getDepth()]);
2110 const Index64 leafCount = *nodeCount.rbegin();
2112 assert(dims.size() == nodeCount.size());
2115 for (
size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2118 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
2119 if (dims.size() >= 2) {
2120 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2121 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2126 os <<
" x " << (1 << dims[i]) <<
"^3)";
2129 os <<
" x " << (1 << dims.back()) <<
"^3)\n";
2131 os <<
" Background value: " << mRoot.background() <<
"\n";
2135 if (verboseLevel > 3) {
2136 os <<
" Min value: " << minVal <<
"\n";
2137 os <<
" Max value: " << maxVal <<
"\n";
2141 numActiveVoxels = this->activeVoxelCount(),
2142 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2143 numActiveTiles = this->activeTileCount();
2150 if (numActiveVoxels) {
2152 this->evalActiveVoxelBoundingBox(bbox);
2154 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
2156 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
2157 os <<
" Dimensions of active voxels: "
2158 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
2160 const double activeRatio = (100.0 * double(numActiveVoxels)) /
double(totalVoxels);
2161 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
2163 if (leafCount > 0) {
2164 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2165 / (
double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2166 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
2169 if (verboseLevel > 2) {
2171 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
2172 os <<
" Number of unallocated nodes: "
2174 << (100.0 * double(sum) / double(totalNodeCount)) <<
"%)\n";
2177 os <<
" Tree is empty!\n";
2181 if (verboseLevel == 2)
return;
2185 actualMem = this->memUsage(),
2186 denseMem =
sizeof(
ValueType) * totalVoxels,
2187 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
2190 os <<
"Memory footprint:\n";
2194 if (numActiveVoxels) {
2196 os <<
" Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2197 <<
"% of an equivalent dense volume\n";
2198 os <<
" Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2199 <<
"% of actual footprint\n";
2207 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
virtual bool evalActiveVoxelDim(Coord &dim) const =0
Return in dim the dimensions of the axis-aligned bounding box of all active voxels....
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:118
Index32 leafCount() const override
Return the number of leaf nodes.
Definition: Tree.h:337
void getNodes(ArrayT &array) const
Definition: Tree.h:578
NodeCIter cbeginNode() const
Definition: Tree.h:1006
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition: Tree.h:1306
virtual Index64 activeTileCount() const =0
Return the total number of active tiles.
The root node of an OpenVDB tree.
virtual Index64 inactiveVoxelCount() const =0
Return the number of inactive voxels within the bounding box of all active voxels.
ValueOnCIter beginValueOn() const
Definition: Tree.h:1032
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1227
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.
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:26
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1165
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1183
~Tree() override
Definition: Tree.h:260
virtual Metadata::Ptr getBackgroundValue() const
Return this tree's background value wrapped as metadata.
Definition: Tree.h:60
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:1533
virtual Index treeDepth() const =0
Return the depth of this tree.
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1416
SharedPtr< const TreeBase > ConstPtr
Definition: Tree.h:39
Tree & operator=(const Tree &)=delete
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:258
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:1433
Name valueType() const override
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
Definition: Tree.h:266
virtual Index32 unallocatedLeafCount() const =0
Return the total number of unallocated leaf nodes residing in this tree.
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1156
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1736
virtual Name valueType() const =0
Return the name of the type of a voxel's value (e.g., "float" or "vec3d").
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:204
Definition: openvdb/Exceptions.h:61
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:1560
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1171
virtual bool evalActiveVoxelBoundingBox(CoordBBox &bbox) const =0
Return in bbox the axis-aligned bounding box of all active voxels and tiles.
TreeBase(const TreeBase &)=default
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1076
virtual void readNonresidentBuffers() const =0
Read all of this tree's data buffers that are not yet resident in memory (because delayed loading is ...
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1223
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal,...
Definition: Tree.h:1100
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:1136
bool cwiseGreaterThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition: Mat.h:1044
Index64 memUsage() const override
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:365
RootNodeType::ChildOffIter beginRootTiles()
Definition: Tree.h:979
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 attachAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:636
Int32 y() const
Definition: Coord.h:132
RootNodeType::ChildOnIter beginRootChildren()
Definition: Tree.h:972
NodeType **const mNodes
Definition: Tree.h:1068
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: Tree.h:1441
SharedPtr< TreeBase > Ptr
Definition: Tree.h:38
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels)
Definition: TreeIterator.h:1187
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Definition: Tree.h:476
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:82
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:249
std::string Name
Definition: Name.h:17
ValueOnCIter cbeginValueOn() const
Definition: Tree.h:1033
virtual void getIndexRange(CoordBBox &bbox) const =0
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1199
virtual ~TreeBase()=default
@ MERGE_NODES
Definition: openvdb/Types.h:368
Int32 x() const
Definition: Coord.h:131
ValueAllCIter beginValueAll() const
Definition: Tree.h:1026
bool operator==(const Tree &) const
Definition: Tree.h:273
uint32_t Index32
Definition: openvdb/Types.h:30
const LeafNodeType * probeLeaf(const Coord &xyz) const
Definition: Tree.h:551
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1177
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:448
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1211
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition: Tree.h:263
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1219
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:85
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:936
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:183
void reset()
Definition: Coord.h:327
const RootNodeType & root() const
Definition: Tree.h:279
uint64_t Index64
Definition: openvdb/Types.h:31
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:140
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1195
TreeBase & operator=(const TreeBase &)=delete
const Name & type() const override
Return the name of this type of tree.
Definition: Tree.h:271
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Definition: Tree.h:356
RootNodeType::ChildOnCIter cbeginRootChildren() const
Definition: Tree.h:971
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition: Tree.h:663
ValueOffCIter beginValueOff() const
Definition: Tree.h:1038
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1189
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:516
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:356
Index64 activeTileCount() const override
Return the total number of active tiles.
Definition: Tree.h:360
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1522
const AValueType & result() const
Get the output value.
Definition: openvdb/Types.h:473
@ MERGE_ACTIVE_STATES_AND_NODES
Definition: openvdb/Types.h:369
virtual const Name & type() const =0
Return the name of this tree's type.
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:452
virtual Index32 leafCount() const =0
Return the number of leaf nodes.
Internal table nodes for OpenVDB trees.
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal,...
Definition: Tree.h:1109
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:1552
Index treeDepth() const override
Return the depth of this tree.
Definition: Tree.h:335
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1063
NodeCIter beginNode() const
Definition: Tree.h:1005
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:648
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition: Tree.h:1568
RootNodeType::ChildAllCIter cbeginRootDense() const
Definition: Tree.h:985
Int32 z() const
Definition: Coord.h:133
CombineOp & op
Definition: Tree.h:1742
ValueOffCIter cbeginValueOff() const
Definition: Tree.h:1039
virtual void clipUnallocatedNodes()=0
Replace with background tiles any nodes whose voxel buffers have not yet been allocated.
static std::unique_ptr< const Name > sTreeTypeName
Definition: Tree.h:1078
const ValueType & background() const
Return this tree's background value.
Definition: Tree.h:660
RootNodeType::ChildOffCIter cbeginRootTiles() const
Definition: Tree.h:978
virtual bool evalLeafDim(Coord &dim) const =0
Return in dim the dimensions of the axis-aligned bounding box of all leaf nodes.
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.
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:605
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1052
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1735
virtual Index64 activeVoxelCount() const =0
Return the total number of active voxels.
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:147
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1159
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1207
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:354
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: openvdb/Types.h:429
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:215
virtual void readTopology(std::istream &, bool saveFloatAsHalf=false)
Read the tree topology from a stream.
Definition: Tree.h:1119
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:1505
LeafCIter cbeginLeaf() const
Definition: Tree.h:1013
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:251
virtual Index64 inactiveLeafVoxelCount() const =0
Return the number of inactive voxels stored in leaf nodes.
virtual void readBuffers(std::istream &, bool saveFloatAsHalf=false)=0
Read all data buffers for this tree.
Coord extents() const
Definition: Coord.h:382
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:618
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition: Tree.h:194
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:607
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: Tree.h:1488
bool operator!=(const Tree &) const
Definition: Tree.h:274
virtual Index64 activeLeafVoxelCount() const =0
Return the number of active voxels stored in leaf nodes.
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: openvdb/Types.h:542
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:617
RootNodeType & root()
Return this tree's root node.
Definition: Tree.h:278
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:450
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1738
CIterT cbegin() const
Return a const iterator of type CIterT (for example, cbegin<ValueOnCIter>() is equivalent to cbeginVa...
LeafCIter beginLeaf() const
Definition: Tree.h:1012
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:95
MergePolicy
Definition: openvdb/Types.h:366
void visitActiveBBox(BBoxOp &op) const
Definition: Tree.h:934
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1051
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition: Mat.h:1030
@ MERGE_ACTIVE_STATES
Definition: openvdb/Types.h:367
typename RootNodeType::ValueType ValueType
Definition: Tree.h:181
DeallocateNodes(std::vector< NodeType * > &nodes)
Definition: Tree.h:1061
_RootNodeType RootNodeType
Definition: Tree.h:180
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1075
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:1965
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1314
RootNodeType::ChildAllIter beginRootDense()
Definition: Tree.h:986
const AValueType & a() const
Get the A input value.
Definition: openvdb/Types.h:468
std::shared_ptr< T > SharedPtr
Definition: openvdb/Types.h:92
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1215
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:352
Definition: openvdb/Exceptions.h:13
virtual TreeBase::Ptr copy() const =0
Return a pointer to a deep copy of this tree.
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:230
Tree()
Definition: Tree.h:199
RootNodeType mRoot
Definition: Tree.h:1074
const BValueType & b() const
Get the B input value.
Definition: openvdb/Types.h:470
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1514
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:131
typename RootNodeType::BuildType BuildType
Definition: Tree.h:182
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:505
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:1465
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:1472
Index32 Index
Definition: openvdb/Types.h:32
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:1457
virtual void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const
Write the tree topology to a stream.
Definition: Tree.h:1128
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1231
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1373
virtual void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const =0
Write out all the data buffers for this tree.
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.
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition: Tree.h:1090
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.
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1203
Base class for typed trees.
Definition: Tree.h:36
ValueAllCIter cbeginValueAll() const
Definition: Tree.h:1027
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:253