HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IndexIterator.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 /// @file points/IndexIterator.h
5 ///
6 /// @author Dan Bailey
7 ///
8 /// @brief Index Iterators.
9 
10 #ifndef OPENVDB_POINTS_INDEX_ITERATOR_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_INDEX_ITERATOR_HAS_BEEN_INCLUDED
12 
13 #include <openvdb/version.h>
14 #include <openvdb/Types.h>
15 
16 namespace openvdb {
18 namespace OPENVDB_VERSION_NAME {
19 namespace points {
20 
21 
22 /// @brief Count up the number of times the iterator can iterate
23 ///
24 /// @param iter the iterator.
25 ///
26 /// @note counting by iteration only performed where a dynamic filter is in use,
27 template <typename IterT>
28 inline Index64 iterCount(const IterT& iter);
29 
30 
31 ////////////////////////////////////////
32 
33 
34 namespace index {
35 // Enum for informing early-exit optimizations
36 // PARTIAL - No optimizations are possible
37 // NONE - No indices to evaluate, can skip computation
38 // ALL - All indices to evaluate, can skip filtering
39 enum State
40 {
44 };
45 }
46 
47 
48 /// @brief A no-op filter that can be used when iterating over all indices
49 /// @see points/IndexFilter.h for the documented interface for an index filter
51 {
52 public:
53  static bool initialized() { return true; }
54  static index::State state() { return index::ALL; }
55  template <typename LeafT>
56  static index::State state(const LeafT&) { return index::ALL; }
57 
58  template <typename LeafT> void reset(const LeafT&) { }
59  template <typename IterT> static bool valid(const IterT&) { return true; }
60 }; // class NullFilter
61 
62 
63 /// @brief A forward iterator over array indices in a single voxel
65 {
66 public:
67  struct Parent
68  {
69  Parent() = default;
70  explicit Parent(Index32 offset): mOffset(offset) { }
71  Index32 getValue(unsigned /*offset*/) const { return mOffset; }
72  private:
73  Index32 mOffset = 0;
74  }; // struct Parent
75 
76  using NodeType = Parent;
77 
78  ValueVoxelCIter() = default;
80  : mOffset(offset), mParent(prevOffset) {}
82  : mOffset(other.mOffset), mParent(other.mParent), mValid(other.mValid) {}
83 
84  /// @brief Return the item to which this iterator is currently pointing.
85  Index32 operator*() { return mOffset; }
86  Index32 operator*() const { return mOffset; }
87 
88  /// @brief Advance to the next (valid) item (prefix).
89  ValueVoxelCIter& operator++() { mValid = false; return *this; }
90 
91  operator bool() const { return mValid; }
92  bool test() const { return mValid; }
93  Index32 end() const { return mOffset+1; }
94 
95  void reset(Index32 /*item*/, Index32 /*end*/) {}
96 
97  Parent& parent() { return mParent; }
98  Index32 offset() { return mOffset; }
99  inline bool next() { this->operator++(); return this->test(); }
100 
101  /// @brief For efficiency, Coord and active state assumed to be readily available
102  /// when iterating over indices of a single voxel
103  Coord getCoord [[noreturn]] () const {
104  OPENVDB_THROW(RuntimeError, "ValueVoxelCIter does not provide a valid Coord.");
105  }
106  void getCoord [[noreturn]] (Coord& /*coord*/) const {
107  OPENVDB_THROW(RuntimeError, "ValueVoxelCIter does not provide a valid Coord.");
108  }
109  bool isValueOn [[noreturn]] () const {
110  OPENVDB_THROW(RuntimeError, "ValueVoxelCIter does not test if voxel is active.");
111  }
112 
113  /// @{
114  /// @brief Equality operators
115  bool operator==(const ValueVoxelCIter& other) const { return mOffset == other.mOffset; }
116  bool operator!=(const ValueVoxelCIter& other) const { return !this->operator==(other); }
117  /// @}
118 
119 private:
120  Index32 mOffset = 0;
121  Parent mParent;
122  mutable bool mValid = true;
123 }; // class ValueVoxelCIter
124 
125 
126 /// @brief A forward iterator over array indices with filtering
127 /// IteratorT can be either IndexIter or ValueIndexIter (or some custom index iterator)
128 /// FilterT should be a struct or class with a valid() method than can be evaluated per index
129 /// Here's a simple filter example that only accepts even indices:
130 ///
131 /// struct EvenIndexFilter
132 /// {
133 /// bool valid(const Index32 offset) const {
134 /// return (offset % 2) == 0;
135 /// }
136 /// };
137 ///
138 template <typename IteratorT, typename FilterT>
140 {
141 public:
142  /// @brief A forward iterator over array indices from a value iterator (such as ValueOnCIter)
144  {
145  public:
146  ValueIndexIter(const IteratorT& iter)
147  : mIter(iter), mParent(&mIter.parent())
148  {
149  if (mIter) {
150  assert(mParent);
151  Index32 start = (mIter.offset() > 0 ?
152  Index32(mParent->getValue(mIter.offset() - 1)) : Index32(0));
153  this->reset(start, *mIter);
154  if (mItem >= mEnd) this->operator++();
155  }
156  }
158  : mEnd(other.mEnd), mItem(other.mItem), mIter(other.mIter), mParent(other.mParent)
159  {
160  assert(mParent);
161  }
162  ValueIndexIter& operator=(const ValueIndexIter&) = default;
163 
164  inline Index32 end() const { return mEnd; }
165 
166  inline void reset(Index32 item, Index32 end) {
167  mItem = item;
168  mEnd = end;
169  }
170 
171  /// @brief Returns the item to which this iterator is currently pointing.
172  inline Index32 operator*() { assert(mIter); return mItem; }
173  inline Index32 operator*() const { assert(mIter); return mItem; }
174 
175  /// @brief Return @c true if this iterator is not yet exhausted.
176  inline operator bool() const { return mIter; }
177  inline bool test() const { return mIter; }
178 
179  /// @brief Advance to the next (valid) item (prefix).
181  ++mItem;
182  while (mItem >= mEnd && mIter.next()) {
183  assert(mParent);
184  this->reset(mParent->getValue(mIter.offset() - 1), *mIter);
185  }
186  return *this;
187  }
188 
189  /// @brief Advance to the next (valid) item.
190  inline bool next() { this->operator++(); return this->test(); }
191  inline bool increment() { this->next(); return this->test(); }
192 
193  /// Return the coordinates of the item to which the value iterator is pointing.
194  inline Coord getCoord() const { assert(mIter); return mIter.getCoord(); }
195  /// Return in @a xyz the coordinates of the item to which the value iterator is pointing.
196  inline void getCoord(Coord& xyz) const { assert(mIter); xyz = mIter.getCoord(); }
197 
198  /// @brief Return @c true if this iterator is pointing to an active value.
199  inline bool isValueOn() const { assert(mIter); return mIter.isValueOn(); }
200 
201  /// Return the const value iterator
202  inline const IteratorT& valueIter() const { return mIter; }
203 
204  /// @brief Equality operators
205  bool operator==(const ValueIndexIter& other) const { return mItem == other.mItem; }
206  bool operator!=(const ValueIndexIter& other) const { return !this->operator==(other); }
207 
208  private:
209  Index32 mEnd = 0;
210  Index32 mItem = 0;
211  IteratorT mIter;
212  const typename IteratorT::NodeType* mParent;
213  }; // ValueIndexIter
214 
215  IndexIter(const IteratorT& iterator, const FilterT& filter)
216  : mIterator(iterator)
217  , mFilter(filter)
218  {
219  if (!mFilter.initialized()) {
220  OPENVDB_THROW(RuntimeError,
221  "Filter needs to be initialized before constructing the iterator.");
222  }
223  if (mIterator) {
224  this->reset(*mIterator, mIterator.end());
225  }
226  }
227  IndexIter(const IndexIter& other)
228  : mIterator(other.mIterator)
229  , mFilter(other.mFilter)
230  {
231  if (!mFilter.initialized()) {
232  OPENVDB_THROW(RuntimeError,
233  "Filter needs to be initialized before constructing the iterator.");
234  }
235  }
237  {
238  if (&other != this) {
239  mIterator = other.mIterator;
240  mFilter = other.mFilter;
241  if (!mFilter.initialized()) {
242  OPENVDB_THROW(RuntimeError,
243  "Filter needs to be initialized before constructing the iterator.");
244  }
245  }
246  return *this;
247  }
248 
249  Index32 end() const { return mIterator.end(); }
250 
251  /// @brief Reset the begining and end of the iterator.
253  mIterator.reset(begin, end);
254  while (mIterator.test() && !mFilter.template valid<ValueIndexIter>(mIterator)) {
255  ++mIterator;
256  }
257  }
258 
259  /// @brief Returns the item to which this iterator is currently pointing.
260  Index32 operator*() { assert(mIterator); return *mIterator; }
261  Index32 operator*() const { assert(mIterator); return *mIterator; }
262 
263  /// @brief Return @c true if this iterator is not yet exhausted.
264  operator bool() const { return mIterator.test(); }
265  bool test() const { return mIterator.test(); }
266 
267  /// @brief Advance to the next (valid) item (prefix).
269  while (true) {
270  ++mIterator;
271  if (!mIterator.test() || mFilter.template valid<ValueIndexIter>(mIterator)) {
272  break;
273  }
274  }
275  return *this;
276  }
277 
278  /// @brief Advance to the next (valid) item (postfix).
279  IndexIter operator++(int /*dummy*/) {
280  IndexIter newIterator(*this);
281  this->operator++();
282  return newIterator;
283  }
284 
285  /// @brief Advance to the next (valid) item.
286  bool next() { this->operator++(); return this->test(); }
287  bool increment() { this->next(); return this->test(); }
288 
289  /// Return the const filter
290  inline const FilterT& filter() const { return mFilter; }
291 
292  /// Return the coordinates of the item to which the value iterator is pointing.
293  inline Coord getCoord() const { assert(mIterator); return mIterator.getCoord(); }
294  /// Return in @a xyz the coordinates of the item to which the value iterator is pointing.
295  inline void getCoord(Coord& xyz) const { assert(mIterator); xyz = mIterator.getCoord(); }
296 
297  /// @brief Return @c true if the value iterator is pointing to an active value.
298  inline bool isValueOn() const { assert(mIterator); return mIterator.valueIter().isValueOn(); }
299 
300  /// @brief Equality operators
301  bool operator==(const IndexIter& other) const { return mIterator == other.mIterator; }
302  bool operator!=(const IndexIter& other) const { return !this->operator==(other); }
303 
304 private:
305  ValueIndexIter mIterator;
306  FilterT mFilter;
307 }; // class IndexIter
308 
309 
310 ////////////////////////////////////////
311 
312 
313 template <typename IterT>
314 inline Index64 iterCount(const IterT& iter)
315 {
316  Index64 size = 0;
317  for (IterT newIter(iter); newIter; ++newIter, ++size) { }
318  return size;
319 }
320 
321 
322 ////////////////////////////////////////
323 
324 
325 } // namespace points
326 } // namespace OPENVDB_VERSION_NAME
327 } // namespace openvdb
328 
329 #endif // OPENVDB_POINTS_INDEX_ITERATOR_HAS_BEEN_INCLUDED
static index::State state(const LeafT &)
Definition: IndexIterator.h:56
GLsizeiptr size
Definition: glew.h:1681
FMT_CONSTEXPR auto begin(const C &c) -> decltype(c.begin())
Definition: format.h:251
GLuint index
Definition: glew.h:1814
const IteratorT & valueIter() const
Return the const value iterator.
bool next()
Advance to the next (valid) item.
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:166
bool operator!=(const IndexIter &other) const
bool isValueOn() const
Return true if the value iterator is pointing to an active value.
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:50
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
ValueVoxelCIter(Index32 prevOffset, Index32 offset)
Definition: IndexIterator.h:79
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:2981
Index32 operator*()
Return the item to which this iterator is currently pointing.
Definition: IndexIterator.h:85
A forward iterator over array indices in a single voxel.
Definition: IndexIterator.h:64
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
GLuint GLuint end
Definition: glew.h:1253
IndexIter & operator++()
Advance to the next (valid) item (prefix).
bool operator==(const ValueIndexIter &other) const
Equality operators.
A forward iterator over array indices with filtering IteratorT can be either IndexIter or ValueIndexI...
ValueIndexIter & operator=(const ValueIndexIter &)=default
ValueVoxelCIter & operator++()
Advance to the next (valid) item (prefix).
Definition: IndexIterator.h:89
GLuint start
Definition: glew.h:1253
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Coord getCoord() const
For efficiency, Coord and active state assumed to be readily available when iterating over indices of...
IndexIter(const IteratorT &iterator, const FilterT &filter)
const FilterT & filter() const
Return the const filter.
bool operator!=(const ValueVoxelCIter &other) const
Equality operators.
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3446
A forward iterator over array indices from a value iterator (such as ValueOnCIter) ...
Index32 operator*()
Returns the item to which this iterator is currently pointing.
IndexIter operator++(int)
Advance to the next (valid) item (postfix).
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
IndexIter & operator=(const IndexIter &other)
void reset(Index32 begin, Index32 end)
Reset the begining and end of the iterator.
ValueIndexIter & operator++()
Advance to the next (valid) item (prefix).
bool isValueOn() const
Return true if this iterator is pointing to an active value.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:112
bool operator==(const IndexIter &other) const
Equality operators.
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
bool operator==(const ValueVoxelCIter &other) const
Equality operators.
GLintptr offset
Definition: glew.h:1682