OpenVDB  0.104.0
Iterator.h
Go to the documentation of this file.
1 
2 //
3 // Copyright (c) 2012 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_ITERATOR_HAS_BEEN_INCLUDED
36 #define OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
37 
38 #include <sstream>
39 #include <boost/type_traits/remove_const.hpp>
40 #include <openvdb/util/NodeMasks.h>
41 #include <openvdb/Exceptions.h>
42 
43 namespace openvdb {
45 namespace OPENVDB_VERSION_NAME {
46 namespace tree {
47 
55 template<typename MaskIterT, typename NodeT>
57 {
58 public:
59  IteratorBase(): mParentNode(NULL) {}
60  IteratorBase(const MaskIterT& iter, NodeT* parent):
61  mParentNode(parent), mMaskIter(iter) {}
62 
63  void operator=(const IteratorBase& other)
64  {
65  mParentNode = other.mParentNode;
66  mMaskIter = other.mMaskIter;
67  }
68 
69  bool operator==(const IteratorBase& other) const
70  {
71  return (mParentNode == other.mParentNode) && (mMaskIter == other.mMaskIter);
72  }
73  bool operator!=(const IteratorBase& other) const
74  {
75  return !(*this == other);
76  }
77 
79  NodeT* getParentNode() const { return mParentNode; }
82  NodeT& parent() const
83  {
84  if (!mParentNode) OPENVDB_THROW(ValueError, "iterator references a null node");
85  return *mParentNode;
86  }
87 
89  OPENVDB_DEPRECATED Index getOffset() const { return mMaskIter.offset(); }
90 
92  Index offset() const { return mMaskIter.offset(); }
93 
95  Index pos() const { return mMaskIter.offset(); }
96 
98  bool test() const { return mMaskIter.test(); }
100  operator bool() const { return this->test(); }
101 
103  bool next() { return mMaskIter.next(); }
105  void increment() { mMaskIter.increment(); }
107  IteratorBase& operator++() { this->increment(); return *this; }
109  void increment(Index n) { mMaskIter.increment(n); }
110 
113  bool isValueOn() const { return parent().isValueMaskOn(this->pos()); }
116  void setValueOn(bool on = true) const { parent().setValueMask(this->pos(), on); }
121  void setValueOff() const { parent().mValueMask.setOff(this->pos()); }
122 
124  Coord getCoord() const { return parent().offset2globalCoord(this->pos()); }
126  void getCoord(Coord& xyz) const { xyz = this->getCoord(); }
127 
128 private:
135  mutable NodeT* mParentNode;
136  MaskIterT mMaskIter;
137 }; // class IteratorBase
138 
139 
141 
142 
144 template<
145  typename MaskIterT, // mask iterator type (OnIterator, OffIterator, etc.)
146  typename IterT, // SparseIteratorBase subclass (the "Curiously Recurring Template Pattern")
147  typename NodeT, // type of node over which to iterate
148  typename ItemT> // type of value to which this iterator points
149 struct SparseIteratorBase: public IteratorBase<MaskIterT, NodeT>
150 {
151  typedef NodeT NodeType;
152  typedef ItemT ValueType;
153  typedef typename boost::remove_const<NodeT>::type NonConstNodeType;
154  typedef typename boost::remove_const<ItemT>::type NonConstValueType;
155  static const bool IsSparseIterator = true, IsDenseIterator = false;
156 
158  SparseIteratorBase(const MaskIterT& iter, NodeT* parent):
159  IteratorBase<MaskIterT, NodeT>(iter, parent) {}
160 
163  ItemT& getItem(Index) const;
166  void setItem(Index, const ItemT&) const;
167 
169  ItemT& operator*() const { return this->getValue(); }
171  ItemT* operator->() const { return &(this->operator*()); }
172 
174  ItemT& getValue() const
175  {
176  return static_cast<const IterT*>(this)->getItem(this->pos()); // static polymorphism
177  }
180  void setValue(const ItemT& value) const
181  {
182  static_cast<const IterT*>(this)->setItem(this->pos(), value); // static polymorphism
183  }
184 }; // class SparseIteratorBase
185 
186 
188 
189 
194 template<
195  typename MaskIterT, // mask iterator type (typically a DenseIterator)
196  typename IterT, // DenseIteratorBase subclass (the "Curiously Recurring Template Pattern")
197  typename NodeT, // type of node over which to iterate
198  typename SetItemT, // type of set value (ChildNodeType, for non-leaf nodes)
199  typename UnsetItemT> // type of unset value (ValueType, usually)
200 struct DenseIteratorBase: public IteratorBase<MaskIterT, NodeT>
201 {
202  typedef NodeT NodeType;
203  typedef UnsetItemT ValueType;
204  typedef SetItemT ChildNodeType;
205  typedef typename boost::remove_const<NodeT>::type NonConstNodeType;
206  typedef typename boost::remove_const<UnsetItemT>::type NonConstValueType;
207  typedef typename boost::remove_const<SetItemT>::type NonConstChildNodeType;
208  static const bool IsSparseIterator = false, IsDenseIterator = true;
209 
211  DenseIteratorBase(const MaskIterT& iter, NodeT* parent):
212  IteratorBase<MaskIterT, NodeT>(iter, parent) {}
213 
218  bool getItem(Index, SetItemT*& child, NonConstValueType& value) const;
221  void setItem(Index, SetItemT*) const;
224  void unsetItem(Index, const UnsetItemT&) const;
225 
227  bool isChildNode() const { return this->parent().isChildMaskOn(this->pos()); }
228 
231  SetItemT* probeChild(NonConstValueType& value) const
232  {
233  SetItemT* child = NULL;
234  static_cast<const IterT*>(this)->getItem(this->pos(), child, value); // static polymorphism
235  return child;
236  }
240  bool probeChild(SetItemT*& child, NonConstValueType& value) const
241  {
242  child = probeChild(value);
243  return (child != NULL);
244  }
245 
248  bool probeValue(NonConstValueType& value) const
249  {
250  SetItemT* child = NULL;
251  const bool isChild = static_cast<const IterT*>(this)-> // static polymorphism
252  getItem(this->pos(), child, value);
253  return !isChild;
254  }
255 
258  void setChild(SetItemT* child) const
259  {
260  static_cast<const IterT*>(this)->setItem(this->pos(), child); // static polymorphism
261  }
262 
265  void setValue(const UnsetItemT& value) const
266  {
267  static_cast<const IterT*>(this)->unsetItem(this->pos(), value); // static polymorphism
268  }
269 }; // struct DenseIteratorBase
270 
271 } // namespace tree
272 } // namespace OPENVDB_VERSION_NAME
273 } // namespace openvdb
274 
275 #endif // OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
276 
277 // Copyright (c) 2012 DreamWorks Animation LLC
278 // All rights reserved. This software is distributed under the
279 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )