OpenVDB 12.0.0
 
Loading...
Searching...
No Matches
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
17namespace openvdb {
19namespace OPENVDB_VERSION_NAME {
20namespace 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,
28template <typename IterT>
29inline Index64 iterCount(const IterT& iter);
30
31
32////////////////////////////////////////
33
34
35namespace 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
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{
53public:
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{
67public:
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
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
120private:
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///
139template <typename IteratorT, typename FilterT>
141{
142public:
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 }
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()) {
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
305private:
306 ValueIndexIter mIterator;
307 FilterT mFilter;
308}; // class IndexIter
309
310
311////////////////////////////////////////
312
313
314template <typename IterT>
315inline 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
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Definition Exceptions.h:63
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
bool increment()
Definition IndexIterator.h:192
ValueIndexIter(const IteratorT &iter)
Definition IndexIterator.h:147
bool isValueOn() const
Return true if this iterator is pointing to an active value.
Definition IndexIterator.h:200
bool operator==(const ValueIndexIter &other) const
Equality operators.
Definition IndexIterator.h:206
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
Definition IndexIterator.h:195
bool test() const
Definition IndexIterator.h:178
bool operator!=(const ValueIndexIter &other) const
Definition IndexIterator.h:207
Index32 end() const
Definition IndexIterator.h:165
ValueIndexIter & operator++()
Advance to the next (valid) item (prefix).
Definition IndexIterator.h:181
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Definition IndexIterator.h:173
bool next()
Advance to the next (valid) item.
Definition IndexIterator.h:191
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Definition IndexIterator.h:197
const IteratorT & valueIter() const
Return the const value iterator.
Definition IndexIterator.h:203
ValueIndexIter(const ValueIndexIter &other)
Definition IndexIterator.h:158
void reset(Index32 item, Index32 end)
Definition IndexIterator.h:167
Index32 operator*() const
Definition IndexIterator.h:174
ValueIndexIter & operator=(const ValueIndexIter &)=default
IndexIter(const IndexIter &other)
Definition IndexIterator.h:228
bool increment()
Definition IndexIterator.h:288
bool isValueOn() const
Return true if the value iterator is pointing to an active value.
Definition IndexIterator.h:299
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
Definition IndexIterator.h:294
bool operator==(const IndexIter &other) const
Equality operators.
Definition IndexIterator.h:302
bool test() const
Definition IndexIterator.h:266
bool operator!=(const IndexIter &other) const
Definition IndexIterator.h:303
IndexIter operator++(int)
Advance to the next (valid) item (postfix).
Definition IndexIterator.h:280
IndexIter & operator++()
Advance to the next (valid) item (prefix).
Definition IndexIterator.h:269
void reset(Index32 begin, Index32 end)
Definition IndexIterator.h:253
Index32 end() const
Definition IndexIterator.h:250
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Definition IndexIterator.h:261
bool next()
Advance to the next (valid) item.
Definition IndexIterator.h:287
IndexIter(const IteratorT &iterator, const FilterT &filter)
Definition IndexIterator.h:216
IndexIter & operator=(const IndexIter &other)
Definition IndexIterator.h:237
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Definition IndexIterator.h:296
const NullFilter & filter() const
Definition IndexIterator.h:291
Index32 operator*() const
Definition IndexIterator.h:262
A no-op filter that can be used when iterating over all indices.
Definition IndexIterator.h:52
static index::State state()
Definition IndexIterator.h:55
static index::State state(const LeafT &)
Definition IndexIterator.h:57
static bool initialized()
Definition IndexIterator.h:54
static bool valid(const IterT &)
Definition IndexIterator.h:60
void reset(const LeafT &)
Definition IndexIterator.h:59
bool operator==(const ValueVoxelCIter &other) const
Equality operators.
Definition IndexIterator.h:116
bool isValueOn() const
Definition IndexIterator.h:110
ValueVoxelCIter(Index32 prevOffset, Index32 offset)
Definition IndexIterator.h:80
Coord getCoord() const
For efficiency, Coord and active state assumed to be readily available when iterating over indices of...
Definition IndexIterator.h:104
bool test() const
Definition IndexIterator.h:93
ValueVoxelCIter(const ValueVoxelCIter &other)
Definition IndexIterator.h:82
Index32 end() const
Definition IndexIterator.h:94
Index32 operator*()
Return the item to which this iterator is currently pointing.
Definition IndexIterator.h:86
Index32 offset()
Definition IndexIterator.h:99
ValueVoxelCIter & operator++()
Advance to the next (valid) item (prefix).
Definition IndexIterator.h:90
bool next()
Definition IndexIterator.h:100
bool operator!=(const ValueVoxelCIter &other) const
Equality operators.
Definition IndexIterator.h:117
Parent NodeType
Definition IndexIterator.h:77
Parent & parent()
Definition IndexIterator.h:98
void reset(Index32, Index32)
Definition IndexIterator.h:96
Index32 operator*() const
Definition IndexIterator.h:87
Definition IndexIterator.h:35
State
Definition IndexIterator.h:41
@ PARTIAL
Definition IndexIterator.h:42
@ ALL
Definition IndexIterator.h:44
@ NONE
Definition IndexIterator.h:43
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition IndexIterator.h:315
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:72
Parent(Index32 offset)
Definition IndexIterator.h:71
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218