HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IndexIterator.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
29 ///////////////////////////////////////////////////////////////////////////
30 
31 /// @file points/IndexIterator.h
32 ///
33 /// @author Dan Bailey
34 ///
35 /// @brief Index Iterators.
36 
37 #ifndef OPENVDB_POINTS_INDEX_ITERATOR_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_INDEX_ITERATOR_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/version.h>
41 #include <openvdb/Types.h>
42 
43 namespace openvdb {
45 namespace OPENVDB_VERSION_NAME {
46 namespace points {
47 
48 
49 /// @brief Count up the number of times the iterator can iterate
50 ///
51 /// @param iter the iterator.
52 ///
53 /// @note counting by iteration only performed where a dynamic filter is in use,
54 template <typename IterT>
55 inline Index64 iterCount(const IterT& iter);
56 
57 
58 ////////////////////////////////////////
59 
60 
61 namespace index {
62 // Enum for informing early-exit optimizations
63 // PARTIAL - No optimizations are possible
64 // NONE - No indices to evaluate, can skip computation
65 // ALL - All indices to evaluate, can skip filtering
66 enum State
67 {
71 };
72 }
73 
74 
75 /// @brief A no-op filter that can be used when iterating over all indices
76 /// @see points/IndexFilter.h for the documented interface for an index filter
78 {
79 public:
80  static bool initialized() { return true; }
81  static index::State state() { return index::ALL; }
82  template <typename LeafT>
83  static index::State state(const LeafT&) { return index::ALL; }
84 
85  template <typename LeafT> void reset(const LeafT&) { }
86  template <typename IterT> static bool valid(const IterT&) { return true; }
87 }; // class NullFilter
88 
89 
90 /// @brief A forward iterator over array indices in a single voxel
92 {
93 public:
94  struct Parent
95  {
96  Parent() = default;
97  explicit Parent(Index32 offset): mOffset(offset) { }
98  Index32 getValue(unsigned /*offset*/) const { return mOffset; }
99  private:
100  Index32 mOffset = 0;
101  }; // struct Parent
102 
103  using NodeType = Parent;
104 
105  ValueVoxelCIter() = default;
107  : mOffset(offset), mParent(prevOffset) {}
109  : mOffset(other.mOffset), mParent(other.mParent), mValid(other.mValid) {}
110 
111  /// @brief Return the item to which this iterator is currently pointing.
112  Index32 operator*() { return mOffset; }
113  Index32 operator*() const { return mOffset; }
114 
115  /// @brief Advance to the next (valid) item (prefix).
116  ValueVoxelCIter& operator++() { mValid = false; return *this; }
117 
118  operator bool() const { return mValid; }
119  bool test() const { return mValid; }
120  Index32 end() const { return mOffset+1; }
121 
122  void reset(Index32 /*item*/, Index32 /*end*/) {}
123 
124  Parent& parent() { return mParent; }
125  Index32 offset() { return mOffset; }
126  inline bool next() { this->operator++(); return this->test(); }
127 
128  /// @brief For efficiency, Coord and active state assumed to be readily available
129  /// when iterating over indices of a single voxel
130  Coord getCoord [[noreturn]] () const {
131  OPENVDB_THROW(RuntimeError, "ValueVoxelCIter does not provide a valid Coord.");
132  }
133  void getCoord [[noreturn]] (Coord& /*coord*/) const {
134  OPENVDB_THROW(RuntimeError, "ValueVoxelCIter does not provide a valid Coord.");
135  }
136  bool isValueOn [[noreturn]] () const {
137  OPENVDB_THROW(RuntimeError, "ValueVoxelCIter does not test if voxel is active.");
138  }
139 
140  /// @{
141  /// @brief Equality operators
142  bool operator==(const ValueVoxelCIter& other) const { return mOffset == other.mOffset; }
143  bool operator!=(const ValueVoxelCIter& other) const { return !this->operator==(other); }
144  /// @}
145 
146 private:
147  Index32 mOffset = 0;
148  Parent mParent;
149  mutable bool mValid = true;
150 }; // class ValueVoxelCIter
151 
152 
153 /// @brief A forward iterator over array indices with filtering
154 /// IteratorT can be either IndexIter or ValueIndexIter (or some custom index iterator)
155 /// FilterT should be a struct or class with a valid() method than can be evaluated per index
156 /// Here's a simple filter example that only accepts even indices:
157 ///
158 /// struct EvenIndexFilter
159 /// {
160 /// bool valid(const Index32 offset) const {
161 /// return (offset % 2) == 0;
162 /// }
163 /// };
164 ///
165 template <typename IteratorT, typename FilterT>
167 {
168 public:
169  /// @brief A forward iterator over array indices from a value iterator (such as ValueOnCIter)
171  {
172  public:
173  ValueIndexIter(const IteratorT& iter)
174  : mIter(iter), mParent(&mIter.parent())
175  {
176  if (mIter) {
177  assert(mParent);
178  Index32 start = (mIter.offset() > 0 ?
179  Index32(mParent->getValue(mIter.offset() - 1)) : Index32(0));
180  this->reset(start, *mIter);
181  if (mItem >= mEnd) this->operator++();
182  }
183  }
185  : mEnd(other.mEnd), mItem(other.mItem), mIter(other.mIter), mParent(other.mParent)
186  {
187  assert(mParent);
188  }
189  ValueIndexIter& operator=(const ValueIndexIter&) = default;
190 
191  inline Index32 end() const { return mEnd; }
192 
193  inline void reset(Index32 item, Index32 end) {
194  mItem = item;
195  mEnd = end;
196  }
197 
198  /// @brief Returns the item to which this iterator is currently pointing.
199  inline Index32 operator*() { assert(mIter); return mItem; }
200  inline Index32 operator*() const { assert(mIter); return mItem; }
201 
202  /// @brief Return @c true if this iterator is not yet exhausted.
203  inline operator bool() const { return mIter; }
204  inline bool test() const { return mIter; }
205 
206  /// @brief Advance to the next (valid) item (prefix).
208  ++mItem;
209  while (mItem >= mEnd && mIter.next()) {
210  assert(mParent);
211  this->reset(mParent->getValue(mIter.offset() - 1), *mIter);
212  }
213  return *this;
214  }
215 
216  /// @brief Advance to the next (valid) item.
217  inline bool next() { this->operator++(); return this->test(); }
218  inline bool increment() { this->next(); return this->test(); }
219 
220  /// Return the coordinates of the item to which the value iterator is pointing.
221  inline Coord getCoord() const { assert(mIter); return mIter.getCoord(); }
222  /// Return in @a xyz the coordinates of the item to which the value iterator is pointing.
223  inline void getCoord(Coord& xyz) const { assert(mIter); xyz = mIter.getCoord(); }
224 
225  /// @brief Return @c true if this iterator is pointing to an active value.
226  inline bool isValueOn() const { assert(mIter); return mIter.isValueOn(); }
227 
228  /// Return the const value iterator
229  inline const IteratorT& valueIter() const { return mIter; }
230 
231  /// @brief Equality operators
232  bool operator==(const ValueIndexIter& other) const { return mItem == other.mItem; }
233  bool operator!=(const ValueIndexIter& other) const { return !this->operator==(other); }
234 
235  private:
236  Index32 mEnd = 0;
237  Index32 mItem = 0;
238  IteratorT mIter;
239  const typename IteratorT::NodeType* mParent;
240  }; // ValueIndexIter
241 
242  IndexIter(const IteratorT& iterator, const FilterT& filter)
243  : mIterator(iterator)
244  , mFilter(filter)
245  {
246  if (!mFilter.initialized()) {
247  OPENVDB_THROW(RuntimeError,
248  "Filter needs to be initialized before constructing the iterator.");
249  }
250  if (mIterator) {
251  this->reset(*mIterator, mIterator.end());
252  }
253  }
254  IndexIter(const IndexIter& other)
255  : mIterator(other.mIterator)
256  , mFilter(other.mFilter)
257  {
258  if (!mFilter.initialized()) {
259  OPENVDB_THROW(RuntimeError,
260  "Filter needs to be initialized before constructing the iterator.");
261  }
262  }
264  {
265  if (&other != this) {
266  mIterator = other.mIterator;
267  mFilter = other.mFilter;
268  if (!mFilter.initialized()) {
269  OPENVDB_THROW(RuntimeError,
270  "Filter needs to be initialized before constructing the iterator.");
271  }
272  }
273  return *this;
274  }
275 
276  Index32 end() const { return mIterator.end(); }
277 
278  /// @brief Reset the begining and end of the iterator.
279  void reset(Index32 begin, Index32 end) {
280  mIterator.reset(begin, end);
281  while (mIterator.test() && !mFilter.template valid<ValueIndexIter>(mIterator)) {
282  ++mIterator;
283  }
284  }
285 
286  /// @brief Returns the item to which this iterator is currently pointing.
287  Index32 operator*() { assert(mIterator); return *mIterator; }
288  Index32 operator*() const { assert(mIterator); return *mIterator; }
289 
290  /// @brief Return @c true if this iterator is not yet exhausted.
291  operator bool() const { return mIterator.test(); }
292  bool test() const { return mIterator.test(); }
293 
294  /// @brief Advance to the next (valid) item (prefix).
296  while (true) {
297  ++mIterator;
298  if (!mIterator.test() || mFilter.template valid<ValueIndexIter>(mIterator)) {
299  break;
300  }
301  }
302  return *this;
303  }
304 
305  /// @brief Advance to the next (valid) item (postfix).
306  IndexIter operator++(int /*dummy*/) {
307  IndexIter newIterator(*this);
308  this->operator++();
309  return newIterator;
310  }
311 
312  /// @brief Advance to the next (valid) item.
313  bool next() { this->operator++(); return this->test(); }
314  bool increment() { this->next(); return this->test(); }
315 
316  /// Return the const filter
317  inline const FilterT& filter() const { return mFilter; }
318 
319  /// Return the coordinates of the item to which the value iterator is pointing.
320  inline Coord getCoord() const { assert(mIterator); return mIterator.getCoord(); }
321  /// Return in @a xyz the coordinates of the item to which the value iterator is pointing.
322  inline void getCoord(Coord& xyz) const { assert(mIterator); xyz = mIterator.getCoord(); }
323 
324  /// @brief Return @c true if the value iterator is pointing to an active value.
325  inline bool isValueOn() const { assert(mIterator); return mIterator.valueIter().isValueOn(); }
326 
327  /// @brief Equality operators
328  bool operator==(const IndexIter& other) const { return mIterator == other.mIterator; }
329  bool operator!=(const IndexIter& other) const { return !this->operator==(other); }
330 
331 private:
332  ValueIndexIter mIterator;
333  FilterT mFilter;
334 }; // class IndexIter
335 
336 
337 ////////////////////////////////////////
338 
339 
340 template <typename IterT>
341 inline Index64 iterCount(const IterT& iter)
342 {
343  Index64 size = 0;
344  for (IterT newIter(iter); newIter; ++newIter, ++size) { }
345  return size;
346 }
347 
348 
349 ////////////////////////////////////////
350 
351 
352 } // namespace points
353 } // namespace OPENVDB_VERSION_NAME
354 } // namespace openvdb
355 
356 #endif // OPENVDB_POINTS_INDEX_ITERATOR_HAS_BEEN_INCLUDED
357 
358 // Copyright (c) 2012-2018 DreamWorks Animation LLC
359 // All rights reserved. This software is distributed under the
360 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
static index::State state(const LeafT &)
Definition: IndexIterator.h:83
GLuint start
Definition: glcorearb.h:474
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:189
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:77
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)
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
GLsizeiptr size
Definition: glcorearb.h:663
Index32 operator*()
Return the item to which this iterator is currently pointing.
A forward iterator over array indices in a single voxel.
Definition: IndexIterator.h:91
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
GLuint GLuint end
Definition: glcorearb.h:474
GLintptr offset
Definition: glcorearb.h:664
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).
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Coord getCoord() const
For efficiency, Coord and active state assumed to be readily available when iterating over indices of...
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:785
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:135
bool operator==(const IndexIter &other) const
Equality operators.
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
bool operator==(const ValueVoxelCIter &other) const
Equality operators.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1296