OpenVDB 5.1.0

DenseSparseTools.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 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
31 #ifndef OPENVDB_TOOLS_DENSESPARSETOOLS_HAS_BEEN_INCLUDED
32 #define OPENVDB_TOOLS_DENSESPARSETOOLS_HAS_BEEN_INCLUDED
33
34 #include <tbb/parallel_reduce.h>
35 #include <tbb/blocked_range3d.h>
36 #include <tbb/blocked_range2d.h>
37 #include <tbb/blocked_range.h>
38 #include <openvdb/Types.h>
39 #include <openvdb/tree/LeafManager.h>
40 #include "Dense.h"
41
42
43 namespace openvdb {
44 OPENVDB_USE_VERSION_NAMESPACE
45 namespace OPENVDB_VERSION_NAME {
46 namespace tools {
47
114 template<typename OpType, typename DenseType>
115 typename OpType::ResultTreeType::Ptr
116 extractSparseTree(const DenseType& dense, const OpType& functor,
117 const typename OpType::ResultValueType& background,
118 bool threaded = true);
119
123 template <typename DenseType, typename TreeType> struct DSConverter {
124 typedef typename DenseType::ValueType ValueType;
125
126 typedef typename TreeType::template ValueConverter<ValueType>::Type Type;
127 };
128
129
139 template<typename DenseType, typename MaskTreeType>
140 typename DSConverter<DenseType, MaskTreeType>::Type::Ptr
141 extractSparseTreeWithMask(const DenseType& dense,
142 const MaskTreeType& mask,
143 const typename DenseType::ValueType& background,
144 bool threaded = true);
145
146
167 template<typename ValueT, typename OpType>
168 void transformDense(Dense<ValueT, openvdb::tools::LayoutZYX>& dense,
169 const openvdb::CoordBBox& bbox, const OpType& op, bool parallel=true);
170
173 enum DSCompositeOp {
174 DS_OVER, DS_ADD, DS_SUB, DS_MIN, DS_MAX, DS_MULT, DS_SET
175 };
176
184 template<DSCompositeOp, typename TreeT>
185 void compositeToDense(Dense<typename TreeT::ValueType, LayoutZYX>& dense,
186 const TreeT& source,
187 const TreeT& alpha,
188 const typename TreeT::ValueType beta,
189 const typename TreeT::ValueType strength,
190 bool threaded = true);
191
192
196 template<typename OpType, typename DenseType>
197 class SparseExtractor
198 {
199
200 public:
201
202 typedef openvdb::math::Coord::ValueType Index;
203
204 typedef typename DenseType::ValueType DenseValueType;
205 typedef typename OpType::ResultTreeType ResultTreeType;
206 typedef typename ResultTreeType::ValueType ResultValueType;
207 typedef typename ResultTreeType::LeafNodeType ResultLeafNodeType;
208 typedef typename ResultTreeType::template ValueConverter<ValueMask>::Type MaskTree;
209
210 typedef tbb::blocked_range3d<Index, Index, Index> Range3d;
211
212
213 private:
214
215 const DenseType& mDense;
216 const OpType& mFunctor;
217 const ResultValueType mBackground;
218 const openvdb::math::CoordBBox mBBox;
219 const Index mWidth;
220 typename ResultTreeType::Ptr mMask;
221 openvdb::math::Coord mMin;
222
223
224 public:
225
226 SparseExtractor(const DenseType& dense, const OpType& functor,
227 const ResultValueType background) :
228 mDense(dense), mFunctor(functor),
229 mBackground(background),
230 mBBox(dense.bbox()),
231 mWidth(ResultLeafNodeType::DIM),
232 mMask( new ResultTreeType(mBackground))
233 {}
234
235
236 SparseExtractor(const DenseType& dense,
237 const openvdb::math::CoordBBox& bbox,
238 const OpType& functor,
239 const ResultValueType background) :
240 mDense(dense), mFunctor(functor),
241 mBackground(background),
242 mBBox(bbox),
243 mWidth(ResultLeafNodeType::DIM),
244 mMask( new ResultTreeType(mBackground))
245 {
246 // mBBox must be inside the coordinate rage of the dense grid
247 if (!dense.bbox().isInside(mBBox)) {
248 OPENVDB_THROW(ValueError, "Data extraction window out of bound");
249 }
250 }
251
252
253 SparseExtractor(SparseExtractor& other, tbb::split):
254 mDense(other.mDense), mFunctor(other.mFunctor),
255 mBackground(other.mBackground), mBBox(other.mBBox),
256 mWidth(other.mWidth),
257 mMask(new ResultTreeType(mBackground)),
258 mMin(other.mMin)
259 {}
260
261 typename ResultTreeType::Ptr extract(bool threaded = true) {
262
263
264 // Construct 3D range of leaf nodes that
265 // intersect mBBox.
266
267 // Snap the bbox to nearest leaf nodes min and max
268
269 openvdb::math::Coord padded_min = mBBox.min();
270 openvdb::math::Coord padded_max = mBBox.max();
271
272
273 padded_min &= ~(mWidth - 1);
274 padded_max &= ~(mWidth - 1);
275
276 padded_max[0] += mWidth - 1;
277 padded_max[1] += mWidth - 1;
278 padded_max[2] += mWidth - 1;
279
280
281 // number of leaf nodes in each direction
282 // division by leaf width, e.g. 8 in most cases
283
284 const Index xleafCount = ( padded_max.x() - padded_min.x() + 1 ) / mWidth;
285 const Index yleafCount = ( padded_max.y() - padded_min.y() + 1 ) / mWidth;
286 const Index zleafCount = ( padded_max.z() - padded_min.z() + 1 ) / mWidth;
287
288 mMin = padded_min;
289
290
291 Range3d leafRange(0, xleafCount, 1,
292 0, yleafCount, 1,
293 0, zleafCount, 1);
294
295
296 // Iterate over the leafnodes applying *this as a functor.
297 if (threaded) {
298 tbb::parallel_reduce(leafRange, *this);
299 } else {
300 (*this)(leafRange);
301 }
302
303 return mMask;
304 }
305
306
307 void operator()(const Range3d& range) {
308
309 ResultLeafNodeType* leaf = NULL;
310
311 // Unpack the range3d item.
312 const Index imin = range.pages().begin();
313 const Index imax = range.pages().end();
314
315 const Index jmin = range.rows().begin();
316 const Index jmax = range.rows().end();
317
318 const Index kmin = range.cols().begin();
319 const Index kmax = range.cols().end();
320
321
322 // loop over all the candidate leafs. Adding only those with 'true' values
323 // to the tree
324
325 for (Index i = imin; i < imax; ++i) {
326 for (Index j = jmin; j < jmax; ++j) {
327 for (Index k = kmin; k < kmax; ++k) {
328
329 // Calculate the origin of candidate leaf
330 const openvdb::math::Coord origin =
331 mMin + openvdb::math::Coord(mWidth * i,
332 mWidth * j,
333 mWidth * k );
334
335 if (leaf == NULL) {
336 leaf = new ResultLeafNodeType(origin, mBackground);
337 } else {
338 leaf->setOrigin(origin);
339 leaf->fill(mBackground);
340 leaf->setValuesOff();
341 }
342
343 // The bounding box for this leaf
344
345 openvdb::math::CoordBBox localBBox = leaf->getNodeBoundingBox();
346
347 // Shrink to the intersection with mBBox (i.e. the dense
348 // volume)
349
350 localBBox.intersect(mBBox);
351
352 // Early out for non-intersecting leafs
353
354 if (localBBox.empty()) continue;
355
356
357 const openvdb::math::Coord start = localBBox.getStart();
358 const openvdb::math::Coord end = localBBox.getEnd();
359
360 // Order the looping to respect the memory layout in
361 // the Dense source
362
363 if (mDense.memoryLayout() == openvdb::tools::LayoutZYX) {
364
365 openvdb::math::Coord ijk;
366 Index offset;
367 const DenseValueType* dp;
368 for (ijk[0] = start.x(); ijk[0] < end.x(); ++ijk[0] ) {
369 for (ijk[1] = start.y(); ijk[1] < end.y(); ++ijk[1] ) {
370 for (ijk[2] = start.z(),
371 offset = ResultLeafNodeType::coordToOffset(ijk),
372 dp = &mDense.getValue(ijk);
373 ijk[2] < end.z(); ++ijk[2], ++offset, ++dp) {
374
375 mFunctor(*dp, offset, leaf);
376 }
377 }
378 }
379
380 } else {
381
382 openvdb::math::Coord ijk;
383 const DenseValueType* dp;
384 for (ijk[2] = start.z(); ijk[2] < end.z(); ++ijk[2]) {
385 for (ijk[1] = start.y(); ijk[1] < end.y(); ++ijk[1]) {
386 for (ijk[0] = start.x(),
387 dp = &mDense.getValue(ijk);
388 ijk[0] < end.x(); ++ijk[0], ++dp) {
389
390 mFunctor(*dp, ijk, leaf);
391
392 }
393 }
394 }
395 }
396
397 // Only add non-empty leafs (empty is defined as all inactive)
398
399 if (!leaf->isEmpty()) {
400 mMask->addLeaf(leaf);
401 leaf = NULL;
402 }
403
404 }
405 }
406 }
407
408 // Clean up an unused leaf.
409
410 if (leaf != NULL) delete leaf;
411 }
412
413 void join(SparseExtractor& rhs) {
414 mMask->merge(*rhs.mMask);
415 }
416 }; // class SparseExtractor
417
418
419 template<typename OpType, typename DenseType>
420 typename OpType::ResultTreeType::Ptr
421 extractSparseTree(const DenseType& dense, const OpType& functor,
422 const typename OpType::ResultValueType& background,
423 bool threaded)
424 {
425
426 // Construct the mask using a parallel reduce pattern.
427 // Each thread computes disjoint mask-trees. The join merges
428 // into a single tree.
429
430 SparseExtractor<OpType, DenseType> extractor(dense, functor, background);
431
432 return extractor.extract(threaded);
433 }
434
435
439 template <typename DenseType, typename MaskTreeType>
440 class SparseMaskedExtractor
441 {
442 public:
443
444 typedef typename DSConverter<DenseType, MaskTreeType>::Type _ResultTreeType;
445 typedef _ResultTreeType ResultTreeType;
446 typedef typename ResultTreeType::LeafNodeType ResultLeafNodeType;
447 typedef typename ResultTreeType::ValueType ResultValueType;
448 typedef ResultValueType DenseValueType;
449
450 typedef typename ResultTreeType::template ValueConverter<ValueMask>::Type MaskTree;
451 typedef typename MaskTree::LeafCIter MaskLeafCIter;
452 typedef std::vector<const typename MaskTree::LeafNodeType*> MaskLeafVec;
453
454
455 SparseMaskedExtractor(const DenseType& dense,
456 const ResultValueType& background,
457 const MaskLeafVec& leafVec
458 ):
459 mDense(dense), mBackground(background), mBBox(dense.bbox()),
460 mLeafVec(leafVec),
461 mResult(new ResultTreeType(mBackground))
462 {}
463
464
465
466 SparseMaskedExtractor(const SparseMaskedExtractor& other, tbb::split):
467 mDense(other.mDense), mBackground(other.mBackground), mBBox(other.mBBox),
468 mLeafVec(other.mLeafVec), mResult( new ResultTreeType(mBackground))
469 {}
470
471 typename ResultTreeType::Ptr extract(bool threaded = true) {
472
473 tbb::blocked_range<size_t> range(0, mLeafVec.size());
474
475 if (threaded) {
476 tbb::parallel_reduce(range, *this);
477 } else {
478 (*this)(range);
479 }
480
481 return mResult;
482 }
483
484
485 // Used in looping over leaf nodes in the masked grid
486 // and using the active mask to select data to
487 void operator()(const tbb::blocked_range<size_t>& range) {
488
489 ResultLeafNodeType* leaf = NULL;
490
491
492 // loop over all the candidate leafs. Adding only those with 'true' values
493 // to the tree
494
495 for (size_t idx = range.begin(); idx < range.end(); ++ idx) {
496
497 const typename MaskTree::LeafNodeType* maskLeaf = mLeafVec[idx];
498
499 // The bounding box for this leaf
500
501 openvdb::math::CoordBBox localBBox = maskLeaf->getNodeBoundingBox();
502
503 // Shrink to the intersection with the dense volume
504
505 localBBox.intersect(mBBox);
506
507 // Early out if there was no intersection
508
509 if (localBBox.empty()) continue;
510
511 // Reset or allocate the target leaf
512
513 if (leaf == NULL) {
514 leaf = new ResultLeafNodeType(maskLeaf->origin(), mBackground);
515 } else {
516 leaf->setOrigin(maskLeaf->origin());
517 leaf->fill(mBackground);
518 leaf->setValuesOff();
519 }
520
521
522 // Iterate over the intersecting bounding box
523 // copying active values to the result tree
524
525 const openvdb::math::Coord start = localBBox.getStart();
526 const openvdb::math::Coord end = localBBox.getEnd();
527
528
529 openvdb::math::Coord ijk;
530
531 if (mDense.memoryLayout() == openvdb::tools::LayoutZYX
532 && maskLeaf->isDense()) {
533
534 Index offset;
535 const DenseValueType* src;
536 for (ijk[0] = start.x(); ijk[0] < end.x(); ++ijk[0] ) {
537 for (ijk[1] = start.y(); ijk[1] < end.y(); ++ijk[1] ) {
538 for (ijk[2] = start.z(),
539 offset = ResultLeafNodeType::coordToOffset(ijk),
540 src = &mDense.getValue(ijk);
541 ijk[2] < end.z(); ++ijk[2], ++offset, ++src) {
542
543 // copy into leaf
544 leaf->setValueOn(offset, *src);
545 }
546
547 }
548 }
549
550 } else {
551
552 Index offset;
553 for (ijk[0] = start.x(); ijk[0] < end.x(); ++ijk[0] ) {
554 for (ijk[1] = start.y(); ijk[1] < end.y(); ++ijk[1] ) {
555 for (ijk[2] = start.z(),
556 offset = ResultLeafNodeType::coordToOffset(ijk);
557 ijk[2] < end.z(); ++ijk[2], ++offset) {
558
559 if (maskLeaf->isValueOn(offset)) {
560 const ResultValueType denseValue = mDense.getValue(ijk);
561 leaf->setValueOn(offset, denseValue);
562 }
563 }
564 }
565 }
566 }
567 // Only add non-empty leafs (empty is defined as all inactive)
568
569 if (!leaf->isEmpty()) {
570 mResult->addLeaf(leaf);
571 leaf = NULL;
572 }
573 }
574
575 // Clean up an unused leaf.
576
577 if (leaf != NULL) delete leaf;
578 }
579
580 void join(SparseMaskedExtractor& rhs) {
581 mResult->merge(*rhs.mResult);
582 }
583
584
585 private:
586 const DenseType& mDense;
587 const ResultValueType mBackground;
588 const openvdb::math::CoordBBox& mBBox;
589 const MaskLeafVec& mLeafVec;
590
591 typename ResultTreeType::Ptr mResult;
592
593 }; // class SparseMaskedExtractor
594
595
597 template<typename _ResultTreeType, typename DenseValueType>
598 struct ExtractAll
599 {
600 typedef _ResultTreeType ResultTreeType;
601 typedef typename ResultTreeType::LeafNodeType ResultLeafNodeType;
602
603 template<typename CoordOrIndex> inline void
604 operator()(const DenseValueType& a, const CoordOrIndex& offset, ResultLeafNodeType* leaf) const
605 {
606 leaf->setValueOn(offset, a);
607 }
608 };
609
610
611 template <typename DenseType, typename MaskTreeType>
612 typename DSConverter<DenseType, MaskTreeType>::Type::Ptr
613 extractSparseTreeWithMask(const DenseType& dense,
614 const MaskTreeType& maskProxy,
615 const typename DenseType::ValueType& background,
616 bool threaded)
617 {
618 typedef SparseMaskedExtractor<DenseType, MaskTreeType> LeafExtractor;
619 typedef typename LeafExtractor::DenseValueType DenseValueType;
620 typedef typename LeafExtractor::ResultTreeType ResultTreeType;
621 typedef typename LeafExtractor::MaskLeafVec MaskLeafVec;
622 typedef typename LeafExtractor::MaskTree MaskTree;
623 typedef typename LeafExtractor::MaskLeafCIter MaskLeafCIter;
624 typedef ExtractAll<ResultTreeType, DenseValueType> ExtractionRule;
625
626 // Use Mask tree to hold the topology
627
628 MaskTree maskTree(maskProxy, false, TopologyCopy());
629
630 // Construct an array of pointers to the mask leafs.
631
632 const size_t leafCount = maskTree.leafCount();
633 MaskLeafVec leafarray(leafCount);
634 MaskLeafCIter leafiter = maskTree.cbeginLeaf();
635 for (size_t n = 0; n != leafCount; ++n, ++leafiter) {
636 leafarray[n] = leafiter.getLeaf();
637 }
638
639
640 // Extract the data that is masked leaf nodes in the mask.
641
642 LeafExtractor leafextractor(dense, background, leafarray);
643 typename ResultTreeType::Ptr resultTree = leafextractor.extract(threaded);
644
645
646 // Extract data that is masked by tiles in the mask.
647
648
649 // Loop over the mask tiles, extracting the data into new trees.
650 // These trees will be leaf-orthogonal to the leafTree (i.e. no leaf
651 // nodes will overlap). Merge these trees into the result.
652
653 typename MaskTreeType::ValueOnCIter tileIter(maskProxy);
654 tileIter.setMaxDepth(MaskTreeType::ValueOnCIter::LEAF_DEPTH - 1);
655
656 // Return the leaf tree if the mask had no tiles
657
658 if (!tileIter) return resultTree;
659
660 ExtractionRule allrule;
661
662 // Loop over the tiles in series, but the actual data extraction
663 // is in parallel.
664
665 CoordBBox bbox;
666 for ( ; tileIter; ++tileIter) {
667
668 // Find the intersection of the tile with the dense grid.
669
670 tileIter.getBoundingBox(bbox);
671 bbox.intersect(dense.bbox());
672
673 if (bbox.empty()) continue;
674
675 SparseExtractor<ExtractionRule, DenseType> copyData(dense, bbox, allrule, background);
676 typename ResultTreeType::Ptr fromTileTree = copyData.extract(threaded);
677 resultTree->merge(*fromTileTree);
678 }
679
680 return resultTree;
681 }
682
683
687 template <typename _ValueT, typename OpType>
688 class DenseTransformer
689 {
690 public:
691
692 typedef _ValueT ValueT;
693 typedef Dense<ValueT, openvdb::tools::LayoutZYX> DenseT;
694 typedef openvdb::math::Coord::ValueType IntType;
695 typedef tbb::blocked_range2d<IntType, IntType> RangeType;
696
697
698 private:
699
700 DenseT& mDense;
701 const OpType& mOp;
702 openvdb::math::CoordBBox mBBox;
703
704 public:
705 DenseTransformer(DenseT& dense,
706 const openvdb::math::CoordBBox& bbox,
707 const OpType& functor):
708 mDense(dense), mOp(functor), mBBox(dense.bbox())
709 {
710 // The iteration space is the intersection of the
711 // input bbox and the index-space covered by the dense grid
712 mBBox.intersect(bbox);
713 }
714
715 DenseTransformer(const DenseTransformer& other) :
716 mDense(other.mDense), mOp(other.mOp), mBBox(other.mBBox) {}
717
718 void apply(bool threaded = true) {
719
720 // Early out if the iteration space is empty
721
722 if (mBBox.empty()) return;
723
724
725 const openvdb::math::Coord start = mBBox.getStart();
726 const openvdb::math::Coord end = mBBox.getEnd();
727
728 // The iteration range only the slower two directions.
729 const RangeType range(start.x(), end.x(), 1,
730 start.y(), end.y(), 1);
731
732 if (threaded) {
733 tbb::parallel_for(range, *this);
734 } else {
735 (*this)(range);
736 }
737 }
738
739 void operator()(const RangeType& range) const {
740
741 // The stride in the z-direction.
742 // Note: the bbox is [inclusive, inclusive]
743
744 const size_t zlength = size_t(mBBox.max().z() - mBBox.min().z() + 1);
745
746 const IntType imin = range.rows().begin();
747 const IntType imax = range.rows().end();
748 const IntType jmin = range.cols().begin();
749 const IntType jmax = range.cols().end();
750
751
752 openvdb::math::Coord xyz(imin, jmin, mBBox.min().z());
753 for (xyz[0] = imin; xyz[0] != imax; ++xyz[0]) {
754 for (xyz[1] = jmin; xyz[1] != jmax; ++xyz[1]) {
755
756 mOp.transform(mDense, xyz, zlength);
757 }
758 }
759 }
760 }; // class DenseTransformer
761
762
766 template <typename ValueT, typename PointWiseOp>
767 struct ContiguousOp
768 {
769 ContiguousOp(const PointWiseOp& op) : mOp(op){}
770
771 typedef Dense<ValueT, openvdb::tools::LayoutZYX> DenseT;
772 inline void transform(DenseT& dense, openvdb::math::Coord& ijk, size_t size) const
773 {
774 ValueT* dp = const_cast<ValueT*>(&dense.getValue(ijk));
775
776 for (size_t offset = 0; offset < size; ++offset) {
777 dp[offset] = mOp(dp[offset]);
778 }
779 }
780
781 const PointWiseOp mOp;
782 };
783
784
786 template <typename ValueT, typename PointwiseOpT>
787 void
788 transformDense(Dense<ValueT, openvdb::tools::LayoutZYX>& dense,
789 const openvdb::CoordBBox& bbox,
790 const PointwiseOpT& functor, bool parallel)
791 {
792 typedef ContiguousOp<ValueT, PointwiseOpT> OpT;
793
794 // Convert the Op so it operates on a contiguous line in memory
795
796 OpT op(functor);
797
798 // Apply to the index space intersection in the dense grid
799 DenseTransformer<ValueT, OpT> transformer(dense, bbox, op);
800 transformer.apply(parallel);
801 }
802
803
804 template <typename CompositeMethod, typename _TreeT>
805 class SparseToDenseCompositor
806 {
807
808 public:
809 typedef _TreeT TreeT;
810 typedef typename TreeT::ValueType ValueT;
811 typedef typename TreeT::LeafNodeType LeafT;
812 typedef typename TreeT::template ValueConverter<ValueMask>::Type MaskTreeT;
813 typedef typename MaskTreeT::LeafNodeType MaskLeafT;
814 typedef Dense<ValueT, openvdb::tools::LayoutZYX> DenseT;
815 typedef openvdb::math::Coord::ValueType Index;
816 typedef tbb::blocked_range3d<Index, Index, Index> Range3d;
817
818 SparseToDenseCompositor(DenseT& dense, const TreeT& source, const TreeT& alpha,
819 const ValueT beta, const ValueT strength) :
820 mDense(dense), mSource(source), mAlpha(alpha), mBeta(beta), mStrength(strength)
821 {}
822
823 SparseToDenseCompositor(const SparseToDenseCompositor& other):
824 mDense(other.mDense), mSource(other.mSource), mAlpha(other.mAlpha),
825 mBeta(other.mBeta), mStrength(other.mStrength) {}
826
827
828
829 void sparseComposite(bool threaded) {
830
831 const ValueT beta = mBeta;
832 const ValueT strenght = mStrength;
833
834 // construct a tree that defines the iteration space
835
836 MaskTreeT maskTree(mSource, false /*background*/, openvdb::TopologyCopy());
837 maskTree.topologyUnion(mAlpha);
838
839 // Composite regions that are represented by leafnodes in either mAlpha or mSource
840 // Parallelize over bool-leafs
841
842 openvdb::tree::LeafManager<const MaskTreeT> maskLeafs(maskTree);
843 maskLeafs.foreach(*this, threaded);
844
845 // Composite regions that are represented by tiles
846 // Parallelize within each tile.
847
848 typename MaskTreeT::ValueOnCIter citer = maskTree.cbeginValueOn();
849 citer.setMaxDepth(MaskTreeT::ValueOnCIter::LEAF_DEPTH - 1);
850
851 if (!citer) return;
852
853 typename tree::ValueAccessor<const TreeT> alphaAccessor(mAlpha);
854 typename tree::ValueAccessor<const TreeT> sourceAccessor(mSource);
855
856 for (; citer; ++citer) {
857
858 const openvdb::math::Coord org = citer.getCoord();
859
860 // Early out if both alpha and source are zero in this tile.
861
862 const ValueT alphaValue = alphaAccessor.getValue(org);
863 const ValueT sourceValue = sourceAccessor.getValue(org);
864
865 if (openvdb::math::isZero(alphaValue) &&
866 openvdb::math::isZero(sourceValue) ) continue;
867
868 // Compute overlap of tile with the dense grid
869
870 openvdb::math::CoordBBox localBBox = citer.getBoundingBox();
871 localBBox.intersect(mDense.bbox());
872
873 // Early out if there is no intersection
874
875 if (localBBox.empty()) continue;
876
877 // Composite the tile-uniform values into the dense grid.
878 compositeFromTile(mDense, localBBox, sourceValue,
879 alphaValue, beta, strenght, threaded);
880 }
881 }
882
883 // Composites leaf values where the alpha values are active.
884 // Used in sparseComposite
885 void inline operator()(const MaskLeafT& maskLeaf, size_t /*i*/) const
886 {
887
888 typedef UniformLeaf ULeaf;
889 openvdb::math::CoordBBox localBBox = maskLeaf.getNodeBoundingBox();
890 localBBox.intersect(mDense.bbox());
891
892 // Early out for non-overlapping leafs
893
894 if (localBBox.empty()) return;
895
896 const openvdb::math::Coord org = maskLeaf.origin();
897 const LeafT* alphaLeaf = mAlpha.probeLeaf(org);
898 const LeafT* sourceLeaf = mSource.probeLeaf(org);
899
900 if (!sourceLeaf) {
901
902 // Create a source leaf proxy with the correct value
903 ULeaf uniformSource(mSource.getValue(org));
904
905 if (!alphaLeaf) {
906
907 // Create an alpha leaf proxy with the correct value
908 ULeaf uniformAlpha(mAlpha.getValue(org));
909
910 compositeFromLeaf(mDense, localBBox, uniformSource, uniformAlpha,
911 mBeta, mStrength);
912 } else {
913
914 compositeFromLeaf(mDense, localBBox, uniformSource, *alphaLeaf,
915 mBeta, mStrength);
916 }
917 } else {
918 if (!alphaLeaf) {
919
920 // Create an alpha leaf proxy with the correct value
921 ULeaf uniformAlpha(mAlpha.getValue(org));
922
923 compositeFromLeaf(mDense, localBBox, *sourceLeaf, uniformAlpha,
924 mBeta, mStrength);
925 } else {
926
927 compositeFromLeaf(mDense, localBBox, *sourceLeaf, *alphaLeaf,
928 mBeta, mStrength);
929 }
930 }
931 }
932 // i.e. it assumes that all valueOff Alpha voxels have value 0.
933
934 template <typename LeafT1, typename LeafT2>
935 inline static void compositeFromLeaf(DenseT& dense, const openvdb::math::CoordBBox& bbox,
936 const LeafT1& source, const LeafT2& alpha,
937 const ValueT beta, const ValueT strength)
938 {
939 typedef openvdb::math::Coord::ValueType IntType;
940
941 const ValueT sbeta = strength * beta;
942 openvdb::math::Coord ijk = bbox.min();
943
944
945 if (alpha.isDense() /*all active values*/) {
946
947 // Optimal path for dense alphaLeaf
948 const IntType size = bbox.max().z() + 1 - bbox.min().z();
949
950 for (ijk[0] = bbox.min().x(); ijk[0] < bbox.max().x() + 1; ++ijk[0]) {
951 for (ijk[1] = bbox.min().y(); ijk[1] < bbox.max().y() + 1; ++ijk[1]) {
952
953 ValueT* d = const_cast<ValueT*>(&dense.getValue(ijk));
954 const ValueT* a = &alpha.getValue(ijk);
955 const ValueT* s = &source.getValue(ijk);
956
957 for (IntType idx = 0; idx < size; ++idx) {
958 d[idx] = CompositeMethod::apply(d[idx], a[idx], s[idx],
959 strength, beta, sbeta);
960 }
961 }
962 }
963 } else {
964
965 // AlphaLeaf has non-active cells.
966
967 for (ijk[0] = bbox.min().x(); ijk[0] < bbox.max().x() + 1; ++ijk[0]) {
968 for (ijk[1] = bbox.min().y(); ijk[1] < bbox.max().y() + 1; ++ijk[1]) {
969 for (ijk[2] = bbox.min().z(); ijk[2] < bbox.max().z() + 1; ++ijk[2]) {
970
971 if (alpha.isValueOn(ijk)) {
972
973 dense.setValue(ijk,
974 CompositeMethod::apply(dense.getValue(ijk),
975 alpha.getValue(ijk), source.getValue(ijk),
976 strength, beta, sbeta)
977 );
978 }
979 }
980 }
981 }
982 }
983 }
984
985 inline static void compositeFromTile(DenseT& dense, openvdb::math::CoordBBox& bbox,
986 const ValueT& sourceValue, const ValueT& alphaValue,
987 const ValueT& beta, const ValueT& strength,
988 bool threaded)
989 {
990
991 typedef UniformTransformer TileTransformer;
992 TileTransformer functor(sourceValue, alphaValue, beta, strength);
993
994 // Transform the data inside the bbox according to the TileTranformer.
995
996 transformDense(dense, bbox, functor, threaded);
997
998 }
999
1000
1001 void denseComposite(bool threaded)
1002 {
1005 const openvdb::math::CoordBBox& bbox = mDense.bbox();
1006
1007 Range3d range(bbox.min().x(), bbox.max().x(), LeafT::DIM,
1008 bbox.min().y(), bbox.max().y(), LeafT::DIM,
1009 bbox.min().z(), bbox.max().z(), LeafT::DIM);
1010
1011 // Iterate over the range, compositing into
1012 // the dense grid using value accessors for
1013 // sparse the grids.
1014 if (threaded) {
1015 tbb::parallel_for(range, *this);
1016 } else {
1017 (*this)(range);
1018 }
1019
1020 }
1021
1022 // Composites a dense region using value accessors
1023 // into a dense grid
1024 void inline operator()(const Range3d& range) const
1025 {
1026 // Use value accessors to alpha and source
1027
1028 typename tree::ValueAccessor<const TreeT> alphaAccessor(mAlpha);
1029 typename tree::ValueAccessor<const TreeT> sourceAccessor(mSource);
1030
1031 const ValueT strength = mStrength;
1032 const ValueT beta = mBeta;
1033 const ValueT sbeta = strength * beta;
1034
1035 // Unpack the range3d item.
1036 const Index imin = range.pages().begin();
1037 const Index imax = range.pages().end();
1038
1039 const Index jmin = range.rows().begin();
1040 const Index jmax = range.rows().end();
1041
1042 const Index kmin = range.cols().begin();
1043 const Index kmax = range.cols().end();
1044
1045 openvdb::Coord ijk;
1046 for (ijk[0] = imin; ijk[0] < imax; ++ijk[0]) {
1047 for (ijk[1] = jmin; ijk[1] < jmax; ++ijk[1]) {
1048 for (ijk[2] = kmin; ijk[2] < kmax; ++ijk[2]) {
1049 const ValueT d_old = mDense.getValue(ijk);
1050 const ValueT& alpha = alphaAccessor.getValue(ijk);
1051 const ValueT& src = sourceAccessor.getValue(ijk);
1052
1053 mDense.setValue(ijk, CompositeMethod::apply(d_old, alpha, src,
1054 strength, beta, sbeta));
1055 }
1056 }
1057 }
1058
1059 }
1060
1061
1062 private:
1063
1064 // Internal class that wraps the templated composite method
1065 // for use when both alpha and source are uniform over
1066 // a prescribed bbox (e.g. a tile).
1067 class UniformTransformer
1068 {
1069 public:
1070 UniformTransformer(const ValueT& source, const ValueT& alpha, const ValueT& _beta,
1071 const ValueT& _strength) :
1072 mSource(source), mAlpha(alpha), mBeta(_beta),
1073 mStrength(_strength), mSBeta(_strength * _beta)
1074 {}
1075
1076 ValueT operator()(const ValueT& input) const
1077 {
1078 return CompositeMethod::apply(input, mAlpha, mSource,
1079 mStrength, mBeta, mSBeta);
1080 }
1081
1082 private:
1083 const ValueT mSource; const ValueT mAlpha; const ValueT mBeta;
1084 const ValueT mStrength; const ValueT mSBeta;
1085 };
1086
1087
1088 // Simple Class structure that mimics a leaf
1089 // with uniform values. Holds LeafT::DIM copies
1090 // of a value in an array.
1091 struct Line { ValueT mValues[LeafT::DIM]; };
1092 class UniformLeaf : private Line
1093 {
1094 public:
1095 typedef typename LeafT::ValueType ValueT;
1096
1097 typedef Line BaseT;
1098 UniformLeaf(const ValueT& value) : BaseT(init(value)) {}
1099
1100 static const BaseT init(const ValueT& value) {
1101 BaseT tmp;
1102 for (openvdb::Index i = 0; i < LeafT::DIM; ++i) {
1103 tmp.mValues[i] = value;
1104 }
1105 return tmp;
1106 }
1107
1108 bool isDense() const { return true; }
1109 bool isValueOn(openvdb::math::Coord&) const { return true; }
1110
1111 inline const ValueT& getValue(const openvdb::math::Coord& ) const
1112 {return BaseT::mValues[0];}
1113 };
1114
1115 private:
1116 DenseT& mDense;
1117 const TreeT& mSource;
1118 const TreeT& mAlpha;
1119 ValueT mBeta;
1120 ValueT mStrength;
1121 }; // class SparseToDenseCompositor
1122
1123
1124 namespace ds
1125 {
1127 template <typename ValueT>
1129 struct OpOver
1130 {
1131 static inline ValueT apply(const ValueT u, const ValueT alpha,
1132 const ValueT v,
1133 const ValueT strength,
1134 const ValueT beta,
1135 const ValueT /*sbeta*/)
1136 { return (u + strength * alpha * (beta * v - u)); }
1137 };
1138
1139
1140 template <typename ValueT>
1141 struct OpAdd
1142 {
1143 static inline ValueT apply(const ValueT u, const ValueT alpha,
1144 const ValueT v,
1145 const ValueT /*strength*/,
1146 const ValueT /*beta*/,
1147 const ValueT sbeta)
1148 { return (u + sbeta * alpha * v); }
1149 };
1150
1151 template <typename ValueT>
1152 struct OpSub
1153 {
1154 static inline ValueT apply(const ValueT u, const ValueT alpha,
1155 const ValueT v,
1156 const ValueT /*strength*/,
1157 const ValueT /*beta*/,
1158 const ValueT sbeta)
1159 { return (u - sbeta * alpha * v); }
1160 };
1161
1162 template <typename ValueT>
1163 struct OpMin
1164 {
1165 static inline ValueT apply(const ValueT u, const ValueT alpha,
1166 const ValueT v,
1167 const ValueT s /*trength*/,
1168 const ValueT beta,
1169 const ValueT /*sbeta*/)
1170 { return ( ( 1 - s * alpha) * u + s * alpha * std::min(u, beta * v) ); }
1171 };
1172
1173
1174 template <typename ValueT>
1175 struct OpMax
1176 {
1177 static inline ValueT apply(const ValueT u, const ValueT alpha,
1178 const ValueT v,
1179 const ValueT s/*trength*/,
1180 const ValueT beta,
1181 const ValueT /*sbeta*/)
1182 { return ( ( 1 - s * alpha ) * u + s * alpha * std::min(u, beta * v) ); }
1183 };
1184
1185 template <typename ValueT>
1186 struct OpMult
1187 {
1188 static inline ValueT apply(const ValueT u, const ValueT alpha,
1189 const ValueT v,
1190 const ValueT s/*trength*/,
1191 const ValueT /*beta*/,
1192 const ValueT sbeta)
1193 { return ( ( 1 + alpha * (sbeta * v - s)) * u ); }
1194 };
1196
1198 template <DSCompositeOp OP, typename ValueT>
1200 struct CompositeFunctorTranslator{};
1201
1202 template <typename ValueT>
1203 struct CompositeFunctorTranslator<DS_OVER, ValueT>{ typedef OpOver<ValueT> OpT; };
1204
1205 template <typename ValueT>
1206 struct CompositeFunctorTranslator<DS_ADD, ValueT>{ typedef OpAdd<ValueT> OpT; };
1207
1208 template <typename ValueT>
1209 struct CompositeFunctorTranslator<DS_SUB, ValueT>{ typedef OpSub<ValueT> OpT; };
1210
1211 template <typename ValueT>
1212 struct CompositeFunctorTranslator<DS_MIN, ValueT>{ typedef OpMin<ValueT> OpT; };
1213
1214 template <typename ValueT>
1215 struct CompositeFunctorTranslator<DS_MAX, ValueT>{ typedef OpMax<ValueT> OpT; };
1216
1217 template <typename ValueT>
1218 struct CompositeFunctorTranslator<DS_MULT, ValueT>{ typedef OpMult<ValueT> OpT; };
1220
1221 } // namespace ds
1222
1223
1224 template <DSCompositeOp OpT, typename TreeT>
1225 void compositeToDense(
1226 Dense<typename TreeT::ValueType, LayoutZYX>& dense,
1227 const TreeT& source, const TreeT& alpha,
1228 const typename TreeT::ValueType beta,
1229 const typename TreeT::ValueType strength,
1230 bool threaded)
1231 {
1232 typedef typename TreeT::ValueType ValueT;
1233 typedef ds::CompositeFunctorTranslator<OpT, ValueT> Translator;
1234 typedef typename Translator::OpT Method;
1235
1236 if (openvdb::math::isZero(strength)) return;
1237
1238 SparseToDenseCompositor<Method, TreeT> tool(dense, source, alpha, beta, strength);
1239
1240 if (openvdb::math::isZero(alpha.background()) &&
1241 openvdb::math::isZero(source.background()))
1242 {
1243 // Use the sparsity of (alpha U source) as the iteration space.
1244 tool.sparseComposite(threaded);
1245 } else {
1246 // Use the bounding box of dense as the iteration space.
1247 tool.denseComposite(threaded);
1248 }
1249 }
1250
1251 } // namespace tools
1252 } // namespace OPENVDB_VERSION_NAME
1253 } // namespace openvdb
1254
1255 #endif //OPENVDB_TOOLS_DENSESPARSETOOLS_HAS_BEEN_INCLUDED
1256
1257 // Copyright (c) 2012-2018 DreamWorks Animation LLC
1258 // All rights reserved. This software is distributed under the
1259 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v5_1::tools::SparseMaskedExtractor::extract
ResultTreeType::Ptr extract(bool threaded=true)
Definition: DenseSparseTools.h:471
openvdb::v5_1::tools::DenseTransformer::IntType
openvdb::math::Coord::ValueType IntType
Definition: DenseSparseTools.h:694
openvdb::v5_1::tree::ValueAccessor::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:257
openvdb::v5_1::tools::DS_SUB
Definition: DenseSparseTools.h:174
openvdb::v5_1::tree::Tree::LeafNodeType
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:212
openvdb::v5_1::tools::DS_OVER
Definition: DenseSparseTools.h:174
openvdb::v5_1::tools::SparseExtractor::extract
ResultTreeType::Ptr extract(bool threaded=true)
Definition: DenseSparseTools.h:261
openvdb::v5_1::tools::SparseToDenseCompositor::sparseComposite
void sparseComposite(bool threaded)
Definition: DenseSparseTools.h:829
openvdb::v5_1::tools::extractSparseTreeWithMask
DSConverter< DenseType, MaskTreeType >::Type::Ptr extractSparseTreeWithMask(const DenseType &dense, const MaskTreeType &mask, const typename DenseType::ValueType &background, bool threaded=true)
Copy data from the intersection of a sparse tree and a dense input grid. The resulting tree has the s...
Definition: DenseSparseTools.h:613
openvdb::v5_1::tools::SparseToDenseCompositor::SparseToDenseCompositor
SparseToDenseCompositor(DenseT &dense, const TreeT &source, const TreeT &alpha, const ValueT beta, const ValueT strength)
Definition: DenseSparseTools.h:818
openvdb::v5_1::tools::ds::CompositeFunctorTranslator< DS_SUB, ValueT >::OpT
OpSub< ValueT > OpT
Definition: DenseSparseTools.h:1209
openvdb::v5_1::tools::SparseMaskedExtractor::SparseMaskedExtractor
SparseMaskedExtractor(const DenseType &dense, const ResultValueType &background, const MaskLeafVec &leafVec)
Definition: DenseSparseTools.h:455
Types.h
openvdb::v5_1::tools::SparseExtractor::SparseExtractor
SparseExtractor(const DenseType &dense, const OpType &functor, const ResultValueType background)
Definition: DenseSparseTools.h:226
openvdb::v5_1::tools::ds::OpMult::apply
static ValueT apply(const ValueT u, const ValueT alpha, const ValueT v, const ValueT s, const ValueT, const ValueT sbeta)
Definition: DenseSparseTools.h:1188
openvdb::v5_1::tools::SparseMaskedExtractor::MaskLeafCIter
MaskTree::LeafCIter MaskLeafCIter
Definition: DenseSparseTools.h:451
openvdb::v5_1::tools::SparseToDenseCompositor::Range3d
tbb::blocked_range3d< Index, Index, Index > Range3d
Definition: DenseSparseTools.h:816
openvdb::v5_1::math::CoordBBox
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
openvdb::v5_1::tools::SparseToDenseCompositor::DenseT
Dense< ValueT, openvdb::tools::LayoutZYX > DenseT
Definition: DenseSparseTools.h:814
openvdb::v5_1::tools::ds::CompositeFunctorTranslator< DS_MIN, ValueT >::OpT
OpMin< ValueT > OpT
Definition: DenseSparseTools.h:1212
openvdb::v5_1::tools::SparseToDenseCompositor
Definition: DenseSparseTools.h:805
openvdb::v5_1::tools::SparseToDenseCompositor::Index
openvdb::math::Coord::ValueType Index
Definition: DenseSparseTools.h:815
openvdb::v5_1::math::isZero
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:308
openvdb::v5_1::tools::SparseExtractor::Index
openvdb::math::Coord::ValueType Index
Definition: DenseSparseTools.h:202
openvdb::v5_1::tools::ds::OpMin
Definition: DenseSparseTools.h:1163
openvdb::v5_1::tools::ds::OpMin::apply
static ValueT apply(const ValueT u, const ValueT alpha, const ValueT v, const ValueT s, const ValueT beta, const ValueT)
Definition: DenseSparseTools.h:1165
openvdb::v5_1::tools::SparseExtractor
Functor-based class used to extract data that satisfies some criteria defined by the embedded OpType ...
Definition: DenseSparseTools.h:197
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
openvdb::v5_1::tools::DSConverter::Type
TreeType::template ValueConverter< ValueType >::Type Type
Definition: DenseSparseTools.h:126
openvdb::v5_1::tools::SparseExtractor::SparseExtractor
SparseExtractor(const DenseType &dense, const openvdb::math::CoordBBox &bbox, const OpType &functor, const ResultValueType background)
Definition: DenseSparseTools.h:236
openvdb::v5_1::tools::SparseToDenseCompositor::compositeFromLeaf
static void compositeFromLeaf(DenseT &dense, const openvdb::math::CoordBBox &bbox, const LeafT1 &source, const LeafT2 &alpha, const ValueT beta, const ValueT strength)
Definition: DenseSparseTools.h:935
openvdb::v5_1::tools::SparseMaskedExtractor::SparseMaskedExtractor
SparseMaskedExtractor(const SparseMaskedExtractor &other, tbb::split)
Definition: DenseSparseTools.h:466
openvdb::v5_1::tools::ds::CompositeFunctorTranslator< DS_OVER, ValueT >::OpT
OpOver< ValueT > OpT
Definition: DenseSparseTools.h:1203
openvdb::v5_1::tools::ds::OpOver::apply
static ValueT apply(const ValueT u, const ValueT alpha, const ValueT v, const ValueT strength, const ValueT beta, const ValueT)
Definition: DenseSparseTools.h:1131
openvdb::v5_1::tools::SparseToDenseCompositor::denseComposite
void denseComposite(bool threaded)
Definition: DenseSparseTools.h:1001
openvdb::v5_1::tools::SparseMaskedExtractor::DenseValueType
ResultValueType DenseValueType
Definition: DenseSparseTools.h:448
Dense.h
This file defines a simple dense grid and efficient converters to and from VDB grids.
openvdb::v5_1::tools::ExtractAll::ResultLeafNodeType
ResultTreeType::LeafNodeType ResultLeafNodeType
Definition: DenseSparseTools.h:601
openvdb::v5_1::tools::SparseToDenseCompositor::TreeT
_TreeT TreeT
Definition: DenseSparseTools.h:809
openvdb::v5_1::tools::ExtractAll::operator()
void operator()(const DenseValueType &a, const CoordOrIndex &offset, ResultLeafNodeType *leaf) const
Definition: DenseSparseTools.h:604
openvdb::v5_1::tools::ds::OpSub::apply
static ValueT apply(const ValueT u, const ValueT alpha, const ValueT v, const ValueT, const ValueT, const ValueT sbeta)
Definition: DenseSparseTools.h:1154
openvdb::v5_1::tools::DenseTransformer::DenseTransformer
DenseTransformer(DenseT &dense, const openvdb::math::CoordBBox &bbox, const OpType &functor)
Definition: DenseSparseTools.h:705
openvdb::v5_1::TopologyCopy
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:515
openvdb::v5_1::tools::SparseExtractor::Range3d
tbb::blocked_range3d< Index, Index, Index > Range3d
Definition: DenseSparseTools.h:210
openvdb::v5_1::tools::compositeToDense
void compositeToDense(Dense< typename TreeT::ValueType, LayoutZYX > &dense, const TreeT &source, const TreeT &alpha, const typename TreeT::ValueType beta, const typename TreeT::ValueType strength, bool threaded=true)
Composite data from a sparse tree into a dense array of the same value type.
Definition: DenseSparseTools.h:1225
openvdb::v5_1::tools::SparseMaskedExtractor::ResultValueType
ResultTreeType::ValueType ResultValueType
Definition: DenseSparseTools.h:447
openvdb::v5_1::tree::LeafIteratorBase::getLeaf
LeafNodeT * getLeaf() const
Return the leaf node to which the iterator is pointing.
Definition: TreeIterator.h:1278
openvdb::v5_1::tools::SparseExtractor::ResultTreeType
OpType::ResultTreeType ResultTreeType
Definition: DenseSparseTools.h:205
openvdb::v5_1::tools::ds::CompositeFunctorTranslator< DS_MAX, ValueT >::OpT
OpMax< ValueT > OpT
Definition: DenseSparseTools.h:1215
openvdb::v5_1::tools::ds::OpMax
Definition: DenseSparseTools.h:1175
openvdb::v5_1::tools::SparseToDenseCompositor::SparseToDenseCompositor
SparseToDenseCompositor(const SparseToDenseCompositor &other)
Definition: DenseSparseTools.h:823
openvdb::v5_1::tools::DSCompositeOp
DSCompositeOp
Definition: DenseSparseTools.h:173
openvdb::v5_1::tools::DenseTransformer::apply
void apply(bool threaded=true)
Definition: DenseSparseTools.h:718
openvdb::v5_1::tools::SparseMaskedExtractor::MaskTree
ResultTreeType::template ValueConverter< ValueMask >::Type MaskTree
Definition: DenseSparseTools.h:450
openvdb::v5_1::tools::SparseMaskedExtractor::ResultTreeType
_ResultTreeType ResultTreeType
Definition: DenseSparseTools.h:445
openvdb::v5_1::tree::Tree::leafCount
Index32 leafCount() const override
Return the number of leaf nodes.
Definition: Tree.h:368
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
openvdb::v5_1::tools::DS_MULT
Definition: DenseSparseTools.h:174
openvdb::v5_1::tools::ds::OpMax::apply
static ValueT apply(const ValueT u, const ValueT alpha, const ValueT v, const ValueT s, const ValueT beta, const ValueT)
Definition: DenseSparseTools.h:1177
openvdb::v5_1::tools::DS_MIN
Definition: DenseSparseTools.h:174
openvdb::v5_1::tools::SparseMaskedExtractor::ResultLeafNodeType
ResultTreeType::LeafNodeType ResultLeafNodeType
Definition: DenseSparseTools.h:446
openvdb::v5_1::math::CoordBBox::intersect
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition: Coord.h:448
openvdb::v5_1::tools::ds::CompositeFunctorTranslator< DS_ADD, ValueT >::OpT
OpAdd< ValueT > OpT
Definition: DenseSparseTools.h:1206
openvdb::v5_1::tools::ds::CompositeFunctorTranslator
Translator that converts an enum to compositing functor types.
Definition: DenseSparseTools.h:1200
openvdb::v5_1::ValueError
Definition: Exceptions.h:92
openvdb::v5_1::tools::ds::OpAdd
Definition: DenseSparseTools.h:1141
openvdb::v5_1::tools::ContiguousOp::transform
void transform(DenseT &dense, openvdb::math::Coord &ijk, size_t size) const
Definition: DenseSparseTools.h:772
openvdb::v5_1::tools::SparseToDenseCompositor::MaskTreeT
TreeT::template ValueConverter< ValueMask >::Type MaskTreeT
Definition: DenseSparseTools.h:812
openvdb::v5_1::tools::DSConverter::ValueType
DenseType::ValueType ValueType
Definition: DenseSparseTools.h:124
openvdb::v5_1::tools::ds::OpSub
Definition: DenseSparseTools.h:1152
openvdb::v5_1::tools::ExtractAll
a simple utility class used by extractSparseTreeWithMask
Definition: DenseSparseTools.h:598
openvdb::v5_1::tools::SparseExtractor::ResultValueType
ResultTreeType::ValueType ResultValueType
Definition: DenseSparseTools.h:206
openvdb::v5_1::tools::SparseToDenseCompositor::operator()
void operator()(const MaskLeafT &maskLeaf, size_t) const
Definition: DenseSparseTools.h:885
openvdb::v5_1::tools::SparseExtractor::join
void join(SparseExtractor &rhs)
Definition: DenseSparseTools.h:413
openvdb
Definition: Exceptions.h:40
openvdb::v5_1::tree::Tree::cbeginLeaf
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1181
openvdb::v5_1::tools::SparseToDenseCompositor::ValueT
TreeT::ValueType ValueT
Definition: DenseSparseTools.h:810
openvdb::v5_1::tools::ExtractAll::ResultTreeType
_ResultTreeType ResultTreeType
Definition: DenseSparseTools.h:600
openvdb::v5_1::tools::DenseTransformer
Class that applies a functor to the index space intersection of a prescribed bounding box and the den...
Definition: DenseSparseTools.h:688
openvdb::v5_1::tree::LeafIteratorBase
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels) ...
Definition: TreeIterator.h:1235
openvdb::v5_1::tools::SparseExtractor::SparseExtractor
SparseExtractor(SparseExtractor &other, tbb::split)
Definition: DenseSparseTools.h:253
openvdb::v5_1::tools::Dense::setValue
void setValue(size_t offset, const ValueT &value)
Set the value of the voxel at the given array offset.
Definition: Dense.h:287
openvdb::v5_1::tools::SparseMaskedExtractor
Functor-based class used to extract data from a dense grid, at the index-space intersection with a su...
Definition: DenseSparseTools.h:440
openvdb::v5_1::tools::SparseToDenseCompositor::LeafT
TreeT::LeafNodeType LeafT
Definition: DenseSparseTools.h:811
openvdb::v5_1::tools::SparseExtractor::operator()
void operator()(const Range3d &range)
Definition: DenseSparseTools.h:307
openvdb::v5_1::tools::SparseToDenseCompositor::compositeFromTile
static void compositeFromTile(DenseT &dense, openvdb::math::CoordBBox &bbox, const ValueT &sourceValue, const ValueT &alphaValue, const ValueT &beta, const ValueT &strength, bool threaded)
Definition: DenseSparseTools.h:985
openvdb::v5_1::tools::SparseExtractor::ResultLeafNodeType
ResultTreeType::LeafNodeType ResultLeafNodeType
Definition: DenseSparseTools.h:207
openvdb::v5_1::tools::SparseMaskedExtractor::join
void join(SparseMaskedExtractor &rhs)
Definition: DenseSparseTools.h:580
openvdb::v5_1::tools::ContiguousOp
a wrapper struct used to avoid unnecessary computation of memory access from Coord when all offsets a...
Definition: DenseSparseTools.h:767
openvdb::v5_1::tools::Dense
Dense is a simple dense grid API used by the CopyToDense and CopyFromDense classes defined below...
Definition: Dense.h:209
openvdb::v5_1::tools::composite::min
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
openvdb::v5_1::tools::DSConverter
Definition: DenseSparseTools.h:123
openvdb::v5_1::tools::DenseTransformer::DenseTransformer
DenseTransformer(const DenseTransformer &other)
Definition: DenseSparseTools.h:715
openvdb::v5_1::math::CoordBBox::empty
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:372
openvdb::v5_1::tools::SparseMaskedExtractor::MaskLeafVec
std::vector< const typename MaskTree::LeafNodeType * > MaskLeafVec
Definition: DenseSparseTools.h:452
openvdb::v5_1::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
openvdb::v5_1::tools::ds::CompositeFunctorTranslator< DS_MULT, ValueT >::OpT
OpMult< ValueT > OpT
Definition: DenseSparseTools.h:1218
openvdb::v5_1::tools::SparseExtractor::DenseValueType
DenseType::ValueType DenseValueType
Definition: DenseSparseTools.h:204
openvdb::v5_1::tools::DS_MAX
Definition: DenseSparseTools.h:174
openvdb::v5_1::tools::extractSparseTree
OpType::ResultTreeType::Ptr extractSparseTree(const DenseType &dense, const OpType &functor, const typename OpType::ResultValueType &background, bool threaded=true)
Selectively extract and transform data from a dense grid, producing a sparse tree with leaf nodes onl...
Definition: DenseSparseTools.h:421
openvdb::v5_1::tree::ValueAccessor< const TreeT >
openvdb::v5_1::tools::SparseExtractor::MaskTree
ResultTreeType::template ValueConverter< ValueMask >::Type MaskTree
Definition: DenseSparseTools.h:208
openvdb::v5_1::tools::DenseTransformer::ValueT
_ValueT ValueT
Definition: DenseSparseTools.h:692
openvdb::v5_1::tools::ds::OpAdd::apply
static ValueT apply(const ValueT u, const ValueT alpha, const ValueT v, const ValueT, const ValueT, const ValueT sbeta)
Definition: DenseSparseTools.h:1143
openvdb::v5_1::tools::SparseMaskedExtractor::operator()
void operator()(const tbb::blocked_range< size_t > &range)
Definition: DenseSparseTools.h:487
openvdb::v5_1::tools::LayoutZYX
Definition: Dense.h:95
openvdb::v5_1::Index
Index32 Index
Definition: Types.h:61
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
openvdb::v5_1::tools::DenseTransformer::RangeType
tbb::blocked_range2d< IntType, IntType > RangeType
Definition: DenseSparseTools.h:695
openvdb::v5_1::tools::Dense::getValue
const ValueT & getValue(size_t offset) const
Return a const reference to the value of the voxel at the given array offset.
Definition: Dense.h:290
LeafManager.h
A LeafManager manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional au...
openvdb::v5_1::tools::DenseTransformer::operator()
void operator()(const RangeType &range) const
Definition: DenseSparseTools.h:739
openvdb::v5_1::tools::SparseToDenseCompositor::MaskLeafT
MaskTreeT::LeafNodeType MaskLeafT
Definition: DenseSparseTools.h:813
openvdb::v5_1::tools::SparseMaskedExtractor::_ResultTreeType
DSConverter< DenseType, MaskTreeType >::Type _ResultTreeType
Definition: DenseSparseTools.h:444
openvdb::v5_1::tools::transformDense
void transformDense(Dense< ValueT, openvdb::tools::LayoutZYX > &dense, const openvdb::CoordBBox &bbox, const PointwiseOpT &functor, bool parallel)
Apply a point-wise functor to the intersection of a dense grid and a given bounding box...
Definition: DenseSparseTools.h:788
openvdb::v5_1::MaskTree
tree::Tree4< ValueMask, 5, 4, 3 >::Type MaskTree
Definition: openvdb.h:54
openvdb::v5_1::tools::DS_ADD
Definition: DenseSparseTools.h:174
openvdb::v5_1::tools::SparseToDenseCompositor::operator()
void operator()(const Range3d &range) const
Definition: DenseSparseTools.h:1024
openvdb::v5_1::tools::DS_SET
Definition: DenseSparseTools.h:174
openvdb::v5_1::tree::Tree
Definition: Tree.h:203
openvdb::v5_1::tools::DenseTransformer::DenseT
Dense< ValueT, openvdb::tools::LayoutZYX > DenseT
Definition: DenseSparseTools.h:693
openvdb::v5_1::tools::ContiguousOp::DenseT
Dense< ValueT, openvdb::tools::LayoutZYX > DenseT
Definition: DenseSparseTools.h:771
openvdb::v5_1::tools::ContiguousOp::mOp
const PointWiseOp mOp
Definition: DenseSparseTools.h:781
openvdb::v5_1::tools::ContiguousOp::ContiguousOp
ContiguousOp(const PointWiseOp &op)
Definition: DenseSparseTools.h:769
openvdb::v5_1::tools::ds::OpOver
Point wise methods used to apply various compositing operations.
Definition: DenseSparseTools.h:1129
openvdb::v5_1::tools::ds::OpMult
Definition: DenseSparseTools.h:1186