OpenVDB  5.0.0
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 #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;
226  using IndexArray = typename PointIndexLeafNode::IndexArray;
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;
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 
460 
461  if (group.empty()) {
462  OPENVDB_THROW(KeyError, "Cannot use an empty group name as a key.");
463  }
464 
465  auto iter = tree.cbeginLeaf();
466 
467  if (!iter) return;
468 
469  const AttributeSet& attributeSet = iter->attributeSet();
470  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
471  GroupInfo groupInfo(attributeSet);
472 
473  // don't add if group already exists
474 
475  if (descriptor->hasGroup(group)) return;
476 
477  // add a new group attribute if there are no unused groups
478 
479  if (groupInfo.unusedGroups() == 0) {
480 
481  // find a new internal group name
482 
483  const Name groupName = descriptor->uniqueName("__group");
484 
485  descriptor = descriptor->duplicateAppend(groupName, GroupAttributeArray::attributeType());
486 
487  const size_t pos = descriptor->find(groupName);
488 
489  // insert new group attribute
490 
491  AppendAttributeOp<PointDataTree> append(descriptor, pos);
492  tbb::parallel_for(typename tree::template LeafManager<PointDataTree>(tree).leafRange(), append);
493  }
494  else {
495  // make the descriptor unique before we modify the group map
496 
497  makeDescriptorUnique(tree);
498  descriptor = attributeSet.descriptorPtr();
499  }
500 
501  // ensure that there are now available groups
502 
503  assert(groupInfo.unusedGroups() > 0);
504 
505  // find next unused offset
506 
507  const size_t offset = groupInfo.nextUnusedOffset();
508 
509  // add the group mapping to the descriptor
510 
511  descriptor->setGroup(group, offset);
512 }
513 
514 
516 
517 
518 template <typename PointDataTree>
519 inline void appendGroups(PointDataTree& tree,
520  const std::vector<Name>& groups)
521 {
522  // TODO: could be more efficient by appending multiple groups at once
523  // instead of one-by-one, however this is likely not that common a use case
524 
525  for (const Name& name : groups) {
526  appendGroup(tree, name);
527  }
528 }
529 
530 
532 
533 
534 template <typename PointDataTree>
535 inline void dropGroup(PointDataTree& tree, const Name& group, const bool compact)
536 {
537  using Descriptor = AttributeSet::Descriptor;
538 
539  if (group.empty()) {
540  OPENVDB_THROW(KeyError, "Cannot use an empty group name as a key.");
541  }
542 
543  auto iter = tree.cbeginLeaf();
544 
545  if (!iter) return;
546 
547  const AttributeSet& attributeSet = iter->attributeSet();
548 
549  // make the descriptor unique before we modify the group map
550 
551  makeDescriptorUnique(tree);
552  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
553 
554  // now drop the group
555 
556  descriptor->dropGroup(group);
557 
558  if (compact) {
559  compactGroups(tree);
560  }
561 }
562 
563 
565 
566 
567 template <typename PointDataTree>
568 inline void dropGroups( PointDataTree& tree,
569  const std::vector<Name>& groups)
570 {
571  for (const Name& name : groups) {
572  dropGroup(tree, name, /*compact=*/false);
573  }
574 
575  // compaction done once for efficiency
576 
577  compactGroups(tree);
578 }
579 
580 
582 
583 
584 template <typename PointDataTree>
585 inline void dropGroups( PointDataTree& tree)
586 {
587  using Descriptor = AttributeSet::Descriptor;
588 
590 
591  auto iter = tree.cbeginLeaf();
592 
593  if (!iter) return;
594 
595  const AttributeSet& attributeSet = iter->attributeSet();
596  GroupInfo groupInfo(attributeSet);
597 
598  // make the descriptor unique before we modify the group map
599 
600  makeDescriptorUnique(tree);
601  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
602 
603  descriptor->clearGroups();
604 
605  // find all indices for group attribute arrays
606 
607  std::vector<size_t> indices = groupInfo.populateGroupIndices();
608 
609  // drop these attributes arrays
610 
611  dropAttributes(tree, indices);
612 }
613 
614 
616 
617 
618 template <typename PointDataTree>
619 inline void compactGroups(PointDataTree& tree)
620 {
621  using Descriptor = AttributeSet::Descriptor;
622  using GroupIndex = Descriptor::GroupIndex;
623 
626 
627  auto iter = tree.cbeginLeaf();
628 
629  if (!iter) return;
630 
631  const AttributeSet& attributeSet = iter->attributeSet();
632  GroupInfo groupInfo(attributeSet);
633 
634  // early exit if not possible to compact
635 
636  if (!groupInfo.canCompactGroups()) return;
637 
638  // make the descriptor unique before we modify the group map
639 
640  makeDescriptorUnique(tree);
641  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
642 
643  // generate a list of group offsets and move them (one-by-one)
644  // TODO: improve this algorithm to move multiple groups per array at once
645  // though this is likely not that common a use case
646 
647  Name sourceName;
648  size_t sourceOffset, targetOffset;
649 
650  while (groupInfo.requiresMove(sourceName, sourceOffset, targetOffset)) {
651 
652  const GroupIndex sourceIndex = attributeSet.groupIndex(sourceOffset);
653  const GroupIndex targetIndex = attributeSet.groupIndex(targetOffset);
654 
655  CopyGroupOp<PointDataTree> copy(targetIndex, sourceIndex);
656  tbb::parallel_for(typename tree::template LeafManager<PointDataTree>(tree).leafRange(), copy);
657 
658  descriptor->setGroup(sourceName, targetOffset);
659  }
660 
661  // drop unused attribute arrays
662 
663  std::vector<size_t> indices = groupInfo.populateGroupIndices();
664 
665  const size_t totalAttributesToDrop = groupInfo.unusedGroups() / groupInfo.groupBits();
666 
667  assert(totalAttributesToDrop <= indices.size());
668 
669  std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop, indices.end());
670 
671  dropAttributes(tree, indicesToDrop);
672 }
673 
674 
676 
677 
678 template <typename PointDataTree, typename PointIndexTree>
679 inline void setGroup( PointDataTree& tree,
680  const PointIndexTree& indexTree,
681  const std::vector<short>& membership,
682  const Name& group,
683  const bool remove)
684 {
685  using Descriptor = AttributeSet::Descriptor;
686  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
687 
688  if (membership.size() != pointCount(tree)) {
689  OPENVDB_THROW(LookupError, "Membership vector size must match number of points.");
690  }
691 
693 
694  auto iter = tree.cbeginLeaf();
695 
696  if (!iter) return;
697 
698  const AttributeSet& attributeSet = iter->attributeSet();
699  const Descriptor& descriptor = attributeSet.descriptor();
700 
701  if (!descriptor.hasGroup(group)) {
702  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
703  }
704 
705  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
706 
707  // set membership
708 
709  if (remove) {
710  SetGroupFromIndexOp<PointDataTree,
711  PointIndexTree, false> set(indexTree, membership, index);
712  tbb::parallel_for(LeafManagerT(tree).leafRange(), set);
713  }
714  else {
715  SetGroupFromIndexOp<PointDataTree,
716  PointIndexTree, true> set(indexTree, membership, index);
717  tbb::parallel_for(LeafManagerT(tree).leafRange(), set);
718  }
719 }
720 
721 
723 
724 
725 template <typename PointDataTree>
726 inline void setGroup( PointDataTree& tree,
727  const Name& group,
728  const bool member)
729 {
730  using Descriptor = AttributeSet::Descriptor;
731  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
732 
734 
735  auto iter = tree.cbeginLeaf();
736 
737  if (!iter) return;
738 
739  const AttributeSet& attributeSet = iter->attributeSet();
740  const Descriptor& descriptor = attributeSet.descriptor();
741 
742  if (!descriptor.hasGroup(group)) {
743  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
744  }
745 
746  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
747 
748  // set membership based on member variable
749 
750  if (member) tbb::parallel_for(LeafManagerT(tree).leafRange(), SetGroupOp<PointDataTree, true>(index));
751  else tbb::parallel_for(LeafManagerT(tree).leafRange(), SetGroupOp<PointDataTree, false>(index));
752 }
753 
754 
756 
757 
758 template <typename PointDataTree, typename FilterT>
759 inline void setGroupByFilter( PointDataTree& tree,
760  const Name& group,
761  const FilterT& filter)
762 {
763  using Descriptor = AttributeSet::Descriptor;
764  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
765 
767 
768  auto iter = tree.cbeginLeaf();
769 
770  if (!iter) return;
771 
772  const AttributeSet& attributeSet = iter->attributeSet();
773  const Descriptor& descriptor = attributeSet.descriptor();
774 
775  if (!descriptor.hasGroup(group)) {
776  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
777  }
778 
779  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
780 
781  // set membership using filter
782 
783  SetGroupByFilterOp<PointDataTree, FilterT> set(index, filter);
784  tbb::parallel_for(LeafManagerT(tree).leafRange(), set);
785 }
786 
787 
789 
790 
791 template <typename PointDataTree>
793  const Name& group,
794  const Index64 targetPoints,
795  const unsigned int seed = 0)
796 {
798 
799  RandomFilter filter(tree, targetPoints, seed);
800 
801  setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
802 }
803 
804 
806 
807 
808 template <typename PointDataTree>
810  const Name& group,
811  const float percentage = 10.0f,
812  const unsigned int seed = 0)
813 {
815 
816  const int currentPoints = static_cast<int>(pointCount(tree));
817  const int targetPoints = int(math::Round((percentage * currentPoints)/100.0f));
818 
819  RandomFilter filter(tree, targetPoints, seed);
820 
821  setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
822 }
823 
824 
826 
827 
828 } // namespace points
829 } // namespace OPENVDB_VERSION_NAME
830 } // namespace openvdb
831 
832 
833 #endif // OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
834 
835 // Copyright (c) 2012-2017 DreamWorks Animation LLC
836 // All rights reserved. This software is distributed under the
837 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:195
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:212
void compactGroups(PointDataTree &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition: PointGroup.h:619
Index64 pointCount(const PointDataTreeT &tree, const bool inCoreOnly=false)
Total points in the PointDataTree.
Definition: PointCount.h:241
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:769
const GroupIndex mIndex
Definition: PointGroup.h:314
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:224
void dropGroups(PointDataTree &tree)
Drops all existing groups from the VDB tree, the tree is compacted after dropping.
Definition: PointGroup.h:585
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 LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:161
Set membership on or off for the specified group.
Definition: PointGroup.h:192
SetGroupByFilterOp(const GroupIndex &index, const FilterT &filter)
Definition: PointGroup.h:288
Definition: AttributeGroup.h:130
bool requiresMove(Name &sourceName, size_t &sourceOffset, size_t &targetOffset) const
Definition: PointGroup.h:409
uint64_t Index64
Definition: Types.h:59
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:169
typename PointDataTree::LeafNodeType LeafNodeT
Definition: PointGroup.h:285
std::vector< size_t > populateGroupIndices() const
Return vector of indices correlating to the group attribute arrays.
Definition: PointGroup.h:391
Definition: Exceptions.h:86
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:292
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:108
Various point counting methods using a VDB Point Grid.
void dropAttributes(PointDataTree &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:604
AttributeSet::Descriptor Descriptor
Definition: PointGroup.h:326
Definition: Exceptions.h:85
const GroupIndex mSourceIndex
Definition: PointGroup.h:186
Definition: AttributeGroup.h:102
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:200
Descriptor & descriptor()
Return a reference to this attribute set&#39;s descriptor, which might be shared with other sets...
Definition: AttributeSet.h:121
std::vector< short > MembershipArray
Definition: PointGroup.h:228
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:286
uint8_t GroupType
Definition: AttributeGroup.h:50
Point attribute manipulation in a VDB Point Grid.
Definition: IndexFilter.h:187
Convenience class with methods for analyzing group data.
Definition: PointGroup.h:323
Index filters primarily designed to be used with a FilterIndexIter.
GroupInfo(const AttributeSet &attributeSet)
Definition: PointGroup.h:328
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:726
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
typename tree::LeafManager< PointDataTreeType > LeafManagerT
Definition: PointGroup.h:160
size_t unusedGroups() const
Definition: PointGroup.h:336
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
size_t nextUnusedOffset() const
Return the next empty group slot.
Definition: PointGroup.h:365
CopyGroupOp(const GroupIndex &targetIndex, const GroupIndex &sourceIndex)
Definition: PointGroup.h:164
Base class for storing attribute data.
Definition: AttributeArray.h:118
const GroupIndex mTargetIndex
Definition: PointGroup.h:185
const GroupIndex mIndex
Definition: PointGroup.h:276
void appendGroup(PointDataTree &tree, const Name &group)
Appends a new empty group to the VDB tree.
Definition: PointGroup.h:454
Definition: Tree.h:203
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:237
typename PointIndexLeafNode::IndexArray IndexArray
Definition: PointGroup.h:226
Definition: Exceptions.h:39
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1181
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:519
bool canCompactGroups() const
Return true if there are sufficient empty slots to allow compacting.
Definition: PointGroup.h:357
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:223
Index Iterators.
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:110
void setGroupByRandomTarget(PointDataTree &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition: PointGroup.h:792
std::string Name
Definition: Name.h:44
Copy a group attribute value from one group offset to another.
Definition: PointGroup.h:158
const FilterT mFilter
Definition: PointGroup.h:315
void setGroupByFilter(PointDataTree &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition: PointGroup.h:759
SetGroupOp(const AttributeSet::Descriptor::GroupIndex &index)
Definition: PointGroup.h:197
const PointIndexTree & mIndexTree
Definition: PointGroup.h:274
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:284
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:227
const MembershipArray & mMembership
Definition: PointGroup.h:275
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1618
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:62
static size_t groupBits()
Return the number of bits in a group (typically 8)
Definition: PointGroup.h:332
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:283
void setGroupByRandomPercentage(PointDataTree &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition: PointGroup.h:809
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:162
SetGroupFromIndexOp(const PointIndexTree &indexTree, const MembershipArray &membership, const GroupIndex &index)
Definition: PointGroup.h:230
bool collapse(bool on)
Set membership for the whole array and attempt to collapse.
void dropGroup(PointDataTree &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition: PointGroup.h:535
Set of Attribute Arrays which tracks metadata about each array.
const GroupIndex mIndex
Definition: PointGroup.h:216
bool isGroup(const AttributeArray &array)
Definition: AttributeGroup.h:93
typename PointIndexTree::LeafNodeType PointIndexLeafNode
Definition: PointGroup.h:225
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
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:194