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
intDataTreeT>
53 template <
typename Po
intDataTreeT>
55 const std::vector<Name>& groups);
63 template <
typename Po
intDataTreeT>
64 inline void dropGroup( PointDataTreeT& tree,
66 const bool compact =
true);
72 template <
typename Po
intDataTreeT>
74 const std::vector<Name>& groups);
79 template <
typename Po
intDataTreeT>
85 template <
typename Po
intDataTreeT>
97 template <
typename Po
intDataTreeT,
typename Po
intIndexTreeT>
98 inline void setGroup( PointDataTreeT& tree,
99 const PointIndexTreeT& indexTree,
100 const std::vector<short>& membership,
102 const bool remove =
false);
109 template <
typename Po
intDataTreeT>
110 inline void setGroup( PointDataTreeT& tree,
112 const bool member =
true);
119 template <
typename Po
intDataTreeT,
typename FilterT>
122 const FilterT& filter);
129 namespace point_group_internal {
133 template<
typename Po
intDataTreeType>
136 using LeafManagerT =
typename tree::LeafManager<PointDataTreeType>;
137 using LeafRangeT =
typename LeafManagerT::LeafRange;
138 using GroupIndex = AttributeSet::Descriptor::GroupIndex;
140 CopyGroupOp(
const GroupIndex& targetIndex,
141 const GroupIndex& sourceIndex)
142 : mTargetIndex(targetIndex)
143 , mSourceIndex(sourceIndex) { }
145 void operator()(
const typename LeafManagerT::LeafRange& range)
const {
147 for (
auto leaf = range.begin(); leaf; ++leaf) {
149 GroupHandle sourceGroup = leaf->groupHandle(mSourceIndex);
150 GroupWriteHandle targetGroup = leaf->groupWriteHandle(mTargetIndex);
152 for (
auto iter = leaf->beginIndexAll(); iter; ++iter) {
153 const bool groupOn = sourceGroup.get(*iter);
154 targetGroup.set(*iter, groupOn);
161 const GroupIndex mTargetIndex;
162 const GroupIndex mSourceIndex;
167 template <
typename Po
intDataTreeT,
bool Member>
170 using LeafManagerT =
typename tree::LeafManager<PointDataTreeT>;
171 using GroupIndex = AttributeSet::Descriptor::GroupIndex;
173 SetGroupOp(
const AttributeSet::Descriptor::GroupIndex& index)
176 void operator()(
const typename LeafManagerT::LeafRange& range)
const 178 for (
auto leaf = range.begin(); leaf; ++leaf) {
182 GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
186 group.collapse(Member);
192 const GroupIndex& mIndex;
196 template <
typename Po
intDataTreeT,
typename Po
intIndexTreeT,
bool Remove>
197 struct SetGroupFromIndexOp
199 using LeafManagerT =
typename tree::LeafManager<PointDataTreeT>;
200 using LeafRangeT =
typename LeafManagerT::LeafRange;
201 using PointIndexLeafNode =
typename PointIndexTreeT::LeafNodeType;
203 using GroupIndex = AttributeSet::Descriptor::GroupIndex;
204 using MembershipArray = std::vector<short>;
206 SetGroupFromIndexOp(
const PointIndexTreeT& indexTree,
207 const MembershipArray& membership,
208 const GroupIndex& index)
209 : mIndexTree(indexTree)
210 , mMembership(membership)
213 void operator()(
const typename LeafManagerT::LeafRange& range)
const 215 for (
auto leaf = range.begin(); leaf; ++leaf) {
219 const PointIndexLeafNode* pointIndexLeaf = mIndexTree.probeConstLeaf(leaf->origin());
221 if (!pointIndexLeaf)
continue;
225 GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
231 const IndexArray& indices = pointIndexLeaf->indices();
233 for (
const Index64 i: indices) {
235 group.set(static_cast<Index>(index), mMembership[i]);
236 }
else if (mMembership[i] ==
short(1)) {
237 group.set(static_cast<Index>(index),
short(1));
250 const PointIndexTreeT& mIndexTree;
251 const MembershipArray& mMembership;
252 const GroupIndex& mIndex;
256 template <
typename Po
intDataTreeT,
typename FilterT,
typename IterT =
typename Po
intDataTreeT::LeafNodeType::ValueAllCIter>
257 struct SetGroupByFilterOp
259 using LeafManagerT =
typename tree::LeafManager<PointDataTreeT>;
260 using LeafRangeT =
typename LeafManagerT::LeafRange;
261 using LeafNodeT =
typename PointDataTreeT::LeafNodeType;
262 using GroupIndex = AttributeSet::Descriptor::GroupIndex;
264 SetGroupByFilterOp(
const GroupIndex& index,
const FilterT& filter)
266 , mFilter(filter) { }
268 void operator()(
const typename LeafManagerT::LeafRange& range)
const 270 for (
auto leaf = range.begin(); leaf; ++leaf) {
274 GroupWriteHandle group(leaf->groupWriteHandle(mIndex));
276 auto iter = leaf->template beginIndex<IterT, FilterT>(mFilter);
278 for (; iter; ++iter) {
279 group.set(*iter,
true);
290 const GroupIndex& mIndex;
291 const FilterT& mFilter;
306 const AttributeSet::Descriptor& descriptor)
308 for (
auto it = groups.begin(); it != groups.end();) {
309 if (!descriptor.hasGroup(*it)) it = groups.erase(it);
318 template <
typename Po
intDataTreeT>
325 auto iter = tree.cbeginLeaf();
329 const AttributeSet& attributeSet = iter->attributeSet();
334 if (descriptor->hasGroup(group))
return;
336 const bool hasUnusedGroup = descriptor->unusedGroups() > 0;
340 if (!hasUnusedGroup) {
344 const Name groupName = descriptor->uniqueName(
"__group");
346 descriptor = descriptor->duplicateAppend(groupName, GroupAttributeArray::attributeType());
347 const size_t pos = descriptor->find(groupName);
353 [&](
typename PointDataTreeT::LeafNodeType& leaf,
size_t ) {
354 auto expected = leaf.attributeSet().descriptorPtr();
355 leaf.appendAttribute(*expected, descriptor, pos);
368 assert(descriptor->unusedGroups() > 0);
372 const size_t offset = descriptor->unusedGroupOffset();
376 descriptor->setGroup(group, offset);
382 if (hasUnusedGroup)
setGroup(tree, group,
false);
389 template <
typename Po
intDataTreeT>
391 const std::vector<Name>& groups)
396 for (
const Name& name : groups) {
405 template <
typename Po
intDataTreeT>
406 inline void dropGroup(PointDataTreeT& tree,
const Name& group,
const bool compact)
408 using Descriptor = AttributeSet::Descriptor;
414 auto iter = tree.cbeginLeaf();
418 const AttributeSet& attributeSet = iter->attributeSet();
427 descriptor->dropGroup(group);
438 template <
typename Po
intDataTreeT>
440 const std::vector<Name>& groups)
442 for (
const Name& name : groups) {
455 template <
typename Po
intDataTreeT>
458 using Descriptor = AttributeSet::Descriptor;
460 auto iter = tree.cbeginLeaf();
464 const AttributeSet& attributeSet = iter->attributeSet();
471 descriptor->clearGroups();
486 template <
typename Po
intDataTreeT>
489 using Descriptor = AttributeSet::Descriptor;
490 using GroupIndex = Descriptor::GroupIndex;
491 using LeafManagerT =
typename tree::template LeafManager<PointDataTreeT>;
493 using point_group_internal::CopyGroupOp;
495 auto iter = tree.cbeginLeaf();
499 const AttributeSet& attributeSet = iter->attributeSet();
503 if (!attributeSet.
descriptor().canCompactGroups())
return;
515 size_t sourceOffset, targetOffset;
517 while (descriptor->requiresGroupMove(sourceName, sourceOffset, targetOffset)) {
519 const GroupIndex sourceIndex = attributeSet.
groupIndex(sourceOffset);
520 const GroupIndex targetIndex = attributeSet.
groupIndex(targetOffset);
522 CopyGroupOp<PointDataTreeT> copy(targetIndex, sourceIndex);
523 LeafManagerT leafManager(tree);
524 tbb::parallel_for(leafManager.leafRange(), copy);
526 descriptor->setGroup(sourceName, targetOffset);
533 const size_t totalAttributesToDrop = descriptor->unusedGroups() / descriptor->groupBits();
535 assert(totalAttributesToDrop <= indices.size());
537 const std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop,
547 template <
typename Po
intDataTreeT,
typename Po
intIndexTreeT>
549 const PointIndexTreeT& indexTree,
550 const std::vector<short>& membership,
554 using Descriptor = AttributeSet::Descriptor;
556 using point_group_internal::SetGroupFromIndexOp;
558 auto iter = tree.cbeginLeaf();
561 const AttributeSet& attributeSet = iter->attributeSet();
562 const Descriptor& descriptor = attributeSet.
descriptor();
564 if (!descriptor.hasGroup(group)) {
575 IndexTreeManager leafManager(indexTree);
577 const int64_t
max = tbb::parallel_reduce(leafManager.leafRange(), -1,
578 [](
const typename IndexTreeManager::LeafRange& range, int64_t
value) -> int64_t {
579 for (
auto leaf = range.begin(); leaf; ++leaf) {
580 auto it = std::max_element(leaf->indices().begin(), leaf->indices().end());
585 [](
const int64_t a,
const int64_t b) {
590 if (max != -1 && membership.size() <=
static_cast<size_t>(
max)) {
592 " the maximum index within the provided index tree.");
596 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
597 LeafManagerT leafManager(tree);
602 SetGroupFromIndexOp<PointDataTreeT, PointIndexTreeT, true>
603 set(indexTree, membership, index);
604 tbb::parallel_for(leafManager.leafRange(),
set);
607 SetGroupFromIndexOp<PointDataTreeT, PointIndexTreeT, false>
608 set(indexTree, membership, index);
609 tbb::parallel_for(leafManager.leafRange(),
set);
617 template <
typename Po
intDataTreeT>
622 using Descriptor = AttributeSet::Descriptor;
625 using point_group_internal::SetGroupOp;
627 auto iter = tree.cbeginLeaf();
631 const AttributeSet& attributeSet = iter->attributeSet();
632 const Descriptor& descriptor = attributeSet.
descriptor();
634 if (!descriptor.hasGroup(group)) {
638 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
639 LeafManagerT leafManager(tree);
643 if (member) tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTreeT, true>(index));
644 else tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTreeT, false>(index));
651 template <
typename Po
intDataTreeT,
typename FilterT>
654 const FilterT& filter)
656 using Descriptor = AttributeSet::Descriptor;
659 using point_group_internal::SetGroupByFilterOp;
661 auto iter = tree.cbeginLeaf();
665 const AttributeSet& attributeSet = iter->attributeSet();
666 const Descriptor& descriptor = attributeSet.
descriptor();
668 if (!descriptor.hasGroup(group)) {
672 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
676 SetGroupByFilterOp<PointDataTreeT, FilterT>
set(index, filter);
677 LeafManagerT leafManager(tree);
679 tbb::parallel_for(leafManager.leafRange(),
set);
686 template <
typename Po
intDataTreeT>
690 const unsigned int seed = 0)
694 RandomFilter filter(tree, targetPoints, seed);
696 setGroupByFilter<PointDataTreeT, RandomFilter>(tree, group, filter);
703 template <
typename Po
intDataTreeT>
706 const float percentage = 10.0f,
707 const unsigned int seed = 0)
711 const int currentPoints =
static_cast<int>(
pointCount(tree));
712 const int targetPoints = int(
math::Round((percentage *
float(currentPoints))/100.0f));
714 RandomFilter filter(tree, targetPoints, seed);
716 setGroupByFilter<PointDataTreeT, RandomFilter>(tree, group, filter);
728 #endif // OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED std::vector< Index > IndexArray
Definition: PointMove.h:161
void setGroupByFilter(PointDataTreeT &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition: PointGroup.h:652
void setGroup(PointDataTreeT &tree, const Name &group, const bool member=true)
Sets membership for the specified group for all points (on/off).
Definition: PointGroup.h:618
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
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:38
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
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.
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
Methods for counting points in VDB Point grids.
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.
void dropGroup(PointDataTreeT &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition: PointGroup.h:406
void dropGroups(PointDataTreeT &tree)
Drops all existing groups from the VDB tree, the tree is compacted after dropping.
Definition: PointGroup.h:456
Definition: Exceptions.h:60
Definition: Exceptions.h:59
void setGroupByRandomPercentage(PointDataTreeT &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition: PointGroup.h:704
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:822
Point attribute manipulation in a VDB Point Grid.
Index filters primarily designed to be used with a FilterIndexIter.
void deleteMissingPointGroups(std::vector< std::string > &groups, const AttributeSet::Descriptor &descriptor)
Delete any group that is not present in the Descriptor.
Definition: PointGroup.h:305
Definition: IndexFilter.h:228
std::string Name
Definition: Name.h:17
void compactGroups(PointDataTreeT &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition: PointGroup.h:487
uint64_t Index64
Definition: Types.h:53
Definition: Exceptions.h:13
void setGroupByRandomTarget(PointDataTreeT &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition: PointGroup.h:687
ValueT value
Definition: GridBuilder.h:1287
void appendGroup(PointDataTreeT &tree, const Name &group)
Appends a new empty group to the VDB tree.
Definition: PointGroup.h:319
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 appendGroups(PointDataTreeT &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
Definition: PointGroup.h:390
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1577
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:380
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
Set of Attribute Arrays which tracks metadata about each array.
Definition: Exceptions.h:57
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202