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