Go to the documentation of this file.
37 #ifndef OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
49 #include <tbb/parallel_reduce.h>
66 const AttributeSet::Descriptor& descriptor);
72 template <
typename Po
intDataTree>
80 template <
typename Po
intDataTree>
82 const std::vector<Name>& groups);
90 template <
typename Po
intDataTree>
93 const bool compact =
true);
99 template <
typename Po
intDataTree>
101 const std::vector<Name>& groups);
106 template <
typename Po
intDataTree>
112 template <
typename Po
intDataTree>
124 template <
typename Po
intDataTree,
typename Po
intIndexTree>
127 const std::vector<short>& membership,
129 const bool remove =
false);
136 template <
typename Po
intDataTree>
139 const bool member =
true);
146 template <
typename Po
intDataTree,
typename FilterT>
149 const FilterT& filter);
155 namespace point_group_internal {
159 template<
typename Po
intDataTreeType>
168 : mTargetIndex(targetIndex)
169 , mSourceIndex(sourceIndex) { }
171 void operator()(
const typename LeafManagerT::LeafRange& range)
const {
173 for (
auto leaf = range.begin(); leaf; ++leaf) {
175 GroupHandle sourceGroup = leaf->groupHandle(mSourceIndex);
178 for (
auto iter = leaf->beginIndexAll(); iter; ++iter) {
179 const bool groupOn = sourceGroup.
get(*iter);
180 targetGroup.
set(*iter, groupOn);
193 template <
typename Po
intDataTree,
bool Member>
199 SetGroupOp(
const AttributeSet::Descriptor::GroupIndex& index)
202 void operator()(
const typename LeafManagerT::LeafRange& range)
const
204 for (
auto leaf = range.begin(); leaf; ++leaf) {
222 template <
typename Po
intDataTree,
typename Po
intIndexTree,
bool Remove>
235 : mIndexTree(indexTree)
236 , mMembership(membership)
239 void operator()(
const typename LeafManagerT::LeafRange& range)
const
241 for (
auto leaf = range.begin(); leaf; ++leaf) {
247 if (!pointIndexLeaf)
continue;
257 const IndexArray& indices = pointIndexLeaf->indices();
259 for (
const Index64 i: indices) {
261 group.
set(
static_cast<Index>(index), mMembership[i]);
262 }
else if (mMembership[i] ==
short(1)) {
263 group.
set(
static_cast<Index>(index),
short(1));
282 template <
typename Po
intDataTree,
typename FilterT,
typename IterT =
typename Po
intDataTree::LeafNodeType::ValueAllCIter>
292 , mFilter(filter) { }
294 void operator()(
const typename LeafManagerT::LeafRange& range)
const
296 for (
auto leaf = range.begin(); leaf; ++leaf) {
302 auto iter = leaf->template beginIndex<IterT, FilterT>(mFilter);
304 for (; iter; ++iter) {
305 group.
set(*iter,
true);
331 : mAttributeSet(attributeSet) { }
340 const Descriptor& descriptor = mAttributeSet.descriptor();
344 const size_t groupAttributes = descriptor.count(GroupAttributeArray::attributeType());
346 if (groupAttributes == 0)
return 0;
348 const size_t totalSlots = groupAttributes * this->groupBits();
352 const AttributeSet::Descriptor::NameToPosMap& groupMap = mAttributeSet.descriptor().groupMap();
353 const size_t usedSlots = groupMap.size();
355 return totalSlots - usedSlots;
363 return this->unusedGroups() >= this->groupBits();
369 const Descriptor::NameToPosMap& groupMap = mAttributeSet.descriptor().groupMap();
373 std::vector<size_t> indices;
374 indices.reserve(groupMap.size());
375 for (
const auto& namePos : groupMap) {
376 indices.push_back(namePos.second);
379 std::sort(indices.begin(), indices.end());
384 for (
const size_t& index : indices) {
385 if (index != offset)
break;
395 std::vector<size_t> indices;
397 const Descriptor::NameToPosMap& map = mAttributeSet.descriptor().map();
399 for (
const auto& namePos : map) {
400 const AttributeArray* array = mAttributeSet.getConst(namePos.first);
402 indices.push_back(namePos.second);
413 targetOffset = this->nextUnusedOffset();
415 const Descriptor::NameToPosMap& groupMap = mAttributeSet.descriptor().groupMap();
417 for (
const auto& namePos : groupMap) {
421 if (namePos.second >= targetOffset) {
422 sourceName = namePos.first;
423 sourceOffset = namePos.second;
443 const AttributeSet::Descriptor& descriptor)
445 for (
auto it = groups.begin(); it != groups.end();) {
446 if (!descriptor.hasGroup(*it)) it = groups.erase(it);
455 template <
typename Po
intDataTreeT>
464 auto iter = tree.cbeginLeaf();
468 const AttributeSet& attributeSet = iter->attributeSet();
470 GroupInfo groupInfo(attributeSet);
474 if (descriptor->hasGroup(group))
return;
476 const bool hasUnusedGroup = groupInfo.unusedGroups() > 0;
480 if (!hasUnusedGroup) {
484 const Name groupName = descriptor->uniqueName(
"__group");
486 descriptor = descriptor->duplicateAppend(groupName, GroupAttributeArray::attributeType());
487 const size_t pos = descriptor->find(groupName);
493 [&](
typename PointDataTreeT::LeafNodeType& leaf,
size_t ) {
494 auto expected = leaf.attributeSet().descriptorPtr();
495 leaf.appendAttribute(*expected, descriptor, pos);
508 assert(groupInfo.unusedGroups() > 0);
512 const size_t offset = groupInfo.nextUnusedOffset();
516 descriptor->setGroup(group, offset);
522 if (hasUnusedGroup)
setGroup(tree, group,
false);
529 template <
typename Po
intDataTree>
531 const std::vector<Name>& groups)
536 for (
const Name& name : groups) {
545 template <
typename Po
intDataTree>
548 using Descriptor = AttributeSet::Descriptor;
558 const AttributeSet& attributeSet = iter->attributeSet();
567 descriptor->dropGroup(group);
578 template <
typename Po
intDataTree>
580 const std::vector<Name>& groups)
582 for (
const Name& name : groups) {
595 template <
typename Po
intDataTree>
598 using Descriptor = AttributeSet::Descriptor;
606 const AttributeSet& attributeSet = iter->attributeSet();
607 GroupInfo groupInfo(attributeSet);
614 descriptor->clearGroups();
618 std::vector<size_t> indices = groupInfo.populateGroupIndices();
629 template <
typename Po
intDataTree>
632 using Descriptor = AttributeSet::Descriptor;
633 using GroupIndex = Descriptor::GroupIndex;
634 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
643 const AttributeSet& attributeSet = iter->attributeSet();
644 GroupInfo groupInfo(attributeSet);
648 if (!groupInfo.canCompactGroups())
return;
660 size_t sourceOffset, targetOffset;
662 while (groupInfo.requiresMove(sourceName, sourceOffset, targetOffset)) {
664 const GroupIndex sourceIndex = attributeSet.
groupIndex(sourceOffset);
665 const GroupIndex targetIndex = attributeSet.
groupIndex(targetOffset);
667 CopyGroupOp<PointDataTree> copy(targetIndex, sourceIndex);
668 LeafManagerT leafManager(tree);
669 tbb::parallel_for(leafManager.leafRange(), copy);
671 descriptor->setGroup(sourceName, targetOffset);
676 std::vector<size_t> indices = groupInfo.populateGroupIndices();
678 const size_t totalAttributesToDrop = groupInfo.unusedGroups() / groupInfo.groupBits();
680 assert(totalAttributesToDrop <= indices.size());
682 std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop, indices.end());
691 template <
typename Po
intDataTree,
typename Po
intIndexTree>
694 const std::vector<short>& membership,
698 using Descriptor = AttributeSet::Descriptor;
699 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
705 const AttributeSet& attributeSet = iter->attributeSet();
706 const Descriptor& descriptor = attributeSet.
descriptor();
708 if (!descriptor.hasGroup(group)) {
719 IndexTreeManager leafManager(indexTree);
721 const int64_t
max = tbb::parallel_reduce(leafManager.leafRange(), -1,
722 [](
const typename IndexTreeManager::LeafRange& range, int64_t value) -> int64_t {
723 for (auto leaf = range.begin(); leaf; ++leaf) {
724 auto it = std::max_element(leaf->indices().begin(), leaf->indices().end());
725 value = std::max(value, static_cast<int64_t>(*it));
729 [](
const int64_t a,
const int64_t b) {
734 if (
max != -1 && membership.size() <=
static_cast<size_t>(
max)) {
736 " the maximum index within the provided index tree.");
740 const Descriptor::GroupIndex index = attributeSet.groupIndex(group);
741 LeafManagerT leafManager(tree);
746 SetGroupFromIndexOp<PointDataTree, PointIndexTree, true>
747 set(indexTree, membership, index);
748 tbb::parallel_for(leafManager.leafRange(), set);
751 SetGroupFromIndexOp<PointDataTree, PointIndexTree, false>
752 set(indexTree, membership, index);
753 tbb::parallel_for(leafManager.leafRange(), set);
761 template <
typename Po
intDataTree>
766 using Descriptor = AttributeSet::Descriptor;
767 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
775 const AttributeSet& attributeSet = iter->attributeSet();
776 const Descriptor& descriptor = attributeSet.
descriptor();
778 if (!descriptor.hasGroup(group)) {
782 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
783 LeafManagerT leafManager(tree);
787 if (member) tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, true>(index));
788 else tbb::parallel_for(leafManager.leafRange(), SetGroupOp<PointDataTree, false>(index));
795 template <
typename Po
intDataTree,
typename FilterT>
798 const FilterT& filter)
800 using Descriptor = AttributeSet::Descriptor;
801 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
809 const AttributeSet& attributeSet = iter->attributeSet();
810 const Descriptor& descriptor = attributeSet.
descriptor();
812 if (!descriptor.hasGroup(group)) {
816 const Descriptor::GroupIndex index = attributeSet.
groupIndex(group);
820 SetGroupByFilterOp<PointDataTree, FilterT> set(index, filter);
821 LeafManagerT leafManager(tree);
823 tbb::parallel_for(leafManager.leafRange(), set);
830 template <
typename Po
intDataTree>
834 const unsigned int seed = 0)
838 RandomFilter filter(tree, targetPoints, seed);
840 setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
847 template <
typename Po
intDataTree>
850 const float percentage = 10.0f,
851 const unsigned int seed = 0)
855 const int currentPoints =
static_cast<int>(
pointCount(tree));
856 const int targetPoints = int(
math::Round((percentage *
float(currentPoints))/100.0f));
858 RandomFilter filter(tree, targetPoints, seed);
860 setGroupByFilter<PointDataTree, RandomFilter>(tree, group, filter);
872 #endif // OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
Set of Attribute Arrays which tracks metadata about each array.
typename PointDataTree::LeafNodeType LeafNodeT
Definition: PointGroup.h:287
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:286
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:239
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:793
std::string Name
Definition: Name.h:44
void appendGroups(PointDataTree &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
Definition: PointGroup.h:530
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:285
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:225
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:197
Definition: AttributeGroup.h:130
const GroupIndex mTargetIndex
Definition: PointGroup.h:187
Definition: AttributeGroup.h:102
std::vector< Index > IndexArray
Definition: PointMove.h:188
const GroupIndex & mIndex
Definition: PointGroup.h:278
typename PointIndexTree::LeafNodeType PointIndexLeafNode
Definition: PointGroup.h:227
const FilterT & mFilter
Definition: PointGroup.h:317
Definition: PointGroup.h:283
typename PointIndexLeafNode::IndexArray IndexArray
Definition: PointGroup.h:228
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1618
Copy a group attribute value from one group offset to another.
Definition: PointGroup.h:160
Methods for counting points in VDB Point grids.
Definition: Exceptions.h:84
uint8_t GroupType
Definition: AttributeGroup.h:50
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:62
std::vector< short > MembershipArray
Definition: PointGroup.h:230
Index32 Index
Definition: Types.h:61
void dropGroup(PointDataTree &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition: PointGroup.h:546
size_t unusedGroups() const
Definition: PointGroup.h:338
Index filters primarily designed to be used with a FilterIndexIter.
bool compact()
Compact the existing array to become uniform if all values are identical.
GroupInfo(const AttributeSet &attributeSet)
Definition: PointGroup.h:330
bool isGroup(const AttributeArray &array)
Definition: AttributeGroup.h:93
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:125
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:226
void setGroupByFilter(PointDataTree &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition: PointGroup.h:796
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:762
tree::Tree< tree::RootNode< tree::InternalNode< tree::InternalNode< PointDataLeafNode< PointDataIndex32, 3 >, 4 >, 5 > >> PointDataTree
Point index tree configured to match the default VDB configurations.
Definition: PointDataGrid.h:216
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:164
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:212
const GroupIndex & mIndex
Definition: PointGroup.h:218
static size_t groupBits()
Return the number of bits in a group (typically 8)
Definition: PointGroup.h:334
Definition: Exceptions.h:87
bool canCompactGroups() const
Return true if there are sufficient empty slots to allow compacting.
Definition: PointGroup.h:359
Point attribute manipulation in a VDB Point Grid.
void deleteMissingPointGroups(std::vector< std::string > &groups, const AttributeSet::Descriptor &descriptor)
Delete any group that is not present in the Descriptor.
Definition: PointGroup.h:442
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
void setGroupByRandomTarget(PointDataTree &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition: PointGroup.h:831
const GroupIndex & mIndex
Definition: PointGroup.h:316
std::vector< size_t > populateGroupIndices() const
Return vector of indices correlating to the group attribute arrays.
Definition: PointGroup.h:393
SetGroupOp(const AttributeSet::Descriptor::GroupIndex &index)
Definition: PointGroup.h:199
void compactGroups(PointDataTree &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition: PointGroup.h:630
typename tree::LeafManager< PointDataTreeType > LeafManagerT
Definition: PointGroup.h:162
Set membership on or off for the specified group.
Definition: PointGroup.h:194
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:115
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointGroup.h:163
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:109
void setGroupByRandomPercentage(PointDataTree &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition: PointGroup.h:848
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:180
const PointIndexTree & mIndexTree
Definition: PointGroup.h:276
Convenience class with methods for analyzing group data.
Definition: PointGroup.h:325
uint64_t Index64
Definition: Types.h:60
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:171
SetGroupByFilterOp(const GroupIndex &index, const FilterT &filter)
Definition: PointGroup.h:290
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:288
Base class for storing attribute data.
Definition: AttributeArray.h:118
void dropGroups(PointDataTree &tree)
Drops all existing groups from the VDB tree, the tree is compacted after dropping.
Definition: PointGroup.h:596
void set(Index n, bool on)
void appendGroup(PointDataTreeT &tree, const Name &group)
Definition: PointGroup.h:456
AttributeSet::Descriptor::GroupIndex GroupIndex
Definition: PointGroup.h:229
typename tree::LeafManager< PointDataTree > LeafManagerT
Definition: PointGroup.h:196
bool collapse(bool on)
Set membership for the whole array and attempt to collapse.
#define OPENVDB_VERSION_NAME
Definition: version.h:134
Definition: PointGroup.h:223
bool requiresMove(Name &sourceName, size_t &sourceOffset, size_t &targetOffset) const
Definition: PointGroup.h:411
Definition: IndexFilter.h:255
const GroupIndex mSourceIndex
Definition: PointGroup.h:188
const MembershipArray & mMembership
Definition: PointGroup.h:277
Definition: Exceptions.h:86
Definition: Exceptions.h:40
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:202
size_t nextUnusedOffset() const
Return the next empty group slot.
Definition: PointGroup.h:367
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointGroup.h:294
AttributeSet::Descriptor Descriptor
Definition: PointGroup.h:328
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:523
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:131
LeafCIter cbeginLeaf() const
Definition: Tree.h:1181
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
CopyGroupOp(const GroupIndex &targetIndex, const GroupIndex &sourceIndex)
Definition: PointGroup.h:166
SetGroupFromIndexOp(const PointIndexTree &indexTree, const MembershipArray &membership, const GroupIndex &index)
Definition: PointGroup.h:232
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:397