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
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
344 std::vector<Index32> vec(DEPTH, 0);
345 mRoot.nodeCount( vec );
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";
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:429
const AValueType & a() const
Get the A input value.
Definition: openvdb/Types.h:468
const BValueType & b() const
Get the B input value.
Definition: openvdb/Types.h:470
const AValueType & result() const
Get the output value.
Definition: openvdb/Types.h:473
Definition: openvdb/Exceptions.h:61
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: openvdb/Types.h:542
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
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:36
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:1128
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:60
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:1136
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:131
virtual TreeBase::Ptr copy() const =0
Return a pointer to a deep copy of this tree.
SharedPtr< TreeBase > Ptr
Definition: Tree.h:38
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:39
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:1119
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:1433
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
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:648
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1076
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:448
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:204
RootNodeType::ChildOffCIter cbeginRootTiles() const
Definition: Tree.h:978
LeafCIter beginLeaf() const
Definition: Tree.h:1012
RootNodeType & root()
Return this tree's root node.
Definition: Tree.h:278
const ValueType & background() const
Return this tree's background value.
Definition: Tree.h:660
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition: Tree.h:1306
ValueOffCIter cbeginValueOff() const
Definition: Tree.h:1039
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:215
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition: Tree.h:1568
Index64 memUsage() const override
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:365
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1373
_RootNodeType RootNodeType
Definition: Tree.h:180
RootNodeType::ChildAllIter beginRootDense()
Definition: Tree.h:986
LeafCIter cbeginLeaf() const
Definition: Tree.h:1013
RootNodeType::ChildOffIter beginRootTiles()
Definition: Tree.h:979
bool operator!=(const Tree &) const
Definition: Tree.h:274
Tree()
Definition: Tree.h:199
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1075
RootNodeType mRoot
Definition: Tree.h:1074
ValueAllCIter cbeginValueAll() const
Definition: Tree.h:1027
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
static std::unique_ptr< const Name > sTreeTypeName
Definition: Tree.h:1078
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
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
RootNodeType::ChildOnIter beginRootChildren()
Definition: Tree.h:972
Tree & operator=(const Tree &)=delete
ValueOnCIter beginValueOn() const
Definition: Tree.h:1032
bool operator==(const Tree &) const
Definition: Tree.h:273
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:352
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1514
Index32 leafCount() const override
Return the number of leaf nodes.
Definition: Tree.h:337
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
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
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Definition: Tree.h:356
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:354
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Definition: Tree.h:476
ValueOffCIter beginValueOff() const
Definition: Tree.h:1038
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
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
void visitActiveBBox(BBoxOp &op) const
Definition: Tree.h:934
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1522
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
std::vector< Index32 > nodeCount() const override
Definition: Tree.h:342
typename RootNodeType::BuildType BuildType
Definition: Tree.h:182
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
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:360
const Name & type() const override
Return the name of this type of tree.
Definition: Tree.h:271
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: Tree.h:1441
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1052
ValueOnCIter cbeginValueOn() const
Definition: Tree.h:1033
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition: Tree.h:263
typename RootNodeType::ValueType ValueType
Definition: Tree.h:181
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1416
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:636
NodeCIter beginNode() const
Definition: Tree.h:1005
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
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:251
RootNodeType::ChildAllCIter cbeginRootDense() const
Definition: Tree.h:985
void getNodes(ArrayT &array) const
Definition: Tree.h:578
const LeafNodeType * probeLeaf(const Coord &xyz) const
Definition: Tree.h:551
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:607
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1314
RootNodeType::ChildOnCIter cbeginRootChildren() const
Definition: Tree.h:971
NodeCIter cbeginNode() const
Definition: Tree.h:1006
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition: Tree.h:663
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:183
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: Tree.h:1488
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() override
Definition: Tree.h:260
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:452
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:258
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:450
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
Index32 nonLeafCount() const override
Return the number of non-leaf nodes.
Definition: Tree.h:350
Name valueType() const override
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
Definition: Tree.h:266
const RootNodeType & root() const
Definition: Tree.h:279
Index treeDepth() const override
Return the depth of this tree.
Definition: Tree.h:335
ValueAllCIter beginValueAll() const
Definition: Tree.h:1026
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1051
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:32
uint32_t Index32
Definition: openvdb/Types.h:30
uint64_t Index64
Definition: openvdb/Types.h:31
std::shared_ptr< T > SharedPtr
Definition: openvdb/Types.h:92
MergePolicy
Definition: openvdb/Types.h:366
@ MERGE_ACTIVE_STATES
Definition: openvdb/Types.h:367
@ MERGE_NODES
Definition: openvdb/Types.h:368
@ MERGE_ACTIVE_STATES_AND_NODES
Definition: openvdb/Types.h:369
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:1735
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1738
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1736
CombineOp & op
Definition: Tree.h:1742
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
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal,...
Definition: Tree.h:1100
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal,...
Definition: Tree.h:1109
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1207
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1203
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1199
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1195
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1189
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1183
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1177
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1171
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1165
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1159
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1231
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1227
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1223
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1219
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1215
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1211
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1156
DeallocateNodes(std::vector< NodeType * > &nodes)
Definition: Tree.h:1061
NodeType **const mNodes
Definition: Tree.h:1068
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1063
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition: Tree.h:194
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:101
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:153