9#ifndef OPENVDB_POINTS_POINT_GROUP_IMPL_HAS_BEEN_INCLUDED
10#define OPENVDB_POINTS_POINT_GROUP_IMPL_HAS_BEEN_INCLUDED
19namespace point_group_internal {
23template<
typename Po
intDataTreeType>
26 using LeafManagerT =
typename tree::LeafManager<PointDataTreeType>;
27 using LeafRangeT =
typename LeafManagerT::LeafRange;
28 using GroupIndex = AttributeSet::Descriptor::GroupIndex;
30 CopyGroupOp(
const GroupIndex& targetIndex,
31 const GroupIndex& sourceIndex)
32 : mTargetIndex(targetIndex)
33 , mSourceIndex(sourceIndex) { }
35 void operator()(
const typename LeafManagerT::LeafRange& range)
const {
37 for (
auto leaf = range.begin(); leaf; ++leaf) {
39 GroupHandle sourceGroup = leaf->groupHandle(mSourceIndex);
40 GroupWriteHandle targetGroup = leaf->groupWriteHandle(mTargetIndex);
42 for (
auto iter = leaf->beginIndexAll(); iter; ++iter) {
43 const bool groupOn = sourceGroup.get(*iter);
44 targetGroup.set(*iter, groupOn);
51 const GroupIndex mTargetIndex;
52 const GroupIndex mSourceIndex;
57template <
typename Po
intDataTreeT,
bool Member>
60 using LeafManagerT =
typename tree::LeafManager<PointDataTreeT>;
61 using GroupIndex = AttributeSet::Descriptor::GroupIndex;
63 SetGroupOp(
const AttributeSet::Descriptor::GroupIndex& index)
66 void operator()(
const typename LeafManagerT::LeafRange& range)
const
68 for (
auto leaf = range.begin(); leaf; ++leaf) {
72 GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
76 group.collapse(Member);
82 const GroupIndex& mIndex;
86template <
typename Po
intDataTreeT,
typename Po
intIndexTreeT,
bool Remove>
87struct SetGroupFromIndexOp
89 using LeafManagerT =
typename tree::LeafManager<PointDataTreeT>;
90 using LeafRangeT =
typename LeafManagerT::LeafRange;
91 using PointIndexLeafNode =
typename PointIndexTreeT::LeafNodeType;
92 using IndexArray =
typename PointIndexLeafNode::IndexArray;
93 using GroupIndex = AttributeSet::Descriptor::GroupIndex;
94 using MembershipArray = std::vector<short>;
96 SetGroupFromIndexOp(
const PointIndexTreeT& indexTree,
97 const MembershipArray& membership,
98 const GroupIndex& index)
99 : mIndexTree(indexTree)
100 , mMembership(membership)
103 void operator()(
const typename LeafManagerT::LeafRange& range)
const
105 for (
auto leaf = range.begin(); leaf; ++leaf) {
109 const PointIndexLeafNode* pointIndexLeaf = mIndexTree.probeConstLeaf(leaf->origin());
111 if (!pointIndexLeaf)
continue;
115 GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
121 const IndexArray& indices = pointIndexLeaf->indices();
123 for (
const Index64 i: indices) {
125 group.set(
static_cast<Index>(index), mMembership[i]);
126 }
else if (mMembership[i] ==
short(1)) {
127 group.set(
static_cast<Index>(index),
short(1));
140 const PointIndexTreeT& mIndexTree;
141 const MembershipArray& mMembership;
142 const GroupIndex& mIndex;
146template <
typename Po
intDataTreeT,
typename FilterT,
typename IterT =
typename Po
intDataTreeT::LeafNodeType::ValueAllCIter>
147struct SetGroupByFilterOp
149 using LeafManagerT =
typename tree::LeafManager<PointDataTreeT>;
150 using LeafRangeT =
typename LeafManagerT::LeafRange;
151 using LeafNodeT =
typename PointDataTreeT::LeafNodeType;
152 using GroupIndex = AttributeSet::Descriptor::GroupIndex;
154 SetGroupByFilterOp(
const GroupIndex& index,
const FilterT& filter)
156 , mFilter(filter) { }
158 void operator()(
const typename LeafManagerT::LeafRange& range)
const
160 for (
auto leaf = range.begin(); leaf; ++leaf) {
164 GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
166 auto iter = leaf->template beginIndex<IterT, FilterT>(mFilter);
168 for (; iter; ++iter) {
169 group.set(*iter,
true);
180 const GroupIndex& mIndex;
181 const FilterT& mFilter;
198 for (
auto it = groups.begin(); it != groups.end();) {
199 if (!descriptor.
hasGroup(*it)) it = groups.erase(it);
208template <
typename Po
intDataTreeT>
215 auto iter = tree.cbeginLeaf();
219 const AttributeSet& attributeSet = iter->attributeSet();
224 if (descriptor->hasGroup(group))
return;
226 const bool hasUnusedGroup = descriptor->unusedGroups() > 0;
230 if (!hasUnusedGroup) {
234 const Name groupName = descriptor->uniqueName(
"__group");
236 descriptor = descriptor->duplicateAppend(groupName, GroupAttributeArray::attributeType());
237 const size_t pos = descriptor->find(groupName);
243 [&](
typename PointDataTreeT::LeafNodeType& leaf,
size_t ) {
244 auto expected = leaf.attributeSet().descriptorPtr();
245 leaf.appendAttribute(*expected, descriptor, pos);
258 assert(descriptor->unusedGroups() > 0);
262 const size_t offset = descriptor->unusedGroupOffset();
266 descriptor->setGroup(group, offset);
272 if (hasUnusedGroup)
setGroup(tree, group,
false);
279template <
typename Po
intDataTreeT>
281 const std::vector<Name>& groups)
286 for (
const Name& name : groups) {
295template <
typename Po
intDataTreeT>
296inline void dropGroup(PointDataTreeT& tree,
const Name& group,
const bool compact)
304 auto iter = tree.cbeginLeaf();
308 const AttributeSet& attributeSet = iter->attributeSet();
317 descriptor->dropGroup(group);
328template <
typename Po
intDataTreeT>
330 const std::vector<Name>& groups)
332 for (
const Name& name : groups) {
345template <
typename Po
intDataTreeT>
350 auto iter = tree.cbeginLeaf();
354 const AttributeSet& attributeSet = iter->attributeSet();
361 descriptor->clearGroups();
376template <
typename Po
intDataTreeT>
380 using GroupIndex = Descriptor::GroupIndex;
381 using LeafManagerT =
typename tree::template LeafManager<PointDataTreeT>;
383 using point_group_internal::CopyGroupOp;
385 auto iter = tree.cbeginLeaf();
389 const AttributeSet& attributeSet = iter->attributeSet();
405 size_t sourceOffset, targetOffset;
407 while (descriptor->requiresGroupMove(sourceName, sourceOffset, targetOffset)) {
409 const GroupIndex sourceIndex = attributeSet.
groupIndex(sourceOffset);
410 const GroupIndex targetIndex = attributeSet.
groupIndex(targetOffset);
412 CopyGroupOp<PointDataTreeT> copy(targetIndex, sourceIndex);
413 LeafManagerT leafManager(tree);
414 tbb::parallel_for(leafManager.leafRange(), copy);
416 descriptor->setGroup(sourceName, targetOffset);
423 const size_t totalAttributesToDrop = descriptor->unusedGroups() / descriptor->groupBits();
425 assert(totalAttributesToDrop <= indices.size());
427 const std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop,
437template <
typename Po
intDataTreeT,
typename Po
intIndexTreeT>
439 const PointIndexTreeT& indexTree,
440 const std::vector<short>& membership,
446 using point_group_internal::SetGroupFromIndexOp;
448 auto iter = tree.cbeginLeaf();
451 const AttributeSet& attributeSet = iter->attributeSet();
452 const Descriptor& descriptor = attributeSet.
descriptor();
454 if (!descriptor.hasGroup(group)) {
465 IndexTreeManager leafManager(indexTree);
467 const int64_t max = tbb::parallel_reduce(leafManager.leafRange(), -1,
468 [](
const typename IndexTreeManager::LeafRange& range, int64_t value) -> int64_t {
469 for (auto leaf = range.begin(); leaf; ++leaf) {
470 auto it = std::max_element(leaf->indices().begin(), leaf->indices().end());
471 value = std::max(value, static_cast<int64_t>(*it));
475 [](
const int64_t a,
const int64_t b) {
476 return std::max(a, b);
480 if (max != -1 && membership.size() <=
static_cast<size_t>(max)) {
482 " the maximum index within the provided index tree.");
486 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
487 LeafManagerT leafManager(tree);
492 SetGroupFromIndexOp<PointDataTreeT, PointIndexTreeT, true>
493 set(indexTree, membership, index);
494 tbb::parallel_for(leafManager.leafRange(), set);
497 SetGroupFromIndexOp<PointDataTreeT, PointIndexTreeT, false>
498 set(indexTree, membership, index);
499 tbb::parallel_for(leafManager.leafRange(), set);
507template <
typename Po
intDataTreeT>
515 using point_group_internal::SetGroupOp;
517 auto iter = tree.cbeginLeaf();
521 const AttributeSet& attributeSet = iter->attributeSet();
522 const Descriptor& descriptor = attributeSet.
descriptor();
524 if (!descriptor.hasGroup(group)) {
528 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
529 LeafManagerT leafManager(tree);
533 if (member) tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTreeT, true>(index));
534 else tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTreeT, false>(index));
541template <
typename Po
intDataTreeT,
typename FilterT>
544 const FilterT& filter)
549 using point_group_internal::SetGroupByFilterOp;
551 auto iter = tree.cbeginLeaf();
555 const AttributeSet& attributeSet = iter->attributeSet();
556 const Descriptor& descriptor = attributeSet.
descriptor();
558 if (!descriptor.hasGroup(group)) {
562 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
566 SetGroupByFilterOp<PointDataTreeT, FilterT> set(index, filter);
567 LeafManagerT leafManager(tree);
569 tbb::parallel_for(leafManager.leafRange(), set);
576template <
typename Po
intDataTreeT>
580 const unsigned int seed = 0)
584 RandomFilter filter(tree, targetPoints, seed);
586 setGroupByFilter<PointDataTreeT, RandomFilter>(tree, group, filter);
593template <
typename Po
intDataTreeT>
596 const float percentage = 10.0f,
597 const unsigned int seed = 0)
601 const int currentPoints =
static_cast<int>(
pointCount(tree));
602 const int targetPoints = int(math::Round((percentage *
float(currentPoints))/100.0f));
604 RandomFilter filter(tree, targetPoints, seed);
606 setGroupByFilter<PointDataTreeT, RandomFilter>(tree, group, filter);
Definition Exceptions.h:57
Definition Exceptions.h:59
Definition Exceptions.h:60
An immutable object that stores name, type and AttributeSet position for a constant collection of att...
Definition AttributeSet.h:312
bool canCompactGroups() const
Return true if there are sufficient empty slots to allow compacting.
GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
bool hasGroup(const Name &group) const
Return true if group exists.
Ordered collection of uniquely-named attribute arrays.
Definition AttributeSet.h:39
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets.
Definition AttributeSet.h:108
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets.
Definition AttributeSet.h:102
std::vector< size_t > groupAttributeIndices() const
Return the indices of the attribute arrays which are group attribute arrays.
Definition IndexFilter.h:229
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:85
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:483
std::vector< Index > IndexArray
Definition PointMoveImpl.h:88
void dropGroups(PointDataTreeT &tree, const std::vector< Name > &groups)
Drops existing groups from the VDB tree, the tree is compacted after dropping.
Definition PointGroupImpl.h:329
void setGroup(PointDataTreeT &tree, const PointIndexTreeT &indexTree, const std::vector< short > &membership, const Name &group, const bool remove=false)
Sets group membership from a PointIndexTree-ordered vector.
Definition PointGroupImpl.h:438
void setGroupByRandomPercentage(PointDataTreeT &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition PointGroupImpl.h:594
void deleteMissingPointGroups(std::vector< std::string > &groups, const AttributeSet::Descriptor &descriptor)
Delete any group that is not present in the Descriptor.
Definition PointGroupImpl.h:195
void compactGroups(PointDataTreeT &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition PointGroupImpl.h:377
void appendGroup(PointDataTreeT &tree, const Name &group)
Appends a new empty group to the VDB tree.
Definition PointGroupImpl.h:209
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 PointCountImpl.h:18
void setGroupByRandomTarget(PointDataTreeT &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition PointGroupImpl.h:577
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition PointAttributeImpl.h:238
void appendGroups(PointDataTreeT &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
Definition PointGroupImpl.h:280
void setGroupByFilter(PointDataTreeT &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition PointGroupImpl.h:542
void dropGroup(PointDataTreeT &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition PointGroupImpl.h:296
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition PointDataGrid.h:1589
std::string Name
Definition Name.h:19
Index32 Index
Definition Types.h:54
uint64_t Index64
Definition Types.h:53
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212