OpenVDB: ParticleAtlas.h Source File

OpenVDB 4.0.2

ParticleAtlas.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2017 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 //
30
51
52 #ifndef OPENVDB_TOOLS_PARTICLE_ATLAS_HAS_BEEN_INCLUDED
53 #define OPENVDB_TOOLS_PARTICLE_ATLAS_HAS_BEEN_INCLUDED
54
55 #include "PointIndexGrid.h"
56
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>
62
63 #include <boost/scoped_array.hpp>
64 #include <tbb/blocked_range.h>
65 #include <tbb/parallel_for.h>
66 #include <tbb/parallel_reduce.h>
67 #include <algorithm> // for std::min(), std::max()
68 #include <cmath> // for std::sqrt()
69 #include <deque>
70 #include <limits>
71 #include <memory>
72 #include <utility> // for std::pair
73 #include <vector>
74
75
76 namespace openvdb {
77 OPENVDB_USE_VERSION_NAMESPACE
78 namespace OPENVDB_VERSION_NAME {
79 namespace tools {
80
81
83
84
110 template<typename PointIndexGridType = PointIndexGrid>
111 struct ParticleAtlas
112 {
113 using Ptr = SharedPtr<ParticleAtlas>;
114 using ConstPtr = SharedPtr<const ParticleAtlas>;
115
116 using PointIndexGridPtr = typename PointIndexGridType::Ptr;
117 using IndexType = typename PointIndexGridType::ValueType;
118
119 struct Iterator;
120
122
123 ParticleAtlas() : mIndexGridArray(), mMinRadiusArray(), mMaxRadiusArray() {}
124
130 template<typename ParticleArrayType>
131 void construct(const ParticleArrayType& particles, double minVoxelSize, size_t maxLevels = 50);
132
138 template<typename ParticleArrayType>
139 static Ptr create(const ParticleArrayType& particles,
140 double minVoxelSize, size_t maxLevels = 50);
141
143 size_t levels() const { return mIndexGridArray.size(); }
145 bool empty() const { return mIndexGridArray.empty(); }
146
148 double minRadius(size_t n) const { return mMinRadiusArray[n]; }
150 double maxRadius(size_t n) const { return mMaxRadiusArray[n]; }
151
153 PointIndexGridType& pointIndexGrid(size_t n) { return *mIndexGridArray[n]; }
155 const PointIndexGridType& pointIndexGrid(size_t n) const { return *mIndexGridArray[n]; }
156
157 private:
158 // Disallow copying
159 ParticleAtlas(const ParticleAtlas&);
160 ParticleAtlas& operator=(const ParticleAtlas&);
161
162 std::vector<PointIndexGridPtr> mIndexGridArray;
163 std::vector<double> mMinRadiusArray, mMaxRadiusArray;
164 }; // struct ParticleAtlas
165
166
167 using ParticleIndexAtlas = ParticleAtlas<PointIndexGrid>;
168
169
171
172
178 template<typename PointIndexGridType>
179 struct ParticleAtlas<PointIndexGridType>::Iterator
180 {
181 using TreeType = typename PointIndexGridType::TreeType;
182 using ConstAccessor = tree::ValueAccessor<const TreeType>;
183 using ConstAccessorPtr = std::unique_ptr<ConstAccessor>;
184
186
188 explicit Iterator(const ParticleAtlas& atlas);
189
195 template<typename ParticleArrayType>
196 void worldSpaceSearchAndUpdate(const Vec3d& center, double radius,
197 const ParticleArrayType& particles);
198
203 template<typename ParticleArrayType>
204 void worldSpaceSearchAndUpdate(const BBoxd& bbox, const ParticleArrayType& particles);
205
207 size_t levels() const { return mAtlas->levels(); }
208
211 void updateFromLevel(size_t level);
212
214 void reset();
215
217 const IndexType& operator*() const { return *mRange.first; }
218
221 bool test() const { return mRange.first < mRange.second || mIter != mRangeList.end(); }
222 operator bool() const { return this->test(); }
224
226 void increment();
227
229 void operator++() { this->increment(); }
230
233 bool next();
234
236 size_t size() const;
237
239 bool operator==(const Iterator& p) const { return mRange.first == p.mRange.first; }
240 bool operator!=(const Iterator& p) const { return !this->operator==(p); }
241
242 private:
243 Iterator(const Iterator& rhs);
244 Iterator& operator=(const Iterator& rhs);
245
246 void clear();
247
248 using Range = std::pair<const IndexType*, const IndexType*>;
249 using RangeDeque = std::deque<Range>;
250 using RangeDequeCIter = typename RangeDeque::const_iterator;
251 using IndexArray = boost::scoped_array<IndexType>;
252
253 ParticleAtlas const * const mAtlas;
254 boost::scoped_array<ConstAccessorPtr> mAccessorList;
255
256 // Primary index collection
257 Range mRange;
258 RangeDeque mRangeList;
259 RangeDequeCIter mIter;
260 // Secondary index collection
261 IndexArray mIndexArray;
262 size_t mIndexArraySize, mAccessorListSize;
263 }; // struct ParticleAtlas::Iterator
264
265
267
268 // Internal operators and implementation details
269
270
271 namespace particle_atlas_internal {
272
273
274 template<typename ParticleArrayT>
275 struct ComputeExtremas
276 {
277 using PosType = typename ParticleArrayT::PosType;
278 using ScalarType = typename PosType::value_type;
279
280 ComputeExtremas(const ParticleArrayT& particles)
281 : particleArray(&particles)
282 , minRadius(std::numeric_limits<ScalarType>::max())
283 , maxRadius(-std::numeric_limits<ScalarType>::max())
284 {
285 }
286
287 ComputeExtremas(ComputeExtremas& rhs, tbb::split)
288 : particleArray(rhs.particleArray)
289 , minRadius(std::numeric_limits<ScalarType>::max())
290 , maxRadius(-std::numeric_limits<ScalarType>::max())
291 {
292 }
293
294 void operator()(const tbb::blocked_range<size_t>& range) {
295
296 ScalarType radius, tmpMin = minRadius, tmpMax = maxRadius;
297
298 for (size_t n = range.begin(), N = range.end(); n != N; ++n) {
299 particleArray->getRadius(n, radius);
300 tmpMin = std::min(radius, tmpMin);
301 tmpMax = std::max(radius, tmpMax);
302 }
303
304 minRadius = std::min(minRadius, tmpMin);
305 maxRadius = std::max(maxRadius, tmpMax);
306 }
307
308 void join(const ComputeExtremas& rhs) {
309 minRadius = std::min(minRadius, rhs.minRadius);
310 maxRadius = std::max(maxRadius, rhs.maxRadius);
311 }
312
313 ParticleArrayT const * const particleArray;
314 ScalarType minRadius, maxRadius;
315 }; // struct ComputeExtremas
316
317
318 template<typename ParticleArrayT, typename PointIndex>
319 struct SplittableParticleArray
320 {
321 using Ptr = SharedPtr<SplittableParticleArray>;
322 using ConstPtr = SharedPtr<const SplittableParticleArray>;
323 using ParticleArray = ParticleArrayT;
324
325 using PosType = typename ParticleArray::PosType;
326 using ScalarType = typename PosType::value_type;
327
328 SplittableParticleArray(const ParticleArrayT& particles)
329 : mIndexMap(), mParticleArray(&particles), mSize(particles.size())
330 {
331 updateExtremas();
332 }
333
334 SplittableParticleArray(const ParticleArrayT& particles, double minR, double maxR)
335 : mIndexMap(), mParticleArray(&particles), mSize(particles.size())
336 {
337 mMinRadius = ScalarType(minR);
338 mMaxRadius = ScalarType(maxR);
339 }
340
341 const ParticleArrayT& particleArray() const { return *mParticleArray; }
342
343 size_t size() const { return mSize; }
344
345 void getPos(size_t n, PosType& xyz) const
346 { return mParticleArray->getPos(getGlobalIndex(n), xyz); }
347 void getRadius(size_t n, ScalarType& radius) const
348 { return mParticleArray->getRadius(getGlobalIndex(n), radius); }
349
350 ScalarType minRadius() const { return mMinRadius; }
351 ScalarType maxRadius() const { return mMaxRadius; }
352
353 size_t getGlobalIndex(size_t n) const { return mIndexMap ? size_t(mIndexMap[n]) : n; }
354
357 Ptr split(ScalarType maxRadiusLimit) {
358
359 if (mMaxRadius < maxRadiusLimit) return Ptr();
360
361 boost::scoped_array<bool> mask(new bool[mSize]);
362
363 tbb::parallel_for(tbb::blocked_range<size_t>(0, mSize),
364 MaskParticles(*this, mask, maxRadiusLimit));
365
366 Ptr output(new SplittableParticleArray(*this, mask));
367 if (output->size() == 0) return Ptr();
368
369 size_t newSize = 0;
370 for (size_t n = 0, N = mSize; n < N; ++n) {
371 newSize += size_t(!mask[n]);
372 }
373
374 boost::scoped_array<PointIndex> newIndexMap(new PointIndex[newSize]);
375
376 setIndexMap(newIndexMap, mask, false);
377
378 mSize = newSize;
379 mIndexMap.swap(newIndexMap);
380 updateExtremas();
381
382 return output;
383 }
384
385
386 private:
387 // Disallow copying
388 SplittableParticleArray(const SplittableParticleArray&);
389 SplittableParticleArray& operator=(const SplittableParticleArray&);
390
391 // Masked copy constructor
392 SplittableParticleArray(const SplittableParticleArray& other,
393 const boost::scoped_array<bool>& mask)
394 : mIndexMap(), mParticleArray(&other.particleArray()), mSize(0)
395 {
396 for (size_t n = 0, N = other.size(); n < N; ++n) {
397 mSize += size_t(mask[n]);
398 }
399
400 if (mSize != 0) {
401 mIndexMap.reset(new PointIndex[mSize]);
402 other.setIndexMap(mIndexMap, mask, true);
403 }
404
405 updateExtremas();
406 }
407
408 struct MaskParticles {
409 MaskParticles(const SplittableParticleArray& particles,
410 const boost::scoped_array<bool>& mask, ScalarType radius)
411 : particleArray(&particles)
412 , particleMask(mask.get())
413 , radiusLimit(radius)
414 {
415 }
416
417 void operator()(const tbb::blocked_range<size_t>& range) const {
418 const ScalarType maxRadius = radiusLimit;
419 ScalarType radius;
420 for (size_t n = range.begin(), N = range.end(); n != N; ++n) {
421 particleArray->getRadius(n, radius);
422 particleMask[n] = !(radius < maxRadius);
423 }
424 }
425
426 SplittableParticleArray const * const particleArray;
427 bool * const particleMask;
428 ScalarType const radiusLimit;
429 }; // struct MaskParticles
430
431 inline void updateExtremas() {
432 ComputeExtremas<SplittableParticleArray> op(*this);
433 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, mSize), op);
434 mMinRadius = op.minRadius;
435 mMaxRadius = op.maxRadius;
436 }
437
438 void setIndexMap(boost::scoped_array<PointIndex>& newIndexMap,
439 const boost::scoped_array<bool>& mask, bool maskValue) const
440 {
441 if (mIndexMap.get() != nullptr) {
442 const PointIndex* indices = mIndexMap.get();
443 for (size_t idx = 0, n = 0, N = mSize; n < N; ++n) {
444 if (mask[n] == maskValue) newIndexMap[idx++] = indices[n];
445 }
446 } else {
447 for (size_t idx = 0, n = 0, N = mSize; n < N; ++n) {
448 if (mask[n] == maskValue) {
449 newIndexMap[idx++] = PointIndex(static_cast<typename PointIndex::IntType>(n));
450 }
451 }
452 }
453 }
454
455
457
458 boost::scoped_array<PointIndex> mIndexMap;
459 ParticleArrayT const * const mParticleArray;
460 size_t mSize;
461 ScalarType mMinRadius, mMaxRadius;
462 }; // struct SplittableParticleArray
463
464
465 template<typename ParticleArrayType, typename PointIndexLeafNodeType>
466 struct RemapIndices {
467
468 RemapIndices(const ParticleArrayType& particles, std::vector<PointIndexLeafNodeType*>& nodes)
469 : mParticles(&particles)
470 , mNodes(nodes.empty() ? nullptr : &nodes.front())
471 {
472 }
473
474 void operator()(const tbb::blocked_range<size_t>& range) const
475 {
476 using PointIndexType = typename PointIndexLeafNodeType::ValueType;
477 for (size_t n = range.begin(), N = range.end(); n != N; ++n) {
478
479 PointIndexLeafNodeType& node = *mNodes[n];
480 const size_t numIndices = node.indices().size();
481
482 if (numIndices > 0) {
483 PointIndexType* begin = &node.indices().front();
484 const PointIndexType* end = begin + numIndices;
485
486 while (begin < end) {
487 *begin = PointIndexType(static_cast<typename PointIndexType::IntType>(
488 mParticles->getGlobalIndex(*begin)));
489 ++begin;
490 }
491 }
492 }
493 }
494
495 ParticleArrayType const * const mParticles;
496 PointIndexLeafNodeType * const * const mNodes;
497 }; // struct RemapIndices
498
499
500 template<typename ParticleArrayType, typename IndexT>
501 struct RadialRangeFilter
502 {
503 using PosType = typename ParticleArrayType::PosType;
504 using ScalarType = typename PosType::value_type;
505
506 using Range = std::pair<const IndexT*, const IndexT*>;
507 using RangeDeque = std::deque<Range>;
508 using IndexDeque = std::deque<IndexT>;
509
510 RadialRangeFilter(RangeDeque& ranges, IndexDeque& indices, const PosType& xyz,
511 ScalarType radius, const ParticleArrayType& particles, bool hasUniformRadius = false)
512 : mRanges(ranges)
513 , mIndices(indices)
514 , mCenter(xyz)
515 , mRadius(radius)
516 , mParticles(&particles)
517 , mHasUniformRadius(hasUniformRadius)
518 {
519 if (mHasUniformRadius) {
520 ScalarType uniformRadius;
521 mParticles->getRadius(0, uniformRadius);
522 mRadius = mRadius + uniformRadius;
523 mRadius *= mRadius;
524 }
525 }
526
527 template <typename LeafNodeType>
528 void filterLeafNode(const LeafNodeType& leaf)
529 {
530 const size_t numIndices = leaf.indices().size();
531 if (numIndices > 0) {
532 const IndexT* begin = &leaf.indices().front();
533 filterVoxel(leaf.origin(), begin, begin + numIndices);
534 }
535 }
536
537 void filterVoxel(const Coord&, const IndexT* begin, const IndexT* end)
538 {
539 PosType pos;
540
541 if (mHasUniformRadius) {
542
543 const ScalarType searchRadiusSqr = mRadius;
544
545 while (begin < end) {
546 mParticles->getPos(size_t(*begin), pos);
547 const ScalarType distSqr = (mCenter - pos).lengthSqr();
548 if (distSqr < searchRadiusSqr) {
549 mIndices.push_back(*begin);
550 }
551 ++begin;
552 }
553 } else {
554 while (begin < end) {
555 const size_t idx = size_t(*begin);
556 mParticles->getPos(idx, pos);
557
558 ScalarType radius;
559 mParticles->getRadius(idx, radius);
560
561 ScalarType searchRadiusSqr = mRadius + radius;
562 searchRadiusSqr *= searchRadiusSqr;
563
564 const ScalarType distSqr = (mCenter - pos).lengthSqr();
565
566 if (distSqr < searchRadiusSqr) {
567 mIndices.push_back(*begin);
568 }
569
570 ++begin;
571 }
572 }
573 }
574
575 private:
576 RadialRangeFilter(const RadialRangeFilter&);
577 RadialRangeFilter& operator=(const RadialRangeFilter&);
578
579 RangeDeque& mRanges;
580 IndexDeque& mIndices;
581 PosType const mCenter;
582 ScalarType mRadius;
583 ParticleArrayType const * const mParticles;
584 bool const mHasUniformRadius;
585 }; // struct RadialRangeFilter
586
587
588 template<typename ParticleArrayType, typename IndexT>
589 struct BBoxFilter
590 {
591 using PosType = typename ParticleArrayType::PosType;
592 using ScalarType = typename PosType::value_type;
593
594 using Range = std::pair<const IndexT*, const IndexT*>;
595 using RangeDeque = std::deque<Range>;
596 using IndexDeque = std::deque<IndexT>;
597
598 BBoxFilter(RangeDeque& ranges, IndexDeque& indices,
599 const BBoxd& bbox, const ParticleArrayType& particles, bool hasUniformRadius = false)
600 : mRanges(ranges)
601 , mIndices(indices)
602 , mBBox(PosType(bbox.min()), PosType(bbox.max()))
603 , mCenter(mBBox.getCenter())
604 , mParticles(&particles)
605 , mHasUniformRadius(hasUniformRadius)
606 , mUniformRadiusSqr(ScalarType(0.0))
607 {
608 if (mHasUniformRadius) {
609 mParticles->getRadius(0, mUniformRadiusSqr);
610 mUniformRadiusSqr *= mUniformRadiusSqr;
611 }
612 }
613
614 template <typename LeafNodeType>
615 void filterLeafNode(const LeafNodeType& leaf)
616 {
617 const size_t numIndices = leaf.indices().size();
618 if (numIndices > 0) {
619 const IndexT* begin = &leaf.indices().front();
620 filterVoxel(leaf.origin(), begin, begin + numIndices);
621 }
622 }
623
624 void filterVoxel(const Coord&, const IndexT* begin, const IndexT* end)
625 {
626 PosType pos;
627
628 if (mHasUniformRadius) {
629 const ScalarType radiusSqr = mUniformRadiusSqr;
630
631 while (begin < end) {
632
633 mParticles->getPos(size_t(*begin), pos);
634 if (mBBox.isInside(pos)) {
635 mIndices.push_back(*begin++);
636 continue;
637 }
638
639 const ScalarType distSqr = pointToBBoxDistSqr(pos);
640 if (!(distSqr > radiusSqr)) {
641 mIndices.push_back(*begin);
642 }
643
644 ++begin;
645 }
646
647 } else {
648 while (begin < end) {
649
650 const size_t idx = size_t(*begin);
651 mParticles->getPos(idx, pos);
652 if (mBBox.isInside(pos)) {
653 mIndices.push_back(*begin++);
654 continue;
655 }
656
657 ScalarType radius;
658 mParticles->getRadius(idx, radius);
659 const ScalarType distSqr = pointToBBoxDistSqr(pos);
660 if (!(distSqr > (radius * radius))) {
661 mIndices.push_back(*begin);
662 }
663
664 ++begin;
665 }
666 }
667 }
668
669 private:
670 BBoxFilter(const BBoxFilter&);
671 BBoxFilter& operator=(const BBoxFilter&);
672
673 ScalarType pointToBBoxDistSqr(const PosType& pos) const
674 {
675 ScalarType distSqr = ScalarType(0.0);
676
677 for (int i = 0; i < 3; ++i) {
678
679 const ScalarType a = pos[i];
680
681 ScalarType b = mBBox.min()[i];
682 if (a < b) {
683 ScalarType delta = b - a;
684 distSqr += delta * delta;
685 }
686
687 b = mBBox.max()[i];
688 if (a > b) {
689 ScalarType delta = a - b;
690 distSqr += delta * delta;
691 }
692 }
693
694 return distSqr;
695 }
696
697 RangeDeque& mRanges;
698 IndexDeque& mIndices;
699 math::BBox<PosType> const mBBox;
700 PosType const mCenter;
701 ParticleArrayType const * const mParticles;
702 bool const mHasUniformRadius;
703 ScalarType mUniformRadiusSqr;
704 }; // struct BBoxFilter
705
706
707 } // namespace particle_atlas_internal
708
709
711
712
713 template<typename PointIndexGridType>
714 template<typename ParticleArrayType>
715 inline void
716 ParticleAtlas<PointIndexGridType>::construct(
717 const ParticleArrayType& particles, double minVoxelSize, size_t maxLevels)
718 {
719 using SplittableParticleArray =
720 typename particle_atlas_internal::SplittableParticleArray<ParticleArrayType, IndexType>;
721 using SplittableParticleArrayPtr = typename SplittableParticleArray::Ptr;
722 using ScalarType = typename ParticleArrayType::ScalarType;
723
725
726 particle_atlas_internal::ComputeExtremas<ParticleArrayType> extremas(particles);
727 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, particles.size()), extremas);
728 const double firstMin = extremas.minRadius;
729 const double firstMax = extremas.maxRadius;
730 const double firstVoxelSize = std::max(minVoxelSize, firstMin);
731
732 if (!(firstMax < (firstVoxelSize * double(2.0))) && maxLevels > 1) {
733
734 std::vector<SplittableParticleArrayPtr> levels;
735 levels.push_back(SplittableParticleArrayPtr(
736 new SplittableParticleArray(particles, firstMin, firstMax)));
737
738 std::vector<double> voxelSizeArray;
739 voxelSizeArray.push_back(firstVoxelSize);
740
741 for (size_t n = 0; n < maxLevels; ++n) {
742
743 const double maxParticleRadius = double(levels.back()->maxRadius());
744 const double particleRadiusLimit = voxelSizeArray.back() * double(2.0);
745 if (maxParticleRadius < particleRadiusLimit) break;
746
747 SplittableParticleArrayPtr newLevel =
748 levels.back()->split(ScalarType(particleRadiusLimit));
749 if (!newLevel) break;
750
751 levels.push_back(newLevel);
752 voxelSizeArray.push_back(double(newLevel->minRadius()));
753 }
754
755 size_t numPoints = 0;
756
757 using PointIndexTreeType = typename PointIndexGridType::TreeType;
758 using PointIndexLeafNodeType = typename PointIndexTreeType::LeafNodeType;
759
760 std::vector<PointIndexLeafNodeType*> nodes;
761
762 for (size_t n = 0, N = levels.size(); n < N; ++n) {
763
764 const SplittableParticleArray& particleArray = *levels[n];
765
766 numPoints += particleArray.size();
767
768 mMinRadiusArray.push_back(double(particleArray.minRadius()));
769 mMaxRadiusArray.push_back(double(particleArray.maxRadius()));
770
771 PointIndexGridPtr grid =
772 createPointIndexGrid<PointIndexGridType>(particleArray, voxelSizeArray[n]);
773
774 nodes.clear();
775 grid->tree().getNodes(nodes);
776
777 tbb::parallel_for(tbb::blocked_range<size_t>(0, nodes.size()),
778 particle_atlas_internal::RemapIndices<SplittableParticleArray,
779 PointIndexLeafNodeType>(particleArray, nodes));
780
781 mIndexGridArray.push_back(grid);
782 }
783
784 } else {
785 mMinRadiusArray.push_back(firstMin);
786 mMaxRadiusArray.push_back(firstMax);
787 mIndexGridArray.push_back(
788 createPointIndexGrid<PointIndexGridType>(particles, firstVoxelSize));
789 }
790 }
791
792
793 template<typename PointIndexGridType>
794 template<typename ParticleArrayType>
795 inline typename ParticleAtlas<PointIndexGridType>::Ptr
796 ParticleAtlas<PointIndexGridType>::create(
797 const ParticleArrayType& particles, double minVoxelSize, size_t maxLevels)
798 {
799 Ptr ret(new ParticleAtlas());
800 ret->construct(particles, minVoxelSize, maxLevels);
801 return ret;
802 }
803
804
806
807 // ParticleAtlas::Iterator implementation
808
809 template<typename PointIndexGridType>
810 inline
811 ParticleAtlas<PointIndexGridType>::Iterator::Iterator(const ParticleAtlas& atlas)
812 : mAtlas(&atlas)
813 , mAccessorList()
814 , mRange(static_cast<IndexType*>(nullptr), static_cast<IndexType*>(nullptr))
815 , mRangeList()
816 , mIter(mRangeList.begin())
817 , mIndexArray()
818 , mIndexArraySize(0)
819 , mAccessorListSize(atlas.levels())
820 {
821 if (mAccessorListSize > 0) {
822 mAccessorList.reset(new ConstAccessorPtr[mAccessorListSize]);
823 for (size_t n = 0, N = mAccessorListSize; n < N; ++n) {
824 mAccessorList[n].reset(new ConstAccessor(atlas.pointIndexGrid(n).tree()));
825 }
826 }
827 }
828
829
830 template<typename PointIndexGridType>
831 inline void
832 ParticleAtlas<PointIndexGridType>::Iterator::reset()
833 {
834 mIter = mRangeList.begin();
835 if (!mRangeList.empty()) {
836 mRange = mRangeList.front();
837 } else if (mIndexArray) {
838 mRange.first = mIndexArray.get();
839 mRange.second = mRange.first + mIndexArraySize;
840 } else {
841 mRange.first = static_cast<IndexType*>(nullptr);
842 mRange.second = static_cast<IndexType*>(nullptr);
843 }
844 }
845
846
847 template<typename PointIndexGridType>
848 inline void
849 ParticleAtlas<PointIndexGridType>::Iterator::increment()
850 {
851 ++mRange.first;
852 if (mRange.first >= mRange.second && mIter != mRangeList.end()) {
853 ++mIter;
854 if (mIter != mRangeList.end()) {
855 mRange = *mIter;
856 } else if (mIndexArray) {
857 mRange.first = mIndexArray.get();
858 mRange.second = mRange.first + mIndexArraySize;
859 }
860 }
861 }
862
863
864 template<typename PointIndexGridType>
865 inline bool
866 ParticleAtlas<PointIndexGridType>::Iterator::next()
867 {
868 if (!this->test()) return false;
869 this->increment();
870 return this->test();
871 }
872
873
874 template<typename PointIndexGridType>
875 inline size_t
876 ParticleAtlas<PointIndexGridType>::Iterator::size() const
877 {
878 size_t count = 0;
879 typename RangeDeque::const_iterator it =
880 mRangeList.begin(), end = mRangeList.end();
881
882 for ( ; it != end; ++it) {
883 count += it->second - it->first;
884 }
885
886 return count + mIndexArraySize;
887 }
888
889
890 template<typename PointIndexGridType>
891 inline void
892 ParticleAtlas<PointIndexGridType>::Iterator::clear()
893 {
894 mRange.first = static_cast<IndexType*>(nullptr);
895 mRange.second = static_cast<IndexType*>(nullptr);
896 mRangeList.clear();
897 mIter = mRangeList.end();
898 mIndexArray.reset();
899 mIndexArraySize = 0;
900 }
901
902
903 template<typename PointIndexGridType>
904 inline void
905 ParticleAtlas<PointIndexGridType>::Iterator::updateFromLevel(size_t level)
906 {
907 using TreeType = typename PointIndexGridType::TreeType;
908 using LeafNodeType = typename TreeType::LeafNodeType;
909
910 this->clear();
911
912 if (mAccessorListSize > 0) {
913 const size_t levelIdx = std::min(mAccessorListSize - 1, level);
914
915 const TreeType& tree = mAtlas->pointIndexGrid(levelIdx).tree();
916
917
918 std::vector<const LeafNodeType*> nodes;
919 tree.getNodes(nodes);
920
921 for (size_t n = 0, N = nodes.size(); n < N; ++n) {
922
923 const LeafNodeType& node = *nodes[n];
924 const size_t numIndices = node.indices().size();
925
926 if (numIndices > 0) {
927 const IndexType* begin = &node.indices().front();
928 mRangeList.push_back(Range(begin, (begin + numIndices)));
929 }
930 }
931 }
932
933 this->reset();
934 }
935
936
937 template<typename PointIndexGridType>
938 template<typename ParticleArrayType>
939 inline void
940 ParticleAtlas<PointIndexGridType>::Iterator::worldSpaceSearchAndUpdate(
941 const Vec3d& center, double radius, const ParticleArrayType& particles)
942 {
943 using PosType = typename ParticleArrayType::PosType;
944 using ScalarType = typename ParticleArrayType::ScalarType;
945
947
948 this->clear();
949
950 std::deque<IndexType> filteredIndices;
951 std::vector<CoordBBox> searchRegions;
952
953 const double iRadius = radius * double(1.0 / std::sqrt(3.0));
954
955 const Vec3d ibMin(center[0] - iRadius, center[1] - iRadius, center[2] - iRadius);
956 const Vec3d ibMax(center[0] + iRadius, center[1] + iRadius, center[2] + iRadius);
957
958 const Vec3d bMin(center[0] - radius, center[1] - radius, center[2] - radius);
959 const Vec3d bMax(center[0] + radius, center[1] + radius, center[2] + radius);
960
961 const PosType pos = PosType(center);
962 const ScalarType dist = ScalarType(radius);
963
964 for (size_t n = 0, N = mAccessorListSize; n < N; ++n) {
965
966 const double maxRadius = mAtlas->maxRadius(n);
967 const bool uniformRadius = math::isApproxEqual(mAtlas->minRadius(n), maxRadius);
968
969 const openvdb::math::Transform& xform = mAtlas->pointIndexGrid(n).transform();
970
971 ConstAccessor& acc = *mAccessorList[n];
972
973 openvdb::CoordBBox inscribedRegion(
974 xform.worldToIndexCellCentered(ibMin),
975 xform.worldToIndexCellCentered(ibMax));
976
977 inscribedRegion.expand(-1); // erode by one voxel
978
979 // collect indices that don't need to be tested
980 point_index_grid_internal::pointIndexSearch(mRangeList, acc, inscribedRegion);
981
982 searchRegions.clear();
983
984 const openvdb::CoordBBox region(
985 xform.worldToIndexCellCentered(bMin - maxRadius),
986 xform.worldToIndexCellCentered(bMax + maxRadius));
987
988 inscribedRegion.expand(1);
989 point_index_grid_internal::constructExclusiveRegions(
990 searchRegions, region, inscribedRegion);
991
992 using FilterType = particle_atlas_internal::RadialRangeFilter<ParticleArrayType, IndexType>;
993 FilterType filter(mRangeList, filteredIndices, pos, dist, particles, uniformRadius);
994
995 for (size_t i = 0, I = searchRegions.size(); i < I; ++i) {
996 point_index_grid_internal::filteredPointIndexSearch(filter, acc, searchRegions[i]);
997 }
998 }
999
1000 point_index_grid_internal::dequeToArray(filteredIndices, mIndexArray, mIndexArraySize);
1001
1002 this->reset();
1003 }
1004
1005
1006 template<typename PointIndexGridType>
1007 template<typename ParticleArrayType>
1008 inline void
1009 ParticleAtlas<PointIndexGridType>::Iterator::worldSpaceSearchAndUpdate(
1010 const BBoxd& bbox, const ParticleArrayType& particles)
1011 {
1012 this->clear();
1013
1014 std::deque<IndexType> filteredIndices;
1015 std::vector<CoordBBox> searchRegions;
1016
1017 for (size_t n = 0, N = mAccessorListSize; n < N; ++n) {
1018
1019 const double maxRadius = mAtlas->maxRadius(n);
1020 const bool uniformRadius = math::isApproxEqual(mAtlas->minRadius(n), maxRadius);
1021 const openvdb::math::Transform& xform = mAtlas->pointIndexGrid(n).transform();
1022
1023 ConstAccessor& acc = *mAccessorList[n];
1024
1025 openvdb::CoordBBox inscribedRegion(
1026 xform.worldToIndexCellCentered(bbox.min()),
1027 xform.worldToIndexCellCentered(bbox.max()));
1028
1029 inscribedRegion.expand(-1); // erode by one voxel
1030
1031 // collect indices that don't need to be tested
1032 point_index_grid_internal::pointIndexSearch(mRangeList, acc, inscribedRegion);
1033
1034 searchRegions.clear();
1035
1036 const openvdb::CoordBBox region(
1037 xform.worldToIndexCellCentered(bbox.min() - maxRadius),
1038 xform.worldToIndexCellCentered(bbox.max() + maxRadius));
1039
1040 inscribedRegion.expand(1);
1041 point_index_grid_internal::constructExclusiveRegions(
1042 searchRegions, region, inscribedRegion);
1043
1044 using FilterType = particle_atlas_internal::BBoxFilter<ParticleArrayType, IndexType>;
1045 FilterType filter(mRangeList, filteredIndices, bbox, particles, uniformRadius);
1046
1047 for (size_t i = 0, I = searchRegions.size(); i < I; ++i) {
1048 point_index_grid_internal::filteredPointIndexSearch(filter, acc, searchRegions[i]);
1049 }
1050 }
1051
1052 point_index_grid_internal::dequeToArray(filteredIndices, mIndexArray, mIndexArraySize);
1053
1054 this->reset();
1055 }
1056
1057
1058 } // namespace tools
1059 } // namespace OPENVDB_VERSION_NAME
1060 } // namespace openvdb
1061
1062 #endif // OPENVDB_TOOLS_PARTICLE_ATLAS_HAS_BEEN_INCLUDED
1063
1064 // Copyright (c) 2012-2017 DreamWorks Animation LLC
1065 // All rights reserved. This software is distributed under the
1066 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v4_0_2::tools::ParticleAtlas::IndexType
typename PointIndexGridType::ValueType IndexType
Definition: ParticleAtlas.h:117
openvdb::v4_0_2::tools::point_index_grid_internal::dequeToArray
void dequeToArray(const std::deque< T > &d, boost::scoped_array< T > &a, size_t &size)
Definition: PointIndexGrid.h:555
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::operator++
void operator++()
Advance iterator to next item.
Definition: ParticleAtlas.h:229
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::ConstAccessor
tree::ValueAccessor< const TreeType > ConstAccessor
Definition: ParticleAtlas.h:182
Types.h
openvdb::v4_0_2::tools::particle_atlas_internal::RadialRangeFilter::filterVoxel
void filterVoxel(const Coord &, const IndexT *begin, const IndexT *end)
Definition: ParticleAtlas.h:537
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas::join
void join(const ComputeExtremas &rhs)
Definition: ParticleAtlas.h:308
openvdb::v4_0_2::SharedPtr
std::shared_ptr< T > SharedPtr
Definition: Types.h:130
openvdb::v4_0_2::tools::particle_atlas_internal::RadialRangeFilter::PosType
typename ParticleArrayType::PosType PosType
Definition: ParticleAtlas.h:503
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::worldSpaceSearchAndUpdate
void worldSpaceSearchAndUpdate(const Vec3d &center, double radius, const ParticleArrayType &particles)
Clear the iterator and update it with the result of the given world-space radial query.
Definition: ParticleAtlas.h:940
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::ConstAccessorPtr
std::unique_ptr< ConstAccessor > ConstAccessorPtr
Definition: ParticleAtlas.h:183
PointIndexGrid.h
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
openvdb::v4_0_2::tools::particle_atlas_internal::RadialRangeFilter::IndexDeque
std::deque< IndexT > IndexDeque
Definition: ParticleAtlas.h:508
openvdb::v4_0_2::tools::ParticleAtlas::maxRadius
double maxRadius(size_t n) const
Returns maximum particle radius for level n.
Definition: ParticleAtlas.h:150
openvdb::v4_0_2::tools::ParticleAtlas::pointIndexGrid
PointIndexGridType & pointIndexGrid(size_t n)
Returns the PointIndexGrid that represents the given level n.
Definition: ParticleAtlas.h:153
openvdb::v4_0_2::tools::particle_atlas_internal::BBoxFilter::ScalarType
typename PosType::value_type ScalarType
Definition: ParticleAtlas.h:592
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::size
size_t size() const
Definition: ParticleAtlas.h:343
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::maxRadius
ScalarType maxRadius() const
Definition: ParticleAtlas.h:351
openvdb::v4_0_2::tools::particle_atlas_internal::RadialRangeFilter
Definition: ParticleAtlas.h:501
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas::minRadius
ScalarType minRadius
Definition: ParticleAtlas.h:314
i
tbb::atomic< Index32 > i
Definition: LeafBuffer.h:71
openvdb::v4_0_2::math::isApproxEqual
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:354
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray
Definition: ParticleAtlas.h:319
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::operator==
bool operator==(const Iterator &p) const
Return true if both iterators point to the same element.
Definition: ParticleAtlas.h:239
openvdb::v4_0_2::math::CoordBBox
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:261
openvdb::v4_0_2::math::CoordBBox::expand
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:419
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::next
bool next()
Advance iterator to next item.
Definition: ParticleAtlas.h:866
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::getGlobalIndex
size_t getGlobalIndex(size_t n) const
Definition: ParticleAtlas.h:353
Transform.h
openvdb::v4_0_2::tools::particle_atlas_internal::RadialRangeFilter::filterLeafNode
void filterLeafNode(const LeafNodeType &leaf)
Definition: ParticleAtlas.h:528
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::split
Ptr split(ScalarType maxRadiusLimit)
Definition: ParticleAtlas.h:357
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas::particleArray
ParticleArrayT const *const particleArray
Definition: ParticleAtlas.h:313
openvdb::v4_0_2::tools::ParticleAtlas::ParticleAtlas
ParticleAtlas()
Definition: ParticleAtlas.h:123
openvdb::v4_0_2::tools::particle_atlas_internal::RemapIndices::operator()
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: ParticleAtlas.h:474
Tree.h
openvdb::v4_0_2::tools::ParticleAtlas::Ptr
SharedPtr< ParticleAtlas > Ptr
Definition: ParticleAtlas.h:113
openvdb::v4_0_2::tools::particle_atlas_internal::RemapIndices::mNodes
PointIndexLeafNodeType *const *const mNodes
Definition: ParticleAtlas.h:496
openvdb::v4_0_2::tools::composite::max
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::updateFromLevel
void updateFromLevel(size_t level)
Clear the iterator and update it with all particles that reside at the given resolution level...
Definition: ParticleAtlas.h:905
openvdb::v4_0_2::tools::composite::min
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
FilterType
Selectively extract and filter point data using a custom filter operator.
openvdb::v4_0_2::tools::ParticleAtlas::Iterator
Provides accelerated range and nearest-neighbor searches for particles that are partitioned using the...
Definition: ParticleAtlas.h:179
openvdb::v4_0_2::tools::point_index_grid_internal::filteredPointIndexSearch
void filteredPointIndexSearch(RangeFilterType &filter, ConstAccessor &acc, const CoordBBox &bbox)
Definition: PointIndexGrid.h:827
openvdb::v4_0_2::tools::particle_atlas_internal::RadialRangeFilter::Range
std::pair< const IndexT *, const IndexT * > Range
Definition: ParticleAtlas.h:506
openvdb::v4_0_2::tools::particle_atlas_internal::BBoxFilter::PosType
typename ParticleArrayType::PosType PosType
Definition: ParticleAtlas.h:591
openvdb::v4_0_2::tools::particle_atlas_internal::RadialRangeFilter::ScalarType
typename PosType::value_type ScalarType
Definition: ParticleAtlas.h:504
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::getRadius
void getRadius(size_t n, ScalarType &radius) const
Definition: ParticleAtlas.h:347
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::levels
size_t levels() const
Returns the total number of resolution levels.
Definition: ParticleAtlas.h:207
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:43
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::SplittableParticleArray
SplittableParticleArray(const ParticleArrayT &particles, double minR, double maxR)
Definition: ParticleAtlas.h:334
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas::PosType
typename ParticleArrayT::PosType PosType
Definition: ParticleAtlas.h:277
openvdb::v4_0_2::tools::point_index_grid_internal::pointIndexSearch
void pointIndexSearch(RangeDeque &rangeList, ConstAccessor &acc, const CoordBBox &bbox)
Definition: PointIndexGrid.h:903
openvdb::v4_0_2::math::BBox::min
const Vec3T & min() const
Return a const reference to the minimum point of the BBox.
Definition: BBox.h:84
openvdb::v4_0_2::tools::ParticleAtlas::PointIndexGridPtr
typename PointIndexGridType::Ptr PointIndexGridPtr
Definition: ParticleAtlas.h:116
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::size
size_t size() const
Return the number of point indices in the iterator range.
Definition: ParticleAtlas.h:876
openvdb::v4_0_2::tools::particle_atlas_internal::RemapIndices::mParticles
ParticleArrayType const *const mParticles
Definition: ParticleAtlas.h:495
openvdb::v4_0_2::math::BBox::max
const Vec3T & max() const
Return a const reference to the maximum point of the BBox.
Definition: BBox.h:87
openvdb::v4_0_2::tools::particle_atlas_internal::BBoxFilter::RangeDeque
std::deque< Range > RangeDeque
Definition: ParticleAtlas.h:595
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas
Definition: ParticleAtlas.h:275
openvdb
Definition: Exceptions.h:39
openvdb::v4_0_2::tools::ParticleAtlas::pointIndexGrid
const PointIndexGridType & pointIndexGrid(size_t n) const
Returns the PointIndexGrid that represents the given level n.
Definition: ParticleAtlas.h:155
openvdb::v4_0_2::math::operator==
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:487
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::operator*
const IndexType & operator*() const
Return a const reference to the item to which this iterator is pointing.
Definition: ParticleAtlas.h:217
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::particleArray
const ParticleArrayT & particleArray() const
Definition: ParticleAtlas.h:341
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas::ScalarType
typename PosType::value_type ScalarType
Definition: ParticleAtlas.h:278
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas::maxRadius
ScalarType maxRadius
Definition: ParticleAtlas.h:314
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::PosType
typename ParticleArray::PosType PosType
Definition: ParticleAtlas.h:325
openvdb::v4_0_2::math::Vec3d
Vec3< double > Vec3d
Definition: Vec3.h:678
openvdb::v4_0_2::tools::ParticleAtlas::minRadius
double minRadius(size_t n) const
Returns minimum particle radius for level n.
Definition: ParticleAtlas.h:148
openvdb::v4_0_2::tree::ValueAccessor< const TreeType >
ParticleArray
Partition particles and performs range and nearest-neighbor searches.
openvdb::v4_0_2::tools::point_index_grid_internal::constructExclusiveRegions
void constructExclusiveRegions(std::vector< CoordBBox > &regions, const CoordBBox &bbox, const CoordBBox &ibox)
Definition: PointIndexGrid.h:566
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::reset
void reset()
Reset the iterator to point to the first item.
Definition: ParticleAtlas.h:832
openvdb::v4_0_2::tools::particle_atlas_internal::RemapIndices
Definition: ParticleAtlas.h:466
openvdb::v4_0_2::tools::ParticleAtlas::ConstPtr
SharedPtr< const ParticleAtlas > ConstPtr
Definition: ParticleAtlas.h:114
LeafNode.h
openvdb::v4_0_2::tools::ParticleAtlas::levels
size_t levels() const
Returns the number of resolution levels.
Definition: ParticleAtlas.h:143
openvdb::v4_0_2::tools::particle_atlas_internal::BBoxFilter::filterLeafNode
void filterLeafNode(const LeafNodeType &leaf)
Definition: ParticleAtlas.h:615
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::operator!=
bool operator!=(const Iterator &p) const
Definition: ParticleAtlas.h:240
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::minRadius
ScalarType minRadius() const
Definition: ParticleAtlas.h:350
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas::operator()
void operator()(const tbb::blocked_range< size_t > &range)
Definition: ParticleAtlas.h:294
openvdb::v4_0_2::tools::particle_atlas_internal::BBoxFilter::filterVoxel
void filterVoxel(const Coord &, const IndexT *begin, const IndexT *end)
Definition: ParticleAtlas.h:624
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::TreeType
typename PointIndexGridType::TreeType TreeType
Definition: ParticleAtlas.h:181
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas::ComputeExtremas
ComputeExtremas(ComputeExtremas &rhs, tbb::split)
Definition: ParticleAtlas.h:287
openvdb::v4_0_2::tools::particle_atlas_internal::BBoxFilter
Definition: ParticleAtlas.h:589
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::test
bool test() const
Return true if this iterator is not yet exhausted.
Definition: ParticleAtlas.h:221
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::Ptr
SharedPtr< SplittableParticleArray > Ptr
Definition: ParticleAtlas.h:321
Grid.h
openvdb::v4_0_2::tools::particle_atlas_internal::RemapIndices::RemapIndices
RemapIndices(const ParticleArrayType &particles, std::vector< PointIndexLeafNodeType *> &nodes)
Definition: ParticleAtlas.h:468
openvdb::v4_0_2::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:48
openvdb::v4_0_2::tools::particle_atlas_internal::BBoxFilter::Range
std::pair< const IndexT *, const IndexT * > Range
Definition: ParticleAtlas.h:594
openvdb::v4_0_2::tools::ParticleAtlas::empty
bool empty() const
true if the container size is 0, false otherwise.
Definition: ParticleAtlas.h:145
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
openvdb::v4_0_2::tools::ParticleAtlas::Iterator::increment
void increment()
Advance iterator to next item.
Definition: ParticleAtlas.h:849
openvdb::v4_0_2::PointIndex
Integer wrapper, required to distinguish PointIndexGrid and PointDataGrid from Int32Grid and Int64Gri...
Definition: Types.h:173
openvdb::v4_0_2::tools::ParticleAtlas
Definition: ParticleAtlas.h:111
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::ScalarType
typename PosType::value_type ScalarType
Definition: ParticleAtlas.h:326
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::SplittableParticleArray
SplittableParticleArray(const ParticleArrayT &particles)
Definition: ParticleAtlas.h:328
size
static constexpr size_t size
The size of a LeafBuffer when LeafBuffer::mOutOfCore is atomic.
Definition: LeafBuffer.h:85
openvdb::v4_0_2::tools::particle_atlas_internal::BBoxFilter::BBoxFilter
BBoxFilter(RangeDeque &ranges, IndexDeque &indices, const BBoxd &bbox, const ParticleArrayType &particles, bool hasUniformRadius=false)
Definition: ParticleAtlas.h:598
openvdb::v4_0_2::tools::particle_atlas_internal::RadialRangeFilter::RangeDeque
std::deque< Range > RangeDeque
Definition: ParticleAtlas.h:507
openvdb::v4_0_2::tools::particle_atlas_internal::ComputeExtremas::ComputeExtremas
ComputeExtremas(const ParticleArrayT &particles)
Definition: ParticleAtlas.h:280
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::ConstPtr
SharedPtr< const SplittableParticleArray > ConstPtr
Definition: ParticleAtlas.h:322
openvdb::v4_0_2::math::BBox< Vec3d >
openvdb::v4_0_2::tools::particle_atlas_internal::SplittableParticleArray::getPos
void getPos(size_t n, PosType &xyz) const
Definition: ParticleAtlas.h:345
openvdb::v4_0_2::tools::particle_atlas_internal::BBoxFilter::IndexDeque
std::deque< IndexT > IndexDeque
Definition: ParticleAtlas.h:596
openvdb::v4_0_2::tools::particle_atlas_internal::RadialRangeFilter::RadialRangeFilter
RadialRangeFilter(RangeDeque &ranges, IndexDeque &indices, const PosType &xyz, ScalarType radius, const ParticleArrayType &particles, bool hasUniformRadius=false)
Definition: ParticleAtlas.h:510