OpenVDB  6.2.1
PointConversion.h
Go to the documentation of this file.
1 //
3 // Copyright (c) DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 
36 
37 #ifndef OPENVDB_POINTS_POINT_CONVERSION_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_CONVERSION_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/math/Transform.h>
41 
45 
46 #include "AttributeArrayString.h"
47 #include "AttributeSet.h"
48 #include "IndexFilter.h"
49 #include "PointAttribute.h"
50 #include "PointDataGrid.h"
51 #include "PointGroup.h"
52 
53 #include <tbb/parallel_reduce.h>
54 
55 #include <type_traits>
56 
57 namespace openvdb {
59 namespace OPENVDB_VERSION_NAME {
60 namespace points {
61 
62 
79 
80 template<
81  typename CompressionT,
82  typename PointDataGridT,
83  typename PositionArrayT,
84  typename PointIndexGridT>
85 inline typename PointDataGridT::Ptr
86 createPointDataGrid(const PointIndexGridT& pointIndexGrid,
87  const PositionArrayT& positions,
88  const math::Transform& xform,
89  Metadata::Ptr positionDefaultValue = Metadata::Ptr());
90 
91 
101 
102 template <typename CompressionT, typename PointDataGridT, typename ValueT>
103 inline typename PointDataGridT::Ptr
104 createPointDataGrid(const std::vector<ValueT>& positions,
105  const math::Transform& xform,
106  Metadata::Ptr positionDefaultValue = Metadata::Ptr());
107 
108 
120 template <typename PointDataTreeT, typename PointIndexTreeT, typename PointArrayT>
121 inline void
122 populateAttribute( PointDataTreeT& tree,
123  const PointIndexTreeT& pointIndexTree,
124  const openvdb::Name& attributeName,
125  const PointArrayT& data,
126  const Index stride = 1,
127  const bool insertMetadata = true);
128 
138 
139 template <typename PositionAttribute, typename PointDataGridT, typename FilterT = NullFilter>
140 inline void
141 convertPointDataGridPosition( PositionAttribute& positionAttribute,
142  const PointDataGridT& grid,
143  const std::vector<Index64>& pointOffsets,
144  const Index64 startOffset,
145  const FilterT& filter = NullFilter(),
146  const bool inCoreOnly = false);
147 
148 
159 template <typename TypedAttribute, typename PointDataTreeT, typename FilterT = NullFilter>
160 inline void
161 convertPointDataGridAttribute( TypedAttribute& attribute,
162  const PointDataTreeT& tree,
163  const std::vector<Index64>& pointOffsets,
164  const Index64 startOffset,
165  const unsigned arrayIndex,
166  const Index stride = 1,
167  const FilterT& filter = NullFilter(),
168  const bool inCoreOnly = false);
169 
170 
181 
182 template <typename Group, typename PointDataTreeT, typename FilterT = NullFilter>
183 inline void
184 convertPointDataGridGroup( Group& group,
185  const PointDataTreeT& tree,
186  const std::vector<Index64>& pointOffsets,
187  const Index64 startOffset,
188  const AttributeSet::Descriptor::GroupIndex index,
189  const FilterT& filter = NullFilter(),
190  const bool inCoreOnly = false);
191 
204 template<typename PositionWrapper, typename InterrupterT = openvdb::util::NullInterrupter>
205 inline float
206 computeVoxelSize( const PositionWrapper& positions,
207  const uint32_t pointsPerVoxel,
208  const math::Mat4d transform = math::Mat4d::identity(),
209  const Index decimalPlaces = 5,
210  InterrupterT* const interrupter = nullptr);
211 
212 
214 
215 
217 template<typename ValueType>
219 public:
220  using PosType = ValueType;
221  using value_type= ValueType;
222 
223  PointAttributeVector(const std::vector<value_type>& data,
224  const Index stride = 1)
225  : mData(data)
226  , mStride(stride) { }
227 
228  size_t size() const { return mData.size(); }
229  void getPos(size_t n, ValueType& xyz) const { xyz = mData[n]; }
230  void get(ValueType& value, size_t n) const { value = mData[n]; }
231  void get(ValueType& value, size_t n, openvdb::Index m) const { value = mData[n * mStride + m]; }
232 
233 private:
234  const std::vector<value_type>& mData;
235  const Index mStride;
236 }; // PointAttributeVector
237 
238 
240 
241 
242 namespace point_conversion_internal {
243 
244 
245 // ConversionTraits to create the relevant Attribute Handles from a LeafNode
246 template <typename T> struct ConversionTraits
247 {
250  static T zero() { return zeroVal<T>(); }
251  template <typename LeafT>
252  static typename Handle::Ptr handleFromLeaf(LeafT& leaf, Index index) {
253  const AttributeArray& array = leaf.constAttributeArray(index);
254  return Handle::create(array);
255  }
256  template <typename LeafT>
257  static typename WriteHandle::Ptr writeHandleFromLeaf(LeafT& leaf, Index index) {
258  AttributeArray& array = leaf.attributeArray(index);
259  return WriteHandle::create(array);
260  }
261 }; // ConversionTraits
262 template <> struct ConversionTraits<openvdb::Name>
263 {
266  static openvdb::Name zero() { return ""; }
267  template <typename LeafT>
268  static typename Handle::Ptr handleFromLeaf(LeafT& leaf, Index index) {
269  const AttributeArray& array = leaf.constAttributeArray(index);
270  const AttributeSet::Descriptor& descriptor = leaf.attributeSet().descriptor();
271  return Handle::create(array, descriptor.getMetadata());
272  }
273  template <typename LeafT>
274  static typename WriteHandle::Ptr writeHandleFromLeaf(LeafT& leaf, Index index) {
275  AttributeArray& array = leaf.attributeArray(index);
276  const AttributeSet::Descriptor& descriptor = leaf.attributeSet().descriptor();
277  return WriteHandle::create(array, descriptor.getMetadata());
278  }
279 }; // ConversionTraits<openvdb::Name>
280 
281 template< typename PointDataTreeType,
282  typename PointIndexTreeType,
283  typename AttributeListType>
285 
287  using LeafRangeT = typename LeafManagerT::LeafRange;
288  using PointIndexLeafNode = typename PointIndexTreeType::LeafNodeType;
290  using ValueType = typename AttributeListType::value_type;
292 
293  PopulateAttributeOp(const PointIndexTreeType& pointIndexTree,
294  const AttributeListType& data,
295  const size_t index,
296  const Index stride = 1)
297  : mPointIndexTree(pointIndexTree)
298  , mData(data)
299  , mIndex(index)
300  , mStride(stride) { }
301 
302  void operator()(const typename LeafManagerT::LeafRange& range) const {
303 
304  for (auto leaf = range.begin(); leaf; ++leaf) {
305 
306  // obtain the PointIndexLeafNode (using the origin of the current leaf)
307 
308  const PointIndexLeafNode* pointIndexLeaf =
309  mPointIndexTree.probeConstLeaf(leaf->origin());
310 
311  if (!pointIndexLeaf) continue;
312 
313  typename HandleT::Ptr attributeWriteHandle =
314  ConversionTraits<ValueType>::writeHandleFromLeaf(*leaf, static_cast<Index>(mIndex));
315 
316  Index64 index = 0;
317 
318  const IndexArray& indices = pointIndexLeaf->indices();
319 
320  for (const Index64 leafIndex: indices)
321  {
322  ValueType value;
323  for (Index i = 0; i < mStride; i++) {
324  mData.get(value, leafIndex, i);
325  attributeWriteHandle->set(static_cast<Index>(index), i, value);
326  }
327  index++;
328  }
329 
330  // attempt to compact the array
331 
332  attributeWriteHandle->compact();
333  }
334  }
335 
337 
338  const PointIndexTreeType& mPointIndexTree;
339  const AttributeListType& mData;
340  const size_t mIndex;
341  const Index mStride;
342 };
343 
344 template<typename PointDataTreeType, typename Attribute, typename FilterT>
346 
347  using LeafNode = typename PointDataTreeType::LeafNodeType;
348  using ValueType = typename Attribute::ValueType;
349  using HandleT = typename Attribute::Handle;
352  using LeafRangeT = typename LeafManagerT::LeafRange;
353 
354  ConvertPointDataGridPositionOp( Attribute& attribute,
355  const std::vector<Index64>& pointOffsets,
356  const Index64 startOffset,
357  const math::Transform& transform,
358  const size_t index,
359  const FilterT& filter,
360  const bool inCoreOnly)
361  : mAttribute(attribute)
362  , mPointOffsets(pointOffsets)
363  , mStartOffset(startOffset)
364  , mTransform(transform)
365  , mIndex(index)
366  , mFilter(filter)
367  , mInCoreOnly(inCoreOnly)
368  {
369  // only accept Vec3f as ValueType
370  static_assert(VecTraits<ValueType>::Size == 3 &&
371  std::is_floating_point<typename ValueType::ValueType>::value,
372  "ValueType is not Vec3f");
373  }
374 
375  template <typename IterT>
376  void convert(IterT& iter, HandleT& targetHandle,
377  SourceHandleT& sourceHandle, Index64& offset) const
378  {
379  for (; iter; ++iter) {
380  const Vec3d xyz = iter.getCoord().asVec3d();
381  const Vec3d pos = sourceHandle.get(*iter);
382  targetHandle.set(static_cast<Index>(offset++), /*stride=*/0,
383  mTransform.indexToWorld(pos + xyz));
384  }
385  }
386 
387  void operator()(const LeafRangeT& range) const
388  {
389  HandleT pHandle(mAttribute);
390 
391  for (auto leaf = range.begin(); leaf; ++leaf) {
392 
393  assert(leaf.pos() < mPointOffsets.size());
394 
395  if (mInCoreOnly && leaf->buffer().isOutOfCore()) continue;
396 
397  Index64 offset = mStartOffset;
398 
399  if (leaf.pos() > 0) offset += mPointOffsets[leaf.pos() - 1];
400 
401  auto handle = SourceHandleT::create(leaf->constAttributeArray(mIndex));
402 
403  if (mFilter.state() == index::ALL) {
404  auto iter = leaf->beginIndexOn();
405  convert(iter, pHandle, *handle, offset);
406  }
407  else {
408  auto iter = leaf->beginIndexOn(mFilter);
409  convert(iter, pHandle, *handle, offset);
410  }
411  }
412  }
413 
415 
416  Attribute& mAttribute;
417  const std::vector<Index64>& mPointOffsets;
420  const size_t mIndex;
421  const FilterT& mFilter;
422  const bool mInCoreOnly;
423 }; // ConvertPointDataGridPositionOp
424 
425 
426 template<typename PointDataTreeType, typename Attribute, typename FilterT>
428 
429  using LeafNode = typename PointDataTreeType::LeafNodeType;
430  using ValueType = typename Attribute::ValueType;
431  using HandleT = typename Attribute::Handle;
434  using LeafRangeT = typename LeafManagerT::LeafRange;
435 
436  ConvertPointDataGridAttributeOp(Attribute& attribute,
437  const std::vector<Index64>& pointOffsets,
438  const Index64 startOffset,
439  const size_t index,
440  const Index stride,
441  const FilterT& filter,
442  const bool inCoreOnly)
443  : mAttribute(attribute)
444  , mPointOffsets(pointOffsets)
445  , mStartOffset(startOffset)
446  , mIndex(index)
447  , mStride(stride)
448  , mFilter(filter)
449  , mInCoreOnly(inCoreOnly) { }
450 
451  template <typename IterT>
452  void convert(IterT& iter, HandleT& targetHandle,
453  SourceHandleT& sourceHandle, Index64& offset) const
454  {
455  if (sourceHandle.isUniform()) {
456  const ValueType uniformValue(sourceHandle.get(0));
457  for (; iter; ++iter) {
458  for (Index i = 0; i < mStride; i++) {
459  targetHandle.set(static_cast<Index>(offset), i, uniformValue);
460  }
461  offset++;
462  }
463  }
464  else {
465  for (; iter; ++iter) {
466  for (Index i = 0; i < mStride; i++) {
467  targetHandle.set(static_cast<Index>(offset), i,
468  sourceHandle.get(*iter, /*stride=*/i));
469  }
470  offset++;
471  }
472  }
473  }
474 
475  void operator()(const LeafRangeT& range) const
476  {
477  HandleT pHandle(mAttribute);
478 
479  for (auto leaf = range.begin(); leaf; ++leaf) {
480 
481  assert(leaf.pos() < mPointOffsets.size());
482 
483  if (mInCoreOnly && leaf->buffer().isOutOfCore()) continue;
484 
485  Index64 offset = mStartOffset;
486 
487  if (leaf.pos() > 0) offset += mPointOffsets[leaf.pos() - 1];
488 
489  typename SourceHandleT::Ptr handle = ConversionTraits<ValueType>::handleFromLeaf(
490  *leaf, static_cast<Index>(mIndex));
491 
492  if (mFilter.state() == index::ALL) {
493  auto iter = leaf->beginIndexOn();
494  convert(iter, pHandle, *handle, offset);
495  } else {
496  auto iter = leaf->beginIndexOn(mFilter);
497  convert(iter, pHandle, *handle, offset);
498  }
499  }
500  }
501 
503 
504  Attribute& mAttribute;
505  const std::vector<Index64>& mPointOffsets;
507  const size_t mIndex;
508  const Index mStride;
509  const FilterT& mFilter;
510  const bool mInCoreOnly;
511 }; // ConvertPointDataGridAttributeOp
512 
513 template<typename PointDataTreeType, typename Group, typename FilterT>
515 
516  using LeafNode = typename PointDataTreeType::LeafNodeType;
517  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
519  using LeafRangeT = typename LeafManagerT::LeafRange;
520 
522  const std::vector<Index64>& pointOffsets,
523  const Index64 startOffset,
524  const AttributeSet::Descriptor::GroupIndex index,
525  const FilterT& filter,
526  const bool inCoreOnly)
527  : mGroup(group)
528  , mPointOffsets(pointOffsets)
529  , mStartOffset(startOffset)
530  , mIndex(index)
531  , mFilter(filter)
532  , mInCoreOnly(inCoreOnly) { }
533 
534  template <typename IterT>
535  void convert(IterT& iter, const GroupAttributeArray& groupArray, Index64& offset) const
536  {
537  const auto bitmask = static_cast<GroupType>(1 << mIndex.second);
538 
539  if (groupArray.isUniform()) {
540  if (groupArray.get(0) & bitmask) {
541  for (; iter; ++iter) {
542  mGroup.setOffsetOn(static_cast<Index>(offset));
543  offset++;
544  }
545  }
546  }
547  else {
548  for (; iter; ++iter) {
549  if (groupArray.get(*iter) & bitmask) {
550  mGroup.setOffsetOn(static_cast<Index>(offset));
551  }
552  offset++;
553  }
554  }
555  }
556 
557  void operator()(const LeafRangeT& range) const
558  {
559  for (auto leaf = range.begin(); leaf; ++leaf) {
560 
561  assert(leaf.pos() < mPointOffsets.size());
562 
563  if (mInCoreOnly && leaf->buffer().isOutOfCore()) continue;
564 
565  Index64 offset = mStartOffset;
566 
567  if (leaf.pos() > 0) offset += mPointOffsets[leaf.pos() - 1];
568 
569  const AttributeArray& array = leaf->constAttributeArray(mIndex.first);
570  assert(isGroup(array));
571  const GroupAttributeArray& groupArray = GroupAttributeArray::cast(array);
572 
573  if (mFilter.state() == index::ALL) {
574  auto iter = leaf->beginIndexOn();
575  convert(iter, groupArray, offset);
576  }
577  else {
578  auto iter = leaf->beginIndexOn(mFilter);
579  convert(iter, groupArray, offset);
580  }
581  }
582  }
583 
585 
586  Group& mGroup;
587  const std::vector<Index64>& mPointOffsets;
590  const FilterT& mFilter;
591  const bool mInCoreOnly;
592 }; // ConvertPointDataGridGroupOp
593 
594 template<typename PositionArrayT>
596 {
597  CalculatePositionBounds(const PositionArrayT& positions,
598  const math::Mat4d& inverse)
599  : mPositions(positions)
600  , mInverseMat(inverse)
601  , mMin(std::numeric_limits<Real>::max())
602  , mMax(-std::numeric_limits<Real>::max()) {}
603 
605  : mPositions(other.mPositions)
606  , mInverseMat(other.mInverseMat)
607  , mMin(std::numeric_limits<Real>::max())
608  , mMax(-std::numeric_limits<Real>::max()) {}
609 
610  void operator()(const tbb::blocked_range<size_t>& range) {
611  Vec3R pos;
612  for (size_t n = range.begin(), N = range.end(); n != N; ++n) {
613  mPositions.getPos(n, pos);
614  pos = mInverseMat.transform(pos);
615  mMin = math::minComponent(mMin, pos);
616  mMax = math::maxComponent(mMax, pos);
617  }
618  }
619 
620  void join(const CalculatePositionBounds& other) {
621  mMin = math::minComponent(mMin, other.mMin);
622  mMax = math::maxComponent(mMax, other.mMax);
623  }
624 
626  return BBoxd(mMin, mMax);
627  }
628 
629 private:
630  const PositionArrayT& mPositions;
631  const math::Mat4d& mInverseMat;
632  Vec3R mMin, mMax;
633 };
634 
635 } // namespace point_conversion_internal
636 
637 
639 
640 
641 template<typename CompressionT, typename PointDataGridT, typename PositionArrayT, typename PointIndexGridT>
642 inline typename PointDataGridT::Ptr
643 createPointDataGrid(const PointIndexGridT& pointIndexGrid, const PositionArrayT& positions,
644  const math::Transform& xform, Metadata::Ptr positionDefaultValue)
645 {
646  using PointDataTreeT = typename PointDataGridT::TreeType;
647  using LeafT = typename PointDataTree::LeafNodeType;
648  using PointIndexLeafT = typename PointIndexGridT::TreeType::LeafNodeType;
649  using PointIndexT = typename PointIndexLeafT::ValueType;
650  using LeafManagerT = typename tree::LeafManager<PointDataTreeT>;
651  using PositionAttributeT = TypedAttributeArray<Vec3f, CompressionT>;
652 
653  const NamePair positionType = PositionAttributeT::attributeType();
654 
655  // construct the Tree using a topology copy of the PointIndexGrid
656 
657  const auto& pointIndexTree = pointIndexGrid.tree();
658  typename PointDataTreeT::Ptr treePtr(new PointDataTreeT(pointIndexTree));
659 
660  // create attribute descriptor from position type
661 
662  auto descriptor = AttributeSet::Descriptor::create(positionType);
663 
664  // add default value for position if provided
665 
666  if (positionDefaultValue) descriptor->setDefaultValue("P", *positionDefaultValue);
667 
668  // retrieve position index
669 
670  const size_t positionIndex = descriptor->find("P");
671  assert(positionIndex != AttributeSet::INVALID_POS);
672 
673  // acquire registry lock to avoid locking when appending attributes in parallel
674 
676 
677  // populate position attribute
678 
679  LeafManagerT leafManager(*treePtr);
680  leafManager.foreach(
681  [&](LeafT& leaf, size_t /*idx*/) {
682 
683  // obtain the PointIndexLeafNode (using the origin of the current leaf)
684 
685  const auto* pointIndexLeaf = pointIndexTree.probeConstLeaf(leaf.origin());
686  assert(pointIndexLeaf);
687 
688  // initialise the attribute storage
689 
690  Index pointCount(static_cast<Index>(pointIndexLeaf->indices().size()));
691  leaf.initializeAttributes(descriptor, pointCount, &lock);
692 
693  // create write handle for position
694 
695  auto attributeWriteHandle = AttributeWriteHandle<Vec3f, CompressionT>::create(
696  leaf.attributeArray(positionIndex));
697 
698  Index index = 0;
699 
700  const PointIndexT
701  *begin = static_cast<PointIndexT*>(nullptr),
702  *end = static_cast<PointIndexT*>(nullptr);
703 
704  // iterator over every active voxel in the point index leaf
705 
706  for (auto iter = pointIndexLeaf->cbeginValueOn(); iter; ++iter) {
707 
708  // find the voxel center
709 
710  const Coord& ijk = iter.getCoord();
711  const Vec3d& positionCellCenter(ijk.asVec3d());
712 
713  // obtain pointers for this voxel from begin to end in the indices array
714 
715  pointIndexLeaf->getIndices(ijk, begin, end);
716 
717  while (begin < end) {
718 
719  typename PositionArrayT::value_type positionWorldSpace;
720  positions.getPos(*begin, positionWorldSpace);
721 
722  // compute the index-space position and then subtract the voxel center
723 
724  const Vec3d positionIndexSpace = xform.worldToIndex(positionWorldSpace);
725  const Vec3f positionVoxelSpace(positionIndexSpace - positionCellCenter);
726 
727  attributeWriteHandle->set(index++, positionVoxelSpace);
728 
729  ++begin;
730  }
731  }
732  },
733  /*threaded=*/true);
734 
735  auto grid = PointDataGridT::create(treePtr);
736  grid->setTransform(xform.copy());
737  return grid;
738 }
739 
740 
742 
743 
744 template <typename CompressionT, typename PointDataGridT, typename ValueT>
745 inline typename PointDataGridT::Ptr
746 createPointDataGrid(const std::vector<ValueT>& positions,
747  const math::Transform& xform,
748  Metadata::Ptr positionDefaultValue)
749 {
750  const PointAttributeVector<ValueT> pointList(positions);
751 
752  tools::PointIndexGrid::Ptr pointIndexGrid = tools::createPointIndexGrid<tools::PointIndexGrid>(pointList, xform);
753  return createPointDataGrid<CompressionT, PointDataGridT>(*pointIndexGrid, pointList, xform, positionDefaultValue);
754 }
755 
756 
758 
759 
760 template <typename PointDataTreeT, typename PointIndexTreeT, typename PointArrayT>
761 inline void
762 populateAttribute(PointDataTreeT& tree, const PointIndexTreeT& pointIndexTree,
763  const openvdb::Name& attributeName, const PointArrayT& data, const Index stride,
764  const bool insertMetadata)
765 {
767  using ValueType = typename PointArrayT::value_type;
768 
769  auto iter = tree.cbeginLeaf();
770 
771  if (!iter) return;
772 
773  const size_t index = iter->attributeSet().find(attributeName);
774 
775  if (index == AttributeSet::INVALID_POS) {
776  OPENVDB_THROW(KeyError, "Attribute not found to populate - " << attributeName << ".");
777  }
778 
779  if (insertMetadata) {
781  }
782 
783  // populate attribute
784 
785  typename tree::LeafManager<PointDataTreeT> leafManager(tree);
786 
787  PopulateAttributeOp<PointDataTreeT,
788  PointIndexTreeT,
789  PointArrayT> populate(pointIndexTree, data, index, stride);
790  tbb::parallel_for(leafManager.leafRange(), populate);
791 }
792 
793 
795 
796 
797 template <typename PositionAttribute, typename PointDataGridT, typename FilterT>
798 inline void
799 convertPointDataGridPosition( PositionAttribute& positionAttribute,
800  const PointDataGridT& grid,
801  const std::vector<Index64>& pointOffsets,
802  const Index64 startOffset,
803  const FilterT& filter,
804  const bool inCoreOnly)
805 {
806  using TreeType = typename PointDataGridT::TreeType;
807  using LeafManagerT = typename tree::LeafManager<const TreeType>;
808 
810 
811  const TreeType& tree = grid.tree();
812  auto iter = tree.cbeginLeaf();
813 
814  if (!iter) return;
815 
816  const size_t positionIndex = iter->attributeSet().find("P");
817 
818  positionAttribute.expand();
819  LeafManagerT leafManager(tree);
820  ConvertPointDataGridPositionOp<TreeType, PositionAttribute, FilterT> convert(
821  positionAttribute, pointOffsets, startOffset, grid.transform(), positionIndex,
822  filter, inCoreOnly);
823  tbb::parallel_for(leafManager.leafRange(), convert);
824  positionAttribute.compact();
825 }
826 
827 
829 
830 
831 template <typename TypedAttribute, typename PointDataTreeT, typename FilterT>
832 inline void
833 convertPointDataGridAttribute( TypedAttribute& attribute,
834  const PointDataTreeT& tree,
835  const std::vector<Index64>& pointOffsets,
836  const Index64 startOffset,
837  const unsigned arrayIndex,
838  const Index stride,
839  const FilterT& filter,
840  const bool inCoreOnly)
841 {
842  using LeafManagerT = typename tree::LeafManager<const PointDataTreeT>;
843 
845 
846  auto iter = tree.cbeginLeaf();
847 
848  if (!iter) return;
849 
850  attribute.expand();
851  LeafManagerT leafManager(tree);
852  ConvertPointDataGridAttributeOp<PointDataTreeT, TypedAttribute, FilterT> convert(
853  attribute, pointOffsets, startOffset, arrayIndex, stride,
854  filter, inCoreOnly);
855  tbb::parallel_for(leafManager.leafRange(), convert);
856  attribute.compact();
857 }
858 
859 
861 
862 
863 template <typename Group, typename PointDataTreeT, typename FilterT>
864 inline void
866  const PointDataTreeT& tree,
867  const std::vector<Index64>& pointOffsets,
868  const Index64 startOffset,
869  const AttributeSet::Descriptor::GroupIndex index,
870  const FilterT& filter,
871  const bool inCoreOnly)
872 {
873  using LeafManagerT= typename tree::LeafManager<const PointDataTreeT>;
874 
876 
877  auto iter = tree.cbeginLeaf();
878  if (!iter) return;
879 
880  LeafManagerT leafManager(tree);
881  ConvertPointDataGridGroupOp<PointDataTree, Group, FilterT> convert(
882  group, pointOffsets, startOffset, index,
883  filter, inCoreOnly);
884  tbb::parallel_for(leafManager.leafRange(), convert);
885 
886  // must call this after modifying point groups in parallel
887 
888  group.finalize();
889 }
890 
891 template<typename PositionWrapper, typename InterrupterT>
892 inline float
893 computeVoxelSize( const PositionWrapper& positions,
894  const uint32_t pointsPerVoxel,
895  const math::Mat4d transform,
896  const Index decimalPlaces,
897  InterrupterT* const interrupter)
898 {
899  using namespace point_conversion_internal;
900 
901  struct Local {
902 
903  static bool voxelSizeFromVolume(const double volume,
904  const size_t estimatedVoxelCount,
905  float& voxelSize)
906  {
907  // dictated by the math::ScaleMap limit
908  static const double minimumVoxelVolume(3e-15);
909  static const double maximumVoxelVolume(std::numeric_limits<float>::max());
910 
911  double voxelVolume = volume / static_cast<double>(estimatedVoxelCount);
912  bool valid = true;
913 
914  if (voxelVolume < minimumVoxelVolume) {
915  voxelVolume = minimumVoxelVolume;
916  valid = false;
917  }
918  else if (voxelVolume > maximumVoxelVolume) {
919  voxelVolume = maximumVoxelVolume;
920  valid = false;
921  }
922 
923  voxelSize = static_cast<float>(math::Pow(voxelVolume, 1.0/3.0));
924  return valid;
925  }
926 
927  static float truncate(const float voxelSize, Index decPlaces)
928  {
929  float truncatedVoxelSize = voxelSize;
930 
931  // attempt to truncate from decPlaces -> 11
932  for (int i = decPlaces; i < 11; i++) {
933  truncatedVoxelSize = static_cast<float>(math::Truncate(double(voxelSize), i));
934  if (truncatedVoxelSize != 0.0f) break;
935  }
936 
937  return truncatedVoxelSize;
938  }
939  };
940 
941  if (pointsPerVoxel == 0) OPENVDB_THROW(ValueError, "Points per voxel cannot be zero.");
942 
943  // constructed with the default voxel size as specified by openvdb interface values
944 
945  float voxelSize(0.1f);
946 
947  const size_t numPoints = positions.size();
948 
949  // return the default voxel size if we have zero or only 1 point
950 
951  if (numPoints <= 1) return voxelSize;
952 
953  size_t targetVoxelCount(numPoints / size_t(pointsPerVoxel));
954  if (targetVoxelCount == 0) targetVoxelCount++;
955 
956  // calculate the world space, transform-oriented bounding box
957 
958  math::Mat4d inverseTransform = transform.inverse();
959  inverseTransform = math::unit(inverseTransform);
960 
961  tbb::blocked_range<size_t> range(0, numPoints);
962  CalculatePositionBounds<PositionWrapper> calculateBounds(positions, inverseTransform);
963  tbb::parallel_reduce(range, calculateBounds);
964 
965  BBoxd bbox = calculateBounds.getBoundingBox();
966 
967  // return default size if points are coincident
968 
969  if (bbox.min() == bbox.max()) return voxelSize;
970 
971  double volume = bbox.volume();
972 
973  // handle points that are collinear or coplanar by expanding the volume
974 
975  if (math::isApproxZero(volume)) {
976  Vec3d extents = bbox.extents().sorted().reversed();
977  if (math::isApproxZero(extents[1])) {
978  // colinear (maxExtent^3)
979  volume = extents[0]*extents[0]*extents[0];
980  }
981  else {
982  // coplanar (maxExtent*nextMaxExtent^2)
983  volume = extents[0]*extents[1]*extents[1];
984  }
985  }
986 
987  double previousVolume = volume;
988 
989  if (!Local::voxelSizeFromVolume(volume, targetVoxelCount, voxelSize)) {
990  OPENVDB_LOG_DEBUG("Out of range, clamping voxel size.");
991  return voxelSize;
992  }
993 
994  size_t previousVoxelCount(0);
995  size_t voxelCount(1);
996 
997  if (interrupter) interrupter->start("Computing voxel size");
998 
999  while (voxelCount > previousVoxelCount)
1000  {
1001  math::Transform::Ptr newTransform;
1002 
1003  if (!math::isIdentity(transform))
1004  {
1005  // if using a custom transform, pre-scale by coefficients
1006  // which define the new voxel size
1007 
1008  math::Mat4d matrix(transform);
1009  matrix.preScale(Vec3d(voxelSize) / math::getScale(matrix));
1010  newTransform = math::Transform::createLinearTransform(matrix);
1011  }
1012  else
1013  {
1014  newTransform = math::Transform::createLinearTransform(voxelSize);
1015  }
1016 
1017  // create a mask grid of the points from the calculated voxel size
1018  // this is the same function call as tools::createPointMask() which has
1019  // been duplicated to provide an interrupter
1020 
1021  MaskGrid::Ptr mask = createGrid<MaskGrid>(false);
1022  mask->setTransform(newTransform);
1023  tools::PointsToMask<MaskGrid, InterrupterT> pointMaskOp(*mask, interrupter);
1024  pointMaskOp.addPoints(positions);
1025 
1026  if (interrupter && util::wasInterrupted(interrupter)) break;
1027 
1028  previousVoxelCount = voxelCount;
1029  voxelCount = mask->activeVoxelCount();
1030  volume = math::Pow3(voxelSize) * static_cast<float>(voxelCount);
1031 
1032  // stop if no change in the volume or the volume has increased
1033 
1034  if (volume >= previousVolume) break;
1035  previousVolume = volume;
1036 
1037  const float previousVoxelSize = voxelSize;
1038 
1039  // compute the new voxel size and if invalid return the previous value
1040 
1041  if (!Local::voxelSizeFromVolume(volume, targetVoxelCount, voxelSize)) {
1042  voxelSize = previousVoxelSize;
1043  break;
1044  }
1045 
1046  // halt convergence if the voxel size has decreased by less
1047  // than 10% in this iteration
1048 
1049  if (voxelSize / previousVoxelSize > 0.9f) break;
1050  }
1051 
1052  if (interrupter) interrupter->end();
1053 
1054  // truncate the voxel size for readability and return the value
1055 
1056  return Local::truncate(voxelSize, decimalPlaces);
1057 }
1058 
1059 
1061 
1062 
1063 // deprecated functions
1064 
1065 
1066 template <typename PositionAttribute, typename PointDataGridT>
1068 inline void
1069 convertPointDataGridPosition( PositionAttribute& positionAttribute,
1070  const PointDataGridT& grid,
1071  const std::vector<Index64>& pointOffsets,
1072  const Index64 startOffset,
1073  const std::vector<Name>& includeGroups,
1074  const std::vector<Name>& excludeGroups,
1075  const bool inCoreOnly = false)
1076 {
1077  auto leaf = grid.tree().cbeginLeaf();
1078  if (!leaf) return;
1079  MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
1080  convertPointDataGridPosition(positionAttribute, grid, pointOffsets, startOffset,
1081  filter, inCoreOnly);
1082 }
1083 
1084 
1085 template <typename TypedAttribute, typename PointDataTreeT>
1087 inline void
1088 convertPointDataGridAttribute( TypedAttribute& attribute,
1089  const PointDataTreeT& tree,
1090  const std::vector<Index64>& pointOffsets,
1091  const Index64 startOffset,
1092  const unsigned arrayIndex,
1093  const Index stride,
1094  const std::vector<Name>& includeGroups,
1095  const std::vector<Name>& excludeGroups,
1096  const bool inCoreOnly = false)
1097 {
1098  auto leaf = tree.cbeginLeaf();
1099  if (!leaf) return;
1100  MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
1101  convertPointDataGridAttribute(attribute, tree, pointOffsets, startOffset,
1102  arrayIndex, stride, filter, inCoreOnly);
1103 }
1104 
1105 
1106 template <typename Group, typename PointDataTreeT>
1108 inline void
1110  const PointDataTreeT& tree,
1111  const std::vector<Index64>& pointOffsets,
1112  const Index64 startOffset,
1113  const AttributeSet::Descriptor::GroupIndex index,
1114  const std::vector<Name>& includeGroups,
1115  const std::vector<Name>& excludeGroups,
1116  const bool inCoreOnly = false)
1117 {
1118  auto leaf = tree.cbeginLeaf();
1119  if (!leaf) return;
1120  MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
1121  convertPointDataGridGroup(group, tree, pointOffsets, startOffset,
1122  index, filter, inCoreOnly);
1123 }
1124 
1125 
1126 } // namespace points
1127 } // namespace OPENVDB_VERSION_NAME
1128 } // namespace openvdb
1129 
1130 #endif // OPENVDB_POINTS_POINT_CONVERSION_HAS_BEEN_INCLUDED
1131 
1132 // Copyright (c) DreamWorks Animation LLC
1133 // All rights reserved. This software is distributed under the
1134 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
SharedPtr< Transform > Ptr
Definition: Transform.h:69
void addPoints(const PointListT &points, size_t grainSize=1024)
Activates the state of any voxel in the input grid that contains a point.
Definition: PointsToMask.h:150
typename PointIndexTreeType::LeafNodeType PointIndexLeafNode
Definition: PointConversion.h:288
Ptr copy() const
Definition: Transform.h:77
#define OPENVDB_DEPRECATED
Definition: Platform.h:69
typename ConversionTraits< ValueType >::Handle SourceHandleT
Definition: PointConversion.h:432
Typed class for storing attribute data.
Definition: AttributeArray.h:608
Vec3d worldToIndex(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:137
void operator()(const LeafRangeT &range) const
Definition: PointConversion.h:387
void join(const CalculatePositionBounds &other)
Definition: PointConversion.h:620
OPENVDB_DEPRECATED void convertPointDataGridGroup(Group &group, const PointDataTreeT &tree, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const AttributeSet::Descriptor::GroupIndex index, const std::vector< Name > &includeGroups, const std::vector< Name > &excludeGroups, const bool inCoreOnly=false)
Definition: PointConversion.h:1109
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointConversion.h:352
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
OPENVDB_API void calculateBounds(const Transform &t, const Vec3d &minWS, const Vec3d &maxWS, Vec3d &minIS, Vec3d &maxIS)
Calculate an axis-aligned bounding box in index space from an axis-aligned bounding box in world spac...
#define OPENVDB_LOG_DEBUG(message)
In debug builds only, log a debugging message of the form &#39;someVar << "text" << ...&#39;.
Definition: logging.h:290
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointConversion.h:519
Definition: IndexFilter.h:164
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
const std::vector< Index64 > & mPointOffsets
Definition: PointConversion.h:587
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
const std::vector< Index64 > & mPointOffsets
Definition: PointConversion.h:417
typename tree::LeafManager< const PointDataTreeType > LeafManagerT
Definition: PointConversion.h:351
std::shared_ptr< Handle > Ptr
Definition: AttributeArray.h:948
void operator()(const LeafRangeT &range) const
Definition: PointConversion.h:475
math::BBox< Vec3d > BBoxd
Definition: Types.h:91
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:385
Definition: Coord.h:614
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointConversion.h:302
Index32 Index
Definition: Types.h:61
void convert(IterT &iter, HandleT &targetHandle, SourceHandleT &sourceHandle, Index64 &offset) const
Definition: PointConversion.h:376
void populateAttribute(PointDataTreeT &tree, const PointIndexTreeT &pointIndexTree, const openvdb::Name &attributeName, const PointArrayT &data, const Index stride=1, const bool insertMetadata=true)
Stores point attribute data in an existing PointDataGrid attribute.
Definition: PointConversion.h:762
CalculatePositionBounds(const CalculatePositionBounds &other, tbb::split)
Definition: PointConversion.h:604
MatType unit(const MatType &mat, typename MatType::value_type eps=1.0e-8)
Return a copy of the given matrix with its upper 3×3 rows normalized.
Definition: Mat.h:680
PointDataGridT::Ptr createPointDataGrid(const std::vector< ValueT > &positions, const math::Transform &xform, Metadata::Ptr positionDefaultValue=Metadata::Ptr())
Convenience method to create a PointDataGrid from a std::vector of point positions.
Definition: PointConversion.h:746
std::shared_ptr< Handle > Ptr
Definition: AttributeArray.h:877
size_t size() const
Definition: PointConversion.h:228
Write-able version of AttributeHandle.
Definition: AttributeArray.h:944
OPENVDB_DEPRECATED void convertPointDataGridPosition(PositionAttribute &positionAttribute, const PointDataGridT &grid, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const std::vector< Name > &includeGroups, const std::vector< Name > &excludeGroups, const bool inCoreOnly=false)
Definition: PointConversion.h:1069
Mat4< double > Mat4d
Definition: Mat4.h:1361
Definition: Types.h:231
ConvertPointDataGridPositionOp(Attribute &attribute, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const math::Transform &transform, const size_t index, const FilterT &filter, const bool inCoreOnly)
Definition: PointConversion.h:354
bool isIdentity(const MatType &m)
Determine if a matrix is an identity matrix.
Definition: Mat.h:892
bool isUniform() const override
Return true if this array is stored as a single uniform value.
Definition: AttributeArray.h:746
Vec3< double > Vec3d
Definition: Vec3.h:689
Point attribute manipulation in a VDB Point Grid.
Point group manipulation in a VDB Point Grid.
Definition: AttributeArrayString.h:136
typename PointDataTreeType::LeafNodeType LeafNode
Definition: PointConversion.h:347
Index filters primarily designed to be used with a FilterIndexIter.
float computeVoxelSize(const PositionWrapper &positions, const uint32_t pointsPerVoxel, const math::Mat4d transform=math::Mat4d::identity(), const Index decimalPlaces=5, InterrupterT *const interrupter=nullptr)
Definition: PointConversion.h:893
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointConversion.h:517
Vec2< T > maxComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise maximum of the two vectors.
Definition: Vec2.h:539
ConvertPointDataGridGroupOp(Group &group, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const AttributeSet::Descriptor::GroupIndex index, const FilterT &filter, const bool inCoreOnly)
Definition: PointConversion.h:521
static Handle::Ptr handleFromLeaf(LeafT &leaf, Index index)
Definition: PointConversion.h:252
Type Truncate(Type x, unsigned int digits)
Return x truncated to the given number of decimal digits.
Definition: Math.h:844
double Real
Definition: Types.h:67
typename PointDataTreeType::LeafNodeType LeafNode
Definition: PointConversion.h:429
std::pair< Name, Name > NamePair
Definition: AttributeArray.h:65
void operator()(const tbb::blocked_range< size_t > &range)
Definition: PointConversion.h:610
std::shared_ptr< StringAttributeWriteHandle > Ptr
Definition: AttributeArrayString.h:171
Type Pow3(Type x)
Return x3.
Definition: Math.h:526
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:128
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointConversion.h:287
bool isApproxZero(const Type &x)
Return true if x is equal to zero to within the default floating-point comparison tolerance...
Definition: Math.h:320
std::string Name
Definition: Name.h:44
PopulateAttributeOp(const PointIndexTreeType &pointIndexTree, const AttributeListType &data, const size_t index, const Index stride=1)
Definition: PointConversion.h:293
typename PointDataTreeType::LeafNodeType LeafNode
Definition: PointConversion.h:516
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointConversion.h:434
void preScale(const Vec3< T0 > &v)
Definition: Mat4.h:782
void convert(IterT &iter, HandleT &targetHandle, SourceHandleT &sourceHandle, Index64 &offset) const
Definition: PointConversion.h:452
typename PointIndexLeafNode::IndexArray IndexArray
Definition: PointConversion.h:289
const AttributeListType & mData
Definition: PointConversion.h:339
typename tree::LeafManager< const PointDataTreeType > LeafManagerT
Definition: PointConversion.h:433
ValueType get(Index n) const
Return the value at index n.
Definition: AttributeArray.h:1441
const math::Transform & mTransform
Definition: PointConversion.h:419
ValueType get(Index n, Index m=0) const
Definition: AttributeArray.h:2217
Definition: Exceptions.h:40
std::shared_ptr< StringAttributeHandle > Ptr
Definition: AttributeArrayString.h:139
typename AttributeListType::value_type ValueType
Definition: PointConversion.h:290
typename Attribute::ValueType ValueType
Definition: PointConversion.h:348
ValueType value_type
Definition: PointConversion.h:221
Makes every voxel of a grid active if it contains a point.
Definition: PointsToMask.h:94
ElementType volume() const
Return the volume enclosed by this bounding box.
Definition: BBox.h:127
static WriteHandle::Ptr writeHandleFromLeaf(LeafT &leaf, Index index)
Definition: PointConversion.h:274
This tool produces a grid where every voxel that contains a point is active. It employes thread-local...
Point-partitioner compatible STL vector attribute wrapper for convenience.
Definition: PointConversion.h:218
Mat4 inverse(T tolerance=0) const
Definition: Mat4.h:531
uint64_t Index64
Definition: Types.h:60
const size_t mIndex
Definition: PointConversion.h:340
typename Attribute::Handle HandleT
Definition: PointConversion.h:349
PointAttributeVector(const std::vector< value_type > &data, const Index stride=1)
Definition: PointConversion.h:223
void getPos(size_t n, ValueType &xyz) const
Definition: PointConversion.h:229
Definition: AttributeArray.h:873
SharedPtr< Grid > Ptr
Definition: Grid.h:596
Index64 pointCount(const PointDataTreeT &tree, const FilterT &filter=NullFilter(), const bool inCoreOnly=false, const bool threaded=true)
Count the total number of points in a PointDataTree.
Definition: PointCount.h:115
typename tree::LeafManager< PointDataTreeType > LeafManagerT
Definition: PointConversion.h:286
Definition: AttributeArrayString.h:168
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:109
const Vec3T & max() const
Return a const reference to the maximum point of this bounding box.
Definition: BBox.h:91
static Handle::Ptr handleFromLeaf(LeafT &leaf, Index index)
Definition: PointConversion.h:268
OPENVDB_DEPRECATED void convertPointDataGridAttribute(TypedAttribute &attribute, const PointDataTreeT &tree, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const unsigned arrayIndex, const Index stride, const std::vector< Name > &includeGroups, const std::vector< Name > &excludeGroups, const bool inCoreOnly=false)
Definition: PointConversion.h:1088
Definition: IndexIterator.h:70
Vec3< T > sorted() const
Return a vector with the components of this in ascending order.
Definition: Vec3.h:475
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:212
Definition: Transform.h:66
const std::vector< Index64 > & mPointOffsets
Definition: PointConversion.h:505
Index64 pointOffsets(std::vector< Index64 > &pointOffsets, const PointDataTreeT &tree, const FilterT &filter=NullFilter(), const bool inCoreOnly=false, const bool threaded=true)
Populate an array of cumulative point offsets per leaf node.
Definition: PointCount.h:149
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
typename tree::LeafManager< const PointDataTreeType > LeafManagerT
Definition: PointConversion.h:518
uint8_t GroupType
Definition: AttributeGroup.h:50
Vec3T extents() const
Return the extents of this bounding box, i.e., the length along each axis.
Definition: BBox.h:280
typename ConversionTraits< ValueType >::WriteHandle HandleT
Definition: PointConversion.h:291
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:530
const Vec3T & min() const
Return a const reference to the minimum point of this bounding box.
Definition: BBox.h:89
Attribute array storage for string data using Descriptor Metadata.
SharedPtr< Metadata > Ptr
Definition: Metadata.h:53
void convert(IterT &iter, const GroupAttributeArray &groupArray, Index64 &offset) const
Definition: PointConversion.h:535
Definition: Exceptions.h:92
bool isGroup(const AttributeArray &array)
Definition: AttributeGroup.h:93
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:180
const Index mStride
Definition: PointConversion.h:341
Vec3< T > reversed() const
Return the vector (z, y, x)
Definition: Vec3.h:485
Definition: Exceptions.h:86
BBoxd getBoundingBox() const
Definition: PointConversion.h:625
typename Attribute::Handle HandleT
Definition: PointConversion.h:431
void operator()(const LeafRangeT &range) const
Definition: PointConversion.h:557
typename Attribute::ValueType ValueType
Definition: PointConversion.h:430
static openvdb::Name zero()
Definition: PointConversion.h:266
const PointIndexTreeType & mPointIndexTree
Definition: PointConversion.h:338
Base class for storing attribute data.
Definition: AttributeArray.h:118
static T zero()
Definition: PointConversion.h:250
Set of Attribute Arrays which tracks metadata about each array.
std::vector< Index > IndexArray
Definition: PointMove.h:188
CalculatePositionBounds(const PositionArrayT &positions, const math::Mat4d &inverse)
Definition: PointConversion.h:597
Vec3< typename MatType::value_type > getScale(const MatType &mat)
Return a Vec3 representing the lengths of the passed matrix&#39;s upper 3×3&#39;s rows.
Definition: Mat.h:665
Type Pow(Type x, int n)
Return xn.
Definition: Math.h:535
static WriteHandle::Ptr writeHandleFromLeaf(LeafT &leaf, Index index)
Definition: PointConversion.h:257
ConvertPointDataGridAttributeOp(Attribute &attribute, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const size_t index, const Index stride, const FilterT &filter, const bool inCoreOnly)
Definition: PointConversion.h:436
ValueType PosType
Definition: PointConversion.h:220
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76