10 #ifndef OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
22 #include <tbb/parallel_reduce.h>
45 template <
typename Po
intDataTree>
53 template <
typename Po
intDataTree>
55 const std::vector<Name>&
groups);
63 template <
typename Po
intDataTree>
66 const bool compact =
true);
72 template <
typename Po
intDataTree>
74 const std::vector<Name>&
groups);
79 template <
typename Po
intDataTree>
85 template <
typename Po
intDataTree>
97 template <
typename Po
intDataTree,
typename Po
intIndexTree>
100 const std::vector<short>& membership,
102 const bool remove =
false);
109 template <
typename Po
intDataTree>
112 const bool member =
true);
119 template <
typename Po
intDataTree,
typename FilterT>
128 namespace point_group_internal {
132 template<
typename Po
intDataTreeType>
146 for (
auto leaf = range.begin(); leaf; ++leaf) {
151 for (
auto iter = leaf->beginIndexAll(); iter; ++iter) {
152 const bool groupOn = sourceGroup.
get(*iter);
153 targetGroup.
set(*iter, groupOn);
166 template <
typename Po
intDataTree,
bool Member>
177 for (
auto leaf = range.begin(); leaf; ++leaf) {
185 group.collapse(Member);
195 template <
typename Po
intDataTree,
typename Po
intIndexTree,
bool Remove>
214 for (
auto leaf = range.begin(); leaf; ++leaf) {
220 if (!pointIndexLeaf)
continue;
232 for (
const Index64 i: indices) {
236 group.set(static_cast<Index>(index),
short(1));
255 template <
typename Po
intDataTree,
typename FilterT,
typename IterT =
typename Po
intDataTree::LeafNodeType::ValueAllCIter>
269 for (
auto leaf = range.begin(); leaf; ++leaf) {
275 auto iter = leaf->template beginIndex<IterT, FilterT>(
mFilter);
277 for (; iter; ++iter) {
278 group.set(*iter,
true);
306 for (
auto it = groups.begin(); it != groups.end();) {
307 if (!descriptor.hasGroup(*it)) it = groups.erase(it);
316 template <
typename Po
intDataTreeT>
320 OPENVDB_THROW(KeyError,
"Cannot use an empty group name as a key.");
323 auto iter = tree.cbeginLeaf();
327 const AttributeSet& attributeSet = iter->attributeSet();
332 if (descriptor->hasGroup(group))
return;
334 const bool hasUnusedGroup = descriptor->unusedGroups() > 0;
338 if (!hasUnusedGroup) {
342 const Name groupName = descriptor->uniqueName(
"__group");
344 descriptor = descriptor->duplicateAppend(groupName, GroupAttributeArray::attributeType());
345 const size_t pos = descriptor->find(groupName);
351 [&](
typename PointDataTreeT::LeafNodeType& leaf,
size_t ) {
352 auto expected = leaf.attributeSet().descriptorPtr();
353 leaf.appendAttribute(*expected, descriptor, pos);
366 assert(descriptor->unusedGroups() > 0);
370 const size_t offset = descriptor->unusedGroupOffset();
374 descriptor->setGroup(group, offset);
380 if (hasUnusedGroup)
setGroup(tree, group,
false);
387 template <
typename Po
intDataTree>
389 const std::vector<Name>&
groups)
403 template <
typename Po
intDataTree>
409 OPENVDB_THROW(KeyError,
"Cannot use an empty group name as a key.");
416 const AttributeSet& attributeSet = iter->attributeSet();
425 descriptor->dropGroup(group);
436 template <
typename Po
intDataTree>
438 const std::vector<Name>&
groups)
453 template <
typename Po
intDataTree>
462 const AttributeSet& attributeSet = iter->attributeSet();
469 descriptor->clearGroups();
484 template <
typename Po
intDataTree>
488 using GroupIndex = Descriptor::GroupIndex;
489 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
497 const AttributeSet& attributeSet = iter->attributeSet();
501 if (!attributeSet.
descriptor().canCompactGroups())
return;
513 size_t sourceOffset, targetOffset;
515 while (descriptor->requiresGroupMove(sourceName, sourceOffset, targetOffset)) {
517 const GroupIndex sourceIndex = attributeSet.
groupIndex(sourceOffset);
518 const GroupIndex targetIndex = attributeSet.
groupIndex(targetOffset);
520 CopyGroupOp<PointDataTree>
copy(targetIndex, sourceIndex);
521 LeafManagerT leafManager(tree);
524 descriptor->setGroup(sourceName, targetOffset);
531 const size_t totalAttributesToDrop = descriptor->unusedGroups() / descriptor->groupBits();
533 assert(totalAttributesToDrop <= indices.size());
535 const std::vector<size_t> indicesToDrop(indices.end() - totalAttributesToDrop,
545 template <
typename Po
intDataTree,
typename Po
intIndexTree>
548 const std::vector<short>& membership,
553 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
559 const AttributeSet& attributeSet = iter->attributeSet();
560 const Descriptor& descriptor = attributeSet.
descriptor();
562 if (!descriptor.hasGroup(group)) {
563 OPENVDB_THROW(LookupError,
"Group must exist on Tree before defining membership.");
573 IndexTreeManager leafManager(indexTree);
575 const int64_t
max = tbb::parallel_reduce(leafManager.leafRange(), -1,
576 [](
const typename IndexTreeManager::LeafRange&
range, int64_t
value) -> int64_t {
577 for (
auto leaf = range.begin(); leaf; ++leaf) {
578 auto it = std::max_element(leaf->indices().begin(), leaf->indices().end());
583 [](
const int64_t
a,
const int64_t
b) {
588 if (max != -1 && membership.size() <=
static_cast<size_t>(
max)) {
589 OPENVDB_THROW(IndexError,
"Group membership vector size must be larger than "
590 " the maximum index within the provided index tree.");
595 LeafManagerT leafManager(tree);
600 SetGroupFromIndexOp<PointDataTree, PointIndexTree, true>
601 set(indexTree, membership, index);
605 SetGroupFromIndexOp<PointDataTree, PointIndexTree, false>
606 set(indexTree, membership, index);
615 template <
typename Po
intDataTree>
621 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
629 const AttributeSet& attributeSet = iter->attributeSet();
630 const Descriptor& descriptor = attributeSet.
descriptor();
632 if (!descriptor.hasGroup(group)) {
633 OPENVDB_THROW(LookupError,
"Group must exist on Tree before defining membership.");
637 LeafManagerT leafManager(tree);
649 template <
typename Po
intDataTree,
typename FilterT>
655 using LeafManagerT =
typename tree::template LeafManager<PointDataTree>;
663 const AttributeSet& attributeSet = iter->attributeSet();
664 const Descriptor& descriptor = attributeSet.
descriptor();
666 if (!descriptor.hasGroup(group)) {
667 OPENVDB_THROW(LookupError,
"Group must exist on Tree before defining membership.");
674 SetGroupByFilterOp<PointDataTree, FilterT> set(index, filter);
675 LeafManagerT leafManager(tree);
684 template <
typename Po
intDataTree>
688 const unsigned int seed = 0)
692 RandomFilter
filter(tree, targetPoints, seed);
694 setGroupByFilter<PointDataTree, RandomFilter>(tree,
group,
filter);
701 template <
typename Po
intDataTree>
704 const float percentage = 10.0
f,
705 const unsigned int seed = 0)
709 const int currentPoints =
static_cast<int>(
pointCount(tree));
710 const int targetPoints =
int(
math::Round((percentage *
float(currentPoints))/100.0
f));
712 RandomFilter
filter(tree, targetPoints, seed);
714 setGroupByFilter<PointDataTree, RandomFilter>(tree,
group,
filter);
726 #endif // OPENVDB_POINTS_POINT_GROUP_HAS_BEEN_INCLUDED
CopyGroupOp(const GroupIndex &targetIndex, const GroupIndex &sourceIndex)
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
vint4 max(const vint4 &a, const vint4 &b)
SetGroupFromIndexOp(const PointIndexTree &indexTree, const MembershipArray &membership, const GroupIndex &index)
void parallel_for(int64_t start, int64_t end, std::function< void(int64_t index)> &&task, parallel_options opt=parallel_options(0, Split_Y, 1))
typename PointIndexTree::LeafNodeType PointIndexLeafNode
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets...
Util::GroupIndex groupIndex(const Name &groupName) const
Return the group index from the name of the group.
AttributeSet::Descriptor::GroupIndex GroupIndex
GLuint const GLchar * name
void dropGroup(PointDataTree &tree, const Name &group, const bool compact=true)
Drops an existing group from the VDB tree.
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
AttributeSet::Descriptor::GroupIndex GroupIndex
SetGroupByFilterOp(const GroupIndex &index, const FilterT &filter)
AttributeSet::Descriptor::GroupIndex GroupIndex
GLboolean GLboolean GLboolean GLboolean a
Copy a group attribute value from one group offset to another.
#define OPENVDB_USE_VERSION_NAMESPACE
Index filters primarily designed to be used with a FilterIndexIter.
const GroupIndex mSourceIndex
const GroupIndex & mIndex
void setGroupByRandomTarget(PointDataTree &tree, const Name &group, const Index64 targetPoints, const unsigned int seed=0)
Set membership on or off for the specified group.
void setGroupByRandomPercentage(PointDataTree &tree, const Name &group, const float percentage=10.0f, const unsigned int seed=0)
AttributeSet::Descriptor::GroupIndex GroupIndex
void operator()(const typename LeafManagerT::LeafRange &range) const
typename LeafManagerT::LeafRange LeafRangeT
typename tree::LeafManager< PointDataTree > LeafManagerT
void deleteMissingPointGroups(std::vector< std::string > &groups, const AttributeSet::Descriptor &descriptor)
Delete any group that is not present in the Descriptor.
std::vector< Index > IndexArray
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
std::vector< size_t > groupAttributeIndices() const
Return the indices of the attribute arrays which are group attribute arrays.
Methods for counting points in VDB Point grids.
const MembershipArray & mMembership
float Round(float x)
Return x rounded to the nearest integer.
void appendGroups(PointDataTree &tree, const std::vector< Name > &groups)
Appends new empty groups to the VDB tree.
void operator()(const typename LeafManagerT::LeafRange &range) const
GLuint GLuint GLsizei GLenum const void * indices
const PointIndexTree & mIndexTree
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
typename tree::LeafManager< PointDataTree > LeafManagerT
typename LeafManagerT::LeafRange LeafRangeT
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
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.
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.
typename tree::LeafManager< PointDataTree > LeafManagerT
void operator()(const typename LeafManagerT::LeafRange &range) const
Point attribute manipulation in a VDB Point Grid.
std::vector< short > MembershipArray
GLdouble GLdouble GLdouble b
typename PointDataTree::LeafNodeType LeafNodeT
const GroupIndex & mIndex
typename tree::LeafManager< PointDataTreeType > LeafManagerT
typename RootNodeType::LeafNodeType LeafNodeType
const GroupIndex & mIndex
Set of Attribute Arrays which tracks metadata about each array.
SetGroupOp(const AttributeSet::Descriptor::GroupIndex &index)
void operator()(const typename LeafManagerT::LeafRange &range) const
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
OIIO_API bool copy(string_view from, string_view to, std::string &err)
void dropGroups(PointDataTree &tree, const std::vector< Name > &groups)
Drops existing groups from the VDB tree, the tree is compacted after dropping.
void setGroup(PointDataTree &tree, const PointIndexTree &indexTree, const std::vector< short > &membership, const Name &group, const bool remove=false)
Sets group membership from a PointIndexTree-ordered vector.
Ordered collection of uniquely-named attribute arrays.
void set(Index n, bool on)
Set on at the given index n.
void appendGroup(PointDataTree &tree, const Name &group)
Appends a new empty group to the VDB tree.
tree::Tree< tree::RootNode< tree::InternalNode< tree::InternalNode< PointDataLeafNode< PointDataIndex32, 3 >, 4 >, 5 >>> PointDataTree
Point index tree configured to match the default VDB configurations.
typename PointIndexLeafNode::IndexArray IndexArray
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
GLsizei const GLfloat * value
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets...
#define OPENVDB_THROW(exception, message)
typename LeafManagerT::LeafRange LeafRangeT
void compactGroups(PointDataTree &tree)
Compacts existing groups of a VDB Tree to use less memory if possible.
const GroupIndex mTargetIndex
void setGroupByFilter(PointDataTree &tree, const Name &group, const FilterT &filter)
Sets group membership based on a provided filter.