OpenVDB: PointDelete.h Source File

OpenVDB 6.1.0

PointDelete.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30
36
37 #ifndef OPENVDB_POINTS_POINT_DELETE_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_DELETE_HAS_BEEN_INCLUDED
39
40 #include "PointDataGrid.h"
41 #include "PointGroup.h"
42 #include "IndexIterator.h"
43 #include "IndexFilter.h"
44
45 #include <openvdb/tools/Prune.h>
46 #include <openvdb/tree/LeafManager.h>
47
48 #include <memory>
49 #include <string>
50 #include <vector>
51
52
53 namespace openvdb {
54 OPENVDB_USE_VERSION_NAMESPACE
55 namespace OPENVDB_VERSION_NAME {
56 namespace points {
57
58
72
73 template <typename PointDataTreeT>
74 inline void deleteFromGroups(PointDataTreeT& pointTree,
75 const std::vector<std::string>& groups,
76 bool invert = false,
77 bool drop = true);
78
92
93 template <typename PointDataTreeT>
94 inline void deleteFromGroup(PointDataTreeT& pointTree,
95 const std::string& group,
96 bool invert = false,
97 bool drop = true);
98
99
101
102
103 namespace point_delete_internal {
104
105
106 struct VectorWrapper
107 {
108 using T = std::vector<std::pair<Index, Index>>;
109
110 VectorWrapper(const T& _data) : data(_data) { }
111 operator bool() const { return index < data.size(); }
112 VectorWrapper& operator++() { index++; return *this; }
113 Index sourceIndex() const { assert(*this); return data[index].first; }
114 Index targetIndex() const { assert(*this); return data[index].second; }
115
116 private:
117 const T& data;
118 T::size_type index = 0;
119 }; // struct VectorWrapper
120
121
122 template <typename PointDataTreeT, typename FilterT>
123 struct DeleteByFilterOp
124 {
125 using LeafManagerT = tree::LeafManager<PointDataTreeT>;
126 using LeafRangeT = typename LeafManagerT::LeafRange;
127 using LeafNodeT = typename PointDataTreeT::LeafNodeType;
128 using ValueType = typename LeafNodeT::ValueType;
129
130 DeleteByFilterOp(const FilterT& filter)
131 : mFilter(filter) { }
132
133 void operator()(const LeafRangeT& range) const
134 {
135 for (auto leaf = range.begin(); leaf != range.end(); ++leaf) {
136
137 const size_t newSize =
138 iterCount(leaf->template beginIndexAll<FilterT>(mFilter));
139
140 // if all points are being deleted, clear the leaf attributes
141 if (newSize == 0) {
142 leaf->clearAttributes();
143 continue;
144 }
145
146 // early exit if no points are being deleted
147
148 const size_t currentSize = leaf->getLastValue();
149 if (newSize == currentSize) continue;
150
151 const AttributeSet& existingAttributeSet = leaf->attributeSet();
152 AttributeSet* newAttributeSet = new AttributeSet(
153 existingAttributeSet, static_cast<Index>(newSize));
154 const size_t attributeSetSize = existingAttributeSet.size();
155
156 // cache the attribute arrays for efficiency
157
158 std::vector<AttributeArray*> newAttributeArrays;
159 std::vector<const AttributeArray*> existingAttributeArrays;
160
161 for (size_t i = 0; i < attributeSetSize; i++) {
162 AttributeArray* newArray = newAttributeSet->get(i);
163 const AttributeArray* existingArray = existingAttributeSet.getConst(i);
164
165 if (!newArray->hasConstantStride() || !existingArray->hasConstantStride()) {
166 OPENVDB_THROW(openvdb::NotImplementedError,
167 "Transfer of attribute values for dynamic arrays not currently supported.");
168 }
169
170 if (newArray->stride() != existingArray->stride()) {
171 OPENVDB_THROW(openvdb::LookupError,
172 "Cannot transfer attribute values with mis-matching strides.");
173 }
174
175 newAttributeArrays.push_back(newArray);
176 existingAttributeArrays.push_back(existingArray);
177 }
178
179 Index attributeIndex = 0;
180 std::vector<ValueType> endOffsets;
181
182 endOffsets.reserve(LeafNodeT::NUM_VALUES);
183
184 // now construct new attribute arrays which exclude data from deleted points
185
186 #if OPENVDB_ABI_VERSION_NUMBER >= 6
187 std::vector<std::pair<Index, Index>> indexMapping;
188 indexMapping.reserve(newSize);
189
190 for (auto voxel = leaf->cbeginValueAll(); voxel; ++voxel) {
191 for (auto iter = leaf->beginIndexVoxel(voxel.getCoord(), mFilter);
192 iter; ++iter) {
193 indexMapping.emplace_back(*iter, attributeIndex++);
194 }
195 endOffsets.push_back(static_cast<ValueType>(attributeIndex));
196 }
197
198 for (size_t i = 0; i < attributeSetSize; i++) {
199 VectorWrapper indexMappingWrapper(indexMapping);
200 newAttributeArrays[i]->copyValues(*(existingAttributeArrays[i]), indexMappingWrapper);
201 }
202 #else
203 for (auto voxel = leaf->cbeginValueAll(); voxel; ++voxel) {
204 for (auto iter = leaf->beginIndexVoxel(voxel.getCoord(), mFilter);
205 iter; ++iter) {
206 for (size_t i = 0; i < attributeSetSize; i++) {
207 newAttributeArrays[i]->set(attributeIndex, *(existingAttributeArrays[i]),
208 *iter);
209 }
210 ++attributeIndex;
211 }
212 endOffsets.push_back(static_cast<ValueType>(attributeIndex));
213 }
214 #endif
215
216 leaf->replaceAttributeSet(newAttributeSet);
217 leaf->setOffsets(endOffsets);
218 }
219 }
220
221 private:
222 const FilterT& mFilter;
223 }; // struct DeleteByFilterOp
224
225 } // namespace point_delete_internal
226
227
229
230
231 template <typename PointDataTreeT>
232 inline void deleteFromGroups(PointDataTreeT& pointTree,
233 const std::vector<std::string>& groups,
234 bool invert,
235 bool drop)
236 {
237 const typename PointDataTreeT::LeafCIter leafIter = pointTree.cbeginLeaf();
238
239 if (!leafIter) return;
240
241 const openvdb::points::AttributeSet& attributeSet = leafIter->attributeSet();
242 const AttributeSet::Descriptor& descriptor = attributeSet.descriptor();
243 std::vector<std::string> availableGroups;
244
245 // determine which of the requested groups exist, and early exit
246 // if none are present in the tree
247
248 for (const auto& groupName : groups) {
249 if (descriptor.hasGroup(groupName)) {
250 availableGroups.push_back(groupName);
251 }
252 }
253
254 if (availableGroups.empty()) return;
255
256 std::vector<std::string> empty;
257 std::unique_ptr<MultiGroupFilter> filter;
258 if (invert) {
259 filter.reset(new MultiGroupFilter(groups, empty, leafIter->attributeSet()));
260 }
261 else {
262 filter.reset(new MultiGroupFilter(empty, groups, leafIter->attributeSet()));
263 }
264
265 tree::LeafManager<PointDataTreeT> leafManager(pointTree);
266 point_delete_internal::DeleteByFilterOp<PointDataTreeT, MultiGroupFilter> deleteOp(*filter);
267 tbb::parallel_for(leafManager.leafRange(), deleteOp);
268
269 // remove empty leaf nodes
270
271 tools::pruneInactive(pointTree);
272
273 // drop the now-empty groups if requested (unless invert = true)
274
275 if (drop && !invert) {
276 dropGroups(pointTree, availableGroups);
277 }
278 }
279
280 template <typename PointDataTreeT>
281 inline void deleteFromGroup(PointDataTreeT& pointTree,
282 const std::string& group,
283 bool invert,
284 bool drop)
285 {
286 std::vector<std::string> groups(1, group);
287
288 deleteFromGroups(pointTree, groups, invert, drop);
289 }
290
291
292 } // namespace points
293 } // namespace OPENVDB_VERSION_NAME
294 } // namespace openvdb
295
296 #endif // OPENVDB_POINTS_POINT_DELETE_HAS_BEEN_INCLUDED
297
298 // Copyright (c) 2012-2018 DreamWorks Animation LLC
299 // All rights reserved. This software is distributed under the
300 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v6_1::points::AttributeArray::stride
virtual Index stride() const =0
openvdb::v6_1::points::point_delete_internal::DeleteByFilterOp::operator()
void operator()(const LeafRangeT &range) const
Definition: PointDelete.h:133
openvdb::v6_1::points::point_delete_internal::VectorWrapper::operator++
VectorWrapper & operator++()
Definition: PointDelete.h:112
openvdb::v6_1::points::point_delete_internal::VectorWrapper::sourceIndex
Index sourceIndex() const
Definition: PointDelete.h:113
openvdb::v6_1::points::AttributeSet::size
size_t size() const
Return the number of attributes in this set.
Definition: AttributeSet.h:130
openvdb::v6_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:232
openvdb::v6_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:281
openvdb::v6_1::points::point_delete_internal::VectorWrapper::VectorWrapper
VectorWrapper(const T &_data)
Definition: PointDelete.h:110
openvdb::v6_1::NotImplementedError
Definition: Exceptions.h:88
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
openvdb::v6_1::points::point_delete_internal::DeleteByFilterOp::LeafNodeT
typename PointDataTreeT::LeafNodeType LeafNodeT
Definition: PointDelete.h:127
openvdb::v6_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::v6_1::points::point_delete_internal::VectorWrapper
Definition: PointDelete.h:106
openvdb::v6_1::points::point_delete_internal::DeleteByFilterOp::LeafRangeT
typename LeafManagerT::LeafRange LeafRangeT
Definition: PointDelete.h:126
openvdb::v6_1::points::AttributeArray
Base class for storing attribute data.
Definition: AttributeArray.h:118
openvdb::v6_1::points::point_delete_internal::DeleteByFilterOp::DeleteByFilterOp
DeleteByFilterOp(const FilterT &filter)
Definition: PointDelete.h:130
Prune.h
Defined various multi-threaded utility functions for trees.
PointGroup.h
Point group manipulation in a VDB Point Grid.
openvdb::v6_1::points::point_delete_internal::DeleteByFilterOp::ValueType
typename LeafNodeT::ValueType ValueType
Definition: PointDelete.h:128
openvdb::v6_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:109
IndexFilter.h
Index filters primarily designed to be used with a FilterIndexIter.
openvdb::v6_1::points::AttributeSet
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:62
openvdb::v6_1::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:580
openvdb::v6_1::tree::LeafManager::leafRange
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:385
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:125
openvdb::v6_1::points::point_delete_internal::VectorWrapper::T
std::vector< std::pair< Index, Index > > T
Definition: PointDelete.h:108
openvdb::v6_1::Index
Index32 Index
Definition: Types.h:61
openvdb
Definition: Exceptions.h:40
openvdb::v6_1::points::point_delete_internal::VectorWrapper::targetIndex
Index targetIndex() const
Definition: PointDelete.h:114
openvdb::v6_1::points::AttributeSet::get
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.
IndexIterator.h
Index Iterators.
openvdb::v6_1::points::point_delete_internal::DeleteByFilterOp
Definition: PointDelete.h:123
openvdb::v6_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:381
openvdb::v6_1::tree::LeafManager::LeafRange
Definition: LeafManager.h:126
openvdb::v6_1::points::AttributeArray::hasConstantStride
bool hasConstantStride() const
Return true if this attribute has a constant stride.
Definition: AttributeArray.h:347
PointDataGrid.h
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:177
openvdb::v6_1::LookupError
Definition: Exceptions.h:87
LeafManager.h
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
openvdb::v6_1::points::MultiGroupFilter
Definition: IndexFilter.h:163
openvdb::v6_1::points::iterCount
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:341