9 #ifndef OPENVDB_POINTS_POINT_GROUP_IMPL_HAS_BEEN_INCLUDED 10 #define OPENVDB_POINTS_POINT_GROUP_IMPL_HAS_BEEN_INCLUDED 19 namespace point_group_internal {
23 template<
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;
57 template <
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;
86 template <
typename Po
intDataTreeT,
typename Po
intIndexTreeT,
bool Remove>
87 struct SetGroupFromIndexOp
89 using LeafManagerT =
typename tree::LeafManager<PointDataTreeT>;
90 using LeafRangeT =
typename LeafManagerT::LeafRange;
91 using PointIndexLeafNode =
typename PointIndexTreeT::LeafNodeType;
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;
146 template <
typename Po
intDataTreeT,
typename FilterT,
typename IterT =
typename Po
intDataTreeT::LeafNodeType::ValueAllCIter>
147 struct 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;
196 const AttributeSet::Descriptor& descriptor)
198 for (
auto it = groups.begin(); it != groups.end();) {
199 if (!descriptor.hasGroup(*it)) it = groups.erase(it);
208 template <
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);
262 const size_t offset = descriptor->unusedGroupOffset();
266 descriptor->setGroup(group, offset);
272 if (hasUnusedGroup)
setGroup(tree, group,
false);
279 template <
typename Po
intDataTreeT>
281 const std::vector<Name>& groups)
286 for (
const Name& name : groups) {
295 template <
typename Po
intDataTreeT>
296 inline void dropGroup(PointDataTreeT& tree,
const Name& group,
const bool compact)
298 using Descriptor = AttributeSet::Descriptor;
304 auto iter = tree.cbeginLeaf();
308 const AttributeSet& attributeSet = iter->attributeSet();
317 descriptor->dropGroup(group);
328 template <
typename Po
intDataTreeT>
330 const std::vector<Name>& groups)
332 for (
const Name& name : groups) {
345 template <
typename Po
intDataTreeT>
348 using Descriptor = AttributeSet::Descriptor;
350 auto iter = tree.cbeginLeaf();
354 const AttributeSet& attributeSet = iter->attributeSet();
361 descriptor->clearGroups();
376 template <
typename Po
intDataTreeT>
379 using Descriptor = AttributeSet::Descriptor;
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();
393 if (!attributeSet.
descriptor().canCompactGroups())
return;
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();
427 const std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop,
437 template <
typename Po
intDataTreeT,
typename Po
intIndexTreeT>
439 const PointIndexTreeT& indexTree,
440 const std::vector<short>& membership,
444 using Descriptor = AttributeSet::Descriptor;
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) {
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);
507 template <
typename Po
intDataTreeT>
512 using Descriptor = AttributeSet::Descriptor;
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));
541 template <
typename Po
intDataTreeT,
typename FilterT>
544 const FilterT& filter)
546 using Descriptor = AttributeSet::Descriptor;
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);
576 template <
typename Po
intDataTreeT>
580 const unsigned int seed = 0)
584 RandomFilter filter(tree, targetPoints, seed);
586 setGroupByFilter<PointDataTreeT, RandomFilter>(tree, group, filter);
593 template <
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);
614 #endif // OPENVDB_POINTS_POINT_GROUP_IMPL_HAS_BEEN_INCLUDED Definition: Exceptions.h:60
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Definition: Exceptions.h:57
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
uint64_t Index64
Definition: Types.h:53
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1586
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition: PointAttributeImpl.h:238
void appendGroup(PointDataTreeT &tree, const Name &group)
Appends a new empty group to the VDB tree.
Definition: PointGroupImpl.h:209
void appendGroups(PointDataTreeT &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
Definition: PointGroupImpl.h:280
void setGroupByRandomTarget(PointDataTreeT &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition: PointGroupImpl.h:577
void setGroupByRandomPercentage(PointDataTreeT &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition: PointGroupImpl.h:594
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
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
void compactGroups(PointDataTreeT &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition: PointGroupImpl.h:377
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
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets...
Definition: AttributeSet.h:109
Definition: Exceptions.h:13
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
Definition: IndexFilter.h:229
void dropGroup(PointDataTreeT &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition: PointGroupImpl.h:296
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:484
void setGroupByFilter(PointDataTreeT &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition: PointGroupImpl.h:542
std::vector< size_t > groupAttributeIndices() const
Return the indices of the attribute arrays which are group attribute arrays.
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets...
Definition: AttributeSet.h:103
std::string Name
Definition: Name.h:19
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:39
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:819
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
std::vector< Index > IndexArray
Definition: PointMoveImpl.h:88
Definition: Exceptions.h:59
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218