6#ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7#define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
22#include <tbb/concurrent_hash_map.h>
54 template<
typename TreeType>
55 bool isType()
const {
return (this->type() == TreeType::treeType()); }
143 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
147 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
150 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
160 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
169 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
176template<
typename _RootNodeType>
188 static const Index DEPTH = RootNodeType::LEVEL + 1;
196 template<
typename OtherValueType>
217 template<
typename OtherRootType>
232 template<
typename OtherTreeType>
233 Tree(
const OtherTreeType& other,
238 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
253 template<
typename OtherTreeType>
263 ~Tree()
override { this->clear(); releaseAllAccessors(); }
272 static const Name& treeType();
274 const Name&
type()
const override {
return this->treeType(); }
291 template<
typename OtherRootNodeType>
294 bool evalLeafBoundingBox(
CoordBBox& bbox)
const override;
295 bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const override;
296 bool evalActiveVoxelDim(
Coord& dim)
const override;
297 bool evalLeafDim(
Coord& dim)
const override;
302 static void getNodeLog2Dims(std::vector<Index>& dims);
311 void readTopology(std::istream&,
bool saveFloatAsHalf =
false)
override;
315 void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
317 void readBuffers(std::istream&,
bool saveFloatAsHalf =
false)
override;
319 void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false)
override;
325 void readNonresidentBuffers()
const override;
327 void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const override;
329 void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const override;
346 std::vector<Index32> vec(DEPTH, 0);
347 mRoot.nodeCount( vec );
365 void evalMinMax(ValueType &min, ValueType &max) const;
367 Index64 memUsage()
const override {
return tools::memUsage(*
this); }
374 const ValueType& getValue(
const Coord& xyz)
const;
382 int getValueDepth(
const Coord& xyz)
const;
385 void setActiveState(
const Coord& xyz,
bool on);
389 void setValueOn(
const Coord& xyz);
396 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
398 void setValueOff(
const Coord& xyz);
420 template<
typename ModifyOp>
421 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
442 template<
typename ModifyOp>
443 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
463 void clipUnallocatedNodes()
override;
466 Index32 unallocatedLeafCount()
const override;
477 void sparseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
480 this->sparseFill(bbox, value, active);
491 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
501 void voxelizeActiveTiles(
bool threaded =
true);
509 this->clearAllAccessors();
510 mRoot.prune(tolerance);
524 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
530 template<
typename NodeT>
531 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
538 LeafNodeType* touchLeaf(
const Coord& xyz);
543 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
544 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
545 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
551 LeafNodeType* probeLeaf(
const Coord& xyz);
552 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
579 template<
typename ArrayT>
void getNodes(ArrayT& array);
580 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
606 template<
typename ArrayT>
607 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
608 template<
typename ArrayT>
611 this->clearAllAccessors();
612 mRoot.stealNodes(array, value, state);
620 bool empty()
const {
return mRoot.empty(); }
626 void clearAllAccessors();
692 template<
typename OtherRootNodeType>
708 template<
typename OtherRootNodeType>
721 template<
typename OtherRootNodeType>
768 template<
typename CombineOp>
769 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
770 template<
typename CombineOp>
771 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
811 template<
typename ExtendedCombineOp>
812 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
813 template<
typename ExtendedCombineOp>
814 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
844 template<
typename CombineOp,
typename OtherTreeType >
845 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);
922 template<
typename ExtendedCombineOp,
typename OtherTreeType >
923 void combine2Extended(
const Tree& a,
const OtherTreeType& b, ExtendedCombineOp& op,
925 template<
typename ExtendedCombineOp,
typename OtherTreeType >
926 void combine2Extended(
const Tree& a,
const OtherTreeType& b,
const ExtendedCombineOp&,
941 typename RootNodeType::ChildOffCIter
beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
942 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
943 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
948 typename RootNodeType::ChildAllCIter
beginRootDense()
const {
return mRoot.cbeginChildAll(); }
949 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
950 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1008 template<
typename IterT> IterT begin();
1011 template<
typename CIterT> CIterT
cbegin()
const;
1020 void releaseAllAccessors();
1023 template<
typename NodeType>
1026 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1028 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
1029 delete mNodes[n]; mNodes[n] =
nullptr;
1048template<
typename T, Index N1=4, Index N2=3>
1058template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1067template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1078TreeBase::readTopology(std::istream& is,
bool )
1080 int32_t bufferCount;
1081 is.read(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1082 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1087TreeBase::writeTopology(std::ostream& os,
bool )
const
1089 int32_t bufferCount = 1;
1090 os.write(
reinterpret_cast<char*
>(&bufferCount),
sizeof(int32_t));
1095TreeBase::print(std::ostream& os,
int )
const
1097 os <<
" Tree Type: " << type()
1098 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1099 <<
" Active tile Count: " << activeTileCount() << std::endl
1100 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1101 <<
" Leaf Node Count: " << leafCount() << std::endl
1102 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1117template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1118 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1119 return tree.beginRootChildren();
1123template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1124 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1125 return tree.cbeginRootChildren();
1129template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1130 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1131 return tree.beginRootTiles();
1135template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1136 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1137 return tree.cbeginRootTiles();
1141template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1142 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1143 return tree.beginRootDense();
1147template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1148 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1149 return tree.cbeginRootDense();
1154 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1158 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1162 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1166 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1170 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1174 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1178 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1181template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1182 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1186 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1189template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1190 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1194template<
typename RootNodeType>
1195template<
typename IterT>
1203template<
typename RootNodeType>
1204template<
typename IterT>
1215template<
typename RootNodeType>
1219 this->clearAllAccessors();
1220 TreeBase::readTopology(is, saveFloatAsHalf);
1221 mRoot.readTopology(is, saveFloatAsHalf);
1225template<
typename RootNodeType>
1229 TreeBase::writeTopology(os, saveFloatAsHalf);
1230 mRoot.writeTopology(os, saveFloatAsHalf);
1234template<
typename RootNodeType>
1238 this->clearAllAccessors();
1239 mRoot.readBuffers(is, saveFloatAsHalf);
1243template<
typename RootNodeType>
1247 this->clearAllAccessors();
1248 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1252template<
typename RootNodeType>
1256 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1258 it->getValue(
Index(0));
1263template<
typename RootNodeType>
1271template<
typename RootNodeType>
1272template<
typename ArrayT>
1276 using NodeT =
typename std::remove_pointer<typename ArrayT::value_type>::type;
1277 static_assert(!std::is_same<NodeT, RootNodeType>::value,
1278 "getNodes() does not work for the RootNode. Use Tree::root()");
1283template<
typename RootNodeType>
1284template<
typename ArrayT>
1288 using NodeT =
typename std::remove_pointer<typename ArrayT::value_type>::type;
1289 static_assert(!std::is_same<NodeT, const RootNodeType>::value,
1290 "getNodes() does not work for the RootNode. Use Tree::root()");
1295template<
typename RootNodeType>
1299 std::vector<LeafNodeType*> leafnodes;
1300 this->stealNodes(leafnodes);
1302 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1305 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1306 this->stealNodes(internalNodes);
1308 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1313 this->clearAllAccessors();
1320template<
typename RootNodeType>
1324 typename AccessorRegistry::accessor a;
1325 mAccessorRegistry.insert(a, &accessor);
1329template<
typename RootNodeType>
1333 typename ConstAccessorRegistry::accessor a;
1334 mConstAccessorRegistry.insert(a, &accessor);
1338template<
typename RootNodeType>
1342 mAccessorRegistry.erase(&accessor);
1346template<
typename RootNodeType>
1350 mConstAccessorRegistry.erase(&accessor);
1354template<
typename RootNodeType>
1358 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1359 it != mAccessorRegistry.end(); ++it)
1361 if (it->first) it->first->clear();
1364 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1365 it != mConstAccessorRegistry.end(); ++it)
1367 if (it->first) it->first->clear();
1372template<
typename RootNodeType>
1376 mAccessorRegistry.erase(
nullptr);
1377 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1378 it != mAccessorRegistry.end(); ++it)
1380 it->first->release();
1382 mAccessorRegistry.
clear();
1384 mAccessorRegistry.erase(
nullptr);
1385 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1386 it != mConstAccessorRegistry.end(); ++it)
1388 it->first->release();
1390 mConstAccessorRegistry.clear();
1397template<
typename RootNodeType>
1398inline const typename RootNodeType::ValueType&
1405template<
typename RootNodeType>
1406template<
typename AccessT>
1407inline const typename RootNodeType::ValueType&
1414template<
typename RootNodeType>
1422template<
typename RootNodeType>
1430template<
typename RootNodeType>
1438template<
typename RootNodeType>
1446template<
typename RootNodeType>
1453template<
typename RootNodeType>
1460template<
typename RootNodeType>
1461template<
typename AccessT>
1469template<
typename RootNodeType>
1477template<
typename RootNodeType>
1485template<
typename RootNodeType>
1486template<
typename ModifyOp>
1494template<
typename RootNodeType>
1495template<
typename ModifyOp>
1503template<
typename RootNodeType>
1514template<
typename RootNodeType>
1519 mRoot.
addTile(level, xyz, value, active);
1523template<
typename RootNodeType>
1524template<
typename NodeT>
1528 this->clearAllAccessors();
1529 return mRoot.template stealNode<NodeT>(xyz, value, active);
1533template<
typename RootNodeType>
1534inline typename RootNodeType::LeafNodeType*
1541template<
typename RootNodeType>
1542inline typename RootNodeType::LeafNodeType*
1549template<
typename RootNodeType>
1550inline const typename RootNodeType::LeafNodeType*
1557template<
typename RootNodeType>
1558template<
typename NodeType>
1562 return mRoot.template probeNode<NodeType>(xyz);
1566template<
typename RootNodeType>
1567template<
typename NodeType>
1568inline const NodeType*
1571 return this->
template probeConstNode<NodeType>(xyz);
1575template<
typename RootNodeType>
1576template<
typename NodeType>
1577inline const NodeType*
1580 return mRoot.template probeConstNode<NodeType>(xyz);
1587template<
typename RootNodeType>
1591 this->clearAllAccessors();
1592 return mRoot.clip(bbox);
1596template<
typename RootNodeType>
1600 this->clearAllAccessors();
1601 for (
LeafIter it = this->beginLeaf(); it; ) {
1604 if (!leaf->isAllocated()) {
1605 this->addTile(0, leaf->origin(), this->background(),
false);
1610template<
typename RootNodeType>
1615 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1620template<
typename RootNodeType>
1624 this->clearAllAccessors();
1625 return mRoot.sparseFill(bbox, value, active);
1629template<
typename RootNodeType>
1633 this->clearAllAccessors();
1634 return mRoot.denseFill(bbox, value, active);
1638template<
typename RootNodeType>
1642 this->clearAllAccessors();
1643 mRoot.voxelizeActiveTiles(threaded);
1647template<
typename RootNodeType>
1652 if (Metadata::isRegisteredType(valueType())) {
1654 result = Metadata::createMetadata(valueType());
1655 if (result->typeName() == MetadataT::staticTypeName()) {
1656 MetadataT* m =
static_cast<MetadataT*
>(result.get());
1657 m->value() = mRoot.background();
1667template<
typename RootNodeType>
1671 this->clearAllAccessors();
1675 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1677 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1679 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1684template<
typename RootNodeType>
1685template<
typename OtherRootNodeType>
1689 this->clearAllAccessors();
1690 mRoot.topologyUnion(other.
root(), preserveTiles);
1693template<
typename RootNodeType>
1694template<
typename OtherRootNodeType>
1698 this->clearAllAccessors();
1699 mRoot.topologyIntersection(other.
root());
1702template<
typename RootNodeType>
1703template<
typename OtherRootNodeType>
1707 this->clearAllAccessors();
1708 mRoot.topologyDifference(other.
root());
1716template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1722 op(args.
a(), args.
b(), args.
result());
1729template<
typename RootNodeType>
1730template<
typename CombineOp>
1735 this->combineExtended(other, extendedOp, prune);
1741template<
typename RootNodeType>
1742template<
typename CombineOp>
1747 this->combineExtended(other, extendedOp, prune);
1751template<
typename RootNodeType>
1752template<
typename ExtendedCombineOp>
1756 this->clearAllAccessors();
1757 mRoot.combine(other.
root(), op, prune);
1763template<
typename RootNodeType>
1764template<
typename ExtendedCombineOp>
1768 this->clearAllAccessors();
1769 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op, prune);
1773template<
typename RootNodeType>
1774template<
typename CombineOp,
typename OtherTreeType>
1779 this->combine2Extended(a, b, extendedOp, prune);
1785template<
typename RootNodeType>
1786template<
typename CombineOp,
typename OtherTreeType>
1791 this->combine2Extended(a, b, extendedOp, prune);
1795template<
typename RootNodeType>
1796template<
typename ExtendedCombineOp,
typename OtherTreeType>
1799 ExtendedCombineOp& op,
bool prune)
1801 this->clearAllAccessors();
1802 mRoot.combine2(a.
root(), b.root(), op, prune);
1809template<
typename RootNodeType>
1810template<
typename ExtendedCombineOp,
typename OtherTreeType>
1813 const ExtendedCombineOp& op,
bool prune)
1815 this->clearAllAccessors();
1816 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op, prune);
1823template<
typename RootNodeType>
1827 static std::string sTreeTypeName = []()
1830 std::vector<Index> dims;
1831 Tree::getNodeLog2Dims(dims);
1832 std::ostringstream ostr;
1833 ostr <<
"Tree_" << typeNameAsString<BuildType>();
1834 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
1835 ostr <<
"_" << dims[i];
1839 return sTreeTypeName;
1843template<
typename RootNodeType>
1844template<
typename OtherRootNodeType>
1852template<
typename RootNodeType>
1858 if (this->empty())
return false;
1860 mRoot.evalActiveBoundingBox(bbox,
false);
1862 return !bbox.
empty();
1865template<
typename RootNodeType>
1871 if (this->empty())
return false;
1873 mRoot.evalActiveBoundingBox(bbox,
true);
1875 return !bbox.
empty();
1879template<
typename RootNodeType>
1884 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
1890template<
typename RootNodeType>
1895 bool notEmpty = this->evalLeafBoundingBox(bbox);
1901template<
typename RootNodeType>
1905 minVal = maxVal = zeroVal<ValueType>();
1907 minVal = maxVal = *iter;
1908 for (++iter; iter; ++iter) {
1910 if (math::cwiseLessThan(val, minVal)) minVal = val;
1911 if (math::cwiseGreaterThan(val, maxVal)) maxVal = val;
1917template<
typename RootNodeType>
1922 RootNodeType::getNodeLog2Dims(dims);
1926template<
typename RootNodeType>
1930 if (verboseLevel <= 0)
return;
1935 std::streamsize savedPrecision;
1936 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
1937 ~OnExit() { os.precision(savedPrecision); }
1939 OnExit restorePrecision(os);
1941 std::vector<Index> dims;
1942 Tree::getNodeLog2Dims(dims);
1944 os <<
"Information about Tree:\n"
1945 <<
" Type: " << this->type() <<
"\n";
1947 os <<
" Configuration:\n";
1949 if (verboseLevel <= 1) {
1951 os <<
" Root(" << mRoot.getTableSize() <<
")";
1952 if (dims.size() > 1) {
1953 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1954 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
1956 os <<
", Leaf(" << (1 << dims.back()) <<
"^3)\n";
1958 os <<
" Background value: " << mRoot.background() <<
"\n";
1964 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
1965 if (verboseLevel > 3) {
1968 minVal = extrema.
min();
1969 maxVal = extrema.
max();
1972 const auto nodeCount = this->nodeCount();
1973 const Index32 leafCount = nodeCount.front();
1974 assert(dims.size() == nodeCount.size());
1977 for (
size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
1980 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
1981 if (dims.size() >= 2) {
1982 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
1983 os <<
", Internal(" << util::formattedInt(nodeCount[N - i]);
1984 os <<
" x " << (1 << dims[i]) <<
"^3)";
1986 os <<
", Leaf(" << util::formattedInt(leafCount);
1987 os <<
" x " << (1 << dims.back()) <<
"^3)\n";
1989 os <<
" Background value: " << mRoot.background() <<
"\n";
1993 if (verboseLevel > 3) {
1994 os <<
" Min value: " << minVal <<
"\n";
1995 os <<
" Max value: " << maxVal <<
"\n";
1999 numActiveVoxels = this->activeVoxelCount(),
2000 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2001 numActiveTiles = this->activeTileCount();
2003 os <<
" Number of active voxels: " << util::formattedInt(numActiveVoxels) <<
"\n";
2004 os <<
" Number of active tiles: " << util::formattedInt(numActiveTiles) <<
"\n";
2008 if (numActiveVoxels) {
2010 this->evalActiveVoxelBoundingBox(bbox);
2012 totalVoxels = dim.
x() * uint64_t(dim.
y()) * dim.
z();
2014 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
2015 os <<
" Dimensions of active voxels: "
2016 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
2018 const double activeRatio = (100.0 * double(numActiveVoxels)) /
double(totalVoxels);
2019 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
2021 if (leafCount > 0) {
2022 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2023 / (
double(leafCount) *
double(LeafNodeType::NUM_VOXELS));
2024 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
2027 if (verboseLevel > 2) {
2029 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
2030 os <<
" Number of unallocated nodes: "
2031 << util::formattedInt(sum) <<
" ("
2032 << (100.0 * double(sum) / double(totalNodeCount)) <<
"%)\n";
2035 os <<
" Tree is empty!\n";
2039 if (verboseLevel == 2)
return;
2043 actualMem = this->memUsage(),
2044 denseMem =
sizeof(
ValueType) * totalVoxels,
2045 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
2048 os <<
"Memory footprint:\n";
2049 util::printBytes(os, actualMem,
" Actual: ");
2050 util::printBytes(os, voxelsMem,
" Active leaf voxels: ");
2052 if (numActiveVoxels) {
2053 util::printBytes(os, denseMem,
" Dense equivalent: ");
2054 os <<
" Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2055 <<
"% of an equivalent dense volume\n";
2056 os <<
" Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2057 <<
"% 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.
ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing c...
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition Types.h:569
const AValueType & result() const
Get the output value.
Definition Types.h:613
const BValueType & b() const
Get the B input value.
Definition Types.h:610
const AValueType & a() const
Get the A input value.
Definition Types.h:608
Definition Exceptions.h:61
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition Types.h:683
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:251
Coord extents() const
Definition Coord.h:384
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition Coord.h:358
void reset()
Definition Coord.h:329
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
Int32 y() const
Definition Coord.h:131
Int32 x() const
Definition Coord.h:130
Int32 z() const
Definition Coord.h:132
double min() const
Return the minimum value.
Definition Stats.h:121
double max() const
Return the maximum value.
Definition Stats.h:124
Templated class to compute the minimum and maximum values.
Definition Stats.h:31
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 const Name & type() const =0
Return the name of this tree's type.
virtual std::vector< Index32 > nodeCount() const =0
virtual Index32 nonLeafCount() const =0
Return the number of non-leaf nodes.
virtual ~TreeBase()=default
virtual Index64 activeLeafVoxelCount() const =0
Return the number of active voxels stored in leaf nodes.
virtual void readBuffers(std::istream &, bool saveFloatAsHalf=false)=0
Read all data buffers for this tree.
bool isType() const
Return true if this tree is of the same type as the template parameter.
Definition Tree.h:55
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:65
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:134
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 & operator=(const TreeBase &)=delete
TreeBase(const TreeBase &)=default
Base class for tree-traversal iterators over tile and voxel values.
Definition TreeIterator.h:617
RootNodeType::ChildAllCIter beginRootDense() const
Return an iterator over all entries of the root node's table.
Definition Tree.h:948
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:1416
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:1846
CIterT cbegin() const
Return a const iterator of type CIterT (for example, cbegin<ValueOnCIter>() is equivalent to cbeginVa...
void releaseAccessor(ValueAccessorBase< Tree, false > &) const
Dummy implementations.
Definition Tree.h:649
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 releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Definition Tree.h:650
ConstAccessorRegistry mConstAccessorRegistry
Definition Tree.h:1040
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition Tree.h:450
RootNodeType & root()
Return this tree's root node.
Definition Tree.h:281
Tree(const Tree &other)
Deep copy constructor.
Definition Tree.h:207
RootNodeType::ChildOffCIter cbeginRootTiles() const
Definition Tree.h:942
LeafCIter beginLeaf() const
Definition Tree.h:976
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition Tree.h:1265
ValueOffCIter cbeginValueOff() const
Definition Tree.h:1003
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition Tree.h:218
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition Tree.h:1551
void clearAllAccessors()
Clear all registered accessors.
Definition Tree.h:1356
_RootNodeType RootNodeType
Definition Tree.h:183
RootNodeType::ChildAllIter beginRootDense()
Definition Tree.h:950
LeafCIter cbeginLeaf() const
Definition Tree.h:977
const Name & type() const override
Return the name of this type of tree.
Definition Tree.h:274
RootNodeType::ChildOffIter beginRootTiles()
Definition Tree.h:943
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition Tree.h:1274
RootNodeType::ChildOnCIter beginRootChildren() const
Return an iterator over children of the root node.
Definition Tree.h:934
bool operator!=(const Tree &) const
Definition Tree.h:277
Tree()
Definition Tree.h:202
AccessorRegistry mAccessorRegistry
Definition Tree.h:1039
RootNodeType mRoot
Definition Tree.h:1038
ValueAllCIter cbeginValueAll() const
Definition Tree.h:991
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:507
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:1543
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:1535
RootNodeType::ChildOnIter beginRootChildren()
Definition Tree.h:936
ValueOnCIter beginValueOn() const
Definition Tree.h:996
bool operator==(const Tree &) const
Definition Tree.h:276
SharedPtr< Tree > Ptr
Definition Tree.h:180
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:1497
Index32 leafCount() const override
Return the number of leaf nodes.
Definition Tree.h:340
Index64 inactiveVoxelCount() const override
Return the number of inactive voxels within the bounding box of all active voxels.
Definition Tree.h:359
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:1455
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:620
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:478
ValueOffCIter beginValueOff() const
Definition Tree.h:1002
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:518
RootNodeType::ChildOffCIter beginRootTiles() const
Return an iterator over non-child entries of the root node's table.
Definition Tree.h:941
std::vector< Index32 > nodeCount() const override
Definition Tree.h:344
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:1516
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition Tree.h:1505
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:1440
ValueOnIter beginValueOn()
Return an iterator over active values (tile and voxel) across all nodes.
Definition Tree.h:995
typename RootNodeType::BuildType BuildType
Definition Tree.h:185
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:1448
Index64 activeTileCount() const override
Return the total number of active tiles.
Definition Tree.h:361
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition Tree.h:1424
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition Tree.h:1016
ValueOnCIter cbeginValueOn() const
Definition Tree.h:997
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition Tree.h:266
typename RootNodeType::ValueType ValueType
Definition Tree.h:184
void attachAccessor(ValueAccessorBase< Tree, false > &) const
Dummy implementations.
Definition Tree.h:637
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition Tree.h:1399
const LeafNodeType * probeLeaf(const Coord &xyz) const
Definition Tree.h:553
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Definition Tree.h:638
NodeCIter beginNode() const
Definition Tree.h:969
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:1488
SharedPtr< const Tree > ConstPtr
Definition Tree.h:181
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition Tree.h:254
RootNodeType::ChildAllCIter cbeginRootDense() const
Definition Tree.h:949
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition Tree.h:609
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition Tree.h:1297
RootNodeType::ChildOnCIter cbeginRootChildren() const
Definition Tree.h:935
NodeCIter cbeginNode() const
Definition Tree.h:970
const ValueType & background() const
Return this tree's background value.
Definition Tree.h:662
Tree & operator=(const Tree &)=delete
ValueOffIter beginValueOff()
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition Tree.h:1001
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition Tree.h:665
typename RootNodeType::LeafNodeType LeafNodeType
Definition Tree.h:186
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition Tree.h:1471
LeafIter beginLeaf()
Return an iterator over all leaf nodes in this tree.
Definition Tree.h:975
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition Tree.h:233
~Tree() override
Definition Tree.h:263
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition Tree.h:454
Tree(const ValueType &background)
Empty tree constructor.
Definition Tree.h:261
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition Tree.h:452
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:607
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:269
Index treeDepth() const override
Return the depth of this tree.
Definition Tree.h:338
const RootNodeType & root() const
Definition Tree.h:282
ValueAllCIter beginValueAll() const
Definition Tree.h:990
NodeIter beginNode()
Return an iterator over all nodes in this tree.
Definition Tree.h:968
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition Tree.h:1015
ValueAllIter beginValueAll()
Return an iterator over all values (tile and voxel) across all nodes.
Definition Tree.h:989
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition ValueAccessor.h:152
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition logging.h:256
std::string Name
Definition Name.h:19
Index32 Index
Definition Types.h:54
uint32_t Index32
Definition Types.h:52
uint64_t Index64
Definition Types.h:53
std::shared_ptr< T > SharedPtr
Definition Types.h:114
MergePolicy
Definition Types.h:506
@ MERGE_ACTIVE_STATES
Definition Types.h:507
@ MERGE_NODES
Definition Types.h:508
@ MERGE_ACTIVE_STATES_AND_NODES
Definition Types.h:509
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition Tree.h:1718
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition Tree.h:1721
CombineOpAdapter(CombineOp &_op)
Definition Tree.h:1719
CombineOp & op
Definition Tree.h:1725
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition Tree.h:1049
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal,...
Definition Tree.h:1059
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal,...
Definition Tree.h:1068
static TreeT::LeafCIter begin(const TreeT &tree)
Definition Tree.h:1166
static TreeT::LeafIter begin(TreeT &tree)
Definition Tree.h:1162
static TreeT::NodeCIter begin(const TreeT &tree)
Definition Tree.h:1158
static TreeT::NodeIter begin(TreeT &tree)
Definition Tree.h:1154
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition Tree.h:1148
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition Tree.h:1142
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition Tree.h:1136
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition Tree.h:1130
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition Tree.h:1124
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition Tree.h:1118
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition Tree.h:1190
static TreeT::ValueAllIter begin(TreeT &tree)
Definition Tree.h:1186
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition Tree.h:1182
static TreeT::ValueOffIter begin(TreeT &tree)
Definition Tree.h:1178
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition Tree.h:1174
static TreeT::ValueOnIter begin(TreeT &tree)
Definition Tree.h:1170
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition Tree.h:1115
DeallocateNodes(std::vector< NodeType * > &nodes)
Definition Tree.h:1025
NodeType **const mNodes
Definition Tree.h:1032
void operator()(const tbb::blocked_range< size_t > &range) const
Definition Tree.h:1027
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition Tree.h:197
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212