OpenVDB  6.0.0
PointGroup.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 
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 <algorithm>
50 #include <random>
51 #include <string>
52 #include <vector>
53 
54 namespace openvdb {
56 namespace OPENVDB_VERSION_NAME {
57 namespace points {
58 
63 inline void deleteMissingPointGroups( std::vector<std::string>& groups,
64  const AttributeSet::Descriptor& descriptor);
65 
70 template <typename PointDataTree>
71 inline void appendGroup(PointDataTree& tree,
72  const Name& group);
73 
78 template <typename PointDataTree>
79 inline void appendGroups(PointDataTree& tree,
80  const std::vector<Name>& groups);
81 
88 template <typename PointDataTree>
89 inline void dropGroup( PointDataTree& tree,
90  const Name& group,
91  const bool compact = true);
92 
97 template <typename PointDataTree>
98 inline void dropGroups( PointDataTree& tree,
99  const std::vector<Name>& groups);
100 
104 template <typename PointDataTree>
105 inline void dropGroups( PointDataTree& tree);
106 
110 template <typename PointDataTree>
111 inline void compactGroups(PointDataTree& tree);
112 
122 template <typename PointDataTree, typename PointIndexTree>
123 inline void setGroup( PointDataTree& tree,
124  const PointIndexTree& indexTree,
125  const std::vector<short>& membership,
126  const Name& group,
127  const bool remove = false);
128 
134 template <typename PointDataTree>
135 inline void setGroup( PointDataTree& tree,
136  const Name& group,
137  const bool member = true);
138 
144 template <typename PointDataTree, typename FilterT>
145 inline void setGroupByFilter( PointDataTree& tree,
146  const Name& group,
147  const FilterT& filter);
148 
149 
151 
152 
153 namespace point_group_internal {
154 
155 
157 template<typename PointDataTreeType>
158 struct CopyGroupOp {
159 
161  using LeafRangeT = typename LeafManagerT::LeafRange;
162  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
163 
164  CopyGroupOp(const GroupIndex& targetIndex,
165  const GroupIndex& sourceIndex)
166  : mTargetIndex(targetIndex)
167  , mSourceIndex(sourceIndex) { }
168 
169  void operator()(const typename LeafManagerT::LeafRange& range) const {
170 
171  for (auto leaf = range.begin(); leaf; ++leaf) {
172 
173  GroupHandle sourceGroup = leaf->groupHandle(mSourceIndex);
174  GroupWriteHandle targetGroup = leaf->groupWriteHandle(mTargetIndex);
175 
176  for (auto iter = leaf->beginIndexAll(); iter; ++iter) {
177  const bool groupOn = sourceGroup.get(*iter);
178  targetGroup.set(*iter, groupOn);
179  }
180  }
181  }
182 
184 
187 };
188 
189 
191 template <typename PointDataTree, bool Member>
193 {
195  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
196 
197  SetGroupOp(const AttributeSet::Descriptor::GroupIndex& index)
198  : mIndex(index) { }
199 
200  void operator()(const typename LeafManagerT::LeafRange& range) const
201  {
202  for (auto leaf = range.begin(); leaf; ++leaf) {
203 
204  // obtain the group attribute array
205 
206  GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
207 
208  // set the group value
209 
210  group.collapse(Member);
211  }
212  }
213 
215 
217 }; // struct SetGroupOp
218 
219 
220 template <typename PointDataTree, typename PointIndexTree, bool Remove>
222 {
224  using LeafRangeT = typename LeafManagerT::LeafRange;
225  using PointIndexLeafNode = typename PointIndexTree::LeafNodeType;
227  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
228  using MembershipArray = std::vector<short>;
229 
231  const MembershipArray& membership,
232  const GroupIndex& index)
233  : mIndexTree(indexTree)
234  , mMembership(membership)
235  , mIndex(index) { }
236 
237  void operator()(const typename LeafManagerT::LeafRange& range) const
238  {
239  for (auto leaf = range.begin(); leaf; ++leaf) {
240 
241  // obtain the PointIndexLeafNode (using the origin of the current leaf)
242 
243  const PointIndexLeafNode* pointIndexLeaf = mIndexTree.probeConstLeaf(leaf->origin());
244 
245  if (!pointIndexLeaf) continue;
246 
247  // obtain the group attribute array
248 
249  GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
250 
251  // initialise the attribute storage
252 
253  Index64 index = 0;
254 
255  const IndexArray& indices = pointIndexLeaf->indices();
256 
257  for (const Index64 i: indices) {
258  if (Remove) {
259  group.set(static_cast<Index>(index), mMembership[i]);
260  } else if (mMembership[i] == short(1)) {
261  group.set(static_cast<Index>(index), short(1));
262  }
263  index++;
264  }
265 
266  // attempt to compact the array
267 
268  group.compact();
269  }
270  }
271 
273 
277 }; // struct SetGroupFromIndexOp
278 
279 
280 template <typename PointDataTree, typename FilterT, typename IterT = typename PointDataTree::LeafNodeType::ValueAllCIter>
282 {
284  using LeafRangeT = typename LeafManagerT::LeafRange;
286  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
287 
288  SetGroupByFilterOp( const GroupIndex& index, const FilterT& filter)
289  : mIndex(index)
290  , mFilter(filter) { }
291 
292  void operator()(const typename LeafManagerT::LeafRange& range) const
293  {
294  for (auto leaf = range.begin(); leaf; ++leaf) {
295 
296  // obtain the group attribute array
297 
298  GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
299 
300  auto iter = leaf->template beginIndex<IterT, FilterT>(mFilter);
301 
302  for (; iter; ++iter) {
303  group.set(*iter, true);
304  }
305 
306  // attempt to compact the array
307 
308  group.compact();
309  }
310  }
311 
313 
315  const FilterT& mFilter; // beginIndex takes a copy of mFilter
316 }; // struct SetGroupByFilterOp
317 
318 
320 
321 
324 {
325 public:
326  using Descriptor = AttributeSet::Descriptor;
327 
328  GroupInfo(const AttributeSet& attributeSet)
329  : mAttributeSet(attributeSet) { }
330 
332  static size_t groupBits() { return sizeof(GroupType) * CHAR_BIT; }
333 
336  size_t unusedGroups() const
337  {
338  const Descriptor& descriptor = mAttributeSet.descriptor();
339 
340  // compute total slots (one slot per bit of the group attributes)
341 
342  const size_t groupAttributes = descriptor.count(GroupAttributeArray::attributeType());
343 
344  if (groupAttributes == 0) return 0;
345 
346  const size_t totalSlots = groupAttributes * this->groupBits();
347 
348  // compute slots in use
349 
350  const AttributeSet::Descriptor::NameToPosMap& groupMap = mAttributeSet.descriptor().groupMap();
351  const size_t usedSlots = groupMap.size();
352 
353  return totalSlots - usedSlots;
354  }
355 
357  bool canCompactGroups() const
358  {
359  // can compact if more unused groups than in one group attribute array
360 
361  return this->unusedGroups() >= this->groupBits();
362  }
363 
365  size_t nextUnusedOffset() const
366  {
367  const Descriptor::NameToPosMap& groupMap = mAttributeSet.descriptor().groupMap();
368 
369  // build a list of group indices
370 
371  std::vector<size_t> indices;
372  indices.reserve(groupMap.size());
373  for (const auto& namePos : groupMap) {
374  indices.push_back(namePos.second);
375  }
376 
377  std::sort(indices.begin(), indices.end());
378 
379  // return first index not present
380 
381  size_t offset = 0;
382  for (const size_t& index : indices) {
383  if (index != offset) break;
384  offset++;
385  }
386 
387  return offset;
388  }
389 
391  std::vector<size_t> populateGroupIndices() const
392  {
393  std::vector<size_t> indices;
394 
395  const Descriptor::NameToPosMap& map = mAttributeSet.descriptor().map();
396 
397  for (const auto& namePos : map) {
398  const AttributeArray* array = mAttributeSet.getConst(namePos.first);
399  if (isGroup(*array)) {
400  indices.push_back(namePos.second);
401  }
402  }
403 
404  return indices;
405  }
406 
409  bool requiresMove(Name& sourceName, size_t& sourceOffset, size_t& targetOffset) const {
410 
411  targetOffset = this->nextUnusedOffset();
412 
413  const Descriptor::NameToPosMap& groupMap = mAttributeSet.descriptor().groupMap();
414 
415  for (const auto& namePos : groupMap) {
416 
417  // move only required if source comes after the target
418 
419  if (namePos.second >= targetOffset) {
420  sourceName = namePos.first;
421  sourceOffset = namePos.second;
422  return true;
423  }
424  }
425 
426  return false;
427  }
428 
429 private:
430  const AttributeSet& mAttributeSet;
431 }; // class GroupInfo
432 
433 
434 } // namespace point_group_internal
435 
436 
438 
439 
440 inline void deleteMissingPointGroups( std::vector<std::string>& groups,
441  const AttributeSet::Descriptor& descriptor)
442 {
443  for (auto it = groups.begin(); it != groups.end();) {
444  if (!descriptor.hasGroup(*it)) it = groups.erase(it);
445  else ++it;
446  }
447 }
448 
449 
451 
452 
453 template <typename PointDataTree>
454 inline void appendGroup(PointDataTree& tree, const Name& group)
455 {
456  using Descriptor = AttributeSet::Descriptor;
457  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
458 
461 
462  if (group.empty()) {
463  OPENVDB_THROW(KeyError, "Cannot use an empty group name as a key.");
464  }
465 
466  auto iter = tree.cbeginLeaf();
467 
468  if (!iter) return;
469 
470  const AttributeSet& attributeSet = iter->attributeSet();
471  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
472  GroupInfo groupInfo(attributeSet);
473 
474  // don't add if group already exists
475 
476  if (descriptor->hasGroup(group)) return;
477 
478  const bool hasUnusedGroup = groupInfo.unusedGroups() > 0;
479 
480  // add a new group attribute if there are no unused groups
481 
482  if (!hasUnusedGroup) {
483 
484  // find a new internal group name
485 
486  const Name groupName = descriptor->uniqueName("__group");
487 
488  descriptor = descriptor->duplicateAppend(groupName, GroupAttributeArray::attributeType());
489 
490  const size_t pos = descriptor->find(groupName);
491 
492  // insert new group attribute
493 
494  AppendAttributeOp<PointDataTree> append(descriptor, pos);
495  LeafManagerT leafManager(tree);
496  tbb::parallel_for(leafManager.leafRange(), append);
497  }
498  else {
499  // make the descriptor unique before we modify the group map
500 
501  makeDescriptorUnique(tree);
502  descriptor = attributeSet.descriptorPtr();
503  }
504 
505  // ensure that there are now available groups
506 
507  assert(groupInfo.unusedGroups() > 0);
508 
509  // find next unused offset
510 
511  const size_t offset = groupInfo.nextUnusedOffset();
512 
513  // add the group mapping to the descriptor
514 
515  descriptor->setGroup(group, offset);
516 
517  // if there was an unused group then we did not need to append a new attribute, so
518  // we must manually clear membership in the new group as its bits may have been
519  // previously set
520 
521  if (hasUnusedGroup) setGroup(tree, group, false);
522 }
523 
524 
526 
527 
528 template <typename PointDataTree>
529 inline void appendGroups(PointDataTree& tree,
530  const std::vector<Name>& groups)
531 {
532  // TODO: could be more efficient by appending multiple groups at once
533  // instead of one-by-one, however this is likely not that common a use case
534 
535  for (const Name& name : groups) {
536  appendGroup(tree, name);
537  }
538 }
539 
540 
542 
543 
544 template <typename PointDataTree>
545 inline void dropGroup(PointDataTree& tree, const Name& group, const bool compact)
546 {
547  using Descriptor = AttributeSet::Descriptor;
548 
549  if (group.empty()) {
550  OPENVDB_THROW(KeyError, "Cannot use an empty group name as a key.");
551  }
552 
553  auto iter = tree.cbeginLeaf();
554 
555  if (!iter) return;
556 
557  const AttributeSet& attributeSet = iter->attributeSet();
558 
559  // make the descriptor unique before we modify the group map
560 
561  makeDescriptorUnique(tree);
562  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
563 
564  // now drop the group
565 
566  descriptor->dropGroup(group);
567 
568  if (compact) {
569  compactGroups(tree);
570  }
571 }
572 
573 
575 
576 
577 template <typename PointDataTree>
578 inline void dropGroups( PointDataTree& tree,
579  const std::vector<Name>& groups)
580 {
581  for (const Name& name : groups) {
582  dropGroup(tree, name, /*compact=*/false);
583  }
584 
585  // compaction done once for efficiency
586 
587  compactGroups(tree);
588 }
589 
590 
592 
593 
594 template <typename PointDataTree>
595 inline void dropGroups( PointDataTree& tree)
596 {
597  using Descriptor = AttributeSet::Descriptor;
598 
600 
601  auto iter = tree.cbeginLeaf();
602 
603  if (!iter) return;
604 
605  const AttributeSet& attributeSet = iter->attributeSet();
606  GroupInfo groupInfo(attributeSet);
607 
608  // make the descriptor unique before we modify the group map
609 
610  makeDescriptorUnique(tree);
611  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
612 
613  descriptor->clearGroups();
614 
615  // find all indices for group attribute arrays
616 
617  std::vector<size_t> indices = groupInfo.populateGroupIndices();
618 
619  // drop these attributes arrays
620 
621  dropAttributes(tree, indices);
622 }
623 
624 
626 
627 
628 template <typename PointDataTree>
629 inline void compactGroups(PointDataTree& tree)
630 {
631  using Descriptor = AttributeSet::Descriptor;
632  using GroupIndex = Descriptor::GroupIndex;
633  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
634 
637 
638  auto iter = tree.cbeginLeaf();
639 
640  if (!iter) return;
641 
642  const AttributeSet& attributeSet = iter->attributeSet();
643  GroupInfo groupInfo(attributeSet);
644 
645  // early exit if not possible to compact
646 
647  if (!groupInfo.canCompactGroups()) return;
648 
649  // make the descriptor unique before we modify the group map
650 
651  makeDescriptorUnique(tree);
652  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
653 
654  // generate a list of group offsets and move them (one-by-one)
655  // TODO: improve this algorithm to move multiple groups per array at once
656  // though this is likely not that common a use case
657 
658  Name sourceName;
659  size_t sourceOffset, targetOffset;
660 
661  while (groupInfo.requiresMove(sourceName, sourceOffset, targetOffset)) {
662 
663  const GroupIndex sourceIndex = attributeSet.groupIndex(sourceOffset);
664  const GroupIndex targetIndex = attributeSet.groupIndex(targetOffset);
665 
666  CopyGroupOp<PointDataTree> copy(targetIndex, sourceIndex);
667  LeafManagerT leafManager(tree);
668  tbb::parallel_for(leafManager.leafRange(), copy);
669 
670  descriptor->setGroup(sourceName, targetOffset);
671  }
672 
673  // drop unused attribute arrays
674 
675  std::vector<size_t> indices = groupInfo.populateGroupIndices();
676 
677  const size_t totalAttributesToDrop = groupInfo.unusedGroups() / groupInfo.groupBits();
678 
679  assert(totalAttributesToDrop <= indices.size());
680 
681  std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop, indices.end());
682 
683  dropAttributes(tree, indicesToDrop);
684 }
685 
686 
688 
689 
690 template <typename PointDataTree, typename PointIndexTree>
691 inline void setGroup( PointDataTree& tree,
692  const PointIndexTree& indexTree,
693  const std::vector<short>& membership,
694  const Name& group,
695  const bool remove)
696 {
697  using Descriptor = AttributeSet::Descriptor;
698  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
699 
700  if (membership.size() != pointCount(tree)) {
701  OPENVDB_THROW(LookupError, "Membership vector size must match number of points.");
702  }
703 
705 
706  auto iter = tree.cbeginLeaf();
707 
708  if (!iter) return;
709 
710  const AttributeSet& attributeSet = iter->attributeSet();
711  const Descriptor& descriptor = attributeSet.descriptor();
712 
713  if (!descriptor.hasGroup(group)) {
714  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
715  }
716 
717  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
718  LeafManagerT leafManager(tree);
719 
720  // set membership
721 
722  if (remove) {
723  SetGroupFromIndexOp<PointDataTree,
724  PointIndexTree, false> set(indexTree, membership, index);
725  tbb::parallel_for(leafManager.leafRange(), set);
726  }
727  else {
728  SetGroupFromIndexOp<PointDataTree,
729  PointIndexTree, true> set(indexTree, membership, index);
730  tbb::parallel_for(leafManager.leafRange(), set);
731  }
732 }
733 
734 
736 
737 
738 template <typename PointDataTree>
739 inline void setGroup( PointDataTree& tree,
740  const Name& group,
741  const bool member)
742 {
743  using Descriptor = AttributeSet::Descriptor;
744  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
745 
747 
748  auto iter = tree.cbeginLeaf();
749 
750  if (!iter) return;
751 
752  const AttributeSet& attributeSet = iter->attributeSet();
753  const Descriptor& descriptor = attributeSet.descriptor();
754 
755  if (!descriptor.hasGroup(group)) {
756  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
757  }
758 
759  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
760  LeafManagerT leafManager(tree);
761 
762  // set membership based on member variable
763 
764  if (member) tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, true>(index));
765  else tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, false>(index));
766 }
767 
768 
770 
771 
772 template <typename PointDataTree, typename FilterT>
773 inline void setGroupByFilter( PointDataTree& tree,
774  const Name& group,
775  const FilterT& filter)
776 {
777  using Descriptor = AttributeSet::Descriptor;
778  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
779 
781 
782  auto iter = tree.cbeginLeaf();
783 
784  if (!iter) return;
785 
786  const AttributeSet& attributeSet = iter->attributeSet();
787  const Descriptor& descriptor = attributeSet.descriptor();
788 
789  if (!descriptor.hasGroup(group)) {
790  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
791  }
792 
793  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
794 
795  // set membership using filter
796 
797  SetGroupByFilterOp<PointDataTree, FilterT> set(index, filter);
798  LeafManagerT leafManager(tree);
799 
800  tbb::parallel_for(leafManager.leafRange(), set);
801 }
802 
803 
805 
806 
807 template <typename PointDataTree>
809  const Name& group,
810  const Index64 targetPoints,
811  const unsigned int seed = 0)
812 {
814 
815  RandomFilter filter(tree, targetPoints, seed);
816 
817  setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
818 }
819 
820 
822 
823 
824 template <typename PointDataTree>
826  const Name& group,
827  const float percentage = 10.0f,
828  const unsigned int seed = 0)
829 {
831 
832  const int currentPoints = static_cast<int>(pointCount(tree));
833  const int targetPoints = int(math::Round((percentage * currentPoints)/100.0f));
834 
835  RandomFilter filter(tree, targetPoints, seed);
836 
837  setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
838 }
839 
840 
842 
843 
844 } // namespace points
845 } // namespace OPENVDB_VERSION_NAME
846 } // namespace openvdb
847 
848 
849 #endif // OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
850 
851 // Copyright (c) 2012-2018 DreamWorks Animation LLC
852 // All rights reserved. This software is distributed under the
853 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
const GroupIndex mSourceIndex
Definition: PointGroup.h:186
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:195
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:773
const FilterT & mFilter
Definition: PointGroup.h:315
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:194
void appendGroup(PointDataTree &tree, const Name &group)
Appends a new empty group to the VDB tree.
Definition: PointGroup.h:454
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
bool requiresMove(Name &sourceName, size_t &sourceOffset, size_t &targetOffset) const
Definition: PointGroup.h:409
uint64_t Index64
Definition: Types.h:60
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:161
SetGroupFromIndexOp(const PointIndexTree &indexTree, const MembershipArray &membership, const GroupIndex &index)
Definition: PointGroup.h:230
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:284
void deleteMissingPointGroups(std::vector< std::string > &groups, const AttributeSet::Descriptor &descriptor)
Delete any group that is not present in the Descriptor.
Definition: PointGroup.h:440
void appendGroups(PointDataTree &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
Definition: PointGroup.h:529
typename PointIndexTree::LeafNodeType PointIndexLeafNode
Definition: PointGroup.h:225
std::vector< size_t > populateGroupIndices() const
Return vector of indices correlating to the group attribute arrays.
Definition: PointGroup.h:391
Definition: AttributeGroup.h:130
void setGroupByRandomTarget(PointDataTree &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition: PointGroup.h:808
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
bool collapse(bool on)
Set membership for the whole array and attempt to collapse.
Methods for counting points in VDB Point grids.
std::vector< Index > IndexArray
Definition: PointMove.h:198
AttributeSet::Descriptor Descriptor
Definition: PointGroup.h:326
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:200
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:121
void setGroupByFilter(PointDataTree &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition: PointGroup.h:773
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:283
CopyGroupOp(const GroupIndex &targetIndex, const GroupIndex &sourceIndex)
Definition: PointGroup.h:164
const GroupIndex & mIndex
Definition: PointGroup.h:216
bool isGroup(const AttributeArray &array)
Definition: AttributeGroup.h:93
Definition: Exceptions.h:86
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:237
Point attribute manipulation in a VDB Point Grid.
Definition: Tree.h:203
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1604
Index filters primarily designed to be used with a FilterIndexIter.
GroupInfo(const AttributeSet &attributeSet)
Definition: PointGroup.h:328
const GroupIndex mTargetIndex
Definition: PointGroup.h:185
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:62
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
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:227
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:529
size_t unusedGroups() const
Definition: PointGroup.h:336
void compactGroups(PointDataTree &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition: PointGroup.h:629
size_t nextUnusedOffset() const
Return the next empty group slot.
Definition: PointGroup.h:365
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:286
void dropGroup(PointDataTree &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition: PointGroup.h:545
Definition: IndexFilter.h:254
void dropGroups(PointDataTree &tree)
Drops all existing groups from the VDB tree, the tree is compacted after dropping.
Definition: PointGroup.h:595
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:223
Definition: Exceptions.h:87
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:292
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:169
Definition: Exceptions.h:40
bool canCompactGroups() const
Return true if there are sufficient empty slots to allow compacting.
Definition: PointGroup.h:357
typename tree::LeafManager< PointDataTreeType > LeafManagerT
Definition: PointGroup.h:160
SetGroupOp(const AttributeSet::Descriptor::GroupIndex &index)
Definition: PointGroup.h:197
Index Iterators.
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:110
void setGroupByRandomPercentage(PointDataTree &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition: PointGroup.h:825
typename PointIndexLeafNode::IndexArray IndexArray
Definition: PointGroup.h:226
std::vector< short > MembershipArray
Definition: PointGroup.h:228
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
Set membership on or off for the specified group.
Definition: PointGroup.h:192
SetGroupByFilterOp(const GroupIndex &index, const FilterT &filter)
Definition: PointGroup.h:288
Base class for storing attribute data.
Definition: AttributeArray.h:118
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:162
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:212
typename PointDataTree::LeafNodeType LeafNodeT
Definition: PointGroup.h:285
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
const GroupIndex & mIndex
Definition: PointGroup.h:276
const PointIndexTree & mIndexTree
Definition: PointGroup.h:274
uint8_t GroupType
Definition: AttributeGroup.h:50
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1181
const MembershipArray & mMembership
Definition: PointGroup.h:275
Definition: AttributeGroup.h:102
const GroupIndex & mIndex
Definition: PointGroup.h:314
static size_t groupBits()
Return the number of bits in a group (typically 8)
Definition: PointGroup.h:332
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:739
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:224
Copy a group attribute value from one group offset to another.
Definition: PointGroup.h:158
std::string Name
Definition: Name.h:44
Set of Attribute Arrays which tracks metadata about each array.
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
Convenience class with methods for analyzing group data.
Definition: PointGroup.h:323
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:127