HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PointGroup.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 /// @author Dan Bailey
5 ///
6 /// @file points/PointGroup.h
7 ///
8 /// @brief Point group manipulation in a VDB Point Grid.
9 
10 #ifndef OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
12 
13 #include <openvdb/openvdb.h>
14 
15 #include "IndexIterator.h" // FilterTraits
16 #include "IndexFilter.h" // FilterTraits
17 #include "AttributeSet.h"
18 #include "PointDataGrid.h"
19 #include "PointAttribute.h"
20 #include "PointCount.h"
21 
22 #include <tbb/parallel_reduce.h>
23 
24 #include <algorithm>
25 #include <random>
26 #include <string>
27 #include <vector>
28 
29 namespace openvdb {
31 namespace OPENVDB_VERSION_NAME {
32 namespace points {
33 
34 /// @brief Delete any group that is not present in the Descriptor.
35 ///
36 /// @param groups the vector of group names.
37 /// @param descriptor the descriptor that holds the group map.
38 inline void deleteMissingPointGroups( std::vector<std::string>& groups,
39  const AttributeSet::Descriptor& descriptor);
40 
41 /// @brief Appends a new empty group to the VDB tree.
42 ///
43 /// @param tree the PointDataTree to be appended to.
44 /// @param group name of the new group.
45 template <typename PointDataTree>
46 inline void appendGroup(PointDataTree& tree,
47  const Name& group);
48 
49 /// @brief Appends new empty groups to the VDB tree.
50 ///
51 /// @param tree the PointDataTree to be appended to.
52 /// @param groups names of the new groups.
53 template <typename PointDataTree>
54 inline void appendGroups(PointDataTree& tree,
55  const std::vector<Name>& groups);
56 
57 /// @brief Drops an existing group from the VDB tree.
58 ///
59 /// @param tree the PointDataTree to be dropped from.
60 /// @param group name of the group.
61 /// @param compact compact attributes if possible to reduce memory - if dropping
62 /// more than one group, compacting once at the end will be faster
63 template <typename PointDataTree>
64 inline void dropGroup( PointDataTree& tree,
65  const Name& group,
66  const bool compact = true);
67 
68 /// @brief Drops existing groups from the VDB tree, the tree is compacted after dropping.
69 ///
70 /// @param tree the PointDataTree to be dropped from.
71 /// @param groups names of the groups.
72 template <typename PointDataTree>
73 inline void dropGroups( PointDataTree& tree,
74  const std::vector<Name>& groups);
75 
76 /// @brief Drops all existing groups from the VDB tree, the tree is compacted after dropping.
77 ///
78 /// @param tree the PointDataTree to be dropped from.
79 template <typename PointDataTree>
80 inline void dropGroups( PointDataTree& tree);
81 
82 /// @brief Compacts existing groups of a VDB Tree to use less memory if possible.
83 ///
84 /// @param tree the PointDataTree to be compacted.
85 template <typename PointDataTree>
86 inline void compactGroups(PointDataTree& tree);
87 
88 /// @brief Sets group membership from a PointIndexTree-ordered vector.
89 ///
90 /// @param tree the PointDataTree.
91 /// @param indexTree the PointIndexTree.
92 /// @param membership @c 1 if the point is in the group, 0 otherwise.
93 /// @param group the name of the group.
94 /// @param remove if @c true also perform removal of points from the group.
95 ///
96 /// @note vector<bool> is not thread-safe on concurrent write, so use vector<short> instead
97 template <typename PointDataTree, typename PointIndexTree>
98 inline void setGroup( PointDataTree& tree,
99  const PointIndexTree& indexTree,
100  const std::vector<short>& membership,
101  const Name& group,
102  const bool remove = false);
103 
104 /// @brief Sets membership for the specified group for all points (on/off).
105 ///
106 /// @param tree the PointDataTree.
107 /// @param group the name of the group.
108 /// @param member true / false for membership of the group.
109 template <typename PointDataTree>
110 inline void setGroup( PointDataTree& tree,
111  const Name& group,
112  const bool member = true);
113 
114 /// @brief Sets group membership based on a provided filter.
115 ///
116 /// @param tree the PointDataTree.
117 /// @param group the name of the group.
118 /// @param filter filter data that is used to create a per-leaf filter
119 template <typename PointDataTree, typename FilterT>
120 inline void setGroupByFilter( PointDataTree& tree,
121  const Name& group,
122  const FilterT& filter);
123 
124 
125 ////////////////////////////////////////
126 
127 
128 namespace point_group_internal {
129 
130 
131 /// Copy a group attribute value from one group offset to another
132 template<typename PointDataTreeType>
133 struct CopyGroupOp {
134 
136  using LeafRangeT = typename LeafManagerT::LeafRange;
137  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
138 
139  CopyGroupOp(const GroupIndex& targetIndex,
140  const GroupIndex& sourceIndex)
141  : mTargetIndex(targetIndex)
142  , mSourceIndex(sourceIndex) { }
143 
144  void operator()(const typename LeafManagerT::LeafRange& range) const {
145 
146  for (auto leaf = range.begin(); leaf; ++leaf) {
147 
148  GroupHandle sourceGroup = leaf->groupHandle(mSourceIndex);
149  GroupWriteHandle targetGroup = leaf->groupWriteHandle(mTargetIndex);
150 
151  for (auto iter = leaf->beginIndexAll(); iter; ++iter) {
152  const bool groupOn = sourceGroup.get(*iter);
153  targetGroup.set(*iter, groupOn);
154  }
155  }
156  }
157 
158  //////////
159 
162 };
163 
164 
165 /// Set membership on or off for the specified group
166 template <typename PointDataTree, bool Member>
168 {
170  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
171 
172  SetGroupOp(const AttributeSet::Descriptor::GroupIndex& index)
173  : mIndex(index) { }
174 
175  void operator()(const typename LeafManagerT::LeafRange& range) const
176  {
177  for (auto leaf = range.begin(); leaf; ++leaf) {
178 
179  // obtain the group attribute array
180 
181  GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
182 
183  // set the group value
184 
185  group.collapse(Member);
186  }
187  }
188 
189  //////////
190 
192 }; // struct SetGroupOp
193 
194 
195 template <typename PointDataTree, typename PointIndexTree, bool Remove>
197 {
199  using LeafRangeT = typename LeafManagerT::LeafRange;
200  using PointIndexLeafNode = typename PointIndexTree::LeafNodeType;
202  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
203  using MembershipArray = std::vector<short>;
204 
206  const MembershipArray& membership,
207  const GroupIndex& index)
208  : mIndexTree(indexTree)
209  , mMembership(membership)
210  , mIndex(index) { }
211 
212  void operator()(const typename LeafManagerT::LeafRange& range) const
213  {
214  for (auto leaf = range.begin(); leaf; ++leaf) {
215 
216  // obtain the PointIndexLeafNode (using the origin of the current leaf)
217 
218  const PointIndexLeafNode* pointIndexLeaf = mIndexTree.probeConstLeaf(leaf->origin());
219 
220  if (!pointIndexLeaf) continue;
221 
222  // obtain the group attribute array
223 
224  GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
225 
226  // initialise the attribute storage
227 
228  Index64 index = 0;
229 
230  const IndexArray& indices = pointIndexLeaf->indices();
231 
232  for (const Index64 i: indices) {
233  if (Remove) {
234  group.set(static_cast<Index>(index), mMembership[i]);
235  } else if (mMembership[i] == short(1)) {
236  group.set(static_cast<Index>(index), short(1));
237  }
238  index++;
239  }
240 
241  // attempt to compact the array
242 
243  group.compact();
244  }
245  }
246 
247  //////////
248 
252 }; // struct SetGroupFromIndexOp
253 
254 
255 template <typename PointDataTree, typename FilterT, typename IterT = typename PointDataTree::LeafNodeType::ValueAllCIter>
257 {
259  using LeafRangeT = typename LeafManagerT::LeafRange;
261  using GroupIndex = AttributeSet::Descriptor::GroupIndex;
262 
263  SetGroupByFilterOp( const GroupIndex& index, const FilterT& filter)
264  : mIndex(index)
265  , mFilter(filter) { }
266 
267  void operator()(const typename LeafManagerT::LeafRange& range) const
268  {
269  for (auto leaf = range.begin(); leaf; ++leaf) {
270 
271  // obtain the group attribute array
272 
273  GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
274 
275  auto iter = leaf->template beginIndex<IterT, FilterT>(mFilter);
276 
277  for (; iter; ++iter) {
278  group.set(*iter, true);
279  }
280 
281  // attempt to compact the array
282 
283  group.compact();
284  }
285  }
286 
287  //////////
288 
290  const FilterT& mFilter; // beginIndex takes a copy of mFilter
291 }; // struct SetGroupByFilterOp
292 
293 
294 ////////////////////////////////////////
295 
296 
297 } // namespace point_group_internal
298 
299 
300 ////////////////////////////////////////
301 
302 
303 inline void deleteMissingPointGroups( std::vector<std::string>& groups,
304  const AttributeSet::Descriptor& descriptor)
305 {
306  for (auto it = groups.begin(); it != groups.end();) {
307  if (!descriptor.hasGroup(*it)) it = groups.erase(it);
308  else ++it;
309  }
310 }
311 
312 
313 ////////////////////////////////////////
314 
315 
316 template <typename PointDataTreeT>
317 inline void appendGroup(PointDataTreeT& tree, const Name& group)
318 {
319  if (group.empty()) {
320  OPENVDB_THROW(KeyError, "Cannot use an empty group name as a key.");
321  }
322 
323  auto iter = tree.cbeginLeaf();
324 
325  if (!iter) return;
326 
327  const AttributeSet& attributeSet = iter->attributeSet();
328  auto descriptor = attributeSet.descriptorPtr();
329 
330  // don't add if group already exists
331 
332  if (descriptor->hasGroup(group)) return;
333 
334  const bool hasUnusedGroup = descriptor->unusedGroups() > 0;
335 
336  // add a new group attribute if there are no unused groups
337 
338  if (!hasUnusedGroup) {
339 
340  // find a new internal group name
341 
342  const Name groupName = descriptor->uniqueName("__group");
343 
344  descriptor = descriptor->duplicateAppend(groupName, GroupAttributeArray::attributeType());
345  const size_t pos = descriptor->find(groupName);
346 
347  // insert new group attribute
348 
349  tree::LeafManager<PointDataTreeT> leafManager(tree);
350  leafManager.foreach(
351  [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
352  auto expected = leaf.attributeSet().descriptorPtr();
353  leaf.appendAttribute(*expected, descriptor, pos);
354  }, /*threaded=*/true
355  );
356  }
357  else {
358  // make the descriptor unique before we modify the group map
359 
360  makeDescriptorUnique(tree);
361  descriptor = attributeSet.descriptorPtr();
362  }
363 
364  // ensure that there are now available groups
365 
366  assert(descriptor->unusedGroups() > 0);
367 
368  // find next unused offset
369 
370  const size_t offset = descriptor->unusedGroupOffset();
371 
372  // add the group mapping to the descriptor
373 
374  descriptor->setGroup(group, offset);
375 
376  // if there was an unused group then we did not need to append a new attribute, so
377  // we must manually clear membership in the new group as its bits may have been
378  // previously set
379 
380  if (hasUnusedGroup) setGroup(tree, group, false);
381 }
382 
383 
384 ////////////////////////////////////////
385 
386 
387 template <typename PointDataTree>
388 inline void appendGroups(PointDataTree& tree,
389  const std::vector<Name>& groups)
390 {
391  // TODO: could be more efficient by appending multiple groups at once
392  // instead of one-by-one, however this is likely not that common a use case
393 
394  for (const Name& name : groups) {
395  appendGroup(tree, name);
396  }
397 }
398 
399 
400 ////////////////////////////////////////
401 
402 
403 template <typename PointDataTree>
404 inline void dropGroup(PointDataTree& tree, const Name& group, const bool compact)
405 {
406  using Descriptor = AttributeSet::Descriptor;
407 
408  if (group.empty()) {
409  OPENVDB_THROW(KeyError, "Cannot use an empty group name as a key.");
410  }
411 
412  auto iter = tree.cbeginLeaf();
413 
414  if (!iter) return;
415 
416  const AttributeSet& attributeSet = iter->attributeSet();
417 
418  // make the descriptor unique before we modify the group map
419 
420  makeDescriptorUnique(tree);
421  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
422 
423  // now drop the group
424 
425  descriptor->dropGroup(group);
426 
427  if (compact) {
428  compactGroups(tree);
429  }
430 }
431 
432 
433 ////////////////////////////////////////
434 
435 
436 template <typename PointDataTree>
437 inline void dropGroups( PointDataTree& tree,
438  const std::vector<Name>& groups)
439 {
440  for (const Name& name : groups) {
441  dropGroup(tree, name, /*compact=*/false);
442  }
443 
444  // compaction done once for efficiency
445 
446  compactGroups(tree);
447 }
448 
449 
450 ////////////////////////////////////////
451 
452 
453 template <typename PointDataTree>
454 inline void dropGroups( PointDataTree& tree)
455 {
456  using Descriptor = AttributeSet::Descriptor;
457 
458  auto iter = tree.cbeginLeaf();
459 
460  if (!iter) return;
461 
462  const AttributeSet& attributeSet = iter->attributeSet();
463 
464  // make the descriptor unique before we modify the group map
465 
466  makeDescriptorUnique(tree);
467  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
468 
469  descriptor->clearGroups();
470 
471  // find all indices for group attribute arrays
472 
473  std::vector<size_t> indices = attributeSet.groupAttributeIndices();
474 
475  // drop these attributes arrays
476 
477  dropAttributes(tree, indices);
478 }
479 
480 
481 ////////////////////////////////////////
482 
483 
484 template <typename PointDataTree>
485 inline void compactGroups(PointDataTree& tree)
486 {
487  using Descriptor = AttributeSet::Descriptor;
488  using GroupIndex = Descriptor::GroupIndex;
489  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
490 
492 
493  auto iter = tree.cbeginLeaf();
494 
495  if (!iter) return;
496 
497  const AttributeSet& attributeSet = iter->attributeSet();
498 
499  // early exit if not possible to compact
500 
501  if (!attributeSet.descriptor().canCompactGroups()) return;
502 
503  // make the descriptor unique before we modify the group map
504 
505  makeDescriptorUnique(tree);
506  Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
507 
508  // generate a list of group offsets and move them (one-by-one)
509  // TODO: improve this algorithm to move multiple groups per array at once
510  // though this is likely not that common a use case
511 
512  Name sourceName;
513  size_t sourceOffset, targetOffset;
514 
515  while (descriptor->requiresGroupMove(sourceName, sourceOffset, targetOffset)) {
516 
517  const GroupIndex sourceIndex = attributeSet.groupIndex(sourceOffset);
518  const GroupIndex targetIndex = attributeSet.groupIndex(targetOffset);
519 
520  CopyGroupOp<PointDataTree> copy(targetIndex, sourceIndex);
521  LeafManagerT leafManager(tree);
522  tbb::parallel_for(leafManager.leafRange(), copy);
523 
524  descriptor->setGroup(sourceName, targetOffset);
525  }
526 
527  // drop unused attribute arrays
528 
529  const std::vector<size_t> indices = attributeSet.groupAttributeIndices();
530 
531  const size_t totalAttributesToDrop = descriptor->unusedGroups() / descriptor->groupBits();
532 
533  assert(totalAttributesToDrop <= indices.size());
534 
535  const std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop,
536  indices.end());
537 
538  dropAttributes(tree, indicesToDrop);
539 }
540 
541 
542 ////////////////////////////////////////
543 
544 
545 template <typename PointDataTree, typename PointIndexTree>
546 inline void setGroup( PointDataTree& tree,
547  const PointIndexTree& indexTree,
548  const std::vector<short>& membership,
549  const Name& group,
550  const bool remove)
551 {
552  using Descriptor = AttributeSet::Descriptor;
553  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
555 
556  auto iter = tree.cbeginLeaf();
557  if (!iter) return;
558 
559  const AttributeSet& attributeSet = iter->attributeSet();
560  const Descriptor& descriptor = attributeSet.descriptor();
561 
562  if (!descriptor.hasGroup(group)) {
563  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
564  }
565 
566  {
567  // Check that that the largest index in the PointIndexTree is smaller than the size
568  // of the membership vector. The index tree will be used to lookup membership
569  // values. If the index tree was constructed with nan positions, this index will
570  // differ from the PointDataTree count
571 
572  using IndexTreeManager = tree::LeafManager<const PointIndexTree>;
573  IndexTreeManager leafManager(indexTree);
574 
575  const int64_t max = tbb::parallel_reduce(leafManager.leafRange(), -1,
576  [](const typename IndexTreeManager::LeafRange& range, int64_t value) -> int64_t {
577  for (auto leaf = range.begin(); leaf; ++leaf) {
578  auto it = std::max_element(leaf->indices().begin(), leaf->indices().end());
579  value = std::max(value, static_cast<int64_t>(*it));
580  }
581  return value;
582  },
583  [](const int64_t a, const int64_t b) {
584  return std::max(a, b);
585  }
586  );
587 
588  if (max != -1 && membership.size() <= static_cast<size_t>(max)) {
589  OPENVDB_THROW(IndexError, "Group membership vector size must be larger than "
590  " the maximum index within the provided index tree.");
591  }
592  }
593 
594  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
595  LeafManagerT leafManager(tree);
596 
597  // set membership
598 
599  if (remove) {
600  SetGroupFromIndexOp<PointDataTree, PointIndexTree, true>
601  set(indexTree, membership, index);
602  tbb::parallel_for(leafManager.leafRange(), set);
603  }
604  else {
605  SetGroupFromIndexOp<PointDataTree, PointIndexTree, false>
606  set(indexTree, membership, index);
607  tbb::parallel_for(leafManager.leafRange(), set);
608  }
609 }
610 
611 
612 ////////////////////////////////////////
613 
614 
615 template <typename PointDataTree>
616 inline void setGroup( PointDataTree& tree,
617  const Name& group,
618  const bool member)
619 {
620  using Descriptor = AttributeSet::Descriptor;
621  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
622 
624 
625  auto iter = tree.cbeginLeaf();
626 
627  if (!iter) return;
628 
629  const AttributeSet& attributeSet = iter->attributeSet();
630  const Descriptor& descriptor = attributeSet.descriptor();
631 
632  if (!descriptor.hasGroup(group)) {
633  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
634  }
635 
636  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
637  LeafManagerT leafManager(tree);
638 
639  // set membership based on member variable
640 
641  if (member) tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, true>(index));
642  else tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, false>(index));
643 }
644 
645 
646 ////////////////////////////////////////
647 
648 
649 template <typename PointDataTree, typename FilterT>
650 inline void setGroupByFilter( PointDataTree& tree,
651  const Name& group,
652  const FilterT& filter)
653 {
654  using Descriptor = AttributeSet::Descriptor;
655  using LeafManagerT = typename tree::template LeafManager<PointDataTree>;
656 
658 
659  auto iter = tree.cbeginLeaf();
660 
661  if (!iter) return;
662 
663  const AttributeSet& attributeSet = iter->attributeSet();
664  const Descriptor& descriptor = attributeSet.descriptor();
665 
666  if (!descriptor.hasGroup(group)) {
667  OPENVDB_THROW(LookupError, "Group must exist on Tree before defining membership.");
668  }
669 
670  const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
671 
672  // set membership using filter
673 
674  SetGroupByFilterOp<PointDataTree, FilterT> set(index, filter);
675  LeafManagerT leafManager(tree);
676 
677  tbb::parallel_for(leafManager.leafRange(), set);
678 }
679 
680 
681 ////////////////////////////////////////
682 
683 
684 template <typename PointDataTree>
686  const Name& group,
687  const Index64 targetPoints,
688  const unsigned int seed = 0)
689 {
691 
692  RandomFilter filter(tree, targetPoints, seed);
693 
694  setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
695 }
696 
697 
698 ////////////////////////////////////////
699 
700 
701 template <typename PointDataTree>
703  const Name& group,
704  const float percentage = 10.0f,
705  const unsigned int seed = 0)
706 {
708 
709  const int currentPoints = static_cast<int>(pointCount(tree));
710  const int targetPoints = int(math::Round((percentage * float(currentPoints))/100.0f));
711 
712  RandomFilter filter(tree, targetPoints, seed);
713 
714  setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
715 }
716 
717 
718 ////////////////////////////////////////
719 
720 
721 } // namespace points
722 } // namespace OPENVDB_VERSION_NAME
723 } // namespace openvdb
724 
725 
726 #endif // OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
CopyGroupOp(const GroupIndex &targetIndex, const GroupIndex &sourceIndex)
Definition: PointGroup.h:139
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
vint4 max(const vint4 &a, const vint4 &b)
Definition: simd.h:4703
SetGroupFromIndexOp(const PointIndexTree &indexTree, const MembershipArray &membership, const GroupIndex &index)
Definition: PointGroup.h:205
void parallel_for(int64_t start, int64_t end, std::function< void(int64_t index)> &&task, parallel_options opt=parallel_options(0, Split_Y, 1))
Definition: parallel.h:153
GLenum GLint * range
Definition: glew.h:3500
Definition: ImfName.h:54
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets...
Definition: AttributeSet.h:102
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
GLuint const GLchar * name
Definition: glew.h:1814
void dropGroup(PointDataTree &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition: PointGroup.h:404
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1013
SetGroupByFilterOp(const GroupIndex &index, const FilterT &filter)
Definition: PointGroup.h:263
GLuint index
Definition: glew.h:1814
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
Copy a group attribute value from one group offset to another.
Definition: PointGroup.h:133
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:167
Index filters primarily designed to be used with a FilterIndexIter.
void setGroupByRandomTarget(PointDataTree &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition: PointGroup.h:685
GLsizei GLuint * groups
Definition: glew.h:2744
Set membership on or off for the specified group.
Definition: PointGroup.h:167
void setGroupByRandomPercentage(PointDataTree &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition: PointGroup.h:702
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:144
void deleteMissingPointGroups(std::vector< std::string > &groups, const AttributeSet::Descriptor &descriptor)
Delete any group that is not present in the Descriptor.
Definition: PointGroup.h:303
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:2981
std::vector< size_t > groupAttributeIndices() const
Return the indices of the attribute arrays which are group attribute arrays.
Methods for counting points in VDB Point grids.
GLclampf f
Definition: glew.h:3499
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:812
void appendGroups(PointDataTree &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
Definition: PointGroup.h:388
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:175
GLuint GLuint GLsizei GLenum const void * indices
Definition: glew.h:1253
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:84
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:169
Index Iterators.
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
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:88
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:485
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:267
Point attribute manipulation in a VDB Point Grid.
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
typename tree::LeafManager< PointDataTreeType > LeafManagerT
Definition: PointGroup.h:135
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:183
Set of Attribute Arrays which tracks metadata about each array.
SetGroupOp(const AttributeSet::Descriptor::GroupIndex &index)
Definition: PointGroup.h:172
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:212
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3446
OIIO_API bool copy(string_view from, string_view to, std::string &err)
void dropGroups(PointDataTree &tree, const std::vector< Name > &groups)
Drops existing groups from the VDB tree, the tree is compacted after dropping.
Definition: PointGroup.h:437
void setGroup(PointDataTree &tree, const PointIndexTree &indexTree, const std::vector< short > &membership, const Name &group, const bool remove=false)
Sets group membership from a PointIndexTree-ordered vector.
Definition: PointGroup.h:546
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:38
void set(Index n, bool on)
Set on at the given index n.
void appendGroup(PointDataTree &tree, const Name &group)
Appends a new empty group to the VDB tree.
tree::Tree< tree::RootNode< tree::InternalNode< tree::InternalNode< PointDataLeafNode< PointDataIndex32, 3 >, 4 >, 5 >>> PointDataTree
Point index tree configured to match the default VDB configurations.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:113
GLsizei const GLfloat * value
Definition: glew.h:1849
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets...
Definition: AttributeSet.h:108
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.
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
void compactGroups(PointDataTree &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition: PointGroup.h:485
GLboolean GLuint group
Definition: glew.h:2745
GLintptr offset
Definition: glew.h:1682
void setGroupByFilter(PointDataTree &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition: PointGroup.h:650