OpenVDB  3.2.0
LeafNodeBool.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 
31 #ifndef OPENVDB_TREE_LEAF_NODE_BOOL_HAS_BEEN_INCLUDED
32 #define OPENVDB_TREE_LEAF_NODE_BOOL_HAS_BEEN_INCLUDED
33 
34 #include <iostream>
35 #include <boost/shared_ptr.hpp>
36 #include <boost/shared_array.hpp>
37 #include <boost/static_assert.hpp>
38 #include <openvdb/Types.h>
39 #include <openvdb/io/Compression.h> // for io::readData(), etc.
40 #include <openvdb/math/Math.h> // for math::isZero()
41 #include <openvdb/util/NodeMasks.h>
42 #include "LeafNode.h"
43 #include "Iterator.h"
44 
45 
46 namespace openvdb {
48 namespace OPENVDB_VERSION_NAME {
49 namespace tree {
50 
53 template<Index Log2Dim>
54 class LeafNode<bool, Log2Dim>
55 {
56 public:
58  typedef boost::shared_ptr<LeafNodeType> Ptr;
59  typedef bool BuildType;
60  typedef bool ValueType;
62 
63  // These static declarations must be on separate lines to avoid VC9 compiler errors.
64  static const Index LOG2DIM = Log2Dim; // needed by parent nodes
65  static const Index TOTAL = Log2Dim; // needed by parent nodes
66  static const Index DIM = 1 << TOTAL; // dimension along one coordinate direction
67  static const Index NUM_VALUES = 1 << 3 * Log2Dim;
68  static const Index NUM_VOXELS = NUM_VALUES; // total number of voxels represented by this node
69  static const Index SIZE = NUM_VALUES;
70  static const Index LEVEL = 0; // level 0 = leaf
71 
74  template<typename ValueType>
75  struct ValueConverter { typedef LeafNode<ValueType, Log2Dim> Type; };
76 
79  template<typename OtherNodeType>
80  struct SameConfiguration {
82  };
83 
84 
85  class Buffer
86  {
87  public:
88  typedef typename NodeMaskType::Word WordType;
89  static const Index WORD_COUNT = NodeMaskType::WORD_COUNT;
90  Buffer() {}
91  Buffer(bool on) : mData(on) {}
92  Buffer(const NodeMaskType& other): mData(other) {}
93  Buffer(const Buffer& other): mData(other.mData) {}
94  ~Buffer() {}
95  void fill(bool val) { mData.set(val); }
96  Buffer& operator=(const Buffer& b) { if (&b != this) { mData = b.mData; } return *this; }
97 
98  const bool& getValue(Index i) const
99  {
100  assert(i < SIZE);
101  // We can't use the ternary operator here, otherwise Visual C++ returns
102  // a reference to a temporary.
103  if (mData.isOn(i)) return LeafNode::sOn; else return LeafNode::sOff;
104  }
105  const bool& operator[](Index i) const { return this->getValue(i); }
106 
107  bool operator==(const Buffer& other) const { return mData == other.mData; }
108  bool operator!=(const Buffer& other) const { return mData != other.mData; }
109 
110  void setValue(Index i, bool val) { assert(i < SIZE); mData.set(i, val); }
111 
112  void swap(Buffer& other) { if (&other != this) std::swap(mData, other.mData); }
113 
114  Index memUsage() const { return sizeof(*this); }
115  static Index size() { return SIZE; }
116 
120  WordType* data()
121  {
122  return &(mData.template getWord<WordType>(0));
123  }
128  const WordType* data() const
129  {
130  return const_cast<Buffer*>(this)->data();
131  }
132 
133  private:
134  friend class ::TestLeaf;
135  // Allow the parent LeafNode to access this Buffer's bit mask.
136  friend class LeafNode;
137 
138  NodeMaskType mData;
139  }; // class Buffer
140 
141 
143  LeafNode();
144 
149  explicit LeafNode(const Coord& xyz, bool value = false, bool active = false);
150 
151 #ifndef OPENVDB_2_ABI_COMPATIBLE
152  LeafNode(PartialCreate, const Coord& xyz, bool value = false, bool active = false);
154 #endif
155 
157  LeafNode(const LeafNode&);
158 
160  template<typename OtherValueType>
161  explicit LeafNode(const LeafNode<OtherValueType, Log2Dim>& other);
162 
164  template<typename ValueType>
166 
168  template<typename ValueType>
171  LeafNode(const LeafNode<ValueType, Log2Dim>& other, bool offValue, bool onValue, TopologyCopy);
172  template<typename ValueType>
173  LeafNode(const LeafNode<ValueType, Log2Dim>& other, bool background, TopologyCopy);
175 
177  ~LeafNode();
178 
179  //
180  // Statistics
181  //
183  static Index log2dim() { return Log2Dim; }
185  static Index dim() { return DIM; }
186  static Index size() { return SIZE; }
187  static Index numValues() { return SIZE; }
188  static Index getLevel() { return LEVEL; }
189  static void getNodeLog2Dims(std::vector<Index>& dims) { dims.push_back(Log2Dim); }
190  static Index getChildDim() { return 1; }
191 
192  static Index32 leafCount() { return 1; }
193  static Index32 nonLeafCount() { return 0; }
194 
196  Index64 onVoxelCount() const { return mValueMask.countOn(); }
198  Index64 offVoxelCount() const { return mValueMask.countOff(); }
199  Index64 onLeafVoxelCount() const { return onVoxelCount(); }
200  Index64 offLeafVoxelCount() const { return offVoxelCount(); }
201  static Index64 onTileCount() { return 0; }
202  static Index64 offTileCount() { return 0; }
203 
205  bool isEmpty() const { return mValueMask.isOff(); }
207  bool isDense() const { return mValueMask.isOn(); }
208 
209 #ifndef OPENVDB_2_ABI_COMPATIBLE
210  bool isAllocated() const { return true; }
217  bool allocate() { return true; }
218 #endif
219 
221  Index64 memUsage() const;
222 
226  void evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels = true) const;
227 
230  CoordBBox getNodeBoundingBox() const { return CoordBBox::createCube(mOrigin, DIM); }
231 
233  void setOrigin(const Coord& origin) { mOrigin = origin; }
235  const Coord& origin() const { return mOrigin; }
237  void getOrigin(Coord& origin) const { origin = mOrigin; }
238  void getOrigin(Int32& x, Int32& y, Int32& z) const { mOrigin.asXYZ(x, y, z); }
240 
242  static Index coordToOffset(const Coord& xyz);
245  static Coord offsetToLocalCoord(Index n);
247  Coord offsetToGlobalCoord(Index n) const;
248 
250  std::string str() const;
251 
254  template<typename OtherType, Index OtherLog2Dim>
255  bool hasSameTopology(const LeafNode<OtherType, OtherLog2Dim>* other) const;
256 
258  bool operator==(const LeafNode&) const;
259  bool operator!=(const LeafNode&) const;
260 
261  //
262  // Buffer management
263  //
266  void swap(Buffer& other) { mBuffer.swap(other); }
267  const Buffer& buffer() const { return mBuffer; }
268  Buffer& buffer() { return mBuffer; }
269 
270  //
271  // I/O methods
272  //
274  void readTopology(std::istream&, bool fromHalf = false);
276  void writeTopology(std::ostream&, bool toHalf = false) const;
277 
279  void readBuffers(std::istream&, bool fromHalf = false);
280  void readBuffers(std::istream& is, const CoordBBox&, bool fromHalf = false);
282  void writeBuffers(std::ostream&, bool toHalf = false) const;
283 
284  //
285  // Accessor methods
286  //
288  const bool& getValue(const Coord& xyz) const;
290  const bool& getValue(Index offset) const;
291 
295  bool probeValue(const Coord& xyz, bool& val) const;
296 
298  static Index getValueLevel(const Coord&) { return LEVEL; }
299 
301  void setActiveState(const Coord& xyz, bool on);
303  void setActiveState(Index offset, bool on) { assert(offset<SIZE); mValueMask.set(offset, on); }
304 
306  void setValueOnly(const Coord& xyz, bool val);
308  void setValueOnly(Index offset, bool val) { assert(offset<SIZE); mBuffer.setValue(offset,val); }
309 
311  void setValueOff(const Coord& xyz) { mValueMask.setOff(this->coordToOffset(xyz)); }
313  void setValueOff(Index offset) { assert(offset < SIZE); mValueMask.setOff(offset); }
314 
316  void setValueOff(const Coord& xyz, bool val);
318  void setValueOff(Index offset, bool val);
319 
321  void setValueOn(const Coord& xyz) { mValueMask.setOn(this->coordToOffset(xyz)); }
323  void setValueOn(Index offset) { assert(offset < SIZE); mValueMask.setOn(offset); }
324 
326  void setValueOn(const Coord& xyz, bool val);
328  void setValue(const Coord& xyz, bool val) { this->setValueOn(xyz, val); }
330  void setValueOn(Index offset, bool val);
331 
334  template<typename ModifyOp>
335  void modifyValue(Index offset, const ModifyOp& op);
338  template<typename ModifyOp>
339  void modifyValue(const Coord& xyz, const ModifyOp& op);
340 
342  template<typename ModifyOp>
343  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op);
344 
346  void setValuesOn() { mValueMask.setOn(); }
348  void setValuesOff() { mValueMask.setOff(); }
349 
351  bool isValueOn(const Coord& xyz) const { return mValueMask.isOn(this->coordToOffset(xyz)); }
353  bool isValueOn(Index offset) const { assert(offset < SIZE); return mValueMask.isOn(offset); }
354 
356  static bool hasActiveTiles() { return false; }
357 
359  void clip(const CoordBBox&, bool background);
360 
362  void fill(const CoordBBox& bbox, bool value, bool active = true);
363 
365  void fill(const bool& value);
367  void fill(const bool& value, bool active);
368 
380  template<typename DenseT>
381  void copyToDense(const CoordBBox& bbox, DenseT& dense) const;
382 
399  template<typename DenseT>
400  void copyFromDense(const CoordBBox& bbox, const DenseT& dense, bool background, bool tolerance);
401 
404  template<typename AccessorT>
405  const bool& getValueAndCache(const Coord& xyz, AccessorT&) const {return this->getValue(xyz);}
406 
409  template<typename AccessorT>
410  bool isValueOnAndCache(const Coord& xyz, AccessorT&) const { return this->isValueOn(xyz); }
411 
414  template<typename AccessorT>
415  void setValueAndCache(const Coord& xyz, bool val, AccessorT&) { this->setValueOn(xyz, val); }
416 
420  template<typename AccessorT>
421  void setValueOnlyAndCache(const Coord& xyz, bool val, AccessorT&) {this->setValueOnly(xyz,val);}
422 
425  template<typename AccessorT>
426  void setValueOffAndCache(const Coord& xyz, bool value, AccessorT&)
427  {
428  this->setValueOff(xyz, value);
429  }
430 
434  template<typename ModifyOp, typename AccessorT>
435  void modifyValueAndCache(const Coord& xyz, const ModifyOp& op, AccessorT&)
436  {
437  this->modifyValue(xyz, op);
438  }
439 
442  template<typename ModifyOp, typename AccessorT>
443  void modifyValueAndActiveStateAndCache(const Coord& xyz, const ModifyOp& op, AccessorT&)
444  {
445  this->modifyValueAndActiveState(xyz, op);
446  }
447 
451  template<typename AccessorT>
452  void setActiveStateAndCache(const Coord& xyz, bool on, AccessorT&)
453  {
454  this->setActiveState(xyz, on);
455  }
456 
460  template<typename AccessorT>
461  bool probeValueAndCache(const Coord& xyz, bool& val, AccessorT&) const
462  {
463  return this->probeValue(xyz, val);
464  }
465 
468  template<typename AccessorT>
469  static Index getValueLevelAndCache(const Coord&, AccessorT&) { return LEVEL; }
470 
474  const bool& getFirstValue() const { if (mValueMask.isOn(0)) return sOn; else return sOff; }
478  const bool& getLastValue() const { if (mValueMask.isOn(SIZE-1)) return sOn; else return sOff; }
479 
483  bool isConstant(bool& constValue, bool& state, bool tolerance = 0) const;
485  bool isInactive() const { return mValueMask.isOff(); }
486 
487  void resetBackground(bool oldBackground, bool newBackground);
488 
489  void negate() { mBuffer.mData.toggle(); }
490 
491  template<MergePolicy Policy>
492  void merge(const LeafNode& other, bool bg = false, bool otherBG = false);
493  template<MergePolicy Policy> void merge(bool tileValue, bool tileActive);
494 
497  void voxelizeActiveTiles(bool = true) {}
498 
505  template<typename OtherType>
506  void topologyUnion(const LeafNode<OtherType, Log2Dim>& other);
507 
519  template<typename OtherType>
520  void topologyIntersection(const LeafNode<OtherType, Log2Dim>& other, const bool&);
521 
533  template<typename OtherType>
534  void topologyDifference(const LeafNode<OtherType, Log2Dim>& other, const bool&);
535 
536  template<typename CombineOp>
537  void combine(const LeafNode& other, CombineOp& op);
538  template<typename CombineOp>
539  void combine(bool, bool valueIsActive, CombineOp& op);
540 
541  template<typename CombineOp, typename OtherType /*= bool*/>
542  void combine2(const LeafNode& other, const OtherType&, bool valueIsActive, CombineOp&);
543  template<typename CombineOp, typename OtherNodeT /*= LeafNode*/>
544  void combine2(bool, const OtherNodeT& other, bool valueIsActive, CombineOp&);
545  template<typename CombineOp, typename OtherNodeT /*= LeafNode*/>
546  void combine2(const LeafNode& b0, const OtherNodeT& b1, CombineOp&);
547 
552  template<typename BBoxOp> void visitActiveBBox(BBoxOp&) const;
553 
554  template<typename VisitorOp> void visit(VisitorOp&);
555  template<typename VisitorOp> void visit(VisitorOp&) const;
556 
557  template<typename OtherLeafNodeType, typename VisitorOp>
558  void visit2Node(OtherLeafNodeType& other, VisitorOp&);
559  template<typename OtherLeafNodeType, typename VisitorOp>
560  void visit2Node(OtherLeafNodeType& other, VisitorOp&) const;
561  template<typename IterT, typename VisitorOp>
562  void visit2(IterT& otherIter, VisitorOp&, bool otherIsLHS = false);
563  template<typename IterT, typename VisitorOp>
564  void visit2(IterT& otherIter, VisitorOp&, bool otherIsLHS = false) const;
565 
567  void prune(const ValueType& /*tolerance*/ = zeroVal<ValueType>()) {}
569  void addLeaf(LeafNode*) {}
570  template<typename AccessorT>
571  void addLeafAndCache(LeafNode*, AccessorT&) {}
572  template<typename NodeT>
573  NodeT* stealNode(const Coord&, const ValueType&, bool) { return NULL; }
574  template<typename NodeT>
575  NodeT* probeNode(const Coord&) { return NULL; }
576  template<typename NodeT>
577  const NodeT* probeConstNode(const Coord&) const { return NULL; }
578  template<typename ArrayT> void getNodes(ArrayT&) const {}
579  template<typename ArrayT> void stealNodes(ArrayT&, const ValueType&, bool) {}
581 
582  void addTile(Index level, const Coord&, bool val, bool active);
583  void addTile(Index offset, bool val, bool active);
584  template<typename AccessorT>
585  void addTileAndCache(Index level, const Coord&, bool val, bool active, AccessorT&);
586 
588  LeafNode* touchLeaf(const Coord&) { return this; }
590  template<typename AccessorT>
591  LeafNode* touchLeafAndCache(const Coord&, AccessorT&) { return this; }
592  LeafNode* probeLeaf(const Coord&) { return this; }
593  template<typename AccessorT>
594  LeafNode* probeLeafAndCache(const Coord&, AccessorT&) { return this; }
595  template<typename NodeT, typename AccessorT>
596  NodeT* probeNodeAndCache(const Coord&, AccessorT&)
597  {
599  if (!(boost::is_same<NodeT,LeafNode>::value)) return NULL;
600  return reinterpret_cast<NodeT*>(this);
602  }
604 
605  const LeafNode* probeLeaf(const Coord&) const { return this; }
607  template<typename AccessorT>
608  const LeafNode* probeLeafAndCache(const Coord&, AccessorT&) const { return this; }
609  const LeafNode* probeConstLeaf(const Coord&) const { return this; }
610  template<typename AccessorT>
611  const LeafNode* probeConstLeafAndCache(const Coord&, AccessorT&) const { return this; }
612  template<typename NodeT, typename AccessorT>
613  const NodeT* probeConstNodeAndCache(const Coord&, AccessorT&) const
614  {
616  if (!(boost::is_same<NodeT,LeafNode>::value)) return NULL;
617  return reinterpret_cast<const NodeT*>(this);
619  }
621 
622  //
623  // Iterators
624  //
625 protected:
629 
630  template<typename MaskIterT, typename NodeT, typename ValueT>
631  struct ValueIter:
632  // Derives from SparseIteratorBase, but can also be used as a dense iterator,
633  // if MaskIterT is a dense mask iterator type.
634  public SparseIteratorBase<MaskIterT, ValueIter<MaskIterT, NodeT, ValueT>, NodeT, ValueT>
635  {
637 
639  ValueIter(const MaskIterT& iter, NodeT* parent): BaseT(iter, parent) {}
640 
641  const bool& getItem(Index pos) const { return this->parent().getValue(pos); }
642  const bool& getValue() const { return this->getItem(this->pos()); }
643 
644  // Note: setItem() can't be called on const iterators.
645  void setItem(Index pos, bool value) const { this->parent().setValueOnly(pos, value); }
646  // Note: setValue() can't be called on const iterators.
647  void setValue(bool value) const { this->setItem(this->pos(), value); }
648 
649  // Note: modifyItem() can't be called on const iterators.
650  template<typename ModifyOp>
651  void modifyItem(Index n, const ModifyOp& op) const { this->parent().modifyValue(n, op); }
652  // Note: modifyValue() can't be called on const iterators.
653  template<typename ModifyOp>
654  void modifyValue(const ModifyOp& op) const { this->modifyItem(this->pos(), op); }
655  };
656 
658  template<typename MaskIterT, typename NodeT>
659  struct ChildIter:
660  public SparseIteratorBase<MaskIterT, ChildIter<MaskIterT, NodeT>, NodeT, bool>
661  {
663  ChildIter(const MaskIterT& iter, NodeT* parent): SparseIteratorBase<
664  MaskIterT, ChildIter<MaskIterT, NodeT>, NodeT, bool>(iter, parent) {}
665  };
666 
667  template<typename NodeT, typename ValueT>
668  struct DenseIter: public DenseIteratorBase<
669  MaskDenseIter, DenseIter<NodeT, ValueT>, NodeT, /*ChildT=*/void, ValueT>
670  {
673 
675  DenseIter(const MaskDenseIter& iter, NodeT* parent): BaseT(iter, parent) {}
676 
677  bool getItem(Index pos, void*& child, NonConstValueT& value) const
678  {
679  value = this->parent().getValue(pos);
680  child = NULL;
681  return false; // no child
682  }
683 
684  // Note: setItem() can't be called on const iterators.
685  //void setItem(Index pos, void* child) const {}
686 
687  // Note: unsetItem() can't be called on const iterators.
688  void unsetItem(Index pos, const ValueT& val) const {this->parent().setValueOnly(pos, val);}
689  };
690 
691 public:
692  typedef ValueIter<MaskOnIter, LeafNode, const bool> ValueOnIter;
693  typedef ValueIter<MaskOnIter, const LeafNode, const bool> ValueOnCIter;
694  typedef ValueIter<MaskOffIter, LeafNode, const bool> ValueOffIter;
695  typedef ValueIter<MaskOffIter, const LeafNode, const bool> ValueOffCIter;
696  typedef ValueIter<MaskDenseIter, LeafNode, const bool> ValueAllIter;
697  typedef ValueIter<MaskDenseIter, const LeafNode, const bool> ValueAllCIter;
698  typedef ChildIter<MaskOnIter, LeafNode> ChildOnIter;
699  typedef ChildIter<MaskOnIter, const LeafNode> ChildOnCIter;
700  typedef ChildIter<MaskOffIter, LeafNode> ChildOffIter;
701  typedef ChildIter<MaskOffIter, const LeafNode> ChildOffCIter;
702  typedef DenseIter<LeafNode, bool> ChildAllIter;
703  typedef DenseIter<const LeafNode, const bool> ChildAllCIter;
704 
705  ValueOnCIter cbeginValueOn() const { return ValueOnCIter(mValueMask.beginOn(), this); }
706  ValueOnCIter beginValueOn() const { return ValueOnCIter(mValueMask.beginOn(), this); }
707  ValueOnIter beginValueOn() { return ValueOnIter(mValueMask.beginOn(), this); }
708  ValueOffCIter cbeginValueOff() const { return ValueOffCIter(mValueMask.beginOff(), this); }
709  ValueOffCIter beginValueOff() const { return ValueOffCIter(mValueMask.beginOff(), this); }
710  ValueOffIter beginValueOff() { return ValueOffIter(mValueMask.beginOff(), this); }
711  ValueAllCIter cbeginValueAll() const { return ValueAllCIter(mValueMask.beginDense(), this); }
712  ValueAllCIter beginValueAll() const { return ValueAllCIter(mValueMask.beginDense(), this); }
713  ValueAllIter beginValueAll() { return ValueAllIter(mValueMask.beginDense(), this); }
714 
715  ValueOnCIter cendValueOn() const { return ValueOnCIter(mValueMask.endOn(), this); }
716  ValueOnCIter endValueOn() const { return ValueOnCIter(mValueMask.endOn(), this); }
717  ValueOnIter endValueOn() { return ValueOnIter(mValueMask.endOn(), this); }
718  ValueOffCIter cendValueOff() const { return ValueOffCIter(mValueMask.endOff(), this); }
719  ValueOffCIter endValueOff() const { return ValueOffCIter(mValueMask.endOff(), this); }
720  ValueOffIter endValueOff() { return ValueOffIter(mValueMask.endOff(), this); }
721  ValueAllCIter cendValueAll() const { return ValueAllCIter(mValueMask.endDense(), this); }
722  ValueAllCIter endValueAll() const { return ValueAllCIter(mValueMask.endDense(), this); }
723  ValueAllIter endValueAll() { return ValueAllIter(mValueMask.endDense(), this); }
724 
725  // Note that [c]beginChildOn() and [c]beginChildOff() actually return end iterators,
726  // because leaf nodes have no children.
727  ChildOnCIter cbeginChildOn() const { return ChildOnCIter(mValueMask.endOn(), this); }
728  ChildOnCIter beginChildOn() const { return ChildOnCIter(mValueMask.endOn(), this); }
729  ChildOnIter beginChildOn() { return ChildOnIter(mValueMask.endOn(), this); }
730  ChildOffCIter cbeginChildOff() const { return ChildOffCIter(mValueMask.endOff(), this); }
731  ChildOffCIter beginChildOff() const { return ChildOffCIter(mValueMask.endOff(), this); }
732  ChildOffIter beginChildOff() { return ChildOffIter(mValueMask.endOff(), this); }
733  ChildAllCIter cbeginChildAll() const { return ChildAllCIter(mValueMask.beginDense(), this); }
734  ChildAllCIter beginChildAll() const { return ChildAllCIter(mValueMask.beginDense(), this); }
735  ChildAllIter beginChildAll() { return ChildAllIter(mValueMask.beginDense(), this); }
736 
737  ChildOnCIter cendChildOn() const { return ChildOnCIter(mValueMask.endOn(), this); }
738  ChildOnCIter endChildOn() const { return ChildOnCIter(mValueMask.endOn(), this); }
739  ChildOnIter endChildOn() { return ChildOnIter(mValueMask.endOn(), this); }
740  ChildOffCIter cendChildOff() const { return ChildOffCIter(mValueMask.endOff(), this); }
741  ChildOffCIter endChildOff() const { return ChildOffCIter(mValueMask.endOff(), this); }
742  ChildOffIter endChildOff() { return ChildOffIter(mValueMask.endOff(), this); }
743  ChildAllCIter cendChildAll() const { return ChildAllCIter(mValueMask.endDense(), this); }
744  ChildAllCIter endChildAll() const { return ChildAllCIter(mValueMask.endDense(), this); }
745  ChildAllIter endChildAll() { return ChildAllIter(mValueMask.endDense(), this); }
746 
747  //
748  // Mask accessors
749  //
750  bool isValueMaskOn(Index n) const { return mValueMask.isOn(n); }
751  bool isValueMaskOn() const { return mValueMask.isOn(); }
752  bool isValueMaskOff(Index n) const { return mValueMask.isOff(n); }
753  bool isValueMaskOff() const { return mValueMask.isOff(); }
754  const NodeMaskType& getValueMask() const { return mValueMask; }
755  const NodeMaskType& valueMask() const { return mValueMask; }
756  NodeMaskType& getValueMask() { return mValueMask; }
757  void setValueMask(const NodeMaskType& mask) { mValueMask = mask; }
758  bool isChildMaskOn(Index) const { return false; } // leaf nodes have no children
759  bool isChildMaskOff(Index) const { return true; }
760  bool isChildMaskOff() const { return true; }
761 protected:
762  void setValueMask(Index n, bool on) { mValueMask.set(n, on); }
763  void setValueMaskOn(Index n) { mValueMask.setOn(n); }
764  void setValueMaskOff(Index n) { mValueMask.setOff(n); }
765 
767  static void evalNodeOrigin(Coord& xyz) { xyz &= ~(DIM - 1); }
768 
769  template<typename NodeT, typename VisitorOp, typename ChildAllIterT>
770  static inline void doVisit(NodeT&, VisitorOp&);
771 
772  template<typename NodeT, typename OtherNodeT, typename VisitorOp,
773  typename ChildAllIterT, typename OtherChildAllIterT>
774  static inline void doVisit2Node(NodeT& self, OtherNodeT& other, VisitorOp&);
775 
776  template<typename NodeT, typename VisitorOp,
777  typename ChildAllIterT, typename OtherChildAllIterT>
778  static inline void doVisit2(NodeT& self, OtherChildAllIterT&, VisitorOp&, bool otherIsLHS);
779 
780 
782  NodeMaskType mValueMask;
784  Buffer mBuffer;
786  Coord mOrigin;
787 
788  // These static declarations must be on separate lines to avoid VC9 compiler errors.
789  static const bool sOn;
790  static const bool sOff;
791 
792 private:
795  template<typename, Index> friend class LeafNode;
796 
797  friend struct ValueIter<MaskOnIter, LeafNode, bool>;
798  friend struct ValueIter<MaskOffIter, LeafNode, bool>;
799  friend struct ValueIter<MaskDenseIter, LeafNode, bool>;
800  friend struct ValueIter<MaskOnIter, const LeafNode, bool>;
801  friend struct ValueIter<MaskOffIter, const LeafNode, bool>;
802  friend struct ValueIter<MaskDenseIter, const LeafNode, bool>;
803 
805  friend class IteratorBase<MaskOnIter, LeafNode>;
808  friend class IteratorBase<MaskOffIter, LeafNode>;
809  friend class IteratorBase<MaskDenseIter, LeafNode>;
811 
812 }; // class LeafNode<bool>
813 
814 
819 template<Index Log2Dim> const bool LeafNode<bool, Log2Dim>::sOn = true;
820 template<Index Log2Dim> const bool LeafNode<bool, Log2Dim>::sOff = false;
821 
822 
824 
825 
826 template<Index Log2Dim>
827 inline
829  : mOrigin(0, 0, 0)
830 {
831 }
832 
833 
834 template<Index Log2Dim>
835 inline
836 LeafNode<bool, Log2Dim>::LeafNode(const Coord& xyz, bool value, bool active)
837  : mValueMask(active)
838  , mBuffer(value)
839  , mOrigin(xyz & (~(DIM - 1)))
840 {
841 }
842 
843 
844 #ifndef OPENVDB_2_ABI_COMPATIBLE
845 template<Index Log2Dim>
846 inline
847 LeafNode<bool, Log2Dim>::LeafNode(PartialCreate, const Coord& xyz, bool value, bool active)
848  : mValueMask(active)
849  , mBuffer(value)
850  , mOrigin(xyz & (~(DIM - 1)))
851 {
855 }
856 #endif
857 
858 
859 template<Index Log2Dim>
860 inline
861 LeafNode<bool, Log2Dim>::LeafNode(const LeafNode &other)
862  : mValueMask(other.valueMask())
863  , mBuffer(other.mBuffer)
864  , mOrigin(other.mOrigin)
865 {
866 }
867 
868 
869 // Copy-construct from a leaf node with the same configuration but a different ValueType.
870 template<Index Log2Dim>
871 template<typename ValueT>
872 inline
874  : mValueMask(other.valueMask())
875  , mOrigin(other.origin())
876 {
877  struct Local {
879  static inline bool convertValue(const ValueT& val) { return bool(val); }
880  };
881 
882  for (Index i = 0; i < SIZE; ++i) {
883  mBuffer.setValue(i, Local::convertValue(other.mBuffer[i]));
884  }
885 }
886 
887 
888 template<Index Log2Dim>
889 template<typename ValueT>
890 inline
892  bool background, TopologyCopy)
893  : mValueMask(other.valueMask())
894  , mBuffer(background)
895  , mOrigin(other.origin())
896 {
897 }
898 
899 
900 template<Index Log2Dim>
901 template<typename ValueT>
902 inline
904  : mValueMask(other.valueMask())
905  , mBuffer(other.valueMask())// value = active state
906  , mOrigin(other.origin())
907 {
908 }
909 
910 
911 template<Index Log2Dim>
912 template<typename ValueT>
913 inline
915  bool offValue, bool onValue, TopologyCopy)
916  : mValueMask(other.valueMask())
917  , mBuffer(other.valueMask())
918  , mOrigin(other.origin())
919 {
920  if (offValue) { if (!onValue) mBuffer.mData.toggle(); else mBuffer.mData.setOn(); }
921 }
922 
923 
924 template<Index Log2Dim>
925 inline
927 {
928 }
929 
930 
932 
933 
934 template<Index Log2Dim>
935 inline Index64
937 {
938  // Use sizeof(*this) to capture alignment-related padding
939  return sizeof(*this);
940 }
941 
942 
943 template<Index Log2Dim>
944 inline void
945 LeafNode<bool, Log2Dim>::evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels) const
946 {
947  CoordBBox this_bbox = this->getNodeBoundingBox();
948  if (bbox.isInside(this_bbox)) return;//this LeafNode is already enclosed in the bbox
949  if (ValueOnCIter iter = this->cbeginValueOn()) {//any active values?
950  if (visitVoxels) {//use voxel granularity?
951  this_bbox.reset();
952  for(; iter; ++iter) this_bbox.expand(this->offsetToLocalCoord(iter.pos()));
953  this_bbox.translate(this->origin());
954  }
955  bbox.expand(this_bbox);
956  }
957 }
958 
959 
960 template<Index Log2Dim>
961 template<typename OtherType, Index OtherLog2Dim>
962 inline bool
964 {
965  assert(other);
966  return (Log2Dim == OtherLog2Dim && mValueMask == other->getValueMask());
967 }
968 
969 
970 template<Index Log2Dim>
971 inline std::string
973 {
974  std::ostringstream ostr;
975  ostr << "LeafNode @" << mOrigin << ": ";
976  for (Index32 n = 0; n < SIZE; ++n) ostr << (mValueMask.isOn(n) ? '#' : '.');
977  return ostr.str();
978 }
979 
980 
982 
983 
984 template<Index Log2Dim>
985 inline Index
987 {
988  assert ((xyz[0] & (DIM-1u)) < DIM && (xyz[1] & (DIM-1u)) < DIM && (xyz[2] & (DIM-1u)) < DIM);
989  return ((xyz[0] & (DIM-1u)) << 2*Log2Dim)
990  + ((xyz[1] & (DIM-1u)) << Log2Dim)
991  + (xyz[2] & (DIM-1u));
992 }
993 
994 
995 template<Index Log2Dim>
996 inline Coord
998 {
999  assert(n < (1 << 3*Log2Dim));
1000  Coord xyz;
1001  xyz.setX(n >> 2*Log2Dim);
1002  n &= ((1 << 2*Log2Dim) - 1);
1003  xyz.setY(n >> Log2Dim);
1004  xyz.setZ(n & ((1 << Log2Dim) - 1));
1005  return xyz;
1006 }
1007 
1008 
1009 template<Index Log2Dim>
1010 inline Coord
1012 {
1013  return (this->offsetToLocalCoord(n) + this->origin());
1014 }
1015 
1016 
1018 
1019 
1020 template<Index Log2Dim>
1021 inline void
1022 LeafNode<bool, Log2Dim>::readTopology(std::istream& is, bool /*fromHalf*/)
1023 {
1024  mValueMask.load(is);
1025 }
1026 
1027 
1028 template<Index Log2Dim>
1029 inline void
1030 LeafNode<bool, Log2Dim>::writeTopology(std::ostream& os, bool /*toHalf*/) const
1031 {
1032  mValueMask.save(os);
1033 }
1034 
1035 
1036 template<Index Log2Dim>
1037 inline void
1038 LeafNode<bool, Log2Dim>::readBuffers(std::istream& is, const CoordBBox& clipBBox, bool fromHalf)
1039 {
1040  // Boolean LeafNodes don't currently implement lazy loading.
1041  // Instead, load the full buffer, then clip it.
1042 
1043  this->readBuffers(is, fromHalf);
1044 
1045  // Get this tree's background value.
1046  bool background = false;
1047  if (const void* bgPtr = io::getGridBackgroundValuePtr(is)) {
1048  background = *static_cast<const bool*>(bgPtr);
1049  }
1050  this->clip(clipBBox, background);
1051 }
1052 
1053 
1054 template<Index Log2Dim>
1055 inline void
1056 LeafNode<bool, Log2Dim>::readBuffers(std::istream& is, bool /*fromHalf*/)
1057 {
1058  // Read in the value mask.
1059  mValueMask.load(is);
1060  // Read in the origin.
1061  is.read(reinterpret_cast<char*>(&mOrigin), sizeof(Coord::ValueType) * 3);
1062 
1064  // Read in the mask for the voxel values.
1065  mBuffer.mData.load(is);
1066  } else {
1067  // Older files stored one or more bool arrays.
1068 
1069  // Read in the number of buffers, which should now always be one.
1070  int8_t numBuffers = 0;
1071  is.read(reinterpret_cast<char*>(&numBuffers), sizeof(int8_t));
1072 
1073  // Read in the buffer.
1074  // (Note: prior to the bool leaf optimization, buffers were always compressed.)
1075  boost::shared_array<bool> buf(new bool[SIZE]);
1076  io::readData<bool>(is, buf.get(), SIZE, /*isCompressed=*/true);
1077 
1078  // Transfer values to mBuffer.
1079  mBuffer.mData.setOff();
1080  for (Index i = 0; i < SIZE; ++i) {
1081  if (buf[i]) mBuffer.mData.setOn(i);
1082  }
1083 
1084  if (numBuffers > 1) {
1085  // Read in and discard auxiliary buffers that were created with
1086  // earlier versions of the library.
1087  for (int i = 1; i < numBuffers; ++i) {
1088  io::readData<bool>(is, buf.get(), SIZE, /*isCompressed=*/true);
1089  }
1090  }
1091  }
1092 }
1093 
1094 
1095 template<Index Log2Dim>
1096 inline void
1097 LeafNode<bool, Log2Dim>::writeBuffers(std::ostream& os, bool /*toHalf*/) const
1098 {
1099  // Write out the value mask.
1100  mValueMask.save(os);
1101  // Write out the origin.
1102  os.write(reinterpret_cast<const char*>(&mOrigin), sizeof(Coord::ValueType) * 3);
1103  // Write out the voxel values.
1104  mBuffer.mData.save(os);
1105 }
1106 
1107 
1109 
1110 
1111 template<Index Log2Dim>
1112 inline bool
1113 LeafNode<bool, Log2Dim>::operator==(const LeafNode& other) const
1114 {
1115  return mOrigin == other.mOrigin &&
1116  mValueMask == other.valueMask() &&
1117  mBuffer == other.mBuffer;
1118 }
1119 
1120 
1121 template<Index Log2Dim>
1122 inline bool
1123 LeafNode<bool, Log2Dim>::operator!=(const LeafNode& other) const
1124 {
1125  return !(this->operator==(other));
1126 }
1127 
1128 
1130 
1131 
1132 template<Index Log2Dim>
1133 inline bool
1134 LeafNode<bool, Log2Dim>::isConstant(bool& constValue, bool& state, bool tolerance) const
1135 {
1136  if (!mValueMask.isConstant(state)) return false;
1137 
1138  // Note: if tolerance is true (i.e., 1), then all boolean values compare equal.
1139  if (!tolerance && !(mBuffer.mData.isOn() || mBuffer.mData.isOff())) return false;
1140 
1141  constValue = mBuffer.mData.isOn();
1142  return true;
1143 }
1144 
1145 
1147 
1148 
1149 template<Index Log2Dim>
1150 inline void
1151 LeafNode<bool, Log2Dim>::addTile(Index /*level*/, const Coord& xyz, bool val, bool active)
1152 {
1153  this->addTile(this->coordToOffset(xyz), val, active);
1154 }
1155 
1156 template<Index Log2Dim>
1157 inline void
1158 LeafNode<bool, Log2Dim>::addTile(Index offset, bool val, bool active)
1159 {
1160  assert(offset < SIZE);
1161  this->setValueOnly(offset, val);
1162  this->setActiveState(offset, active);
1163 }
1164 
1165 template<Index Log2Dim>
1166 template<typename AccessorT>
1167 inline void
1169  bool val, bool active, AccessorT&)
1170 {
1171  this->addTile(level, xyz, val, active);
1172 }
1173 
1174 
1176 
1177 
1178 template<Index Log2Dim>
1179 inline const bool&
1180 LeafNode<bool, Log2Dim>::getValue(const Coord& xyz) const
1181 {
1182  // This *CANNOT* use operator ? because Visual C++
1183  if (mBuffer.mData.isOn(this->coordToOffset(xyz))) return sOn; else return sOff;
1184 }
1185 
1186 
1187 template<Index Log2Dim>
1188 inline const bool&
1190 {
1191  assert(offset < SIZE);
1192  // This *CANNOT* use operator ? for Windows
1193  if (mBuffer.mData.isOn(offset)) return sOn; else return sOff;
1194 }
1195 
1196 
1197 template<Index Log2Dim>
1198 inline bool
1199 LeafNode<bool, Log2Dim>::probeValue(const Coord& xyz, bool& val) const
1200 {
1201  const Index offset = this->coordToOffset(xyz);
1202  val = mBuffer.mData.isOn(offset);
1203  return mValueMask.isOn(offset);
1204 }
1205 
1206 
1207 template<Index Log2Dim>
1208 inline void
1209 LeafNode<bool, Log2Dim>::setValueOn(const Coord& xyz, bool val)
1210 {
1211  this->setValueOn(this->coordToOffset(xyz), val);
1212 }
1213 
1214 
1215 template<Index Log2Dim>
1216 inline void
1218 {
1219  assert(offset < SIZE);
1220  mValueMask.setOn(offset);
1221  mBuffer.mData.set(offset, val);
1222 }
1223 
1224 
1225 template<Index Log2Dim>
1226 inline void
1227 LeafNode<bool, Log2Dim>::setValueOnly(const Coord& xyz, bool val)
1228 {
1229  this->setValueOnly(this->coordToOffset(xyz), val);
1230 }
1231 
1232 
1233 template<Index Log2Dim>
1234 inline void
1236 {
1237  mValueMask.set(this->coordToOffset(xyz), on);
1238 }
1239 
1240 
1241 template<Index Log2Dim>
1242 inline void
1243 LeafNode<bool, Log2Dim>::setValueOff(const Coord& xyz, bool val)
1244 {
1245  this->setValueOff(this->coordToOffset(xyz), val);
1246 }
1247 
1248 
1249 template<Index Log2Dim>
1250 inline void
1252 {
1253  assert(offset < SIZE);
1254  mValueMask.setOff(offset);
1255  mBuffer.mData.set(offset, val);
1256 }
1257 
1258 
1259 template<Index Log2Dim>
1260 template<typename ModifyOp>
1261 inline void
1262 LeafNode<bool, Log2Dim>::modifyValue(Index offset, const ModifyOp& op)
1263 {
1264  bool val = mBuffer.mData.isOn(offset);
1265  op(val);
1266  mBuffer.mData.set(offset, val);
1267  mValueMask.setOn(offset);
1268 }
1269 
1270 
1271 template<Index Log2Dim>
1272 template<typename ModifyOp>
1273 inline void
1274 LeafNode<bool, Log2Dim>::modifyValue(const Coord& xyz, const ModifyOp& op)
1275 {
1276  this->modifyValue(this->coordToOffset(xyz), op);
1277 }
1278 
1279 
1280 template<Index Log2Dim>
1281 template<typename ModifyOp>
1282 inline void
1283 LeafNode<bool, Log2Dim>::modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1284 {
1285  const Index offset = this->coordToOffset(xyz);
1286  bool val = mBuffer.mData.isOn(offset), state = mValueMask.isOn(offset);
1287  op(val, state);
1288  mBuffer.mData.set(offset, val);
1289  mValueMask.set(offset, state);
1290 }
1291 
1292 
1294 
1295 
1296 template<Index Log2Dim>
1297 inline void
1298 LeafNode<bool, Log2Dim>::resetBackground(bool oldBackground, bool newBackground)
1299 {
1300  if (newBackground != oldBackground) {
1301  // Flip mBuffer's background bits and zero its foreground bits.
1302  NodeMaskType bgMask = !(mBuffer.mData | mValueMask);
1303  // Overwrite mBuffer's background bits, leaving its foreground bits intact.
1304  mBuffer.mData = (mBuffer.mData & mValueMask) | bgMask;
1305  }
1306 }
1307 
1308 
1310 
1311 
1312 template<Index Log2Dim>
1313 template<MergePolicy Policy>
1314 inline void
1315 LeafNode<bool, Log2Dim>::merge(const LeafNode& other, bool /*bg*/, bool /*otherBG*/)
1316 {
1318  if (Policy == MERGE_NODES) return;
1319  for (typename NodeMaskType::OnIterator iter = other.valueMask().beginOn(); iter; ++iter) {
1320  const Index n = iter.pos();
1321  if (mValueMask.isOff(n)) {
1322  mBuffer.mData.set(n, other.mBuffer.mData.isOn(n));
1323  mValueMask.setOn(n);
1324  }
1325  }
1327 }
1328 
1329 template<Index Log2Dim>
1330 template<MergePolicy Policy>
1331 inline void
1332 LeafNode<bool, Log2Dim>::merge(bool tileValue, bool tileActive)
1333 {
1335  if (Policy != MERGE_ACTIVE_STATES_AND_NODES) return;
1336  if (!tileActive) return;
1337  // Replace all inactive values with the active tile value.
1338  if (tileValue) mBuffer.mData |= !mValueMask; // -0=>1, +0=>0, -1=>1, +1=>1 (-,+ = off,on)
1339  else mBuffer.mData &= mValueMask; // -0=>0, +0=>0, -1=>0, +1=>1
1340  mValueMask.setOn();
1342 }
1343 
1344 
1346 
1347 
1348 template<Index Log2Dim>
1349 template<typename OtherType>
1350 inline void
1352 {
1353  mValueMask |= other.valueMask();
1354 }
1355 
1356 
1357 template<Index Log2Dim>
1358 template<typename OtherType>
1359 inline void
1361  const bool&)
1362 {
1363  mValueMask &= other.valueMask();
1364 }
1365 
1366 
1367 template<Index Log2Dim>
1368 template<typename OtherType>
1369 inline void
1371  const bool&)
1372 {
1373  mValueMask &= !other.valueMask();
1374 }
1375 
1376 
1378 
1379 
1380 template<Index Log2Dim>
1381 inline void
1382 LeafNode<bool, Log2Dim>::clip(const CoordBBox& clipBBox, bool background)
1383 {
1384  CoordBBox nodeBBox = this->getNodeBoundingBox();
1385  if (!clipBBox.hasOverlap(nodeBBox)) {
1386  // This node lies completely outside the clipping region. Fill it with background tiles.
1387  this->fill(nodeBBox, background, /*active=*/false);
1388  } else if (clipBBox.isInside(nodeBBox)) {
1389  // This node lies completely inside the clipping region. Leave it intact.
1390  return;
1391  }
1392 
1393  // This node isn't completely contained inside the clipping region.
1394  // Set any voxels that lie outside the region to the background value.
1395 
1396  // Construct a boolean mask that is on inside the clipping region and off outside it.
1397  NodeMaskType mask;
1398  nodeBBox.intersect(clipBBox);
1399  Coord xyz;
1400  int &x = xyz.x(), &y = xyz.y(), &z = xyz.z();
1401  for (x = nodeBBox.min().x(); x <= nodeBBox.max().x(); ++x) {
1402  for (y = nodeBBox.min().y(); y <= nodeBBox.max().y(); ++y) {
1403  for (z = nodeBBox.min().z(); z <= nodeBBox.max().z(); ++z) {
1404  mask.setOn(static_cast<Index32>(this->coordToOffset(xyz)));
1405  }
1406  }
1407  }
1408 
1409  // Set voxels that lie in the inactive region of the mask (i.e., outside
1410  // the clipping region) to the background value.
1411  for (MaskOffIter maskIter = mask.beginOff(); maskIter; ++maskIter) {
1412  this->setValueOff(maskIter.pos(), background);
1413  }
1414 }
1415 
1416 
1418 
1419 
1420 template<Index Log2Dim>
1421 inline void
1422 LeafNode<bool, Log2Dim>::fill(const CoordBBox& bbox, bool value, bool active)
1423 {
1424  for (Int32 x = bbox.min().x(); x <= bbox.max().x(); ++x) {
1425  const Index offsetX = (x & (DIM-1u))<<2*Log2Dim;
1426  for (Int32 y = bbox.min().y(); y <= bbox.max().y(); ++y) {
1427  const Index offsetXY = offsetX + ((y & (DIM-1u))<< Log2Dim);
1428  for (Int32 z = bbox.min().z(); z <= bbox.max().z(); ++z) {
1429  const Index offset = offsetXY + (z & (DIM-1u));
1430  mValueMask.set(offset, active);
1431  mBuffer.mData.set(offset, value);
1432  }
1433  }
1434  }
1435 }
1436 
1437 template<Index Log2Dim>
1438 inline void
1440 {
1441  mBuffer.fill(value);
1442 }
1443 
1444 template<Index Log2Dim>
1445 inline void
1446 LeafNode<bool, Log2Dim>::fill(const bool& value, bool active)
1447 {
1448  mBuffer.fill(value);
1449  mValueMask.set(active);
1450 }
1451 
1452 
1454 
1455 
1456 template<Index Log2Dim>
1457 template<typename DenseT>
1458 inline void
1459 LeafNode<bool, Log2Dim>::copyToDense(const CoordBBox& bbox, DenseT& dense) const
1460 {
1461  typedef typename DenseT::ValueType DenseValueType;
1462 
1463  const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1464  const Coord& min = dense.bbox().min();
1465  DenseValueType* t0 = dense.data() + zStride * (bbox.min()[2] - min[2]); // target array
1466  const Int32 n0 = bbox.min()[2] & (DIM-1u);
1467  for (Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1; x < ex; ++x) {
1468  DenseValueType* t1 = t0 + xStride * (x - min[0]);
1469  const Int32 n1 = n0 + ((x & (DIM-1u)) << 2*LOG2DIM);
1470  for (Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1; y < ey; ++y) {
1471  DenseValueType* t2 = t1 + yStride * (y - min[1]);
1472  Int32 n2 = n1 + ((y & (DIM-1u)) << LOG2DIM);
1473  for (Int32 z = bbox.min()[2], ez = bbox.max()[2] + 1; z < ez; ++z, t2 += zStride) {
1474  *t2 = DenseValueType(mBuffer.mData.isOn(n2++));
1475  }
1476  }
1477  }
1478 }
1479 
1480 
1481 template<Index Log2Dim>
1482 template<typename DenseT>
1483 inline void
1484 LeafNode<bool, Log2Dim>::copyFromDense(const CoordBBox& bbox, const DenseT& dense,
1485  bool background, bool tolerance)
1486 {
1487  typedef typename DenseT::ValueType DenseValueType;
1488  struct Local {
1489  inline static bool toBool(const DenseValueType& v) { return !math::isZero(v); }
1490  };
1491 
1492  const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1493  const Coord& min = dense.bbox().min();
1494  const DenseValueType* s0 = dense.data() + zStride * (bbox.min()[2] - min[2]); // source
1495  const Int32 n0 = bbox.min()[2] & (DIM-1u);
1496  for (Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1; x < ex; ++x) {
1497  const DenseValueType* s1 = s0 + xStride * (x - min[0]);
1498  const Int32 n1 = n0 + ((x & (DIM-1u)) << 2*LOG2DIM);
1499  for (Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1; y < ey; ++y) {
1500  const DenseValueType* s2 = s1 + yStride * (y - min[1]);
1501  Int32 n2 = n1 + ((y & (DIM-1u)) << LOG2DIM);
1502  for (Int32 z = bbox.min()[2], ez = bbox.max()[2]+1; z < ez; ++z, ++n2, s2 += zStride) {
1503  // Note: if tolerance is true (i.e., 1), then all boolean values compare equal.
1504  if (tolerance || (background == Local::toBool(*s2))) {
1505  mValueMask.setOff(n2);
1506  mBuffer.mData.set(n2, background);
1507  } else {
1508  mValueMask.setOn(n2);
1509  mBuffer.mData.set(n2, Local::toBool(*s2));
1510  }
1511  }
1512  }
1513  }
1514 }
1515 
1516 
1518 
1519 
1520 template<Index Log2Dim>
1521 template<typename CombineOp>
1522 inline void
1523 LeafNode<bool, Log2Dim>::combine(const LeafNode& other, CombineOp& op)
1524 {
1525  CombineArgs<bool> args;
1526  for (Index i = 0; i < SIZE; ++i) {
1527  bool result = false, aVal = mBuffer.mData.isOn(i), bVal = other.mBuffer.mData.isOn(i);
1528  op(args.setARef(aVal)
1529  .setAIsActive(mValueMask.isOn(i))
1530  .setBRef(bVal)
1531  .setBIsActive(other.valueMask().isOn(i))
1532  .setResultRef(result));
1533  mValueMask.set(i, args.resultIsActive());
1534  mBuffer.mData.set(i, result);
1535  }
1536 }
1537 
1538 
1539 template<Index Log2Dim>
1540 template<typename CombineOp>
1541 inline void
1542 LeafNode<bool, Log2Dim>::combine(bool value, bool valueIsActive, CombineOp& op)
1543 {
1544  CombineArgs<bool> args;
1545  args.setBRef(value).setBIsActive(valueIsActive);
1546  for (Index i = 0; i < SIZE; ++i) {
1547  bool result = false, aVal = mBuffer.mData.isOn(i);
1548  op(args.setARef(aVal)
1549  .setAIsActive(mValueMask.isOn(i))
1550  .setResultRef(result));
1551  mValueMask.set(i, args.resultIsActive());
1552  mBuffer.mData.set(i, result);
1553  }
1554 }
1555 
1556 
1558 
1559 
1560 template<Index Log2Dim>
1561 template<typename CombineOp, typename OtherType>
1562 inline void
1563 LeafNode<bool, Log2Dim>::combine2(const LeafNode& other, const OtherType& value,
1564  bool valueIsActive, CombineOp& op)
1565 {
1567  args.setBRef(value).setBIsActive(valueIsActive);
1568  for (Index i = 0; i < SIZE; ++i) {
1569  bool result = false, aVal = other.mBuffer.mData.isOn(i);
1570  op(args.setARef(aVal)
1571  .setAIsActive(other.valueMask().isOn(i))
1572  .setResultRef(result));
1573  mValueMask.set(i, args.resultIsActive());
1574  mBuffer.mData.set(i, result);
1575  }
1576 }
1577 
1578 
1579 template<Index Log2Dim>
1580 template<typename CombineOp, typename OtherNodeT>
1581 inline void
1582 LeafNode<bool, Log2Dim>::combine2(bool value, const OtherNodeT& other,
1583  bool valueIsActive, CombineOp& op)
1584 {
1586  args.setARef(value).setAIsActive(valueIsActive);
1587  for (Index i = 0; i < SIZE; ++i) {
1588  bool result = false, bVal = other.mBuffer.mData.isOn(i);
1589  op(args.setBRef(bVal)
1590  .setBIsActive(other.valueMask().isOn(i))
1591  .setResultRef(result));
1592  mValueMask.set(i, args.resultIsActive());
1593  mBuffer.mData.set(i, result);
1594  }
1595 }
1596 
1597 
1598 template<Index Log2Dim>
1599 template<typename CombineOp, typename OtherNodeT>
1600 inline void
1601 LeafNode<bool, Log2Dim>::combine2(const LeafNode& b0, const OtherNodeT& b1, CombineOp& op)
1602 {
1604  for (Index i = 0; i < SIZE; ++i) {
1605  // Default behavior: output voxel is active if either input voxel is active.
1606  mValueMask.set(i, b0.valueMask().isOn(i) || b1.valueMask().isOn(i));
1607 
1608  bool result = false, b0Val = b0.mBuffer.mData.isOn(i), b1Val = b1.mBuffer.mData.isOn(i);
1609  op(args.setARef(b0Val)
1610  .setAIsActive(b0.valueMask().isOn(i))
1611  .setBRef(b1Val)
1612  .setBIsActive(b1.valueMask().isOn(i))
1613  .setResultRef(result));
1614  mValueMask.set(i, args.resultIsActive());
1615  mBuffer.mData.set(i, result);
1616  }
1617 }
1618 
1619 
1621 
1622 template<Index Log2Dim>
1623 template<typename BBoxOp>
1624 inline void
1626 {
1627  if (op.template descent<LEVEL>()) {
1628  for (ValueOnCIter i=this->cbeginValueOn(); i; ++i) {
1629 #ifdef _MSC_VER
1630  op.operator()<LEVEL>(CoordBBox::createCube(i.getCoord(), 1));
1631 #else
1632  op.template operator()<LEVEL>(CoordBBox::createCube(i.getCoord(), 1));
1633 #endif
1634  }
1635  } else {
1636 #ifdef _MSC_VER
1637  op.operator()<LEVEL>(this->getNodeBoundingBox());
1638 #else
1639  op.template operator()<LEVEL>(this->getNodeBoundingBox());
1640 #endif
1641  }
1642 }
1643 
1644 
1645 template<Index Log2Dim>
1646 template<typename VisitorOp>
1647 inline void
1649 {
1650  doVisit<LeafNode, VisitorOp, ChildAllIter>(*this, op);
1651 }
1652 
1653 
1654 template<Index Log2Dim>
1655 template<typename VisitorOp>
1656 inline void
1658 {
1659  doVisit<const LeafNode, VisitorOp, ChildAllCIter>(*this, op);
1660 }
1661 
1662 
1663 template<Index Log2Dim>
1664 template<typename NodeT, typename VisitorOp, typename ChildAllIterT>
1665 inline void
1666 LeafNode<bool, Log2Dim>::doVisit(NodeT& self, VisitorOp& op)
1667 {
1668  for (ChildAllIterT iter = self.beginChildAll(); iter; ++iter) {
1669  op(iter);
1670  }
1671 }
1672 
1673 
1675 
1676 
1677 template<Index Log2Dim>
1678 template<typename OtherLeafNodeType, typename VisitorOp>
1679 inline void
1680 LeafNode<bool, Log2Dim>::visit2Node(OtherLeafNodeType& other, VisitorOp& op)
1681 {
1682  doVisit2Node<LeafNode, OtherLeafNodeType, VisitorOp, ChildAllIter,
1683  typename OtherLeafNodeType::ChildAllIter>(*this, other, op);
1684 }
1685 
1686 
1687 template<Index Log2Dim>
1688 template<typename OtherLeafNodeType, typename VisitorOp>
1689 inline void
1690 LeafNode<bool, Log2Dim>::visit2Node(OtherLeafNodeType& other, VisitorOp& op) const
1691 {
1692  doVisit2Node<const LeafNode, OtherLeafNodeType, VisitorOp, ChildAllCIter,
1693  typename OtherLeafNodeType::ChildAllCIter>(*this, other, op);
1694 }
1695 
1696 
1697 template<Index Log2Dim>
1698 template<
1699  typename NodeT,
1700  typename OtherNodeT,
1701  typename VisitorOp,
1702  typename ChildAllIterT,
1703  typename OtherChildAllIterT>
1704 inline void
1705 LeafNode<bool, Log2Dim>::doVisit2Node(NodeT& self, OtherNodeT& other, VisitorOp& op)
1706 {
1707  // Allow the two nodes to have different ValueTypes, but not different dimensions.
1708  BOOST_STATIC_ASSERT(OtherNodeT::SIZE == NodeT::SIZE);
1709  BOOST_STATIC_ASSERT(OtherNodeT::LEVEL == NodeT::LEVEL);
1710 
1711  ChildAllIterT iter = self.beginChildAll();
1712  OtherChildAllIterT otherIter = other.beginChildAll();
1713 
1714  for ( ; iter && otherIter; ++iter, ++otherIter) {
1715  op(iter, otherIter);
1716  }
1717 }
1718 
1719 
1721 
1722 
1723 template<Index Log2Dim>
1724 template<typename IterT, typename VisitorOp>
1725 inline void
1726 LeafNode<bool, Log2Dim>::visit2(IterT& otherIter, VisitorOp& op, bool otherIsLHS)
1727 {
1728  doVisit2<LeafNode, VisitorOp, ChildAllIter, IterT>(*this, otherIter, op, otherIsLHS);
1729 }
1730 
1731 
1732 template<Index Log2Dim>
1733 template<typename IterT, typename VisitorOp>
1734 inline void
1735 LeafNode<bool, Log2Dim>::visit2(IterT& otherIter, VisitorOp& op, bool otherIsLHS) const
1736 {
1737  doVisit2<const LeafNode, VisitorOp, ChildAllCIter, IterT>(*this, otherIter, op, otherIsLHS);
1738 }
1739 
1740 
1741 template<Index Log2Dim>
1742 template<
1743  typename NodeT,
1744  typename VisitorOp,
1745  typename ChildAllIterT,
1746  typename OtherChildAllIterT>
1747 inline void
1748 LeafNode<bool, Log2Dim>::doVisit2(NodeT& self, OtherChildAllIterT& otherIter,
1749  VisitorOp& op, bool otherIsLHS)
1750 {
1751  if (!otherIter) return;
1752 
1753  if (otherIsLHS) {
1754  for (ChildAllIterT iter = self.beginChildAll(); iter; ++iter) {
1755  op(otherIter, iter);
1756  }
1757  } else {
1758  for (ChildAllIterT iter = self.beginChildAll(); iter; ++iter) {
1759  op(iter, otherIter);
1760  }
1761  }
1762 }
1763 
1764 } // namespace tree
1765 } // namespace OPENVDB_VERSION_NAME
1766 } // namespace openvdb
1767 
1768 #endif // OPENVDB_TREE_LEAF_NODE_BOOL_HAS_BEEN_INCLUDED
1769 
1770 // Copyright (c) 2012-2016 DreamWorks Animation LLC
1771 // All rights reserved. This software is distributed under the
1772 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
NodeMaskType & getValueMask()
Definition: LeafNodeBool.h:756
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:523
bool isChildMaskOff(Index) const
Definition: LeafNodeBool.h:759
bool probeValueAndCache(const Coord &xyz, bool &val, AccessorT &) const
Return true if the voxel at the given coordinates is active and return the voxel value in val...
Definition: LeafNodeBool.h:461
Index64 onLeafVoxelCount() const
Definition: LeafNodeBool.h:199
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: LeafNodeBool.h:351
static bool hasActiveTiles()
Return false since leaf nodes never contain tiles.
Definition: LeafNodeBool.h:356
Index64 offVoxelCount() const
Return the number of inactive voxels.
Definition: LeafNodeBool.h:198
static const Index LEVEL
Definition: LeafNode.h:81
static Index32 nonLeafCount()
Definition: LeafNodeBool.h:193
ValueOnIter endValueOn()
Definition: LeafNodeBool.h:717
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: LeafNode.h:1276
void setValueOffAndCache(const Coord &xyz, bool value, AccessorT &)
Change the value of the voxel at the given coordinates and mark it as inactive.
Definition: LeafNodeBool.h:426
void stealNodes(ArrayT &, const ValueType &, bool)
This function exists only to enable template instantiation.
Definition: LeafNodeBool.h:579
const Coord & origin() const
Return the grid index coordinates of this node&#39;s local origin.
Definition: LeafNode.h:475
DenseIter< LeafNode, bool > ChildAllIter
Definition: LeafNodeBool.h:702
ValueOffCIter cendValueOff() const
Definition: LeafNodeBool.h:718
static Index32 leafCount()
Definition: LeafNodeBool.h:192
void modifyItem(Index n, const ModifyOp &op) const
Definition: LeafNodeBool.h:651
bool allocate()
Allocate memory for this node&#39;s buffer if it has not already been allocated.
Definition: LeafNodeBool.h:217
ChildOnCIter beginChildOn() const
Definition: LeafNodeBool.h:728
const NodeT * probeConstNodeAndCache(const Coord &, AccessorT &) const
Return a const pointer to this node.
Definition: LeafNodeBool.h:613
CoordBBox getNodeBoundingBox() const
Return the bounding box of this node, i.e., the full index space spanned by this leaf node...
Definition: LeafNode.h:469
static const bool sOn
Definition: LeafNodeBool.h:789
void addTile(Index level, const Coord &, const ValueType &, bool)
Definition: LeafNode.h:1792
bool operator!=(const Buffer &other) const
Definition: LeafNodeBool.h:108
NodeT * stealNode(const Coord &, const ValueType &, bool)
This function exists only to enable template instantiation.
Definition: LeafNodeBool.h:573
void copyToDense(const GridOrTreeT &sparse, DenseT &dense, bool serial=false)
Populate a dense grid with the values of voxels from a sparse grid, where the sparse grid intersects ...
Definition: Dense.h:443
bool BuildType
Definition: LeafNodeBool.h:59
const NodeMaskType & valueMask() const
Definition: LeafNodeBool.h:755
void unsetItem(Index pos, const ValueT &val) const
Definition: LeafNodeBool.h:688
Definition: Types.h:442
const NodeMaskType & getValueMask() const
Definition: LeafNode.h:1109
DenseIteratorBase< MaskDenseIter, DenseIter, NodeT, void, ValueT > BaseT
Definition: LeafNodeBool.h:671
bool operator==(const LeafNode &other) const
Check for buffer, state and origin equivalence.
Definition: LeafNode.h:1707
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: LeafNode.h:1300
void getOrigin(Coord &origin) const
Return the grid index coordinates of this node&#39;s local origin.
Definition: LeafNodeBool.h:237
static Index size()
Definition: LeafNodeBool.h:186
void load(std::istream &is)
Definition: NodeMasks.h:566
void setValueMaskOff(Index n)
Definition: LeafNodeBool.h:764
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: LeafNode.h:714
void visit(VisitorOp &)
Definition: LeafNode.h:2068
static Coord offsetToLocalCoord(Index n)
Return the local coordinates for a linear table offset, where offset 0 has coordinates (0...
Definition: LeafNode.h:1286
bool isValueMaskOn(Index n) const
Definition: LeafNodeBool.h:750
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: LeafNodeBool.h:663
ChildOnCIter endChildOn() const
Definition: LeafNodeBool.h:738
void setValueMaskOn(Index n)
Definition: LeafNodeBool.h:763
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:365
void setValueOnly(Index offset, bool val)
Set the value of the voxel at the given offset but don&#39;t change its active state. ...
Definition: LeafNodeBool.h:308
void topologyDifference(const LeafNode< OtherType, Log2Dim > &other, const ValueType &)
Difference this node&#39;s set of active values with the active values of the other node, whose ValueType may be different. So a resulting voxel will be active only if the original voxel is active in this LeafNode and inactive in the other LeafNode.
Definition: LeafNode.h:1914
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: LeafNodeBool.h:189
const bool & getFirstValue() const
Return a const reference to the first entry in the buffer.
Definition: LeafNodeBool.h:474
static const bool sOff
Definition: LeafNodeBool.h:790
ChildOnCIter cendChildOn() const
Definition: LeafNodeBool.h:737
void setItem(Index pos, bool value) const
Definition: LeafNodeBool.h:645
void setValueOnlyAndCache(const Coord &xyz, bool val, AccessorT &)
Change the value of the voxel at the given coordinates but preserve its state.
Definition: LeafNodeBool.h:421
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:324
ValueOnCIter endValueOn() const
Definition: LeafNodeBool.h:716
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: LeafNode.h:1753
bool isValueMaskOff() const
Definition: LeafNodeBool.h:753
void modifyValue(Index offset, const ModifyOp &op)
Apply a functor to the value of the voxel at the given offset and mark the voxel as active...
Definition: LeafNode.h:732
void readBuffers(std::istream &is, bool fromHalf=false)
Read buffers from a stream.
Definition: LeafNode.h:1598
Definition: PointIndexGrid.h:69
DenseIter< const LeafNode, const ValueType, ChildAll > ChildAllCIter
Definition: LeafNode.h:592
static Index dim()
Return the number of voxels in each dimension.
Definition: LeafNodeBool.h:185
const NodeMaskType & getValueMask() const
Definition: LeafNodeBool.h:754
bool operator!=(const LeafNode &other) const
Definition: LeafNode.h:498
ChildAllCIter endChildAll() const
Definition: LeafNodeBool.h:744
static Index64 onTileCount()
Definition: LeafNodeBool.h:201
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information. An additional level argument is pro...
Definition: LeafNode.h:2045
ValueIter< MaskOnIter, LeafNode, const bool > ValueOnIter
Definition: LeafNodeBool.h:692
util::NodeMask< Log2Dim > NodeMaskType
Definition: LeafNodeBool.h:61
void setValueAndCache(const Coord &xyz, bool val, AccessorT &)
Change the value of the voxel at the given coordinates and mark it as active.
Definition: LeafNodeBool.h:415
ChildOnCIter cbeginChildOn() const
Definition: LeafNodeBool.h:727
OPENVDB_API const void * getGridBackgroundValuePtr(std::ios_base &)
Return a pointer to the background value of the grid currently being read from or written to the give...
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Set the active state of the voxel at the given coordinates without changing its value.
Definition: LeafNodeBool.h:452
NodeMaskType::DenseIterator MaskDenseIter
Definition: LeafNodeBool.h:628
static Index getChildDim()
Definition: LeafNodeBool.h:190
const bool & getValue(Index i) const
Definition: LeafNodeBool.h:98
NodeT * probeNode(const Coord &)
This function exists only to enable template instantiation.
Definition: LeafNodeBool.h:575
ValueAllIter endValueAll()
Definition: LeafNodeBool.h:723
ValueAllCIter cbeginValueAll() const
Definition: LeafNodeBool.h:711
const WordType * data() const
Definition: LeafNodeBool.h:128
void copyFromDense(const DenseT &dense, GridOrTreeT &sparse, const typename GridOrTreeT::ValueType &tolerance, bool serial=false)
Populate a sparse grid with the values of all of the voxels of a dense grid.
Definition: Dense.h:590
boost::shared_ptr< LeafNodeType > Ptr
Definition: LeafNodeBool.h:58
ValueType * mData
Definition: LeafNode.h:361
DenseIter< const LeafNode, const bool > ChildAllCIter
Definition: LeafNodeBool.h:703
static Index numValues()
Definition: LeafNodeBool.h:187
OffIterator beginOff() const
Definition: NodeMasks.h:351
LeafNode< bool, Log2Dim > LeafNodeType
Definition: LeafNodeBool.h:57
void resetBackground(const ValueType &oldBackground, const ValueType &newBackground)
Replace inactive occurrences of oldBackground with newBackground, and inactive occurrences of -oldBac...
Definition: LeafNode.h:1821
Index32 Index
Definition: Types.h:58
ValueIter< MaskDenseIter, LeafNode, const bool > ValueAllIter
Definition: LeafNodeBool.h:696
ChildOffCIter beginChildOff() const
Definition: LeafNodeBool.h:731
NodeT * probeNodeAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
Definition: LeafNodeBool.h:596
ChildAllCIter beginChildAll() const
Definition: LeafNode.h:623
ChildIter< MaskOnIter, const LeafNode > ChildOnCIter
Definition: LeafNodeBool.h:699
ValueAllCIter endValueAll() const
Definition: LeafNodeBool.h:722
bool hasSameTopology(const LeafNode< OtherType, OtherLog2Dim > *other) const
Return true if the given node (which may have a different ValueType than this node) has the same acti...
Definition: LeafNode.h:1745
int32_t Int32
Definition: Types.h:60
ChildAllIter beginChildAll()
Definition: LeafNodeBool.h:735
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: LeafNodeBool.h:353
void combine2(const LeafNode &other, const OtherType &, bool valueIsActive, CombineOp &)
Definition: LeafNode.h:1981
uint64_t Index64
Definition: Types.h:57
void fill(const ValueType &val)
Populate this buffer with a constant value.
Definition: LeafNode.h:171
ChildOffCIter cendChildOff() const
Definition: LeafNodeBool.h:740
#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
ValueOnCIter cendValueOn() const
Definition: LeafNodeBool.h:715
bool getItem(Index pos, void *&child, NonConstValueT &value) const
Definition: LeafNodeBool.h:677
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:499
WordType * data()
Definition: LeafNodeBool.h:120
NodeMaskType::Word WordType
Definition: LeafNodeBool.h:88
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: LeafNode.h:1387
const bool & getValue() const
Definition: LeafNodeBool.h:642
Buffer mBuffer
Bitmask representing the values of voxels.
Definition: LeafNodeBool.h:784
void fill(bool val)
Definition: LeafNodeBool.h:95
LeafNode * touchLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
Definition: LeafNodeBool.h:591
void swap(Buffer &other)
Definition: LeafNodeBool.h:112
void setValuesOff()
Mark all voxels as inactive but don&#39;t change their values.
Definition: LeafNodeBool.h:348
Index64 onVoxelCount() const
Return the number of active voxels.
Definition: LeafNodeBool.h:196
bool isValueMaskOff(Index n) const
Definition: LeafNodeBool.h:752
Templated block class to hold specific data types and a fixed number of values determined by Log2Dim...
Definition: LeafNode.h:65
void visit2Node(OtherLeafNodeType &other, VisitorOp &)
Definition: LeafNode.h:2100
ValueOffIter endValueOff()
Definition: LeafNodeBool.h:720
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: LeafNode.h:1361
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
CoordBBox getNodeBoundingBox() const
Return the bounding box of this node, i.e., the full index space spanned by this leaf node...
Definition: LeafNodeBool.h:230
ValueAllCIter beginValueAll() const
Definition: LeafNodeBool.h:712
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:304
void addTileAndCache(Index, const Coord &, const ValueType &, bool, AccessorT &)
Definition: LeafNode.h:1809
~LeafNode()
Destructor.
Definition: LeafNode.h:1256
const bool & getLastValue() const
Return a const reference to the last entry in the buffer.
Definition: LeafNodeBool.h:478
bool isInactive() const
Return true if all of this node&#39;s values are inactive.
Definition: LeafNodeBool.h:485
void setValue(bool value) const
Definition: LeafNodeBool.h:647
NodeMaskType::OnIterator MaskOnIter
Definition: LeafNodeBool.h:626
void readTopology(std::istream &is, bool fromHalf=false)
Read in just the topology.
Definition: LeafNode.h:1536
Definition: Exceptions.h:39
void topologyUnion(const LeafNode< OtherType, Log2Dim > &other)
Union this node&#39;s set of active values with the active values of the other node, whose ValueType may ...
Definition: LeafNode.h:1897
uint32_t Index32
Definition: Types.h:56
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:129
std::string str() const
Return a string representation of this node.
Definition: LeafNode.h:1263
ChildIter< MaskOnIter, LeafNode > ChildOnIter
Definition: LeafNodeBool.h:698
ValueIter< MaskOnIter, const LeafNode, const bool > ValueOnCIter
Definition: LeafNodeBool.h:693
const NodeT * probeConstNode(const Coord &) const
This function exists only to enable template instantiation.
Definition: LeafNodeBool.h:577
bool ValueType
Definition: LeafNodeBool.h:60
Index memUsage() const
Definition: LeafNodeBool.h:114
void getOrigin(Int32 &x, Int32 &y, Int32 &z) const
Return the grid index coordinates of this node&#39;s local origin.
Definition: LeafNodeBool.h:238
Index64 Word
Definition: NodeMasks.h:313
static Index64 offTileCount()
Definition: LeafNodeBool.h:202
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:211
static Index size()
Definition: LeafNodeBool.h:115
bool isDense() const
Return true if this node only contains active voxels.
Definition: LeafNodeBool.h:207
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:148
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: LeafNode.h:1311
boost::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:217
static Index getLevel()
Definition: LeafNodeBool.h:188
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition: NodeMasks.h:459
ValueIter< MaskOffIter, LeafNode, const bool > ValueOffIter
Definition: LeafNodeBool.h:694
static void doVisit2(NodeT &self, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: LeafNode.h:2170
ValueAllCIter cendValueAll() const
Definition: LeafNodeBool.h:721
void addLeaf(LeafNode *)
This function exists only to enable template instantiation.
Definition: LeafNodeBool.h:569
ChildAllCIter cendChildAll() const
Definition: LeafNodeBool.h:743
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:505
ValueOnCIter cbeginValueOn() const
Definition: LeafNode.h:594
void setValuesOn()
Mark all voxels as active but don&#39;t change their values.
Definition: LeafNodeBool.h:346
LeafNode * probeLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
Definition: LeafNodeBool.h:594
void negate()
Definition: LeafNodeBool.h:489
Buffer & operator=(const Buffer &b)
Definition: LeafNodeBool.h:96
Definition: NodeMasks.h:267
bool probeValue(const Coord &xyz, ValueType &val) const
Return true if the voxel at the given coordinates is active.
Definition: LeafNode.h:1327
static const Index SIZE
Definition: LeafNode.h:80
ChildOffCIter cbeginChildOff() const
Definition: LeafNodeBool.h:730
void setValueMask(const NodeMaskType &mask)
Definition: LeafNodeBool.h:757
ChildAllIter endChildAll()
Definition: LeafNodeBool.h:745
const bool & operator[](Index i) const
Definition: LeafNodeBool.h:105
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:449
ValueOffCIter cbeginValueOff() const
Definition: LeafNodeBool.h:708
void combine(const LeafNode &other, CombineOp &op)
Definition: LeafNode.h:1939
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node&#39;s local origin.
Definition: LeafNodeBool.h:233
bool isEmpty() const
Return true if this node has no active voxels.
Definition: LeafNodeBool.h:205
ChildAllCIter cbeginChildAll() const
Definition: LeafNodeBool.h:733
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: LeafNodeBool.h:311
Index64 memUsage() const
Return the memory in bytes occupied by this node.
Definition: LeafNode.h:1717
ChildIter< MaskOffIter, const LeafNode > ChildOffCIter
Definition: LeafNodeBool.h:701
ChildOffIter endChildOff()
Definition: LeafNodeBool.h:742
void copyToDense(const CoordBBox &bbox, DenseT &dense) const
Copy into a dense grid the values of the voxels that lie within a given bounding box.
Definition: LeafNode.h:1468
Buffer(const NodeMaskType &other)
Definition: LeafNodeBool.h:92
void modifyValue(const ModifyOp &op) const
Definition: LeafNodeBool.h:654
static void doVisit2Node(NodeT &self, OtherNodeT &other, VisitorOp &)
Definition: LeafNode.h:2125
ValueOnCIter cbeginValueOn() const
Definition: LeafNodeBool.h:705
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:450
LeafNode()
Default constructor.
Definition: LeafNode.h:1170
ValueOffIter beginValueOff()
Definition: LeafNodeBool.h:710
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: LeafNodeBool.h:639
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: LeafNodeBool.h:435
Buffer(bool on)
Definition: LeafNodeBool.h:91
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:130
ValueOffCIter endValueOff() const
Definition: LeafNodeBool.h:719
ChildAllCIter beginChildAll() const
Definition: LeafNodeBool.h:734
OnIterator beginOn() const
Definition: NodeMasks.h:349
BaseT::NonConstValueType NonConstValueT
Definition: LeafNodeBool.h:672
CombineArgs & setBRef(const BValueType &b)
Redirect the B value to a new external source.
Definition: Types.h:367
void setValueOnly(const Coord &xyz, const ValueType &val)
Set the value of the voxel at the given coordinates but don&#39;t change its active state.
Definition: LeafNode.h:1369
ChildOnIter endChildOn()
Definition: LeafNodeBool.h:739
static const Index LOG2DIM
Definition: LeafNode.h:75
void voxelizeActiveTiles(bool=true)
No-op.
Definition: LeafNodeBool.h:497
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:454
LeafNode specialization for values of type bool that stores both the active states and the values of ...
Definition: LeafNodeBool.h:54
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Return true if the voxel at the given coordinates is active.
Definition: LeafNodeBool.h:410
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
Definition: LeafNode.h:1727
Index64 offLeafVoxelCount() const
Definition: LeafNodeBool.h:200
ChildOnIter beginChildOn()
Definition: LeafNodeBool.h:729
bool isChildMaskOff() const
Definition: LeafNodeBool.h:760
const NodeMaskType & valueMask() const
Definition: LeafNode.h:1111
DenseIter(const MaskDenseIter &iter, NodeT *parent)
Definition: LeafNodeBool.h:675
DenseIter< LeafNode, ValueType, ChildAll > ChildAllIter
Definition: LeafNode.h:591
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: LeafNodeBool.h:443
NodeMaskType::OffIterator MaskOffIter
Definition: LeafNodeBool.h:627
Buffer(const Buffer &other)
Definition: LeafNodeBool.h:93
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:458
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
void addLeafAndCache(LeafNode *, AccessorT &)
This function exists only to enable template instantiation.
Definition: LeafNodeBool.h:571
void copyFromDense(const CoordBBox &bbox, const DenseT &dense, const ValueType &background, const ValueType &tolerance)
Copy from a dense grid into this node the values of the voxels that lie within a given bounding box...
Definition: LeafNode.h:1497
const bool & getValueAndCache(const Coord &xyz, AccessorT &) const
Return the value of the voxel at the given coordinates.
Definition: LeafNodeBool.h:405
void setActiveState(Index offset, bool on)
Set the active state of the voxel at the given offset but don&#39;t change its value. ...
Definition: LeafNodeBool.h:303
void setValueOn(Index offset)
Mark the voxel at the given offset as active but don&#39;t change its value.
Definition: LeafNodeBool.h:323
bool isChildMaskOn(Index) const
Definition: LeafNodeBool.h:758
ValueOnIter beginValueOn()
Definition: LeafNodeBool.h:707
SparseIteratorBase< MaskIterT, ValueIter, NodeT, ValueT > BaseT
Definition: LeafNodeBool.h:636
Definition: NodeMasks.h:205
ValueOnCIter beginValueOn() const
Definition: LeafNodeBool.h:706
Definition: NodeMasks.h:236
bool operator==(const Buffer &other) const
Definition: LeafNodeBool.h:107
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: LeafNodeBool.h:321
ChildIter< MaskOffIter, LeafNode > ChildOffIter
Definition: LeafNodeBool.h:700
LeafNode * probeLeaf(const Coord &)
Return a pointer to this node.
Definition: LeafNodeBool.h:592
Definition: Types.h:444
static void doVisit(NodeT &, VisitorOp &)
Definition: LeafNode.h:2086
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
void setValueOff(Index offset)
Mark the voxel at the given offset as inactive but don&#39;t change its value.
Definition: LeafNodeBool.h:313
Buffer & buffer()
Definition: LeafNodeBool.h:268
void topologyIntersection(const LeafNode< OtherType, Log2Dim > &other, const ValueType &)
Intersect this node&#39;s set of active values with the active values of the other node, whose ValueType may be different. So a resulting voxel will be active only if both of the original voxels were active.
Definition: LeafNode.h:1905
void save(std::ostream &os) const
Definition: NodeMasks.h:562
void setValue(const Coord &xyz, bool val)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: LeafNodeBool.h:328
static void evalNodeOrigin(Coord &xyz)
Compute the origin of the leaf node that contains the voxel with the given coordinates.
Definition: LeafNodeBool.h:767
void merge(const LeafNode &)
Definition: LeafNode.h:1844
void setValue(Index i, bool val)
Definition: LeafNodeBool.h:110
ValueIter< MaskOffIter, const LeafNode, const bool > ValueOffCIter
Definition: LeafNodeBool.h:695
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: LeafNode.h:749
LeafNode< ValueType, Log2Dim > Type
Definition: LeafNodeBool.h:75
ValueIter< MaskDenseIter, const LeafNode, const bool > ValueAllCIter
Definition: LeafNodeBool.h:697
Definition: Types.h:266
bool isValueMaskOn() const
Definition: LeafNodeBool.h:751
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: LeafNodeBool.h:786
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
Definition: LeafNode.h:2146
void fill(const CoordBBox &bbox, const ValueType &, bool active=true)
Set all voxels within an axis-aligned box to the specified value and active state.
Definition: LeafNode.h:1427
const Buffer & buffer() const
Definition: LeafNodeBool.h:267
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: LeafNode.h:704
ValueOffCIter beginValueOff() const
Definition: LeafNodeBool.h:709
static Index log2dim()
Return log2 of the size of the buffer storage.
Definition: LeafNodeBool.h:183
ChildOffIter beginChildOff()
Definition: LeafNodeBool.h:732
void swap(Buffer &other)
Exchange this node&#39;s data buffer with the given data buffer without changing the active states of the...
Definition: LeafNodeBool.h:266
NodeMaskType mValueMask
Bitmask that determines which voxels are active.
Definition: LeafNodeBool.h:782
void writeTopology(std::ostream &os, bool toHalf=false) const
Write out just the topology.
Definition: LeafNode.h:1544
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:312
bool resultIsActive() const
Definition: Types.h:376
void writeBuffers(std::ostream &os, bool toHalf=false) const
Write buffers to a stream.
Definition: LeafNode.h:1690
const LeafNode * probeLeafAndCache(const Coord &, AccessorT &) const
Return a const pointer to this node.
Definition: LeafNodeBool.h:608
ChildOffCIter endChildOff() const
Definition: LeafNodeBool.h:741
ValueAllIter beginValueAll()
Definition: LeafNodeBool.h:713
void setValueMask(Index n, bool on)
Definition: LeafNodeBool.h:762
const LeafNode * probeConstLeaf(const Coord &) const
Return a const pointer to this node.
Definition: LeafNodeBool.h:609
static const Index DIM
Definition: LeafNode.h:77
const bool & getItem(Index pos) const
Definition: LeafNodeBool.h:641
const LeafNode * probeConstLeafAndCache(const Coord &, AccessorT &) const
Return a const pointer to this node.
Definition: LeafNodeBool.h:611
void getNodes(ArrayT &) const
This function exists only to enable template instantiation.
Definition: LeafNodeBool.h:578
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:58
static Index getValueLevelAndCache(const Coord &, AccessorT &)
Return the LEVEL (=0) at which leaf node values reside.
Definition: LeafNodeBool.h:469
static Index getValueLevel(const Coord &)
Return the level (0) at which leaf node values reside.
Definition: LeafNodeBool.h:298
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:128