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>
20 
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 
26 namespace openvdb {
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 
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>
97 {
100  using LeafNodeT = typename PointDataTreeT::LeafNodeType;
101  using ValueType = typename LeafNodeT::ValueType;
102 
103  DeleteByFilterOp(const FilterT& filter,
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()) {
142  "Transfer of attribute values for dynamic arrays not currently supported.");
143  }
144 
145  if (newArray->stride() != existingArray->stride()) {
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;
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 
244 
245  tree::LeafManager<PointDataTreeT> leafManager(pointTree);
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
Definition: Exceptions.h:61
void operator()(const LeafRangeT &range) const
Definition: PointDelete.h:108
virtual Index stride() const =0
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
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
Base class for storing attribute data.
Definition: AttributeArray.h:92
VectorWrapper & operator++()
Definition: PointDelete.h:85
DeleteByFilterOp(const FilterT &filter, const AttributeArray::ScopedRegistryLock *lock)
Definition: PointDelete.h:103
Index targetIndex() const
Definition: PointDelete.h:87
std::vector< std::pair< Index, Index >> T
Definition: PointDelete.h:81
Defined various multi-threaded utility functions for trees.
Point group manipulation in a VDB Point Grid.
Index filters primarily designed to be used with a FilterIndexIter.
bool hasConstantStride() const
Return true if this attribute has a constant stride.
Definition: AttributeArray.h:323
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...
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
const AttributeArray * get(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...
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
Definition: IndexFilter.h:135
Definition: Exceptions.h:13
typename PointDataTreeT::LeafNodeType LeafNodeT
Definition: PointDelete.h:100
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointDelete.h:99
Index Iterators.
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:82
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:314
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:358
Index32 Index
Definition: Types.h:31
Definition: Exceptions.h:60
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
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
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Index sourceIndex() const
Definition: PointDelete.h:86
VectorWrapper(const T &_data)
Definition: PointDelete.h:83
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
A LeafManager manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional au...
size_t size() const
Return the number of attributes in this set.
Definition: AttributeSet.h:107
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:35
typename LeafNodeT::ValueType ValueType
Definition: PointDelete.h:101