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