OpenVDB 12.0.0
 
Loading...
Searching...
No Matches
PointDeleteImpl.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/// @author Nick Avramoussis, Francisco Gochez, Dan Bailey
5///
6/// @file PointDeleteImpl.h
7///
8
9#ifndef OPENVDB_POINTS_POINT_DELETE_IMPL_HAS_BEEN_INCLUDED
10#define OPENVDB_POINTS_POINT_DELETE_IMPL_HAS_BEEN_INCLUDED
11
12namespace openvdb {
14namespace OPENVDB_VERSION_NAME {
15namespace points {
16
17/// @cond OPENVDB_DOCS_INTERNAL
18
19namespace point_delete_internal {
20
21struct VectorWrapper
22{
23 using T = std::vector<std::pair<Index, Index>>;
24
25 VectorWrapper(const T& _data) : data(_data) { }
26 operator bool() const { return index < data.size(); }
27 VectorWrapper& operator++() { index++; return *this; }
28 Index sourceIndex() const { OPENVDB_ASSERT(*this); return data[index].first; }
29 Index targetIndex() const { OPENVDB_ASSERT(*this); return data[index].second; }
30
31private:
32 const T& data;
33 T::size_type index = 0;
34}; // struct VectorWrapper
35
36
37template <typename PointDataTreeT, typename FilterT>
38struct DeleteByFilterOp
39{
40 using LeafManagerT = tree::LeafManager<PointDataTreeT>;
41 using LeafRangeT = typename LeafManagerT::LeafRange;
42 using LeafNodeT = typename PointDataTreeT::LeafNodeType;
43 using ValueType = typename LeafNodeT::ValueType;
44
45 DeleteByFilterOp(const FilterT& filter,
46 const AttributeArray::ScopedRegistryLock* lock)
47 : mFilter(filter)
48 , mLock(lock) { }
49
50 void operator()(const LeafRangeT& range) const
51 {
52 for (auto leaf = range.begin(); leaf != range.end(); ++leaf) {
53
54 const size_t newSize =
55 iterCount(leaf->template beginIndexAll<FilterT>(mFilter));
56
57 // if all points are being deleted, clear the leaf attributes
58 if (newSize == 0) {
59 leaf->clearAttributes(/*updateValueMask=*/true, mLock);
60 continue;
61 }
62
63 // early exit if no points are being deleted
64
65 const size_t currentSize = leaf->getLastValue();
66 if (newSize == currentSize) continue;
67
68 const AttributeSet& existingAttributeSet = leaf->attributeSet();
69 AttributeSet* newAttributeSet = new AttributeSet(
70 existingAttributeSet, static_cast<Index>(newSize), mLock);
71 const size_t attributeSetSize = existingAttributeSet.size();
72
73 // cache the attribute arrays for efficiency
74
75 std::vector<AttributeArray*> newAttributeArrays;
76 std::vector<const AttributeArray*> existingAttributeArrays;
77
78 for (size_t i = 0; i < attributeSetSize; i++) {
79 AttributeArray* newArray = newAttributeSet->get(i);
80 const AttributeArray* existingArray = existingAttributeSet.getConst(i);
81
82 if (!newArray->hasConstantStride() || !existingArray->hasConstantStride()) {
83 OPENVDB_THROW(openvdb::NotImplementedError,
84 "Transfer of attribute values for dynamic arrays not currently supported.");
85 }
86
87 if (newArray->stride() != existingArray->stride()) {
88 OPENVDB_THROW(openvdb::LookupError,
89 "Cannot transfer attribute values with mis-matching strides.");
90 }
91
92 newAttributeArrays.push_back(newArray);
93 existingAttributeArrays.push_back(existingArray);
94 }
95
96 Index attributeIndex = 0;
97 std::vector<ValueType> endOffsets;
98
99 endOffsets.reserve(LeafNodeT::NUM_VALUES);
100
101 // now construct new attribute arrays which exclude data from deleted points
102
103 std::vector<std::pair<Index, Index>> indexMapping;
104 indexMapping.reserve(newSize);
105
106 for (auto voxel = leaf->cbeginValueAll(); voxel; ++voxel) {
107 for (auto iter = leaf->beginIndexVoxel(voxel.getCoord(), mFilter);
108 iter; ++iter) {
109 indexMapping.emplace_back(*iter, attributeIndex++);
110 }
111 endOffsets.push_back(static_cast<ValueType>(attributeIndex));
112 }
113
114 for (size_t i = 0; i < attributeSetSize; i++) {
115 VectorWrapper indexMappingWrapper(indexMapping);
116 newAttributeArrays[i]->copyValues(*(existingAttributeArrays[i]), indexMappingWrapper);
117 }
118
119 leaf->replaceAttributeSet(newAttributeSet);
120 leaf->setOffsets(endOffsets);
121 }
122 }
123
124private:
125 const FilterT& mFilter;
126 const AttributeArray::ScopedRegistryLock* mLock;
127}; // struct DeleteByFilterOp
128
129} // namespace point_delete_internal
130
131/// @endcond
132
133////////////////////////////////////////
134
135template <typename PointDataTreeT>
136inline void deleteFromGroups(PointDataTreeT& pointTree,
137 const std::vector<std::string>& groups,
138 bool invert,
139 bool drop)
140{
141 const typename PointDataTreeT::LeafCIter leafIter = pointTree.cbeginLeaf();
142
143 if (!leafIter) return;
144
145 const openvdb::points::AttributeSet& attributeSet = leafIter->attributeSet();
146 const AttributeSet::Descriptor& descriptor = attributeSet.descriptor();
147 std::vector<std::string> availableGroups;
148
149 // determine which of the requested groups exist, and early exit
150 // if none are present in the tree
151
152 for (const auto& groupName : groups) {
153 if (descriptor.hasGroup(groupName)) {
154 availableGroups.push_back(groupName);
155 }
156 }
157
158 if (availableGroups.empty()) return;
159
160 std::vector<std::string> empty;
161 std::unique_ptr<MultiGroupFilter> filter;
162 if (invert) {
163 filter.reset(new MultiGroupFilter(groups, empty, leafIter->attributeSet()));
164 }
165 else {
166 filter.reset(new MultiGroupFilter(empty, groups, leafIter->attributeSet()));
167 }
168
169 { // acquire registry lock to avoid locking when appending attributes in parallel
170
172
173 tree::LeafManager<PointDataTreeT> leafManager(pointTree);
174 point_delete_internal::DeleteByFilterOp<PointDataTreeT, MultiGroupFilter> deleteOp(
175 *filter, &lock);
176 tbb::parallel_for(leafManager.leafRange(), deleteOp);
177 }
178
179 // remove empty leaf nodes
180
181 tools::pruneInactive(pointTree);
182
183 // drop the now-empty groups if requested (unless invert = true)
184
185 if (drop && !invert) {
186 dropGroups(pointTree, availableGroups);
187 }
188}
189
190template <typename PointDataTreeT>
191inline void deleteFromGroup(PointDataTreeT& pointTree,
192 const std::string& group,
193 bool invert,
194 bool drop)
195{
196 std::vector<std::string> groups(1, group);
197
198 deleteFromGroups(pointTree, groups, invert, drop);
199}
200
201
202////////////////////////////////////////
203
204
205} // namespace points
206} // namespace OPENVDB_VERSION_NAME
207} // namespace openvdb
208
209#endif // OPENVDB_POINTS_POINT_DELETE_IMPL_HAS_BEEN_INCLUDED
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
An immutable object that stores name, type and AttributeSet position for a constant collection of att...
Definition AttributeSet.h:311
bool hasGroup(const Name &group) const
Return true if group exists.
Definition IndexFilter.h:139
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:86
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition LeafManager.h:346
@ AttributeArray
Definition NanoVDB.h:418
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 deleteFromGroups(PointDataTreeT &pointTree, const std::vector< std::string > &groups, bool invert=false, bool drop=true)
Delete points that are members of specific groups.
Definition PointDeleteImpl.h:136
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition IndexIterator.h:315
void deleteFromGroup(PointDataTreeT &pointTree, const std::string &group, bool invert=false, bool drop=true)
Delete points that are members of a group.
Definition PointDeleteImpl.h:191
OutGridT const XformOp bool bool
Definition ValueTransformer.h:610
void pruneInactive(TreeT &tree, bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing with background tiles any nodes whose values are a...
Definition Prune.h:355
Index32 Index
Definition Types.h:54
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