HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PointConversion.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2017 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
29 ///////////////////////////////////////////////////////////////////////////
30 
31 /// @author Dan Bailey, Nick Avramoussis
32 ///
33 /// @file points/PointConversion.h
34 ///
35 /// @brief Convert points and attributes to and from VDB Point Data grids.
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 
63 /// @brief Localises points with position into a @c PointDataGrid into two stages:
64 /// allocation of the leaf attribute data and population of the positions.
65 ///
66 /// @param pointIndexGrid a PointIndexGrid into the points.
67 /// @param positions list of world space point positions.
68 /// @param xform world to index space transform.
69 /// @param positionDefaultValue metadata default position value
70 ///
71 /// @note The position data must be supplied in a Point-Partitioner compatible
72 /// data structure. A convenience PointAttributeVector class is offered.
73 ///
74 /// @note The position data is populated separately to perform world space to
75 /// voxel space conversion and apply quantisation.
76 ///
77 /// @note A @c PointIndexGrid to the points must be supplied to perform this
78 /// operation. Typically this is built implicitly by the PointDataGrid constructor.
79 
80 template<
81  typename CompressionT,
82  typename PointDataGridT,
83  typename PositionArrayT,
84  typename PointIndexGridT>
85 inline typename PointDataGridT::Ptr
87  const PointIndexGridT& pointIndexGrid, const PositionArrayT& positions,
88  const math::Transform& xform, Metadata::Ptr positionDefaultValue = Metadata::Ptr());
89 
90 
91 /// @brief Convenience method to create a @c PointDataGrid from a std::vector of
92 /// point positions.
93 ///
94 /// @param positions list of world space point positions.
95 /// @param xform world to index space transform.
96 /// @param positionDefaultValue metadata default position value
97 ///
98 /// @note This method implicitly wraps the std::vector for a Point-Partitioner compatible
99 /// data structure and creates the required @c PointIndexGrid to the points.
100 
101 template <typename CompressionT, typename PointDataGridT, typename ValueT>
102 inline typename PointDataGridT::Ptr
103 createPointDataGrid(const std::vector<ValueT>& positions, const math::Transform& xform,
104  Metadata::Ptr positionDefaultValue = Metadata::Ptr());
105 
106 
107 /// @brief Stores point attribute data in an existing @c PointDataGrid attribute.
108 ///
109 /// @param tree the PointDataGrid to be populated.
110 /// @param pointIndexTree a PointIndexTree into the points.
111 /// @param attributeName the name of the VDB Points attribute to be populated.
112 /// @param data a wrapper to the attribute data.
113 /// @param stride the stride of the attribute
114 /// @param insertMetadata true if strings are to be automatically inserted as metadata.
115 ///
116 /// @note A @c PointIndexGrid to the points must be supplied to perform this
117 /// operation. This is required to ensure the same point index ordering.
118 template <typename PointDataTreeT, typename PointIndexTreeT, typename PointArrayT>
119 inline void
120 populateAttribute( PointDataTreeT& tree, const PointIndexTreeT& pointIndexTree,
121  const openvdb::Name& attributeName, const PointArrayT& data,
122  const Index stride = 1, const bool insertMetadata = true);
123 
124 /// @brief Convert the position attribute from a Point Data Grid
125 ///
126 /// @param positionAttribute the position attribute to be populated.
127 /// @param grid the PointDataGrid to be converted.
128 /// @param pointOffsets a vector of cumulative point offsets for each leaf
129 /// @param startOffset a value to shift all the point offsets by
130 /// @param includeGroups a vector of VDB Points groups to be included (default is all)
131 /// @param excludeGroups a vector of VDB Points groups to be excluded (default is none)
132 /// @param inCoreOnly true if out-of-core leaf nodes are to be ignored
133 ///
134 
135 template <typename PositionAttribute, typename PointDataGridT>
136 inline void
137 convertPointDataGridPosition( PositionAttribute& positionAttribute,
138  const PointDataGridT& grid,
139  const std::vector<Index64>& pointOffsets,
140  const Index64 startOffset,
141  const std::vector<Name>& includeGroups = std::vector<Name>(),
142  const std::vector<Name>& excludeGroups = std::vector<Name>(),
143  const bool inCoreOnly = false);
144 
145 
146 /// @brief Convert the attribute from a PointDataGrid
147 ///
148 /// @param attribute the attribute to be populated.
149 /// @param tree the PointDataTree to be converted.
150 /// @param pointOffsets a vector of cumulative point offsets for each leaf.
151 /// @param startOffset a value to shift all the point offsets by
152 /// @param arrayIndex the index in the Descriptor of the array to be converted.
153 /// @param stride the stride of the attribute
154 /// @param includeGroups a vector of VDB Points groups to be included (default is all)
155 /// @param excludeGroups a vector of VDB Points groups to be excluded (default is none)
156 /// @param inCoreOnly true if out-of-core leaf nodes are to be ignored
157 template <typename TypedAttribute, typename PointDataTreeT>
158 inline void
160  const PointDataTreeT& tree,
161  const std::vector<Index64>& pointOffsets,
162  const Index64 startOffset,
163  const unsigned arrayIndex,
164  const Index stride = 1,
165  const std::vector<Name>& includeGroups = std::vector<Name>(),
166  const std::vector<Name>& excludeGroups = std::vector<Name>(),
167  const bool inCoreOnly = false);
168 
169 
170 /// @brief Convert the group from a PointDataGrid
171 ///
172 /// @param group the group to be populated.
173 /// @param tree the PointDataTree to be converted.
174 /// @param pointOffsets a vector of cumulative point offsets for each leaf
175 /// @param startOffset a value to shift all the point offsets by
176 /// @param index the group index to be converted.
177 /// @param includeGroups a vector of VDB Points groups to be included (default is all)
178 /// @param excludeGroups a vector of VDB Points groups to be excluded (default is none)
179 /// @param inCoreOnly true if out-of-core leaf nodes are to be ignored
180 ///
181 
182 template <typename Group, typename PointDataTreeT>
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 std::vector<Name>& includeGroups = std::vector<Name>(),
190  const std::vector<Name>& excludeGroups = std::vector<Name>(),
191  const bool inCoreOnly = false);
192 
193 /// @ brief Given a container of world space positions and a target points per voxel,
194 /// compute a uniform voxel size that would best represent the storage of the points in a grid.
195 /// This voxel size is typically used for conversion of the points into a PointDataGrid.
196 ///
197 /// @param positions array of world space positions
198 /// @param pointsPerVoxel the target number of points per voxel, must be positive and non-zero
199 /// @param transform voxel size will be computed using this optional transform if provided
200 /// @param decimalPlaces for readability, truncate voxel size to this number of decimals
201 /// @param interrupter an optional interrupter
202 ///
203 /// @note if none or one point provided in positions, the default voxel size of 0.1 will be returned
204 ///
205 template<typename PositionWrapper, typename InterrupterT = openvdb::util::NullInterrupter>
206 inline float
207 computeVoxelSize( const PositionWrapper& positions,
208  const uint32_t pointsPerVoxel,
210  const Index decimalPlaces = 5,
211  InterrupterT* const interrupter = nullptr);
212 
213 
214 ////////////////////////////////////////
215 
216 
217 /// @brief Point-partitioner compatible STL vector attribute wrapper for convenience
218 template<typename ValueType>
220 public:
221  using PosType = ValueType;
222  using value_type= ValueType;
223 
224  PointAttributeVector(const std::vector<value_type>& data,
225  const Index stride = 1)
226  : mData(data)
227  , mStride(stride) { }
228 
229  size_t size() const { return mData.size(); }
230  void getPos(size_t n, ValueType& xyz) const { xyz = mData[n]; }
231  void get(ValueType& value, size_t n) const { value = mData[n]; }
232  void get(ValueType& value, size_t n, openvdb::Index m) const { value = mData[n * mStride + m]; }
233 
234 private:
235  const std::vector<value_type>& mData;
236  const Index mStride;
237 }; // PointAttributeVector
238 
239 
240 ////////////////////////////////////////
241 
242 
243 namespace point_conversion_internal {
244 
245 
246 // ConversionTraits to create the relevant Attribute Handles from a LeafNode
247 template <typename T> struct ConversionTraits
248 {
251  static T zero() { return zeroVal<T>(); }
252  template <typename LeafT>
253  static typename Handle::Ptr handleFromLeaf(LeafT& leaf, Index index) {
254  const AttributeArray& array = leaf.constAttributeArray(index);
255  return Handle::create(array);
256  }
257  template <typename LeafT>
258  static typename WriteHandle::Ptr writeHandleFromLeaf(LeafT& leaf, Index index) {
259  AttributeArray& array = leaf.attributeArray(index);
260  return WriteHandle::create(array);
261  }
262 }; // ConversionTraits
263 template <> struct ConversionTraits<openvdb::Name>
264 {
267  static openvdb::Name zero() { return ""; }
268  template <typename LeafT>
269  static typename Handle::Ptr handleFromLeaf(LeafT& leaf, Index index) {
270  const AttributeArray& array = leaf.constAttributeArray(index);
271  const AttributeSet::Descriptor& descriptor = leaf.attributeSet().descriptor();
272  return Handle::create(array, descriptor.getMetadata());
273  }
274  template <typename LeafT>
275  static typename WriteHandle::Ptr writeHandleFromLeaf(LeafT& leaf, Index index) {
276  AttributeArray& array = leaf.attributeArray(index);
277  const AttributeSet::Descriptor& descriptor = leaf.attributeSet().descriptor();
278  return WriteHandle::create(array, descriptor.getMetadata());
279  }
280 }; // ConversionTraits<openvdb::Name>
281 
282 
283 template<typename PointDataTreeType, typename PointIndexTreeType>
285 
287  using LeafRangeT = typename LeafManagerT::LeafRange;
288 
289  using PointIndexLeafNode = typename PointIndexTreeType::LeafNodeType;
290  using IndexArray = typename PointIndexLeafNode::IndexArray;
291 
292  InitialiseAttributesOp( const PointIndexTreeType& pointIndexTree,
293  const AttributeSet::Descriptor::Ptr& attributeDescriptor)
294  : mPointIndexTree(pointIndexTree)
295  , mAttributeDescriptor(attributeDescriptor) { }
296 
297  void operator()(const typename LeafManagerT::LeafRange& range) const {
298  for (auto leaf = range.begin(); leaf; ++leaf) {
299 
300  // obtain the PointIndexLeafNode (using the origin of the current leaf)
301 
302  const PointIndexLeafNode* pointIndexLeaf = mPointIndexTree.probeConstLeaf(leaf->origin());
303 
304  if (!pointIndexLeaf) continue;
305 
306  // initialise the attribute storage
307 
308  const IndexArray& indices = pointIndexLeaf->indices();
309 
310  auto pointCount = static_cast<Index>(indices.size());
311 
312  leaf->initializeAttributes(mAttributeDescriptor, pointCount);
313  }
314  }
315 
316  //////////
317 
318  const PointIndexTreeType& mPointIndexTree;
319  const AttributeSet::Descriptor::Ptr& mAttributeDescriptor;
320 };
321 
322 template< typename PointDataTreeType,
323  typename PointIndexTreeType,
324  typename PositionListType>
326 
328  using LeafRangeT = typename LeafManagerT::LeafRange;
329 
330  using PointIndexLeafNode = typename PointIndexTreeType::LeafNodeType;
331  using IndexArray = typename PointIndexLeafNode::IndexArray;
332 
334 
335  PopulatePositionAttributeOp(const PointIndexTreeType& pointIndexTree,
336  const math::Transform& transform,
337  const PositionListType& positions)
338  : mPointIndexTree(pointIndexTree)
339  , mTransform(transform)
340  , mPositions(positions) { }
341 
342  void operator()(const typename LeafManagerT::LeafRange& range) const {
343 
344  for (auto leaf = range.begin(); leaf; ++leaf) {
345 
346  // obtain the PointIndexLeafNode (using the origin of the current leaf)
347 
348  const PointIndexLeafNode* pointIndexLeaf = mPointIndexTree.probeConstLeaf(leaf->origin());
349 
350  if (!pointIndexLeaf) continue;
351 
352  auto attributeWriteHandle = AttributeWriteHandle<Vec3f>::create(leaf->attributeArray("P"));
353 
354  Index64 index = 0;
355 
356  const IndexArray& indices = pointIndexLeaf->indices();
357 
358  for (const Index64 i: indices) {
359  ValueType positionWorldSpace;
360  mPositions.getPos(i, positionWorldSpace);
361 
362  const ValueType positionIndexSpace = mTransform.worldToIndex(positionWorldSpace);
363 
364  const ValueType positionVoxelSpace = ValueType(
365  positionIndexSpace.x() - math::Round(positionIndexSpace.x()),
366  positionIndexSpace.y() - math::Round(positionIndexSpace.y()),
367  positionIndexSpace.z() - math::Round(positionIndexSpace.z()));
368 
369  attributeWriteHandle->set(static_cast<Index>(index), Vec3f(positionVoxelSpace));
370 
371  index++;
372  }
373  }
374  }
375 
376  //////////
377 
378  const PointIndexTreeType& mPointIndexTree;
380  const PositionListType& mPositions;
381 };
382 
383 template< typename PointDataTreeType,
384  typename PointIndexTreeType,
385  typename AttributeListType>
387 
389  using LeafRangeT = typename LeafManagerT::LeafRange;
390  using PointIndexLeafNode = typename PointIndexTreeType::LeafNodeType;
391  using IndexArray = typename PointIndexLeafNode::IndexArray;
394 
395  PopulateAttributeOp(const PointIndexTreeType& pointIndexTree,
396  const AttributeListType& data,
397  const size_t index,
398  const Index stride = 1)
399  : mPointIndexTree(pointIndexTree)
400  , mData(data)
401  , mIndex(index)
402  , mStride(stride) { }
403 
404  void operator()(const typename LeafManagerT::LeafRange& range) const {
405 
406  for (auto leaf = range.begin(); leaf; ++leaf) {
407 
408  // obtain the PointIndexLeafNode (using the origin of the current leaf)
409 
410  const PointIndexLeafNode* pointIndexLeaf =
411  mPointIndexTree.probeConstLeaf(leaf->origin());
412 
413  if (!pointIndexLeaf) continue;
414 
415  typename HandleT::Ptr attributeWriteHandle =
416  ConversionTraits<ValueType>::writeHandleFromLeaf(*leaf, static_cast<Index>(mIndex));
417 
418  Index64 index = 0;
419 
420  const IndexArray& indices = pointIndexLeaf->indices();
421 
422  for (const Index64 leafIndex: indices)
423  {
425  for (Index i = 0; i < mStride; i++) {
426  mData.get(value, leafIndex, i);
427  attributeWriteHandle->set(static_cast<Index>(index), i, value);
428  }
429  index++;
430  }
431 
432  // attempt to compact the array
433 
434  attributeWriteHandle->compact();
435  }
436  }
437 
438  //////////
439 
440  const PointIndexTreeType& mPointIndexTree;
441  const AttributeListType& mData;
442  const size_t mIndex;
443  const Index mStride;
444 };
445 
446 template<typename PointDataTreeType, typename Attribute>
448 
449  using LeafNode = typename PointDataTreeType::LeafNodeType;
450  using ValueType = typename Attribute::ValueType;
452  using LeafRangeT = typename LeafManagerT::LeafRange;
453 
455  const std::vector<Index64>& pointOffsets,
456  const Index64 startOffset,
457  const math::Transform& transform,
458  const size_t index,
459  const std::vector<Name>& includeGroups = std::vector<Name>(),
460  const std::vector<Name>& excludeGroups = std::vector<Name>(),
461  const bool inCoreOnly = false)
462  : mAttribute(attribute)
463  , mPointOffsets(pointOffsets)
464  , mStartOffset(startOffset)
465  , mTransform(transform)
466  , mIndex(index)
467  , mIncludeGroups(includeGroups)
468  , mExcludeGroups(excludeGroups)
469  , mInCoreOnly(inCoreOnly)
470  {
471  // only accept Vec3f as ValueType
472  static_assert(VecTraits<ValueType>::Size == 3 &&
474  "ValueType is not Vec3f");
475  }
476 
477  void operator()(const LeafRangeT& range) const {
478 
479  const bool useGroups = !mIncludeGroups.empty() || !mExcludeGroups.empty();
480 
481  typename Attribute::Handle pHandle(mAttribute);
482 
483  for (auto leaf = range.begin(); leaf; ++leaf) {
484 
485  assert(leaf.pos() < mPointOffsets.size());
486 
487  if (mInCoreOnly && leaf->buffer().isOutOfCore()) continue;
488 
490 
491  if (leaf.pos() > 0) offset += mPointOffsets[leaf.pos() - 1];
492 
493  auto handle = AttributeHandle<ValueType>::create(leaf->constAttributeArray(mIndex));
494 
495  if (useGroups) {
496  auto iter = leaf->beginIndexOn(MultiGroupFilter(mIncludeGroups, mExcludeGroups));
497 
498  for (; iter; ++iter) {
499  const Vec3d xyz = iter.getCoord().asVec3d();
500  const Vec3d pos = handle->get(*iter);
501  pHandle.set(static_cast<Index>(offset++), /*stride=*/0,
502  mTransform.indexToWorld(pos + xyz));
503  }
504  }
505  else {
506  auto iter = leaf->beginIndexOn();
507 
508  for (; iter; ++iter) {
509  const Vec3d xyz = iter.getCoord().asVec3d();
510  const Vec3d pos = handle->get(*iter);
511  pHandle.set(static_cast<Index>(offset++), /*stride=*/0,
512  mTransform.indexToWorld(pos + xyz));
513  }
514  }
515  }
516  }
517 
518  //////////
519 
521  const std::vector<Index64>& mPointOffsets;
524  const size_t mIndex;
525  const std::vector<std::string>& mIncludeGroups;
526  const std::vector<std::string>& mExcludeGroups;
527  const bool mInCoreOnly;
528 }; // ConvertPointDataGridPositionOp
529 
530 
531 template<typename PointDataTreeType, typename Attribute>
533 
534  using LeafNode = typename PointDataTreeType::LeafNodeType;
535  using ValueType = typename Attribute::ValueType;
538  using LeafRangeT = typename LeafManagerT::LeafRange;
539 
541  const std::vector<Index64>& pointOffsets,
542  const Index64 startOffset,
543  const size_t index,
544  const Index stride = 1,
545  const std::vector<Name>& includeGroups = std::vector<Name>(),
546  const std::vector<Name>& excludeGroups = std::vector<Name>(),
547  const bool inCoreOnly = false)
548  : mAttribute(attribute)
549  , mPointOffsets(pointOffsets)
550  , mStartOffset(startOffset)
551  , mIndex(index)
552  , mStride(stride)
553  , mIncludeGroups(includeGroups)
554  , mExcludeGroups(excludeGroups)
555  , mInCoreOnly(inCoreOnly) { }
556 
557  void operator()(const LeafRangeT& range) const {
558 
559  const bool useGroups = !mIncludeGroups.empty() || !mExcludeGroups.empty();
560 
561  typename Attribute::Handle pHandle(mAttribute);
562 
563  for (auto leaf = range.begin(); leaf; ++leaf) {
564 
565  assert(leaf.pos() < mPointOffsets.size());
566 
567  if (mInCoreOnly && leaf->buffer().isOutOfCore()) continue;
568 
570 
571  if (leaf.pos() > 0) offset += mPointOffsets[leaf.pos() - 1];
572 
573  typename HandleT::Ptr handle = ConversionTraits<ValueType>::handleFromLeaf(
574  *leaf, static_cast<Index>(mIndex));
575 
576  const bool uniform = handle->isUniform();
577 
579  if (uniform) uniformValue = ValueType(handle->get(0));
580 
581  if (useGroups) {
582  auto iter = leaf->beginIndexOn(MultiGroupFilter(mIncludeGroups, mExcludeGroups));
583 
584  if (uniform) {
585  for (; iter; ++iter) {
586  for (Index i = 0; i < mStride; i++) {
587  pHandle.set(static_cast<Index>(offset), i, uniformValue);
588  }
589  offset++;
590  }
591  }
592  else {
593  for (; iter; ++iter) {
594  for (Index i = 0; i < mStride; i++) {
595  pHandle.set(static_cast<Index>(offset), i, handle->get(*iter));
596  }
597  offset++;
598  }
599  }
600  }
601  else {
602  auto iter = leaf->beginIndexOn();
603 
604  if (uniform) {
605  for (; iter; ++iter) {
606  for (Index i = 0; i < mStride; i++) {
607  pHandle.set(static_cast<Index>(offset), i, uniformValue);
608  }
609  offset++;
610  }
611  }
612  else {
613  for (; iter; ++iter) {
614  for (Index i = 0; i < mStride; i++) {
615  pHandle.set(static_cast<Index>(offset), i,
616  handle->get(*iter, /*stride=*/i));
617  }
618  offset++;
619  }
620  }
621  }
622  }
623  }
624 
625  //////////
626 
628  const std::vector<Index64>& mPointOffsets;
630  const size_t mIndex;
631  const Index mStride;
632  const std::vector<std::string>& mIncludeGroups;
633  const std::vector<std::string>& mExcludeGroups;
634  const bool mInCoreOnly;
635 }; // ConvertPointDataGridAttributeOp
636 
637 template<typename PointDataTreeType, typename Group>
639 
640  using LeafNode = typename PointDataTreeType::LeafNodeType;
641  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
643  using LeafRangeT = typename LeafManagerT::LeafRange;
644 
646  const std::vector<Index64>& pointOffsets,
647  const Index64 startOffset,
648  const AttributeSet::Descriptor::GroupIndex index,
649  const std::vector<Name>& includeGroups = std::vector<Name>(),
650  const std::vector<Name>& excludeGroups = std::vector<Name>(),
651  const bool inCoreOnly = false)
652  : mGroup(group)
653  , mPointOffsets(pointOffsets)
654  , mStartOffset(startOffset)
655  , mIndex(index)
656  , mIncludeGroups(includeGroups)
657  , mExcludeGroups(excludeGroups)
658  , mInCoreOnly(inCoreOnly) { }
659 
660  void operator()(const LeafRangeT& range) const {
661 
662  const bool useGroups = !mIncludeGroups.empty() || !mExcludeGroups.empty();
663 
664  for (auto leaf = range.begin(); leaf; ++leaf) {
665 
666  assert(leaf.pos() < mPointOffsets.size());
667 
668  if (mInCoreOnly && leaf->buffer().isOutOfCore()) continue;
669 
671 
672  if (leaf.pos() > 0) offset += mPointOffsets[leaf.pos() - 1];
673 
674  const AttributeArray& array = leaf->constAttributeArray(mIndex.first);
675  const auto bitmask = static_cast<GroupType>(1 << mIndex.second);
676 
677  assert(isGroup(array));
678 
679  const GroupAttributeArray& groupArray = GroupAttributeArray::cast(array);
680 
681  const bool uniform = groupArray.isUniform();
682 
683  if (uniform) {
684  if (!(groupArray.get(0) & bitmask)) continue;
685  }
686 
687  if (useGroups) {
688  auto iter = leaf->beginIndexOn(MultiGroupFilter(mIncludeGroups, mExcludeGroups));
689 
690  if (uniform) {
691  for (; iter; ++iter) {
692  mGroup.setOffsetOn(static_cast<Index>(offset));
693  offset++;
694  }
695  }
696  else {
697  for (; iter; ++iter) {
698  if (groupArray.get(*iter) & bitmask) {
699  mGroup.setOffsetOn(static_cast<Index>(offset));
700  }
701  offset++;
702  }
703  }
704  }
705  else {
706  auto iter = leaf->beginIndexOn();
707 
708  if (uniform) {
709  for (; iter; ++iter) {
710  mGroup.setOffsetOn(static_cast<Index>(offset));
711  offset++;
712  }
713  }
714  else {
715  for (; iter; ++iter) {
716  if (groupArray.get(*iter) & bitmask) {
717  mGroup.setOffsetOn(static_cast<Index>(offset));
718  }
719  offset++;
720  }
721  }
722  }
723  }
724  }
725 
726  //////////
727 
728  Group& mGroup;
729  const std::vector<Index64>& mPointOffsets;
732  const std::vector<std::string>& mIncludeGroups;
733  const std::vector<std::string>& mExcludeGroups;
734  const bool mInCoreOnly;
735 }; // ConvertPointDataGridGroupOp
736 
737 template<typename PositionArrayT>
739 {
740  CalculatePositionBounds(const PositionArrayT& positions,
741  const math::Mat4d& inverse)
742  : mPositions(positions)
743  , mInverseMat(inverse)
744  , mMin(std::numeric_limits<Real>::max())
745  , mMax(-std::numeric_limits<Real>::max()) {}
746 
748  : mPositions(other.mPositions)
749  , mInverseMat(other.mInverseMat)
750  , mMin(std::numeric_limits<Real>::max())
751  , mMax(-std::numeric_limits<Real>::max()) {}
752 
753  void operator()(const tbb::blocked_range<size_t>& range) {
754  Vec3R pos;
755  for (size_t n = range.begin(), N = range.end(); n != N; ++n) {
756  mPositions.getPos(n, pos);
757  pos = mInverseMat.transform(pos);
758  mMin = math::minComponent(mMin, pos);
759  mMax = math::maxComponent(mMax, pos);
760  }
761  }
762 
763  void join(const CalculatePositionBounds& other) {
764  mMin = math::minComponent(mMin, other.mMin);
765  mMax = math::maxComponent(mMax, other.mMax);
766  }
767 
769  return BBoxd(mMin, mMax);
770  }
771 
772 private:
773  const PositionArrayT& mPositions;
774  const math::Mat4d& mInverseMat;
775  Vec3R mMin, mMax;
776 };
777 
778 } // namespace point_conversion_internal
779 
780 
781 ////////////////////////////////////////
782 
783 
784 template<typename CompressionT, typename PointDataGridT, typename PositionArrayT, typename PointIndexGridT>
785 inline typename PointDataGridT::Ptr
786 createPointDataGrid(const PointIndexGridT& pointIndexGrid, const PositionArrayT& positions,
787  const math::Transform& xform, Metadata::Ptr positionDefaultValue)
788 {
789  using PointDataTreeT = typename PointDataGridT::TreeType;
790  using PointIndexTreeT = typename PointIndexGridT::TreeType;
791  using LeafManagerT = typename tree::LeafManager<PointDataTreeT>;
792  using LeafRangeT = typename LeafManagerT::LeafRange;
793  using PositionAttributeT = TypedAttributeArray<Vec3f, CompressionT>;
794 
797 
798  const NamePair positionType = PositionAttributeT::attributeType();
799 
800  // construct the Tree using a topology copy of the PointIndexGrid
801 
802  const PointIndexTreeT& pointIndexTree(pointIndexGrid.tree());
803  typename PointDataTreeT::Ptr treePtr(new PointDataTreeT(pointIndexTree));
804 
805  LeafManagerT leafManager = LeafManagerT(*treePtr);
806  LeafRangeT leafRange = leafManager.leafRange();
807 
808  // create attribute descriptor from position type
809 
810  auto descriptor = AttributeSet::Descriptor::create(positionType);
811 
812  // add default value for position if provided
813 
814  if (positionDefaultValue) descriptor->setDefaultValue("P", *positionDefaultValue);
815 
816  // create point attribute storage on each leaf
817 
818  InitialiseAttributesOp<PointDataTreeT, PointIndexTreeT> initialise(
819  pointIndexGrid.tree(), descriptor);
820  tbb::parallel_for(leafRange, initialise);
821 
822  // populate position attribute
823 
824  PopulatePositionAttributeOp<PointDataTreeT,
825  PointIndexTreeT,
826  PositionArrayT> populate(pointIndexTree,
827  xform,
828  positions);
829 
830  tbb::parallel_for(leafRange, populate);
831 
832  auto grid = PointDataGridT::create(treePtr);
833  grid->setTransform(xform.copy());
834  return grid;
835 }
836 
837 
838 ////////////////////////////////////////
839 
840 
841 template <typename CompressionT, typename PointDataGridT, typename ValueT>
842 inline typename PointDataGridT::Ptr
843 createPointDataGrid(const std::vector<ValueT>& positions,
844  const math::Transform& xform,
845  Metadata::Ptr positionDefaultValue)
846 {
847  const PointAttributeVector<ValueT> pointList(positions);
848 
849  tools::PointIndexGrid::Ptr pointIndexGrid = tools::createPointIndexGrid<tools::PointIndexGrid>(pointList, xform);
850  return createPointDataGrid<CompressionT, PointDataGridT>(*pointIndexGrid, pointList, xform, positionDefaultValue);
851 }
852 
853 
854 ////////////////////////////////////////
855 
856 
857 template <typename PointDataTreeT, typename PointIndexTreeT, typename PointArrayT>
858 inline void
859 populateAttribute(PointDataTreeT& tree, const PointIndexTreeT& pointIndexTree,
860  const openvdb::Name& attributeName, const PointArrayT& data, const Index stride,
861  const bool insertMetadata)
862 {
864  using ValueType = typename PointArrayT::value_type;
865 
866  auto iter = tree.cbeginLeaf();
867 
868  if (!iter) return;
869 
870  const size_t index = iter->attributeSet().find(attributeName);
871 
872  if (index == AttributeSet::INVALID_POS) {
873  OPENVDB_THROW(KeyError, "Attribute not found to populate - " << attributeName << ".");
874  }
875 
876  if (insertMetadata) {
878  }
879 
880  // populate attribute
881 
882  typename tree::LeafManager<PointDataTreeT> leafManager(tree);
883 
884  PopulateAttributeOp<PointDataTreeT,
885  PointIndexTreeT,
886  PointArrayT> populate(pointIndexTree, data, index, stride);
887  tbb::parallel_for(leafManager.leafRange(), populate);
888 }
889 
890 
891 ////////////////////////////////////////
892 
893 
894 template <typename PositionAttribute, typename PointDataGridT>
895 inline void
896 convertPointDataGridPosition( PositionAttribute& positionAttribute,
897  const PointDataGridT& grid,
898  const std::vector<Index64>& pointOffsets,
899  const Index64 startOffset,
900  const std::vector<Name>& includeGroups,
901  const std::vector<Name>& excludeGroups,
902  const bool inCoreOnly)
903 {
904  using TreeType = typename PointDataGridT::TreeType;
905  using LeafManagerT = typename tree::LeafManager<const TreeType>;
906 
908 
909  const TreeType& tree = grid.tree();
910  auto iter = tree.cbeginLeaf();
911 
912  if (!iter) return;
913 
914  // for efficiency, keep only groups that are present in the Descriptor
915 
916  const AttributeSet::Descriptor& descriptor = iter->attributeSet().descriptor();
917 
918  std::vector<Name> newIncludeGroups(includeGroups);
919  std::vector<Name> newExcludeGroups(excludeGroups);
920 
921  deleteMissingPointGroups(newIncludeGroups, descriptor);
922  deleteMissingPointGroups(newExcludeGroups, descriptor);
923 
924  LeafManagerT leafManager(tree);
925 
926  const size_t positionIndex = iter->attributeSet().find("P");
927 
928  positionAttribute.expand();
929  ConvertPointDataGridPositionOp<TreeType, PositionAttribute> convert(
930  positionAttribute, pointOffsets, startOffset, grid.transform(), positionIndex,
931  newIncludeGroups, newExcludeGroups, inCoreOnly);
932  tbb::parallel_for(leafManager.leafRange(), convert);
933  positionAttribute.compact();
934 }
935 
936 
937 ////////////////////////////////////////
938 
939 
940 template <typename TypedAttribute, typename PointDataTreeT>
941 inline void
943  const PointDataTreeT& tree,
944  const std::vector<Index64>& pointOffsets,
945  const Index64 startOffset,
946  const unsigned arrayIndex,
947  const Index stride,
948  const std::vector<Name>& includeGroups,
949  const std::vector<Name>& excludeGroups,
950  const bool inCoreOnly)
951 {
952  using LeafManagerT = typename tree::LeafManager<const PointDataTreeT>;
953 
955 
956  auto iter = tree.cbeginLeaf();
957 
958  if (!iter) return;
959 
960  // for efficiency, keep only groups that are present in the Descriptor
961 
962  const AttributeSet::Descriptor& descriptor = iter->attributeSet().descriptor();
963 
964  std::vector<Name> newIncludeGroups(includeGroups);
965  std::vector<Name> newExcludeGroups(excludeGroups);
966 
967  deleteMissingPointGroups(newIncludeGroups, descriptor);
968  deleteMissingPointGroups(newExcludeGroups, descriptor);
969 
970  LeafManagerT leafManager(tree);
971 
972  attribute.expand();
973  ConvertPointDataGridAttributeOp<PointDataTreeT, TypedAttribute> convert(
974  attribute, pointOffsets, startOffset, arrayIndex, stride,
975  newIncludeGroups, newExcludeGroups, inCoreOnly);
976  tbb::parallel_for(leafManager.leafRange(), convert);
977  attribute.compact();
978 }
979 
980 
981 ////////////////////////////////////////
982 
983 
984 template <typename Group, typename PointDataTreeT>
985 inline void
987  const PointDataTreeT& tree,
988  const std::vector<Index64>& pointOffsets,
989  const Index64 startOffset,
990  const AttributeSet::Descriptor::GroupIndex index,
991  const std::vector<Name>& includeGroups,
992  const std::vector<Name>& excludeGroups,
993  const bool inCoreOnly)
994 {
995  using LeafManagerT= typename tree::LeafManager<const PointDataTreeT>;
996 
998 
999  auto iter = tree.cbeginLeaf();
1000 
1001  if (!iter) return;
1002 
1003  // for efficiency, keep only groups that are present in the Descriptor
1004 
1005  const AttributeSet::Descriptor& descriptor = iter->attributeSet().descriptor();
1006 
1007  std::vector<Name> newIncludeGroups(includeGroups);
1008  std::vector<Name> newExcludeGroups(excludeGroups);
1009 
1010  deleteMissingPointGroups(newIncludeGroups, descriptor);
1011  deleteMissingPointGroups(newExcludeGroups, descriptor);
1012 
1013  LeafManagerT leafManager(tree);
1014 
1015  ConvertPointDataGridGroupOp<PointDataTree, Group> convert(
1016  group, pointOffsets, startOffset, index,
1017  newIncludeGroups, newExcludeGroups, inCoreOnly);
1018  tbb::parallel_for(leafManager.leafRange(), convert);
1019 
1020  // must call this after modifying point groups in parallel
1021 
1022  group.finalize();
1023 }
1024 
1025 template<typename PositionWrapper, typename InterrupterT>
1026 inline float
1027 computeVoxelSize( const PositionWrapper& positions,
1028  const uint32_t pointsPerVoxel,
1029  const math::Mat4d transform,
1030  const Index decimalPlaces,
1031  InterrupterT* const interrupter)
1032 {
1033  using namespace point_conversion_internal;
1034 
1035  struct Local {
1036 
1037  static bool voxelSizeFromVolume(const double volume,
1038  const size_t estimatedVoxelCount,
1039  float& voxelSize)
1040  {
1041  // dictated by the math::ScaleMap limit
1042  static const double minimumVoxelVolume(3e-15);
1043  static const double maximumVoxelVolume(std::numeric_limits<float>::max());
1044 
1045  double voxelVolume = volume / static_cast<double>(estimatedVoxelCount);
1046  bool valid = true;
1047 
1048  if (voxelVolume < minimumVoxelVolume) {
1049  voxelVolume = minimumVoxelVolume;
1050  valid = false;
1051  }
1052  else if (voxelVolume > maximumVoxelVolume) {
1053  voxelVolume = maximumVoxelVolume;
1054  valid = false;
1055  }
1056 
1057  voxelSize = static_cast<float>(math::Pow(voxelVolume, 1.0/3.0));
1058  return valid;
1059  }
1060 
1061  static float truncate(const float voxelSize, Index decPlaces)
1062  {
1063  float truncatedVoxelSize = voxelSize;
1064 
1065  // attempt to truncate from decPlaces -> 11
1066  for (int i = decPlaces; i < 11; i++) {
1067  truncatedVoxelSize = static_cast<float>(math::Truncate(double(voxelSize), i));
1068  if (truncatedVoxelSize != 0.0f) break;
1069  }
1070 
1071  return truncatedVoxelSize;
1072  }
1073  };
1074 
1075  if (pointsPerVoxel == 0) OPENVDB_THROW(ValueError, "Points per voxel cannot be zero.");
1076 
1077  // constructed with the default voxel size as specified by openvdb interface values
1078 
1079  float voxelSize(0.1f);
1080 
1081  const size_t numPoints = positions.size();
1082 
1083  // return the default voxel size if we have zero or only 1 point
1084 
1085  if (numPoints <= 1) return voxelSize;
1086 
1087  size_t targetVoxelCount(numPoints / size_t(pointsPerVoxel));
1088  if (targetVoxelCount == 0) targetVoxelCount++;
1089 
1090  // calculate the world space, transform-oriented bounding box
1091 
1092  math::Mat4d inverseTransform = transform.inverse();
1093  inverseTransform = math::unit(inverseTransform);
1094 
1095  tbb::blocked_range<size_t> range(0, numPoints);
1096  CalculatePositionBounds<PositionWrapper> calculateBounds(positions, inverseTransform);
1097  tbb::parallel_reduce(range, calculateBounds);
1098 
1099  BBoxd bbox = calculateBounds.getBoundingBox();
1100 
1101  // return default size if points are coincident
1102 
1103  if (bbox.min() == bbox.max()) return voxelSize;
1104 
1105  double volume = bbox.volume();
1106 
1107  // handle points that are collinear or coplanar by expanding the volume
1108 
1109  if (math::isApproxZero(volume)) {
1110  Vec3d extents = bbox.extents().sorted().reversed();
1111  if (math::isApproxZero(extents[1])) {
1112  // colinear (maxExtent^3)
1113  volume = extents[0]*extents[0]*extents[0];
1114  }
1115  else {
1116  // coplanar (maxExtent*nextMaxExtent^2)
1117  volume = extents[0]*extents[1]*extents[1];
1118  }
1119  }
1120 
1121  double previousVolume = volume;
1122 
1123  if (!Local::voxelSizeFromVolume(volume, targetVoxelCount, voxelSize)) {
1124  OPENVDB_LOG_DEBUG("Out of range, clamping voxel size.");
1125  return voxelSize;
1126  }
1127 
1128  size_t previousVoxelCount(0);
1129  size_t voxelCount(1);
1130 
1131  if (interrupter) interrupter->start("Computing voxel size");
1132 
1133  while (voxelCount > previousVoxelCount)
1134  {
1135  math::Transform::Ptr newTransform;
1136 
1137  if (!math::isIdentity(transform))
1138  {
1139  // if using a custom transform, pre-scale by coefficients
1140  // which define the new voxel size
1141 
1142  math::Mat4d matrix(transform);
1143  matrix.preScale(Vec3d(voxelSize) / math::getScale(matrix));
1144  newTransform = math::Transform::createLinearTransform(matrix);
1145  }
1146  else
1147  {
1148  newTransform = math::Transform::createLinearTransform(voxelSize);
1149  }
1150 
1151  // create a mask grid of the points from the calculated voxel size
1152  // this is the same function call as tools::createPointMask() which has
1153  // been duplicated to provide an interrupter
1154 
1155  MaskGrid::Ptr mask = createGrid<MaskGrid>(false);
1156  mask->setTransform(newTransform);
1157  tools::PointsToMask<MaskGrid, InterrupterT> pointMaskOp(*mask, interrupter);
1158  pointMaskOp.addPoints(positions);
1159 
1160  if (interrupter && util::wasInterrupted(interrupter)) break;
1161 
1162  previousVoxelCount = voxelCount;
1163  voxelCount = mask->activeVoxelCount();
1164  volume = math::Pow3(voxelSize) * voxelCount;
1165 
1166  // stop if no change in the volume or the volume has increased
1167 
1168  if (volume >= previousVolume) break;
1169  previousVolume = volume;
1170 
1171  const float previousVoxelSize = voxelSize;
1172 
1173  // compute the new voxel size and if invalid return the previous value
1174 
1175  if (!Local::voxelSizeFromVolume(volume, targetVoxelCount, voxelSize)) {
1176  voxelSize = previousVoxelSize;
1177  break;
1178  }
1179 
1180  // halt convergence if the voxel size has decreased by less
1181  // than 10% in this iteration
1182 
1183  if (voxelSize / previousVoxelSize > 0.9f) break;
1184  }
1185 
1186  if (interrupter) interrupter->end();
1187 
1188  // truncate the voxel size for readability and return the value
1189 
1190  return Local::truncate(voxelSize, decimalPlaces);
1191 }
1192 
1193 
1194 } // namespace points
1195 } // namespace OPENVDB_VERSION_NAME
1196 } // namespace openvdb
1197 
1198 #endif // OPENVDB_POINTS_POINT_CONVERSION_HAS_BEEN_INCLUDED
1199 
1200 // Copyright (c) 2012-2017 DreamWorks Animation LLC
1201 // All rights reserved. This software is distributed under the
1202 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
bool isUniform() const override
Return true if this array is stored as a single uniform value.
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:553
Definition: ImfName.h:53
This tool produces a grid where every voxel that contains a point is active. It employes thread-local...
Type Truncate(Type x, unsigned int digits)
Return x truncated to the given number of decimal digits.
Definition: Math.h:836
GLsizei GLenum const void * indices
Definition: glcorearb.h:405
void operator()(const typename LeafManagerT::LeafRange &range) const
void operator()(const typename LeafManagerT::LeafRange &range) const
GLenum GLint * range
Definition: glcorearb.h:1924
PointDataGridT::Ptr createPointDataGrid(const PointIndexGridT &pointIndexGrid, const PositionArrayT &positions, const math::Transform &xform, Metadata::Ptr positionDefaultValue=Metadata::Ptr())
Localises points with position into a PointDataGrid into two stages: allocation of the leaf attribute...
Vec3d indexToWorld(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:135
Type Pow(Type x, int n)
Return .
Definition: Math.h:527
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:391
void convertPointDataGridPosition(PositionAttribute &positionAttribute, const PointDataGridT &grid, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const std::vector< Name > &includeGroups=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >(), const bool inCoreOnly=false)
Convert the position attribute from a Point Data Grid.
static TypedAttributeArray & cast(AttributeArray &attributeArray)
Cast an AttributeArray to TypedAttributeArray<T>
ValueType get(Index n) const
Return the value at index n.
bool isIdentity(const MatType &m)
Determine if a matrix is an identity matrix.
Definition: Mat.h:855
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=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >(), const bool inCoreOnly=false)
Convert the group from a PointDataGrid.
GLint GLuint mask
Definition: glcorearb.h:123
Point group manipulation in a VDB Point Grid.
Index filters primarily designed to be used with a FilterIndexIter.
#define OPENVDB_LOG_DEBUG(mesg)
Definition: logging.h:302
Makes every voxel of a grid active if it contains a point.
Definition: PointsToMask.h:93
MatType unit(const MatType &mat, typename MatType::value_type eps=1.0e-8)
Return a copy of the given matrix with its upper 3x3 rows normalized.
Definition: Mat.h:643
png_uint_32 i
Definition: png.h:2877
uint64 value_type
Definition: GA_PrimCompat.h:29
static Ptr create(AttributeArray &array, const bool expand=true)
Index64 pointCount(const PointDataTreeT &tree, const bool inCoreOnly=false)
Total points in the PointDataTree.
Definition: PointCount.h:198
bool isGroup(const AttributeArray &array)
CalculatePositionBounds(const PositionArrayT &positions, const math::Mat4d &inverse)
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
float computeVoxelSize(const PositionWrapper &positions, const uint32_t pointsPerVoxel, const math::Mat4d transform=math::Mat4d::identity(), const Index decimalPlaces=5, InterrupterT *const interrupter=nullptr)
SYS_FORCE_INLINE const_iterator end() const
static Ptr create(const AttributeArray &array, const bool preserveCompression=true)
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.
void deleteMissingPointGroups(std::vector< std::string > &groups, const AttributeSet::Descriptor &descriptor)
Delete any group that is not present in the Descriptor.
Definition: PointGroup.h:434
GLdouble n
Definition: glcorearb.h:2007
GLfloat f
Definition: glcorearb.h:1925
Base class for storing attribute data.
Vec3< T > reversed() const
Return the vector (z, y, x)
Definition: Vec3.h:489
Calculate an axis-aligned bounding box in index space from a bounding sphere in world space...
Definition: Transform.h:66
void preScale(const Vec3< T0 > &v)
Definition: Mat4.h:790
#define OPENVDB_VERSION_NAME
Definition: version.h:43
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:785
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:871
Attribute array storage for string data using Descriptor Metadata.
PopulatePositionAttributeOp(const PointIndexTreeType &pointIndexTree, const math::Transform &transform, const PositionListType &positions)
GLintptr offset
Definition: glcorearb.h:664
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...
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:115
Type Pow3(Type x)
Return .
Definition: Math.h:518
Vec3< T > sorted() const
Return a vector with the components of this in ascending order.
Definition: Vec3.h:479
ConvertPointDataGridAttributeOp(Attribute &attribute, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const size_t index, const Index stride=1, const std::vector< Name > &includeGroups=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >(), const bool inCoreOnly=false)
GLboolean * data
Definition: glcorearb.h:130
std::pair< Name, Name > NamePair
bool isApproxZero(const Type &x)
Return true if x is equal to zero to within the default floating-point comparison tolerance...
Definition: Math.h:336
GA_API const UT_StringHolder transform
Point attribute manipulation in a VDB Point Grid.
ConvertPointDataGridPositionOp(Attribute &attribute, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const math::Transform &transform, const size_t index, const std::vector< Name > &includeGroups=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >(), const bool inCoreOnly=false)
GLsizei const GLfloat * value
Definition: glcorearb.h:823
Typed class for storing attribute data.
Set of Attribute Arrays which tracks metadata about each array.
ElementType volume() const
Return the volume spanned by this BBox.
Definition: BBox.h:126
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
GLuint index
Definition: glcorearb.h:785
ConvertPointDataGridGroupOp(Group &group, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const AttributeSet::Descriptor::GroupIndex index, const std::vector< Name > &includeGroups=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >(), const bool inCoreOnly=false)
Vec4< T0 > transform(const Vec4< T0 > &v) const
Transform a Vec4 by post-multiplication.
Definition: Mat4.h:1052
math::BBox< Vec3d > BBoxd
Definition: Types.h:87
Vec2< T > maxComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise maximum of the two vectors.
Definition: Vec2.h:562
Vec3< typename MatType::value_type > getScale(const MatType &mat)
Return a Vec3 representing the lengths of the passed matrix's upper 3x3's rows.
Definition: Mat.h:628
static const Mat4< double > & identity()
Predefined constant for identity matrix.
Definition: Mat4.h:152
GA_API const UT_StringHolder N
Point-partitioner compatible STL vector attribute wrapper for convenience.
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
static Transform::Ptr createLinearTransform(double voxelSize=1.0)
Create and return a shared pointer to a new transform.
InitialiseAttributesOp(const PointIndexTreeType &pointIndexTree, const AttributeSet::Descriptor::Ptr &attributeDescriptor)
Vec3d worldToIndex(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:137
bool wasInterrupted(T *i, int percent=-1)
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Mat4 inverse(T tolerance=0) const
Definition: Mat4.h:539
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
PopulateAttributeOp(const PointIndexTreeType &pointIndexTree, const AttributeListType &data, const size_t index, const Index stride=1)
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:149
PointAttributeVector(const std::vector< value_type > &data, const Index stride=1)
void convertPointDataGridAttribute(TypedAttribute &attribute, const PointDataTreeT &tree, const std::vector< Index64 > &pointOffsets, const Index64 startOffset, const unsigned arrayIndex, const Index stride=1, const std::vector< Name > &includeGroups=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >(), const bool inCoreOnly=false)
Convert the attribute from a PointDataGrid.
math::Vec3< float > Vec3f
Definition: Types.h:77