OpenVDB  9.0.1
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;
79  ValueVoxelCIter(Index32 prevOffset, Index32 offset)
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()) {
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()) {
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()) {
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.
252  void reset(Index32 begin, Index32 end) {
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
void reset(const LeafT &)
Definition: IndexIterator.h:58
Index32 operator*() const
Definition: IndexIterator.h:261
bool next()
Advance to the next (valid) item.
Definition: IndexIterator.h:190
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:50
ValueVoxelCIter(const ValueVoxelCIter &other)
Definition: IndexIterator.h:81
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
Definition: IndexIterator.h:194
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
bool operator==(const ValueVoxelCIter &other) const
Equality operators.
Definition: IndexIterator.h:115
ValueIndexIter(const ValueIndexIter &other)
Definition: IndexIterator.h:157
Definition: IndexIterator.h:41
bool increment()
Definition: IndexIterator.h:287
IndexIter(const IteratorT &iterator, const FilterT &filter)
Definition: IndexIterator.h:215
Parent & parent()
Definition: IndexIterator.h:97
bool operator==(const IndexIter &other) const
Equality operators.
Definition: IndexIterator.h:301
IndexIter & operator++()
Advance to the next (valid) item (prefix).
Definition: IndexIterator.h:268
static bool valid(const IterT &)
Definition: IndexIterator.h:59
void reset(Index32 item, Index32 end)
Definition: IndexIterator.h:166
Parent(Index32 offset)
Definition: IndexIterator.h:70
Index32 end() const
Definition: IndexIterator.h:93
bool operator==(const ValueIndexIter &other) const
Equality operators.
Definition: IndexIterator.h:205
bool test() const
Definition: IndexIterator.h:265
bool isValueOn() const
Return true if this iterator is pointing to an active value.
Definition: IndexIterator.h:199
bool operator!=(const IndexIter &other) const
Definition: IndexIterator.h:302
Index32 end() const
Definition: IndexIterator.h:249
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Definition: IndexIterator.h:260
State
Definition: IndexIterator.h:39
IndexIter(const IndexIter &other)
Definition: IndexIterator.h:227
static index::State state()
Definition: IndexIterator.h:54
static index::State state(const LeafT &)
Definition: IndexIterator.h:56
Index32 offset()
Definition: IndexIterator.h:98
A forward iterator over array indices in a single voxel.
Definition: IndexIterator.h:64
ValueIndexIter(const IteratorT &iter)
Definition: IndexIterator.h:146
uint64_t Index64
Definition: Types.h:53
Index32 operator*() const
Definition: IndexIterator.h:173
void reset(Index32, Index32)
Definition: IndexIterator.h:95
Definition: Exceptions.h:13
Definition: Exceptions.h:63
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
Definition: IndexIterator.h:293
bool next()
Advance to the next (valid) item.
Definition: IndexIterator.h:286
A forward iterator over array indices with filtering IteratorT can be either IndexIter or ValueIndexI...
Definition: IndexIterator.h:139
Definition: IndexIterator.h:43
ValueIndexIter & operator++()
Advance to the next (valid) item (prefix).
Definition: IndexIterator.h:180
bool isValueOn() const
Return true if the value iterator is pointing to an active value.
Definition: IndexIterator.h:298
IndexIter & operator=(const IndexIter &other)
Definition: IndexIterator.h:236
bool operator!=(const ValueVoxelCIter &other) const
Equality operators.
Definition: IndexIterator.h:116
Index32 operator*() const
Definition: IndexIterator.h:86
IndexIter operator++(int)
Advance to the next (valid) item (postfix).
Definition: IndexIterator.h:279
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Definition: IndexIterator.h:295
ValueVoxelCIter(Index32 prevOffset, Index32 offset)
Definition: IndexIterator.h:79
bool test() const
Definition: IndexIterator.h:92
ValueVoxelCIter & operator++()
Advance to the next (valid) item (prefix).
Definition: IndexIterator.h:89
const FilterT & filter() const
Return the const filter.
Definition: IndexIterator.h:290
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:314
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Definition: IndexIterator.h:196
A forward iterator over array indices from a value iterator (such as ValueOnCIter) ...
Definition: IndexIterator.h:143
void reset(Index32 begin, Index32 end)
Reset the begining and end of the iterator.
Definition: IndexIterator.h:252
bool operator!=(const ValueIndexIter &other) const
Definition: IndexIterator.h:206
bool next()
Definition: IndexIterator.h:99
Index32 operator*()
Return the item to which this iterator is currently pointing.
Definition: IndexIterator.h:85
uint32_t Index32
Definition: Types.h:52
Index32 end() const
Definition: IndexIterator.h:164
static bool initialized()
Definition: IndexIterator.h:53
const IteratorT & valueIter() const
Return the const value iterator.
Definition: IndexIterator.h:202
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
bool test() const
Definition: IndexIterator.h:177
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:477
Index32 getValue(unsigned) const
Definition: IndexIterator.h:71
bool increment()
Definition: IndexIterator.h:191
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Definition: IndexIterator.h:172
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202
Definition: IndexIterator.h:42