52 #ifndef OPENVDB_TOOLS_PARTICLE_ATLAS_HAS_BEEN_INCLUDED 53 #define OPENVDB_TOOLS_PARTICLE_ATLAS_HAS_BEEN_INCLUDED 57 #include <openvdb/Grid.h> 58 #include <openvdb/Types.h> 59 #include <openvdb/math/Transform.h> 60 #include <openvdb/tree/Tree.h> 61 #include <openvdb/tree/LeafNode.h> 63 #include <tbb/blocked_range.h> 64 #include <tbb/parallel_for.h> 65 #include <tbb/parallel_reduce.h> 109 template<
typename Po
intIndexGr
idType = Po
intIndexGr
id>
116 using IndexType =
typename PointIndexGridType::ValueType;
122 ParticleAtlas() : mIndexGridArray(), mMinRadiusArray(), mMaxRadiusArray() {}
129 template<
typename ParticleArrayType>
130 void construct(
const ParticleArrayType& particles,
double minVoxelSize,
size_t maxLevels = 50);
137 template<
typename ParticleArrayType>
138 static Ptr create(
const ParticleArrayType& particles,
139 double minVoxelSize,
size_t maxLevels = 50);
142 size_t levels()
const {
return mIndexGridArray.size(); }
144 bool empty()
const {
return mIndexGridArray.empty(); }
147 double minRadius(
size_t n)
const {
return mMinRadiusArray[n]; }
149 double maxRadius(
size_t n)
const {
return mMaxRadiusArray[n]; }
154 const PointIndexGridType&
pointIndexGrid(
size_t n)
const {
return *mIndexGridArray[n]; }
161 std::vector<PointIndexGridPtr> mIndexGridArray;
162 std::vector<double> mMinRadiusArray, mMaxRadiusArray;
177 template<
typename Po
intIndexGr
idType>
180 using TreeType =
typename PointIndexGridType::TreeType;
194 template<
typename ParticleArrayType>
195 void worldSpaceSearchAndUpdate(
const Vec3d& center,
double radius,
196 const ParticleArrayType& particles);
202 template<
typename ParticleArrayType>
203 void worldSpaceSearchAndUpdate(
const BBoxd& bbox,
const ParticleArrayType& particles);
206 size_t levels()
const {
return mAtlas->levels(); }
210 void updateFromLevel(
size_t level);
220 bool test()
const {
return mRange.first < mRange.second || mIter != mRangeList.end(); }
221 operator bool()
const {
return this->test(); }
247 using Range = std::pair<const IndexType*, const IndexType*>;
248 using RangeDeque = std::deque<Range>;
249 using RangeDequeCIter =
typename RangeDeque::const_iterator;
250 using IndexArray = std::unique_ptr<IndexType[]>;
253 std::unique_ptr<ConstAccessorPtr[]> mAccessorList;
257 RangeDeque mRangeList;
258 RangeDequeCIter mIter;
260 IndexArray mIndexArray;
261 size_t mIndexArraySize, mAccessorListSize;
270 namespace particle_atlas_internal {
273 template<
typename ParticleArrayT>
276 using PosType =
typename ParticleArrayT::PosType;
280 : particleArray(&particles)
287 : particleArray(rhs.particleArray)
295 ScalarType radius, tmpMin = minRadius, tmpMax = maxRadius;
297 for (
size_t n = range.begin(), N = range.end(); n != N; ++n) {
298 particleArray->getRadius(n, radius);
303 minRadius =
std::min(minRadius, tmpMin);
304 maxRadius =
std::max(maxRadius, tmpMax);
317 template<
typename ParticleArrayT,
typename Po
intIndex>
324 using PosType =
typename ParticleArray::PosType;
328 : mIndexMap(), mParticleArray(&particles), mSize(particles.size())
334 : mIndexMap(), mParticleArray(&particles), mSize(particles.size())
342 size_t size()
const {
return mSize; }
345 {
return mParticleArray->getPos(getGlobalIndex(n), xyz); }
347 {
return mParticleArray->getRadius(getGlobalIndex(n), radius); }
352 size_t getGlobalIndex(
size_t n)
const {
return mIndexMap ? size_t(mIndexMap[n]) : n; }
358 if (mMaxRadius < maxRadiusLimit)
return Ptr();
360 std::unique_ptr<bool[]> mask{
new bool[mSize]};
362 tbb::parallel_for(tbb::blocked_range<size_t>(0, mSize),
363 MaskParticles(*
this, mask, maxRadiusLimit));
366 if (output->size() == 0)
return Ptr();
369 for (
size_t n = 0, N = mSize; n < N; ++n) {
370 newSize += size_t(!mask[n]);
373 std::unique_ptr<PointIndex[]> newIndexMap{
new PointIndex[newSize]};
375 setIndexMap(newIndexMap, mask,
false);
378 mIndexMap.swap(newIndexMap);
392 const std::unique_ptr<
bool[]>& mask)
393 : mIndexMap(), mParticleArray(&other.
particleArray()), mSize(0)
395 for (
size_t n = 0, N = other.
size(); n < N; ++n) {
396 mSize += size_t(mask[n]);
401 other.setIndexMap(mIndexMap, mask,
true);
407 struct MaskParticles {
409 const std::unique_ptr<
bool[]>& mask,
ScalarType radius)
410 : particleArray(&particles)
411 , particleMask(mask.get())
412 , radiusLimit(radius)
416 void operator()(
const tbb::blocked_range<size_t>& range)
const {
419 for (
size_t n = range.begin(), N = range.end(); n != N; ++n) {
420 particleArray->getRadius(n, radius);
421 particleMask[n] = !(radius < maxRadius);
426 bool *
const particleMask;
430 inline void updateExtremas() {
432 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, mSize), op);
437 void setIndexMap(std::unique_ptr<
PointIndex[]>& newIndexMap,
438 const std::unique_ptr<
bool[]>& mask,
bool maskValue)
const 440 if (mIndexMap.get() !=
nullptr) {
442 for (
size_t idx = 0, n = 0, N = mSize; n < N; ++n) {
443 if (mask[n] == maskValue) newIndexMap[idx++] = indices[n];
446 for (
size_t idx = 0, n = 0, N = mSize; n < N; ++n) {
447 if (mask[n] == maskValue) {
448 newIndexMap[idx++] =
PointIndex(static_cast<typename PointIndex::IntType>(n));
457 std::unique_ptr<PointIndex[]> mIndexMap;
458 ParticleArrayT
const *
const mParticleArray;
464 template<
typename ParticleArrayType,
typename Po
intIndexLeafNodeType>
467 RemapIndices(
const ParticleArrayType& particles, std::vector<PointIndexLeafNodeType*>& nodes)
468 : mParticles(&particles)
469 , mNodes(nodes.empty() ? nullptr : &nodes.front())
473 void operator()(
const tbb::blocked_range<size_t>& range)
const 475 using PointIndexType =
typename PointIndexLeafNodeType::ValueType;
476 for (
size_t n = range.begin(), N = range.end(); n != N; ++n) {
478 PointIndexLeafNodeType& node = *mNodes[n];
479 const size_t numIndices = node.indices().size();
481 if (numIndices > 0) {
482 PointIndexType* begin = &node.indices().front();
483 const PointIndexType* end = begin + numIndices;
485 while (begin < end) {
486 *begin = PointIndexType(static_cast<typename PointIndexType::IntType>(
487 mParticles->getGlobalIndex(*begin)));
495 PointIndexLeafNodeType *
const *
const mNodes;
499 template<
typename ParticleArrayType,
typename IndexT>
502 using PosType =
typename ParticleArrayType::PosType;
505 using Range = std::pair<const IndexT*, const IndexT*>;
510 ScalarType radius,
const ParticleArrayType& particles,
bool hasUniformRadius =
false)
515 , mParticles(&particles)
516 , mHasUniformRadius(hasUniformRadius)
518 if (mHasUniformRadius) {
520 mParticles->getRadius(0, uniformRadius);
521 mRadius = mRadius + uniformRadius;
526 template <
typename LeafNodeType>
529 const size_t numIndices = leaf.indices().size();
530 if (numIndices > 0) {
531 const IndexT* begin = &leaf.indices().front();
532 filterVoxel(leaf.origin(), begin, begin + numIndices);
540 if (mHasUniformRadius) {
544 while (begin < end) {
545 mParticles->getPos(
size_t(*begin), pos);
546 const ScalarType distSqr = (mCenter - pos).lengthSqr();
547 if (distSqr < searchRadiusSqr) {
548 mIndices.push_back(*begin);
553 while (begin < end) {
554 const size_t idx = size_t(*begin);
555 mParticles->getPos(idx, pos);
558 mParticles->getRadius(idx, radius);
560 ScalarType searchRadiusSqr = mRadius + radius;
561 searchRadiusSqr *= searchRadiusSqr;
563 const ScalarType distSqr = (mCenter - pos).lengthSqr();
565 if (distSqr < searchRadiusSqr) {
566 mIndices.push_back(*begin);
582 ParticleArrayType
const *
const mParticles;
583 bool const mHasUniformRadius;
587 template<
typename ParticleArrayType,
typename IndexT>
590 using PosType =
typename ParticleArrayType::PosType;
593 using Range = std::pair<const IndexT*, const IndexT*>;
598 const BBoxd& bbox,
const ParticleArrayType& particles,
bool hasUniformRadius =
false)
602 , mCenter(mBBox.getCenter())
603 , mParticles(&particles)
604 , mHasUniformRadius(hasUniformRadius)
607 if (mHasUniformRadius) {
608 mParticles->getRadius(0, mUniformRadiusSqr);
609 mUniformRadiusSqr *= mUniformRadiusSqr;
613 template <
typename LeafNodeType>
616 const size_t numIndices = leaf.indices().size();
617 if (numIndices > 0) {
618 const IndexT* begin = &leaf.indices().front();
619 filterVoxel(leaf.origin(), begin, begin + numIndices);
627 if (mHasUniformRadius) {
628 const ScalarType radiusSqr = mUniformRadiusSqr;
630 while (begin < end) {
632 mParticles->getPos(
size_t(*begin), pos);
633 if (mBBox.isInside(pos)) {
634 mIndices.push_back(*begin++);
638 const ScalarType distSqr = pointToBBoxDistSqr(pos);
639 if (!(distSqr > radiusSqr)) {
640 mIndices.push_back(*begin);
647 while (begin < end) {
649 const size_t idx = size_t(*begin);
650 mParticles->getPos(idx, pos);
651 if (mBBox.isInside(pos)) {
652 mIndices.push_back(*begin++);
657 mParticles->getRadius(idx, radius);
658 const ScalarType distSqr = pointToBBoxDistSqr(pos);
659 if (!(distSqr > (radius * radius))) {
660 mIndices.push_back(*begin);
676 for (
int i = 0; i < 3; ++i) {
683 distSqr += delta * delta;
689 distSqr += delta * delta;
700 ParticleArrayType
const *
const mParticles;
701 bool const mHasUniformRadius;
712 template<
typename Po
intIndexGr
idType>
713 template<
typename ParticleArrayType>
716 const ParticleArrayType& particles,
double minVoxelSize,
size_t maxLevels)
718 using SplittableParticleArray =
720 using SplittableParticleArrayPtr =
typename SplittableParticleArray::Ptr;
721 using ScalarType =
typename ParticleArrayType::ScalarType;
726 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, particles.size()), extremas);
727 const double firstMin = extremas.
minRadius;
728 const double firstMax = extremas.
maxRadius;
729 const double firstVoxelSize =
std::max(minVoxelSize, firstMin);
731 if (!(firstMax < (firstVoxelSize *
double(2.0))) && maxLevels > 1) {
733 std::vector<SplittableParticleArrayPtr> levels;
734 levels.push_back(SplittableParticleArrayPtr(
735 new SplittableParticleArray(particles, firstMin, firstMax)));
737 std::vector<double> voxelSizeArray;
738 voxelSizeArray.push_back(firstVoxelSize);
740 for (
size_t n = 0; n < maxLevels; ++n) {
742 const double maxParticleRadius = double(levels.back()->maxRadius());
743 const double particleRadiusLimit = voxelSizeArray.back() * double(2.0);
744 if (maxParticleRadius < particleRadiusLimit)
break;
746 SplittableParticleArrayPtr newLevel =
747 levels.back()->split(ScalarType(particleRadiusLimit));
748 if (!newLevel)
break;
750 levels.push_back(newLevel);
751 voxelSizeArray.push_back(
double(newLevel->minRadius()));
754 size_t numPoints = 0;
756 using PointIndexTreeType =
typename PointIndexGridType::TreeType;
757 using PointIndexLeafNodeType =
typename PointIndexTreeType::LeafNodeType;
759 std::vector<PointIndexLeafNodeType*> nodes;
761 for (
size_t n = 0, N = levels.size(); n < N; ++n) {
763 const SplittableParticleArray& particleArray = *levels[n];
765 numPoints += particleArray.size();
767 mMinRadiusArray.push_back(
double(particleArray.minRadius()));
768 mMaxRadiusArray.push_back(
double(particleArray.maxRadius()));
771 createPointIndexGrid<PointIndexGridType>(particleArray, voxelSizeArray[n]);
774 grid->tree().getNodes(nodes);
776 tbb::parallel_for(tbb::blocked_range<size_t>(0, nodes.size()),
778 PointIndexLeafNodeType>(particleArray, nodes));
780 mIndexGridArray.push_back(grid);
784 mMinRadiusArray.push_back(firstMin);
785 mMaxRadiusArray.push_back(firstMax);
786 mIndexGridArray.push_back(
787 createPointIndexGrid<PointIndexGridType>(particles, firstVoxelSize));
792 template<
typename Po
intIndexGr
idType>
793 template<
typename ParticleArrayType>
796 const ParticleArrayType& particles,
double minVoxelSize,
size_t maxLevels)
799 ret->construct(particles, minVoxelSize, maxLevels);
808 template<
typename Po
intIndexGr
idType>
815 , mIter(mRangeList.begin())
818 , mAccessorListSize(atlas.levels())
820 if (mAccessorListSize > 0) {
822 for (
size_t n = 0, N = mAccessorListSize; n < N; ++n) {
829 template<
typename Po
intIndexGr
idType>
833 mIter = mRangeList.begin();
834 if (!mRangeList.empty()) {
835 mRange = mRangeList.front();
836 }
else if (mIndexArray) {
837 mRange.first = mIndexArray.get();
838 mRange.second = mRange.first + mIndexArraySize;
840 mRange.first =
static_cast<IndexType*
>(
nullptr);
841 mRange.second =
static_cast<IndexType*
>(
nullptr);
846 template<
typename Po
intIndexGr
idType>
851 if (mRange.first >= mRange.second && mIter != mRangeList.end()) {
853 if (mIter != mRangeList.end()) {
855 }
else if (mIndexArray) {
856 mRange.first = mIndexArray.get();
857 mRange.second = mRange.first + mIndexArraySize;
863 template<
typename Po
intIndexGr
idType>
867 if (!this->
test())
return false;
873 template<
typename Po
intIndexGr
idType>
878 typename RangeDeque::const_iterator it =
879 mRangeList.begin(), end = mRangeList.end();
881 for ( ; it != end; ++it) {
882 count += it->second - it->first;
885 return count + mIndexArraySize;
889 template<
typename Po
intIndexGr
idType>
893 mRange.first =
static_cast<IndexType*
>(
nullptr);
894 mRange.second =
static_cast<IndexType*
>(
nullptr);
896 mIter = mRangeList.end();
902 template<
typename Po
intIndexGr
idType>
906 using TreeType =
typename PointIndexGridType::TreeType;
907 using LeafNodeType =
typename TreeType::LeafNodeType;
911 if (mAccessorListSize > 0) {
912 const size_t levelIdx =
std::min(mAccessorListSize - 1, level);
917 std::vector<const LeafNodeType*> nodes;
918 tree.getNodes(nodes);
920 for (
size_t n = 0, N = nodes.size(); n < N; ++n) {
922 const LeafNodeType& node = *nodes[n];
923 const size_t numIndices = node.indices().size();
925 if (numIndices > 0) {
926 const IndexType* begin = &node.indices().front();
927 mRangeList.push_back(Range(begin, (begin + numIndices)));
936 template<
typename Po
intIndexGr
idType>
937 template<
typename ParticleArrayType>
940 const Vec3d& center,
double radius,
const ParticleArrayType& particles)
942 using PosType =
typename ParticleArrayType::PosType;
943 using ScalarType =
typename ParticleArrayType::ScalarType;
949 std::deque<IndexType> filteredIndices;
950 std::vector<CoordBBox> searchRegions;
952 const double iRadius = radius * double(1.0 / std::sqrt(3.0));
954 const Vec3d ibMin(center[0] - iRadius, center[1] - iRadius, center[2] - iRadius);
955 const Vec3d ibMax(center[0] + iRadius, center[1] + iRadius, center[2] + iRadius);
957 const Vec3d bMin(center[0] - radius, center[1] - radius, center[2] - radius);
958 const Vec3d bMax(center[0] + radius, center[1] + radius, center[2] + radius);
960 const PosType pos = PosType(center);
961 const ScalarType dist = ScalarType(radius);
963 for (
size_t n = 0, N = mAccessorListSize; n < N; ++n) {
968 const openvdb::math::Transform& xform = mAtlas->
pointIndexGrid(n).transform();
973 xform.worldToIndexCellCentered(ibMin),
974 xform.worldToIndexCellCentered(ibMax));
976 inscribedRegion.
expand(-1);
981 searchRegions.clear();
984 xform.worldToIndexCellCentered(bMin - maxRadius),
985 xform.worldToIndexCellCentered(bMax + maxRadius));
987 inscribedRegion.
expand(1);
989 searchRegions, region, inscribedRegion);
992 FilterType filter(mRangeList, filteredIndices, pos, dist, particles, uniformRadius);
994 for (
size_t i = 0, I = searchRegions.size(); i < I; ++i) {
1005 template<
typename Po
intIndexGr
idType>
1006 template<
typename ParticleArrayType>
1009 const BBoxd& bbox,
const ParticleArrayType& particles)
1013 std::deque<IndexType> filteredIndices;
1014 std::vector<CoordBBox> searchRegions;
1016 for (
size_t n = 0, N = mAccessorListSize; n < N; ++n) {
1020 const openvdb::math::Transform& xform = mAtlas->
pointIndexGrid(n).transform();
1025 xform.worldToIndexCellCentered(bbox.
min()),
1026 xform.worldToIndexCellCentered(bbox.
max()));
1028 inscribedRegion.
expand(-1);
1033 searchRegions.clear();
1036 xform.worldToIndexCellCentered(bbox.
min() -
maxRadius),
1037 xform.worldToIndexCellCentered(bbox.
max() +
maxRadius));
1039 inscribedRegion.
expand(1);
1041 searchRegions, region, inscribedRegion);
1044 FilterType filter(mRangeList, filteredIndices, bbox, particles, uniformRadius);
1046 for (
size_t i = 0, I = searchRegions.size(); i < I; ++i) {
1061 #endif // OPENVDB_TOOLS_PARTICLE_ATLAS_HAS_BEEN_INCLUDED Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
bool empty() const
true if the container size is 0, false otherwise.
Definition: ParticleAtlas.h:144
typename ParticleArray::PosType PosType
Definition: ParticleAtlas.h:324
double minRadius(size_t n) const
Returns minimum particle radius for level n.
Definition: ParticleAtlas.h:147
Definition: ParticleAtlas.h:465
SplittableParticleArray(const ParticleArrayT &particles)
Definition: ParticleAtlas.h:327
const IndexType & operator*() const
Return a const reference to the item to which this iterator is pointing.
Definition: ParticleAtlas.h:216
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
ParticleArrayType const *const mParticles
Definition: ParticleAtlas.h:494
typename PosType::value_type ScalarType
Definition: ParticleAtlas.h:503
void increment()
Advance iterator to next item.
Definition: ParticleAtlas.h:848
bool operator!=(const Iterator &p) const
Definition: ParticleAtlas.h:239
Definition: ParticleAtlas.h:500
Definition: ParticleAtlas.h:318
PointIndexGridType & pointIndexGrid(size_t n)
Returns the PointIndexGrid that represents the given level n.
Definition: ParticleAtlas.h:152
typename PosType::value_type ScalarType
Definition: ParticleAtlas.h:591
const Vec3T & min() const
Return a const reference to the minimum point of this bounding box.
Definition: BBox.h:89
Definition: ParticleAtlas.h:274
tree::ValueAccessor< const TreeType > ConstAccessor
Definition: ParticleAtlas.h:181
ParticleArrayT const *const particleArray
Definition: ParticleAtlas.h:312
const PointIndexGridType & pointIndexGrid(size_t n) const
Returns the PointIndexGrid that represents the given level n.
Definition: ParticleAtlas.h:154
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
bool operator==(const Iterator &p) const
Return true if both iterators point to the same element.
Definition: ParticleAtlas.h:238
size_t size() const
Return the number of point indices in the iterator range.
Definition: ParticleAtlas.h:875
double maxRadius(size_t n) const
Returns maximum particle radius for level n.
Definition: ParticleAtlas.h:149
BBoxFilter(RangeDeque &ranges, IndexDeque &indices, const BBoxd &bbox, const ParticleArrayType &particles, bool hasUniformRadius=false)
Definition: ParticleAtlas.h:597
std::shared_ptr< T > SharedPtr
Definition: Types.h:139
size_t levels() const
Returns the total number of resolution levels.
Definition: ParticleAtlas.h:206
std::deque< IndexT > IndexDeque
Definition: ParticleAtlas.h:595
std::pair< const IndexT *, const IndexT * > Range
Definition: ParticleAtlas.h:593
std::deque< IndexT > IndexDeque
Definition: ParticleAtlas.h:507
ScalarType maxRadius() const
Definition: ParticleAtlas.h:350
ComputeExtremas(const ParticleArrayT &particles)
Definition: ParticleAtlas.h:279
ScalarType minRadius() const
Definition: ParticleAtlas.h:349
void operator++()
Advance iterator to next item.
Definition: ParticleAtlas.h:228
typename ParticleArrayT::PosType PosType
Definition: ParticleAtlas.h:276
size_t getGlobalIndex(size_t n) const
Definition: ParticleAtlas.h:352
Selectively extract and filter point data using a custom filter operator.
bool test() const
Return true if this iterator is not yet exhausted.
Definition: ParticleAtlas.h:220
size_t levels() const
Returns the number of resolution levels.
Definition: ParticleAtlas.h:142
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:422
Vec3< double > Vec3d
Definition: Vec3.h:679
Ptr split(ScalarType maxRadiusLimit)
Definition: ParticleAtlas.h:356
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
void filterLeafNode(const LeafNodeType &leaf)
Definition: ParticleAtlas.h:527
std::deque< Range > RangeDeque
Definition: ParticleAtlas.h:506
typename PointIndexGridType::ValueType IndexType
Definition: ParticleAtlas.h:116
SharedPtr< SplittableParticleArray > Ptr
Definition: ParticleAtlas.h:320
void reset()
Reset the iterator to point to the first item.
Definition: ParticleAtlas.h:831
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: ParticleAtlas.h:473
std::pair< const IndexT *, const IndexT * > Range
Definition: ParticleAtlas.h:505
SharedPtr< ParticleAtlas > Ptr
Definition: ParticleAtlas.h:112
Definition: Exceptions.h:40
const ParticleArrayT & particleArray() const
Definition: ParticleAtlas.h:340
SplittableParticleArray(const ParticleArrayT &particles, double minR, double maxR)
Definition: ParticleAtlas.h:333
PointIndexLeafNodeType *const *const mNodes
Definition: ParticleAtlas.h:495
typename PosType::value_type ScalarType
Definition: ParticleAtlas.h:325
ComputeExtremas(ComputeExtremas &rhs, tbb::split)
Definition: ParticleAtlas.h:286
Partition particles and performs range and nearest-neighbor searches.
Definition: ParticleAtlas.h:110
void updateFromLevel(size_t level)
Clear the iterator and update it with all particles that reside at the given resolution level...
Definition: ParticleAtlas.h:904
void filterLeafNode(const LeafNodeType &leaf)
Definition: ParticleAtlas.h:614
RemapIndices(const ParticleArrayType &particles, std::vector< PointIndexLeafNodeType *> &nodes)
Definition: ParticleAtlas.h:467
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:488
typename ParticleArrayType::PosType PosType
Definition: ParticleAtlas.h:502
const Vec3T & max() const
Return a const reference to the maximum point of this bounding box.
Definition: BBox.h:91
Integer wrapper, required to distinguish PointIndexGrid and PointDataGrid from Int32Grid and Int64Gri...
Definition: Types.h:183
Definition: ParticleAtlas.h:588
std::unique_ptr< ConstAccessor > ConstAccessorPtr
Definition: ParticleAtlas.h:182
ScalarType maxRadius
Definition: ParticleAtlas.h:313
void worldSpaceSearchAndUpdate(const Vec3d ¢er, double radius, const ParticleArrayType &particles)
Clear the iterator and update it with the result of the given world-space radial query.
Definition: ParticleAtlas.h:939
std::deque< Range > RangeDeque
Definition: ParticleAtlas.h:594
bool next()
Advance iterator to next item.
Definition: ParticleAtlas.h:865
ParticleAtlas()
Definition: ParticleAtlas.h:122
SharedPtr< const ParticleAtlas > ConstPtr
Definition: ParticleAtlas.h:113
Provides accelerated range and nearest-neighbor searches for particles that are partitioned using the...
Definition: ParticleAtlas.h:178
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:358
ScalarType minRadius
Definition: ParticleAtlas.h:313
void operator()(const tbb::blocked_range< size_t > &range)
Definition: ParticleAtlas.h:293
size_t size() const
Definition: ParticleAtlas.h:342
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
SharedPtr< const SplittableParticleArray > ConstPtr
Definition: ParticleAtlas.h:321
void join(const ComputeExtremas &rhs)
Definition: ParticleAtlas.h:307
typename PosType::value_type ScalarType
Definition: ParticleAtlas.h:277
typename PointIndexGridType::TreeType TreeType
Definition: ParticleAtlas.h:180
void getPos(size_t n, PosType &xyz) const
Definition: ParticleAtlas.h:344
void getRadius(size_t n, ScalarType &radius) const
Definition: ParticleAtlas.h:346
void filterVoxel(const Coord &, const IndexT *begin, const IndexT *end)
Definition: ParticleAtlas.h:536
void filterVoxel(const Coord &, const IndexT *begin, const IndexT *end)
Definition: ParticleAtlas.h:623
RadialRangeFilter(RangeDeque &ranges, IndexDeque &indices, const PosType &xyz, ScalarType radius, const ParticleArrayType &particles, bool hasUniformRadius=false)
Definition: ParticleAtlas.h:509
typename ParticleArrayType::PosType PosType
Definition: ParticleAtlas.h:590
typename PointIndexGridType::Ptr PointIndexGridPtr
Definition: ParticleAtlas.h:115