HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Iterator.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2017 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 //
29 ///////////////////////////////////////////////////////////////////////////
30 //
31 /// @file Iterator.h
32 ///
33 /// @author Peter Cucka and Ken Museth
34 
35 #ifndef OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
36 #define OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
37 
38 #include <sstream>
39 #include <hboost/static_assert.hpp>
40 #include <hboost/type_traits/is_const.hpp>
41 #include <hboost/type_traits/remove_const.hpp>
42 #include <openvdb/util/NodeMasks.h>
43 #include <openvdb/Exceptions.h>
44 
45 namespace openvdb {
47 namespace OPENVDB_VERSION_NAME {
48 namespace tree {
49 
50 /// @brief Base class for iterators over internal and leaf nodes
51 ///
52 /// This class is typically not instantiated directly, since it doesn't provide methods
53 /// to dereference the iterator. Those methods (@vdblink::tree::SparseIteratorBase::operator*()
54 /// operator*()@endlink, @vdblink::tree::SparseIteratorBase::setValue() setValue()@endlink, etc.)
55 /// are implemented in the @vdblink::tree::SparseIteratorBase sparse@endlink and
56 /// @vdblink::tree::DenseIteratorBase dense@endlink iterator subclasses.
57 template<typename MaskIterT, typename NodeT>
59 {
60 public:
61  IteratorBase(): mParentNode(nullptr) {}
62  IteratorBase(const MaskIterT& iter, NodeT* parent): mParentNode(parent), mMaskIter(iter) {}
63  IteratorBase(const IteratorBase&) = default;
64  IteratorBase& operator=(const IteratorBase&) = default;
65 
66  bool operator==(const IteratorBase& other) const
67  {
68  return (mParentNode == other.mParentNode) && (mMaskIter == other.mMaskIter);
69  }
70  bool operator!=(const IteratorBase& other) const
71  {
72  return !(*this == other);
73  }
74 
75  /// Return a pointer to the node (if any) over which this iterator is iterating.
76  NodeT* getParentNode() const { return mParentNode; }
77  /// @brief Return a reference to the node over which this iterator is iterating.
78  /// @throw ValueError if there is no parent node.
79  NodeT& parent() const
80  {
81  if (!mParentNode) OPENVDB_THROW(ValueError, "iterator references a null node");
82  return *mParentNode;
83  }
84 
85  /// Return this iterator's position as an index into the parent node's table.
86  Index offset() const { return mMaskIter.offset(); }
87 
88  /// Identical to offset
89  Index pos() const { return mMaskIter.offset(); }
90 
91  /// Return @c true if this iterator is not yet exhausted.
92  bool test() const { return mMaskIter.test(); }
93  /// Return @c true if this iterator is not yet exhausted.
94  operator bool() const { return this->test(); }
95 
96  /// Advance to the next item in the parent node's table.
97  bool next() { return mMaskIter.next(); }
98  /// Advance to the next item in the parent node's table.
99  void increment() { mMaskIter.increment(); }
100  /// Advance to the next item in the parent node's table.
101  IteratorBase& operator++() { this->increment(); return *this; }
102  /// Advance @a n items in the parent node's table.
103  void increment(Index n) { mMaskIter.increment(n); }
104 
105  /// @brief Return @c true if this iterator is pointing to an active value.
106  /// Return @c false if it is pointing to either an inactive value or a child node.
107  bool isValueOn() const { return parent().isValueMaskOn(this->pos()); }
108  /// @brief If this iterator is pointing to a value, set the value's active state.
109  /// Otherwise, do nothing.
110  void setValueOn(bool on = true) const { parent().setValueMask(this->pos(), on); }
111  /// @brief If this iterator is pointing to a value, mark the value as inactive.
112  /// @details If this iterator is pointing to a child node, then the current item
113  /// in the parent node's table is required to be inactive. In that case,
114  /// this method has no effect.
115  void setValueOff() const { parent().mValueMask.setOff(this->pos()); }
116 
117  /// Return the coordinates of the item to which this iterator is pointing.
118  Coord getCoord() const { return parent().offsetToGlobalCoord(this->pos()); }
119  /// Return in @a xyz the coordinates of the item to which this iterator is pointing.
120  void getCoord(Coord& xyz) const { xyz = this->getCoord(); }
121 
122 private:
123  /// @note This parent node pointer is mutable, because setValueOn() and
124  /// setValueOff(), though const, need to call non-const methods on the parent.
125  /// There is a distinction between a const iterator (e.g., const ValueOnIter),
126  /// which is an iterator that can't be incremented, and an iterator over
127  /// a const node (e.g., ValueOnCIter), which might be const or non-const itself
128  /// but can't call non-const methods like setValue() on the node.
129  mutable NodeT* mParentNode;
130  MaskIterT mMaskIter;
131 }; // class IteratorBase
132 
133 
134 ////////////////////////////////////////
135 
136 
137 /// @brief Base class for sparse iterators over internal and leaf nodes
138 template<
139  typename MaskIterT, // mask iterator type (OnIterator, OffIterator, etc.)
140  typename IterT, // SparseIteratorBase subclass (the "Curiously Recurring Template Pattern")
141  typename NodeT, // type of node over which to iterate
142  typename ItemT> // type of value to which this iterator points
143 struct SparseIteratorBase: public IteratorBase<MaskIterT, NodeT>
144 {
145  typedef NodeT NodeType;
146  typedef ItemT ValueType;
149  static const bool IsSparseIterator = true, IsDenseIterator = false;
150 
152  SparseIteratorBase(const MaskIterT& iter, NodeT* parent):
153  IteratorBase<MaskIterT, NodeT>(iter, parent) {}
154 
155  /// @brief Return the item at the given index in the parent node's table.
156  /// @note All subclasses must implement this accessor.
157  ItemT& getItem(Index) const;
158  /// @brief Set the value of the item at the given index in the parent node's table.
159  /// @note All non-const iterator subclasses must implement this accessor.
160  void setItem(Index, const ItemT&) const;
161 
162  /// Return a reference to the item to which this iterator is pointing.
163  ItemT& operator*() const { return this->getValue(); }
164  /// Return a pointer to the item to which this iterator is pointing.
165  ItemT* operator->() const { return &(this->operator*()); }
166 
167  /// Return the item to which this iterator is pointing.
168  ItemT& getValue() const
169  {
170  return static_cast<const IterT*>(this)->getItem(this->pos()); // static polymorphism
171  }
172  /// @brief Set the value of the item to which this iterator is pointing.
173  /// (Not valid for const iterators.)
174  void setValue(const ItemT& value) const
175  {
176  HBOOST_STATIC_ASSERT(!hboost::is_const<NodeT>::value);
177  static_cast<const IterT*>(this)->setItem(this->pos(), value); // static polymorphism
178  }
179  /// @brief Apply a functor to the item to which this iterator is pointing.
180  /// (Not valid for const iterators.)
181  /// @param op a functor of the form <tt>void op(ValueType&) const</tt> that modifies
182  /// its argument in place
183  /// @see Tree::modifyValue()
184  template<typename ModifyOp>
185  void modifyValue(const ModifyOp& op) const
186  {
187  HBOOST_STATIC_ASSERT(!hboost::is_const<NodeT>::value);
188  static_cast<const IterT*>(this)->modifyItem(this->pos(), op); // static polymorphism
189  }
190 }; // class SparseIteratorBase
191 
192 
193 ////////////////////////////////////////
194 
195 
196 /// @brief Base class for dense iterators over internal and leaf nodes
197 /// @note Dense iterators have no @c %operator*() or @c %operator->(),
198 /// because their return type would have to vary depending on whether
199 /// the iterator is pointing to a value or a child node.
200 template<
201  typename MaskIterT, // mask iterator type (typically a DenseIterator)
202  typename IterT, // DenseIteratorBase subclass (the "Curiously Recurring Template Pattern")
203  typename NodeT, // type of node over which to iterate
204  typename SetItemT, // type of set value (ChildNodeType, for non-leaf nodes)
205  typename UnsetItemT> // type of unset value (ValueType, usually)
206 struct DenseIteratorBase: public IteratorBase<MaskIterT, NodeT>
207 {
208  typedef NodeT NodeType;
209  typedef UnsetItemT ValueType;
210  typedef SetItemT ChildNodeType;
214  static const bool IsSparseIterator = false, IsDenseIterator = true;
215 
217  DenseIteratorBase(const MaskIterT& iter, NodeT* parent):
218  IteratorBase<MaskIterT, NodeT>(iter, parent) {}
219 
220  /// @brief Return @c true if the item at the given index in the parent node's table
221  /// is a set value and return either the set value in @a child or the unset value
222  /// in @a value.
223  /// @note All subclasses must implement this accessor.
224  bool getItem(Index, SetItemT*& child, NonConstValueType& value) const;
225  /// @brief Set the value of the item at the given index in the parent node's table.
226  /// @note All non-const iterator subclasses must implement this accessor.
227  void setItem(Index, SetItemT*) const;
228  /// @brief "Unset" the value of the item at the given index in the parent node's table.
229  /// @note All non-const iterator subclasses must implement this accessor.
230  void unsetItem(Index, const UnsetItemT&) const;
231 
232  /// Return @c true if this iterator is pointing to a child node.
233  bool isChildNode() const { return this->parent().isChildMaskOn(this->pos()); }
234 
235  /// @brief If this iterator is pointing to a child node, return a pointer to the node.
236  /// Otherwise, return nullptr and, in @a value, the value to which this iterator is pointing.
238  {
239  SetItemT* child = nullptr;
240  static_cast<const IterT*>(this)->getItem(this->pos(), child, value); // static polymorphism
241  return child;
242  }
243  /// @brief If this iterator is pointing to a child node, return @c true and return
244  /// a pointer to the child node in @a child. Otherwise, return @c false and return
245  /// the value to which this iterator is pointing in @a value.
246  bool probeChild(SetItemT*& child, NonConstValueType& value) const
247  {
248  child = probeChild(value);
249  return (child != nullptr);
250  }
251 
252  /// @brief Return @c true if this iterator is pointing to a value and return
253  /// the value in @a value. Otherwise, return @c false.
255  {
256  SetItemT* child = nullptr;
257  const bool isChild = static_cast<const IterT*>(this)-> // static polymorphism
258  getItem(this->pos(), child, value);
259  return !isChild;
260  }
261 
262  /// @brief Replace with the given child node the item in the parent node's table
263  /// to which this iterator is pointing.
264  void setChild(SetItemT* child) const
265  {
266  static_cast<const IterT*>(this)->setItem(this->pos(), child); // static polymorphism
267  }
268 
269  /// @brief Replace with the given value the item in the parent node's table
270  /// to which this iterator is pointing.
271  void setValue(const UnsetItemT& value) const
272  {
273  static_cast<const IterT*>(this)->unsetItem(this->pos(), value); // static polymorphism
274  }
275 }; // struct DenseIteratorBase
276 
277 } // namespace tree
278 } // namespace OPENVDB_VERSION_NAME
279 } // namespace openvdb
280 
281 #endif // OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
282 
283 // Copyright (c) 2012-2017 DreamWorks Animation LLC
284 // All rights reserved. This software is distributed under the
285 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Coord getCoord() const
Return the coordinates of the item to which this iterator is pointing.
Definition: Iterator.h:118
IteratorBase & operator++()
Advance to the next item in the parent node's table.
Definition: Iterator.h:101
bool isValueOn() const
Return true if this iterator is pointing to an active value. Return false if it is pointing to either...
Definition: Iterator.h:107
IteratorBase & operator=(const IteratorBase &)=default
Index pos() const
Identical to offset.
Definition: Iterator.h:89
void increment()
Advance to the next item in the parent node's table.
Definition: Iterator.h:99
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:58
void setItem(Index, SetItemT *) const
Set the value of the item at the given index in the parent node's table.
NodeT & parent() const
Return a reference to the node over which this iterator is iterating.
Definition: Iterator.h:79
void modifyValue(const ModifyOp &op) const
Apply a functor to the item to which this iterator is pointing. (Not valid for const iterators...
Definition: Iterator.h:185
SetItemT * probeChild(NonConstValueType &value) const
If this iterator is pointing to a child node, return a pointer to the node. Otherwise, return nullptr and, in value, the value to which this iterator is pointing.
Definition: Iterator.h:237
bool probeValue(NonConstValueType &value) const
Return true if this iterator is pointing to a value and return the value in value. Otherwise, return false.
Definition: Iterator.h:254
IteratorBase(const MaskIterT &iter, NodeT *parent)
Definition: Iterator.h:62
GLdouble n
Definition: glcorearb.h:2007
void unsetItem(Index, const UnsetItemT &) const
"Unset" the value of the item at the given index in the parent node's table.
hboost::remove_const< ItemT >::type NonConstValueType
Definition: Iterator.h:148
bool probeChild(SetItemT *&child, NonConstValueType &value) const
If this iterator is pointing to a child node, return true and return a pointer to the child node in c...
Definition: Iterator.h:246
#define OPENVDB_VERSION_NAME
Definition: version.h:43
void setItem(Index, const ItemT &) const
Set the value of the item at the given index in the parent node's table.
hboost::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:212
bool test() const
Return true if this iterator is not yet exhausted.
Definition: Iterator.h:92
void setValueOn(bool on=true) const
If this iterator is pointing to a value, set the value's active state. Otherwise, do nothing...
Definition: Iterator.h:110
Index offset() const
Return this iterator's position as an index into the parent node's table.
Definition: Iterator.h:86
bool getItem(Index, SetItemT *&child, NonConstValueType &value) const
Return true if the item at the given index in the parent node's table is a set value and return eithe...
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:143
bool operator!=(const IteratorBase &other) const
Definition: Iterator.h:70
DenseIteratorBase(const MaskIterT &iter, NodeT *parent)
Definition: Iterator.h:217
ItemT * operator->() const
Return a pointer to the item to which this iterator is pointing.
Definition: Iterator.h:165
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:206
GLsizei const GLfloat * value
Definition: glcorearb.h:823
void increment(Index n)
Advance n items in the parent node's table.
Definition: Iterator.h:103
bool isChildNode() const
Return true if this iterator is pointing to a child node.
Definition: Iterator.h:233
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which this iterator is pointing.
Definition: Iterator.h:120
void setChild(SetItemT *child) const
Replace with the given child node the item in the parent node's table to which this iterator is point...
Definition: Iterator.h:264
hboost::remove_const< SetItemT >::type NonConstChildNodeType
Definition: Iterator.h:213
hboost::remove_const< NodeT >::type NonConstNodeType
Definition: Iterator.h:211
NodeT * getParentNode() const
Return a pointer to the node (if any) over which this iterator is iterating.
Definition: Iterator.h:76
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
void setValue(const UnsetItemT &value) const
Replace with the given value the item in the parent node's table to which this iterator is pointing...
Definition: Iterator.h:271
void setValue(const ItemT &value) const
Set the value of the item to which this iterator is pointing. (Not valid for const iterators...
Definition: Iterator.h:174
bool operator==(const IteratorBase &other) const
Definition: Iterator.h:66
void setValueOff() const
If this iterator is pointing to a value, mark the value as inactive.
Definition: Iterator.h:115
bool next()
Advance to the next item in the parent node's table.
Definition: Iterator.h:97
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
ItemT & getValue() const
Return the item to which this iterator is pointing.
Definition: Iterator.h:168
ItemT & operator*() const
Return a reference to the item to which this iterator is pointing.
Definition: Iterator.h:163
hboost::remove_const< NodeT >::type NonConstNodeType
Definition: Iterator.h:147
ItemT & getItem(Index) const
Return the item at the given index in the parent node's table.
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
SparseIteratorBase(const MaskIterT &iter, NodeT *parent)
Definition: Iterator.h:152