OpenVDB: ParticlesToLevelSet.h Source File

OpenVDB 3.1.0

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

ParticlesToLevelSet.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2015 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 //
96
97 #ifndef OPENVDB_TOOLS_PARTICLES_TO_LEVELSET_HAS_BEEN_INCLUDED
98 #define OPENVDB_TOOLS_PARTICLES_TO_LEVELSET_HAS_BEEN_INCLUDED
99
100 #include <tbb/parallel_reduce.h>
101 #include <tbb/blocked_range.h>
102 #include <boost/bind.hpp>
103 #include <boost/function.hpp>
104 #include <boost/type_traits/is_floating_point.hpp>
105 #include <boost/utility/enable_if.hpp>
106 #include <boost/mpl/if.hpp>
107 #include <openvdb/Types.h>
108 #include <openvdb/Grid.h>
109 #include <openvdb/math/Math.h>
110 #include <openvdb/math/Transform.h>
111 #include <openvdb/util/NullInterrupter.h>
112 #include "Composite.h" // for csgUnion()
113 #include "PointPartitioner.h"
114 #include "Prune.h"
115 #include "SignedFloodFill.h"
116
117 namespace openvdb {
118 OPENVDB_USE_VERSION_NAMESPACE
119 namespace OPENVDB_VERSION_NAME {
120 namespace tools {
121
122 namespace p2ls_internal {
123 // This is a simple type that combines a distance value and a particle
124 // attribute. It's required for attribute transfer which is performed
125 // in the ParticlesToLevelSet::Raster member class defined below.
126 template<typename VisibleT, typename BlindT> class BlindData;
127 }// namespace p2ls_internal
128
129
130 template<typename SdfGridT,
131 typename AttributeT = void,
132 typename InterrupterT = util::NullInterrupter>
133 class ParticlesToLevelSet
134 {
135 public:
136 typedef typename boost::is_void<AttributeT>::type DisableT;
137 typedef InterrupterT InterrupterType;
138
139 typedef SdfGridT SdfGridType;
140 typedef typename SdfGridT::ValueType SdfType;
141
142 typedef typename boost::mpl::if_<DisableT, size_t, AttributeT>::type AttType;
143 typedef typename SdfGridT::template ValueConverter<AttType>::Type AttGridType;
144
145 BOOST_STATIC_ASSERT(boost::is_floating_point<SdfType>::value);
146
168 explicit ParticlesToLevelSet(SdfGridT& grid, InterrupterT* interrupt = NULL);
169
171 ~ParticlesToLevelSet() { delete mBlindGrid; }
172
181 void finalize(bool prune = false);
182
188 typename AttGridType::Ptr attributeGrid() { return mAttGrid; }
189
191 Real getVoxelSize() const { return mDx; }
192
194 Real getHalfWidth() const { return mHalfWidth; }
195
197 Real getRmin() const { return mRmin; }
199 Real getRmax() const { return mRmax; }
200
202 bool ignoredParticles() const { return mMinCount>0 || mMaxCount>0; }
204 size_t getMinCount() const { return mMinCount; }
206 size_t getMaxCount() const { return mMaxCount; }
207
209 void setRmin(Real Rmin) { mRmin = math::Max(Real(0),Rmin); }
211 void setRmax(Real Rmax) { mRmax = math::Max(mRmin,Rmax); }
212
214 int getGrainSize() const { return mGrainSize; }
217 void setGrainSize(int grainSize) { mGrainSize = grainSize; }
218
223 template <typename ParticleListT>
224 void rasterizeSpheres(const ParticleListT& pa);
225
231 template <typename ParticleListT>
232 void rasterizeSpheres(const ParticleListT& pa, Real radius);
233
250 template <typename ParticleListT>
251 void rasterizeTrails(const ParticleListT& pa, Real delta=1.0);
252
253 private:
254 typedef p2ls_internal::BlindData<SdfType, AttType> BlindType;
255 typedef typename SdfGridT::template ValueConverter<BlindType>::Type BlindGridType;
256
258 template<typename ParticleListT, typename GridT> struct Raster;
259
260 SdfGridType* mSdfGrid;
261 typename AttGridType::Ptr mAttGrid;
262 BlindGridType* mBlindGrid;
263 InterrupterT* mInterrupter;
264 Real mDx, mHalfWidth;
265 Real mRmin, mRmax;//ignore particles outside this range of radii in voxel
266 size_t mMinCount, mMaxCount;//counters for ignored particles!
267 int mGrainSize;
268
269 };//end of ParticlesToLevelSet class
270
271 template<typename SdfGridT, typename AttributeT, typename InterrupterT>
272 inline ParticlesToLevelSet<SdfGridT, AttributeT, InterrupterT>::
273 ParticlesToLevelSet(SdfGridT& grid, InterrupterT* interrupter) :
274 mSdfGrid(&grid),
275 mBlindGrid(NULL),
276 mInterrupter(interrupter),
277 mDx(grid.voxelSize()[0]),
278 mHalfWidth(grid.background()/mDx),
279 mRmin(1.5),// corresponds to the Nyquist grid sampling frequency
280 mRmax(100.0),// corresponds to a huge particle (probably too large!)
281 mMinCount(0),
282 mMaxCount(0),
283 mGrainSize(1)
284 {
285 if (!mSdfGrid->hasUniformVoxels() ) {
286 OPENVDB_THROW(RuntimeError,
287 "ParticlesToLevelSet only supports uniform voxels!");
288 }
289 if (mSdfGrid->getGridClass() != GRID_LEVEL_SET) {
290 OPENVDB_THROW(RuntimeError,
291 "ParticlesToLevelSet only supports level sets!"
292 "\nUse Grid::setGridClass(openvdb::GRID_LEVEL_SET)");
293 }
294
295 if (!DisableT::value) {
296 mBlindGrid = new BlindGridType(BlindType(grid.background()));
297 mBlindGrid->setTransform(mSdfGrid->transform().copy());
298 }
299 }
300
301 template<typename SdfGridT, typename AttributeT, typename InterrupterT>
302 template <typename ParticleListT>
303 inline void ParticlesToLevelSet<SdfGridT, AttributeT, InterrupterT>::
304 rasterizeSpheres(const ParticleListT& pa)
305 {
306 if (DisableT::value) {
307 Raster<ParticleListT, SdfGridT> r(*this, mSdfGrid, pa);
308 r.rasterizeSpheres();
309 } else {
310 Raster<ParticleListT, BlindGridType> r(*this, mBlindGrid, pa);
311 r.rasterizeSpheres();
312 }
313 }
314
315 template<typename SdfGridT, typename AttributeT, typename InterrupterT>
316 template <typename ParticleListT>
317 inline void ParticlesToLevelSet<SdfGridT, AttributeT, InterrupterT>::
318 rasterizeSpheres(const ParticleListT& pa, Real radius)
319 {
320 if (DisableT::value) {
321 Raster<ParticleListT, SdfGridT> r(*this, mSdfGrid, pa);
322 r.rasterizeSpheres(radius/mDx);
323 } else {
324 Raster<ParticleListT, BlindGridType> r(*this, mBlindGrid, pa);
325 r.rasterizeSpheres(radius/mDx);
326 }
327 }
328
329 template<typename SdfGridT, typename AttributeT, typename InterrupterT>
330 template <typename ParticleListT>
331 inline void ParticlesToLevelSet<SdfGridT, AttributeT, InterrupterT>::
332 rasterizeTrails(const ParticleListT& pa, Real delta)
333 {
334 if (DisableT::value) {
335 Raster<ParticleListT, SdfGridT> r(*this, mSdfGrid, pa);
336 r.rasterizeTrails(delta);
337 } else {
338 Raster<ParticleListT, BlindGridType> r(*this, mBlindGrid, pa);
339 r.rasterizeTrails(delta);
340 }
341 }
342
343 template<typename SdfGridT, typename AttributeT, typename InterrupterT>
344 inline void
345 ParticlesToLevelSet<SdfGridT, AttributeT, InterrupterT>::finalize(bool prune)
346 {
347 if (mBlindGrid==NULL) {
348 if (prune) tools::pruneLevelSet(mSdfGrid->tree());
349 return;
350 } else {
351 if (prune) tools::prune(mBlindGrid->tree());
352 }
353
354 typedef typename SdfGridType::TreeType SdfTreeT;
355 typedef typename AttGridType::TreeType AttTreeT;
356 typedef typename BlindGridType::TreeType BlindTreeT;
357 // Use topology copy constructors since output grids have the same topology as mBlindDataGrid
358 const BlindTreeT& tree = mBlindGrid->tree();
359
360 // New level set tree
361 typename SdfTreeT::Ptr sdfTree(new SdfTreeT(
362 tree, tree.background().visible(), openvdb::TopologyCopy()));
363
364 // Note this overwrites any existing attribute grids!
365 typename AttTreeT::Ptr attTree(new AttTreeT(
366 tree, tree.background().blind(), openvdb::TopologyCopy()));
367 mAttGrid = typename AttGridType::Ptr(new AttGridType(attTree));
368 mAttGrid->setTransform(mBlindGrid->transform().copy());
369
370 // Extract the level set and IDs from mBlindDataGrid. We will
371 // explore the fact that by design active values always live
372 // at the leaf node level, i.e. level sets have no active tiles!
373 typedef typename BlindTreeT::LeafCIter LeafIterT;
374 typedef typename BlindTreeT::LeafNodeType LeafT;
375 typedef typename SdfTreeT::LeafNodeType SdfLeafT;
376 typedef typename AttTreeT::LeafNodeType AttLeafT;
377 for (LeafIterT n = tree.cbeginLeaf(); n; ++n) {
378 const LeafT& leaf = *n;
379 const openvdb::Coord xyz = leaf.origin();
380 // Get leafnodes that were allocated during topology construction!
381 SdfLeafT* sdfLeaf = sdfTree->probeLeaf(xyz);
382 AttLeafT* attLeaf = attTree->probeLeaf(xyz);
383 // Use linear offset (vs coordinate) access for better performance!
384 typename LeafT::ValueOnCIter m=leaf.cbeginValueOn();
385 if (!m) {//no active values in leaf node so copy everything
386 for (openvdb::Index k = 0; k!=LeafT::SIZE; ++k) {
387 const BlindType& v = leaf.getValue(k);
388 sdfLeaf->setValueOnly(k, v.visible());
389 attLeaf->setValueOnly(k, v.blind());
390 }
391 } else {//only copy active values (using flood fill for the inactive values)
392 for(; m; ++m) {
393 const openvdb::Index k = m.pos();
394 const BlindType& v = *m;
395 sdfLeaf->setValueOnly(k, v.visible());
396 attLeaf->setValueOnly(k, v.blind());
397 }
398 }
399 }
400
401 tools::signedFloodFill(*sdfTree);//required since we only transferred active voxels!
402
403 if (mSdfGrid->empty()) {
404 mSdfGrid->setTree(sdfTree);
405 } else {
406 tools::csgUnion(mSdfGrid->tree(), *sdfTree, /*prune=*/true);
407 }
408 }
409
411
412 template<typename SdfGridT, typename AttributeT, typename InterrupterT>
413 template<typename ParticleListT, typename GridT>
414 struct ParticlesToLevelSet<SdfGridT, AttributeT, InterrupterT>::Raster
415 {
416 typedef typename boost::is_void<AttributeT>::type DisableT;
417 typedef ParticlesToLevelSet<SdfGridT, AttributeT, InterrupterT> ParticlesToLevelSetT;
418 typedef typename ParticlesToLevelSetT::SdfType SdfT;//type of signed distance values
419 typedef typename ParticlesToLevelSetT::AttType AttT;//type of particle attribute
420 typedef typename GridT::ValueType ValueT;
421 typedef typename GridT::Accessor AccessorT;
422 typedef typename GridT::TreeType TreeT;
423 typedef typename TreeT::LeafNodeType LeafNodeT;
424 typedef PointPartitioner<Index32, LeafNodeT::LOG2DIM> PointPartitionerT;
425
426
428 Raster(ParticlesToLevelSetT& parent, GridT* grid, const ParticleListT& particles)
429 : mParent(parent)
430 , mParticles(particles)
431 , mGrid(grid)
432 , mMap(*(mGrid->transform().baseMap()))
433 , mMinCount(0)
434 , mMaxCount(0)
435 , mIsCopy(false)
436 {
437 mPointPartitioner = new PointPartitionerT();
438 mPointPartitioner->construct(particles, mGrid->transform());
439 }
440
442 Raster(Raster& other, tbb::split)
443 : mParent(other.mParent)
444 , mParticles(other.mParticles)
445 , mGrid(new GridT(*other.mGrid, openvdb::ShallowCopy()))
446 , mMap(other.mMap)
447 , mMinCount(0)
448 , mMaxCount(0)
449 , mTask(other.mTask)
450 , mIsCopy(true)
451 , mPointPartitioner(other.mPointPartitioner)
452 {
453 mGrid->newTree();
454 }
455
456 virtual ~Raster() {
457
458 // Copies construct temporary grids that have to be deleted
459 // but the original has ownership of the bucket array
460 if (mIsCopy) {
461 delete mGrid;
462 } else {
463 delete mPointPartitioner;
464 }
465 }
466
469 void rasterizeSpheres()
470 {
471 mMinCount = mMaxCount = 0;
472 if (mParent.mInterrupter) {
473 mParent.mInterrupter->start("Rasterizing particles to level set using spheres");
474 }
475 mTask = boost::bind(&Raster::rasterSpheres, _1, _2);
476 this->cook();
477 if (mParent.mInterrupter) mParent.mInterrupter->end();
478 }
482 void rasterizeSpheres(Real radius)
483 {
484 mMinCount = radius < mParent.mRmin ? mParticles.size() : 0;
485 mMaxCount = radius > mParent.mRmax ? mParticles.size() : 0;
486 if (mMinCount>0 || mMaxCount>0) {//skipping all particles!
487 mParent.mMinCount = mMinCount;
488 mParent.mMaxCount = mMaxCount;
489 } else {
490 if (mParent.mInterrupter) {
491 mParent.mInterrupter->start(
492 "Rasterizing particles to level set using const spheres");
493 }
494 mTask = boost::bind(&Raster::rasterFixedSpheres, _1, _2, SdfT(radius));
495 this->cook();
496 if (mParent.mInterrupter) mParent.mInterrupter->end();
497 }
498 }
513 void rasterizeTrails(Real delta=1.0)
514 {
515 mMinCount = mMaxCount = 0;
516 if (mParent.mInterrupter) {
517 mParent.mInterrupter->start("Rasterizing particles to level set using trails");
518 }
519 mTask = boost::bind(&Raster::rasterTrails, _1, _2, SdfT(delta));
520 this->cook();
521 if (mParent.mInterrupter) mParent.mInterrupter->end();
522 }
523
525 void operator()(const tbb::blocked_range<size_t>& r)
526 {
527 assert(mTask);
528 mTask(this, r);
529 mParent.mMinCount = mMinCount;
530 mParent.mMaxCount = mMaxCount;
531 }
532
534 void join(Raster& other)
535 {
536 tools::csgUnion(*mGrid, *other.mGrid, /*prune=*/true);
537 mMinCount += other.mMinCount;
538 mMaxCount += other.mMaxCount;
539 }
540 private:
542 Raster& operator=(const Raster&) { return *this; }
543
545 bool ignoreParticle(SdfT R)
546 {
547 if (R < mParent.mRmin) {// below the cutoff radius
548 ++mMinCount;
549 return true;
550 }
551 if (R > mParent.mRmax) {// above the cutoff radius
552 ++mMaxCount;
553 return true;
554 }
555 return false;
556 }
561 void rasterSpheres(const tbb::blocked_range<size_t>& r)
562 {
563 AccessorT acc = mGrid->getAccessor(); // local accessor
564 bool run = true;
565 const SdfT invDx = SdfT(1/mParent.mDx);
566 AttT att;
567 Vec3R pos;
568 Real rad;
569
570 // Loop over buckets
571 for (size_t n = r.begin(), N = r.end(); n < N; ++n) {
572 // Loop over particles in bucket n.
573 typename PointPartitionerT::IndexIterator iter = mPointPartitioner->indices(n);
574 for ( ; run && iter; ++iter) {
575 const Index32& id = *iter;
576 mParticles.getPosRad(id, pos, rad);
577 const SdfT R = SdfT(invDx * rad);// in voxel units
578 if (this->ignoreParticle(R)) continue;
579 const Vec3R P = mMap.applyInverseMap(pos);
580 this->getAtt<DisableT>(id, att);
581 run = this->makeSphere(P, R, att, acc);
582 }//end loop over particles
583 }//end loop over buckets
584 }
585
590 void rasterFixedSpheres(const tbb::blocked_range<size_t>& r, SdfT R)
591 {
592 const SdfT
593 dx = static_cast<SdfT>(mParent.mDx),
594 w = static_cast<SdfT>(mParent.mHalfWidth); // in voxel units
595 AccessorT acc = mGrid->getAccessor(); // local accessor
596 const ValueT inside = -mGrid->background();
597 const SdfT max = R + w;// maximum distance in voxel units
598 const SdfT max2 = math::Pow2(max);//square of maximum distance in voxel units
599 const SdfT min2 = math::Pow2(math::Max(SdfT(0), R - w));//square of minimum distance
600 ValueT v;
601 size_t count = 0;
602 AttT att;
603 Vec3R pos;
604
605 // Loop over buckets
606 for (size_t n = r.begin(), N = r.end(); n < N; ++n) {
607 // Loop over particles in bucket n.
608 typename PointPartitionerT::IndexIterator iter = mPointPartitioner->indices(n);
609 for ( ; iter; ++iter) {
610 const Index32& id = *iter;
611 this->getAtt<DisableT>(id, att);
612 mParticles.getPos(id, pos);
613 const Vec3R P = mMap.applyInverseMap(pos);
614 const Coord a(math::Floor(P[0]-max),math::Floor(P[1]-max),math::Floor(P[2]-max));
615 const Coord b(math::Ceil( P[0]+max),math::Ceil( P[1]+max),math::Ceil( P[2]+max));
616 for (Coord c = a; c.x() <= b.x(); ++c.x()) {
617 //only check interrupter every 32'th scan in x
618 if (!(count++ & ((1<<5)-1)) && util::wasInterrupted(mParent.mInterrupter)) {
619 tbb::task::self().cancel_group_execution();
620 return;
621 }
622 SdfT x2 = static_cast<SdfT>(math::Pow2(c.x() - P[0]));
623 for (c.y() = a.y(); c.y() <= b.y(); ++c.y()) {
624 SdfT x2y2 = static_cast<SdfT>(x2 + math::Pow2(c.y() - P[1]));
625 for (c.z() = a.z(); c.z() <= b.z(); ++c.z()) {
626 SdfT x2y2z2 = static_cast<SdfT>(
627 x2y2 + math::Pow2(c.z()- P[2])); // square distance from c to P
628 if (x2y2z2 >= max2 || (!acc.probeValue(c,v) && v<ValueT(0)))
629 continue;//outside narrow band of particle or inside existing level set
630 if (x2y2z2 <= min2) {//inside narrow band of the particle.
631 acc.setValueOff(c, inside);
632 continue;
633 }
634 // convert signed distance from voxel units to world units
635 const ValueT d=Merge(dx*(math::Sqrt(x2y2z2) - R), att);
636 if (d < v) acc.setValue(c, d);//CSG union
637 }//end loop over z
638 }//end loop over y
639 }//end loop over x
640 }//end loop over particles
641 }// end loop over buckts
642 }
643
648 void rasterTrails(const tbb::blocked_range<size_t>& r, SdfT delta)
649 {
650 AccessorT acc = mGrid->getAccessor(); // local accessor
651 bool run = true;
652 AttT att;
653 Vec3R pos, vel;
654 Real rad;
655 const Vec3R origin = mMap.applyInverseMap(Vec3R(0,0,0));
656 const SdfT Rmin = SdfT(mParent.mRmin), invDx = SdfT(1/mParent.mDx);
657
658 // Loop over buckets
659 for (size_t n = r.begin(), N = r.end(); n < N; ++n) {
660 // Loop over particles in bucket n.
661 typename PointPartitionerT::IndexIterator iter = mPointPartitioner->indices(n);
662 for ( ; run && iter; ++iter) {
663 const Index32& id = *iter;
664 mParticles.getPosRadVel(id, pos, rad, vel);
665 const SdfT R0 = SdfT(invDx*rad);
666 if (this->ignoreParticle(R0)) continue;
667 this->getAtt<DisableT>(id, att);
668 const Vec3R P0 = mMap.applyInverseMap(pos);
669 const Vec3R V = mMap.applyInverseMap(vel) - origin;//exclude translation
670 const SdfT speed = SdfT(V.length()), inv_speed = SdfT(1.0/speed);
671 const Vec3R Nrml = -V*inv_speed;// inverse normalized direction
672 Vec3R P = P0;// local position of instance
673 SdfT R = R0, d=0;// local radius and length of trail
674 for (size_t m=0; run && d <= speed ; ++m) {
675 run = this->makeSphere(P, R, att, acc);
676 P += 0.5*delta*R*Nrml;// adaptive offset along inverse velocity direction
677 d = SdfT((P-P0).length());// current length of trail
678 R = R0-(R0-Rmin)*d*inv_speed;// R = R0 -> mRmin(e.g. 1.5)
679 }//end loop over sphere instances
680 }//end loop over particles
681 }//end loop over buckets
682 }
683
684 void cook()
685 {
686 // parallelize over the point buckets
687 const Index32 bucketCount = Index32(mPointPartitioner->size());
688
689 if (mParent.mGrainSize>0) {
690 tbb::parallel_reduce(
691 tbb::blocked_range<size_t>(0, bucketCount, mParent.mGrainSize), *this);
692 } else {
693 (*this)(tbb::blocked_range<size_t>(0, bucketCount));
694 }
695 }
696
712 bool makeSphere(const Vec3R &P, SdfT R, const AttT& att, AccessorT& acc)
713 {
714 const ValueT inside = -mGrid->background();
715 const SdfT dx = SdfT(mParent.mDx), w = SdfT(mParent.mHalfWidth);
716 const SdfT max = R + w;// maximum distance in voxel units
717 const Coord a(math::Floor(P[0]-max),math::Floor(P[1]-max),math::Floor(P[2]-max));
718 const Coord b(math::Ceil( P[0]+max),math::Ceil( P[1]+max),math::Ceil( P[2]+max));
719 const SdfT max2 = math::Pow2(max);//square of maximum distance in voxel units
720 const SdfT min2 = math::Pow2(math::Max(SdfT(0), R - w));//square of minimum distance
721 ValueT v;
722 size_t count = 0;
723 for ( Coord c = a; c.x() <= b.x(); ++c.x() ) {
724 //only check interrupter every 32'th scan in x
725 if (!(count++ & ((1<<5)-1)) && util::wasInterrupted(mParent.mInterrupter)) {
726 tbb::task::self().cancel_group_execution();
727 return false;
728 }
729 SdfT x2 = SdfT(math::Pow2(c.x() - P[0]));
730 for (c.y() = a.y(); c.y() <= b.y(); ++c.y()) {
731 SdfT x2y2 = SdfT(x2 + math::Pow2(c.y() - P[1]));
732 for (c.z() = a.z(); c.z() <= b.z(); ++c.z()) {
733 SdfT x2y2z2 = SdfT(x2y2 + math::Pow2(c.z()-P[2]));//square distance from c to P
734 if (x2y2z2 >= max2 || (!acc.probeValue(c,v) && v<ValueT(0)))
735 continue;//outside narrow band of the particle or inside existing level set
736 if (x2y2z2 <= min2) {//inside narrow band of the particle.
737 acc.setValueOff(c, inside);
738 continue;
739 }
740 // convert signed distance from voxel units to world units
741 //const ValueT d=dx*(math::Sqrt(x2y2z2) - R);
742 const ValueT d=Merge(dx*(math::Sqrt(x2y2z2) - R), att);
743 if (d < v) acc.setValue(c, d);//CSG union
744 }//end loop over z
745 }//end loop over y
746 }//end loop over x
747 return true;
748 }
749 typedef typename boost::function<void (Raster*, const tbb::blocked_range<size_t>&)> FuncType;
750
751 template <typename DisableType>
752 typename boost::enable_if<DisableType>::type
753 getAtt(size_t, AttT&) const {;}
754
755 template <typename DisableType>
756 typename boost::disable_if<DisableType>::type
757 getAtt(size_t n, AttT& a) const { mParticles.getAtt(n, a); }
758
759 template <typename T>
760 typename boost::enable_if<boost::is_same<T,ValueT>, ValueT>::type
761 Merge(T s, const AttT&) const { return s; }
762
763 template <typename T>
764 typename boost::disable_if<boost::is_same<T,ValueT>, ValueT>::type
765 Merge(T s, const AttT& a) const { return ValueT(s,a); }
766
767 ParticlesToLevelSetT& mParent;
768 const ParticleListT& mParticles;//list of particles
769 GridT* mGrid;
770 const math::MapBase& mMap;
771 size_t mMinCount, mMaxCount;//counters for ignored particles!
772 FuncType mTask;
773 const bool mIsCopy;
774 PointPartitionerT* mPointPartitioner;
775 };//end of Raster struct
776
777
779
780 namespace p2ls_internal {
781
782 // This is a simple type that combines a distance value and a particle
783 // attribute. It's required for attribute transfer which is defined in the
784 // Raster class above.
785 template<typename VisibleT, typename BlindT>
786 class BlindData
787 {
788 public:
789 typedef VisibleT type;
790 typedef VisibleT VisibleType;
791 typedef BlindT BlindType;
792
793 BlindData() {}
794 explicit BlindData(VisibleT v) : mVisible(v), mBlind(zeroVal<BlindType>()) {}
795 BlindData(VisibleT v, BlindT b) : mVisible(v), mBlind(b) {}
796 BlindData& operator=(const BlindData& rhs)
797 {
798 mVisible = rhs.mVisible;
799 mBlind = rhs.mBlind;
800 return *this;
801 }
802 const VisibleT& visible() const { return mVisible; }
803 const BlindT& blind() const { return mBlind; }
804 OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
805 bool operator==(const BlindData& rhs) const { return mVisible == rhs.mVisible; }
806 OPENVDB_NO_FP_EQUALITY_WARNING_END
807 bool operator< (const BlindData& rhs) const { return mVisible < rhs.mVisible; }
808 bool operator> (const BlindData& rhs) const { return mVisible > rhs.mVisible; }
809 BlindData operator+(const BlindData& rhs) const { return BlindData(mVisible + rhs.mVisible); }
810 BlindData operator+(const VisibleT& rhs) const { return BlindData(mVisible + rhs); }
811 BlindData operator-(const BlindData& rhs) const { return BlindData(mVisible - rhs.mVisible); }
812 BlindData operator-() const { return BlindData(-mVisible, mBlind); }
813
814 protected:
815 VisibleT mVisible;
816 BlindT mBlind;
817 };
818
819 // Required by several of the tree nodes
820 template<typename VisibleT, typename BlindT>
821 inline std::ostream& operator<<(std::ostream& ostr, const BlindData<VisibleT, BlindT>& rhs)
822 {
823 ostr << rhs.visible();
824 return ostr;
825 }
826
827 // Required by math::Abs
828 template<typename VisibleT, typename BlindT>
829 inline BlindData<VisibleT, BlindT> Abs(const BlindData<VisibleT, BlindT>& x)
830 {
831 return BlindData<VisibleT, BlindT>(math::Abs(x.visible()), x.blind());
832 }
833
834 } // namespace p2ls_internal
835
837
838 } // namespace tools
839 } // namespace OPENVDB_VERSION_NAME
840 } // namespace openvdb
841
842 #endif // OPENVDB_TOOLS_PARTICLES_TO_LEVELSET_HAS_BEEN_INCLUDED
843
844 // Copyright (c) 2012-2015 DreamWorks Animation LLC
845 // All rights reserved. This software is distributed under the
846 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v3_1_0::tools::ParticlesToLevelSet::getRmin
Real getRmin() const
Return the smallest radius allowed in voxel units.
Definition: ParticlesToLevelSet.h:197
openvdb::v3_1_0::tools::p2ls_internal::BlindData::BlindType
BlindT BlindType
Definition: ParticlesToLevelSet.h:791
openvdb::v3_1_0::tools::p2ls_internal::BlindData::blind
const BlindT & blind() const
Definition: ParticlesToLevelSet.h:803
openvdb::v3_1_0::tools::ParticlesToLevelSet::finalize
void finalize(bool prune=false)
This methods syncs up the level set and attribute grids and therefore needs to be called before any o...
Definition: ParticlesToLevelSet.h:345
openvdb::v3_1_0::Index
Index32 Index
Definition: Types.h:58
openvdb::v3_1_0::util::wasInterrupted
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76
Types.h
openvdb::v3_1_0::tools::csgUnion
OPENVDB_STATIC_SPECIALIZATION void csgUnion(GridOrTreeT &a, GridOrTreeT &b, bool prune=true)
Given two level set grids, replace the A grid with the union of A and B.
Definition: Composite.h:550
NullInterrupter.h
openvdb::v3_1_0::zeroVal
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:94
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v3_1_0::math::Abs
int32_t Abs(int32_t i)
Return the absolute value of the given quantity.
Definition: Math.h:293
Composite.h
Functions to efficiently perform various compositing operations on grids.
openvdb::v3_1_0::tools::ParticlesToLevelSet::~ParticlesToLevelSet
~ParticlesToLevelSet()
Destructor.
Definition: ParticlesToLevelSet.h:171
openvdb::v3_1_0::tools::p2ls_internal::BlindData::operator+
BlindData operator+(const VisibleT &rhs) const
Definition: ParticlesToLevelSet.h:810
openvdb::v3_1_0::math::MapBase
Abstract base class for maps.
Definition: Maps.h:159
openvdb::v3_1_0::Vec3R
math::Vec3< Real > Vec3R
Definition: Types.h:76
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
openvdb::v3_1_0::Index32
uint32_t Index32
Definition: Types.h:56
openvdb::v3_1_0::tools::ParticlesToLevelSet::ignoredParticles
bool ignoredParticles() const
Return true if any particles were ignored due to their size.
Definition: ParticlesToLevelSet.h:202
openvdb::v3_1_0::tools::ParticlesToLevelSet::getVoxelSize
Real getVoxelSize() const
Return the size of a voxel in world units.
Definition: ParticlesToLevelSet.h:191
openvdb::v3_1_0::tools::p2ls_internal::BlindData::mBlind
BlindT mBlind
Definition: ParticlesToLevelSet.h:816
openvdb::v3_1_0::math::operator<
bool operator<(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:158
Transform.h
openvdb::v3_1_0::math::Ceil
int Ceil(float x)
Return the ceiling of x.
Definition: Math.h:804
openvdb::v3_1_0::tools::PointPartitioner
Definition: PointPartitioner.h:101
openvdb::v3_1_0::math::operator>
bool operator>(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:170
openvdb::v3_1_0::tools::ParticlesToLevelSet
Definition: ParticlesToLevelSet.h:133
PointPartitioner.h
Spatially partitions points using a parallel radix-based sorting algorithm.
Prune.h
Defined various multi-threaded utility functions for trees.
openvdb::v3_1_0::tools::ParticlesToLevelSet::getGrainSize
int getGrainSize() const
Returns the grain-size used for multi-threading.
Definition: ParticlesToLevelSet.h:214
openvdb::v3_1_0::tools::p2ls_internal::BlindData::visible
const VisibleT & visible() const
Definition: ParticlesToLevelSet.h:802
openvdb::v3_1_0::tools::p2ls_internal::BlindData::operator==
OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN bool operator==(const BlindData &rhs) const
Definition: ParticlesToLevelSet.h:805
openvdb::v3_1_0::tools::p2ls_internal::BlindData::BlindData
BlindData()
Definition: ParticlesToLevelSet.h:793
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:43
openvdb::v3_1_0::tools::ParticlesToLevelSet::getMaxCount
size_t getMaxCount() const
Return number of large particles that were ignore due to Rmax.
Definition: ParticlesToLevelSet.h:206
openvdb::v3_1_0::tools::ParticlesToLevelSet::rasterizeTrails
void rasterizeTrails(const ParticleListT &pa, Real delta=1.0)
Rasterize a trail per particle derived from their position, radius and velocity. Each trail is genera...
Definition: ParticlesToLevelSet.h:332
openvdb::v3_1_0::tools::p2ls_internal::BlindData::operator+
BlindData operator+(const BlindData &rhs) const
Definition: ParticlesToLevelSet.h:809
openvdb::v3_1_0::tools::ParticlesToLevelSet::SdfType
SdfGridT::ValueType SdfType
Definition: ParticlesToLevelSet.h:140
openvdb::v3_1_0::tools::ParticlesToLevelSet::rasterizeSpheres
void rasterizeSpheres(const ParticleListT &pa)
Rasterize a sphere per particle derived from their position and radius. All spheres are CSG unioned...
Definition: ParticlesToLevelSet.h:304
openvdb::v3_1_0::util::NullInterrupter
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
openvdb::v3_1_0::tools::ParticlesToLevelSet::setRmax
void setRmax(Real Rmax)
set the largest radius allowed in voxel units
Definition: ParticlesToLevelSet.h:211
openvdb::v3_1_0::tools::ParticlesToLevelSet::attributeGrid
AttGridType::Ptr attributeGrid()
Return a shared pointer to the grid containing the (optional) attribute.
Definition: ParticlesToLevelSet.h:188
SignedFloodFill.h
Propagates the sign of distance values from the active voxels in the narrow band to the inactive valu...
openvdb::v3_1_0::tools::p2ls_internal::BlindData
Definition: ParticlesToLevelSet.h:126
openvdb::v3_1_0::tools::p2ls_internal::BlindData::operator-
BlindData operator-() const
Definition: ParticlesToLevelSet.h:812
openvdb::v3_1_0::math::Vec3< Real >
openvdb::v3_1_0::tools::pruneLevelSet
void pruneLevelSet(TreeT &tree, bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing nodes whose values are all inactive with inactive ...
Definition: Prune.h:402
openvdb::v3_1_0::RuntimeError
Definition: Exceptions.h:86
openvdb
Definition: Exceptions.h:39
openvdb::v3_1_0::TopologyCopy
Definition: Types.h:419
openvdb::v3_1_0::tools::prune
void prune(TreeT &tree, typename TreeT::ValueType tolerance=zeroVal< typename TreeT::ValueType >(), bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing with tiles any nodes whose values are all the same...
Definition: Prune.h:347
openvdb::v3_1_0::tools::ParticlesToLevelSet::setGrainSize
void setGrainSize(int grainSize)
Set the grain-size used for multi-threading.
Definition: ParticlesToLevelSet.h:217
OPENVDB_NO_FP_EQUALITY_WARNING_END
#define OPENVDB_NO_FP_EQUALITY_WARNING_END
Definition: Math.h:83
openvdb::v3_1_0::math::Vec3::length
T length() const
Length of the vector.
Definition: Vec3.h:212
openvdb::v3_1_0::math::Max
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:561
openvdb::v3_1_0::tools::p2ls_internal::BlindData::BlindData
BlindData(VisibleT v, BlindT b)
Definition: ParticlesToLevelSet.h:795
openvdb::v3_1_0::GRID_LEVEL_SET
Definition: Types.h:206
openvdb::v3_1_0::math::Pow2
Type Pow2(Type x)
Return .
Definition: Math.h:514
openvdb::v3_1_0::tools::ParticlesToLevelSet::InterrupterType
InterrupterT InterrupterType
Definition: ParticlesToLevelSet.h:137
OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
#define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
Definition: Math.h:82
openvdb::v3_1_0::tools::signedFloodFill
void signedFloodFill(TreeOrLeafManagerT &tree, bool threaded=true, size_t grainSize=1)
Set the values of all inactive voxels and tiles of a narrow-band level set from the signs of the acti...
Definition: SignedFloodFill.h:280
openvdb::v3_1_0::tools::ParticlesToLevelSet::setRmin
void setRmin(Real Rmin)
set the smallest radius allowed in voxel units
Definition: ParticlesToLevelSet.h:209
openvdb::v3_1_0::tools::ParticlesToLevelSet::SdfGridType
SdfGridT SdfGridType
Definition: ParticlesToLevelSet.h:139
openvdb::v3_1_0::tools::p2ls_internal::BlindData::type
VisibleT type
Definition: ParticlesToLevelSet.h:789
openvdb::v3_1_0::Real
double Real
Definition: Types.h:64
openvdb::v3_1_0::tools::composite::max
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:109
Grid.h
openvdb::v3_1_0::tools::p2ls_internal::BlindData::operator-
BlindData operator-(const BlindData &rhs) const
Definition: ParticlesToLevelSet.h:811
openvdb::v3_1_0::tools::Abs
MeshToVoxelEdgeData::EdgeData Abs(const MeshToVoxelEdgeData::EdgeData &x)
Definition: MeshToVolume.h:3387
openvdb::v3_1_0::ShallowCopy
Definition: Types.h:416
openvdb::v3_1_0::tools::ParticlesToLevelSet::DisableT
boost::is_void< AttributeT >::type DisableT
Definition: ParticlesToLevelSet.h:136
openvdb::v3_1_0::math::Floor
int Floor(float x)
Return the floor of x.
Definition: Math.h:796
openvdb::v3_1_0::tools::ParticlesToLevelSet::getRmax
Real getRmax() const
Return the largest radius allowed in voxel units.
Definition: ParticlesToLevelSet.h:199
openvdb::v3_1_0::tools::ParticlesToLevelSet::getHalfWidth
Real getHalfWidth() const
Return the half-width of the narrow band in voxel units.
Definition: ParticlesToLevelSet.h:194
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
openvdb::v3_1_0::math::Sqrt
float Sqrt(float x)
Return the square root of a floating-point value.
Definition: Math.h:709
openvdb::v3_1_0::tools::p2ls_internal::BlindData::VisibleType
VisibleT VisibleType
Definition: ParticlesToLevelSet.h:790
openvdb::v3_1_0::tools::ParticlesToLevelSet::AttType
boost::mpl::if_< DisableT, size_t, AttributeT >::type AttType
Definition: ParticlesToLevelSet.h:142
openvdb::v3_1_0::tools::ParticlesToLevelSet::getMinCount
size_t getMinCount() const
Return number of small particles that were ignore due to Rmin.
Definition: ParticlesToLevelSet.h:204
openvdb::v3_1_0::tools::p2ls_internal::BlindData::BlindData
BlindData(VisibleT v)
Definition: ParticlesToLevelSet.h:794
openvdb::v3_1_0::tools::p2ls_internal::BlindData::operator=
BlindData & operator=(const BlindData &rhs)
Definition: ParticlesToLevelSet.h:796
openvdb::v3_1_0::tools::p2ls_internal::BlindData::mVisible
VisibleT mVisible
Definition: ParticlesToLevelSet.h:815
openvdb::v3_1_0::tools::ParticlesToLevelSet::AttGridType
SdfGridT::template ValueConverter< AttType >::Type AttGridType
Definition: ParticlesToLevelSet.h:143