9#ifndef OPENVDB_POINTS_POINT_GROUP_IMPL_HAS_BEEN_INCLUDED 
   10#define OPENVDB_POINTS_POINT_GROUP_IMPL_HAS_BEEN_INCLUDED 
   19namespace point_group_internal {
 
   23template<
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;
 
   57template <
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;
 
   86template <
typename Po
intDataTreeT, 
typename Po
intIndexTreeT, 
bool Remove>
 
   87struct SetGroupFromIndexOp
 
   89    using LeafManagerT          = 
typename tree::LeafManager<PointDataTreeT>;
 
   90    using LeafRangeT            = 
typename LeafManagerT::LeafRange;
 
   91    using PointIndexLeafNode    = 
typename PointIndexTreeT::LeafNodeType;
 
   92    using IndexArray            = 
typename PointIndexLeafNode::IndexArray;
 
   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;
 
  146template <
typename Po
intDataTreeT, 
typename FilterT, 
typename IterT = 
typename Po
intDataTreeT::LeafNodeType::ValueAllCIter>
 
  147struct 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; 
 
  198    for (
auto it = groups.begin(); it != groups.end();) {
 
  199        if (!descriptor.
hasGroup(*it))  it = groups.erase(it);
 
 
  208template <
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");
 
  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);
 
 
  279template <
typename Po
intDataTreeT>
 
  281                         const std::vector<Name>& groups)
 
  286    for (
const Name& name : groups) {
 
 
  295template <
typename Po
intDataTreeT>
 
  304    auto iter = 
tree.cbeginLeaf();
 
  308    const AttributeSet& attributeSet = iter->attributeSet();
 
  317    descriptor->dropGroup(group);
 
 
  328template <
typename Po
intDataTreeT>
 
  330                        const std::vector<Name>& groups)
 
  332    for (
const Name& name : groups) {
 
 
  345template <
typename Po
intDataTreeT>
 
  350    auto iter = 
tree.cbeginLeaf();
 
  354    const AttributeSet& attributeSet = iter->attributeSet();
 
  361    descriptor->clearGroups();
 
 
  376template <
typename Po
intDataTreeT>
 
  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();
 
  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,
 
 
  437template <
typename Po
intDataTreeT, 
typename Po
intIndexTreeT>
 
  439                        const PointIndexTreeT& indexTree,
 
  440                        const std::vector<short>& membership,
 
  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) {
 
  476                return std::max(a, 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);
 
 
  507template <
typename Po
intDataTreeT>
 
  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)) {
 
  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));
 
 
  541template <
typename Po
intDataTreeT, 
typename FilterT>
 
  544                                const FilterT& filter)
 
  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)) {
 
  566    SetGroupByFilterOp<PointDataTreeT, FilterT> set(
index, filter);
 
  567    LeafManagerT leafManager(
tree);
 
  569    tbb::parallel_for(leafManager.leafRange(), set);
 
 
  576template <
typename Po
intDataTreeT>
 
  580                                    const unsigned int seed = 0)
 
  584    RandomFilter filter(
tree, targetPoints, seed);
 
 
  593template <
typename Po
intDataTreeT>
 
  596                                        const float percentage = 10.0f,
 
  597                                        const unsigned int seed = 0)
 
  602    const int targetPoints = int(
math::Round((percentage * 
float(currentPoints))/100.0f));
 
  604    RandomFilter filter(
tree, targetPoints, seed);
 
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Definition Exceptions.h:57
Definition Exceptions.h:59
Definition Exceptions.h:60
An immutable object that stores name, type and AttributeSet position for a constant collection of att...
Definition AttributeSet.h:311
bool canCompactGroups() const
Return true if there are sufficient empty slots to allow compacting.
GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
bool hasGroup(const Name &group) const
Return true if group exists.
Ordered collection of uniquely-named attribute arrays.
Definition AttributeSet.h:40
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets.
Definition AttributeSet.h:109
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets.
Definition AttributeSet.h:103
std::vector< size_t > groupAttributeIndices() const
Return the indices of the attribute arrays which are group attribute arrays.
Definition IndexFilter.h:230
static const NamePair & attributeType()
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:86
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
float Round(float x)
Return x rounded to the nearest integer.
Definition Math.h:819
Definition IndexIterator.h:35
std::vector< Index > IndexArray
Definition PointMoveImpl.h:88
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 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 setGroupByRandomPercentage(PointDataTreeT &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
Definition PointGroupImpl.h:594
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
void compactGroups(PointDataTreeT &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
Definition PointGroupImpl.h:377
void appendGroup(PointDataTreeT &tree, const Name &group)
Appends a new empty group to the VDB tree.
Definition PointGroupImpl.h:209
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
void setGroupByRandomTarget(PointDataTreeT &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Definition PointGroupImpl.h:577
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition PointAttributeImpl.h:238
void appendGroups(PointDataTreeT &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
Definition PointGroupImpl.h:280
void setGroupByFilter(PointDataTreeT &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.
Definition PointGroupImpl.h:542
void dropGroup(PointDataTreeT &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
Definition PointGroupImpl.h:296
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition PointDataGrid.h:1586
Definition PointDataGrid.h:170
std::string Name
Definition Name.h:19
Index32 Index
Definition Types.h:54
uint64_t Index64
Definition Types.h:53
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218