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