OpenVDB 9.0.0
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
16namespace openvdb {
18namespace OPENVDB_VERSION_NAME {
19namespace 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,
27template <typename IterT>
28inline Index64 iterCount(const IterT& iter);
29
30
31////////////////////////////////////////
32
33
34namespace 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
40{
43 ALL
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{
52public:
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{
66public:
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
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
119private:
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///
138template <typename IteratorT, typename FilterT>
140{
141public:
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 }
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
304private:
305 ValueIndexIter mIterator;
306 FilterT mFilter;
307}; // class IndexIter
308
309
310////////////////////////////////////////
311
312
313template <typename IterT>
314inline 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
Definition: Exceptions.h:63
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
A forward iterator over array indices from a value iterator (such as ValueOnCIter)
Definition: IndexIterator.h:144
bool increment()
Definition: IndexIterator.h:191
ValueIndexIter(const IteratorT &iter)
Definition: IndexIterator.h:146
bool isValueOn() const
Return true if this iterator is pointing to an active value.
Definition: IndexIterator.h:199
bool operator==(const ValueIndexIter &other) const
Equality operators.
Definition: IndexIterator.h:205
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
Definition: IndexIterator.h:194
bool test() const
Definition: IndexIterator.h:177
bool operator!=(const ValueIndexIter &other) const
Definition: IndexIterator.h:206
Index32 end() const
Definition: IndexIterator.h:164
ValueIndexIter & operator++()
Advance to the next (valid) item (prefix).
Definition: IndexIterator.h:180
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Definition: IndexIterator.h:172
bool next()
Advance to the next (valid) item.
Definition: IndexIterator.h:190
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Definition: IndexIterator.h:196
const IteratorT & valueIter() const
Return the const value iterator.
Definition: IndexIterator.h:202
ValueIndexIter(const ValueIndexIter &other)
Definition: IndexIterator.h:157
void reset(Index32 item, Index32 end)
Definition: IndexIterator.h:166
Index32 operator*() const
Definition: IndexIterator.h:173
ValueIndexIter & operator=(const ValueIndexIter &)=default
A forward iterator over array indices with filtering IteratorT can be either IndexIter or ValueIndexI...
Definition: IndexIterator.h:140
IndexIter(const IndexIter &other)
Definition: IndexIterator.h:227
bool increment()
Definition: IndexIterator.h:287
bool isValueOn() const
Return true if the value iterator is pointing to an active value.
Definition: IndexIterator.h:298
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
Definition: IndexIterator.h:293
bool operator==(const IndexIter &other) const
Equality operators.
Definition: IndexIterator.h:301
bool test() const
Definition: IndexIterator.h:265
bool operator!=(const IndexIter &other) const
Definition: IndexIterator.h:302
IndexIter operator++(int)
Advance to the next (valid) item (postfix).
Definition: IndexIterator.h:279
IndexIter & operator++()
Advance to the next (valid) item (prefix).
Definition: IndexIterator.h:268
void reset(Index32 begin, Index32 end)
Reset the begining and end of the iterator.
Definition: IndexIterator.h:252
Index32 end() const
Definition: IndexIterator.h:249
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Definition: IndexIterator.h:260
bool next()
Advance to the next (valid) item.
Definition: IndexIterator.h:286
IndexIter(const IteratorT &iterator, const FilterT &filter)
Definition: IndexIterator.h:215
IndexIter & operator=(const IndexIter &other)
Definition: IndexIterator.h:236
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Definition: IndexIterator.h:295
const FilterT & filter() const
Return the const filter.
Definition: IndexIterator.h:290
Index32 operator*() const
Definition: IndexIterator.h:261
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:51
static index::State state()
Definition: IndexIterator.h:54
static index::State state(const LeafT &)
Definition: IndexIterator.h:56
static bool initialized()
Definition: IndexIterator.h:53
static bool valid(const IterT &)
Definition: IndexIterator.h:59
void reset(const LeafT &)
Definition: IndexIterator.h:58
A forward iterator over array indices in a single voxel.
Definition: IndexIterator.h:65
bool operator==(const ValueVoxelCIter &other) const
Equality operators.
Definition: IndexIterator.h:115
ValueVoxelCIter(Index32 prevOffset, Index32 offset)
Definition: IndexIterator.h:79
bool test() const
Definition: IndexIterator.h:92
ValueVoxelCIter(const ValueVoxelCIter &other)
Definition: IndexIterator.h:81
Index32 end() const
Definition: IndexIterator.h:93
Index32 operator*()
Return the item to which this iterator is currently pointing.
Definition: IndexIterator.h:85
Index32 offset()
Definition: IndexIterator.h:98
ValueVoxelCIter & operator++()
Advance to the next (valid) item (prefix).
Definition: IndexIterator.h:89
bool next()
Definition: IndexIterator.h:99
bool operator!=(const ValueVoxelCIter &other) const
Equality operators.
Definition: IndexIterator.h:116
Parent & parent()
Definition: IndexIterator.h:97
void reset(Index32, Index32)
Definition: IndexIterator.h:95
Index32 operator*() const
Definition: IndexIterator.h:86
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:477
State
Definition: IndexIterator.h:40
@ PARTIAL
Definition: IndexIterator.h:41
@ ALL
Definition: IndexIterator.h:43
@ NONE
Definition: IndexIterator.h:42
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:314
uint32_t Index32
Definition: Types.h:52
uint64_t Index64
Definition: Types.h:53
Definition: Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Index32 getValue(unsigned) const
Definition: IndexIterator.h:71
Parent(Index32 offset)
Definition: IndexIterator.h:70
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202