OpenVDB: Tree.h Source File

OpenVDB 8.1.0

Tree.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
5
6 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
8
9 #include <openvdb/Types.h>
10 #include <openvdb/Metadata.h>
11 #include <openvdb/math/Math.h>
12 #include <openvdb/math/BBox.h>
13 #include <openvdb/tools/Count.h> // tools::countActiveVoxels(), tools::memUsage()
14 #include <openvdb/util/Formats.h>
15 #include <openvdb/util/logging.h>
16 #include <openvdb/Platform.h>
17 #include "RootNode.h"
18 #include "InternalNode.h"
19 #include "LeafNode.h"
20 #include "TreeIterator.h"
21 #include "ValueAccessor.h"
22 #include <tbb/concurrent_hash_map.h>
23 #include <cstdint>
24 #include <iostream>
25 #include <mutex>
26 #include <sstream>
27 #include <vector>
28
29
30 namespace openvdb {
31 OPENVDB_USE_VERSION_NAMESPACE
32 namespace OPENVDB_VERSION_NAME {
33 namespace tree {
34
36 class OPENVDB_API TreeBase
37 {
38 public:
39 using Ptr = SharedPtr<TreeBase>;
40 using ConstPtr = SharedPtr<const TreeBase>;
41
42 TreeBase() = default;
43 TreeBase(const TreeBase&) = default;
44 TreeBase& operator=(const TreeBase&) = delete; // disallow assignment
45 virtual ~TreeBase() = default;
46
48 virtual const Name& type() const = 0;
49
51 virtual Name valueType() const = 0;
52
54 virtual TreeBase::Ptr copy() const = 0;
55
56 //
57 // Tree methods
58 //
61 virtual Metadata::Ptr getBackgroundValue() const { return Metadata::Ptr(); }
62
70 virtual bool evalLeafBoundingBox(CoordBBox& bbox) const = 0;
71
75 virtual bool evalLeafDim(Coord& dim) const = 0;
76
84 virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const = 0;
85
89 virtual bool evalActiveVoxelDim(Coord& dim) const = 0;
90
91 virtual void getIndexRange(CoordBBox& bbox) const = 0;
92
98 virtual void clipUnallocatedNodes() = 0;
100 virtual Index32 unallocatedLeafCount() const = 0;
101
102
103 //
104 // Statistics
105 //
109 virtual Index treeDepth() const = 0;
111 virtual Index32 leafCount() const = 0;
112 #if OPENVDB_ABI_VERSION_NUMBER >= 7
116 virtual std::vector<Index32> nodeCount() const = 0;
117 #endif
119 virtual Index32 nonLeafCount() const = 0;
121 virtual Index64 activeLeafVoxelCount() const = 0;
123 virtual Index64 inactiveLeafVoxelCount() const = 0;
125 virtual Index64 activeVoxelCount() const = 0;
127 virtual Index64 inactiveVoxelCount() const = 0;
129 virtual Index64 activeTileCount() const = 0;
130
132 virtual Index64 memUsage() const { return 0; }
133
134
135 //
136 // I/O methods
137 //
141 virtual void readTopology(std::istream&, bool saveFloatAsHalf = false);
145 virtual void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const;
146
148 virtual void readBuffers(std::istream&, bool saveFloatAsHalf = false) = 0;
150 virtual void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false) = 0;
156 virtual void readNonresidentBuffers() const = 0;
158 virtual void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const = 0;
159
167 virtual void print(std::ostream& os = std::cout, int verboseLevel = 1) const;
168 };
169
170
172
173
174 template<typename _RootNodeType>
175 class Tree: public TreeBase
176 {
177 public:
178 using Ptr = SharedPtr<Tree>;
179 using ConstPtr = SharedPtr<const Tree>;
180
181 using RootNodeType = _RootNodeType;
182 using ValueType = typename RootNodeType::ValueType;
183 using BuildType = typename RootNodeType::BuildType;
184 using LeafNodeType = typename RootNodeType::LeafNodeType;
185
186 static const Index DEPTH = RootNodeType::LEVEL + 1;
187
194 template<typename OtherValueType>
195 struct ValueConverter {
196 using Type = Tree<typename RootNodeType::template ValueConverter<OtherValueType>::Type>;
197 };
198
199
200 Tree() {}
201
202 Tree& operator=(const Tree&) = delete; // disallow assignment
203
205 Tree(const Tree& other): TreeBase(other), mRoot(other.mRoot)
206 {
207 }
208
215 template<typename OtherRootType>
216 explicit Tree(const Tree<OtherRootType>& other): TreeBase(other), mRoot(other.root())
217 {
218 }
219
230 template<typename OtherTreeType>
231 Tree(const OtherTreeType& other,
232 const ValueType& inactiveValue,
233 const ValueType& activeValue,
234 TopologyCopy):
235 TreeBase(other),
236 mRoot(other.root(), inactiveValue, activeValue, TopologyCopy())
237 {
238 }
239
251 template<typename OtherTreeType>
252 Tree(const OtherTreeType& other, const ValueType& background, TopologyCopy):
253 TreeBase(other),
254 mRoot(other.root(), background, TopologyCopy())
255 {
256 }
257
259 Tree(const ValueType& background): mRoot(background) {}
260
261 ~Tree() override { this->clear(); releaseAllAccessors(); }
262
264 TreeBase::Ptr copy() const override { return TreeBase::Ptr(new Tree(*this)); }
265
267 Name valueType() const override { return typeNameAsString<ValueType>(); }
268
270 static const Name& treeType();
272 const Name& type() const override { return this->treeType(); }
273
274 bool operator==(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
275 bool operator!=(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
276
278 RootNodeType& root() { return mRoot; }
280 const RootNodeType& root() const { return mRoot; }
282
283
284 //
285 // Tree methods
286 //
289 template<typename OtherRootNodeType>
290 bool hasSameTopology(const Tree<OtherRootNodeType>& other) const;
291
292 bool evalLeafBoundingBox(CoordBBox& bbox) const override;
293 bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const override;
294 bool evalActiveVoxelDim(Coord& dim) const override;
295 bool evalLeafDim(Coord& dim) const override;
296
300 static void getNodeLog2Dims(std::vector<Index>& dims);
301
302
303 //
304 // I/O methods
305 //
309 void readTopology(std::istream&, bool saveFloatAsHalf = false) override;
313 void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const override;
315 void readBuffers(std::istream&, bool saveFloatAsHalf = false) override;
317 void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false) override;
323 void readNonresidentBuffers() const override;
325 void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const override;
326
327 void print(std::ostream& os = std::cout, int verboseLevel = 1) const override;
328
329
330 //
331 // Statistics
332 //
336 Index treeDepth() const override { return DEPTH; }
338 Index32 leafCount() const override { return mRoot.leafCount(); }
339 #if OPENVDB_ABI_VERSION_NUMBER >= 7
343 std::vector<Index32> nodeCount() const override
344 {
345 std::vector<Index32> vec(DEPTH, 0);
346 mRoot.nodeCount( vec );
347 return vec;// Named Return Value Optimization
348 }
349 #endif
351 Index32 nonLeafCount() const override { return mRoot.nonLeafCount(); }
353 Index64 activeLeafVoxelCount() const override { return mRoot.onLeafVoxelCount(); }
355 Index64 inactiveLeafVoxelCount() const override { return mRoot.offLeafVoxelCount(); }
357 Index64 activeVoxelCount() const override { return tools::countActiveVoxels(*this); }
359 Index64 inactiveVoxelCount() const override;
361 Index64 activeTileCount() const override { return mRoot.onTileCount(); }
362
364 void evalMinMax(ValueType &min, ValueType &max) const;
365
366 Index64 memUsage() const override { return tools::memUsage(*this); }
367
368
369 //
370 // Voxel access methods (using signed indexing)
371 //
373 const ValueType& getValue(const Coord& xyz) const;
376 template<typename AccessT> const ValueType& getValue(const Coord& xyz, AccessT&) const;
377
381 int getValueDepth(const Coord& xyz) const;
382
384 void setActiveState(const Coord& xyz, bool on);
386 void setValueOnly(const Coord& xyz, const ValueType& value);
388 void setValueOn(const Coord& xyz);
390 void setValueOn(const Coord& xyz, const ValueType& value);
392 void setValue(const Coord& xyz, const ValueType& value);
395 template<typename AccessT> void setValue(const Coord& xyz, const ValueType& value, AccessT&);
397 void setValueOff(const Coord& xyz);
399 void setValueOff(const Coord& xyz, const ValueType& value);
400
419 template<typename ModifyOp>
420 void modifyValue(const Coord& xyz, const ModifyOp& op);
421
441 template<typename ModifyOp>
442 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op);
443
446 bool probeValue(const Coord& xyz, ValueType& value) const;
447
449 bool isValueOn(const Coord& xyz) const { return mRoot.isValueOn(xyz); }
451 bool isValueOff(const Coord& xyz) const { return !this->isValueOn(xyz); }
453 bool hasActiveTiles() const { return mRoot.hasActiveTiles(); }
454
456 void clip(const CoordBBox&);
462 void clipUnallocatedNodes() override;
463
465 Index32 unallocatedLeafCount() const override;
466
468 void sparseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
477 void fill(const CoordBBox& bbox, const ValueType& value, bool active = true)
478 {
479 this->sparseFill(bbox, value, active);
480 }
482
490 void denseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
491
500 void voxelizeActiveTiles(bool threaded = true);
501
506 void prune(const ValueType& tolerance = zeroVal<ValueType>())
507 {
508 this->clearAllAccessors();
509 mRoot.prune(tolerance);
510 }
511
517 void addLeaf(LeafNodeType* leaf) { assert(leaf); mRoot.addLeaf(leaf); }
518
523 void addTile(Index level, const Coord& xyz, const ValueType& value, bool active);
524
529 template<typename NodeT>
530 NodeT* stealNode(const Coord& xyz, const ValueType& value, bool active);
531
537 LeafNodeType* touchLeaf(const Coord& xyz);
538
540 template<typename NodeType> NodeType* probeNode(const Coord& xyz);
543 template<typename NodeType> const NodeType* probeConstNode(const Coord& xyz) const;
544 template<typename NodeType> const NodeType* probeNode(const Coord& xyz) const;
546
548 LeafNodeType* probeLeaf(const Coord& xyz);
551 const LeafNodeType* probeConstLeaf(const Coord& xyz) const;
552 const LeafNodeType* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
554
556 template<typename ArrayT> void getNodes(ArrayT& array) { mRoot.getNodes(array); }
579 template<typename ArrayT> void getNodes(ArrayT& array) const { mRoot.getNodes(array); }
581
605 template<typename ArrayT>
606 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
607 template<typename ArrayT>
608 void stealNodes(ArrayT& array, const ValueType& value, bool state)
609 {
610 this->clearAllAccessors();
611 mRoot.stealNodes(array, value, state);
612 }
613
614 //
615 // Aux methods
616 //
619 bool empty() const { return mRoot.empty(); }
620
622 void clear();
623
625 void clearAllAccessors();
626
628 void attachAccessor(ValueAccessorBase<Tree, true>&) const;
631 void attachAccessor(ValueAccessorBase<const Tree, true>&) const;
633
635 void attachAccessor(ValueAccessorBase<Tree, false>&) const {}
637 void attachAccessor(ValueAccessorBase<const Tree, false>&) const {}
639
641 void releaseAccessor(ValueAccessorBase<Tree, true>&) const;
643 void releaseAccessor(ValueAccessorBase<const Tree, true>&) const;
645
647 void releaseAccessor(ValueAccessorBase<Tree, false>&) const {}
649 void releaseAccessor(ValueAccessorBase<const Tree, false>&) const {}
651
654 Metadata::Ptr getBackgroundValue() const override;
655
661 const ValueType& background() const { return mRoot.background(); }
662
664 void getIndexRange(CoordBBox& bbox) const override { mRoot.getIndexRange(bbox); }
665
673 void merge(Tree& other, MergePolicy = MERGE_ACTIVE_STATES);
674
691 template<typename OtherRootNodeType>
692 void topologyUnion(const Tree<OtherRootNodeType>& other, const bool preserveTiles = false);
693
707 template<typename OtherRootNodeType>
708 void topologyIntersection(const Tree<OtherRootNodeType>& other);
709
720 template<typename OtherRootNodeType>
721 void topologyDifference(const Tree<OtherRootNodeType>& other);
722
767 template<typename CombineOp>
768 void combine(Tree& other, CombineOp& op, bool prune = false);
769 #ifndef _MSC_VER
770 template<typename CombineOp>
771 void combine(Tree& other, const CombineOp& op, bool prune = false);
772 #endif
773
812 template<typename ExtendedCombineOp>
813 void combineExtended(Tree& other, ExtendedCombineOp& op, bool prune = false);
814 #ifndef _MSC_VER
815 template<typename ExtendedCombineOp>
816 void combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune = false);
817 #endif
818
847 template<typename CombineOp, typename OtherTreeType /*= Tree*/>
848 void combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune = false);
849 #ifndef _MSC_VER
850 template<typename CombineOp, typename OtherTreeType /*= Tree*/>
851 void combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune = false);
852 #endif
853
927 template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
928 void combine2Extended(const Tree& a, const OtherTreeType& b, ExtendedCombineOp& op,
929 bool prune = false);
930 #ifndef _MSC_VER
931 template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
932 void combine2Extended(const Tree& a, const OtherTreeType& b, const ExtendedCombineOp&,
933 bool prune = false);
934 #endif
935
936 template<typename BBoxOp>
937 OPENVDB_DEPRECATED_MESSAGE("Use tools::visitNodesDepthFirst or DynamicNodeManager instead")
938 void visitActiveBBox(BBoxOp& op) const { mRoot.visitActiveBBox(op); }
939
940 template<typename VisitorOp>
941 OPENVDB_DEPRECATED_MESSAGE("Use tools::visitNodesDepthFirst or DynamicNodeManager instead")
942 void visit(VisitorOp& op);
943 template<typename VisitorOp>
944 OPENVDB_DEPRECATED_MESSAGE("Use tools::visitNodesDepthFirst or DynamicNodeManager instead")
945 void visit(const VisitorOp& op);
946
947 template<typename VisitorOp>
948 OPENVDB_DEPRECATED_MESSAGE("Use tools::visitNodesDepthFirst or DynamicNodeManager instead")
949 void visit(VisitorOp& op) const;
950 template<typename VisitorOp>
951 OPENVDB_DEPRECATED_MESSAGE("Use tools::visitNodesDepthFirst or DynamicNodeManager instead")
952 void visit(const VisitorOp& op) const;
953
954 template<typename OtherTreeType, typename VisitorOp>
955 OPENVDB_DEPRECATED_MESSAGE("Use tools::visitNodesDepthFirst or DynamicNodeManager instead")
956 void visit2(OtherTreeType& other, VisitorOp& op);
957 template<typename OtherTreeType, typename VisitorOp>
958 OPENVDB_DEPRECATED_MESSAGE("Use tools::visitNodesDepthFirst or DynamicNodeManager instead")
959 void visit2(OtherTreeType& other, const VisitorOp& op);
960
961 template<typename OtherTreeType, typename VisitorOp>
962 OPENVDB_DEPRECATED_MESSAGE("Use tools::visitNodesDepthFirst or DynamicNodeManager instead")
963 void visit2(OtherTreeType& other, VisitorOp& op) const;
964 template<typename OtherTreeType, typename VisitorOp>
965 OPENVDB_DEPRECATED_MESSAGE("Use tools::visitNodesDepthFirst or DynamicNodeManager instead")
966 void visit2(OtherTreeType& other, const VisitorOp& op) const;
967
968
969 //
970 // Iteration
971 //
973 typename RootNodeType::ChildOnCIter beginRootChildren() const { return mRoot.cbeginChildOn(); }
975 typename RootNodeType::ChildOnCIter cbeginRootChildren() const { return mRoot.cbeginChildOn(); }
976 typename RootNodeType::ChildOnIter beginRootChildren() { return mRoot.beginChildOn(); }
978
980 typename RootNodeType::ChildOffCIter beginRootTiles() const { return mRoot.cbeginChildOff(); }
982 typename RootNodeType::ChildOffCIter cbeginRootTiles() const { return mRoot.cbeginChildOff(); }
983 typename RootNodeType::ChildOffIter beginRootTiles() { return mRoot.beginChildOff(); }
985
987 typename RootNodeType::ChildAllCIter beginRootDense() const { return mRoot.cbeginChildAll(); }
989 typename RootNodeType::ChildAllCIter cbeginRootDense() const { return mRoot.cbeginChildAll(); }
990 typename RootNodeType::ChildAllIter beginRootDense() { return mRoot.beginChildAll(); }
992
993
995 using NodeIter = NodeIteratorBase<Tree, typename RootNodeType::ChildOnIter>;
997 using NodeCIter = NodeIteratorBase<const Tree, typename RootNodeType::ChildOnCIter>;
999
1001 using LeafIter = LeafIteratorBase<Tree, typename RootNodeType::ChildOnIter>;
1003 using LeafCIter = LeafIteratorBase<const Tree, typename RootNodeType::ChildOnCIter>;
1005
1007 NodeIter beginNode() { return NodeIter(*this); }
1009 NodeCIter beginNode() const { return NodeCIter(*this); }
1010 NodeCIter cbeginNode() const { return NodeCIter(*this); }
1012
1014 LeafIter beginLeaf() { return LeafIter(*this); }
1016 LeafCIter beginLeaf() const { return LeafCIter(*this); }
1017 LeafCIter cbeginLeaf() const { return LeafCIter(*this); }
1019
1020 using ValueAllIter = TreeValueIteratorBase<Tree, typename RootNodeType::ValueAllIter>;
1021 using ValueAllCIter = TreeValueIteratorBase<const Tree, typename RootNodeType::ValueAllCIter>;
1022 using ValueOnIter = TreeValueIteratorBase<Tree, typename RootNodeType::ValueOnIter>;
1023 using ValueOnCIter = TreeValueIteratorBase<const Tree, typename RootNodeType::ValueOnCIter>;
1024 using ValueOffIter = TreeValueIteratorBase<Tree, typename RootNodeType::ValueOffIter>;
1025 using ValueOffCIter = TreeValueIteratorBase<const Tree, typename RootNodeType::ValueOffCIter>;
1026
1028 ValueAllIter beginValueAll() { return ValueAllIter(*this); }
1030 ValueAllCIter beginValueAll() const { return ValueAllCIter(*this); }
1031 ValueAllCIter cbeginValueAll() const { return ValueAllCIter(*this); }
1033
1034 ValueOnIter beginValueOn() { return ValueOnIter(*this); }
1036 ValueOnCIter beginValueOn() const { return ValueOnCIter(*this); }
1037 ValueOnCIter cbeginValueOn() const { return ValueOnCIter(*this); }
1039
1040 ValueOffIter beginValueOff() { return ValueOffIter(*this); }
1042 ValueOffCIter beginValueOff() const { return ValueOffCIter(*this); }
1043 ValueOffCIter cbeginValueOff() const { return ValueOffCIter(*this); }
1045
1048 template<typename IterT> IterT begin();
1051 template<typename CIterT> CIterT cbegin() const;
1052
1053
1054 protected:
1055 using AccessorRegistry = tbb::concurrent_hash_map<ValueAccessorBase<Tree, true>*, bool>;
1056 using ConstAccessorRegistry = tbb::concurrent_hash_map<ValueAccessorBase<const Tree, true>*, bool>;
1057
1060 void releaseAllAccessors();
1061
1062 // TBB body object used to deallocates nodes in parallel.
1063 template<typename NodeType>
1064 struct DeallocateNodes {
1065 DeallocateNodes(std::vector<NodeType*>& nodes)
1066 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1067 void operator()(const tbb::blocked_range<size_t>& range) const {
1068 for (size_t n = range.begin(), N = range.end(); n < N; ++n) {
1069 delete mNodes[n]; mNodes[n] = nullptr;
1070 }
1071 }
1072 NodeType ** const mNodes;
1073 };
1074
1075 //
1076 // Data members
1077 //
1078 RootNodeType mRoot; // root node of the tree
1079 mutable AccessorRegistry mAccessorRegistry;
1080 mutable ConstAccessorRegistry mConstAccessorRegistry;
1081
1082 static std::unique_ptr<const Name> sTreeTypeName;
1083 }; // end of Tree class
1084
1085 template<typename _RootNodeType>
1086 std::unique_ptr<const Name> Tree<_RootNodeType>::sTreeTypeName;
1087
1088
1093 template<typename T, Index N1=4, Index N2=3>
1094 struct Tree3 {
1095 using Type = Tree<RootNode<InternalNode<LeafNode<T, N2>, N1>>>;
1096 };
1097
1098
1103 template<typename T, Index N1=5, Index N2=4, Index N3=3>
1104 struct Tree4 {
1105 using Type = Tree<RootNode<InternalNode<InternalNode<LeafNode<T, N3>, N2>, N1>>>;
1106 };
1107
1112 template<typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1113 struct Tree5 {
1114 using Type =
1115 Tree<RootNode<InternalNode<InternalNode<InternalNode<LeafNode<T, N4>, N3>, N2>, N1>>>;
1116 };
1117
1118
1120
1121
1122 inline void
1123 TreeBase::readTopology(std::istream& is, bool /*saveFloatAsHalf*/)
1124 {
1125 int32_t bufferCount;
1126 is.read(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1127 if (bufferCount != 1) OPENVDB_LOG_WARN("multi-buffer trees are no longer supported");
1128 }
1129
1130
1131 inline void
1132 TreeBase::writeTopology(std::ostream& os, bool /*saveFloatAsHalf*/) const
1133 {
1134 int32_t bufferCount = 1;
1135 os.write(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1136 }
1137
1138
1139 inline void
1140 TreeBase::print(std::ostream& os, int /*verboseLevel*/) const
1141 {
1142 os << " Tree Type: " << type()
1143 << " Active Voxel Count: " << activeVoxelCount() << std::endl
1144 << " Active tile Count: " << activeTileCount() << std::endl
1145 << " Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1146 << " Leaf Node Count: " << leafCount() << std::endl
1147 << " Non-leaf Node Count: " << nonLeafCount() << std::endl;
1148 }
1149
1150
1152
1153
1154 //
1155 // Type traits for tree iterators
1156 //
1157
1160 template<typename TreeT, typename IterT> struct TreeIterTraits;
1161
1162 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1163 static typename TreeT::RootNodeType::ChildOnIter begin(TreeT& tree) {
1164 return tree.beginRootChildren();
1165 }
1166 };
1167
1168 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1169 static typename TreeT::RootNodeType::ChildOnCIter begin(const TreeT& tree) {
1170 return tree.cbeginRootChildren();
1171 }
1172 };
1173
1174 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1175 static typename TreeT::RootNodeType::ChildOffIter begin(TreeT& tree) {
1176 return tree.beginRootTiles();
1177 }
1178 };
1179
1180 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1181 static typename TreeT::RootNodeType::ChildOffCIter begin(const TreeT& tree) {
1182 return tree.cbeginRootTiles();
1183 }
1184 };
1185
1186 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1187 static typename TreeT::RootNodeType::ChildAllIter begin(TreeT& tree) {
1188 return tree.beginRootDense();
1189 }
1190 };
1191
1192 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1193 static typename TreeT::RootNodeType::ChildAllCIter begin(const TreeT& tree) {
1194 return tree.cbeginRootDense();
1195 }
1196 };
1197
1198 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeIter> {
1199 static typename TreeT::NodeIter begin(TreeT& tree) { return tree.beginNode(); }
1200 };
1201
1202 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeCIter> {
1203 static typename TreeT::NodeCIter begin(const TreeT& tree) { return tree.cbeginNode(); }
1204 };
1205
1206 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafIter> {
1207 static typename TreeT::LeafIter begin(TreeT& tree) { return tree.beginLeaf(); }
1208 };
1209
1210 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafCIter> {
1211 static typename TreeT::LeafCIter begin(const TreeT& tree) { return tree.cbeginLeaf(); }
1212 };
1213
1214 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnIter> {
1215 static typename TreeT::ValueOnIter begin(TreeT& tree) { return tree.beginValueOn(); }
1216 };
1217
1218 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1219 static typename TreeT::ValueOnCIter begin(const TreeT& tree) { return tree.cbeginValueOn(); }
1220 };
1221
1222 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1223 static typename TreeT::ValueOffIter begin(TreeT& tree) { return tree.beginValueOff(); }
1224 };
1225
1226 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1227 static typename TreeT::ValueOffCIter begin(const TreeT& tree) { return tree.cbeginValueOff(); }
1228 };
1229
1230 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1231 static typename TreeT::ValueAllIter begin(TreeT& tree) { return tree.beginValueAll(); }
1232 };
1233
1234 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1235 static typename TreeT::ValueAllCIter begin(const TreeT& tree) { return tree.cbeginValueAll(); }
1236 };
1237
1238
1239 template<typename RootNodeType>
1240 template<typename IterT>
1241 inline IterT
1242 Tree<RootNodeType>::begin()
1243 {
1244 return TreeIterTraits<Tree, IterT>::begin(*this);
1245 }
1246
1247
1248 template<typename RootNodeType>
1249 template<typename IterT>
1250 inline IterT
1251 Tree<RootNodeType>::cbegin() const
1252 {
1253 return TreeIterTraits<Tree, IterT>::begin(*this);
1254 }
1255
1256
1258
1259
1260 template<typename RootNodeType>
1261 void
1262 Tree<RootNodeType>::readTopology(std::istream& is, bool saveFloatAsHalf)
1263 {
1264 this->clearAllAccessors();
1265 TreeBase::readTopology(is, saveFloatAsHalf);
1266 mRoot.readTopology(is, saveFloatAsHalf);
1267 }
1268
1269
1270 template<typename RootNodeType>
1271 void
1272 Tree<RootNodeType>::writeTopology(std::ostream& os, bool saveFloatAsHalf) const
1273 {
1274 TreeBase::writeTopology(os, saveFloatAsHalf);
1275 mRoot.writeTopology(os, saveFloatAsHalf);
1276 }
1277
1278
1279 template<typename RootNodeType>
1280 inline void
1281 Tree<RootNodeType>::readBuffers(std::istream &is, bool saveFloatAsHalf)
1282 {
1283 this->clearAllAccessors();
1284 mRoot.readBuffers(is, saveFloatAsHalf);
1285 }
1286
1287
1288 template<typename RootNodeType>
1289 inline void
1290 Tree<RootNodeType>::readBuffers(std::istream &is, const CoordBBox& bbox, bool saveFloatAsHalf)
1291 {
1292 this->clearAllAccessors();
1293 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1294 }
1295
1296
1297 template<typename RootNodeType>
1298 inline void
1299 Tree<RootNodeType>::readNonresidentBuffers() const
1300 {
1301 for (LeafCIter it = this->cbeginLeaf(); it; ++it) {
1302 // Retrieving the value of a leaf voxel forces loading of the leaf node's voxel buffer.
1303 it->getValue(Index(0));
1304 }
1305 }
1306
1307
1308 template<typename RootNodeType>
1309 inline void
1310 Tree<RootNodeType>::writeBuffers(std::ostream &os, bool saveFloatAsHalf) const
1311 {
1312 mRoot.writeBuffers(os, saveFloatAsHalf);
1313 }
1314
1315
1316 template<typename RootNodeType>
1317 inline void
1318 Tree<RootNodeType>::clear()
1319 {
1320 std::vector<LeafNodeType*> leafnodes;
1321 this->stealNodes(leafnodes);
1322
1323 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1324 DeallocateNodes<LeafNodeType>(leafnodes));
1325
1326 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1327 this->stealNodes(internalNodes);
1328
1329 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1330 DeallocateNodes<typename RootNodeType::ChildNodeType>(internalNodes));
1331
1332 mRoot.clear();
1333
1334 this->clearAllAccessors();
1335 }
1336
1337
1339
1340
1341 template<typename RootNodeType>
1342 inline void
1343 Tree<RootNodeType>::attachAccessor(ValueAccessorBase<Tree, true>& accessor) const
1344 {
1345 typename AccessorRegistry::accessor a;
1346 mAccessorRegistry.insert(a, &accessor);
1347 }
1348
1349
1350 template<typename RootNodeType>
1351 inline void
1352 Tree<RootNodeType>::attachAccessor(ValueAccessorBase<const Tree, true>& accessor) const
1353 {
1354 typename ConstAccessorRegistry::accessor a;
1355 mConstAccessorRegistry.insert(a, &accessor);
1356 }
1357
1358
1359 template<typename RootNodeType>
1360 inline void
1361 Tree<RootNodeType>::releaseAccessor(ValueAccessorBase<Tree, true>& accessor) const
1362 {
1363 mAccessorRegistry.erase(&accessor);
1364 }
1365
1366
1367 template<typename RootNodeType>
1368 inline void
1369 Tree<RootNodeType>::releaseAccessor(ValueAccessorBase<const Tree, true>& accessor) const
1370 {
1371 mConstAccessorRegistry.erase(&accessor);
1372 }
1373
1374
1375 template<typename RootNodeType>
1376 inline void
1377 Tree<RootNodeType>::clearAllAccessors()
1378 {
1379 for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1380 it != mAccessorRegistry.end(); ++it)
1381 {
1382 if (it->first) it->first->clear();
1383 }
1384
1385 for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1386 it != mConstAccessorRegistry.end(); ++it)
1387 {
1388 if (it->first) it->first->clear();
1389 }
1390 }
1391
1392
1393 template<typename RootNodeType>
1394 inline void
1395 Tree<RootNodeType>::releaseAllAccessors()
1396 {
1397 mAccessorRegistry.erase(nullptr);
1398 for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1399 it != mAccessorRegistry.end(); ++it)
1400 {
1401 it->first->release();
1402 }
1403 mAccessorRegistry.clear();
1404
1405 mAccessorRegistry.erase(nullptr);
1406 for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1407 it != mConstAccessorRegistry.end(); ++it)
1408 {
1409 it->first->release();
1410 }
1411 mConstAccessorRegistry.clear();
1412 }
1413
1414
1416
1417
1418 template<typename RootNodeType>
1419 inline const typename RootNodeType::ValueType&
1420 Tree<RootNodeType>::getValue(const Coord& xyz) const
1421 {
1422 return mRoot.getValue(xyz);
1423 }
1424
1425
1426 template<typename RootNodeType>
1427 template<typename AccessT>
1428 inline const typename RootNodeType::ValueType&
1429 Tree<RootNodeType>::getValue(const Coord& xyz, AccessT& accessor) const
1430 {
1431 return accessor.getValue(xyz);
1432 }
1433
1434
1435 template<typename RootNodeType>
1436 inline int
1437 Tree<RootNodeType>::getValueDepth(const Coord& xyz) const
1438 {
1439 return mRoot.getValueDepth(xyz);
1440 }
1441
1442
1443 template<typename RootNodeType>
1444 inline void
1445 Tree<RootNodeType>::setValueOff(const Coord& xyz)
1446 {
1447 mRoot.setValueOff(xyz);
1448 }
1449
1450
1451 template<typename RootNodeType>
1452 inline void
1453 Tree<RootNodeType>::setValueOff(const Coord& xyz, const ValueType& value)
1454 {
1455 mRoot.setValueOff(xyz, value);
1456 }
1457
1458
1459 template<typename RootNodeType>
1460 inline void
1461 Tree<RootNodeType>::setActiveState(const Coord& xyz, bool on)
1462 {
1463 mRoot.setActiveState(xyz, on);
1464 }
1465
1466
1467 template<typename RootNodeType>
1468 inline void
1469 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value)
1470 {
1471 mRoot.setValueOn(xyz, value);
1472 }
1473
1474 template<typename RootNodeType>
1475 inline void
1476 Tree<RootNodeType>::setValueOnly(const Coord& xyz, const ValueType& value)
1477 {
1478 mRoot.setValueOnly(xyz, value);
1479 }
1480
1481 template<typename RootNodeType>
1482 template<typename AccessT>
1483 inline void
1484 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value, AccessT& accessor)
1485 {
1486 accessor.setValue(xyz, value);
1487 }
1488
1489
1490 template<typename RootNodeType>
1491 inline void
1492 Tree<RootNodeType>::setValueOn(const Coord& xyz)
1493 {
1494 mRoot.setActiveState(xyz, true);
1495 }
1496
1497
1498 template<typename RootNodeType>
1499 inline void
1500 Tree<RootNodeType>::setValueOn(const Coord& xyz, const ValueType& value)
1501 {
1502 mRoot.setValueOn(xyz, value);
1503 }
1504
1505
1506 template<typename RootNodeType>
1507 template<typename ModifyOp>
1508 inline void
1509 Tree<RootNodeType>::modifyValue(const Coord& xyz, const ModifyOp& op)
1510 {
1511 mRoot.modifyValue(xyz, op);
1512 }
1513
1514
1515 template<typename RootNodeType>
1516 template<typename ModifyOp>
1517 inline void
1518 Tree<RootNodeType>::modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1519 {
1520 mRoot.modifyValueAndActiveState(xyz, op);
1521 }
1522
1523
1524 template<typename RootNodeType>
1525 inline bool
1526 Tree<RootNodeType>::probeValue(const Coord& xyz, ValueType& value) const
1527 {
1528 return mRoot.probeValue(xyz, value);
1529 }
1530
1531
1533
1534
1535 template<typename RootNodeType>
1536 inline void
1537 Tree<RootNodeType>::addTile(Index level, const Coord& xyz,
1538 const ValueType& value, bool active)
1539 {
1540 mRoot.addTile(level, xyz, value, active);
1541 }
1542
1543
1544 template<typename RootNodeType>
1545 template<typename NodeT>
1546 inline NodeT*
1547 Tree<RootNodeType>::stealNode(const Coord& xyz, const ValueType& value, bool active)
1548 {
1549 this->clearAllAccessors();
1550 return mRoot.template stealNode<NodeT>(xyz, value, active);
1551 }
1552
1553
1554 template<typename RootNodeType>
1555 inline typename RootNodeType::LeafNodeType*
1556 Tree<RootNodeType>::touchLeaf(const Coord& xyz)
1557 {
1558 return mRoot.touchLeaf(xyz);
1559 }
1560
1561
1562 template<typename RootNodeType>
1563 inline typename RootNodeType::LeafNodeType*
1564 Tree<RootNodeType>::probeLeaf(const Coord& xyz)
1565 {
1566 return mRoot.probeLeaf(xyz);
1567 }
1568
1569
1570 template<typename RootNodeType>
1571 inline const typename RootNodeType::LeafNodeType*
1572 Tree<RootNodeType>::probeConstLeaf(const Coord& xyz) const
1573 {
1574 return mRoot.probeConstLeaf(xyz);
1575 }
1576
1577
1578 template<typename RootNodeType>
1579 template<typename NodeType>
1580 inline NodeType*
1581 Tree<RootNodeType>::probeNode(const Coord& xyz)
1582 {
1583 return mRoot.template probeNode<NodeType>(xyz);
1584 }
1585
1586
1587 template<typename RootNodeType>
1588 template<typename NodeType>
1589 inline const NodeType*
1590 Tree<RootNodeType>::probeNode(const Coord& xyz) const
1591 {
1592 return this->template probeConstNode<NodeType>(xyz);
1593 }
1594
1595
1596 template<typename RootNodeType>
1597 template<typename NodeType>
1598 inline const NodeType*
1599 Tree<RootNodeType>::probeConstNode(const Coord& xyz) const
1600 {
1601 return mRoot.template probeConstNode<NodeType>(xyz);
1602 }
1603
1604
1606
1607
1608 template<typename RootNodeType>
1609 inline void
1610 Tree<RootNodeType>::clip(const CoordBBox& bbox)
1611 {
1612 this->clearAllAccessors();
1613 return mRoot.clip(bbox);
1614 }
1615
1616
1617 template<typename RootNodeType>
1618 inline void
1619 Tree<RootNodeType>::clipUnallocatedNodes()
1620 {
1621 this->clearAllAccessors();
1622 for (LeafIter it = this->beginLeaf(); it; ) {
1623 const LeafNodeType* leaf = it.getLeaf();
1624 ++it; // advance the iterator before deleting the leaf node
1625 if (!leaf->isAllocated()) {
1626 this->addTile(/*level=*/0, leaf->origin(), this->background(), /*active=*/false);
1627 }
1628 }
1629 }
1630
1631 template<typename RootNodeType>
1632 inline Index32
1633 Tree<RootNodeType>::unallocatedLeafCount() const
1634 {
1635 Index32 sum = 0;
1636 for (auto it = this->cbeginLeaf(); it; ++it) if (!it->isAllocated()) ++sum;
1637 return sum;
1638 }
1639
1640
1641 template<typename RootNodeType>
1642 inline void
1643 Tree<RootNodeType>::sparseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1644 {
1645 this->clearAllAccessors();
1646 return mRoot.sparseFill(bbox, value, active);
1647 }
1648
1649
1650 template<typename RootNodeType>
1651 inline void
1652 Tree<RootNodeType>::denseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1653 {
1654 this->clearAllAccessors();
1655 return mRoot.denseFill(bbox, value, active);
1656 }
1657
1658
1659 template<typename RootNodeType>
1660 inline void
1661 Tree<RootNodeType>::voxelizeActiveTiles(bool threaded)
1662 {
1663 this->clearAllAccessors();
1664 mRoot.voxelizeActiveTiles(threaded);
1665 }
1666
1667
1668 template<typename RootNodeType>
1669 Metadata::Ptr
1670 Tree<RootNodeType>::getBackgroundValue() const
1671 {
1672 Metadata::Ptr result;
1673 if (Metadata::isRegisteredType(valueType())) {
1674 using MetadataT = TypedMetadata<ValueType>;
1675 result = Metadata::createMetadata(valueType());
1676 if (result->typeName() == MetadataT::staticTypeName()) {
1677 MetadataT* m = static_cast<MetadataT*>(result.get());
1678 m->value() = mRoot.background();
1679 }
1680 }
1681 return result;
1682 }
1683
1684
1686
1687
1688 template<typename RootNodeType>
1689 inline void
1690 Tree<RootNodeType>::merge(Tree& other, MergePolicy policy)
1691 {
1692 this->clearAllAccessors();
1693 other.clearAllAccessors();
1694 switch (policy) {
1695 case MERGE_ACTIVE_STATES:
1696 mRoot.template merge<MERGE_ACTIVE_STATES>(other.mRoot); break;
1697 case MERGE_NODES:
1698 mRoot.template merge<MERGE_NODES>(other.mRoot); break;
1699 case MERGE_ACTIVE_STATES_AND_NODES:
1700 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.mRoot); break;
1701 }
1702 }
1703
1704
1705 template<typename RootNodeType>
1706 template<typename OtherRootNodeType>
1707 inline void
1708 Tree<RootNodeType>::topologyUnion(const Tree<OtherRootNodeType>& other, const bool preserveTiles)
1709 {
1710 this->clearAllAccessors();
1711 mRoot.topologyUnion(other.root(), preserveTiles);
1712 }
1713
1714 template<typename RootNodeType>
1715 template<typename OtherRootNodeType>
1716 inline void
1717 Tree<RootNodeType>::topologyIntersection(const Tree<OtherRootNodeType>& other)
1718 {
1719 this->clearAllAccessors();
1720 mRoot.topologyIntersection(other.root());
1721 }
1722
1723 template<typename RootNodeType>
1724 template<typename OtherRootNodeType>
1725 inline void
1726 Tree<RootNodeType>::topologyDifference(const Tree<OtherRootNodeType>& other)
1727 {
1728 this->clearAllAccessors();
1729 mRoot.topologyDifference(other.root());
1730 }
1731
1733
1734
1737 template<typename AValueT, typename CombineOp, typename BValueT = AValueT>
1738 struct CombineOpAdapter
1739 {
1740 CombineOpAdapter(CombineOp& _op): op(_op) {}
1741
1742 void operator()(CombineArgs<AValueT, BValueT>& args) const {
1743 op(args.a(), args.b(), args.result());
1744 }
1745
1746 CombineOp& op;
1747 };
1748
1749
1750 template<typename RootNodeType>
1751 template<typename CombineOp>
1752 inline void
1753 Tree<RootNodeType>::combine(Tree& other, CombineOp& op, bool prune)
1754 {
1755 CombineOpAdapter<ValueType, CombineOp> extendedOp(op);
1756 this->combineExtended(other, extendedOp, prune);
1757 }
1758
1759
1762 #ifndef _MSC_VER
1763 template<typename RootNodeType>
1764 template<typename CombineOp>
1765 inline void
1766 Tree<RootNodeType>::combine(Tree& other, const CombineOp& op, bool prune)
1767 {
1768 CombineOpAdapter<ValueType, const CombineOp> extendedOp(op);
1769 this->combineExtended(other, extendedOp, prune);
1770 }
1771 #endif
1772
1773
1774 template<typename RootNodeType>
1775 template<typename ExtendedCombineOp>
1776 inline void
1777 Tree<RootNodeType>::combineExtended(Tree& other, ExtendedCombineOp& op, bool prune)
1778 {
1779 this->clearAllAccessors();
1780 mRoot.combine(other.root(), op, prune);
1781 }
1782
1783
1786 #ifndef _MSC_VER
1787 template<typename RootNodeType>
1788 template<typename ExtendedCombineOp>
1789 inline void
1790 Tree<RootNodeType>::combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune)
1791 {
1792 this->clearAllAccessors();
1793 mRoot.template combine<const ExtendedCombineOp>(other.mRoot, op, prune);
1794 }
1795 #endif
1796
1797
1798 template<typename RootNodeType>
1799 template<typename CombineOp, typename OtherTreeType>
1800 inline void
1801 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune)
1802 {
1803 CombineOpAdapter<ValueType, CombineOp, typename OtherTreeType::ValueType> extendedOp(op);
1804 this->combine2Extended(a, b, extendedOp, prune);
1805 }
1806
1807
1810 #ifndef _MSC_VER
1811 template<typename RootNodeType>
1812 template<typename CombineOp, typename OtherTreeType>
1813 inline void
1814 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune)
1815 {
1816 CombineOpAdapter<ValueType, const CombineOp, typename OtherTreeType::ValueType> extendedOp(op);
1817 this->combine2Extended(a, b, extendedOp, prune);
1818 }
1819 #endif
1820
1821
1822 template<typename RootNodeType>
1823 template<typename ExtendedCombineOp, typename OtherTreeType>
1824 inline void
1825 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
1826 ExtendedCombineOp& op, bool prune)
1827 {
1828 this->clearAllAccessors();
1829 mRoot.combine2(a.root(), b.root(), op, prune);
1830 }
1831
1832
1836 #ifndef _MSC_VER
1837 template<typename RootNodeType>
1838 template<typename ExtendedCombineOp, typename OtherTreeType>
1839 inline void
1840 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
1841 const ExtendedCombineOp& op, bool prune)
1842 {
1843 this->clearAllAccessors();
1844 mRoot.template combine2<const ExtendedCombineOp>(a.root(), b.root(), op, prune);
1845 }
1846 #endif
1847
1848
1850
1851
1852 template<typename RootNodeType>
1853 template<typename VisitorOp>
1854 inline void
1855 Tree<RootNodeType>::visit(VisitorOp& op)
1856 {
1857 this->clearAllAccessors();
1858 mRoot.template visit<VisitorOp>(op);
1859 }
1860
1861
1862 template<typename RootNodeType>
1863 template<typename VisitorOp>
1864 inline void
1865 Tree<RootNodeType>::visit(VisitorOp& op) const
1866 {
1867 mRoot.template visit<VisitorOp>(op);
1868 }
1869
1870
1873 template<typename RootNodeType>
1874 template<typename VisitorOp>
1875 inline void
1876 Tree<RootNodeType>::visit(const VisitorOp& op)
1877 {
1878 this->clearAllAccessors();
1879 mRoot.template visit<const VisitorOp>(op);
1880 }
1881
1882
1885 template<typename RootNodeType>
1886 template<typename VisitorOp>
1887 inline void
1888 Tree<RootNodeType>::visit(const VisitorOp& op) const
1889 {
1890 mRoot.template visit<const VisitorOp>(op);
1891 }
1892
1893
1895
1896
1897 template<typename RootNodeType>
1898 template<typename OtherTreeType, typename VisitorOp>
1899 inline void
1900 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op)
1901 {
1902 this->clearAllAccessors();
1903 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
1904 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
1905 }
1906
1907
1908 template<typename RootNodeType>
1909 template<typename OtherTreeType, typename VisitorOp>
1910 inline void
1911 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op) const
1912 {
1913 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
1914 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
1915 }
1916
1917
1920 template<typename RootNodeType>
1921 template<typename OtherTreeType, typename VisitorOp>
1922 inline void
1923 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op)
1924 {
1925 this->clearAllAccessors();
1926 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
1927 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
1928 }
1929
1930
1933 template<typename RootNodeType>
1934 template<typename OtherTreeType, typename VisitorOp>
1935 inline void
1936 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op) const
1937 {
1938 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
1939 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
1940 }
1941
1942
1944
1945
1946 template<typename RootNodeType>
1947 inline const Name&
1948 Tree<RootNodeType>::treeType()
1949 {
1950 static std::once_flag once;
1951 std::call_once(once, []()
1952 {
1953 std::vector<Index> dims;
1954 Tree::getNodeLog2Dims(dims);
1955 std::ostringstream ostr;
1956 ostr << "Tree_" << typeNameAsString<BuildType>();
1957 for (size_t i = 1, N = dims.size(); i < N; ++i) { // start from 1 to skip the RootNode
1958 ostr << "_" << dims[i];
1959 }
1960 sTreeTypeName.reset(new Name(ostr.str()));
1961 });
1962 return *sTreeTypeName;
1963 }
1964
1965
1966 template<typename RootNodeType>
1967 template<typename OtherRootNodeType>
1968 inline bool
1969 Tree<RootNodeType>::hasSameTopology(const Tree<OtherRootNodeType>& other) const
1970 {
1971 return mRoot.hasSameTopology(other.root());
1972 }
1973
1974
1975 template<typename RootNodeType>
1976 Index64
1977 Tree<RootNodeType>::inactiveVoxelCount() const
1978 {
1979 Coord dim(0, 0, 0);
1980 this->evalActiveVoxelDim(dim);
1981 const Index64
1982 totalVoxels = dim.x() * dim.y() * dim.z(),
1983 activeVoxels = this->activeVoxelCount();
1984 assert(totalVoxels >= activeVoxels);
1985 return totalVoxels - activeVoxels;
1986 }
1987
1988
1989 template<typename RootNodeType>
1990 inline bool
1991 Tree<RootNodeType>::evalLeafBoundingBox(CoordBBox& bbox) const
1992 {
1993 bbox.reset(); // default invalid bbox
1994
1995 if (this->empty()) return false; // empty
1996
1997 mRoot.evalActiveBoundingBox(bbox, false);
1998
1999 return !bbox.empty();
2000 }
2001
2002 template<typename RootNodeType>
2003 inline bool
2004 Tree<RootNodeType>::evalActiveVoxelBoundingBox(CoordBBox& bbox) const
2005 {
2006 bbox.reset(); // default invalid bbox
2007
2008 if (this->empty()) return false; // empty
2009
2010 mRoot.evalActiveBoundingBox(bbox, true);
2011
2012 return !bbox.empty();
2013 }
2014
2015
2016 template<typename RootNodeType>
2017 inline bool
2018 Tree<RootNodeType>::evalActiveVoxelDim(Coord& dim) const
2019 {
2020 CoordBBox bbox;
2021 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2022 dim = bbox.extents();
2023 return notEmpty;
2024 }
2025
2026
2027 template<typename RootNodeType>
2028 inline bool
2029 Tree<RootNodeType>::evalLeafDim(Coord& dim) const
2030 {
2031 CoordBBox bbox;
2032 bool notEmpty = this->evalLeafBoundingBox(bbox);
2033 dim = bbox.extents();
2034 return notEmpty;
2035 }
2036
2037
2038 template<typename RootNodeType>
2039 inline void
2040 Tree<RootNodeType>::evalMinMax(ValueType& minVal, ValueType& maxVal) const
2041 {
2043 minVal = maxVal = zeroVal<ValueType>();
2044 if (ValueOnCIter iter = this->cbeginValueOn()) {
2045 minVal = maxVal = *iter;
2046 for (++iter; iter; ++iter) {
2047 const ValueType& val = *iter;
2048 if (math::cwiseLessThan(val, minVal)) minVal = val;
2049 if (math::cwiseGreaterThan(val, maxVal)) maxVal = val;
2050 }
2051 }
2052 }
2053
2054
2055 template<typename RootNodeType>
2056 inline void
2057 Tree<RootNodeType>::getNodeLog2Dims(std::vector<Index>& dims)
2058 {
2059 dims.clear();
2060 RootNodeType::getNodeLog2Dims(dims);
2061 }
2062
2063
2064 template<typename RootNodeType>
2065 inline void
2066 Tree<RootNodeType>::print(std::ostream& os, int verboseLevel) const
2067 {
2068 if (verboseLevel <= 0) return;
2069
2071 struct OnExit {
2072 std::ostream& os;
2073 std::streamsize savedPrecision;
2074 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2075 ~OnExit() { os.precision(savedPrecision); }
2076 };
2077 OnExit restorePrecision(os);
2078
2079 std::vector<Index> dims;
2080 Tree::getNodeLog2Dims(dims);// leaf is the last element
2081
2082 os << "Information about Tree:\n"
2083 << " Type: " << this->type() << "\n";
2084
2085 os << " Configuration:\n";
2086
2087 if (verboseLevel <= 1) {
2088 // Print node types and sizes.
2089 os << " Root(" << mRoot.getTableSize() << ")";
2090 if (dims.size() > 1) {
2091 for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2092 os << ", Internal(" << (1 << dims[i]) << "^3)";
2093 }
2094 os << ", Leaf(" << (1 << dims.back()) << "^3)\n";
2095 }
2096 os << " Background value: " << mRoot.background() << "\n";
2097 return;
2098 }
2099
2100 // The following is tree information that is expensive to extract.
2101
2102 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2103 if (verboseLevel > 3) {
2104 // This forces loading of all non-resident nodes.
2105 this->evalMinMax(minVal, maxVal);
2106 }
2107
2108 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2109 const auto nodeCount = this->nodeCount();//fast
2110 const Index32 leafCount = nodeCount.front();// leaf is the first element
2111 #else
2112 std::vector<Index64> nodeCount(dims.size());
2113 for (NodeCIter it = cbeginNode(); it; ++it) ++(nodeCount[it.getDepth()]);//slow
2114 const Index64 leafCount = *nodeCount.rbegin();// leaf is the last element
2115 #endif
2116 assert(dims.size() == nodeCount.size());
2117
2118 Index64 totalNodeCount = 0;
2119 for (size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2120
2121 // Print node types, counts and sizes.
2122 os << " Root(1 x " << mRoot.getTableSize() << ")";
2123 if (dims.size() >= 2) {
2124 for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2125 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2126 os << ", Internal(" << util::formattedInt(nodeCount[N - i]);
2127 #else
2128 os << ", Internal(" << util::formattedInt(nodeCount[i]);
2129 #endif
2130 os << " x " << (1 << dims[i]) << "^3)";
2131 }
2132 os << ", Leaf(" << util::formattedInt(leafCount);
2133 os << " x " << (1 << dims.back()) << "^3)\n";
2134 }
2135 os << " Background value: " << mRoot.background() << "\n";
2136
2137 // Statistics of topology and values
2138
2139 if (verboseLevel > 3) {
2140 os << " Min value: " << minVal << "\n";
2141 os << " Max value: " << maxVal << "\n";
2142 }
2143
2144 const Index64
2145 numActiveVoxels = this->activeVoxelCount(),
2146 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2147 numActiveTiles = this->activeTileCount();
2148
2149 os << " Number of active voxels: " << util::formattedInt(numActiveVoxels) << "\n";
2150 os << " Number of active tiles: " << util::formattedInt(numActiveTiles) << "\n";
2151
2152 Coord dim(0, 0, 0);
2153 Index64 totalVoxels = 0;
2154 if (numActiveVoxels) { // nonempty
2155 CoordBBox bbox;
2156 this->evalActiveVoxelBoundingBox(bbox);
2157 dim = bbox.extents();
2158 totalVoxels = dim.x() * uint64_t(dim.y()) * dim.z();
2159
2160 os << " Bounding box of active voxels: " << bbox << "\n";
2161 os << " Dimensions of active voxels: "
2162 << dim[0] << " x " << dim[1] << " x " << dim[2] << "\n";
2163
2164 const double activeRatio = (100.0 * double(numActiveVoxels)) / double(totalVoxels);
2165 os << " Percentage of active voxels: " << std::setprecision(3) << activeRatio << "%\n";
2166
2167 if (leafCount > 0) {
2168 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2169 / (double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2170 os << " Average leaf node fill ratio: " << fillRatio << "%\n";
2171 }
2172
2173 if (verboseLevel > 2) {
2174 Index64 sum = 0;// count the number of unallocated leaf nodes
2175 for (auto it = this->cbeginLeaf(); it; ++it) if (!it->isAllocated()) ++sum;
2176 os << " Number of unallocated nodes: "
2177 << util::formattedInt(sum) << " ("
2178 << (100.0 * double(sum) / double(totalNodeCount)) << "%)\n";
2179 }
2180 } else {
2181 os << " Tree is empty!\n";
2182 }
2183 os << std::flush;
2184
2185 if (verboseLevel == 2) return;
2186
2187 // Memory footprint in bytes
2188 const Index64
2189 actualMem = this->memUsage(),
2190 denseMem = sizeof(ValueType) * totalVoxels,
2191 voxelsMem = sizeof(ValueType) * numActiveLeafVoxels;
2193
2194 os << "Memory footprint:\n";
2195 util::printBytes(os, actualMem, " Actual: ");
2196 util::printBytes(os, voxelsMem, " Active leaf voxels: ");
2197
2198 if (numActiveVoxels) {
2199 util::printBytes(os, denseMem, " Dense equivalent: ");
2200 os << " Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2201 << "% of an equivalent dense volume\n";
2202 os << " Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2203 << "% of actual footprint\n";
2204 }
2205 }
2206
2207 } // namespace tree
2208 } // namespace OPENVDB_VERSION_NAME
2209 } // namespace openvdb
2210
2211 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
BBox.h
Count.h
Functions to count tiles, nodes or voxels in a grid.
Formats.h
Utility routines to output nicely-formatted numeric values.
InternalNode.h
Internal table nodes for OpenVDB trees.
LeafNode.h
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Metadata.h
Platform.h
OPENVDB_API
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:240
OPENVDB_DEPRECATED_MESSAGE
#define OPENVDB_DEPRECATED_MESSAGE(msg)
Definition: Platform.h:123
RootNode.h
The root node of an OpenVDB tree.
TreeIterator.h
ValueAccessor.h
openvdb::v8_1::CombineArgs
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: openvdb/Types.h:447
openvdb::v8_1::CombineArgs::a
const AValueType & a() const
Get the A input value.
Definition: openvdb/Types.h:486
openvdb::v8_1::CombineArgs::b
const BValueType & b() const
Get the B input value.
Definition: openvdb/Types.h:488
openvdb::v8_1::CombineArgs::result
const AValueType & result() const
Get the output value.
Definition: openvdb/Types.h:491
openvdb::v8_1::Metadata::createMetadata
static Metadata::Ptr createMetadata(const Name &typeName)
Create new metadata of the given type.
openvdb::v8_1::Metadata::isRegisteredType
static bool isRegisteredType(const Name &typeName)
Return true if the given type is known by the metadata type registry.
openvdb::v8_1::Metadata::Ptr
SharedPtr< Metadata > Ptr
Definition: Metadata.h:26
openvdb::v8_1::NotImplementedError
Definition: openvdb/Exceptions.h:61
openvdb::v8_1::TopologyCopy
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: openvdb/Types.h:560
openvdb::v8_1::TypedMetadata
Templated metadata class to hold specific types.
Definition: Metadata.h:122
openvdb::v8_1::math::CoordBBox
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:249
openvdb::v8_1::math::CoordBBox::extents
Coord extents() const
Definition: Coord.h:382
openvdb::v8_1::math::CoordBBox::empty
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:356
openvdb::v8_1::math::CoordBBox::reset
void reset()
Definition: Coord.h:327
openvdb::v8_1::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:26
openvdb::v8_1::math::Coord::y
Int32 y() const
Definition: Coord.h:132
openvdb::v8_1::math::Coord::x
Int32 x() const
Definition: Coord.h:131
openvdb::v8_1::math::Coord::z
Int32 z() const
Definition: Coord.h:133
openvdb::v8_1::tree::DynamicNodeManager
Definition: NodeManager.h:884
openvdb::v8_1::tree::LeafIteratorBase
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels)
Definition: TreeIterator.h:1187
openvdb::v8_1::tree::NodeIteratorBase
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:936
openvdb::v8_1::tree::TreeBase
Base class for typed trees.
Definition: Tree.h:37
openvdb::v8_1::tree::TreeBase::valueType
virtual Name valueType() const =0
Return the name of the type of a voxel's value (e.g., "float" or "vec3d").
openvdb::v8_1::tree::TreeBase::nonLeafCount
virtual Index32 nonLeafCount() const =0
Return the number of non-leaf nodes.
openvdb::v8_1::tree::TreeBase::writeTopology
virtual void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const
Write the tree topology to a stream.
Definition: Tree.h:1132
openvdb::v8_1::tree::TreeBase::~TreeBase
virtual ~TreeBase()=default
openvdb::v8_1::tree::TreeBase::activeLeafVoxelCount
virtual Index64 activeLeafVoxelCount() const =0
Return the number of active voxels stored in leaf nodes.
openvdb::v8_1::tree::TreeBase::nodeCount
virtual std::vector< Index32 > nodeCount() const =0
openvdb::v8_1::tree::TreeBase::readBuffers
virtual void readBuffers(std::istream &, bool saveFloatAsHalf=false)=0
Read all data buffers for this tree.
openvdb::v8_1::tree::TreeBase::writeBuffers
virtual void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const =0
Write out all the data buffers for this tree.
openvdb::v8_1::tree::TreeBase::getBackgroundValue
virtual Metadata::Ptr getBackgroundValue() const
Return this tree's background value wrapped as metadata.
Definition: Tree.h:61
openvdb::v8_1::tree::TreeBase::TreeBase
TreeBase()=default
openvdb::v8_1::tree::TreeBase::type
virtual const Name & type() const =0
Return the name of this tree's type.
openvdb::v8_1::tree::TreeBase::operator=
TreeBase & operator=(const TreeBase &)=delete
openvdb::v8_1::tree::TreeBase::print
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:1140
openvdb::v8_1::tree::TreeBase::readBuffers
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.
openvdb::v8_1::tree::TreeBase::getIndexRange
virtual void getIndexRange(CoordBBox &bbox) const =0
openvdb::v8_1::tree::TreeBase::leafCount
virtual Index32 leafCount() const =0
Return the number of leaf nodes.
openvdb::v8_1::tree::TreeBase::unallocatedLeafCount
virtual Index32 unallocatedLeafCount() const =0
Return the total number of unallocated leaf nodes residing in this tree.
openvdb::v8_1::tree::TreeBase::activeVoxelCount
virtual Index64 activeVoxelCount() const =0
Return the total number of active voxels.
openvdb::v8_1::tree::TreeBase::inactiveVoxelCount
virtual Index64 inactiveVoxelCount() const =0
Return the number of inactive voxels within the bounding box of all active voxels.
openvdb::v8_1::tree::TreeBase::clipUnallocatedNodes
virtual void clipUnallocatedNodes()=0
Replace with background tiles any nodes whose voxel buffers have not yet been allocated.
openvdb::v8_1::tree::TreeBase::readNonresidentBuffers
virtual void readNonresidentBuffers() const =0
Read all of this tree's data buffers that are not yet resident in memory (because delayed loading is ...
openvdb::v8_1::tree::TreeBase::inactiveLeafVoxelCount
virtual Index64 inactiveLeafVoxelCount() const =0
Return the number of inactive voxels stored in leaf nodes.
openvdb::v8_1::tree::TreeBase::memUsage
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:132
openvdb::v8_1::tree::TreeBase::copy
virtual TreeBase::Ptr copy() const =0
Return a pointer to a deep copy of this tree.
openvdb::v8_1::tree::TreeBase::Ptr
SharedPtr< TreeBase > Ptr
Definition: Tree.h:39
openvdb::v8_1::tree::TreeBase::evalLeafDim
virtual bool evalLeafDim(Coord &dim) const =0
Return in dim the dimensions of the axis-aligned bounding box of all leaf nodes.
openvdb::v8_1::tree::TreeBase::evalActiveVoxelBoundingBox
virtual bool evalActiveVoxelBoundingBox(CoordBBox &bbox) const =0
Return in bbox the axis-aligned bounding box of all active voxels and tiles.
openvdb::v8_1::tree::TreeBase::treeDepth
virtual Index treeDepth() const =0
Return the depth of this tree.
openvdb::v8_1::tree::TreeBase::activeTileCount
virtual Index64 activeTileCount() const =0
Return the total number of active tiles.
openvdb::v8_1::tree::TreeBase::ConstPtr
SharedPtr< const TreeBase > ConstPtr
Definition: Tree.h:40
openvdb::v8_1::tree::TreeBase::evalActiveVoxelDim
virtual bool evalActiveVoxelDim(Coord &dim) const =0
Return in dim the dimensions of the axis-aligned bounding box of all active voxels....
openvdb::v8_1::tree::TreeBase::evalLeafBoundingBox
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.
openvdb::v8_1::tree::TreeBase::TreeBase
TreeBase(const TreeBase &)=default
openvdb::v8_1::tree::TreeBase::readTopology
virtual void readTopology(std::istream &, bool saveFloatAsHalf=false)
Read the tree topology from a stream.
Definition: Tree.h:1123
openvdb::v8_1::tree::TreeValueIteratorBase
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:617
openvdb::v8_1::tree::Tree
Definition: Tree.h:176
openvdb::v8_1::tree::Tree::getValueDepth
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:1437
openvdb::v8_1::tree::Tree::hasSameTopology
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:1969
openvdb::v8_1::tree::Tree::cbegin
CIterT cbegin() const
Return a const iterator of type CIterT (for example, cbegin<ValueOnCIter>() is equivalent to cbeginVa...
openvdb::v8_1::tree::Tree::releaseAccessor
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:649
openvdb::v8_1::tree::Tree::mConstAccessorRegistry
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1080
openvdb::v8_1::tree::Tree::isValueOn
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:449
openvdb::v8_1::tree::Tree::Tree
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:205
openvdb::v8_1::tree::Tree::cbeginRootTiles
RootNodeType::ChildOffCIter cbeginRootTiles() const
Definition: Tree.h:982
openvdb::v8_1::tree::Tree::beginLeaf
LeafCIter beginLeaf() const
Definition: Tree.h:1016
openvdb::v8_1::tree::Tree::root
RootNodeType & root()
Return this tree's root node.
Definition: Tree.h:279
openvdb::v8_1::tree::Tree::background
const ValueType & background() const
Return this tree's background value.
Definition: Tree.h:661
openvdb::v8_1::tree::Tree::writeBuffers
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition: Tree.h:1310
openvdb::v8_1::tree::Tree::cbeginValueOff
ValueOffCIter cbeginValueOff() const
Definition: Tree.h:1043
openvdb::v8_1::tree::Tree::Tree
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:216
openvdb::v8_1::tree::Tree::probeConstLeaf
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition: Tree.h:1572
openvdb::v8_1::tree::Tree::memUsage
Index64 memUsage() const override
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:366
openvdb::v8_1::tree::Tree::clearAllAccessors
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1377
openvdb::v8_1::tree::Tree::RootNodeType
_RootNodeType RootNodeType
Definition: Tree.h:181
openvdb::v8_1::tree::Tree::beginRootDense
RootNodeType::ChildAllIter beginRootDense()
Definition: Tree.h:990
openvdb::v8_1::tree::Tree::cbeginLeaf
LeafCIter cbeginLeaf() const
Definition: Tree.h:1017
openvdb::v8_1::tree::Tree::beginRootTiles
RootNodeType::ChildOffIter beginRootTiles()
Definition: Tree.h:983
openvdb::v8_1::tree::Tree::operator!=
bool operator!=(const Tree &) const
Definition: Tree.h:275
openvdb::v8_1::tree::Tree::Tree
Tree()
Definition: Tree.h:200
openvdb::v8_1::tree::Tree::mAccessorRegistry
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1079
openvdb::v8_1::tree::Tree::mRoot
RootNodeType mRoot
Definition: Tree.h:1078
openvdb::v8_1::tree::Tree::cbeginValueAll
ValueAllCIter cbeginValueAll() const
Definition: Tree.h:1031
openvdb::v8_1::tree::Tree::prune
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:506
openvdb::v8_1::tree::Tree::sTreeTypeName
static std::unique_ptr< const Name > sTreeTypeName
Definition: Tree.h:1082
openvdb::v8_1::tree::Tree::probeLeaf
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:1564
openvdb::v8_1::tree::Tree::touchLeaf
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:1556
openvdb::v8_1::tree::Tree::beginRootChildren
RootNodeType::ChildOnIter beginRootChildren()
Definition: Tree.h:976
openvdb::v8_1::tree::Tree::operator=
Tree & operator=(const Tree &)=delete
openvdb::v8_1::tree::Tree::beginValueOn
ValueOnCIter beginValueOn() const
Definition: Tree.h:1036
openvdb::v8_1::tree::Tree::operator==
bool operator==(const Tree &) const
Definition: Tree.h:274
openvdb::v8_1::tree::Tree::activeLeafVoxelCount
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:353
openvdb::v8_1::tree::Tree::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1518
openvdb::v8_1::tree::Tree::leafCount
Index32 leafCount() const override
Return the number of leaf nodes.
Definition: Tree.h:338
openvdb::v8_1::tree::Tree::setValueOnly
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:1476
openvdb::v8_1::tree::Tree::empty
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:619
openvdb::v8_1::tree::Tree::activeVoxelCount
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Definition: Tree.h:357
openvdb::v8_1::tree::Tree::inactiveLeafVoxelCount
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:355
openvdb::v8_1::tree::Tree::fill
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Definition: Tree.h:477
openvdb::v8_1::tree::Tree::beginValueOff
ValueOffCIter beginValueOff() const
Definition: Tree.h:1042
openvdb::v8_1::tree::Tree::addLeaf
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:517
openvdb::v8_1::tree::Tree::addTile
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:1537
openvdb::v8_1::tree::Tree::probeValue
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1526
openvdb::v8_1::tree::Tree::setActiveState
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:1461
openvdb::v8_1::tree::Tree::nodeCount
std::vector< Index32 > nodeCount() const override
Definition: Tree.h:343
openvdb::v8_1::tree::Tree::BuildType
typename RootNodeType::BuildType BuildType
Definition: Tree.h:183
openvdb::v8_1::tree::Tree::setValue
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:1469
openvdb::v8_1::tree::Tree::getValue
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.
openvdb::v8_1::tree::Tree::activeTileCount
Index64 activeTileCount() const override
Return the total number of active tiles.
Definition: Tree.h:361
openvdb::v8_1::tree::Tree::type
const Name & type() const override
Return the name of this type of tree.
Definition: Tree.h:272
openvdb::v8_1::tree::Tree::setValueOff
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: Tree.h:1445
openvdb::v8_1::tree::Tree::ConstAccessorRegistry
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1056
openvdb::v8_1::tree::Tree::cbeginValueOn
ValueOnCIter cbeginValueOn() const
Definition: Tree.h:1037
openvdb::v8_1::tree::Tree::copy
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition: Tree.h:264
openvdb::v8_1::tree::Tree::ValueType
typename RootNodeType::ValueType ValueType
Definition: Tree.h:182
openvdb::v8_1::tree::Tree::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1420
openvdb::v8_1::tree::Tree::attachAccessor
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:637
openvdb::v8_1::tree::Tree::beginNode
NodeCIter beginNode() const
Definition: Tree.h:1009
openvdb::v8_1::tree::Tree::modifyValue
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:1509
openvdb::v8_1::tree::Tree::Tree
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:252
openvdb::v8_1::tree::Tree::cbeginRootDense
RootNodeType::ChildAllCIter cbeginRootDense() const
Definition: Tree.h:989
openvdb::v8_1::tree::Tree::getNodes
void getNodes(ArrayT &array) const
Definition: Tree.h:579
openvdb::v8_1::tree::Tree::probeLeaf
const LeafNodeType * probeLeaf(const Coord &xyz) const
Definition: Tree.h:552
openvdb::v8_1::tree::Tree::stealNodes
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:608
openvdb::v8_1::tree::Tree::clear
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1318
openvdb::v8_1::tree::Tree::cbeginRootChildren
RootNodeType::ChildOnCIter cbeginRootChildren() const
Definition: Tree.h:975
openvdb::v8_1::tree::Tree::cbeginNode
NodeCIter cbeginNode() const
Definition: Tree.h:1010
openvdb::v8_1::tree::Tree::getIndexRange
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition: Tree.h:664
openvdb::v8_1::tree::Tree::LeafNodeType
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:184
openvdb::v8_1::tree::Tree::setValueOn
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: Tree.h:1492
openvdb::v8_1::tree::Tree::Tree
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:231
openvdb::v8_1::tree::Tree::~Tree
~Tree() override
Definition: Tree.h:261
openvdb::v8_1::tree::Tree::hasActiveTiles
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:453
openvdb::v8_1::tree::Tree::Tree
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:259
openvdb::v8_1::tree::Tree::isValueOff
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:451
openvdb::v8_1::tree::Tree::stealNodes
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:606
openvdb::v8_1::tree::Tree::nonLeafCount
Index32 nonLeafCount() const override
Return the number of non-leaf nodes.
Definition: Tree.h:351
openvdb::v8_1::tree::Tree::valueType
Name valueType() const override
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
Definition: Tree.h:267
openvdb::v8_1::tree::Tree::root
const RootNodeType & root() const
Definition: Tree.h:280
openvdb::v8_1::tree::Tree::treeDepth
Index treeDepth() const override
Return the depth of this tree.
Definition: Tree.h:336
openvdb::v8_1::tree::Tree::beginValueAll
ValueAllCIter beginValueAll() const
Definition: Tree.h:1030
openvdb::v8_1::tree::Tree::AccessorRegistry
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1055
openvdb::v8_1::tree::ValueAccessorBase
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:85
logging.h
OPENVDB_LOG_WARN
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:253
openvdb::v8_1::ax::ast::print
void print(const ast::Node &node, const bool numberStatements=true, std::ostream &os=std::cout, const char *indent=" ")
Writes a descriptive printout of a Node hierarchy into a target stream.
openvdb::v8_1::math::cwiseLessThan
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition: Mat.h:1037
openvdb::v8_1::math::cwiseGreaterThan
bool cwiseGreaterThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition: Mat.h:1051
openvdb::v8_1::tools::composite::max
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:107
openvdb::v8_1::tools::composite::min
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:103
openvdb::v8_1::tools::prune
void prune(TreeT &tree, typename TreeT::ValueType tolerance=zeroVal< typename TreeT::ValueType >(), bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing with tiles any nodes whose values are all the same...
Definition: Prune.h:334
openvdb::v8_1::tools::clip
GridType::Ptr clip(const GridType &grid, const BBoxd &bbox, bool keepInterior=true)
Clip the given grid against a world-space bounding box and return a new grid containing the result.
Definition: Clip.h:348
openvdb::v8_1::tools::countActiveVoxels
Index64 countActiveVoxels(const TreeT &tree, bool threaded=true)
Return the total number of active voxels in the tree.
Definition: Count.h:210
openvdb::v8_1::tools::visitNodesDepthFirst
size_t visitNodesDepthFirst(TreeT &tree, OpT &op, size_t idx=0)
Visit all nodes in the tree depth-first and apply a user-supplied functor to each node.
Definition: NodeVisitor.h:229
openvdb::v8_1::tools::memUsage
Index64 memUsage(const TreeT &tree, bool threaded=true)
Return the total amount of memory in bytes occupied by this tree.
Definition: Count.h:233
openvdb::v8_1::util::formattedInt
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:118
openvdb::v8_1::util::printBytes
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)
openvdb::v8_1::Name
std::string Name
Definition: Name.h:17
openvdb::v8_1::Index
Index32 Index
Definition: openvdb/Types.h:50
openvdb::v8_1::Index32
uint32_t Index32
Definition: openvdb/Types.h:48
openvdb::v8_1::Index64
uint64_t Index64
Definition: openvdb/Types.h:49
openvdb::v8_1::SharedPtr
std::shared_ptr< T > SharedPtr
Definition: openvdb/Types.h:110
openvdb::v8_1::MergePolicy
MergePolicy
Definition: openvdb/Types.h:384
openvdb::v8_1::MERGE_ACTIVE_STATES
@ MERGE_ACTIVE_STATES
Definition: openvdb/Types.h:385
openvdb::v8_1::MERGE_NODES
@ MERGE_NODES
Definition: openvdb/Types.h:386
openvdb::v8_1::MERGE_ACTIVE_STATES_AND_NODES
@ MERGE_ACTIVE_STATES_AND_NODES
Definition: openvdb/Types.h:387
openvdb_houdini::combine
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:140
openvdb
Definition: openvdb/Exceptions.h:13
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
Types.h
openvdb::v8_1::tree::CombineOpAdapter
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1739
openvdb::v8_1::tree::CombineOpAdapter::operator()
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1742
openvdb::v8_1::tree::CombineOpAdapter::CombineOpAdapter
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1740
openvdb::v8_1::tree::CombineOpAdapter::op
CombineOp & op
Definition: Tree.h:1746
openvdb::v8_1::tree::Tree3
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition: Tree.h:1094
openvdb::v8_1::tree::Tree4
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal,...
Definition: Tree.h:1104
openvdb::v8_1::tree::Tree5
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal,...
Definition: Tree.h:1113
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::LeafCIter >::begin
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1211
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::LeafIter >::begin
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1207
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::NodeCIter >::begin
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1203
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::NodeIter >::begin
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1199
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildAllCIter >::begin
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1193
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildAllIter >::begin
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1187
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOffCIter >::begin
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1181
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOffIter >::begin
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1175
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOnCIter >::begin
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1169
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOnIter >::begin
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1163
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::ValueAllCIter >::begin
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1235
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::ValueAllIter >::begin
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1231
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::ValueOffCIter >::begin
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1227
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::ValueOffIter >::begin
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1223
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::ValueOnCIter >::begin
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1219
openvdb::v8_1::tree::TreeIterTraits< TreeT, typename TreeT::ValueOnIter >::begin
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1215
openvdb::v8_1::tree::TreeIterTraits
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1160
openvdb::v8_1::tree::Tree::DeallocateNodes
Definition: Tree.h:1064
openvdb::v8_1::tree::Tree::DeallocateNodes::DeallocateNodes
DeallocateNodes(std::vector< NodeType * > &nodes)
Definition: Tree.h:1065
openvdb::v8_1::tree::Tree::DeallocateNodes::mNodes
NodeType **const mNodes
Definition: Tree.h:1072
openvdb::v8_1::tree::Tree::DeallocateNodes::operator()
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1067
openvdb::v8_1::tree::Tree::ValueConverter
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition: Tree.h:195
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178