OpenVDB  12.0.0
IndexFilter.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/IndexFilter.h
5 ///
6 /// @author Dan Bailey
7 ///
8 /// @brief Index filters primarily designed to be used with a FilterIndexIter.
9 ///
10 /// Filters must adhere to the interface described in the example below:
11 /// @code
12 /// struct MyFilter
13 /// {
14 /// // Return true when the filter has been initialized for first use
15 /// bool initialized() { return true; }
16 ///
17 /// // Return index::ALL if all points are valid, index::NONE if no points are valid
18 /// // and index::PARTIAL if some points are valid
19 /// index::State state() { return index::PARTIAL; }
20 ///
21 /// // Return index::ALL if all points in this leaf are valid, index::NONE if no points
22 /// // in this leaf are valid and index::PARTIAL if some points in this leaf are valid
23 /// template <typename LeafT>
24 /// index::State state(const LeafT&) { return index::PARTIAL; }
25 ///
26 /// // Resets the filter to refer to the specified leaf, all subsequent valid() calls
27 /// // will be relative to this leaf until reset() is called with a different leaf.
28 /// // Although a required method, many filters will provide an empty implementation if
29 /// // there is no leaf-specific logic needed.
30 /// template <typename LeafT> void reset(const LeafT&) { }
31 ///
32 /// // Returns true if the filter is valid for the supplied iterator
33 /// template <typename IterT> bool valid(const IterT&) { return true; }
34 /// };
35 /// @endcode
36 
37 #ifndef OPENVDB_POINTS_INDEX_FILTER_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_INDEX_FILTER_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/version.h>
41 #include <openvdb/Types.h>
42 
43 #include <openvdb/math/Transform.h>
45 #include <openvdb/util/Assert.h>
46 
47 #include "IndexIterator.h"
48 #include "AttributeArray.h"
49 #include "AttributeGroup.h"
50 #include "AttributeSet.h"
51 
52 #include <random> // std::mt19937
53 #include <numeric> // std::iota
54 #include <unordered_map>
55 
56 
57 class TestIndexFilter;
58 
59 namespace openvdb {
61 namespace OPENVDB_VERSION_NAME {
62 namespace points {
63 
64 
65 ////////////////////////////////////////
66 
67 /// @cond OPENVDB_DOCS_INTERNAL
68 
69 namespace index_filter_internal {
70 
71 
72 // generate a random subset of n indices from the range [0:m]
73 template <typename RandGenT, typename IntType>
74 std::vector<IntType>
75 generateRandomSubset(const unsigned int seed, const IntType n, const IntType m)
76 {
77  if (n <= 0) return std::vector<IntType>();
78 
79  // fill vector with ascending indices
80  std::vector<IntType> values(m);
81  std::iota(values.begin(), values.end(), 0);
82  if (n >= m) return values;
83 
84  // shuffle indices using random generator
85 
86  RandGenT randGen(seed);
87  std::shuffle(values.begin(), values.end(), randGen);
88 
89  // resize the container to n elements
90  values.resize(n);
91 
92  // sort the subset of the indices vector that will be used
93  std::sort(values.begin(), values.end());
94 
95  return values;
96 }
97 
98 
99 } // namespace index_filter_internal
100 
101 /// @endcond
102 
103 
104 /// Index filtering on active / inactive state of host voxel
105 template <bool On>
107 {
108 public:
109  static bool initialized() { return true; }
110  static index::State state() { return index::PARTIAL; }
111  template <typename LeafT>
112  static index::State state(const LeafT& leaf)
113  {
114  if (leaf.isDense()) return On ? index::ALL : index::NONE;
115  else if (leaf.isEmpty()) return On ? index::NONE : index::ALL;
116  return index::PARTIAL;
117  }
118 
119  template <typename LeafT>
120  void reset(const LeafT&) { }
121 
122  template <typename IterT>
123  bool valid(const IterT& iter) const
124  {
125  const bool valueOn = iter.isValueOn();
126  return On ? valueOn : !valueOn;
127  }
128 };
129 
130 
133 
134 
135 /// Index filtering on multiple group membership for inclusion and exclusion
136 ///
137 /// @note include filters are applied first, then exclude filters
139 {
140 public:
141  using NameVector = std::vector<Name>;
142  using IndexVector = std::vector<AttributeSet::Descriptor::GroupIndex>;
143  using HandleVector = std::vector<GroupHandle>;
144 
145 private:
146  static IndexVector namesToIndices(const AttributeSet& attributeSet, const NameVector& names) {
147  IndexVector indices;
148  for (const auto& name : names) {
149  try {
150  indices.emplace_back(attributeSet.groupIndex(name));
151  } catch (LookupError&) {
152  // silently drop group names that don't exist
153  }
154  }
155  return indices;
156  }
157 
158 public:
159  MultiGroupFilter( const NameVector& include,
160  const NameVector& exclude,
161  const AttributeSet& attributeSet)
162  : mInclude(MultiGroupFilter::namesToIndices(attributeSet, include))
163  , mExclude(MultiGroupFilter::namesToIndices(attributeSet, exclude)) { }
164 
165  MultiGroupFilter( const IndexVector& include,
166  const IndexVector& exclude)
167  : mInclude(include)
168  , mExclude(exclude) { }
169 
171  : mInclude(filter.mInclude)
172  , mExclude(filter.mExclude)
173  , mIncludeHandles(filter.mIncludeHandles)
174  , mExcludeHandles(filter.mExcludeHandles)
175  , mInitialized(filter.mInitialized) { }
176 
177  inline bool initialized() const { return mInitialized; }
178 
179  inline index::State state() const
180  {
181  return (mInclude.empty() && mExclude.empty()) ? index::ALL : index::PARTIAL;
182  }
183 
184  template <typename LeafT>
185  static index::State state(const LeafT&) { return index::PARTIAL; }
186 
187  template <typename LeafT>
188  void reset(const LeafT& leaf) {
189  mIncludeHandles.clear();
190  mExcludeHandles.clear();
191  for (const auto& i : mInclude) {
192  mIncludeHandles.emplace_back(leaf.groupHandle(i));
193  }
194  for (const auto& i : mExclude) {
195  mExcludeHandles.emplace_back(leaf.groupHandle(i));
196  }
197  mInitialized = true;
198  }
199 
200  template <typename IterT>
201  bool valid(const IterT& iter) const {
202  OPENVDB_ASSERT(mInitialized);
203  // accept no include filters as valid
204  bool includeValid = mIncludeHandles.empty();
205  for (const GroupHandle& handle : mIncludeHandles) {
206  if (handle.getUnsafe(*iter)) {
207  includeValid = true;
208  break;
209  }
210  }
211  if (!includeValid) return false;
212  for (const GroupHandle& handle : mExcludeHandles) {
213  if (handle.getUnsafe(*iter)) return false;
214  }
215  return true;
216  }
217 
218 private:
219  IndexVector mInclude;
220  IndexVector mExclude;
221  HandleVector mIncludeHandles;
222  HandleVector mExcludeHandles;
223  bool mInitialized = false;
224 }; // class MultiGroupFilter
225 
226 
227 // Random index filtering per leaf
228 template <typename PointDataTreeT, typename RandGenT>
230 {
231 public:
232  using SeedCountPair = std::pair<Index, Index>;
233  using LeafMap = std::unordered_map<openvdb::Coord, SeedCountPair>;
234 
235  RandomLeafFilter( const PointDataTreeT& tree,
236  const Index64 targetPoints,
237  const unsigned int seed = 0) {
238  Index64 currentPoints = 0;
239  for (auto iter = tree.cbeginLeaf(); iter; ++iter) {
240  currentPoints += iter->pointCount();
241  }
242 
243  const float factor = targetPoints > currentPoints ? 1.0f : float(targetPoints) / float(currentPoints);
244 
245  std::mt19937 generator(seed);
246  std::uniform_int_distribution<unsigned int> dist(0, std::numeric_limits<unsigned int>::max() - 1);
247 
248  Index64 leafCounter = 0;
249  float totalPointsFloat = 0.0f;
250  int totalPoints = 0;
251  for (auto iter = tree.cbeginLeaf(); iter; ++iter) {
252  // for the last leaf - use the remaining points to reach the target points
253  if (leafCounter + 1 == tree.leafCount()) {
254  const int leafPoints = static_cast<int>(targetPoints) - totalPoints;
255  mLeafMap[iter->origin()] = SeedCountPair(dist(generator), leafPoints);
256  break;
257  }
258  totalPointsFloat += factor * static_cast<float>(iter->pointCount());
259  const auto leafPoints = static_cast<int>(math::Floor(totalPointsFloat));
260  totalPointsFloat -= static_cast<float>(leafPoints);
261  totalPoints += leafPoints;
262 
263  mLeafMap[iter->origin()] = SeedCountPair(dist(generator), leafPoints);
264 
265  leafCounter++;
266  }
267  }
268 
269  inline bool initialized() const { return mNextIndex == -1; }
270 
271  static index::State state() { return index::PARTIAL; }
272  template <typename LeafT>
273  static index::State state(const LeafT&) { return index::PARTIAL; }
274 
275  template <typename LeafT>
276  void reset(const LeafT& leaf) {
277  using index_filter_internal::generateRandomSubset;
278 
279  auto it = mLeafMap.find(leaf.origin());
280  if (it == mLeafMap.end()) {
282  "Cannot find leaf origin in map for random filter - " << leaf.origin());
283  }
284 
285  const SeedCountPair& value = it->second;
286  const unsigned int seed = static_cast<unsigned int>(value.first);
287  const auto total = static_cast<Index>(leaf.pointCount());
288  mCount = std::min(value.second, total);
289 
290  mIndices = generateRandomSubset<RandGenT, int>(seed, mCount, total);
291 
292  mSubsetOffset = -1;
293  mNextIndex = -1;
294  }
295 
296  inline void next() const {
297  mSubsetOffset++;
298  mNextIndex = mSubsetOffset >= mCount ?
300  mIndices[mSubsetOffset];
301  }
302 
303  template <typename IterT>
304  bool valid(const IterT& iter) const {
305  const int index = *iter;
306  while (mNextIndex < index) this->next();
307  return mNextIndex == index;
308  }
309 
310 protected:
311  friend class ::TestIndexFilter;
312 
313 private:
314  LeafMap mLeafMap;
315  std::vector<int> mIndices;
316  int mCount = 0;
317  mutable int mSubsetOffset = -1;
318  mutable int mNextIndex = -1;
319 }; // class RandomLeafFilter
320 
321 
322 // Hash attribute value for deterministic, but approximate filtering
323 template <typename RandGenT, typename IntType>
325 {
326 public:
328 
329  AttributeHashFilter(const size_t index,
330  const double percentage,
331  const unsigned int seed = 0)
332  : mIndex(index)
333  , mFactor(percentage / 100.0)
334  , mSeed(seed) { }
335 
337  : mIndex(filter.mIndex)
338  , mFactor(filter.mFactor)
339  , mSeed(filter.mSeed)
340  {
341  if (filter.mIdHandle) mIdHandle.reset(new Handle(*filter.mIdHandle));
342  }
343 
344  inline bool initialized() const { return bool(mIdHandle); }
345 
346  static index::State state() { return index::PARTIAL; }
347  template <typename LeafT>
348  static index::State state(const LeafT&) { return index::PARTIAL; }
349 
350  template <typename LeafT>
351  void reset(const LeafT& leaf) {
352  OPENVDB_ASSERT(leaf.hasAttribute(mIndex));
353  mIdHandle.reset(new Handle(leaf.constAttributeArray(mIndex)));
354  }
355 
356  template <typename IterT>
357  bool valid(const IterT& iter) const {
358  OPENVDB_ASSERT(mIdHandle);
359  const IntType id = mIdHandle->get(*iter);
360  const unsigned int seed = mSeed + static_cast<unsigned int>(id);
361  RandGenT generator(seed);
362  std::uniform_real_distribution<double> dist(0.0, 1.0);
363  return dist(generator) < mFactor;
364  }
365 
366 private:
367  const size_t mIndex;
368  const double mFactor;
369  const unsigned int mSeed;
370  typename Handle::UniquePtr mIdHandle;
371 }; // class AttributeHashFilter
372 
373 
374 template <typename LevelSetGridT>
376 {
377 public:
378  using ValueT = typename LevelSetGridT::ValueType;
380 
381  LevelSetFilter( const LevelSetGridT& grid,
382  const math::Transform& transform,
383  const ValueT min,
384  const ValueT max)
385  : mAccessor(grid.getConstAccessor())
386  , mLevelSetTransform(grid.transform())
387  , mTransform(transform)
388  , mMin(min)
389  , mMax(max) { }
390 
392  : mAccessor(filter.mAccessor)
393  , mLevelSetTransform(filter.mLevelSetTransform)
394  , mTransform(filter.mTransform)
395  , mMin(filter.mMin)
396  , mMax(filter.mMax)
397  {
398  if (filter.mPositionHandle) mPositionHandle.reset(new Handle(*filter.mPositionHandle));
399  }
400 
401  inline bool initialized() const { return bool(mPositionHandle); }
402 
403  static index::State state() { return index::PARTIAL; }
404  template <typename LeafT>
405  static index::State state(const LeafT&) { return index::PARTIAL; }
406 
407  template <typename LeafT>
408  void reset(const LeafT& leaf) {
409  mPositionHandle.reset(new Handle(leaf.constAttributeArray("P")));
410  }
411 
412  template <typename IterT>
413  bool valid(const IterT& iter) const {
414  OPENVDB_ASSERT(mPositionHandle);
415  OPENVDB_ASSERT(iter);
416 
417  const openvdb::Coord ijk = iter.getCoord();
418  const openvdb::Vec3f voxelIndexSpace = ijk.asVec3d();
419 
420  // Retrieve point position in voxel space
421  const openvdb::Vec3f& pointVoxelSpace = mPositionHandle->get(*iter);
422 
423  // Compute point position in index space
424  const openvdb::Vec3f pointWorldSpace = mTransform.indexToWorld(pointVoxelSpace + voxelIndexSpace);
425  const openvdb::Vec3f pointIndexSpace = mLevelSetTransform.worldToIndex(pointWorldSpace);
426 
427  // Perform level-set sampling
428  const typename LevelSetGridT::ValueType value = tools::BoxSampler::sample(mAccessor, pointIndexSpace);
429 
430  // if min is greater than max, we invert so that values are valid outside of the range (not inside)
431  const bool invert = mMin > mMax;
432 
433  return invert ? (value < mMax || value > mMin) : (value < mMax && value > mMin);
434  }
435 
436 private:
437  // not a reference to ensure const-accessor is unique per-thread
438  const typename LevelSetGridT::ConstAccessor mAccessor;
439  const math::Transform& mLevelSetTransform;
440  const math::Transform& mTransform;
441  const ValueT mMin;
442  const ValueT mMax;
443  Handle::UniquePtr mPositionHandle;
444 }; // class LevelSetFilter
445 
446 
447 // BBox index filtering
449 {
450 public:
452 
453  BBoxFilter(const openvdb::math::Transform& transform,
454  const openvdb::BBoxd& bboxWS)
455  : mTransform(transform)
456  , mBbox(transform.worldToIndex(bboxWS)) { }
457 
458  BBoxFilter(const BBoxFilter& filter)
459  : mTransform(filter.mTransform)
460  , mBbox(filter.mBbox)
461  {
462  if (filter.mPositionHandle) mPositionHandle.reset(new Handle(*filter.mPositionHandle));
463  }
464 
465  inline bool initialized() const { return bool(mPositionHandle); }
466 
467  inline index::State state() const
468  {
469  return mBbox.empty() ? index::NONE : index::PARTIAL;
470  }
471  template <typename LeafT>
472  static index::State state(const LeafT&) { return index::PARTIAL; }
473 
474  template <typename LeafT>
475  void reset(const LeafT& leaf) {
476  mPositionHandle.reset(new Handle(leaf.constAttributeArray("P")));
477  }
478 
479  template <typename IterT>
480  bool valid(const IterT& iter) const {
481  OPENVDB_ASSERT(mPositionHandle);
482 
483  const openvdb::Coord ijk = iter.getCoord();
484  const openvdb::Vec3f voxelIndexSpace = ijk.asVec3d();
485 
486  // Retrieve point position in voxel space
487  const openvdb::Vec3f& pointVoxelSpace = mPositionHandle->get(*iter);
488 
489  // Compute point position in index space
490  const openvdb::Vec3f pointIndexSpace = pointVoxelSpace + voxelIndexSpace;
491 
492  return mBbox.isInside(pointIndexSpace);
493  }
494 
495 private:
496  const openvdb::math::Transform& mTransform;
497  const openvdb::BBoxd mBbox;
498  Handle::UniquePtr mPositionHandle;
499 }; // class BBoxFilter
500 
501 
502 // Index filtering based on evaluating both sub-filters
503 template <typename T1, typename T2, bool And = true>
505 {
506 public:
507  BinaryFilter( const T1& filter1,
508  const T2& filter2)
509  : mFilter1(filter1)
510  , mFilter2(filter2) { }
511 
512  inline bool initialized() const { return mFilter1.initialized() && mFilter2.initialized(); }
513 
514  inline index::State state() const
515  {
516  return this->computeState(mFilter1.state(), mFilter2.state());
517  }
518  template <typename LeafT>
519  inline index::State state(const LeafT& leaf) const
520  {
521  return this->computeState(mFilter1.state(leaf), mFilter2.state(leaf));
522  }
523 
524  template <typename LeafT>
525  void reset(const LeafT& leaf) {
526  mFilter1.reset(leaf);
527  mFilter2.reset(leaf);
528  }
529 
530  template <typename IterT>
531  bool valid(const IterT& iter) const {
532  if (And) return mFilter1.valid(iter) && mFilter2.valid(iter);
533  return mFilter1.valid(iter) || mFilter2.valid(iter);
534  }
535 
536 private:
537  inline index::State computeState( index::State state1,
538  index::State state2) const
539  {
540  if (And) {
541  if (state1 == index::NONE || state2 == index::NONE) return index::NONE;
542  else if (state1 == index::ALL && state2 == index::ALL) return index::ALL;
543  } else {
544  if (state1 == index::NONE && state2 == index::NONE) return index::NONE;
545  else if (state1 == index::ALL && state2 == index::ALL) return index::ALL;
546  }
547  return index::PARTIAL;
548  }
549 
550  T1 mFilter1;
551  T2 mFilter2;
552 }; // class BinaryFilter
553 
554 
555 ////////////////////////////////////////
556 
557 
558 template<typename T>
559 struct FilterTraits {
560  static const bool RequiresCoord = false;
561 };
562 template<>
564  static const bool RequiresCoord = true;
565 };
566 template <typename T>
568  static const bool RequiresCoord = true;
569 };
570 template <typename T0, typename T1, bool And>
571 struct FilterTraits<BinaryFilter<T0, T1, And>> {
572  static const bool RequiresCoord = FilterTraits<T0>::RequiresCoord ||
574 };
575 
576 
577 ////////////////////////////////////////
578 
579 
580 } // namespace points
581 } // namespace OPENVDB_VERSION_NAME
582 } // namespace openvdb
583 
584 #endif // OPENVDB_POINTS_INDEX_FILTER_HAS_BEEN_INCLUDED
Definition: IndexFilter.h:324
Definition: IndexFilter.h:375
std::unordered_map< openvdb::Coord, SeedCountPair > LeafMap
Definition: IndexFilter.h:233
static bool initialized()
Definition: IndexFilter.h:109
bool valid(const IterT &iter) const
Definition: IndexFilter.h:201
Attribute Group access and filtering for iteration.
Definition: Exceptions.h:60
LevelSetFilter(const LevelSetGridT &grid, const math::Transform &transform, const ValueT min, const ValueT max)
Definition: IndexFilter.h:381
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
static index::State state()
Definition: IndexFilter.h:403
bool valid(const IterT &iter) const
Definition: IndexFilter.h:357
uint64_t Index64
Definition: Types.h:53
index::State state() const
Definition: IndexFilter.h:179
void reset(const LeafT &leaf)
Definition: IndexFilter.h:408
bool valid(const IterT &iter) const
Definition: IndexFilter.h:531
static index::State state(const LeafT &leaf)
Definition: IndexFilter.h:112
Definition: IndexFilter.h:138
AttributeHashFilter(const size_t index, const double percentage, const unsigned int seed=0)
Definition: IndexFilter.h:329
static index::State state(const LeafT &)
Definition: IndexFilter.h:273
Attribute Array storage templated on type and compression codec.
BBoxFilter(const BBoxFilter &filter)
Definition: IndexFilter.h:458
bool valid(const IterT &iter) const
Definition: IndexFilter.h:480
AttributeHashFilter(const AttributeHashFilter &filter)
Definition: IndexFilter.h:336
void reset(const LeafT &leaf)
Definition: IndexFilter.h:276
std::unique_ptr< Handle > UniquePtr
Definition: AttributeArray.h:768
Index filtering on active / inactive state of host voxel.
Definition: IndexFilter.h:106
static index::State state()
Definition: IndexFilter.h:110
Definition: AttributeArray.h:763
MultiGroupFilter(const MultiGroupFilter &filter)
Definition: IndexFilter.h:170
Definition: IndexFilter.h:448
void reset(const LeafT &leaf)
Definition: IndexFilter.h:351
Index32 Index
Definition: Types.h:54
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:110
index::State state() const
Definition: IndexFilter.h:514
bool initialized() const
Definition: IndexFilter.h:177
Definition: IndexIterator.h:44
bool initialized() const
Definition: IndexFilter.h:465
BBoxFilter(const openvdb::math::Transform &transform, const openvdb::BBoxd &bboxWS)
Definition: IndexFilter.h:453
Definition: IndexIterator.h:43
Definition: AttributeGroup.h:73
LevelSetFilter(const LevelSetFilter &filter)
Definition: IndexFilter.h:391
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
Definition: IndexFilter.h:504
void reset(const LeafT &)
Definition: IndexFilter.h:120
bool valid(const IterT &iter) const
Definition: IndexFilter.h:413
static index::State state()
Definition: IndexFilter.h:346
std::pair< Index, Index > SeedCountPair
Definition: IndexFilter.h:232
int Floor(float x)
Return the floor of x.
Definition: Math.h:848
void next() const
Definition: IndexFilter.h:296
static index::State state()
Definition: IndexFilter.h:271
Definition: Exceptions.h:13
std::vector< Name > NameVector
Definition: IndexFilter.h:141
MultiGroupFilter(const NameVector &include, const NameVector &exclude, const AttributeSet &attributeSet)
Definition: IndexFilter.h:159
bool valid(const IterT &iter) const
Definition: IndexFilter.h:304
void reset(const LeafT &leaf)
Definition: IndexFilter.h:475
RandomLeafFilter(const PointDataTreeT &tree, const Index64 targetPoints, const unsigned int seed=0)
Definition: IndexFilter.h:235
Index Iterators.
Definition: Mat.h:165
OutGridT const XformOp bool bool
Definition: ValueTransformer.h:609
bool initialized() const
Definition: IndexFilter.h:344
Definition: IndexFilter.h:559
State
Definition: IndexIterator.h:40
Definition: IndexFilter.h:229
bool initialized() const
Definition: IndexFilter.h:401
MultiGroupFilter(const IndexVector &include, const IndexVector &exclude)
Definition: IndexFilter.h:165
void reset(const LeafT &leaf)
Definition: IndexFilter.h:525
bool valid(const IterT &iter) const
Definition: IndexFilter.h:123
void reset(const LeafT &leaf)
Definition: IndexFilter.h:188
Definition: Transform.h:39
index::State state() const
Definition: IndexFilter.h:467
std::vector< GroupHandle > HandleVector
Definition: IndexFilter.h:143
std::vector< AttributeSet::Descriptor::GroupIndex > IndexVector
Definition: IndexFilter.h:142
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:106
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:39
bool initialized() const
Definition: IndexFilter.h:512
static index::State state(const LeafT &)
Definition: IndexFilter.h:185
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
Definition: IndexIterator.h:42
bool initialized() const
Definition: IndexFilter.h:269
static index::State state(const LeafT &)
Definition: IndexFilter.h:472
Set of Attribute Arrays which tracks metadata about each array.
static index::State state(const LeafT &)
Definition: IndexFilter.h:348
index::State state(const LeafT &leaf) const
Definition: IndexFilter.h:519
typename LevelSetGridT::ValueType ValueT
Definition: IndexFilter.h:378
Definition: Exceptions.h:59
BinaryFilter(const T1 &filter1, const T2 &filter2)
Definition: IndexFilter.h:507
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218
static index::State state(const LeafT &)
Definition: IndexFilter.h:405