OpenVDB: Tree.h Source File

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