10 #ifndef OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
22 #include <tbb/parallel_reduce.h>
39 const AttributeSet::Descriptor& descriptor);
45 template <
typename Po
intDataTree>
53 template <
typename Po
intDataTree>
55 const std::vector<Name>& groups);
63 template <
typename Po
intDataTree>
66 const bool compact =
true);
72 template <
typename Po
intDataTree>
74 const std::vector<Name>& groups);
79 template <
typename Po
intDataTree>
85 template <
typename Po
intDataTree>
97 template <
typename Po
intDataTree,
typename Po
intIndexTree>
100 const std::vector<short>& membership,
102 const bool remove =
false);
109 template <
typename Po
intDataTree>
112 const bool member =
true);
119 template <
typename Po
intDataTree,
typename FilterT>
122 const FilterT& filter);
128 namespace point_group_internal {
132 template<
typename Po
intDataTreeType>
141 : mTargetIndex(targetIndex)
142 , mSourceIndex(sourceIndex) { }
144 void operator()(
const typename LeafManagerT::LeafRange& range)
const {
146 for (
auto leaf = range.begin(); leaf; ++leaf) {
148 GroupHandle sourceGroup = leaf->groupHandle(mSourceIndex);
151 for (
auto iter = leaf->beginIndexAll(); iter; ++iter) {
152 const bool groupOn = sourceGroup.
get(*iter);
153 targetGroup.
set(*iter, groupOn);
166 template <
typename Po
intDataTree,
bool Member>
172 SetGroupOp(
const AttributeSet::Descriptor::GroupIndex& index)
175 void operator()(
const typename LeafManagerT::LeafRange& range)
const
177 for (
auto leaf = range.begin(); leaf; ++leaf) {
195 template <
typename Po
intDataTree,
typename Po
intIndexTree,
bool Remove>
208 : mIndexTree(indexTree)
209 , mMembership(membership)
212 void operator()(
const typename LeafManagerT::LeafRange& range)
const
214 for (
auto leaf = range.begin(); leaf; ++leaf) {
220 if (!pointIndexLeaf)
continue;
230 const IndexArray& indices = pointIndexLeaf->indices();
232 for (
const Index64 i: indices) {
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));
255 template <
typename Po
intDataTree,
typename FilterT,
typename IterT =
typename Po
intDataTree::LeafNodeType::ValueAllCIter>
265 , mFilter(filter) { }
267 void operator()(
const typename LeafManagerT::LeafRange& range)
const
269 for (
auto leaf = range.begin(); leaf; ++leaf) {
275 auto iter = leaf->template beginIndex<IterT, FilterT>(mFilter);
277 for (; iter; ++iter) {
278 group.
set(*iter,
true);
304 const AttributeSet::Descriptor& descriptor)
306 for (
auto it = groups.begin(); it != groups.end();) {
307 if (!descriptor.hasGroup(*it)) it = groups.erase(it);
316 template <
typename Po
intDataTreeT>
323 auto iter = tree.cbeginLeaf();
327 const AttributeSet& attributeSet = iter->attributeSet();
332 if (descriptor->hasGroup(group))
return;
334 const bool hasUnusedGroup = descriptor->unusedGroups() > 0;
338 if (!hasUnusedGroup) {
342 const Name groupName = descriptor->uniqueName(
"__group");
344 descriptor = descriptor->duplicateAppend(groupName, GroupAttributeArray::attributeType());
345 const size_t pos = descriptor->find(groupName);
351 [&](
typename PointDataTreeT::LeafNodeType& leaf,
size_t ) {
352 auto expected = leaf.attributeSet().descriptorPtr();
353 leaf.appendAttribute(*expected, descriptor, pos);
366 assert(descriptor->unusedGroups() > 0);
370 const size_t offset = descriptor->unusedGroupOffset();
374 descriptor->setGroup(group, offset);
380 if (hasUnusedGroup)
setGroup(tree, group,
false);
387 template <
typename Po
intDataTree>
389 const std::vector<Name>& groups)
394 for (
const Name& name : groups) {
403 template <
typename Po
intDataTree>
406 using Descriptor = AttributeSet::Descriptor;
416 const AttributeSet& attributeSet = iter->attributeSet();
425 descriptor->dropGroup(group);
436 template <
typename Po
intDataTree>
438 const std::vector<Name>& groups)
440 for (
const Name& name : groups) {
453 template <
typename Po
intDataTree>
456 using Descriptor = AttributeSet::Descriptor;
462 const AttributeSet& attributeSet = iter->attributeSet();
469 descriptor->clearGroups();
484 template <
typename Po
intDataTree>
487 using Descriptor = AttributeSet::Descriptor;
488 using GroupIndex = Descriptor::GroupIndex;
489 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
497 const AttributeSet& attributeSet = iter->attributeSet();
501 if (!attributeSet.
descriptor().canCompactGroups())
return;
513 size_t sourceOffset, targetOffset;
515 while (descriptor->requiresGroupMove(sourceName, sourceOffset, targetOffset)) {
517 const GroupIndex sourceIndex = attributeSet.
groupIndex(sourceOffset);
518 const GroupIndex targetIndex = attributeSet.
groupIndex(targetOffset);
520 CopyGroupOp<PointDataTree> copy(targetIndex, sourceIndex);
521 LeafManagerT leafManager(tree);
522 tbb::parallel_for(leafManager.leafRange(), copy);
524 descriptor->setGroup(sourceName, targetOffset);
531 const size_t totalAttributesToDrop = descriptor->unusedGroups() / descriptor->groupBits();
533 assert(totalAttributesToDrop <= indices.size());
535 const std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop,
545 template <
typename Po
intDataTree,
typename Po
intIndexTree>
548 const std::vector<short>& membership,
552 using Descriptor = AttributeSet::Descriptor;
553 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
559 const AttributeSet& attributeSet = iter->attributeSet();
560 const Descriptor& descriptor = attributeSet.
descriptor();
562 if (!descriptor.hasGroup(group)) {
573 IndexTreeManager leafManager(indexTree);
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));
583 [](
const int64_t a,
const int64_t b) {
588 if (
max != -1 && membership.size() <=
static_cast<size_t>(
max)) {
590 " the maximum index within the provided index tree.");
594 const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
595 LeafManagerT leafManager(tree);
600 SetGroupFromIndexOp<PointDataTree, PointIndexTree, true>
601 set(indexTree, membership, index);
602 tbb::parallel_for(leafManager.leafRange(), set);
605 SetGroupFromIndexOp<PointDataTree, PointIndexTree, false>
606 set(indexTree, membership, index);
607 tbb::parallel_for(leafManager.leafRange(), set);
615 template <
typename Po
intDataTree>
620 using Descriptor = AttributeSet::Descriptor;
621 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
629 const AttributeSet& attributeSet = iter->attributeSet();
630 const Descriptor& descriptor = attributeSet.
descriptor();
632 if (!descriptor.hasGroup(group)) {
636 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
637 LeafManagerT leafManager(tree);
641 if (member) tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, true>(index));
642 else tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, false>(index));
649 template <
typename Po
intDataTree,
typename FilterT>
652 const FilterT& filter)
654 using Descriptor = AttributeSet::Descriptor;
655 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
663 const AttributeSet& attributeSet = iter->attributeSet();
664 const Descriptor& descriptor = attributeSet.
descriptor();
666 if (!descriptor.hasGroup(group)) {
670 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
674 SetGroupByFilterOp<PointDataTree, FilterT> set(index, filter);
675 LeafManagerT leafManager(tree);
677 tbb::parallel_for(leafManager.leafRange(), set);
684 template <
typename Po
intDataTree>
688 const unsigned int seed = 0)
692 RandomFilter filter(tree, targetPoints, seed);
694 setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
701 template <
typename Po
intDataTree>
704 const float percentage = 10.0f,
705 const unsigned int seed = 0)
709 const int currentPoints =
static_cast<int>(
pointCount(tree));
710 const int targetPoints = int(
math::Round((percentage *
float(currentPoints))/100.0f));
712 RandomFilter filter(tree, targetPoints, seed);
714 setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
Set of Attribute Arrays which tracks metadata about each array.
Index filters primarily designed to be used with a FilterIndexIter.
Point attribute manipulation in a VDB Point Grid.
Methods for counting points in VDB Point grids.
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Definition: openvdb/Exceptions.h:57
Definition: openvdb/Exceptions.h:59
Definition: openvdb/Exceptions.h:60
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.
std::vector< size_t > groupAttributeIndices() const
Return the indices of the attribute arrays which are group attribute arrays.
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:102
Definition: AttributeGroup.h:73
Definition: AttributeGroup.h:102
bool compact()
Compact the existing array to become uniform if all values are identical.
bool collapse(bool on)
Set membership for the whole array and attempt to collapse.
void set(Index n, bool on)
Set on at the given index n.
Definition: IndexFilter.h:227
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
LeafCIter cbeginLeaf() const
Definition: Tree.h:1013
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:183
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:822
std::vector< Index > IndexArray
Definition: PointMove.h:161
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:616
void setGroupByRandomTarget(PointDataTree &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition: PointGroup.h:685
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
void appendGroup(PointDataTreeT &tree, const Name &group)
Definition: PointGroup.h:317
void dropGroups(PointDataTree &tree)
Drops all existing groups from the VDB tree, the tree is compacted after dropping.
Definition: PointGroup.h:454
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 setGroupByRandomPercentage(PointDataTree &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition: PointGroup.h:702
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:377
void dropGroup(PointDataTree &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition: PointGroup.h:404
void appendGroups(PointDataTree &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
Definition: PointGroup.h:388
void compactGroups(PointDataTree &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition: PointGroup.h:485
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1571
void setGroupByFilter(PointDataTree &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition: PointGroup.h:650
std::string Name
Definition: Name.h:17
Index32 Index
Definition: openvdb/Types.h:32
uint64_t Index64
Definition: openvdb/Types.h:31
Definition: openvdb/Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
Copy a group attribute value from one group offset to another.
Definition: PointGroup.h:133
typename tree::LeafManager< PointDataTreeType > LeafManagerT
Definition: PointGroup.h:135
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:136
const GroupIndex mTargetIndex
Definition: PointGroup.h:160
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:144
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:137
const GroupIndex mSourceIndex
Definition: PointGroup.h:161
CopyGroupOp(const GroupIndex &targetIndex, const GroupIndex &sourceIndex)
Definition: PointGroup.h:139
Definition: PointGroup.h:257
const GroupIndex & mIndex
Definition: PointGroup.h:289
typename PointDataTree::LeafNodeType LeafNodeT
Definition: PointGroup.h:260
SetGroupByFilterOp(const GroupIndex &index, const FilterT &filter)
Definition: PointGroup.h:263
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:259
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:267
const FilterT & mFilter
Definition: PointGroup.h:290
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:261
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:258
Definition: PointGroup.h:197
const GroupIndex & mIndex
Definition: PointGroup.h:251
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:199
typename PointIndexTree::LeafNodeType PointIndexLeafNode
Definition: PointGroup.h:200
SetGroupFromIndexOp(const PointIndexTree &indexTree, const MembershipArray &membership, const GroupIndex &index)
Definition: PointGroup.h:205
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:212
std::vector< short > MembershipArray
Definition: PointGroup.h:203
typename PointIndexLeafNode::IndexArray IndexArray
Definition: PointGroup.h:201
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:202
const MembershipArray & mMembership
Definition: PointGroup.h:250
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:198
const PointIndexTree & mIndexTree
Definition: PointGroup.h:249
Set membership on or off for the specified group.
Definition: PointGroup.h:168
const GroupIndex & mIndex
Definition: PointGroup.h:191
SetGroupOp(const AttributeSet::Descriptor::GroupIndex &index)
Definition: PointGroup.h:172
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:175
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:170
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:169
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:101
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:153