33 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
34 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
39 #include <boost/shared_ptr.hpp>
40 #include <boost/cstdint.hpp>
41 #include <tbb/atomic.h>
42 #include <tbb/concurrent_hash_map.h>
43 #include <openvdb/Types.h>
44 #include <openvdb/metadata/Metadata.h>
45 #include <openvdb/math/Math.h>
46 #include <openvdb/math/BBox.h>
47 #include <openvdb/util/Formats.h>
48 #include <openvdb/util/logging.h>
49 #include <openvdb/Platform.h>
67 typedef boost::shared_ptr<TreeBase>
Ptr;
68 typedef boost::shared_ptr<const TreeBase>
ConstPtr;
74 virtual const Name& type()
const = 0;
77 virtual Name valueType()
const = 0;
96 virtual bool evalLeafBoundingBox(CoordBBox& bbox)
const = 0;
101 virtual bool evalLeafDim(Coord& dim)
const = 0;
110 virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox)
const = 0;
115 virtual bool evalActiveVoxelDim(Coord& dim)
const = 0;
117 virtual void getIndexRange(CoordBBox& bbox)
const = 0;
126 virtual Index treeDepth()
const = 0;
128 virtual Index32 leafCount()
const = 0;
130 virtual Index32 nonLeafCount()
const = 0;
132 virtual Index64 activeLeafVoxelCount()
const = 0;
134 virtual Index64 inactiveLeafVoxelCount()
const = 0;
136 virtual Index64 activeVoxelCount()
const = 0;
138 virtual Index64 inactiveVoxelCount()
const = 0;
150 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
154 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
157 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false) = 0;
159 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const = 0;
165 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
177 template<
typename _RootNodeType>
181 typedef boost::shared_ptr<Tree>
Ptr;
188 static const Index DEPTH = RootNodeType::LEVEL + 1;
196 template<
typename OtherValueType>
215 template<
typename OtherRootType>
230 template<
typename OtherTreeType>
231 Tree(
const OtherTreeType& other,
236 mRoot(other.root(), inactiveValue, activeValue,
TopologyCopy())
251 template<
typename OtherTreeType>
261 virtual ~Tree() { releaseAllAccessors(); }
270 static const Name& treeType();
272 virtual const Name&
type()
const {
return this->treeType(); }
278 RootNodeType& root() {
return mRoot; }
295 template<
typename OtherRootNodeType>
298 virtual bool evalLeafBoundingBox(CoordBBox& bbox)
const;
299 virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox)
const;
300 virtual bool evalActiveVoxelDim(Coord& dim)
const;
301 virtual bool evalLeafDim(Coord& dim)
const;
306 static void getNodeLog2Dims(std::vector<Index>& dims);
315 virtual void readTopology(std::istream&,
bool saveFloatAsHalf =
false);
319 virtual void writeTopology(std::ostream&,
bool saveFloatAsHalf =
false)
const;
321 virtual void readBuffers(std::istream&,
bool saveFloatAsHalf =
false);
323 virtual void writeBuffers(std::ostream&,
bool saveFloatAsHalf =
false)
const;
325 virtual void print(std::ostream& os = std::cout,
int verboseLevel = 1)
const;
346 virtual Index64 inactiveVoxelCount()
const;
353 void evalMinMax(ValueType &
min, ValueType &
max)
const;
362 const ValueType& getValue(
const Coord& xyz)
const;
365 template<
typename AccessT>
const ValueType& getValue(
const Coord& xyz, AccessT&)
const;
370 int getValueDepth(
const Coord& xyz)
const;
373 void setActiveState(
const Coord& xyz,
bool on);
375 void setValueOnly(
const Coord& xyz,
const ValueType& value);
377 void setValueOn(
const Coord& xyz);
379 void setValueOn(
const Coord& xyz,
const ValueType& value);
381 void setValue(
const Coord& xyz,
const ValueType& value);
384 template<
typename AccessT>
void setValue(
const Coord& xyz,
const ValueType& value, AccessT&);
386 void setValueOff(
const Coord& xyz);
388 void setValueOff(
const Coord& xyz,
const ValueType& value);
408 template<
typename ModifyOp>
409 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
430 template<
typename ModifyOp>
431 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
435 bool probeValue(
const Coord& xyz, ValueType& value)
const;
438 bool isValueOn(
const Coord& xyz)
const {
return mRoot.isValueOn(xyz); }
440 bool isValueOff(
const Coord& xyz)
const {
return !this->isValueOn(xyz); }
453 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
461 template<
typename PruneOp>
void pruneOp(PruneOp&);
466 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
470 void pruneInactive(
const ValueType&);
474 void pruneInactive();
482 void pruneLevelSet();
492 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool active);
498 template<
typename NodeT>
499 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool active);
506 LeafNodeType* touchLeaf(
const Coord& xyz);
509 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
512 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
513 template<
typename NodeType>
const NodeType* probeNode(
const Coord& xyz)
const;
517 LeafNodeType* probeLeaf(
const Coord& xyz);
520 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
530 bool empty()
const {
return mRoot.empty(); }
533 void clear() { this->clearAllAccessors(); mRoot.clear(); }
536 void clearAllAccessors();
560 virtual void getIndexRange(CoordBBox& bbox)
const { mRoot.getIndexRange(bbox); }
573 void signedFloodFill(
const ValueType& outside,
const ValueType& inside);
576 void voxelizeActiveTiles();
600 template<
typename OtherRootNodeType>
616 template<
typename OtherRootNodeType>
629 template<
typename OtherRootNodeType>
676 template<
typename CombineOp>
677 void combine(
Tree& other, CombineOp& op,
bool prune =
false);
679 template<
typename CombineOp>
680 void combine(
Tree& other,
const CombineOp& op,
bool prune =
false);
721 template<
typename ExtendedCombineOp>
722 void combineExtended(
Tree& other, ExtendedCombineOp& op,
bool prune =
false);
724 template<
typename ExtendedCombineOp>
725 void combineExtended(
Tree& other,
const ExtendedCombineOp& op,
bool prune =
false);
756 template<
typename CombineOp,
typename OtherTreeType >
757 void combine2(
const Tree& a,
const OtherTreeType& b, CombineOp& op,
bool prune =
false);
759 template<
typename CombineOp,
typename OtherTreeType >
760 void combine2(
const Tree& a,
const OtherTreeType& b,
const CombineOp& op,
bool prune =
false);
836 template<
typename ExtendedCombineOp,
typename OtherTreeType >
837 void combine2Extended(
const Tree& a,
const OtherTreeType& b, ExtendedCombineOp& op,
840 template<
typename ExtendedCombineOp,
typename OtherTreeType >
841 void combine2Extended(
const Tree& a,
const OtherTreeType& b,
const ExtendedCombineOp&,
885 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp& op)
const { mRoot.visitActiveBBox(op); }
940 template<
typename VisitorOp>
void visit(VisitorOp& op);
941 template<
typename VisitorOp>
void visit(
const VisitorOp& op);
947 template<
typename VisitorOp>
void visit(VisitorOp& op)
const;
948 template<
typename VisitorOp>
void visit(
const VisitorOp& op)
const;
997 template<
typename OtherTreeType,
typename VisitorOp>
998 void visit2(OtherTreeType& other, VisitorOp& op);
999 template<
typename OtherTreeType,
typename VisitorOp>
1000 void visit2(OtherTreeType& other,
const VisitorOp& op);
1012 template<
typename OtherTreeType,
typename VisitorOp>
1013 void visit2(OtherTreeType& other, VisitorOp& op)
const;
1014 template<
typename OtherTreeType,
typename VisitorOp>
1015 void visit2(OtherTreeType& other,
const VisitorOp& op)
const;
1022 typename RootNodeType::ChildOnCIter beginRootChildren()
const {
return mRoot.cbeginChildOn(); }
1029 typename RootNodeType::ChildOffCIter beginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1031 typename RootNodeType::ChildOffCIter
cbeginRootTiles()
const {
return mRoot.cbeginChildOff(); }
1032 typename RootNodeType::ChildOffIter
beginRootTiles() {
return mRoot.beginChildOff(); }
1036 typename RootNodeType::ChildAllCIter beginRootDense()
const {
return mRoot.cbeginChildAll(); }
1038 typename RootNodeType::ChildAllCIter
cbeginRootDense()
const {
return mRoot.cbeginChildAll(); }
1039 typename RootNodeType::ChildAllIter
beginRootDense() {
return mRoot.beginChildAll(); }
1063 LeafIter beginLeaf() {
return LeafIter(*
this); }
1083 ValueOnIter beginValueOn() {
return ValueOnIter(*
this); }
1089 ValueOffIter beginValueOff() {
return ValueOffIter(*
this); }
1097 template<
typename IterT> IterT begin();
1100 template<
typename CIterT> CIterT cbegin()
const;
1112 void releaseAllAccessors();
1128 template<
typename T, Index N1, Index N2>
1138 template<
typename T, Index N1, Index N2, Index N3>
1148 template<
typename T, Index N1, Index N2, Index N3, Index N4>
1161 int32_t bufferCount;
1162 is.read(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1163 if (bufferCount != 1)
OPENVDB_LOG_WARN(
"multi-buffer trees are no longer supported");
1170 int32_t bufferCount = 1;
1171 os.write(reinterpret_cast<char*>(&bufferCount),
sizeof(int32_t));
1178 os <<
" Tree Type: " << type()
1179 <<
" Active Voxel Count: " << activeVoxelCount() << std::endl
1180 <<
" Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1181 <<
" Leaf Node Count: " << leafCount() << std::endl
1182 <<
" Non-leaf Node Count: " << nonLeafCount() << std::endl;
1197 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1198 static typename TreeT::RootNodeType::ChildOnIter
begin(TreeT& tree) {
1199 return tree.beginRootChildren();
1203 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1204 static typename TreeT::RootNodeType::ChildOnCIter
begin(
const TreeT& tree) {
1205 return tree.cbeginRootChildren();
1209 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1210 static typename TreeT::RootNodeType::ChildOffIter
begin(TreeT& tree) {
1211 return tree.beginRootTiles();
1215 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1216 static typename TreeT::RootNodeType::ChildOffCIter
begin(
const TreeT& tree) {
1217 return tree.cbeginRootTiles();
1221 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1222 static typename TreeT::RootNodeType::ChildAllIter
begin(TreeT& tree) {
1223 return tree.beginRootDense();
1227 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1228 static typename TreeT::RootNodeType::ChildAllCIter
begin(
const TreeT& tree) {
1229 return tree.cbeginRootDense();
1234 static typename TreeT::NodeIter
begin(TreeT& tree) {
return tree.beginNode(); }
1238 static typename TreeT::NodeCIter
begin(
const TreeT& tree) {
return tree.cbeginNode(); }
1242 static typename TreeT::LeafIter
begin(TreeT& tree) {
return tree.beginLeaf(); }
1246 static typename TreeT::LeafCIter
begin(
const TreeT& tree) {
return tree.cbeginLeaf(); }
1250 static typename TreeT::ValueOnIter
begin(TreeT& tree) {
return tree.beginValueOn(); }
1253 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1254 static typename TreeT::ValueOnCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOn(); }
1257 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1258 static typename TreeT::ValueOffIter
begin(TreeT& tree) {
return tree.beginValueOff(); }
1261 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1262 static typename TreeT::ValueOffCIter
begin(
const TreeT& tree) {
return tree.cbeginValueOff(); }
1265 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1266 static typename TreeT::ValueAllIter
begin(TreeT& tree) {
return tree.beginValueAll(); }
1269 template<
typename TreeT>
struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1270 static typename TreeT::ValueAllCIter
begin(
const TreeT& tree) {
return tree.cbeginValueAll(); }
1274 template<
typename RootNodeType>
1275 template<
typename IterT>
1283 template<
typename RootNodeType>
1284 template<
typename IterT>
1295 template<
typename RootNodeType>
1299 this->clearAllAccessors();
1301 mRoot.readTopology(is, saveFloatAsHalf);
1305 template<
typename RootNodeType>
1310 mRoot.writeTopology(os, saveFloatAsHalf);
1314 template<
typename RootNodeType>
1318 this->clearAllAccessors();
1319 mRoot.readBuffers(is, saveFloatAsHalf);
1323 template<
typename RootNodeType>
1334 template<
typename RootNodeType>
1338 typename AccessorRegistry::accessor a;
1339 mAccessorRegistry.insert(a, &accessor);
1343 template<
typename RootNodeType>
1347 typename ConstAccessorRegistry::accessor a;
1348 mConstAccessorRegistry.insert(a, &accessor);
1352 template<
typename RootNodeType>
1356 mAccessorRegistry.erase(&accessor);
1360 template<
typename RootNodeType>
1364 mConstAccessorRegistry.erase(&accessor);
1368 template<
typename RootNodeType>
1372 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1373 it != mAccessorRegistry.end(); ++it)
1375 if (it->first) it->first->
clear();
1378 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1379 it != mConstAccessorRegistry.end(); ++it)
1381 if (it->first) it->first->clear();
1386 template<
typename RootNodeType>
1390 mAccessorRegistry.erase(NULL);
1391 for (
typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1392 it != mAccessorRegistry.end(); ++it)
1394 it->first->release();
1396 mAccessorRegistry.
clear();
1398 mAccessorRegistry.erase(NULL);
1399 for (
typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1400 it != mConstAccessorRegistry.end(); ++it)
1402 it->first->release();
1404 mConstAccessorRegistry.clear();
1411 template<
typename RootNodeType>
1412 inline const typename RootNodeType::ValueType&
1419 template<
typename RootNodeType>
1420 template<
typename AccessT>
1421 inline const typename RootNodeType::ValueType&
1428 template<
typename RootNodeType>
1436 template<
typename RootNodeType>
1444 template<
typename RootNodeType>
1452 template<
typename RootNodeType>
1460 template<
typename RootNodeType>
1467 template<
typename RootNodeType>
1474 template<
typename RootNodeType>
1475 template<
typename AccessT>
1483 template<
typename RootNodeType>
1491 template<
typename RootNodeType>
1499 template<
typename RootNodeType>
1500 template<
typename ModifyOp>
1508 template<
typename RootNodeType>
1509 template<
typename ModifyOp>
1517 template<
typename RootNodeType>
1528 template<
typename RootNodeType>
1529 template<
typename PruneOp>
1533 this->clearAllAccessors();
1538 template<
typename RootNodeType>
1547 template<
typename RootNodeType>
1556 template<
typename RootNodeType>
1560 this->pruneInactive(this->background());
1564 template<
typename RootNodeType>
1573 template<
typename RootNodeType>
1578 mRoot.
addTile(level, xyz, value, active);
1582 template<
typename RootNodeType>
1583 template<
typename NodeT>
1587 this->clearAllAccessors();
1588 return mRoot.template stealNode<NodeT>(xyz, value, active);
1592 template<
typename RootNodeType>
1593 inline typename RootNodeType::LeafNodeType*
1600 template<
typename RootNodeType>
1601 inline typename RootNodeType::LeafNodeType*
1608 template<
typename RootNodeType>
1609 inline const typename RootNodeType::LeafNodeType*
1616 template<
typename RootNodeType>
1617 template<
typename NodeType>
1621 return mRoot.template probeNode<NodeType>(xyz);
1625 template<
typename RootNodeType>
1626 template<
typename NodeType>
1627 inline const NodeType*
1630 return this->
template probeConstNode<NodeType>(xyz);
1634 template<
typename RootNodeType>
1635 template<
typename NodeType>
1636 inline const NodeType*
1639 return mRoot.template probeConstNode<NodeType>(xyz);
1646 template<
typename RootNodeType>
1650 this->clearAllAccessors();
1651 return mRoot.fill(bbox, value, active);
1655 template<
typename RootNodeType>
1663 template<
typename RootNodeType>
1671 if (MetadataT* m = dynamic_cast<MetadataT*>(result.get())) {
1672 m->value() = mRoot.background();
1682 template<
typename RootNodeType>
1686 this->clearAllAccessors();
1687 mRoot.voxelizeActiveTiles();
1691 template<
typename RootNodeType>
1695 this->clearAllAccessors();
1699 mRoot.template merge<MERGE_ACTIVE_STATES>(other.
mRoot);
break;
1701 mRoot.template merge<MERGE_NODES>(other.
mRoot);
break;
1703 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.
mRoot);
break;
1708 template<
typename RootNodeType>
1709 template<
typename OtherRootNodeType>
1713 this->clearAllAccessors();
1714 mRoot.topologyUnion(other.
root());
1717 template<
typename RootNodeType>
1718 template<
typename OtherRootNodeType>
1722 this->clearAllAccessors();
1723 mRoot.topologyIntersection(other.
root());
1726 template<
typename RootNodeType>
1727 template<
typename OtherRootNodeType>
1731 this->clearAllAccessors();
1732 mRoot.topologyDifference(other.
root());
1740 template<
typename AValueT,
typename CombineOp,
typename BValueT = AValueT>
1746 op(args.
a(), args.
b(), args.
result());
1753 template<
typename RootNodeType>
1754 template<
typename CombineOp>
1759 this->combineExtended(other, extendedOp, prune);
1766 template<
typename RootNodeType>
1767 template<
typename CombineOp>
1772 this->combineExtended(other, extendedOp, prune);
1777 template<
typename RootNodeType>
1778 template<
typename ExtendedCombineOp>
1782 this->clearAllAccessors();
1783 mRoot.combine(other.
root(), op, prune);
1790 template<
typename RootNodeType>
1791 template<
typename ExtendedCombineOp>
1795 this->clearAllAccessors();
1796 mRoot.template combine<const ExtendedCombineOp>(other.
mRoot, op, prune);
1801 template<
typename RootNodeType>
1802 template<
typename CombineOp,
typename OtherTreeType>
1807 this->combine2Extended(a, b, extendedOp, prune);
1814 template<
typename RootNodeType>
1815 template<
typename CombineOp,
typename OtherTreeType>
1820 this->combine2Extended(a, b, extendedOp, prune);
1825 template<
typename RootNodeType>
1826 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1829 ExtendedCombineOp& op,
bool prune)
1831 this->clearAllAccessors();
1832 mRoot.combine2(a.
root(), b.root(), op, prune);
1840 template<
typename RootNodeType>
1841 template<
typename ExtendedCombineOp,
typename OtherTreeType>
1844 const ExtendedCombineOp& op,
bool prune)
1846 this->clearAllAccessors();
1847 mRoot.template combine2<const ExtendedCombineOp>(a.
root(), b.root(), op, prune);
1855 template<
typename RootNodeType>
1856 template<
typename VisitorOp>
1860 this->clearAllAccessors();
1861 mRoot.template visit<VisitorOp>(op);
1865 template<
typename RootNodeType>
1866 template<
typename VisitorOp>
1870 mRoot.template visit<VisitorOp>(op);
1876 template<
typename RootNodeType>
1877 template<
typename VisitorOp>
1881 this->clearAllAccessors();
1882 mRoot.template visit<const VisitorOp>(op);
1888 template<
typename RootNodeType>
1889 template<
typename VisitorOp>
1893 mRoot.template visit<const VisitorOp>(op);
1900 template<
typename RootNodeType>
1901 template<
typename OtherTreeType,
typename VisitorOp>
1905 this->clearAllAccessors();
1906 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1907 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
1911 template<
typename RootNodeType>
1912 template<
typename OtherTreeType,
typename VisitorOp>
1916 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1917 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
1923 template<
typename RootNodeType>
1924 template<
typename OtherTreeType,
typename VisitorOp>
1928 this->clearAllAccessors();
1929 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1930 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
1936 template<
typename RootNodeType>
1937 template<
typename OtherTreeType,
typename VisitorOp>
1941 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
1942 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
1949 template<
typename RootNodeType>
1953 static tbb::atomic<const Name*> sTypeName;
1954 if (sTypeName == NULL) {
1955 std::vector<Index> dims;
1956 Tree::getNodeLog2Dims(dims);
1957 std::ostringstream ostr;
1958 ostr <<
"Tree_" << typeNameAsString<ValueType>();
1959 for (
size_t i = 1, N = dims.size(); i < N; ++i) {
1960 ostr <<
"_" << dims[i];
1963 if (sTypeName.compare_and_swap(s, NULL) != NULL)
delete s;
1969 template<
typename RootNodeType>
1970 template<
typename OtherRootNodeType>
1978 template<
typename RootNodeType>
1983 this->evalActiveVoxelDim(dim);
1985 totalVoxels = dim.x() * dim.y() * dim.z(),
1986 activeVoxels = this->activeVoxelCount();
1987 assert(totalVoxels >= activeVoxels);
1988 return totalVoxels - activeVoxels;
1992 template<
typename RootNodeType>
1998 if (this->empty())
return false;
2000 mRoot.evalActiveBoundingBox(bbox,
false);
2005 template<
typename RootNodeType>
2011 if (this->empty())
return false;
2013 mRoot.evalActiveBoundingBox(bbox,
true);
2019 template<
typename RootNodeType>
2024 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2025 dim = bbox.extents();
2030 template<
typename RootNodeType>
2035 bool notEmpty = this->evalLeafBoundingBox(bbox);
2036 dim = bbox.extents();
2041 template<
typename RootNodeType>
2045 minVal = maxVal = zeroVal<ValueType>();
2047 minVal = maxVal = *iter;
2048 for (++iter; iter; ++iter) {
2050 if (val < minVal) minVal = val;
2051 if (val > maxVal) maxVal = val;
2057 template<
typename RootNodeType>
2062 RootNodeType::getNodeLog2Dims(dims);
2066 template<
typename RootNodeType>
2070 if (verboseLevel <= 0)
return;
2074 std::streamsize savedPrecision;
2075 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2076 ~OnExit() { os.precision(savedPrecision); }
2078 OnExit restorePrecision(os);
2080 std::vector<Index> dims;
2081 Tree::getNodeLog2Dims(dims);
2083 std::vector<Index64> nodeCount;
2085 os <<
"Information about Tree:\n"
2086 <<
" Type: " << this->type() <<
"\n";
2088 os <<
" Configuration:\n";
2089 if (verboseLevel <= 1) {
2091 os <<
" Root(" << mRoot.getTableSize() <<
")";
2092 if (dims.size() > 1) {
2093 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2094 os <<
", Internal(" << (1 << dims[i]) <<
"^3)";
2096 os <<
", Leaf(" << (1 << *dims.rbegin()) <<
"^3)\n";
2100 nodeCount.resize(dims.size());
2101 for (
NodeCIter it = cbeginNode(); it; ++it) {
2102 ++(nodeCount[it.getDepth()]);
2104 os <<
" Root(1 x " << mRoot.getTableSize() <<
")";
2105 if (dims.size() > 1) {
2106 for (
size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2108 os <<
" x " << (1 << dims[i]) <<
"^3)";
2111 os <<
" x " << (1 << *dims.rbegin()) <<
"^3)\n";
2114 os <<
" Background value: " << mRoot.background() <<
"\n";
2116 if (verboseLevel == 1)
return;
2120 if (nodeCount.empty()) {
2121 nodeCount.resize(dims.size());
2122 for (
NodeCIter it = cbeginNode(); it; ++it) {
2123 ++(nodeCount[it.getDepth()]);
2129 this->evalMinMax(minVal, maxVal);
2130 os <<
" Min value: " << minVal <<
"\n";
2131 os <<
" Max value: " << maxVal <<
"\n";
2134 leafCount = *nodeCount.rbegin(),
2135 numActiveVoxels = this->activeVoxelCount(),
2136 numActiveLeafVoxels = this->activeLeafVoxelCount();
2141 uint64_t totalVoxels = 0;
2142 if (numActiveVoxels) {
2144 this->evalActiveVoxelBoundingBox(bbox);
2145 dim = bbox.extents();
2146 totalVoxels = dim.x() * uint64_t(dim.y()) * dim.z();
2148 os <<
" Bounding box of active voxels: " << bbox <<
"\n";
2149 os <<
" Dimensions of active voxels: "
2150 << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
2152 const double activeRatio = (100.0 * numActiveVoxels) / totalVoxels;
2153 os <<
" Percentage of active voxels: " << std::setprecision(3) << activeRatio <<
"%\n";
2156 const double fillRatio =
2157 (100.0 * numActiveLeafVoxels) / (leafCount * LeafNodeType::NUM_VOXELS);
2158 os <<
" Average leaf node fill ratio: " << fillRatio <<
"%\n";
2161 os <<
" Tree is empty!\n";
2165 if (verboseLevel == 2)
return;
2169 actualMem = this->memUsage(),
2170 denseMem =
sizeof(
ValueType) * totalVoxels,
2171 voxelsMem =
sizeof(
ValueType) * numActiveLeafVoxels;
2174 os <<
"Memory footprint:\n";
2178 if (numActiveVoxels) {
2180 os <<
" Actual footprint is " << (100.0 * actualMem / denseMem)
2181 <<
"% of dense* footprint\n";
2182 os <<
" Leaf voxel footprint is " << (100.0 * voxelsMem / actualMem)
2183 <<
"% of actual footprint\n";
2184 os <<
" *Dense refers to the smallest equivalent non-sparse volume" << std::endl;
2192 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
Tree< RootNode< InternalNode< InternalNode< InternalNode< LeafNode< T, N4 >, N3 >, N2 >, N1 > > > Type
Definition: Tree.h:1151
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
virtual Index64 inactiveLeafVoxelCount() const
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:342
void setBackground(const ValueType &background)
Replace this tree's background value.
Definition: Tree.h:557
TreeValueIteratorBase< Tree, typename RootNodeType::ValueOnIter > ValueOnIter
Definition: Tree.h:1071
RootNodeType::ChildAllIter beginRootDense()
Return an iterator over all entries of the root node's table.
Definition: Tree.h:1039
TreeValueIteratorBase< Tree, typename RootNodeType::ValueOffIter > ValueOffIter
Definition: Tree.h:1073
ValueOnCIter cbeginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1086
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1238
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1254
virtual Index64 activeLeafVoxelCount() const
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:340
virtual Index64 activeVoxelCount() const
Return the total number of active voxels.
Definition: Tree.h:344
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:533
void signedFloodFill()
Set the values of all inactive voxels and tiles of a narrow-band level set from the signs of the acti...
Definition: Tree.h:566
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1262
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)
Tree5::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.
Definition: Tree.h:1149
void visitActiveBBox(BBoxOp &op) const
Use sparse traversal to call the given functor with bounding box information for all active tiles and...
Definition: Tree.h:885
boost::shared_ptr< const TreeBase > ConstPtr
Definition: Tree.h:68
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:438
NodeCIter cbeginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1059
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:205
virtual void readTopology(std::istream &, bool saveFloatAsHalf=false)
Read the tree topology from a stream.
Definition: Tree.h:1159
ValueOnCIter beginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1085
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1370
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:1502
ValueOffCIter beginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1091
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:964
Index32 Index
Definition: Types.h:57
boost::shared_ptr< const Tree > ConstPtr
Definition: Tree.h:182
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
LeafIteratorBase< const Tree, typename RootNodeType::ChildOnCIter > LeafCIter
Iterator over all leaf nodes in this tree.
Definition: Tree.h:1052
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueOnCIter > ValueOnCIter
Definition: Tree.h:1072
virtual Index32 nonLeafCount() const
Return the number of non-leaf nodes.
Definition: Tree.h:338
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1222
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1743
RootNodeType::ValueType ValueType
Definition: Tree.h:185
MergePolicy
Definition: Types.h:221
TreeValueIteratorBase< Tree, typename RootNodeType::ValueAllIter > ValueAllIter
Definition: Tree.h:1069
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1198
virtual const Name & type() const
Return the name of this type of tree.
Definition: Tree.h:272
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.
Definition: Tree.h:1594
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1228
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:252
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:355
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:1430
Helper class for use with Tree::pruneOp() to replace constant branches (to within the provided tolera...
Definition: tree/Util.h:47
Index64 activeTileCount() const
Definition: Tree.h:350
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:486
OPENVDB_DEPRECATED const RootNodeType & getRootNode() const
Return this tree's root node.
Definition: Tree.h:286
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:440
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:442
RootNodeType::ChildOnIter beginRootChildren()
Return an iterator over children of the root node.
Definition: Tree.h:1025
virtual TreeBase::Ptr copy() const
Return a pointer to a deep copy of this tree.
Definition: Tree.h:264
RootNodeType::ChildAllCIter cbeginRootDense() const
Return an iterator over all entries of the root node's table.
Definition: Tree.h:1038
RootNodeType mRoot
Definition: Tree.h:1118
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1242
const AValueType & result() const
Get the output value.
Definition: Types.h:295
Tree< RootNode< InternalNode< LeafNode< T, N2 >, N1 > > > Type
Definition: Tree.h:1130
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: Tree.h:1485
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1234
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:216
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 NULL.
Definition: Tree.h:1610
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: Tree.h:1602
virtual Metadata::Ptr getBackgroundValue() const
Return this tree's background value wrapped as metadata.
Definition: Tree.h:87
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1270
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1745
ValueOffCIter cbeginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1092
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:265
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:102
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:1972
ValueConverter::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition: Tree.h:197
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1216
Tree4::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.
Definition: Tree.h:1139
Internal table nodes for OpenVDB trees.
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:141
uint64_t Index64
Definition: Types.h:56
#define OPENVDB_VERSION_NAME
Definition: version.h:45
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1519
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1246
CombineOp & op
Definition: Tree.h:1749
virtual Index treeDepth() const
Return the depth of this tree.
Definition: Tree.h:334
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1066
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1266
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueOffCIter > ValueOffCIter
Definition: Tree.h:1074
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:39
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: Tree.h:1438
NodeIteratorBase< const Tree, typename RootNodeType::ChildOnCIter > NodeCIter
Iterator over all nodes in this tree.
Definition: Tree.h:1046
Base class for typed trees.
Definition: Tree.h:64
const AValueType & a() const
Get the A input value.
Definition: Types.h:290
RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:186
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1195
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 NULL.
Definition: Tree.h:521
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1119
Helper class for use with Tree::pruneOp() to prune any branches whose values are all inactive and rep...
Definition: tree/Util.h:99
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1210
TreeBase()
Definition: Tree.h:70
tbb::concurrent_hash_map< ValueAccessorBase< const Tree > *, bool > ConstAccessorRegistry
Definition: Tree.h:1105
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1250
const ValueType & background() const
Return this tree's background value.
Definition: Tree.h:555
boost::shared_ptr< TreeBase > Ptr
Definition: Tree.h:67
uint32_t Index32
Definition: Types.h:55
Tree3::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition: Tree.h:1129
Tree()
Definition: Tree.h:202
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:658
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels) ...
Definition: TreeIterator.h:1211
ValueAllCIter cbeginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1080
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1413
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:1575
const BValueType & b() const
Get the B input value.
Definition: Types.h:292
Helper class for use with Tree::pruneOp() to replace inactive branches with more memory-efficient ina...
Definition: tree/Util.h:74
_RootNodeType RootNodeType
Definition: Tree.h:184
NodeCIter beginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1058
Tree< RootNode< InternalNode< InternalNode< LeafNode< T, N3 >, N2 >, N1 > > > Type
Definition: Tree.h:1140
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:1176
Definition: Exceptions.h:84
tbb::concurrent_hash_map< ValueAccessorBase< Tree > *, bool > AccessorRegistry
Definition: Tree.h:1104
The root node of an OpenVDB tree.
RootNodeType & root()
Return this tree's root node.
Definition: Tree.h:279
RootNodeType::ChildOffIter beginRootTiles()
Return an iterator over non-child entries of the root node's table.
Definition: Tree.h:1032
RootNodeType::ChildOnCIter cbeginRootChildren() const
Return an iterator over children of the root node.
Definition: Tree.h:1024
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:259
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:1454
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1204
LeafCIter beginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1065
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:530
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1258
ValueAllCIter beginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1079
const RootNodeType & root() const
Return this tree's root node.
Definition: Tree.h:280
boost::shared_ptr< Tree > Ptr
Definition: Tree.h:181
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:1462
virtual void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const
Write out all data buffers for this tree.
Definition: Tree.h:1325
RootNodeType::ChildOffCIter cbeginRootTiles() const
Return an iterator over non-child entries of the root node's table.
Definition: Tree.h:1031
virtual ~Tree()
Definition: Tree.h:261
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
virtual void getIndexRange(CoordBBox &bbox) const
Min and max are both inclusive.
Definition: Tree.h:560
virtual ~TreeBase()
Definition: Tree.h:71
virtual Name valueType() const
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
Definition: Tree.h:267
virtual void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const
Write the tree topology to a stream.
Definition: Tree.h:1168
Tree< typename RootNodeType::template ValueConverter< OtherValueType >::Type > Type
Definition: Tree.h:198
virtual Index32 leafCount() const
Return the number of leaf nodes.
Definition: Tree.h:336
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:231
bool operator!=(const Tree &) const
Definition: Tree.h:275
bool operator==(const Tree &) const
Definition: Tree.h:274
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:1469
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1120
std::string Name
Definition: Name.h:44
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1511
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:130
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1741
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueAllCIter > ValueAllCIter
Definition: Tree.h:1070