OpenVDB 7.0.0

PointDelete.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
9
10 #ifndef OPENVDB_POINTS_POINT_DELETE_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_POINT_DELETE_HAS_BEEN_INCLUDED
12
13 #include "PointDataGrid.h"
14 #include "PointGroup.h"
15 #include "IndexIterator.h"
16 #include "IndexFilter.h"
17
18 #include <openvdb/tools/Prune.h>
19 #include <openvdb/tree/LeafManager.h>
20
21 #include <memory>
22 #include <string>
23 #include <vector>
24
25
26 namespace openvdb {
27 OPENVDB_USE_VERSION_NAMESPACE
28 namespace OPENVDB_VERSION_NAME {
29 namespace points {
30
31
45
46 template <typename PointDataTreeT>
47 inline void deleteFromGroups(PointDataTreeT& pointTree,
48 const std::vector<std::string>& groups,
49 bool invert = false,
50 bool drop = true);
51
65
66 template <typename PointDataTreeT>
67 inline void deleteFromGroup(PointDataTreeT& pointTree,
68 const std::string& group,
69 bool invert = false,
70 bool drop = true);
71
72
74
75
76 namespace point_delete_internal {
77
78
79 struct VectorWrapper
80 {
81 using T = std::vector<std::pair<Index, Index>>;
82
83 VectorWrapper(const T& _data) : data(_data) { }
84 operator bool() const { return index < data.size(); }
85 VectorWrapper& operator++() { index++; return *this; }
86 Index sourceIndex() const { assert(*this); return data[index].first; }
87 Index targetIndex() const { assert(*this); return data[index].second; }
88
89 private:
90 const T& data;
91 T::size_type index = 0;
92 }; // struct VectorWrapper
93
94
95 template <typename PointDataTreeT, typename FilterT>
96 struct DeleteByFilterOp
97 {
98 using LeafManagerT = tree::LeafManager<PointDataTreeT>;
99 using LeafRangeT = typename LeafManagerT::LeafRange;
100 using LeafNodeT = typename PointDataTreeT::LeafNodeType;
101 using ValueType = typename LeafNodeT::ValueType;
102
103 DeleteByFilterOp(const FilterT& filter,
104 const AttributeArray::ScopedRegistryLock* lock)
105 : mFilter(filter)
106 , mLock(lock) { }
107
108 void operator()(const LeafRangeT& range) const
109 {
110 for (auto leaf = range.begin(); leaf != range.end(); ++leaf) {
111
112 const size_t newSize =
113 iterCount(leaf->template beginIndexAll<FilterT>(mFilter));
114
115 // if all points are being deleted, clear the leaf attributes
116 if (newSize == 0) {
117 leaf->clearAttributes(/*updateValueMask=*/true, mLock);
118 continue;
119 }
120
121 // early exit if no points are being deleted
122
123 const size_t currentSize = leaf->getLastValue();
124 if (newSize == currentSize) continue;
125
126 const AttributeSet& existingAttributeSet = leaf->attributeSet();
127 AttributeSet* newAttributeSet = new AttributeSet(
128 existingAttributeSet, static_cast<Index>(newSize), mLock);
129 const size_t attributeSetSize = existingAttributeSet.size();
130
131 // cache the attribute arrays for efficiency
132
133 std::vector<AttributeArray*> newAttributeArrays;
134 std::vector<const AttributeArray*> existingAttributeArrays;
135
136 for (size_t i = 0; i < attributeSetSize; i++) {
137 AttributeArray* newArray = newAttributeSet->get(i);
138 const AttributeArray* existingArray = existingAttributeSet.getConst(i);
139
140 if (!newArray->hasConstantStride() || !existingArray->hasConstantStride()) {
141 OPENVDB_THROW(openvdb::NotImplementedError,
142 "Transfer of attribute values for dynamic arrays not currently supported.");
143 }
144
145 if (newArray->stride() != existingArray->stride()) {
146 OPENVDB_THROW(openvdb::LookupError,
147 "Cannot transfer attribute values with mis-matching strides.");
148 }
149
150 newAttributeArrays.push_back(newArray);
151 existingAttributeArrays.push_back(existingArray);
152 }
153
154 Index attributeIndex = 0;
155 std::vector<ValueType> endOffsets;
156
157 endOffsets.reserve(LeafNodeT::NUM_VALUES);
158
159 // now construct new attribute arrays which exclude data from deleted points
160
161 #if OPENVDB_ABI_VERSION_NUMBER >= 6
162 std::vector<std::pair<Index, Index>> indexMapping;
163 indexMapping.reserve(newSize);
164
165 for (auto voxel = leaf->cbeginValueAll(); voxel; ++voxel) {
166 for (auto iter = leaf->beginIndexVoxel(voxel.getCoord(), mFilter);
167 iter; ++iter) {
168 indexMapping.emplace_back(*iter, attributeIndex++);
169 }
170 endOffsets.push_back(static_cast<ValueType>(attributeIndex));
171 }
172
173 for (size_t i = 0; i < attributeSetSize; i++) {
174 VectorWrapper indexMappingWrapper(indexMapping);
175 newAttributeArrays[i]->copyValues(*(existingAttributeArrays[i]), indexMappingWrapper);
176 }
177 #else
178 for (auto voxel = leaf->cbeginValueAll(); voxel; ++voxel) {
179 for (auto iter = leaf->beginIndexVoxel(voxel.getCoord(), mFilter);
180 iter; ++iter) {
181 for (size_t i = 0; i < attributeSetSize; i++) {
182 newAttributeArrays[i]->set(attributeIndex, *(existingAttributeArrays[i]),
183 *iter);
184 }
185 ++attributeIndex;
186 }
187 endOffsets.push_back(static_cast<ValueType>(attributeIndex));
188 }
189 #endif
190
191 leaf->replaceAttributeSet(newAttributeSet);
192 leaf->setOffsets(endOffsets);
193 }
194 }
195
196 private:
197 const FilterT& mFilter;
198 const AttributeArray::ScopedRegistryLock* mLock;
199 }; // struct DeleteByFilterOp
200
201 } // namespace point_delete_internal
202
203
205
206
207 template <typename PointDataTreeT>
208 inline void deleteFromGroups(PointDataTreeT& pointTree,
209 const std::vector<std::string>& groups,
210 bool invert,
211 bool drop)
212 {
213 const typename PointDataTreeT::LeafCIter leafIter = pointTree.cbeginLeaf();
214
215 if (!leafIter) return;
216
217 const openvdb::points::AttributeSet& attributeSet = leafIter->attributeSet();
218 const AttributeSet::Descriptor& descriptor = attributeSet.descriptor();
219 std::vector<std::string> availableGroups;
220
221 // determine which of the requested groups exist, and early exit
222 // if none are present in the tree
223
224 for (const auto& groupName : groups) {
225 if (descriptor.hasGroup(groupName)) {
226 availableGroups.push_back(groupName);
227 }
228 }
229
230 if (availableGroups.empty()) return;
231
232 std::vector<std::string> empty;
233 std::unique_ptr<MultiGroupFilter> filter;
234 if (invert) {
235 filter.reset(new MultiGroupFilter(groups, empty, leafIter->attributeSet()));
236 }
237 else {
238 filter.reset(new MultiGroupFilter(empty, groups, leafIter->attributeSet()));
239 }
240
241 { // acquire registry lock to avoid locking when appending attributes in parallel
242
243 AttributeArray::ScopedRegistryLock lock;
244
245 tree::LeafManager<PointDataTreeT> leafManager(pointTree);
246 point_delete_internal::DeleteByFilterOp<PointDataTreeT, MultiGroupFilter> deleteOp(
247 *filter, &lock);
248 tbb::parallel_for(leafManager.leafRange(), deleteOp);
249 }
250
251 // remove empty leaf nodes
252
253 tools::pruneInactive(pointTree);
254
255 // drop the now-empty groups if requested (unless invert = true)
256
257 if (drop && !invert) {
258 dropGroups(pointTree, availableGroups);
259 }
260 }
261
262 template <typename PointDataTreeT>
263 inline void deleteFromGroup(PointDataTreeT& pointTree,
264 const std::string& group,
265 bool invert,
266 bool drop)
267 {
268 std::vector<std::string> groups(1, group);
269
270 deleteFromGroups(pointTree, groups, invert, drop);
271 }
272
273
274 } // namespace points
275 } // namespace OPENVDB_VERSION_NAME
276 } // namespace openvdb
277
278 #endif // OPENVDB_POINTS_POINT_DELETE_HAS_BEEN_INCLUDED
openvdb::v7_0::points::point_delete_internal::VectorWrapper::sourceIndex
Index sourceIndex() const
Definition: PointDelete.h:86
openvdb::v7_0::points::point_delete_internal::DeleteByFilterOp::DeleteByFilterOp
DeleteByFilterOp(const FilterT &filter, const AttributeArray::ScopedRegistryLock *lock)
Definition: PointDelete.h:103
openvdb::v7_0::points::point_delete_internal::DeleteByFilterOp::LeafRangeT
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointDelete.h:99
openvdb::v7_0::points::AttributeArray::stride
virtual Index stride() const =0
openvdb::v7_0::points::point_delete_internal::VectorWrapper::VectorWrapper
VectorWrapper(const T &_data)
Definition: PointDelete.h:83
PointGroup.h
Point group manipulation in a VDB Point Grid.
openvdb::v7_0::points::AttributeArray
Base class for storing attribute data.
Definition: AttributeArray.h:92
openvdb::v7_0::LookupError
Definition: Exceptions.h:60
openvdb::v7_0::tree::LeafManager::leafRange
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:358
openvdb::v7_0::NotImplementedError
Definition: Exceptions.h:61
openvdb::v7_0::points::deleteFromGroup
void deleteFromGroup(PointDataTreeT &pointTree, const std::string &group, bool invert=false, bool drop=true)
Delete points that are members of a group.
Definition: PointDelete.h:263
openvdb::v7_0::points::point_delete_internal::DeleteByFilterOp::LeafNodeT
typename PointDataTreeT::LeafNodeType LeafNodeT
Definition: PointDelete.h:100
IndexFilter.h
Index filters primarily designed to be used with a FilterIndexIter.
openvdb::v7_0::points::point_delete_internal::DeleteByFilterOp::ValueType
typename LeafNodeT::ValueType ValueType
Definition: PointDelete.h:101
PointDataGrid.h
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
openvdb::v7_0::tree::LeafManager::LeafRange
Definition: LeafManager.h:99
Prune.h
Defined various multi-threaded utility functions for trees.
openvdb::v7_0::points::point_delete_internal::VectorWrapper
Definition: PointDelete.h:79
openvdb::v7_0::points::iterCount
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:314
openvdb::v7_0::points::point_delete_internal::DeleteByFilterOp
Definition: PointDelete.h:96
IndexIterator.h
Index Iterators.
openvdb::v7_0::tree::LeafManager
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:82
openvdb::v7_0::points::AttributeArray::hasConstantStride
bool hasConstantStride() const
Return true if this attribute has a constant stride.
Definition: AttributeArray.h:323
openvdb::v7_0::points::point_delete_internal::VectorWrapper::T
std::vector< std::pair< Index, Index > > T
Definition: PointDelete.h:81
openvdb::v7_0::points::point_delete_internal::VectorWrapper::targetIndex
Index targetIndex() const
Definition: PointDelete.h:87
openvdb::v7_0::points::point_delete_internal::DeleteByFilterOp::operator()
void operator()(const LeafRangeT &range) const
Definition: PointDelete.h:108
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
openvdb::v7_0::points::AttributeArray::ScopedRegistryLock
Definition: AttributeArray.h:119
openvdb::v7_0::points::AttributeSet::size
size_t size() const
Return the number of attributes in this set.
Definition: AttributeSet.h:107
openvdb::v7_0::points::AttributeSet
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:35
LeafManager.h
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
openvdb::v7_0::points::AttributeSet::getConst
const AttributeArray * getConst(const std::string &name) const
Return a pointer to the attribute array whose name is name or a null pointer if no match is found.
openvdb::v7_0::points::point_delete_internal::VectorWrapper::operator++
VectorWrapper & operator++()
Definition: PointDelete.h:85
openvdb::v7_0::Index
Index32 Index
Definition: Types.h:31
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
openvdb::v7_0::points::dropGroups
void dropGroups(PointDataTree &tree, const std::vector< Name > &groups)
Drops existing groups from the VDB tree, the tree is compacted after dropping.
Definition: PointGroup.h:552
openvdb
Definition: Exceptions.h:13
openvdb::v7_0::tools::pruneInactive
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:354
openvdb::v7_0::points::MultiGroupFilter
Definition: IndexFilter.h:135
openvdb::v7_0::points::deleteFromGroups
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: PointDelete.h:208
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
openvdb::v7_0::points::AttributeSet::get
const AttributeArray * get(const std::string &name) const