OpenVDB  3.2.0
Tree.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2016 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 //
34 
35 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
36 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
37 
38 #include <iostream>
39 #include <sstream>
40 #include <vector>
41 #include <boost/shared_ptr.hpp>
42 #include <boost/cstdint.hpp>
43 #include <tbb/atomic.h>
44 #include <tbb/concurrent_hash_map.h>
45 #include <openvdb/Types.h>
47 #include <openvdb/math/Math.h>
48 #include <openvdb/math/BBox.h>
49 #include <openvdb/util/Formats.h>
50 #include <openvdb/util/logging.h>
51 #include <openvdb/Platform.h>
52 #include "RootNode.h"
53 #include "InternalNode.h"
54 #include "LeafNode.h"
55 #include "TreeIterator.h"
56 #include "ValueAccessor.h"
57 
58 
59 namespace openvdb {
61 namespace OPENVDB_VERSION_NAME {
62 namespace tree {
63 
66 {
67 public:
68  typedef boost::shared_ptr<TreeBase> Ptr;
69  typedef boost::shared_ptr<const TreeBase> ConstPtr;
70 
71  TreeBase() {}
72  virtual ~TreeBase() {}
73 
75  virtual const Name& type() const = 0;
76 
78  virtual Name valueType() const = 0;
79 
81  virtual TreeBase::Ptr copy() const = 0;
82 
83  //
84  // Tree methods
85  //
88  virtual Metadata::Ptr getBackgroundValue() const { return Metadata::Ptr(); }
89 
97  virtual bool evalLeafBoundingBox(CoordBBox& bbox) const = 0;
98 
102  virtual bool evalLeafDim(Coord& dim) const = 0;
103 
111  virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const = 0;
112 
116  virtual bool evalActiveVoxelDim(Coord& dim) const = 0;
117 
118  virtual void getIndexRange(CoordBBox& bbox) const = 0;
119 
120 #ifndef OPENVDB_2_ABI_COMPATIBLE
121  virtual void clipUnallocatedNodes() = 0;
127 #endif
128 
129 
130  //
131  // Statistics
132  //
136  virtual Index treeDepth() const = 0;
138  virtual Index32 leafCount() const = 0;
140  virtual Index32 nonLeafCount() const = 0;
142  virtual Index64 activeLeafVoxelCount() const = 0;
144  virtual Index64 inactiveLeafVoxelCount() const = 0;
146  virtual Index64 activeVoxelCount() const = 0;
148  virtual Index64 inactiveVoxelCount() const = 0;
149 #ifndef OPENVDB_2_ABI_COMPATIBLE
150  virtual Index64 activeTileCount() const = 0;
152 #endif
153 
155  virtual Index64 memUsage() const { return 0; }
156 
157 
158  //
159  // I/O methods
160  //
164  virtual void readTopology(std::istream&, bool saveFloatAsHalf = false);
168  virtual void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const;
169 
171  virtual void readBuffers(std::istream&, bool saveFloatAsHalf = false) = 0;
172 #ifndef OPENVDB_2_ABI_COMPATIBLE
173  virtual void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false) = 0;
180  virtual void readNonresidentBuffers() const = 0;
181 #endif
182  virtual void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const = 0;
184 
192  virtual void print(std::ostream& os = std::cout, int verboseLevel = 1) const;
193 
194 private:
195  // Disallow copying of instances of this class.
196  //TreeBase(const TreeBase& other);
197  TreeBase& operator=(const TreeBase& other);
198 };
199 
200 
202 
203 
204 template<typename _RootNodeType>
205 class Tree: public TreeBase
206 {
207 public:
208  typedef boost::shared_ptr<Tree> Ptr;
209  typedef boost::shared_ptr<const Tree> ConstPtr;
210 
211  typedef _RootNodeType RootNodeType;
212  typedef typename RootNodeType::ValueType ValueType;
213  typedef typename RootNodeType::BuildType BuildType;
214  typedef typename RootNodeType::LeafNodeType LeafNodeType;
215 
216  static const Index DEPTH = RootNodeType::LEVEL + 1;
217 
224  template<typename OtherValueType>
225  struct ValueConverter {
227  };
228 
229 
230  Tree() {}
231 
233  Tree(const Tree& other): TreeBase(other), mRoot(other.mRoot)
234  {
235  }
236 
243  template<typename OtherRootType>
244  explicit Tree(const Tree<OtherRootType>& other): TreeBase(other), mRoot(other.root())
245  {
246  }
247 
258  template<typename OtherTreeType>
259  Tree(const OtherTreeType& other,
260  const ValueType& inactiveValue,
261  const ValueType& activeValue,
262  TopologyCopy):
263  TreeBase(other),
264  mRoot(other.root(), inactiveValue, activeValue, TopologyCopy())
265  {
266  }
267 
279  template<typename OtherTreeType>
280  Tree(const OtherTreeType& other, const ValueType& background, TopologyCopy):
281  TreeBase(other),
282  mRoot(other.root(), background, TopologyCopy())
283  {
284  }
285 
287  Tree(const ValueType& background): mRoot(background) {}
288 
289  virtual ~Tree() { this->clear(); releaseAllAccessors(); }
290 
292  virtual TreeBase::Ptr copy() const { return TreeBase::Ptr(new Tree(*this)); }
293 
295  virtual Name valueType() const { return typeNameAsString<ValueType>(); }
296 
298  static const Name& treeType();
300  virtual const Name& type() const { return this->treeType(); }
301 
302  bool operator==(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
303  bool operator!=(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
304 
306  RootNodeType& root() { return mRoot; }
308  const RootNodeType& root() const { return mRoot; }
310 
311 
312  //
313  // Tree methods
314  //
317  template<typename OtherRootNodeType>
318  bool hasSameTopology(const Tree<OtherRootNodeType>& other) const;
319 
320  virtual bool evalLeafBoundingBox(CoordBBox& bbox) const;
321  virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const;
322  virtual bool evalActiveVoxelDim(Coord& dim) const;
323  virtual bool evalLeafDim(Coord& dim) const;
324 
328  static void getNodeLog2Dims(std::vector<Index>& dims);
329 
330 
331  //
332  // I/O methods
333  //
337  virtual void readTopology(std::istream&, bool saveFloatAsHalf = false);
341  virtual void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const;
343  virtual void readBuffers(std::istream&, bool saveFloatAsHalf = false);
344 #ifndef OPENVDB_2_ABI_COMPATIBLE
345  virtual void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false);
352  virtual void readNonresidentBuffers() const;
353 #endif
354  virtual void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const;
356 
357  virtual void print(std::ostream& os = std::cout, int verboseLevel = 1) const;
358 
359 
360  //
361  // Statistics
362  //
366  virtual Index treeDepth() const { return DEPTH; }
368  virtual Index32 leafCount() const { return mRoot.leafCount(); }
370  virtual Index32 nonLeafCount() const { return mRoot.nonLeafCount(); }
372  virtual Index64 activeLeafVoxelCount() const { return mRoot.onLeafVoxelCount(); }
374  virtual Index64 inactiveLeafVoxelCount() const { return mRoot.offLeafVoxelCount(); }
376  virtual Index64 activeVoxelCount() const { return mRoot.onVoxelCount(); }
378  virtual Index64 inactiveVoxelCount() const;
380  Index64 activeTileCount() const { return mRoot.onTileCount(); }
381 
383  void evalMinMax(ValueType &min, ValueType &max) const;
384 
385  virtual Index64 memUsage() const { return sizeof(*this) + mRoot.memUsage(); }
386 
387 
388  //
389  // Voxel access methods (using signed indexing)
390  //
392  const ValueType& getValue(const Coord& xyz) const;
395  template<typename AccessT> const ValueType& getValue(const Coord& xyz, AccessT&) const;
396 
400  int getValueDepth(const Coord& xyz) const;
401 
403  void setActiveState(const Coord& xyz, bool on);
405  void setValueOnly(const Coord& xyz, const ValueType& value);
407  void setValueOn(const Coord& xyz);
409  void setValueOn(const Coord& xyz, const ValueType& value);
411  void setValue(const Coord& xyz, const ValueType& value);
414  template<typename AccessT> void setValue(const Coord& xyz, const ValueType& value, AccessT&);
416  void setValueOff(const Coord& xyz);
418  void setValueOff(const Coord& xyz, const ValueType& value);
419 
438  template<typename ModifyOp>
439  void modifyValue(const Coord& xyz, const ModifyOp& op);
440 
460  template<typename ModifyOp>
461  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op);
462 
465  bool probeValue(const Coord& xyz, ValueType& value) const;
466 
468  bool isValueOn(const Coord& xyz) const { return mRoot.isValueOn(xyz); }
470  bool isValueOff(const Coord& xyz) const { return !this->isValueOn(xyz); }
472  bool hasActiveTiles() const { return mRoot.hasActiveTiles(); }
473 
475  void clip(const CoordBBox&);
476 
477 #ifndef OPENVDB_2_ABI_COMPATIBLE
478  virtual void clipUnallocatedNodes();
484 #endif
485 
487  void sparseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
496  void fill(const CoordBBox& bbox, const ValueType& value, bool active = true)
497  {
498  this->sparseFill(bbox, value, active);
499  }
501 
511  void denseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
512 
517  void prune(const ValueType& tolerance = zeroVal<ValueType>())
518  {
519  this->clearAllAccessors();
520  mRoot.prune(tolerance);
521  }
522 
524  void addLeaf(LeafNodeType* leaf) { assert(leaf); mRoot.addLeaf(leaf); }
530  OPENVDB_DEPRECATED void addLeaf(LeafNodeType& leaf) { mRoot.addLeaf(&leaf); }
532 
537  void addTile(Index level, const Coord& xyz, const ValueType& value, bool active);
538 
543  template<typename NodeT>
544  NodeT* stealNode(const Coord& xyz, const ValueType& value, bool active);
545 
551  LeafNodeType* touchLeaf(const Coord& xyz);
552 
554  template<typename NodeType> NodeType* probeNode(const Coord& xyz);
557  template<typename NodeType> const NodeType* probeConstNode(const Coord& xyz) const;
558  template<typename NodeType> const NodeType* probeNode(const Coord& xyz) const;
560 
562  LeafNodeType* probeLeaf(const Coord& xyz);
565  const LeafNodeType* probeConstLeaf(const Coord& xyz) const;
566  const LeafNodeType* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
568 
570  template<typename ArrayT> void getNodes(ArrayT& array) { mRoot.getNodes(array); }
593  template<typename ArrayT> void getNodes(ArrayT& array) const { mRoot.getNodes(array); }
595 
619  template<typename ArrayT>
620  void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
621  template<typename ArrayT>
622  void stealNodes(ArrayT& array, const ValueType& value, bool state)
623  {
624  this->clearAllAccessors();
625  mRoot.stealNodes(array, value, state);
626  }
627 
628  //
629  // Aux methods
630  //
633  bool empty() const { return mRoot.empty(); }
634 
636  void clear();
637 
639  void clearAllAccessors();
640 
642  void attachAccessor(ValueAccessorBase<Tree, true>&) const;
645  void attachAccessor(ValueAccessorBase<const Tree, true>&) const;
647 
649  void attachAccessor(ValueAccessorBase<Tree, false>&) const {}
653 
655  void releaseAccessor(ValueAccessorBase<Tree, true>&) const;
657  void releaseAccessor(ValueAccessorBase<const Tree, true>&) const;
659 
661  void releaseAccessor(ValueAccessorBase<Tree, false>&) const {}
665 
668  virtual Metadata::Ptr getBackgroundValue() const;
669 
675  const ValueType& background() const { return mRoot.background(); }
676 
678  virtual void getIndexRange(CoordBBox& bbox) const { mRoot.getIndexRange(bbox); }
679 
686  void voxelizeActiveTiles(bool threaded = true);
687 
695  void merge(Tree& other, MergePolicy = MERGE_ACTIVE_STATES);
696 
710  template<typename OtherRootNodeType>
711  void topologyUnion(const Tree<OtherRootNodeType>& other);
712 
726  template<typename OtherRootNodeType>
727  void topologyIntersection(const Tree<OtherRootNodeType>& other);
728 
739  template<typename OtherRootNodeType>
740  void topologyDifference(const Tree<OtherRootNodeType>& other);
741 
786  template<typename CombineOp>
787  void combine(Tree& other, CombineOp& op, bool prune = false);
788 #ifndef _MSC_VER
789  template<typename CombineOp>
790  void combine(Tree& other, const CombineOp& op, bool prune = false);
791 #endif
792 
831  template<typename ExtendedCombineOp>
832  void combineExtended(Tree& other, ExtendedCombineOp& op, bool prune = false);
833 #ifndef _MSC_VER
834  template<typename ExtendedCombineOp>
835  void combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune = false);
836 #endif
837 
866  template<typename CombineOp, typename OtherTreeType /*= Tree*/>
867  void combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune = false);
868 #ifndef _MSC_VER
869  template<typename CombineOp, typename OtherTreeType /*= Tree*/>
870  void combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune = false);
871 #endif
872 
946  template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
947  void combine2Extended(const Tree& a, const OtherTreeType& b, ExtendedCombineOp& op,
948  bool prune = false);
949 #ifndef _MSC_VER
950  template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
951  void combine2Extended(const Tree& a, const OtherTreeType& b, const ExtendedCombineOp&,
952  bool prune = false);
953 #endif
954 
995  template<typename BBoxOp> void visitActiveBBox(BBoxOp& op) const { mRoot.visitActiveBBox(op); }
996 
1050  template<typename VisitorOp> void visit(VisitorOp& op);
1051  template<typename VisitorOp> void visit(const VisitorOp& op);
1052 
1057  template<typename VisitorOp> void visit(VisitorOp& op) const;
1058  template<typename VisitorOp> void visit(const VisitorOp& op) const;
1059 
1107  template<typename OtherTreeType, typename VisitorOp>
1108  void visit2(OtherTreeType& other, VisitorOp& op);
1109  template<typename OtherTreeType, typename VisitorOp>
1110  void visit2(OtherTreeType& other, const VisitorOp& op);
1111 
1122  template<typename OtherTreeType, typename VisitorOp>
1123  void visit2(OtherTreeType& other, VisitorOp& op) const;
1124  template<typename OtherTreeType, typename VisitorOp>
1125  void visit2(OtherTreeType& other, const VisitorOp& op) const;
1126 
1127 
1128  //
1129  // Iteration
1130  //
1132  typename RootNodeType::ChildOnCIter beginRootChildren() const { return mRoot.cbeginChildOn(); }
1134  typename RootNodeType::ChildOnCIter cbeginRootChildren() const { return mRoot.cbeginChildOn(); }
1135  typename RootNodeType::ChildOnIter beginRootChildren() { return mRoot.beginChildOn(); }
1137 
1139  typename RootNodeType::ChildOffCIter beginRootTiles() const { return mRoot.cbeginChildOff(); }
1141  typename RootNodeType::ChildOffCIter cbeginRootTiles() const { return mRoot.cbeginChildOff(); }
1142  typename RootNodeType::ChildOffIter beginRootTiles() { return mRoot.beginChildOff(); }
1144 
1146  typename RootNodeType::ChildAllCIter beginRootDense() const { return mRoot.cbeginChildAll(); }
1148  typename RootNodeType::ChildAllCIter cbeginRootDense() const { return mRoot.cbeginChildAll(); }
1149  typename RootNodeType::ChildAllIter beginRootDense() { return mRoot.beginChildAll(); }
1151 
1152 
1158 
1164 
1166  NodeIter beginNode() { return NodeIter(*this); }
1168  NodeCIter beginNode() const { return NodeCIter(*this); }
1169  NodeCIter cbeginNode() const { return NodeCIter(*this); }
1171 
1173  LeafIter beginLeaf() { return LeafIter(*this); }
1175  LeafCIter beginLeaf() const { return LeafCIter(*this); }
1176  LeafCIter cbeginLeaf() const { return LeafCIter(*this); }
1178 
1185 
1187  ValueAllIter beginValueAll() { return ValueAllIter(*this); }
1189  ValueAllCIter beginValueAll() const { return ValueAllCIter(*this); }
1190  ValueAllCIter cbeginValueAll() const { return ValueAllCIter(*this); }
1192 
1193  ValueOnIter beginValueOn() { return ValueOnIter(*this); }
1195  ValueOnCIter beginValueOn() const { return ValueOnCIter(*this); }
1196  ValueOnCIter cbeginValueOn() const { return ValueOnCIter(*this); }
1198 
1199  ValueOffIter beginValueOff() { return ValueOffIter(*this); }
1201  ValueOffCIter beginValueOff() const { return ValueOffCIter(*this); }
1202  ValueOffCIter cbeginValueOff() const { return ValueOffCIter(*this); }
1204 
1207  template<typename IterT> IterT begin();
1210  template<typename CIterT> CIterT cbegin() const;
1211 
1212 
1213 protected:
1214  typedef tbb::concurrent_hash_map<ValueAccessorBase<Tree, true>*, bool> AccessorRegistry;
1215  typedef tbb::concurrent_hash_map<ValueAccessorBase<const Tree, true>*, bool> ConstAccessorRegistry;
1216 
1217  // Disallow assignment of instances of this class.
1218  Tree& operator=(const Tree&);
1219 
1222  void releaseAllAccessors();
1223 
1224  // TBB body object used to deallocates nodes in parallel.
1225  template<typename NodeType>
1227  DeallocateNodes(std::vector<NodeType*>& nodes)
1228  : mNodes(nodes.empty() ? NULL : &nodes.front()) { }
1229  void operator()(const tbb::blocked_range<size_t>& range) const {
1230  for (size_t n = range.begin(), N = range.end(); n < N; ++n) {
1231  delete mNodes[n]; mNodes[n] = NULL;
1232  }
1233  }
1234  NodeType ** const mNodes;
1235  };
1236 
1237  //
1238  // Data members
1239  //
1240  RootNodeType mRoot; // root node of the tree
1241  mutable AccessorRegistry mAccessorRegistry;
1242  mutable ConstAccessorRegistry mConstAccessorRegistry;
1243 
1244  static tbb::atomic<const Name*> sTreeTypeName;
1245 }; // end of Tree class
1246 
1247 template<typename _RootNodeType>
1248 tbb::atomic<const Name*> Tree<_RootNodeType>::sTreeTypeName;
1249 
1250 
1255 template<typename T, Index N1=4, Index N2=3>
1256 struct Tree3 {
1258 };
1259 
1260 
1265 template<typename T, Index N1=5, Index N2=4, Index N3=3>
1266 struct Tree4 {
1268 };
1269 
1274 template<typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1275 struct Tree5 {
1278 };
1279 
1280 
1282 
1283 
1284 inline void
1285 TreeBase::readTopology(std::istream& is, bool /*saveFloatAsHalf*/)
1286 {
1287  int32_t bufferCount;
1288  is.read(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1289  if (bufferCount != 1) OPENVDB_LOG_WARN("multi-buffer trees are no longer supported");
1290 }
1291 
1292 
1293 inline void
1294 TreeBase::writeTopology(std::ostream& os, bool /*saveFloatAsHalf*/) const
1295 {
1296  int32_t bufferCount = 1;
1297  os.write(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1298 }
1299 
1300 
1301 inline void
1302 TreeBase::print(std::ostream& os, int /*verboseLevel*/) const
1303 {
1304  os << " Tree Type: " << type()
1305  << " Active Voxel Count: " << activeVoxelCount() << std::endl
1306 #ifndef OPENVDB_2_ABI_COMPATIBLE
1307  << " Active tile Count: " << activeTileCount() << std::endl
1308 #endif
1309  << " Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1310  << " Leaf Node Count: " << leafCount() << std::endl
1311  << " Non-leaf Node Count: " << nonLeafCount() << std::endl;
1312 }
1313 
1314 
1316 
1317 
1318 //
1319 // Type traits for tree iterators
1320 //
1321 
1324 template<typename TreeT, typename IterT> struct TreeIterTraits;
1325 
1326 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1327  static typename TreeT::RootNodeType::ChildOnIter begin(TreeT& tree) {
1328  return tree.beginRootChildren();
1329  }
1330 };
1331 
1332 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1333  static typename TreeT::RootNodeType::ChildOnCIter begin(const TreeT& tree) {
1334  return tree.cbeginRootChildren();
1335  }
1336 };
1337 
1338 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1339  static typename TreeT::RootNodeType::ChildOffIter begin(TreeT& tree) {
1340  return tree.beginRootTiles();
1341  }
1342 };
1343 
1344 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1345  static typename TreeT::RootNodeType::ChildOffCIter begin(const TreeT& tree) {
1346  return tree.cbeginRootTiles();
1347  }
1348 };
1349 
1350 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1351  static typename TreeT::RootNodeType::ChildAllIter begin(TreeT& tree) {
1352  return tree.beginRootDense();
1353  }
1354 };
1355 
1356 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1357  static typename TreeT::RootNodeType::ChildAllCIter begin(const TreeT& tree) {
1358  return tree.cbeginRootDense();
1359  }
1360 };
1361 
1362 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeIter> {
1363  static typename TreeT::NodeIter begin(TreeT& tree) { return tree.beginNode(); }
1364 };
1365 
1366 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeCIter> {
1367  static typename TreeT::NodeCIter begin(const TreeT& tree) { return tree.cbeginNode(); }
1368 };
1369 
1370 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafIter> {
1371  static typename TreeT::LeafIter begin(TreeT& tree) { return tree.beginLeaf(); }
1372 };
1373 
1374 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafCIter> {
1375  static typename TreeT::LeafCIter begin(const TreeT& tree) { return tree.cbeginLeaf(); }
1376 };
1377 
1378 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnIter> {
1379  static typename TreeT::ValueOnIter begin(TreeT& tree) { return tree.beginValueOn(); }
1380 };
1381 
1382 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1383  static typename TreeT::ValueOnCIter begin(const TreeT& tree) { return tree.cbeginValueOn(); }
1384 };
1385 
1386 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1387  static typename TreeT::ValueOffIter begin(TreeT& tree) { return tree.beginValueOff(); }
1388 };
1389 
1390 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1391  static typename TreeT::ValueOffCIter begin(const TreeT& tree) { return tree.cbeginValueOff(); }
1392 };
1393 
1394 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1395  static typename TreeT::ValueAllIter begin(TreeT& tree) { return tree.beginValueAll(); }
1396 };
1397 
1398 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1399  static typename TreeT::ValueAllCIter begin(const TreeT& tree) { return tree.cbeginValueAll(); }
1400 };
1401 
1402 
1403 template<typename RootNodeType>
1404 template<typename IterT>
1405 inline IterT
1407 {
1408  return TreeIterTraits<Tree, IterT>::begin(*this);
1409 }
1410 
1411 
1412 template<typename RootNodeType>
1413 template<typename IterT>
1414 inline IterT
1416 {
1417  return TreeIterTraits<Tree, IterT>::begin(*this);
1418 }
1419 
1420 
1422 
1423 
1424 template<typename RootNodeType>
1425 void
1426 Tree<RootNodeType>::readTopology(std::istream& is, bool saveFloatAsHalf)
1427 {
1428  this->clearAllAccessors();
1429  TreeBase::readTopology(is, saveFloatAsHalf);
1430  mRoot.readTopology(is, saveFloatAsHalf);
1431 }
1432 
1433 
1434 template<typename RootNodeType>
1435 void
1436 Tree<RootNodeType>::writeTopology(std::ostream& os, bool saveFloatAsHalf) const
1437 {
1438  TreeBase::writeTopology(os, saveFloatAsHalf);
1439  mRoot.writeTopology(os, saveFloatAsHalf);
1440 }
1441 
1442 
1443 template<typename RootNodeType>
1444 inline void
1445 Tree<RootNodeType>::readBuffers(std::istream &is, bool saveFloatAsHalf)
1446 {
1447  this->clearAllAccessors();
1448  mRoot.readBuffers(is, saveFloatAsHalf);
1449 }
1450 
1451 
1452 #ifndef OPENVDB_2_ABI_COMPATIBLE
1453 
1454 template<typename RootNodeType>
1455 inline void
1456 Tree<RootNodeType>::readBuffers(std::istream &is, const CoordBBox& bbox, bool saveFloatAsHalf)
1457 {
1458  this->clearAllAccessors();
1459  mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1460 }
1461 
1462 
1463 template<typename RootNodeType>
1464 inline void
1466 {
1467  for (LeafCIter it = this->cbeginLeaf(); it; ++it) {
1468  // Retrieving the value of a leaf voxel forces loading of the leaf node's voxel buffer.
1469  it->getValue(Index(0));
1470  }
1471 }
1472 
1473 #endif // !OPENVDB_2_ABI_COMPATIBLE
1474 
1475 
1476 template<typename RootNodeType>
1477 inline void
1478 Tree<RootNodeType>::writeBuffers(std::ostream &os, bool saveFloatAsHalf) const
1479 {
1480  mRoot.writeBuffers(os, saveFloatAsHalf);
1481 }
1482 
1483 
1484 template<typename RootNodeType>
1485 inline void
1487 {
1488  std::vector<LeafNodeType*> leafnodes;
1489  this->stealNodes(leafnodes);
1490 
1491  tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1492  DeallocateNodes<LeafNodeType>(leafnodes));
1493 
1494  std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1495  this->stealNodes(internalNodes);
1496 
1497  tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1499 
1500  mRoot.clear();
1501 
1502  this->clearAllAccessors();
1503 }
1504 
1505 
1507 
1508 
1509 template<typename RootNodeType>
1510 inline void
1512 {
1513  typename AccessorRegistry::accessor a;
1514  mAccessorRegistry.insert(a, &accessor);
1515 }
1516 
1517 
1518 template<typename RootNodeType>
1519 inline void
1521 {
1522  typename ConstAccessorRegistry::accessor a;
1523  mConstAccessorRegistry.insert(a, &accessor);
1524 }
1525 
1526 
1527 template<typename RootNodeType>
1528 inline void
1530 {
1531  mAccessorRegistry.erase(&accessor);
1532 }
1533 
1534 
1535 template<typename RootNodeType>
1536 inline void
1538 {
1539  mConstAccessorRegistry.erase(&accessor);
1540 }
1541 
1542 
1543 template<typename RootNodeType>
1544 inline void
1546 {
1547  for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1548  it != mAccessorRegistry.end(); ++it)
1549  {
1550  if (it->first) it->first->clear();
1551  }
1552 
1553  for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1554  it != mConstAccessorRegistry.end(); ++it)
1555  {
1556  if (it->first) it->first->clear();
1557  }
1558 }
1559 
1560 
1561 template<typename RootNodeType>
1562 inline void
1564 {
1565  mAccessorRegistry.erase(NULL);
1566  for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1567  it != mAccessorRegistry.end(); ++it)
1568  {
1569  it->first->release();
1570  }
1571  mAccessorRegistry.clear();
1572 
1573  mAccessorRegistry.erase(NULL);
1574  for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1575  it != mConstAccessorRegistry.end(); ++it)
1576  {
1577  it->first->release();
1578  }
1579  mConstAccessorRegistry.clear();
1580 }
1581 
1582 
1584 
1585 
1586 template<typename RootNodeType>
1587 inline const typename RootNodeType::ValueType&
1589 {
1590  return mRoot.getValue(xyz);
1591 }
1592 
1593 
1594 template<typename RootNodeType>
1595 template<typename AccessT>
1596 inline const typename RootNodeType::ValueType&
1597 Tree<RootNodeType>::getValue(const Coord& xyz, AccessT& accessor) const
1598 {
1599  return accessor.getValue(xyz);
1600 }
1601 
1602 
1603 template<typename RootNodeType>
1604 inline int
1606 {
1607  return mRoot.getValueDepth(xyz);
1608 }
1609 
1610 
1611 template<typename RootNodeType>
1612 inline void
1614 {
1615  mRoot.setValueOff(xyz);
1616 }
1617 
1618 
1619 template<typename RootNodeType>
1620 inline void
1621 Tree<RootNodeType>::setValueOff(const Coord& xyz, const ValueType& value)
1622 {
1623  mRoot.setValueOff(xyz, value);
1624 }
1625 
1626 
1627 template<typename RootNodeType>
1628 inline void
1630 {
1631  mRoot.setActiveState(xyz, on);
1632 }
1633 
1634 
1635 template<typename RootNodeType>
1636 inline void
1637 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value)
1638 {
1639  mRoot.setValueOn(xyz, value);
1640 }
1641 
1642 template<typename RootNodeType>
1643 inline void
1644 Tree<RootNodeType>::setValueOnly(const Coord& xyz, const ValueType& value)
1645 {
1646  mRoot.setValueOnly(xyz, value);
1647 }
1648 
1649 template<typename RootNodeType>
1650 template<typename AccessT>
1651 inline void
1652 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value, AccessT& accessor)
1653 {
1654  accessor.setValue(xyz, value);
1655 }
1656 
1657 
1658 template<typename RootNodeType>
1659 inline void
1661 {
1662  mRoot.setActiveState(xyz, true);
1663 }
1664 
1665 
1666 template<typename RootNodeType>
1667 inline void
1668 Tree<RootNodeType>::setValueOn(const Coord& xyz, const ValueType& value)
1669 {
1670  mRoot.setValueOn(xyz, value);
1671 }
1672 
1673 
1674 template<typename RootNodeType>
1675 template<typename ModifyOp>
1676 inline void
1677 Tree<RootNodeType>::modifyValue(const Coord& xyz, const ModifyOp& op)
1678 {
1679  mRoot.modifyValue(xyz, op);
1680 }
1681 
1682 
1683 template<typename RootNodeType>
1684 template<typename ModifyOp>
1685 inline void
1687 {
1688  mRoot.modifyValueAndActiveState(xyz, op);
1689 }
1690 
1691 
1692 template<typename RootNodeType>
1693 inline bool
1694 Tree<RootNodeType>::probeValue(const Coord& xyz, ValueType& value) const
1695 {
1696  return mRoot.probeValue(xyz, value);
1697 }
1698 
1699 
1701 
1702 
1703 template<typename RootNodeType>
1704 inline void
1706  const ValueType& value, bool active)
1707 {
1708  mRoot.addTile(level, xyz, value, active);
1709 }
1710 
1711 
1712 template<typename RootNodeType>
1713 template<typename NodeT>
1714 inline NodeT*
1715 Tree<RootNodeType>::stealNode(const Coord& xyz, const ValueType& value, bool active)
1716 {
1717  this->clearAllAccessors();
1718  return mRoot.template stealNode<NodeT>(xyz, value, active);
1719 }
1720 
1721 
1722 template<typename RootNodeType>
1723 inline typename RootNodeType::LeafNodeType*
1725 {
1726  return mRoot.touchLeaf(xyz);
1727 }
1728 
1729 
1730 template<typename RootNodeType>
1731 inline typename RootNodeType::LeafNodeType*
1733 {
1734  return mRoot.probeLeaf(xyz);
1735 }
1736 
1737 
1738 template<typename RootNodeType>
1739 inline const typename RootNodeType::LeafNodeType*
1741 {
1742  return mRoot.probeConstLeaf(xyz);
1743 }
1744 
1745 
1746 template<typename RootNodeType>
1747 template<typename NodeType>
1748 inline NodeType*
1750 {
1751  return mRoot.template probeNode<NodeType>(xyz);
1752 }
1753 
1754 
1755 template<typename RootNodeType>
1756 template<typename NodeType>
1757 inline const NodeType*
1759 {
1760  return this->template probeConstNode<NodeType>(xyz);
1761 }
1762 
1763 
1764 template<typename RootNodeType>
1765 template<typename NodeType>
1766 inline const NodeType*
1768 {
1769  return mRoot.template probeConstNode<NodeType>(xyz);
1770 }
1771 
1772 
1774 
1775 
1776 template<typename RootNodeType>
1777 inline void
1779 {
1780  this->clearAllAccessors();
1781  return mRoot.clip(bbox);
1782 }
1783 
1784 
1785 #ifndef OPENVDB_2_ABI_COMPATIBLE
1786 template<typename RootNodeType>
1787 inline void
1789 {
1790  this->clearAllAccessors();
1791  for (LeafIter it = this->beginLeaf(); it; ) {
1792  const LeafNodeType* leaf = it.getLeaf();
1793  ++it; // advance the iterator before deleting the leaf node
1794  if (!leaf->isAllocated()) {
1795  this->addTile(/*level=*/0, leaf->origin(), this->background(), /*active=*/false);
1796  }
1797  }
1798 }
1799 #endif
1800 
1801 
1802 template<typename RootNodeType>
1803 inline void
1804 Tree<RootNodeType>::denseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1805 {
1806  this->clearAllAccessors();
1807  return mRoot.denseFill(bbox, value, active);
1808 }
1809 
1810 template<typename RootNodeType>
1811 inline void
1812 Tree<RootNodeType>::sparseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1813 {
1814  this->clearAllAccessors();
1815  return mRoot.sparseFill(bbox, value, active);
1816 }
1817 
1818 
1819 template<typename RootNodeType>
1822 {
1823  Metadata::Ptr result;
1824  if (Metadata::isRegisteredType(valueType())) {
1825  typedef TypedMetadata<ValueType> MetadataT;
1826  result = Metadata::createMetadata(valueType());
1827  if (result->typeName() == MetadataT::staticTypeName()) {
1828  MetadataT* m = static_cast<MetadataT*>(result.get());
1829  m->value() = mRoot.background();
1830  }
1831  }
1832  return result;
1833 }
1834 
1835 
1837 
1838 
1839 template<typename RootNodeType>
1840 inline void
1842 {
1843  this->clearAllAccessors();
1844  mRoot.voxelizeActiveTiles(threaded);
1845 }
1846 
1847 
1848 template<typename RootNodeType>
1849 inline void
1851 {
1852  this->clearAllAccessors();
1853  other.clearAllAccessors();
1854  switch (policy) {
1855  case MERGE_ACTIVE_STATES:
1856  mRoot.template merge<MERGE_ACTIVE_STATES>(other.mRoot); break;
1857  case MERGE_NODES:
1858  mRoot.template merge<MERGE_NODES>(other.mRoot); break;
1860  mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.mRoot); break;
1861  }
1862 }
1863 
1864 
1865 template<typename RootNodeType>
1866 template<typename OtherRootNodeType>
1867 inline void
1869 {
1870  this->clearAllAccessors();
1871  mRoot.topologyUnion(other.root());
1872 }
1873 
1874 template<typename RootNodeType>
1875 template<typename OtherRootNodeType>
1876 inline void
1878 {
1879  this->clearAllAccessors();
1880  mRoot.topologyIntersection(other.root());
1881 }
1882 
1883 template<typename RootNodeType>
1884 template<typename OtherRootNodeType>
1885 inline void
1887 {
1888  this->clearAllAccessors();
1889  mRoot.topologyDifference(other.root());
1890 }
1891 
1893 
1894 
1897 template<typename AValueT, typename CombineOp, typename BValueT = AValueT>
1899 {
1900  CombineOpAdapter(CombineOp& _op): op(_op) {}
1901 
1903  op(args.a(), args.b(), args.result());
1904  }
1905 
1906  CombineOp& op;
1907 };
1908 
1909 
1910 template<typename RootNodeType>
1911 template<typename CombineOp>
1912 inline void
1913 Tree<RootNodeType>::combine(Tree& other, CombineOp& op, bool prune)
1914 {
1916  this->combineExtended(other, extendedOp, prune);
1917 }
1918 
1919 
1922 #ifndef _MSC_VER
1923 template<typename RootNodeType>
1924 template<typename CombineOp>
1925 inline void
1926 Tree<RootNodeType>::combine(Tree& other, const CombineOp& op, bool prune)
1927 {
1929  this->combineExtended(other, extendedOp, prune);
1930 }
1931 #endif
1932 
1933 
1934 template<typename RootNodeType>
1935 template<typename ExtendedCombineOp>
1936 inline void
1937 Tree<RootNodeType>::combineExtended(Tree& other, ExtendedCombineOp& op, bool prune)
1938 {
1939  this->clearAllAccessors();
1940  mRoot.combine(other.root(), op, prune);
1941 }
1942 
1943 
1946 #ifndef _MSC_VER
1947 template<typename RootNodeType>
1948 template<typename ExtendedCombineOp>
1949 inline void
1950 Tree<RootNodeType>::combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune)
1951 {
1952  this->clearAllAccessors();
1953  mRoot.template combine<const ExtendedCombineOp>(other.mRoot, op, prune);
1954 }
1955 #endif
1956 
1957 
1958 template<typename RootNodeType>
1959 template<typename CombineOp, typename OtherTreeType>
1960 inline void
1961 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune)
1962 {
1964  this->combine2Extended(a, b, extendedOp, prune);
1965 }
1966 
1967 
1970 #ifndef _MSC_VER
1971 template<typename RootNodeType>
1972 template<typename CombineOp, typename OtherTreeType>
1973 inline void
1974 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune)
1975 {
1977  this->combine2Extended(a, b, extendedOp, prune);
1978 }
1979 #endif
1980 
1981 
1982 template<typename RootNodeType>
1983 template<typename ExtendedCombineOp, typename OtherTreeType>
1984 inline void
1985 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
1986  ExtendedCombineOp& op, bool prune)
1987 {
1988  this->clearAllAccessors();
1989  mRoot.combine2(a.root(), b.root(), op, prune);
1990 }
1991 
1992 
1996 #ifndef _MSC_VER
1997 template<typename RootNodeType>
1998 template<typename ExtendedCombineOp, typename OtherTreeType>
1999 inline void
2000 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
2001  const ExtendedCombineOp& op, bool prune)
2002 {
2003  this->clearAllAccessors();
2004  mRoot.template combine2<const ExtendedCombineOp>(a.root(), b.root(), op, prune);
2005 }
2006 #endif
2007 
2008 
2010 
2011 
2012 template<typename RootNodeType>
2013 template<typename VisitorOp>
2014 inline void
2016 {
2017  this->clearAllAccessors();
2018  mRoot.template visit<VisitorOp>(op);
2019 }
2020 
2021 
2022 template<typename RootNodeType>
2023 template<typename VisitorOp>
2024 inline void
2025 Tree<RootNodeType>::visit(VisitorOp& op) const
2026 {
2027  mRoot.template visit<VisitorOp>(op);
2028 }
2029 
2030 
2033 template<typename RootNodeType>
2034 template<typename VisitorOp>
2035 inline void
2036 Tree<RootNodeType>::visit(const VisitorOp& op)
2037 {
2038  this->clearAllAccessors();
2039  mRoot.template visit<const VisitorOp>(op);
2040 }
2041 
2042 
2045 template<typename RootNodeType>
2046 template<typename VisitorOp>
2047 inline void
2048 Tree<RootNodeType>::visit(const VisitorOp& op) const
2049 {
2050  mRoot.template visit<const VisitorOp>(op);
2051 }
2052 
2053 
2055 
2056 
2057 template<typename RootNodeType>
2058 template<typename OtherTreeType, typename VisitorOp>
2059 inline void
2060 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op)
2061 {
2062  this->clearAllAccessors();
2063  typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
2064  mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2065 }
2066 
2067 
2068 template<typename RootNodeType>
2069 template<typename OtherTreeType, typename VisitorOp>
2070 inline void
2071 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op) const
2072 {
2073  typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
2074  mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2075 }
2076 
2077 
2080 template<typename RootNodeType>
2081 template<typename OtherTreeType, typename VisitorOp>
2082 inline void
2083 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op)
2084 {
2085  this->clearAllAccessors();
2086  typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
2087  mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2088 }
2089 
2090 
2093 template<typename RootNodeType>
2094 template<typename OtherTreeType, typename VisitorOp>
2095 inline void
2096 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op) const
2097 {
2098  typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
2099  mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2100 }
2101 
2102 
2104 
2105 
2106 template<typename RootNodeType>
2107 inline const Name&
2109 {
2110  if (sTreeTypeName == NULL) {
2111  std::vector<Index> dims;
2112  Tree::getNodeLog2Dims(dims);
2113  std::ostringstream ostr;
2114  ostr << "Tree_" << typeNameAsString<BuildType>();
2115  for (size_t i = 1, N = dims.size(); i < N; ++i) { // start from 1 to skip the RootNode
2116  ostr << "_" << dims[i];
2117  }
2118  Name* s = new Name(ostr.str());
2119  if (sTreeTypeName.compare_and_swap(s, NULL) != NULL) delete s;
2120  }
2121  return *sTreeTypeName;
2122 }
2123 
2124 
2125 template<typename RootNodeType>
2126 template<typename OtherRootNodeType>
2127 inline bool
2129 {
2130  return mRoot.hasSameTopology(other.root());
2131 }
2132 
2133 
2134 template<typename RootNodeType>
2135 Index64
2137 {
2138  Coord dim(0, 0, 0);
2139  this->evalActiveVoxelDim(dim);
2140  const Index64
2141  totalVoxels = dim.x() * dim.y() * dim.z(),
2142  activeVoxels = this->activeVoxelCount();
2143  assert(totalVoxels >= activeVoxels);
2144  return totalVoxels - activeVoxels;
2145 }
2146 
2147 
2148 template<typename RootNodeType>
2149 inline bool
2151 {
2152  bbox.reset(); // default invalid bbox
2153 
2154  if (this->empty()) return false; // empty
2155 
2156  mRoot.evalActiveBoundingBox(bbox, false);
2157 
2158  return true;// not empty
2159 }
2160 
2161 template<typename RootNodeType>
2162 inline bool
2164 {
2165  bbox.reset(); // default invalid bbox
2166 
2167  if (this->empty()) return false; // empty
2168 
2169  mRoot.evalActiveBoundingBox(bbox, true);
2170 
2171  return true;// not empty
2172 }
2173 
2174 
2175 template<typename RootNodeType>
2176 inline bool
2178 {
2179  CoordBBox bbox;
2180  bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2181  dim = bbox.extents();
2182  return notEmpty;
2183 }
2184 
2185 
2186 template<typename RootNodeType>
2187 inline bool
2189 {
2190  CoordBBox bbox;
2191  bool notEmpty = this->evalLeafBoundingBox(bbox);
2192  dim = bbox.extents();
2193  return notEmpty;
2194 }
2195 
2196 
2197 template<typename RootNodeType>
2198 inline void
2199 Tree<RootNodeType>::evalMinMax(ValueType& minVal, ValueType& maxVal) const
2200 {
2201  minVal = maxVal = zeroVal<ValueType>();
2202  if (ValueOnCIter iter = this->cbeginValueOn()) {
2203  minVal = maxVal = *iter;
2204  for (++iter; iter; ++iter) {
2205  const ValueType& val = *iter;
2206  if (val < minVal) minVal = val;
2207  if (val > maxVal) maxVal = val;
2208  }
2209  }
2210 }
2211 
2212 
2213 template<typename RootNodeType>
2214 inline void
2215 Tree<RootNodeType>::getNodeLog2Dims(std::vector<Index>& dims)
2216 {
2217  dims.clear();
2218  RootNodeType::getNodeLog2Dims(dims);
2219 }
2220 
2221 
2222 template<typename RootNodeType>
2223 inline void
2224 Tree<RootNodeType>::print(std::ostream& os, int verboseLevel) const
2225 {
2226  if (verboseLevel <= 0) return;
2227 
2229  struct OnExit {
2230  std::ostream& os;
2231  std::streamsize savedPrecision;
2232  OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2233  ~OnExit() { os.precision(savedPrecision); }
2234  };
2235  OnExit restorePrecision(os);
2236 
2237  std::vector<Index> dims;
2238  Tree::getNodeLog2Dims(dims);
2239 
2240  os << "Information about Tree:\n"
2241  << " Type: " << this->type() << "\n";
2242 
2243  os << " Configuration:\n";
2244 
2245  if (verboseLevel <= 1) {
2246  // Print node types and sizes.
2247  os << " Root(" << mRoot.getTableSize() << ")";
2248  if (dims.size() > 1) {
2249  for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2250  os << ", Internal(" << (1 << dims[i]) << "^3)";
2251  }
2252  os << ", Leaf(" << (1 << *dims.rbegin()) << "^3)\n";
2253  }
2254  os << " Background value: " << mRoot.background() << "\n";
2255  return;
2256  }
2257 
2258  // The following is tree information that is expensive to extract.
2259 
2260  ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2261  if (verboseLevel > 3) {
2262  // This forces loading of all non-resident nodes.
2263  this->evalMinMax(minVal, maxVal);
2264  }
2265 
2266  std::vector<Index64> nodeCount(dims.size());
2267 #ifndef OPENVDB_2_ABI_COMPATIBLE
2268  Index64 unallocatedLeafCount = 0;
2269 #endif
2270  for (NodeCIter it = cbeginNode(); it; ++it) {
2271  ++(nodeCount[it.getDepth()]);
2272 
2273 #ifndef OPENVDB_2_ABI_COMPATIBLE
2274  if (it.getLevel() == 0) {
2275  const LeafNodeType* leaf = NULL;
2276  it.getNode(leaf);
2277  if (leaf && !leaf->isAllocated()) ++unallocatedLeafCount;
2278  }
2279 #endif
2280  }
2281  Index64 totalNodeCount = 0;
2282  for (size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2283 
2284  // Print node types, counts and sizes.
2285  os << " Root(1 x " << mRoot.getTableSize() << ")";
2286  if (dims.size() > 1) {
2287  for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2288  os << ", Internal(" << util::formattedInt(nodeCount[i]);
2289  os << " x " << (1 << dims[i]) << "^3)";
2290  }
2291  os << ", Leaf(" << util::formattedInt(*nodeCount.rbegin());
2292  os << " x " << (1 << *dims.rbegin()) << "^3)\n";
2293  }
2294  os << " Background value: " << mRoot.background() << "\n";
2295 
2296  // Statistics of topology and values
2297 
2298  if (verboseLevel > 3) {
2299  os << " Min value: " << minVal << "\n";
2300  os << " Max value: " << maxVal << "\n";
2301  }
2302 
2303  const uint64_t
2304  leafCount = *nodeCount.rbegin(),
2305  numActiveVoxels = this->activeVoxelCount(),
2306  numActiveLeafVoxels = this->activeLeafVoxelCount(),
2307  numActiveTiles = this->activeTileCount();
2308 
2309  os << " Number of active voxels: " << util::formattedInt(numActiveVoxels) << "\n";
2310  os << " Number of active tiles: " << util::formattedInt(numActiveTiles) << "\n";
2311 
2312  Coord dim(0, 0, 0);
2313  uint64_t totalVoxels = 0;
2314  if (numActiveVoxels) { // nonempty
2315  CoordBBox bbox;
2316  this->evalActiveVoxelBoundingBox(bbox);
2317  dim = bbox.extents();
2318  totalVoxels = dim.x() * uint64_t(dim.y()) * dim.z();
2319 
2320  os << " Bounding box of active voxels: " << bbox << "\n";
2321  os << " Dimensions of active voxels: "
2322  << dim[0] << " x " << dim[1] << " x " << dim[2] << "\n";
2323 
2324  const double activeRatio = (100.0 * double(numActiveVoxels)) / double(totalVoxels);
2325  os << " Percentage of active voxels: " << std::setprecision(3) << activeRatio << "%\n";
2326 
2327  if (leafCount > 0) {
2328  const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2329  / (double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2330  os << " Average leaf node fill ratio: " << fillRatio << "%\n";
2331  }
2332 
2333 #ifndef OPENVDB_2_ABI_COMPATIBLE
2334  if (verboseLevel > 2) {
2335  os << " Number of unallocated nodes: "
2336  << util::formattedInt(unallocatedLeafCount) << " ("
2337  << (100.0 * double(unallocatedLeafCount) / double(totalNodeCount)) << "%)\n";
2338  }
2339 #endif
2340  } else {
2341  os << " Tree is empty!\n";
2342  }
2343  os << std::flush;
2344 
2345  if (verboseLevel == 2) return;
2346 
2347  // Memory footprint in bytes
2348  const uint64_t
2349  actualMem = this->memUsage(),
2350  denseMem = sizeof(ValueType) * totalVoxels,
2351  voxelsMem = sizeof(ValueType) * numActiveLeafVoxels;
2353 
2354  os << "Memory footprint:\n";
2355  util::printBytes(os, actualMem, " Actual: ");
2356  util::printBytes(os, voxelsMem, " Active leaf voxels: ");
2357 
2358  if (numActiveVoxels) {
2359  util::printBytes(os, denseMem, " Dense equivalent: ");
2360  os << " Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2361  << "% of an equivalent dense volume\n";
2362  os << " Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2363  << "% of actual footprint\n";
2364  }
2365 }
2366 
2367 } // namespace tree
2368 } // namespace OPENVDB_VERSION_NAME
2369 } // namespace openvdb
2370 
2371 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
2372 
2373 // Copyright (c) 2012-2016 DreamWorks Animation LLC
2374 // All rights reserved. This software is distributed under the
2375 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal, Internal, Leaf) with value type T and internal and leaf node log dimensions N1, N2, N3 and N4, respectively.
Definition: Tree.h:1275
Base class for typed trees.
Definition: Tree.h:65
bool operator==(const Tree &) const
Definition: Tree.h:302
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: Tree.h:1613
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates but don&#39;t change its active state.
Definition: Tree.h:1644
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:195
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:1677
Templated metadata class to hold specific types.
Definition: metadata/Metadata.h:139
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:1605
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1351
void getNodes(ArrayT &array) const
Adds all nodes of a certain type to a container with the following API:
Definition: Tree.h:593
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1686
ValueAllCIter cbeginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1190
#define OPENVDB_DEPRECATED
Definition: Platform.h:49
DeallocateNodes(std::vector< NodeType *> &nodes)
Definition: Tree.h:1227
RootNodeType::ValueType ValueType
Definition: Tree.h:212
Utility routines to output nicely-formatted numeric values.
RootNodeType mRoot
Definition: Tree.h:1240
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:259
RootNodeType & root()
Return this tree&#39;s root node.
Definition: Tree.h:307
Tree< RootNode< InternalNode< LeafNode< T, N2 >, N1 > > > Type
Definition: Tree.h:1257
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
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:1302
virtual Index64 activeVoxelCount() const
Return the total number of active voxels.
Definition: Tree.h:376
boost::shared_ptr< const TreeBase > ConstPtr
Definition: Tree.h:69
Tree< RootNode< InternalNode< InternalNode< InternalNode< LeafNode< T, N4 >, N3 >, N2 >, N1 > > > Type
Definition: Tree.h:1277
Definition: Types.h:442
void reset()
Definition: Coord.h:338
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: Tree.h:1660
RootNodeType::ChildAllCIter cbeginRootDense() const
Return an iterator over all entries of the root node&#39;s table.
Definition: Tree.h:1148
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:470
ValueAllCIter beginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1189
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1339
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition: Tree.h:225
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueAllCIter > ValueAllCIter
Definition: Tree.h:1180
std::string Name
Definition: Name.h:44
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1229
ValueOffCIter beginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1201
const LeafNodeType * probeLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: Tree.h:566
virtual Index64 inactiveLeafVoxelCount() const
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:374
RootNodeType::ChildOffIter beginRootTiles()
Return an iterator over non-child entries of the root node&#39;s table.
Definition: Tree.h:1142
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:977
virtual Index32 nonLeafCount() const
Return the number of non-leaf nodes.
Definition: Tree.h:370
void visitActiveBBox(BBoxOp &op) const
Use sparse traversal to call the given functor with bounding box information for all active tiles and...
Definition: Tree.h:995
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1242
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:517
NodeIteratorBase< const Tree, typename RootNodeType::ChildOnCIter > NodeCIter
Iterator over all nodes in this tree.
Definition: Tree.h:1156
Tree< typename RootNodeType::template ValueConverter< OtherValueType >::Type > Type
Definition: Tree.h:226
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:47
boost::shared_ptr< TreeBase > Ptr
Definition: Tree.h:68
const RootNodeType & root() const
Return this tree&#39;s root node.
Definition: Tree.h:308
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:155
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:130
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1900
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:658
RootNodeType::ChildOffCIter cbeginRootTiles() const
Return an iterator over non-child entries of the root node&#39;s table.
Definition: Tree.h:1141
virtual const Name & type() const
Return the name of this type of tree.
Definition: Tree.h:300
Int32 x() const
Definition: Coord.h:146
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1324
ValueOffCIter cbeginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1202
TreeValueIteratorBase< Tree, typename RootNodeType::ValueOnIter > ValueOnIter
Definition: Tree.h:1181
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal, Leaf) with value type T and internal and leaf node log dimensions N1, N2 and N3, respectively.
Definition: Tree.h:1266
static bool isRegisteredType(const Name &typeName)
Return true if the given type is known by the metadata type registry.
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:233
NodeType **const mNodes
Definition: Tree.h:1234
const AValueType & a() const
Get the A input value.
Definition: Types.h:352
boost::shared_ptr< Metadata > Ptr
Definition: metadata/Metadata.h:52
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueOnCIter > ValueOnCIter
Definition: Tree.h:1182
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:1637
Index32 Index
Definition: Types.h:58
TreeValueIteratorBase< Tree, typename RootNodeType::ValueOffIter > ValueOffIter
Definition: Tree.h:1183
_RootNodeType RootNodeType
Definition: Tree.h:211
OPENVDB_DEPRECATED 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:530
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1367
Tree()
Definition: Tree.h:230
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:280
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1395
Index64 activeTileCount() const
Return the total number of active tiles.
Definition: Tree.h:380
RootNodeType::ChildOnCIter cbeginRootChildren() const
Return an iterator over children of the root node.
Definition: Tree.h:1134
uint64_t Index64
Definition: Types.h:57
Internal table nodes for OpenVDB trees.
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1333
#define OPENVDB_VERSION_NAME
Definition: version.h:43
OPENVDB_STATIC_SPECIALIZATION GridType::Ptr clip(const GridType &grid, const BBoxd &)
Clip the given grid against a world-space bounding box and return a new grid containing the result...
Definition: Clip.h:356
NodeCIter beginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1168
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
Definition: Tree.h:651
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1176
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don&#39;t change its value.
Definition: Tree.h:1629
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1214
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1486
const BValueType & b() const
Get the B input value.
Definition: Types.h:354
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1363
ValueOnCIter cbeginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1196
const AValueType & result() const
Get the output value.
Definition: Types.h:357
TreeValueIteratorBase< Tree, typename RootNodeType::ValueAllIter > ValueAllIter
Definition: Tree.h:1179
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form &#39;someVar << "some text" << ...&#39;.
Definition: logging.h:39
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:633
const ValueType & background() const
Return this tree&#39;s background value.
Definition: Tree.h:675
Coord extents() const
Definition: Coord.h:365
OPENVDB_API int printBytes(std::ostream &os, uint64_t bytes, const std::string &head="", const std::string &tail="\, bool exact=false, int width=8, int precision=3)
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1545
virtual ~Tree()
Definition: Tree.h:289
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:468
MergePolicy
Definition: Types.h:264
virtual TreeBase::Ptr copy() const
Return a pointer to a deep copy of this tree.
Definition: Tree.h:292
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1327
Definition: Exceptions.h:39
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: Tree.h:1740
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:287
boost::shared_ptr< Tree > Ptr
Definition: Tree.h:208
uint32_t Index32
Definition: Types.h:56
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition: Tree.h:1256
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1399
CombineOp & op
Definition: Tree.h:1906
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels) ...
Definition: TreeIterator.h:1228
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueOffCIter > ValueOffCIter
Definition: Tree.h:1184
virtual Name valueType() const
Return the name of the type of a voxel&#39;s value (e.g., "float" or "vec3d")
Definition: Tree.h:295
Int32 z() const
Definition: Coord.h:148
RootNodeType::BuildType BuildType
Definition: Tree.h:213
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1898
RootNodeType::ChildOnIter beginRootChildren()
Return an iterator over children of the root node.
Definition: Tree.h:1135
virtual Index32 leafCount() const
Return the number of leaf nodes.
Definition: Tree.h:368
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:472
bool operator!=(const Tree &) const
Definition: Tree.h:303
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1588
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1694
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: Tree.h:1732
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:259
Definition: Exceptions.h:84
The root node of an OpenVDB tree.
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: Tree.h:496
NodeCIter cbeginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1169
virtual Index treeDepth() const
Return the depth of this tree.
Definition: Tree.h:366
Int32 y() const
Definition: Coord.h:147
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1383
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1375
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1371
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:374
static tbb::atomic< const Name * > sTreeTypeName
Definition: Tree.h:1244
virtual void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const
Write the tree topology to a stream.
Definition: Tree.h:1294
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1379
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1391
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:121
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1345
RootNodeType::ChildAllIter beginRootDense()
Return an iterator over all entries of the root node&#39;s table.
Definition: Tree.h:1149
virtual void getIndexRange(CoordBBox &bbox) const
Min and max are both inclusive.
Definition: Tree.h:678
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:244
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
virtual void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const
Write out all data buffers for this tree.
Definition: Tree.h:1478
virtual Index64 activeLeafVoxelCount() const
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:372
RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:214
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1387
ValueOnCIter beginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1195
Definition: Tree.h:205
virtual Metadata::Ptr getBackgroundValue() const
Return this tree&#39;s background value wrapped as metadata.
Definition: Tree.h:88
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1215
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1902
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
Definition: Tree.h:663
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:385
LeafIteratorBase< const Tree, typename RootNodeType::ChildOnCIter > LeafCIter
Iterator over all leaf nodes in this tree.
Definition: Tree.h:1162
Definition: Types.h:266
Tree< RootNode< InternalNode< InternalNode< LeafNode< T, N3 >, N2 >, N1 > > > Type
Definition: Tree.h:1267
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:312
LeafCIter beginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1175
virtual ~TreeBase()
Definition: Tree.h:72
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:620
TreeBase()
Definition: Tree.h:71
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1241
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:1705
virtual void readTopology(std::istream &, bool saveFloatAsHalf=false)
Read the tree topology from a stream.
Definition: Tree.h:1285
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:2128
static Metadata::Ptr createMetadata(const Name &typeName)
Create new metadata of the given type.
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1357
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:622
boost::shared_ptr< const Tree > ConstPtr
Definition: Tree.h:209
LeafNodeType * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, create one that preserves the values and active states of all voxels.
Definition: Tree.h:1724
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:128