Loading...
Searching...
No Matches
IndexIterator.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
/// @file points/IndexIterator.h
///
/// @author Dan Bailey
///
/// @brief Index Iterators.
#ifndef OPENVDB_POINTS_INDEX_ITERATOR_HAS_BEEN_INCLUDED
#define OPENVDB_POINTS_INDEX_ITERATOR_HAS_BEEN_INCLUDED
#include <openvdb/version.h>
#include <openvdb/Types.h>
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace points {
/// @brief Count up the number of times the iterator can iterate
///
/// @param iter the iterator.
///
/// @note counting by iteration only performed where a dynamic filter is in use,
template <typename IterT>
inline Index64 iterCount(const IterT& iter);
////////////////////////////////////////
namespace index {
// Enum for informing early-exit optimizations
// PARTIAL - No optimizations are possible
// NONE - No indices to evaluate, can skip computation
// ALL - All indices to evaluate, can skip filtering
enum State
{
PARTIAL=0,
NONE,
ALL
};
}
/// @brief A no-op filter that can be used when iterating over all indices
/// @see points/IndexFilter.h for the documented interface for an index filter
class NullFilter
{
public:
static bool initialized() { return true; }
static index::State state() { return index::ALL; }
template <typename LeafT>
static index::State state(const LeafT&) { return index::ALL; }
template <typename LeafT> void reset(const LeafT&) { }
template <typename IterT> static bool valid(const IterT&) { return true; }
}; // class NullFilter
/// @brief A forward iterator over array indices in a single voxel
class ValueVoxelCIter
{
public:
struct Parent
{
Parent() = default;
explicit Parent(Index32 offset): mOffset(offset) { }
Index32 getValue(unsigned /*offset*/) const { return mOffset; }
private:
Index32 mOffset = 0;
}; // struct Parent
using NodeType = Parent;
ValueVoxelCIter() = default;
ValueVoxelCIter(Index32 prevOffset, Index32 offset)
: mOffset(offset), mParent(prevOffset) {}
ValueVoxelCIter(const ValueVoxelCIter& other)
: mOffset(other.mOffset), mParent(other.mParent), mValid(other.mValid) {}
/// @brief Return the item to which this iterator is currently pointing.
Index32 operator*() { return mOffset; }
Index32 operator*() const { return mOffset; }
/// @brief Advance to the next (valid) item (prefix).
ValueVoxelCIter& operator++() { mValid = false; return *this; }
operator bool() const { return mValid; }
bool test() const { return mValid; }
Index32 end() const { return mOffset+1; }
void reset(Index32 /*item*/, Index32 /*end*/) {}
Parent& parent() { return mParent; }
Index32 offset() { return mOffset; }
inline bool next() { this->operator++(); return this->test(); }
/// @brief For efficiency, Coord and active state assumed to be readily available
/// when iterating over indices of a single voxel
Coord getCoord [[noreturn]] () const {
OPENVDB_THROW(RuntimeError, "ValueVoxelCIter does not provide a valid Coord.");
}
void getCoord [[noreturn]] (Coord& /*coord*/) const {
OPENVDB_THROW(RuntimeError, "ValueVoxelCIter does not provide a valid Coord.");
}
bool isValueOn [[noreturn]] () const {
OPENVDB_THROW(RuntimeError, "ValueVoxelCIter does not test if voxel is active.");
}
/// @{
/// @brief Equality operators
bool operator==(const ValueVoxelCIter& other) const { return mOffset == other.mOffset; }
bool operator!=(const ValueVoxelCIter& other) const { return !this->operator==(other); }
/// @}
private:
Index32 mOffset = 0;
Parent mParent;
mutable bool mValid = true;
}; // class ValueVoxelCIter
/// @brief A forward iterator over array indices with filtering
/// IteratorT can be either IndexIter or ValueIndexIter (or some custom index iterator)
/// FilterT should be a struct or class with a valid() method than can be evaluated per index
/// Here's a simple filter example that only accepts even indices:
///
/// struct EvenIndexFilter
/// {
/// bool valid(const Index32 offset) const {
/// return (offset % 2) == 0;
/// }
/// };
///
template <typename IteratorT, typename FilterT>
class IndexIter
{
public:
/// @brief A forward iterator over array indices from a value iterator (such as ValueOnCIter)
class ValueIndexIter
{
public:
ValueIndexIter(const IteratorT& iter)
: mIter(iter), mParent(&mIter.parent())
{
if (mIter) {
assert(mParent);
Index32 start = (mIter.offset() > 0 ?
Index32(mParent->getValue(mIter.offset() - 1)) : Index32(0));
this->reset(start, *mIter);
if (mItem >= mEnd) this->operator++();
}
}
ValueIndexIter(const ValueIndexIter& other)
: mEnd(other.mEnd), mItem(other.mItem), mIter(other.mIter), mParent(other.mParent)
{
assert(mParent);
}
ValueIndexIter& operator=(const ValueIndexIter&) = default;
inline Index32 end() const { return mEnd; }
inline void reset(Index32 item, Index32 end) {
mItem = item;
mEnd = end;
}
/// @brief Returns the item to which this iterator is currently pointing.
inline Index32 operator*() { assert(mIter); return mItem; }
inline Index32 operator*() const { assert(mIter); return mItem; }
/// @brief Return @c true if this iterator is not yet exhausted.
inline operator bool() const { return mIter; }
inline bool test() const { return mIter; }
/// @brief Advance to the next (valid) item (prefix).
inline ValueIndexIter& operator++() {
++mItem;
while (mItem >= mEnd && mIter.next()) {
assert(mParent);
this->reset(mParent->getValue(mIter.offset() - 1), *mIter);
}
return *this;
}
/// @brief Advance to the next (valid) item.
inline bool next() { this->operator++(); return this->test(); }
inline bool increment() { this->next(); return this->test(); }
/// Return the coordinates of the item to which the value iterator is pointing.
inline Coord getCoord() const { assert(mIter); return mIter.getCoord(); }
/// Return in @a xyz the coordinates of the item to which the value iterator is pointing.
inline void getCoord(Coord& xyz) const { assert(mIter); xyz = mIter.getCoord(); }
/// @brief Return @c true if this iterator is pointing to an active value.
inline bool isValueOn() const { assert(mIter); return mIter.isValueOn(); }
/// Return the const value iterator
inline const IteratorT& valueIter() const { return mIter; }
/// @brief Equality operators
bool operator==(const ValueIndexIter& other) const { return mItem == other.mItem; }
bool operator!=(const ValueIndexIter& other) const { return !this->operator==(other); }
private:
Index32 mEnd = 0;
Index32 mItem = 0;
IteratorT mIter;
const typename IteratorT::NodeType* mParent;
}; // ValueIndexIter
IndexIter(const IteratorT& iterator, const FilterT& filter)
: mIterator(iterator)
, mFilter(filter)
{
if (!mFilter.initialized()) {
OPENVDB_THROW(RuntimeError,
"Filter needs to be initialized before constructing the iterator.");
}
if (mIterator) {
this->reset(*mIterator, mIterator.end());
}
}
IndexIter(const IndexIter& other)
: mIterator(other.mIterator)
, mFilter(other.mFilter)
{
if (!mFilter.initialized()) {
OPENVDB_THROW(RuntimeError,
"Filter needs to be initialized before constructing the iterator.");
}
}
IndexIter& operator=(const IndexIter& other)
{
if (&other != this) {
mIterator = other.mIterator;
mFilter = other.mFilter;
if (!mFilter.initialized()) {
OPENVDB_THROW(RuntimeError,
"Filter needs to be initialized before constructing the iterator.");
}
}
return *this;
}
Index32 end() const { return mIterator.end(); }
/// @brief Reset the begining and end of the iterator.
void reset(Index32 begin, Index32 end) {
mIterator.reset(begin, end);
while (mIterator.test() && !mFilter.template valid<ValueIndexIter>(mIterator)) {
++mIterator;
}
}
/// @brief Returns the item to which this iterator is currently pointing.
Index32 operator*() { assert(mIterator); return *mIterator; }
Index32 operator*() const { assert(mIterator); return *mIterator; }
/// @brief Return @c true if this iterator is not yet exhausted.
operator bool() const { return mIterator.test(); }
bool test() const { return mIterator.test(); }
/// @brief Advance to the next (valid) item (prefix).
IndexIter& operator++() {
while (true) {
++mIterator;
if (!mIterator.test() || mFilter.template valid<ValueIndexIter>(mIterator)) {
break;
}
}
return *this;
}
/// @brief Advance to the next (valid) item (postfix).
IndexIter operator++(int /*dummy*/) {
IndexIter newIterator(*this);
this->operator++();
return newIterator;
}
/// @brief Advance to the next (valid) item.
bool next() { this->operator++(); return this->test(); }
bool increment() { this->next(); return this->test(); }
/// Return the const filter
inline const FilterT& filter() const { return mFilter; }
/// Return the coordinates of the item to which the value iterator is pointing.
inline Coord getCoord() const { assert(mIterator); return mIterator.getCoord(); }
/// Return in @a xyz the coordinates of the item to which the value iterator is pointing.
inline void getCoord(Coord& xyz) const { assert(mIterator); xyz = mIterator.getCoord(); }
/// @brief Return @c true if the value iterator is pointing to an active value.
inline bool isValueOn() const { assert(mIterator); return mIterator.valueIter().isValueOn(); }
/// @brief Equality operators
bool operator==(const IndexIter& other) const { return mIterator == other.mIterator; }
bool operator!=(const IndexIter& other) const { return !this->operator==(other); }
private:
ValueIndexIter mIterator;
FilterT mFilter;
}; // class IndexIter
////////////////////////////////////////
template <typename IterT>
inline Index64 iterCount(const IterT& iter)
{
Index64 size = 0;
for (IterT newIter(iter); newIter; ++newIter, ++size) { }
return size;
}
////////////////////////////////////////
} // namespace points
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb
#endif // OPENVDB_POINTS_INDEX_ITERATOR_HAS_BEEN_INCLUDED
openvdb::v10_0::RuntimeError
Definition Exceptions.h:63
openvdb::v10_0::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
openvdb::v10_0::points::IndexIter::ValueIndexIter::increment
bool increment()
Definition IndexIterator.h:191
openvdb::v10_0::points::IndexIter::ValueIndexIter::ValueIndexIter
ValueIndexIter(const IteratorT &iter)
Definition IndexIterator.h:146
openvdb::v10_0::points::IndexIter::ValueIndexIter::isValueOn
bool isValueOn() const
Return true if this iterator is pointing to an active value.
Definition IndexIterator.h:199
openvdb::v10_0::points::IndexIter::ValueIndexIter::operator==
bool operator==(const ValueIndexIter &other) const
Equality operators.
Definition IndexIterator.h:205
openvdb::v10_0::points::IndexIter::ValueIndexIter::getCoord
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
Definition IndexIterator.h:194
openvdb::v10_0::points::IndexIter::ValueIndexIter::test
bool test() const
Definition IndexIterator.h:177
openvdb::v10_0::points::IndexIter::ValueIndexIter::operator!=
bool operator!=(const ValueIndexIter &other) const
Definition IndexIterator.h:206
openvdb::v10_0::points::IndexIter::ValueIndexIter::end
Index32 end() const
Definition IndexIterator.h:164
openvdb::v10_0::points::IndexIter::ValueIndexIter::operator++
ValueIndexIter & operator++()
Advance to the next (valid) item (prefix).
Definition IndexIterator.h:180
openvdb::v10_0::points::IndexIter::ValueIndexIter::operator*
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Definition IndexIterator.h:172
openvdb::v10_0::points::IndexIter::ValueIndexIter::next
bool next()
Advance to the next (valid) item.
Definition IndexIterator.h:190
openvdb::v10_0::points::IndexIter::ValueIndexIter::getCoord
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Definition IndexIterator.h:196
openvdb::v10_0::points::IndexIter::ValueIndexIter::valueIter
const IteratorT & valueIter() const
Return the const value iterator.
Definition IndexIterator.h:202
openvdb::v10_0::points::IndexIter::ValueIndexIter::ValueIndexIter
ValueIndexIter(const ValueIndexIter &other)
Definition IndexIterator.h:157
openvdb::v10_0::points::IndexIter::ValueIndexIter::reset
void reset(Index32 item, Index32 end)
Definition IndexIterator.h:166
openvdb::v10_0::points::IndexIter::ValueIndexIter::operator*
Index32 operator*() const
Definition IndexIterator.h:173
openvdb::v10_0::points::IndexIter::ValueIndexIter::operator=
ValueIndexIter & operator=(const ValueIndexIter &)=default
openvdb::v10_0::points::IndexIter::IndexIter
IndexIter(const IndexIter &other)
Definition IndexIterator.h:227
openvdb::v10_0::points::IndexIter::increment
bool increment()
Definition IndexIterator.h:287
openvdb::v10_0::points::IndexIter::isValueOn
bool isValueOn() const
Return true if the value iterator is pointing to an active value.
Definition IndexIterator.h:298
openvdb::v10_0::points::IndexIter::getCoord
Coord getCoord() const
Return the coordinates of the item to which the value iterator is pointing.
Definition IndexIterator.h:293
openvdb::v10_0::points::IndexIter::operator==
bool operator==(const IndexIter &other) const
Equality operators.
Definition IndexIterator.h:301
openvdb::v10_0::points::IndexIter::test
bool test() const
Definition IndexIterator.h:265
openvdb::v10_0::points::IndexIter::operator!=
bool operator!=(const IndexIter &other) const
Definition IndexIterator.h:302
openvdb::v10_0::points::IndexIter::operator++
IndexIter operator++(int)
Advance to the next (valid) item (postfix).
Definition IndexIterator.h:279
openvdb::v10_0::points::IndexIter::operator++
IndexIter & operator++()
Advance to the next (valid) item (prefix).
Definition IndexIterator.h:268
openvdb::v10_0::points::IndexIter< ValueVoxelCIter, NullFilter >::reset
void reset(Index32 begin, Index32 end)
Definition IndexIterator.h:252
openvdb::v10_0::points::IndexIter::end
Index32 end() const
Definition IndexIterator.h:249
openvdb::v10_0::points::IndexIter::operator*
Index32 operator*()
Returns the item to which this iterator is currently pointing.
Definition IndexIterator.h:260
openvdb::v10_0::points::IndexIter::next
bool next()
Advance to the next (valid) item.
Definition IndexIterator.h:286
openvdb::v10_0::points::IndexIter::IndexIter
IndexIter(const IteratorT &iterator, const FilterT &filter)
Definition IndexIterator.h:215
openvdb::v10_0::points::IndexIter::operator=
IndexIter & operator=(const IndexIter &other)
Definition IndexIterator.h:236
openvdb::v10_0::points::IndexIter::getCoord
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which the value iterator is pointing.
Definition IndexIterator.h:295
openvdb::v10_0::points::IndexIter< ValueVoxelCIter, NullFilter >::filter
const NullFilter & filter() const
Definition IndexIterator.h:290
openvdb::v10_0::points::IndexIter::operator*
Index32 operator*() const
Definition IndexIterator.h:261
openvdb::v10_0::points::NullFilter
A no-op filter that can be used when iterating over all indices.
Definition IndexIterator.h:51
openvdb::v10_0::points::NullFilter::state
static index::State state()
Definition IndexIterator.h:54
openvdb::v10_0::points::NullFilter::state
static index::State state(const LeafT &)
Definition IndexIterator.h:56
openvdb::v10_0::points::NullFilter::initialized
static bool initialized()
Definition IndexIterator.h:53
openvdb::v10_0::points::NullFilter::valid
static bool valid(const IterT &)
Definition IndexIterator.h:59
openvdb::v10_0::points::NullFilter::reset
void reset(const LeafT &)
Definition IndexIterator.h:58
openvdb::v10_0::points::ValueVoxelCIter::ValueVoxelCIter
ValueVoxelCIter()=default
openvdb::v10_0::points::ValueVoxelCIter::operator==
bool operator==(const ValueVoxelCIter &other) const
Equality operators.
Definition IndexIterator.h:115
openvdb::v10_0::points::ValueVoxelCIter::isValueOn
bool isValueOn() const
Definition IndexIterator.h:109
openvdb::v10_0::points::ValueVoxelCIter::ValueVoxelCIter
ValueVoxelCIter(Index32 prevOffset, Index32 offset)
Definition IndexIterator.h:79
openvdb::v10_0::points::ValueVoxelCIter::getCoord
Coord getCoord() const
For efficiency, Coord and active state assumed to be readily available when iterating over indices of...
Definition IndexIterator.h:103
openvdb::v10_0::points::ValueVoxelCIter::test
bool test() const
Definition IndexIterator.h:92
openvdb::v10_0::points::ValueVoxelCIter::ValueVoxelCIter
ValueVoxelCIter(const ValueVoxelCIter &other)
Definition IndexIterator.h:81
openvdb::v10_0::points::ValueVoxelCIter::end
Index32 end() const
Definition IndexIterator.h:93
openvdb::v10_0::points::ValueVoxelCIter::operator*
Index32 operator*()
Return the item to which this iterator is currently pointing.
Definition IndexIterator.h:85
openvdb::v10_0::points::ValueVoxelCIter::offset
Index32 offset()
Definition IndexIterator.h:98
openvdb::v10_0::points::ValueVoxelCIter::operator++
ValueVoxelCIter & operator++()
Advance to the next (valid) item (prefix).
Definition IndexIterator.h:89
openvdb::v10_0::points::ValueVoxelCIter::next
bool next()
Definition IndexIterator.h:99
openvdb::v10_0::points::ValueVoxelCIter::operator!=
bool operator!=(const ValueVoxelCIter &other) const
Equality operators.
Definition IndexIterator.h:116
openvdb::v10_0::points::ValueVoxelCIter::NodeType
Parent NodeType
Definition IndexIterator.h:76
openvdb::v10_0::points::ValueVoxelCIter::parent
Parent & parent()
Definition IndexIterator.h:97
openvdb::v10_0::points::ValueVoxelCIter::reset
void reset(Index32, Index32)
Definition IndexIterator.h:95
openvdb::v10_0::points::ValueVoxelCIter::operator*
Index32 operator*() const
Definition IndexIterator.h:86
openvdb::v10_0::points::index
Definition IndexIterator.h:34
openvdb::v10_0::points::index::State
State
Definition IndexIterator.h:40
openvdb::v10_0::points::index::PARTIAL
@ PARTIAL
Definition IndexIterator.h:41
openvdb::v10_0::points::index::ALL
@ ALL
Definition IndexIterator.h:43
openvdb::v10_0::points::index::NONE
@ NONE
Definition IndexIterator.h:42
openvdb::v10_0::points::iterCount
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition IndexIterator.h:314
openvdb::v10_0::Index32
uint32_t Index32
Definition Types.h:52
openvdb::v10_0::Index64
uint64_t Index64
Definition Types.h:53
openvdb
Definition Exceptions.h:13
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Types.h
openvdb::v10_0::points::ValueVoxelCIter::Parent
Definition IndexIterator.h:68
openvdb::v10_0::points::ValueVoxelCIter::Parent::getValue
Index32 getValue(unsigned) const
Definition IndexIterator.h:71
openvdb::v10_0::points::ValueVoxelCIter::Parent::Parent
Parent(Index32 offset)
Definition IndexIterator.h:70
openvdb::v10_0::points::ValueVoxelCIter::Parent::Parent
Parent()=default
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212