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: 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;
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()) {
221  OPENVDB_THROW(RuntimeError,
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()) {
233  OPENVDB_THROW(RuntimeError,
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()) {
243  OPENVDB_THROW(RuntimeError,
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.
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
GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glad.h:2676
GLuint start
Definition: glcorearb.h:475
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:245
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:51
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:80
Index32 operator*()
Returns the item to which this iterator is currently pointing.
OutGridT const XformOp bool bool
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
Index32 operator*()
Return the item to which this iterator is currently pointing.
Definition: IndexIterator.h:86
GLintptr offset
Definition: glcorearb.h:665
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.
GLuint GLuint end
Definition: glcorearb.h:475
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:90
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
GLsizeiptr size
Definition: glcorearb.h:664
Coord getCoord() const
For efficiency, Coord and active state assumed to be readily available when iterating over indices of...
Library and file format version numbers.
IndexIter(const IteratorT &iterator, const FilterT &filter)
const FilterT & filter() const
Return the const filter.
bool operator!=(const ValueVoxelCIter &other) const
Equality operators.
GLuint index
Definition: glcorearb.h:786
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:119
bool operator==(const IndexIter &other) const
Equality operators.
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
bool operator==(const ValueVoxelCIter &other) const
Equality operators.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:566