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:59
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
uint64_t Index64
Definition: Types.h:53
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
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes. 
Definition: PointDataGrid.h:1586
Definition: Exceptions.h:60
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets...
Definition: AttributeSet.h:103
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree. 
Definition: PointAttributeImpl.h:238
Definition: IndexFilter.h:229
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
DescriptorPtr descriptorPtr() const 
Return a pointer to this attribute set's descriptor, which might be shared with other sets...
Definition: AttributeSet.h:109
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 setGroupByRandomPercentage(PointDataTreeT &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition: PointGroupImpl.h:594
#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
Definition: Exceptions.h:13
float Round(float x)
Return x rounded to the nearest integer. 
Definition: Math.h:819
std::vector< Index > IndexArray
Definition: PointMoveImpl.h:88
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 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 dropGroup(PointDataTreeT &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree. 
Definition: PointGroupImpl.h:296
std::vector< size_t > groupAttributeIndices() const 
Return the indices of the attribute arrays which are group attribute arrays. 
void setGroupByFilter(PointDataTreeT &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter. 
Definition: PointGroupImpl.h:542
void setGroupByRandomTarget(PointDataTreeT &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition: PointGroupImpl.h:577
std::string Name
Definition: Name.h:19
#define OPENVDB_VERSION_NAME
The version namespace name for this library version. 
Definition: version.h.in:121
Ordered collection of uniquely-named attribute arrays. 
Definition: AttributeSet.h:39
Util::GroupIndex groupIndex(const Name &groupName) const 
Return the group index from the name of the group. 
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218