6 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
22 #include <tbb/concurrent_hash_map.h>
48 virtual const Name&
type()
const = 0;
51 virtual Name valueType()
const = 0;
54 template<
typename TreeType>
55 bool isType()
const {
return (this->
type() == TreeType::treeType()); }
74 virtual bool evalLeafBoundingBox(
CoordBBox& bbox)
const = 0;
79 virtual bool evalLeafDim(Coord& dim)
const = 0;
88 virtual bool evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const = 0;
93 virtual bool evalActiveVoxelDim(Coord& dim)
const = 0;
95 virtual void getIndexRange(
CoordBBox& bbox)
const = 0;
102 virtual void clipUnallocatedNodes() = 0;
104 virtual Index32 unallocatedLeafCount()
const = 0;
113 virtual Index treeDepth()
const = 0;
115 virtual Index32 leafCount()
const = 0;
119 virtual std::vector<Index32> nodeCount()
const = 0;
121 virtual Index32 nonLeafCount()
const = 0;
123 virtual Index64 activeLeafVoxelCount()
const = 0;
125 virtual Index64 inactiveLeafVoxelCount()
const = 0;
127 virtual Index64 activeVoxelCount()
const = 0;
129 virtual Index64 inactiveVoxelCount()
const = 0;
131 virtual Index64 activeTileCount()
const = 0;
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;
152 virtual void readBuffers(std::istream&,
const CoordBBox&,
bool saveFloatAsHalf =
false) = 0;
158 virtual void readNonresidentBuffers()
const = 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;
176 template<
typename _RootNodeType>
196 template<
typename OtherValueType>
217 template<
typename OtherRootType>
232 template<
typename OtherTreeType>
233 Tree(
const OtherTreeType& other,
253 template<
typename OtherTreeType>
291 template<
typename OtherRootNodeType>
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;
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 );
377 template<
typename AccessT>
const ValueType&
getValue(
const Coord& xyz, AccessT&)
const;
420 template<
typename ModifyOp>
421 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
442 template<
typename ModifyOp>
510 mRoot.prune(tolerance);
530 template<
typename NodeT>
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;
579 template<
typename ArrayT>
void getNodes(ArrayT& array);
580 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
606 template<
typename ArrayT>
608 template<
typename ArrayT>
612 mRoot.stealNodes(array, value, state);
692 template<
typename OtherRootNodeType>
708 template<
typename OtherRootNodeType>
721 template<
typename OtherRootNodeType>
768 template<
typename CombineOp>
770 template<
typename CombineOp>
811 template<
typename ExtendedCombineOp>
813 template<
typename ExtendedCombineOp>
844 template<
typename CombineOp,
typename OtherTreeType >
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 >
925 template<
typename ExtendedCombineOp,
typename OtherTreeType >
1008 template<
typename IterT> IterT
begin();
1011 template<
typename CIterT> CIterT
cbegin()
const;
1023 template<
typename NodeType>
1026 :
mNodes(nodes.
empty() ? nullptr : &nodes.front()) { }
1028 for (
size_t n = range.begin(),
N = range.
end();
n <
N; ++
n) {
1048 template<
typename T, Index N1=4, Index N2=3>
1058 template<
typename T, Index N1=5, Index N2=4, Index N3=3>
1067 template<
typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
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");
1089 int32_t bufferCount = 1;
1090 os.write(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1097 os <<
" Tree Type: " <<
type()
1101 <<
" Leaf Node Count: " <<
leafCount() << std::endl
1102 <<
" Non-leaf Node Count: " <<
nonLeafCount() << std::endl;
1117 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1118 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1119 return tree.beginRootChildren();
1123 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1124 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1125 return tree.cbeginRootChildren();
1129 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1130 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1131 return tree.beginRootTiles();
1135 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1136 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1137 return tree.cbeginRootTiles();
1141 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1142 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1143 return tree.beginRootDense();
1147 template<
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(); }
1173 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1174 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1177 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1178 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1181 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1182 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1185 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1186 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1189 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1190 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1194 template<
typename RootNodeType>
1195 template<
typename IterT>
1203 template<
typename RootNodeType>
1204 template<
typename IterT>
1215 template<
typename RootNodeType>
1219 this->clearAllAccessors();
1221 mRoot.readTopology(is, saveFloatAsHalf);
1225 template<
typename RootNodeType>
1230 mRoot.writeTopology(os, saveFloatAsHalf);
1234 template<
typename RootNodeType>
1238 this->clearAllAccessors();
1239 mRoot.readBuffers(is, saveFloatAsHalf);
1243 template<
typename RootNodeType>
1247 this->clearAllAccessors();
1248 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1252 template<
typename RootNodeType>
1256 for (
LeafCIter it = this->cbeginLeaf(); it; ++it) {
1258 it->getValue(
Index(0));
1263 template<
typename RootNodeType>
1267 mRoot.writeBuffers(os, saveFloatAsHalf);
1271 template<
typename RootNodeType>
1272 template<
typename ArrayT>
1278 "getNodes() does not work for the RootNode. Use Tree::root()");
1279 mRoot.getNodes(array);
1283 template<
typename RootNodeType>
1284 template<
typename ArrayT>
1290 "getNodes() does not work for the RootNode. Use Tree::root()");
1291 mRoot.getNodes(array);
1295 template<
typename RootNodeType>
1299 std::vector<LeafNodeType*> leafnodes;
1300 this->stealNodes(leafnodes);
1305 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1306 this->stealNodes(internalNodes);
1313 this->clearAllAccessors();
1320 template<
typename RootNodeType>
1324 typename AccessorRegistry::accessor
a;
1325 mAccessorRegistry.insert(a, &accessor);
1329 template<
typename RootNodeType>
1333 typename ConstAccessorRegistry::accessor
a;
1334 mConstAccessorRegistry.insert(a, &accessor);
1338 template<
typename RootNodeType>
1342 mAccessorRegistry.erase(&accessor);
1346 template<
typename RootNodeType>
1350 mConstAccessorRegistry.erase(&accessor);
1354 template<
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();
1372 template<
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();
1397 template<
typename RootNodeType>
1401 return mRoot.getValue(xyz);
1405 template<
typename RootNodeType>
1406 template<
typename AccessT>
1410 return accessor.getValue(xyz);
1414 template<
typename RootNodeType>
1418 return mRoot.getValueDepth(xyz);
1422 template<
typename RootNodeType>
1426 mRoot.setValueOff(xyz);
1430 template<
typename RootNodeType>
1434 mRoot.setValueOff(xyz, value);
1438 template<
typename RootNodeType>
1442 mRoot.setActiveState(xyz, on);
1446 template<
typename RootNodeType>
1450 mRoot.setValueOn(xyz, value);
1453 template<
typename RootNodeType>
1457 mRoot.setValueOnly(xyz, value);
1460 template<
typename RootNodeType>
1461 template<
typename AccessT>
1465 accessor.setValue(xyz, value);
1469 template<
typename RootNodeType>
1473 mRoot.setActiveState(xyz,
true);
1477 template<
typename RootNodeType>
1481 mRoot.setValueOn(xyz, value);
1485 template<
typename RootNodeType>
1486 template<
typename ModifyOp>
1490 mRoot.modifyValue(xyz, op);
1494 template<
typename RootNodeType>
1495 template<
typename ModifyOp>
1499 mRoot.modifyValueAndActiveState(xyz, op);
1503 template<
typename RootNodeType>
1507 return mRoot.probeValue(xyz, value);
1514 template<
typename RootNodeType>
1519 mRoot.addTile(level, xyz, value, active);
1523 template<
typename RootNodeType>
1524 template<
typename NodeT>
1528 this->clearAllAccessors();
1529 return mRoot.template stealNode<NodeT>(xyz,
value,
active);
1533 template<
typename RootNodeType>
1534 inline typename RootNodeType::LeafNodeType*
1537 return mRoot.touchLeaf(xyz);
1541 template<
typename RootNodeType>
1542 inline typename RootNodeType::LeafNodeType*
1545 return mRoot.probeLeaf(xyz);
1549 template<
typename RootNodeType>
1550 inline const typename RootNodeType::LeafNodeType*
1553 return mRoot.probeConstLeaf(xyz);
1557 template<
typename RootNodeType>
1558 template<
typename NodeType>
1562 return mRoot.template probeNode<NodeType>(xyz);
1566 template<
typename RootNodeType>
1567 template<
typename NodeType>
1568 inline const NodeType*
1571 return this->
template probeConstNode<NodeType>(xyz);
1575 template<
typename RootNodeType>
1576 template<
typename NodeType>
1577 inline const NodeType*
1580 return mRoot.template probeConstNode<NodeType>(xyz);
1587 template<
typename RootNodeType>
1591 this->clearAllAccessors();
1592 return mRoot.clip(bbox);
1596 template<
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);
1610 template<
typename RootNodeType>
1615 for (
auto it = this->cbeginLeaf(); it; ++it)
if (!it->isAllocated()) ++sum;
1620 template<
typename RootNodeType>
1624 this->clearAllAccessors();
1625 return mRoot.sparseFill(bbox, value, active);
1629 template<
typename RootNodeType>
1633 this->clearAllAccessors();
1634 return mRoot.denseFill(bbox, value, active);
1638 template<
typename RootNodeType>
1642 this->clearAllAccessors();
1643 mRoot.voxelizeActiveTiles(threaded);
1647 template<
typename RootNodeType>
1655 if (result->typeName() == MetadataT::staticTypeName()) {
1656 MetadataT* m =
static_cast<MetadataT*
>(result.get());
1657 m->value() = mRoot.background();
1667 template<
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;
1684 template<
typename RootNodeType>
1685 template<
typename OtherRootNodeType>
1689 this->clearAllAccessors();
1690 mRoot.topologyUnion(other.
root(), preserveTiles);
1693 template<
typename RootNodeType>
1694 template<
typename OtherRootNodeType>
1698 this->clearAllAccessors();
1699 mRoot.topologyIntersection(other.
root());
1702 template<
typename RootNodeType>
1703 template<
typename OtherRootNodeType>
1707 this->clearAllAccessors();
1708 mRoot.topologyDifference(other.
root());
1716 template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1722 op(args.
a(), args.
b(), args.
result());
1729 template<
typename RootNodeType>
1730 template<
typename CombineOp>
1735 this->combineExtended(other, extendedOp, prune);
1741 template<
typename RootNodeType>
1742 template<
typename CombineOp>
1747 this->combineExtended(other, extendedOp, prune);
1751 template<
typename RootNodeType>
1752 template<
typename ExtendedCombineOp>
1756 this->clearAllAccessors();
1763 template<
typename RootNodeType>
1764 template<
typename ExtendedCombineOp>
1768 this->clearAllAccessors();
1769 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op,
prune);
1773 template<
typename RootNodeType>
1774 template<
typename CombineOp,
typename OtherTreeType>
1779 this->combine2Extended(a, b, extendedOp, prune);
1785 template<
typename RootNodeType>
1786 template<
typename CombineOp,
typename OtherTreeType>
1791 this->combine2Extended(a, b, extendedOp, prune);
1795 template<
typename RootNodeType>
1796 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1799 ExtendedCombineOp& op,
bool prune)
1801 this->clearAllAccessors();
1802 mRoot.combine2(a.
root(), b.root(), op,
prune);
1809 template<
typename RootNodeType>
1810 template<
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);
1823 template<
typename RootNodeType>
1830 std::vector<Index> 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;
1843 template<
typename RootNodeType>
1844 template<
typename OtherRootNodeType>
1848 return mRoot.hasSameTopology(other.
root());
1852 template<
typename RootNodeType>
1858 if (this->empty())
return false;
1860 mRoot.evalActiveBoundingBox(bbox,
false);
1862 return !bbox.empty();
1865 template<
typename RootNodeType>
1871 if (this->empty())
return false;
1873 mRoot.evalActiveBoundingBox(bbox,
true);
1875 return !bbox.empty();
1879 template<
typename RootNodeType>
1884 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
1885 dim = bbox.extents();
1890 template<
typename RootNodeType>
1895 bool notEmpty = this->evalLeafBoundingBox(bbox);
1896 dim = bbox.extents();
1901 template<
typename RootNodeType>
1905 minVal = maxVal = zeroVal<ValueType>();
1907 minVal = maxVal = *iter;
1908 for (++iter; iter; ++iter) {
1917 template<
typename RootNodeType>
1922 RootNodeType::getNodeLog2Dims(dims);
1926 template<
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;
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) {
1984 os <<
" x " << (1 << dims[i]) <<
"^3)";
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();
2008 if (numActiveVoxels) {
2010 this->evalActiveVoxelBoundingBox(bbox);
2011 dim = bbox.extents();
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: "
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";
2052 if (numActiveVoxels) {
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";
2065 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
virtual Index64 activeTileCount() const =0
Return the total number of active tiles.
const AValueType & result() const
Get the output value.
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueOnCIter > ValueOnCIter
virtual void readTopology(std::istream &, bool saveFloatAsHalf=false)
Read the tree topology from a stream.
ValueOffIter beginValueOff()
Return an iterator over inactive values (tile and voxel) across all nodes.
void releaseAccessor(ValueAccessorBase< Tree, true > &) const
Deregister an accessor so that it is no longer automatically cleared.
AccessorRegistry mAccessorRegistry
bool operator==(const Tree &) const
virtual void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const
Write the tree topology to a stream.
void parallel_for(int64_t start, int64_t end, std::function< void(int64_t index)> &&task, parallel_options opt=parallel_options(0, Split_Y, 1))
bool hasSameTopology(const Tree< OtherRootNodeType > &other) const
Return true if the given tree has the same node and active value topology as this tree...
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
SharedPtr< TreeBase > Ptr
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
bool cwiseGreaterThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
LeafIteratorBase< Tree, typename RootNodeType::ChildOnIter > LeafIter
Iterator over all leaf nodes in this tree.
static TreeT::ValueAllIter begin(TreeT &tree)
hboost::math::policies::policy< hboost::math::policies::domain_error< hboost::math::policies::ignore_error >, hboost::math::policies::pole_error< hboost::math::policies::ignore_error >, hboost::math::policies::overflow_error< hboost::math::policies::ignore_error >, hboost::math::policies::underflow_error< hboost::math::policies::ignore_error >, hboost::math::policies::denorm_error< hboost::math::policies::ignore_error >, hboost::math::policies::rounding_error< hboost::math::policies::ignore_error >, hboost::math::policies::evaluation_error< hboost::math::policies::ignore_error >, hboost::math::policies::indeterminate_result_error< hboost::math::policies::ignore_error > > policy
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
void stealNodes(ArrayT &array, const ValueType &value, bool state)
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
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...
virtual Metadata::Ptr getBackgroundValue() const
Return this tree's background value wrapped as metadata.
void attachAccessor(ValueAccessorBase< Tree, false > &) const
Dummy implementations.
static const Name & treeType()
Return the name of this type of tree.
TreeValueIteratorBase< Tree, typename RootNodeType::ValueOnIter > ValueOnIter
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...
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
RootNodeType::ChildOffCIter cbeginRootTiles() const
Return an iterator over non-child entries of the root node's table.
Index64 inactiveVoxelCount() const override
Return the number of inactive voxels within the bounding box of all active voxels.
void stealNodes(ArrayT &array)
Steals all nodes of a certain type from the tree and adds them to a container with the following API:...
GLsizei const GLchar *const * string
GLsizei const GLfloat * value
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...
int getValueDepth(const Coord &xyz) const
Return the tree depth (0 = root) at which the value of voxel (x, y, z) resides.
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
void sparseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Base class for tree-traversal iterators over all nodes.
static TreeT::NodeCIter begin(const TreeT &tree)
#define OPENVDB_LOG_WARN(mesg)
ValueAllCIter beginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
DeallocateNodes(std::vector< NodeType * > &nodes)
RootNodeType::ChildOffCIter beginRootTiles() const
Return an iterator over non-child entries of the root node's table.
NodeIteratorBase< Tree, typename RootNodeType::ChildOnIter > NodeIter
Iterator over all nodes in this tree.
static TreeT::LeafCIter begin(const TreeT &tree)
GLboolean GLboolean GLboolean GLboolean a
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
RootNodeType::ChildAllCIter cbeginRootDense() const
Return an iterator over all entries of the root node's table.
RootNodeType & root()
Return this tree's root node.
#define OPENVDB_USE_VERSION_NAMESPACE
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
virtual Index64 activeVoxelCount() const =0
Return the total number of active voxels.
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
**But if you need a result
TreeValueIteratorBase< Tree, typename RootNodeType::ValueAllIter > ValueAllIter
virtual Index32 leafCount() const =0
Return the number of leaf nodes.
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueAllCIter > ValueAllCIter
Tree(const ValueType &background)
Empty tree constructor.
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Index32 unallocatedLeafCount() const override
Return the total number of unallocated leaf nodes residing in this tree.
void readNonresidentBuffers() const override
Read all of this tree's data buffers that are not yet resident in memory (because delayed loading is ...
void clip(const CoordBBox &)
Set all voxels that lie outside the given axis-aligned box to the background.
Index64 memUsage() const override
Return the total amount of memory in bytes occupied by this tree.
ValueOffCIter cbeginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
RootNodeType::ChildOffIter beginRootTiles()
Return an iterator over non-child entries of the root node's table.
static TreeT::LeafIter begin(TreeT &tree)
bool operator!=(const Tree &) const
void topologyIntersection(const Tree< OtherRootNodeType > &other)
Intersects this tree's set of active values with the active values of the other tree, whose ValueType may be different.
void releaseAllAccessors()
Notify all registered accessors, by calling ValueAccessor::release(), that this tree is about to be d...
virtual Index64 inactiveVoxelCount() const =0
Return the number of inactive voxels within the bounding box of all active voxels.
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal, Leaf) with value type T and internal and leaf node log dimensions N1, N2 and N3, respectively.
bool evalActiveVoxelBoundingBox(CoordBBox &bbox) const override
Return in bbox the axis-aligned bounding box of all active voxels and tiles.
ValueAllIter beginValueAll()
Return an iterator over all values (tile and voxel) across all nodes.
Tree & operator=(const Tree &)=delete
CombineOpAdapter(CombineOp &_op)
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
std::shared_ptr< T > SharedPtr
void clear()
Remove all tiles from this tree and all nodes other than the root node.
void topologyDifference(const Tree< OtherRootNodeType > &other)
Difference this tree's set of active values with the active values of the other tree, whose ValueType may be different. So a resulting voxel will be active only if the original voxel is active in this tree and inactive in the other tree.
SYS_FORCE_INLINE const_iterator end() const
const AValueType & a() const
Get the A input value.
RootNodeType::ChildOnCIter beginRootChildren() const
Return an iterator over children of the root node.
Name valueType() const override
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
void readBuffers(std::istream &, bool saveFloatAsHalf=false) override
Read all data buffers for this tree.
const ValueType & background() const
Return this tree's background value.
bool isType() const
Return true if this tree is of the same type as the template parameter.
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
LeafCIter beginLeaf() const
Return an iterator over all leaf nodes in this tree.
void operator()(CombineArgs< AValueT, BValueT > &args) const
ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing c...
void print(std::ostream &os=std::cout, int verboseLevel=1) const override
Print statistics, memory usage and other information about this tree.
void merge(Tree &other, MergePolicy=MERGE_ACTIVE_STATES)
Efficiently merge another tree into this tree using one of several schemes.
Index64 activeTileCount() const override
Return the total number of active tiles.
LeafIter beginLeaf()
Return an iterator over all leaf nodes in this tree.
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
void releaseAccessor(ValueAccessorBase< Tree, false > &) const
Dummy implementations.
LeafIteratorBase< const Tree, typename RootNodeType::ChildOnCIter > LeafCIter
Iterator over all leaf nodes in this tree.
Index32 leafCount() const override
Return the number of leaf nodes.
void attachAccessor(ValueAccessorBase< Tree, true > &) const
Register an accessor for this tree. Registered accessors are automatically cleared whenever one of th...
NodeCIter beginNode() const
Return an iterator over all nodes in this tree.
bool evalActiveVoxelDim(Coord &dim) const override
Return in dim the dimensions of the axis-aligned bounding box of all active voxels. This is a tighter bounding box than the leaf node bounding box.
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
const RootNodeType & root() const
Return this tree's root node.
Functions to count tiles, nodes or voxels in a grid.
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
const ValueType & max() const
Return the maximum value.
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
ValueOffCIter beginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
const NodeType * probeConstNode(const Coord &xyz) const
Return a pointer to the node of type NodeType that contains voxel (x, y, z). If no such node exists...
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
const LeafNodeType * probeLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Templated class to compute the minimum and maximum values.
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
static TreeT::ValueOffCIter begin(const TreeT &tree)
GLboolean GLboolean GLboolean b
void operator()(const tbb::blocked_range< size_t > &range) const
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
static TreeT::ValueAllCIter begin(const TreeT &tree)
bool evalLeafBoundingBox(CoordBBox &bbox) const override
Return in bbox the axis-aligned bounding box of all active tiles and leaf nodes with active values...
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate active
typename RootNodeType::ValueType ValueType
NodeIteratorBase< const Tree, typename RootNodeType::ChildOnCIter > NodeCIter
Iterator over all nodes in this tree.
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
TreeValueIteratorBase< Tree, typename RootNodeType::ValueOffIter > ValueOffIter
The root node of an OpenVDB tree.
bool hasActiveTiles() const
Return true if this tree has any active tiles.
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
void evalMinMax(ValueType &min, ValueType &max) const
Return the minimum and maximum active values in this tree.
CIterT cbegin() const
Return a const iterator of type CIterT (for example, cbegin<ValueOnCIter>() is equivalent to cbeginVa...
ValueAllCIter cbeginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Base class for typed trees.
static TreeT::NodeIter begin(TreeT &tree)
static TreeT::ValueOffIter begin(TreeT &tree)
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Index32 nonLeafCount() const override
Return the number of non-leaf nodes.
virtual Index32 nonLeafCount() const =0
Return the number of non-leaf nodes.
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueOffCIter > ValueOffCIter
static void getNodeLog2Dims(std::vector< Index > &dims)
Traverse the type hierarchy of nodes, and return, in dims, a list of the Log2Dims of nodes in order f...
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
typename RootNodeType::LeafNodeType LeafNodeType
Tree(const Tree &other)
Deep copy constructor.
ConstAccessorRegistry mConstAccessorRegistry
ValueOnCIter beginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
void readTopology(std::istream &, bool saveFloatAsHalf=false) override
Read the tree topology from a stream.
virtual void print(std::ostream &os=std::cout, int verboseLevel=1) const
Print statistics, memory usage and other information about this tree.
const ValueType & min() const
Return the minimum value.
LeafData & operator=(const LeafData &)=delete
typename RootNodeType::BuildType BuildType
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
ValueOnIter beginValueOn()
Return an iterator over active values (tile and voxel) across all nodes.
Base class for tree-traversal iterators over tile and voxel values.
void setValue(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
RootNodeType::ChildAllIter beginRootDense()
Return an iterator over all entries of the root node's table.
NodeCIter cbeginNode() const
Return an iterator over all nodes in this tree.
RootNodeType::ChildOnIter beginRootChildren()
Return an iterator over children of the root node.
NodeT * stealNode(const Coord &xyz, const ValueType &value, bool active)
Return a pointer to the node of type NodeT that contains voxel (x, y, z) and replace it with a tile o...
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
GA_API const UT_StringHolder N
_RootNodeType RootNodeType
FormattedInt< IntT > formattedInt(IntT n)
SharedPtr< const TreeBase > ConstPtr
static TreeT::ValueOnCIter begin(const TreeT &tree)
void combine2Extended(const Tree &a, const OtherTreeType &b, ExtendedCombineOp &op, bool prune=false)
**If you just want to fire and args
RootNodeType::ChildOnCIter cbeginRootChildren() const
Return an iterator over children of the root node.
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
void combine2(const Tree &a, const OtherTreeType &b, CombineOp &op, bool prune=false)
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)
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node of type NodeType that contains voxel (x, y, z). If no such node exists...
const Name & type() const override
Return the name of this type of tree.
void clipUnallocatedNodes() override
Replace with background tiles any nodes whose voxel buffers have not yet been allocated.
RootNodeType::ChildAllCIter beginRootDense() const
Return an iterator over all entries of the root node's table.
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
const BValueType & b() const
Get the B input value.
ValueOnCIter cbeginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
virtual const Name & type() const =0
Return the name of this tree's type.
Metadata::Ptr getBackgroundValue() const override
Return this tree's background value wrapped as metadata.
NodeIter beginNode()
Return an iterator over all nodes in this tree.
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
bool evalLeafDim(Coord &dim) const override
Return in dim the dimensions of the axis-aligned bounding box of all leaf nodes.
IterT begin()
Return an iterator of type IterT (for example, begin<ValueOnIter>() is equivalent to beginValueOn())...
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...
LeafNodeType * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, create one that preserves the values and active states of all voxels.
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
bool empty() const
Return true if this tree contains no nodes other than the root node and no tiles other than backgroun...
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don't change its value.
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
std::vector< Index32 > nodeCount() const override
void denseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value and ensure that those voxels are a...
void topologyUnion(const Tree< OtherRootNodeType > &other, const bool preserveTiles=false)
Union this tree's set of active values with the active values of the other tree, whose ValueType may ...
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
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.
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal, Internal, Leaf) with value type T and internal and leaf node log dimensions N1, N2, N3 and N4, respectively.
void combine(Tree &other, CombineOp &op, bool prune=false)
Internal table nodes for OpenVDB trees.
Index treeDepth() const override
Return the depth of this tree.
#define OPENVDB_THROW(exception, message)
void combineExtended(Tree &other, ExtendedCombineOp &op, bool prune=false)
void clearAllAccessors()
Clear all registered accessors.
void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const override
Write the tree topology to a stream.
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels) ...
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
static TreeT::ValueOnIter begin(TreeT &tree)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.