OpenVDB  8.1.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()) {
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  std::vector<std::pair<Index, Index>> indexMapping;
162  indexMapping.reserve(newSize);
163 
164  for (auto voxel = leaf->cbeginValueAll(); voxel; ++voxel) {
165  for (auto iter = leaf->beginIndexVoxel(voxel.getCoord(), mFilter);
166  iter; ++iter) {
167  indexMapping.emplace_back(*iter, attributeIndex++);
168  }
169  endOffsets.push_back(static_cast<ValueType>(attributeIndex));
170  }
171 
172  for (size_t i = 0; i < attributeSetSize; i++) {
173  VectorWrapper indexMappingWrapper(indexMapping);
174  newAttributeArrays[i]->copyValues(*(existingAttributeArrays[i]), indexMappingWrapper);
175  }
176 
177  leaf->replaceAttributeSet(newAttributeSet);
178  leaf->setOffsets(endOffsets);
179  }
180  }
181 
182 private:
183  const FilterT& mFilter;
185 }; // struct DeleteByFilterOp
186 
187 } // namespace point_delete_internal
188 
189 
191 
192 
193 template <typename PointDataTreeT>
194 inline void deleteFromGroups(PointDataTreeT& pointTree,
195  const std::vector<std::string>& groups,
196  bool invert,
197  bool drop)
198 {
199  const typename PointDataTreeT::LeafCIter leafIter = pointTree.cbeginLeaf();
200 
201  if (!leafIter) return;
202 
203  const openvdb::points::AttributeSet& attributeSet = leafIter->attributeSet();
204  const AttributeSet::Descriptor& descriptor = attributeSet.descriptor();
205  std::vector<std::string> availableGroups;
206 
207  // determine which of the requested groups exist, and early exit
208  // if none are present in the tree
209 
210  for (const auto& groupName : groups) {
211  if (descriptor.hasGroup(groupName)) {
212  availableGroups.push_back(groupName);
213  }
214  }
215 
216  if (availableGroups.empty()) return;
217 
218  std::vector<std::string> empty;
219  std::unique_ptr<MultiGroupFilter> filter;
220  if (invert) {
221  filter.reset(new MultiGroupFilter(groups, empty, leafIter->attributeSet()));
222  }
223  else {
224  filter.reset(new MultiGroupFilter(empty, groups, leafIter->attributeSet()));
225  }
226 
227  { // acquire registry lock to avoid locking when appending attributes in parallel
228 
230 
231  tree::LeafManager<PointDataTreeT> leafManager(pointTree);
233  *filter, &lock);
234  tbb::parallel_for(leafManager.leafRange(), deleteOp);
235  }
236 
237  // remove empty leaf nodes
238 
239  tools::pruneInactive(pointTree);
240 
241  // drop the now-empty groups if requested (unless invert = true)
242 
243  if (drop && !invert) {
244  dropGroups(pointTree, availableGroups);
245  }
246 }
247 
248 template <typename PointDataTreeT>
249 inline void deleteFromGroup(PointDataTreeT& pointTree,
250  const std::string& group,
251  bool invert,
252  bool drop)
253 {
254  std::vector<std::string> groups(1, group);
255 
256  deleteFromGroups(pointTree, groups, invert, drop);
257 }
258 
259 
260 } // namespace points
261 } // namespace OPENVDB_VERSION_NAME
262 } // namespace openvdb
263 
264 #endif // OPENVDB_POINTS_POINT_DELETE_HAS_BEEN_INCLUDED
openvdb::v8_1::points::point_delete_internal::DeleteByFilterOp::LeafNodeT
typename PointDataTreeT::LeafNodeType LeafNodeT
Definition: PointDelete.h:100
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
openvdb::v8_1::points::AttributeArray::stride
virtual Index stride() const =0
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178
PointGroup.h
Point group manipulation in a VDB Point Grid.
openvdb::v8_1::points::AttributeSet::size
size_t size() const
Return the number of attributes in this set.
Definition: AttributeSet.h:111
openvdb::v8_1::tree::LeafManager::leafRange
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:345
openvdb::v8_1::points::point_delete_internal::VectorWrapper::operator++
VectorWrapper & operator++()
Definition: PointDelete.h:85
openvdb::v8_1::points::AttributeSet
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:38
openvdb::v8_1::points::point_delete_internal::VectorWrapper::T
std::vector< std::pair< Index, Index > > T
Definition: PointDelete.h:81
openvdb::v8_1::points::AttributeArray::ScopedRegistryLock
Definition: AttributeArray.h:118
openvdb::v8_1::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:84
IndexFilter.h
Index filters primarily designed to be used with a FilterIndexIter.
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
openvdb::v8_1::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::v8_1::points::point_delete_internal::VectorWrapper::targetIndex
Index targetIndex() const
Definition: PointDelete.h:87
openvdb::v8_1::points::MultiGroupFilter
Definition: IndexFilter.h:135
openvdb::v8_1::points::point_delete_internal::DeleteByFilterOp
Definition: PointDelete.h:96
openvdb::v8_1::Index
Index32 Index
Definition: openvdb/Types.h:50
openvdb::v8_1::points::AttributeArray
Base class for storing attribute data.
Definition: AttributeArray.h:92
PointDataGrid.h
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
openvdb::v8_1::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:194
openvdb::v8_1::points::point_delete_internal::DeleteByFilterOp::ValueType
typename LeafNodeT::ValueType ValueType
Definition: PointDelete.h:101
Prune.h
Defined various multi-threaded utility functions for trees.
IndexIterator.h
Index Iterators.
openvdb::v8_1::points::point_delete_internal::DeleteByFilterOp::DeleteByFilterOp
DeleteByFilterOp(const FilterT &filter, const AttributeArray::ScopedRegistryLock *lock)
Definition: PointDelete.h:103
openvdb::v8_1::points::point_delete_internal::DeleteByFilterOp::operator()
void operator()(const LeafRangeT &range) const
Definition: PointDelete.h:108
openvdb::v8_1::tree::LeafManager::LeafRange
Definition: LeafManager.h:101
openvdb::v8_1::points::AttributeSet::get
const AttributeArray * get(const std::string &name) const
openvdb::v8_1::points::point_delete_internal::VectorWrapper::VectorWrapper
VectorWrapper(const T &_data)
Definition: PointDelete.h:83
openvdb::v8_1::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:249
LeafManager.h
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
openvdb::v8_1::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::v8_1::points::point_delete_internal::VectorWrapper::sourceIndex
Index sourceIndex() const
Definition: PointDelete.h:86
openvdb::v8_1::points::point_delete_internal::DeleteByFilterOp::LeafRangeT
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointDelete.h:99
openvdb::v8_1::points::dropGroups
void dropGroups(PointDataTreeT &tree, const std::vector< Name > &groups)
Drops existing groups from the VDB tree, the tree is compacted after dropping.
Definition: PointGroup.h:437
openvdb
Definition: openvdb/Exceptions.h:13
openvdb::v8_1::points::point_delete_internal::VectorWrapper
Definition: PointDelete.h:79
openvdb::v8_1::points::AttributeArray::hasConstantStride
bool hasConstantStride() const
Return true if this attribute has a constant stride.
Definition: AttributeArray.h:303
openvdb::v8_1::points::iterCount
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:314