OpenVDB  6.2.0
PointGroup.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_GROUP_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/openvdb.h>
41 
42 #include "IndexIterator.h" // FilterTraits
43 #include "IndexFilter.h" // FilterTraits
44 #include "AttributeSet.h"
45 #include "PointDataGrid.h"
46 #include "PointAttribute.h"
47 #include "PointCount.h"
48 
49 #include <tbb/parallel_reduce.h>
50 
51 #include <algorithm>
52 #include <random>
53 #include <string>
54 #include <vector>
55 
56 namespace openvdb {
58 namespace OPENVDB_VERSION_NAME {
59 namespace points {
60 
65 inline void deleteMissingPointGroups( std::vector<std::string>& groups,
66  const AttributeSet::Descriptor& descriptor);
67 
72 template <typename PointDataTree>
73 inline void appendGroup(PointDataTree& tree,
74  const Name& group);
75 
80 template <typename PointDataTree>
81 inline void appendGroups(PointDataTree& tree,
82  const std::vector<Name>& groups);
83 
90 template <typename PointDataTree>
91 inline void dropGroup( PointDataTree& tree,
92  const Name& group,
93  const bool compact = true);
94 
99 template <typename PointDataTree>
100 inline void dropGroups( PointDataTree& tree,
101  const std::vector<Name>& groups);
102 
106 template <typename PointDataTree>
107 inline void dropGroups( PointDataTree& tree);
108 
112 template <typename PointDataTree>
113 inline void compactGroups(PointDataTree& tree);
114 
124 template <typename PointDataTree, typename PointIndexTree>
125 inline void setGroup( PointDataTree& tree,
126  const PointIndexTree& indexTree,
127  const std::vector<short>& membership,
128  const Name& group,
129  const bool remove = false);
130 
136 template <typename PointDataTree>
137 inline void setGroup( PointDataTree& tree,
138  const Name& group,
139  const bool member = true);
140 
146 template <typename PointDataTree, typename FilterT>
147 inline void setGroupByFilter( PointDataTree& tree,
148  const Name& group,
149  const FilterT& filter);
150 
151 
153 
154 
155 namespace point_group_internal {
156 
157 
159 template<typename PointDataTreeType>
160 struct CopyGroupOp {
161 
163  using LeafRangeT = typename LeafManagerT::LeafRange;
164  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
165 
166  CopyGroupOp(const GroupIndex& targetIndex,
167  const GroupIndex& sourceIndex)
168  : mTargetIndex(targetIndex)
169  , mSourceIndex(sourceIndex) { }
170 
171  void operator()(const typename LeafManagerT::LeafRange& range) const {
172 
173  for (auto leaf = range.begin(); leaf; ++leaf) {
174 
175  GroupHandle sourceGroup = leaf->groupHandle(mSourceIndex);
176  GroupWriteHandle targetGroup = leaf->groupWriteHandle(mTargetIndex);
177 
178  for (auto iter = leaf->beginIndexAll(); iter; ++iter) {
179  const bool groupOn = sourceGroup.get(*iter);
180  targetGroup.set(*iter, groupOn);
181  }
182  }
183  }
184 
186 
189 };
190 
191 
193 template <typename PointDataTree, bool Member>
195 {
197  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
198 
199  SetGroupOp(const AttributeSet::Descriptor::GroupIndex& index)
200  : mIndex(index) { }
201 
202  void operator()(const typename LeafManagerT::LeafRange& range) const
203  {
204  for (auto leaf = range.begin(); leaf; ++leaf) {
205 
206  // obtain the group attribute array
207 
208  GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
209 
210  // set the group value
211 
212  group.collapse(Member);
213  }
214  }
215 
217 
219 }; // struct SetGroupOp
220 
221 
222 template <typename PointDataTree, typename PointIndexTree, bool Remove>
224 {
226  using LeafRangeT = typename LeafManagerT::LeafRange;
227  using PointIndexLeafNode = typename PointIndexTree::LeafNodeType;
229  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
230  using MembershipArray = std::vector<short>;
231 
233  const MembershipArray& membership,
234  const GroupIndex& index)
235  : mIndexTree(indexTree)
236  , mMembership(membership)
237  , mIndex(index) { }
238 
239  void operator()(const typename LeafManagerT::LeafRange& range) const
240  {
241  for (auto leaf = range.begin(); leaf; ++leaf) {
242 
243  // obtain the PointIndexLeafNode (using the origin of the current leaf)
244 
245  const PointIndexLeafNode* pointIndexLeaf = mIndexTree.probeConstLeaf(leaf->origin());
246 
247  if (!pointIndexLeaf) continue;
248 
249  // obtain the group attribute array
250 
251  GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
252 
253  // initialise the attribute storage
254 
255  Index64 index = 0;
256 
257  const IndexArray& indices = pointIndexLeaf->indices();
258 
259  for (const Index64 i: indices) {
260  if (Remove) {
261  group.set(static_cast<Index>(index), mMembership[i]);
262  } else if (mMembership[i] == short(1)) {
263  group.set(static_cast<Index>(index), short(1));
264  }
265  index++;
266  }
267 
268  // attempt to compact the array
269 
270  group.compact();
271  }
272  }
273 
275 
279 }; // struct SetGroupFromIndexOp
280 
281 
282 template <typename PointDataTree, typename FilterT, typename IterT = typename PointDataTree::LeafNodeType::ValueAllCIter>
284 {
286  using LeafRangeT = typename LeafManagerT::LeafRange;
288  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
289 
290  SetGroupByFilterOp( const GroupIndex& index, const FilterT& filter)
291  : mIndex(index)
292  , mFilter(filter) { }
293 
294  void operator()(const typename LeafManagerT::LeafRange& range) const
295  {
296  for (auto leaf = range.begin(); leaf; ++leaf) {
297 
298  // obtain the group attribute array
299 
300  GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
301 
302  auto iter = leaf->template beginIndex<IterT, FilterT>(mFilter);
303 
304  for (; iter; ++iter) {
305  group.set(*iter, true);
306  }
307 
308  // attempt to compact the array
309 
310  group.compact();
311  }
312  }
313 
315 
317  const FilterT& mFilter; // beginIndex takes a copy of mFilter
318 }; // struct SetGroupByFilterOp
319 
320 
322 
323 
326 {
327 public:
328  using Descriptor = AttributeSet::Descriptor;
329 
330  GroupInfo(const AttributeSet& attributeSet)
331  : mAttributeSet(attributeSet) { }
332 
334  static size_t groupBits() { return sizeof(GroupType) * CHAR_BIT; }
335 
338  size_t unusedGroups() const
339  {
340  const Descriptor& descriptor = mAttributeSet.descriptor();
341 
342  // compute total slots (one slot per bit of the group attributes)
343 
344  const size_t groupAttributes = descriptor.count(GroupAttributeArray::attributeType());
345 
346  if (groupAttributes == 0) return 0;
347 
348  const size_t totalSlots = groupAttributes * this->groupBits();
349 
350  // compute slots in use
351 
352  const AttributeSet::Descriptor::NameToPosMap& groupMap = mAttributeSet.descriptor().groupMap();
353  const size_t usedSlots = groupMap.size();
354 
355  return totalSlots - usedSlots;
356  }
357 
359  bool canCompactGroups() const
360  {
361  // can compact if more unused groups than in one group attribute array
362 
363  return this->unusedGroups() >= this->groupBits();
364  }
365 
367  size_t nextUnusedOffset() const
368  {
369  const Descriptor::NameToPosMap& groupMap = mAttributeSet.descriptor().groupMap();
370 
371  // build a list of group indices
372 
373  std::vector<size_t> indices;
374  indices.reserve(groupMap.size());
375  for (const auto& namePos : groupMap) {
376  indices.push_back(namePos.second);
377  }
378 
379  std::sort(indices.begin(), indices.end());
380 
381  // return first index not present
382 
383  size_t offset = 0;
384  for (const size_t& index : indices) {
385  if (index != offset) break;
386  offset++;
387  }
388 
389  return offset;
390  }
391 
393  std::vector<size_t> populateGroupIndices() const
394  {
395  std::vector<size_t> indices;
396 
397  const Descriptor::NameToPosMap& map = mAttributeSet.descriptor().map();
398 
399  for (const auto& namePos : map) {
400  const AttributeArray* array = mAttributeSet.getConst(namePos.first);
401  if (isGroup(*array)) {
402  indices.push_back(namePos.second);
403  }
404  }
405 
406  return indices;
407  }
408 
411  bool requiresMove(Name& sourceName, size_t& sourceOffset, size_t& targetOffset) const {
412 
413  targetOffset = this->nextUnusedOffset();
414 
415  const Descriptor::NameToPosMap& groupMap = mAttributeSet.descriptor().groupMap();
416 
417  for (const auto& namePos : groupMap) {
418 
419  // move only required if source comes after the target
420 
421  if (namePos.second >= targetOffset) {
422  sourceName = namePos.first;
423  sourceOffset = namePos.second;
424  return true;
425  }
426  }
427 
428  return false;
429  }
430 
431 private:
432  const AttributeSet& mAttributeSet;
433 }; // class GroupInfo
434 
435 
436 } // namespace point_group_internal
437 
438 
440 
441 
442 inline void deleteMissingPointGroups( std::vector<std::string>& groups,
443  const AttributeSet::Descriptor& descriptor)
444 {
445  for (auto it = groups.begin(); it != groups.end();) {
446  if (!descriptor.hasGroup(*it)) it = groups.erase(it);
447  else ++it;
448  }
449 }
450 
451 
453 
454 
455 template <typename PointDataTreeT>
456 inline void appendGroup(PointDataTreeT& tree, const Name& group)
457 {
459 
460  if (group.empty()) {
461  OPENVDB_THROW(KeyError, "Cannot use an empty group name as a key.");
462  }
463 
464  auto iter = tree.cbeginLeaf();
465 
466  if (!iter) return;
467 
468  const AttributeSet& attributeSet = iter->attributeSet();
469  auto descriptor = attributeSet.descriptorPtr();
470  GroupInfo groupInfo(attributeSet);
471 
472  // don't add if group already exists
473 
474  if (descriptor->hasGroup(group)) return;
475 
476  const bool hasUnusedGroup = groupInfo.unusedGroups() > 0;
477 
478  // add a new group attribute if there are no unused groups
479 
480  if (!hasUnusedGroup) {
481 
482  // find a new internal group name
483 
484  const Name groupName = descriptor->uniqueName("__group");
485 
486  descriptor = descriptor->duplicateAppend(groupName, GroupAttributeArray::attributeType());
487  const size_t pos = descriptor->find(groupName);
488 
489  // insert new group attribute
490 
491  tree::LeafManager<PointDataTreeT> leafManager(tree);
492  leafManager.foreach(
493  [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
494  auto expected = leaf.attributeSet().descriptorPtr();
495  leaf.appendAttribute(*expected, descriptor, pos);
496  }, /*threaded=*/true
497  );
498  }
499  else {
500  // make the descriptor unique before we modify the group map
501 
502  makeDescriptorUnique(tree);
503  descriptor = attributeSet.descriptorPtr();
504  }
505 
506  // ensure that there are now available groups
507 
508  assert(groupInfo.unusedGroups() > 0);
509 
510  // find next unused offset
511 
512  const size_t offset = groupInfo.nextUnusedOffset();
513 
514  // add the group mapping to the descriptor
515 
516  descriptor->setGroup(group, offset);
517 
518  // if there was an unused group then we did not need to append a new attribute, so
519  // we must manually clear membership in the new group as its bits may have been
520  // previously set
521 
522  if (hasUnusedGroup) setGroup(tree, group, false);
523 }
524 
525 
527 
528 
529 template <typename PointDataTree>
530 inline void appendGroups(PointDataTree& tree,
531  const std::vector<Name>& groups)
532 {
533  // TODO: could be more efficient by appending multiple groups at once
534  // instead of one-by-one, however this is likely not that common a use case
535 
536  for (const Name& name : groups) {
537  appendGroup(tree, name);
538  }
539 }
540 
541 
543 
544 
545 template <typename PointDataTree>
546 inline void dropGroup(PointDataTree& tree, const Name& group, const bool compact)
547 {
548  using Descriptor = AttributeSet::Descriptor;
549 
550  if (group.empty()) {
551  OPENVDB_THROW(KeyError, "Cannot use an empty group name as a key.");
552  }
553 
554  auto iter = tree.cbeginLeaf();
555 
556  if (!iter) return;
557 
558  const AttributeSet& attributeSet = iter->attributeSet();
559 
560  // make the descriptor unique before we modify the group map
561 
562  makeDescriptorUnique(tree);
563  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
564 
565  // now drop the group
566 
567  descriptor->dropGroup(group);
568 
569  if (compact) {
570  compactGroups(tree);
571  }
572 }
573 
574 
576 
577 
578 template <typename PointDataTree>
579 inline void dropGroups( PointDataTree& tree,
580  const std::vector<Name>& groups)
581 {
582  for (const Name& name : groups) {
583  dropGroup(tree, name, /*compact=*/false);
584  }
585 
586  // compaction done once for efficiency
587 
588  compactGroups(tree);
589 }
590 
591 
593 
594 
595 template <typename PointDataTree>
596 inline void dropGroups( PointDataTree& tree)
597 {
598  using Descriptor = AttributeSet::Descriptor;
599 
601 
602  auto iter = tree.cbeginLeaf();
603 
604  if (!iter) return;
605 
606  const AttributeSet& attributeSet = iter->attributeSet();
607  GroupInfo groupInfo(attributeSet);
608 
609  // make the descriptor unique before we modify the group map
610 
611  makeDescriptorUnique(tree);
612  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
613 
614  descriptor->clearGroups();
615 
616  // find all indices for group attribute arrays
617 
618  std::vector<size_t> indices = groupInfo.populateGroupIndices();
619 
620  // drop these attributes arrays
621 
622  dropAttributes(tree, indices);
623 }
624 
625 
627 
628 
629 template <typename PointDataTree>
630 inline void compactGroups(PointDataTree& tree)
631 {
632  using Descriptor = AttributeSet::Descriptor;
633  using GroupIndex = Descriptor::GroupIndex;
634  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
635 
638 
639  auto iter = tree.cbeginLeaf();
640 
641  if (!iter) return;
642 
643  const AttributeSet& attributeSet = iter->attributeSet();
644  GroupInfo groupInfo(attributeSet);
645 
646  // early exit if not possible to compact
647 
648  if (!groupInfo.canCompactGroups()) return;
649 
650  // make the descriptor unique before we modify the group map
651 
652  makeDescriptorUnique(tree);
653  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
654 
655  // generate a list of group offsets and move them (one-by-one)
656  // TODO: improve this algorithm to move multiple groups per array at once
657  // though this is likely not that common a use case
658 
659  Name sourceName;
660  size_t sourceOffset, targetOffset;
661 
662  while (groupInfo.requiresMove(sourceName, sourceOffset, targetOffset)) {
663 
664  const GroupIndex sourceIndex = attributeSet.groupIndex(sourceOffset);
665  const GroupIndex targetIndex = attributeSet.groupIndex(targetOffset);
666 
667  CopyGroupOp<PointDataTree> copy(targetIndex, sourceIndex);
668  LeafManagerT leafManager(tree);
669  tbb::parallel_for(leafManager.leafRange(), copy);
670 
671  descriptor->setGroup(sourceName, targetOffset);
672  }
673 
674  // drop unused attribute arrays
675 
676  std::vector<size_t> indices = groupInfo.populateGroupIndices();
677 
678  const size_t totalAttributesToDrop = groupInfo.unusedGroups() / groupInfo.groupBits();
679 
680  assert(totalAttributesToDrop <= indices.size());
681 
682  std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop, indices.end());
683 
684  dropAttributes(tree, indicesToDrop);
685 }
686 
687 
689 
690 
691 template <typename PointDataTree, typename PointIndexTree>
692 inline void setGroup( PointDataTree& tree,
693  const PointIndexTree& indexTree,
694  const std::vector<short>& membership,
695  const Name& group,
696  const bool remove)
697 {
698  using Descriptor = AttributeSet::Descriptor;
699  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
701 
702  auto iter = tree.cbeginLeaf();
703  if (!iter) return;
704 
705  const AttributeSet& attributeSet = iter->attributeSet();
706  const Descriptor& descriptor = attributeSet.descriptor();
707 
708  if (!descriptor.hasGroup(group)) {
709  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
710  }
711 
712  {
713  // Check that that the largest index in the PointIndexTree is smaller than the size
714  // of the membership vector. The index tree will be used to lookup membership
715  // values. If the index tree was constructed with nan positions, this index will
716  // differ from the PointDataTree count
717 
718  using IndexTreeManager = tree::LeafManager<const PointIndexTree>;
719  IndexTreeManager leafManager(indexTree);
720 
721  const int64_t max = tbb::parallel_reduce(leafManager.leafRange(), -1,
722  [](const typename IndexTreeManager::LeafRange& range, int64_t value) -> int64_t {
723  for (auto leaf = range.begin(); leaf; ++leaf) {
724  auto it = std::max_element(leaf->indices().begin(), leaf->indices().end());
725  value = std::max(value, static_cast<int64_t>(*it));
726  }
727  return value;
728  },
729  [](const int64_t a, const int64_t b) {
730  return std::max(a, b);
731  }
732  );
733 
734  if (max != -1 && membership.size() <= static_cast<size_t>(max)) {
735  OPENVDB_THROW(IndexError, "Group membership vector size must be larger than "
736  " the maximum index within the provided index tree.");
737  }
738  }
739 
740  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
741  LeafManagerT leafManager(tree);
742 
743  // set membership
744 
745  if (remove) {
746  SetGroupFromIndexOp<PointDataTree, PointIndexTree, true>
747  set(indexTree, membership, index);
748  tbb::parallel_for(leafManager.leafRange(), set);
749  }
750  else {
751  SetGroupFromIndexOp<PointDataTree, PointIndexTree, false>
752  set(indexTree, membership, index);
753  tbb::parallel_for(leafManager.leafRange(), set);
754  }
755 }
756 
757 
759 
760 
761 template <typename PointDataTree>
762 inline void setGroup( PointDataTree& tree,
763  const Name& group,
764  const bool member)
765 {
766  using Descriptor = AttributeSet::Descriptor;
767  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
768 
770 
771  auto iter = tree.cbeginLeaf();
772 
773  if (!iter) return;
774 
775  const AttributeSet& attributeSet = iter->attributeSet();
776  const Descriptor& descriptor = attributeSet.descriptor();
777 
778  if (!descriptor.hasGroup(group)) {
779  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
780  }
781 
782  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
783  LeafManagerT leafManager(tree);
784 
785  // set membership based on member variable
786 
787  if (member) tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, true>(index));
788  else tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, false>(index));
789 }
790 
791 
793 
794 
795 template <typename PointDataTree, typename FilterT>
796 inline void setGroupByFilter( PointDataTree& tree,
797  const Name& group,
798  const FilterT& filter)
799 {
800  using Descriptor = AttributeSet::Descriptor;
801  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
802 
804 
805  auto iter = tree.cbeginLeaf();
806 
807  if (!iter) return;
808 
809  const AttributeSet& attributeSet = iter->attributeSet();
810  const Descriptor& descriptor = attributeSet.descriptor();
811 
812  if (!descriptor.hasGroup(group)) {
813  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
814  }
815 
816  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
817 
818  // set membership using filter
819 
820  SetGroupByFilterOp<PointDataTree, FilterT> set(index, filter);
821  LeafManagerT leafManager(tree);
822 
823  tbb::parallel_for(leafManager.leafRange(), set);
824 }
825 
826 
828 
829 
830 template <typename PointDataTree>
832  const Name& group,
833  const Index64 targetPoints,
834  const unsigned int seed = 0)
835 {
837 
838  RandomFilter filter(tree, targetPoints, seed);
839 
840  setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
841 }
842 
843 
845 
846 
847 template <typename PointDataTree>
849  const Name& group,
850  const float percentage = 10.0f,
851  const unsigned int seed = 0)
852 {
854 
855  const int currentPoints = static_cast<int>(pointCount(tree));
856  const int targetPoints = int(math::Round((percentage * float(currentPoints))/100.0f));
857 
858  RandomFilter filter(tree, targetPoints, seed);
859 
860  setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
861 }
862 
863 
865 
866 
867 } // namespace points
868 } // namespace OPENVDB_VERSION_NAME
869 } // namespace openvdb
870 
871 
872 #endif // OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
873 
874 // Copyright (c) DreamWorks Animation LLC
875 // All rights reserved. This software is distributed under the
876 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
const PointIndexTree & mIndexTree
Definition: PointGroup.h:276
bool collapse(bool on)
Set membership for the whole array and attempt to collapse.
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:294
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:163
std::vector< short > MembershipArray
Definition: PointGroup.h:230
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:226
const GroupIndex mSourceIndex
Definition: PointGroup.h:188
const GroupIndex & mIndex
Definition: PointGroup.h:218
SetGroupOp(const AttributeSet::Descriptor::GroupIndex &index)
Definition: PointGroup.h:199
void appendGroups(PointDataTree &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
Definition: PointGroup.h:530
void deleteMissingPointGroups(std::vector< std::string > &groups, const AttributeSet::Descriptor &descriptor)
Delete any group that is not present in the Descriptor.
Definition: PointGroup.h:442
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
Methods for counting points in VDB Point grids.
SetGroupFromIndexOp(const PointIndexTree &indexTree, const MembershipArray &membership, const GroupIndex &index)
Definition: PointGroup.h:232
Definition: IndexFilter.h:255
void setGroupByFilter(PointDataTree &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition: PointGroup.h:796
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:793
Convenience class with methods for analyzing group data.
Definition: PointGroup.h:325
typename PointIndexTree::LeafNodeType PointIndexLeafNode
Definition: PointGroup.h:227
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:196
CopyGroupOp(const GroupIndex &targetIndex, const GroupIndex &sourceIndex)
Definition: PointGroup.h:166
Point attribute manipulation in a VDB Point Grid.
size_t unusedGroups() const
Definition: PointGroup.h:338
static size_t groupBits()
Return the number of bits in a group (typically 8)
Definition: PointGroup.h:334
typename tree::LeafManager< PointDataTreeType > LeafManagerT
Definition: PointGroup.h:162
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1618
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:202
Index filters primarily designed to be used with a FilterIndexIter.
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:239
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:62
Copy a group attribute value from one group offset to another.
Definition: PointGroup.h:160
tree::Tree< tree::RootNode< tree::InternalNode< tree::InternalNode< PointDataLeafNode< PointDataIndex32, 3 >, 4 >, 5 > >> PointDataTree
Point index tree configured to match the default VDB configurations.
Definition: PointDataGrid.h:216
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:128
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:397
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:197
std::string Name
Definition: Name.h:44
void dropGroup(PointDataTree &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition: PointGroup.h:546
void compactGroups(PointDataTree &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition: PointGroup.h:630
GroupInfo(const AttributeSet &attributeSet)
Definition: PointGroup.h:330
bool canCompactGroups() const
Return true if there are sufficient empty slots to allow compacting.
Definition: PointGroup.h:359
void dropGroups(PointDataTree &tree)
Drops all existing groups from the VDB tree, the tree is compacted after dropping.
Definition: PointGroup.h:596
typename PointIndexLeafNode::IndexArray IndexArray
Definition: PointGroup.h:228
const FilterT & mFilter
Definition: PointGroup.h:317
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:171
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:131
Definition: Tree.h:203
Definition: Exceptions.h:40
Definition: Exceptions.h:87
const GroupIndex mTargetIndex
Definition: PointGroup.h:187
SetGroupByFilterOp(const GroupIndex &index, const FilterT &filter)
Definition: PointGroup.h:290
Definition: AttributeGroup.h:130
Definition: Exceptions.h:84
tree::Tree< tree::RootNode< tree::InternalNode< tree::InternalNode< PointIndexLeafNode< PointIndex32, 3 >, 4 >, 5 > >> PointIndexTree
Point index tree configured to match the default OpenVDB tree configuration.
Definition: PointIndexGrid.h:83
Index Iterators.
uint64_t Index64
Definition: Types.h:60
const GroupIndex & mIndex
Definition: PointGroup.h:316
std::vector< size_t > populateGroupIndices() const
Return vector of indices correlating to the group attribute arrays.
Definition: PointGroup.h:393
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:125
void appendGroup(PointDataTreeT &tree, const Name &group)
Definition: PointGroup.h:456
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
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:109
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:285
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:225
Definition: AttributeGroup.h:102
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:212
size_t nextUnusedOffset() const
Return the next empty group slot.
Definition: PointGroup.h:367
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
uint8_t GroupType
Definition: AttributeGroup.h:50
void setGroupByRandomTarget(PointDataTree &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition: PointGroup.h:831
void setGroupByRandomPercentage(PointDataTree &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition: PointGroup.h:848
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1181
const GroupIndex & mIndex
Definition: PointGroup.h:278
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:164
bool isGroup(const AttributeArray &array)
Definition: AttributeGroup.h:93
void setGroup(PointDataTree &tree, const Name &group, const bool member=true)
Sets membership for the specified group for all points (on/off).
Definition: PointGroup.h:762
const MembershipArray & mMembership
Definition: PointGroup.h:277
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:180
Definition: Exceptions.h:86
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:288
AttributeSet::Descriptor Descriptor
Definition: PointGroup.h:328
Base class for storing attribute data.
Definition: AttributeArray.h:118
typename PointDataTree::LeafNodeType LeafNodeT
Definition: PointGroup.h:287
Set of Attribute Arrays which tracks metadata about each array.
std::vector< Index > IndexArray
Definition: PointMove.h:188
Set membership on or off for the specified group.
Definition: PointGroup.h:194
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:229
void foreach(const LeafOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to each leaf node in the LeafManager.
Definition: LeafManager.h:523
bool requiresMove(Name &sourceName, size_t &sourceOffset, size_t &targetOffset) const
Definition: PointGroup.h:411
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:286