GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/points/PointAttribute.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 104 106 98.1%
Functions: 62 65 95.4%
Branches: 140 264 53.0%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 /// @author Dan Bailey, Khang Ngo
5 ///
6 /// @file points/PointAttribute.h
7 ///
8 /// @brief Point attribute manipulation in a VDB Point Grid.
9
10 #ifndef OPENVDB_POINTS_POINT_ATTRIBUTE_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_POINT_ATTRIBUTE_HAS_BEEN_INCLUDED
12
13 #include <openvdb/openvdb.h>
14
15 #include "AttributeArrayString.h"
16 #include "AttributeSet.h"
17 #include "AttributeGroup.h"
18 #include "PointDataGrid.h"
19
20
21 namespace openvdb {
22 OPENVDB_USE_VERSION_NAMESPACE
23 namespace OPENVDB_VERSION_NAME {
24 namespace points {
25
26 namespace point_attribute_internal {
27
28 template <typename ValueType>
29 struct Default
30 {
31 1511 static inline ValueType value() { return zeroVal<ValueType>(); }
32 };
33
34 } // namespace point_attribute_internal
35
36
37 /// @brief Appends a new attribute to the VDB tree
38 /// (this method does not require a templated AttributeType)
39 ///
40 /// @param tree the PointDataTree to be appended to.
41 /// @param name name for the new attribute.
42 /// @param type the type of the attibute.
43 /// @param strideOrTotalSize the stride of the attribute
44 /// @param constantStride if @c false, stride is interpreted as total size of the array
45 /// @param defaultValue metadata default attribute value
46 /// @param hidden mark attribute as hidden
47 /// @param transient mark attribute as transient
48 template <typename PointDataTreeT>
49 inline void appendAttribute(PointDataTreeT& tree,
50 const Name& name,
51 const NamePair& type,
52 const Index strideOrTotalSize = 1,
53 const bool constantStride = true,
54 const Metadata* defaultValue = nullptr,
55 const bool hidden = false,
56 const bool transient = false);
57
58 /// @brief Appends a new attribute to the VDB tree.
59 ///
60 /// @param tree the PointDataTree to be appended to.
61 /// @param name name for the new attribute
62 /// @param uniformValue the initial value of the attribute
63 /// @param strideOrTotalSize the stride of the attribute
64 /// @param constantStride if @c false, stride is interpreted as total size of the array
65 /// @param defaultValue metadata default attribute value
66 /// @param hidden mark attribute as hidden
67 /// @param transient mark attribute as transient
68 template <typename ValueType,
69 typename CodecType = NullCodec,
70 typename PointDataTreeT>
71 inline void appendAttribute(PointDataTreeT& tree,
72 const std::string& name,
73 const ValueType& uniformValue =
74
18/40
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✓ Branch 20 taken 1 times.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 2 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
35 point_attribute_internal::Default<ValueType>::value(),
75 const Index strideOrTotalSize = 1,
76 const bool constantStride = true,
77 const TypedMetadata<ValueType>* defaultValue = nullptr,
78 const bool hidden = false,
79 const bool transient = false);
80
81 /// @brief Collapse the attribute into a uniform value
82 ///
83 /// @param tree the PointDataTree in which to collapse the attribute.
84 /// @param name name for the attribute.
85 /// @param uniformValue value of the attribute
86 template <typename ValueType, typename PointDataTreeT>
87 inline void collapseAttribute( PointDataTreeT& tree,
88 const Name& name,
89 const ValueType& uniformValue =
90 point_attribute_internal::Default<ValueType>::value());
91
92 /// @brief Drops attributes from the VDB tree.
93 ///
94 /// @param tree the PointDataTree to be dropped from.
95 /// @param indices indices of the attributes to drop.
96 template <typename PointDataTreeT>
97 inline void dropAttributes( PointDataTreeT& tree,
98 const std::vector<size_t>& indices);
99
100 /// @brief Drops attributes from the VDB tree.
101 ///
102 /// @param tree the PointDataTree to be dropped from.
103 /// @param names names of the attributes to drop.
104 template <typename PointDataTreeT>
105 inline void dropAttributes( PointDataTreeT& tree,
106 const std::vector<Name>& names);
107
108 /// @brief Drop one attribute from the VDB tree (convenience method).
109 ///
110 /// @param tree the PointDataTree to be dropped from.
111 /// @param index index of the attribute to drop.
112 template <typename PointDataTreeT>
113 inline void dropAttribute( PointDataTreeT& tree,
114 const size_t& index);
115
116 /// @brief Drop one attribute from the VDB tree (convenience method).
117 ///
118 /// @param tree the PointDataTree to be dropped from.
119 /// @param name name of the attribute to drop.
120 template <typename PointDataTreeT>
121 inline void dropAttribute( PointDataTreeT& tree,
122 const Name& name);
123
124 /// @brief Rename attributes in a VDB tree.
125 ///
126 /// @param tree the PointDataTree.
127 /// @param oldNames a list of old attribute names to rename from.
128 /// @param newNames a list of new attribute names to rename to.
129 ///
130 /// @note Number of oldNames must match the number of newNames.
131 ///
132 /// @note Duplicate names and renaming group attributes are not allowed.
133 template <typename PointDataTreeT>
134 inline void renameAttributes(PointDataTreeT& tree,
135 const std::vector<Name>& oldNames,
136 const std::vector<Name>& newNames);
137
138 /// @brief Rename an attribute in a VDB tree.
139 ///
140 /// @param tree the PointDataTree.
141 /// @param oldName the old attribute name to rename from.
142 /// @param newName the new attribute name to rename to.
143 ///
144 /// @note newName must not already exist and must not be a group attribute.
145 template <typename PointDataTreeT>
146 inline void renameAttribute(PointDataTreeT& tree,
147 const Name& oldName,
148 const Name& newName);
149
150 /// @brief Compact attributes in a VDB tree (if possible).
151 ///
152 /// @param tree the PointDataTree.
153 template <typename PointDataTreeT>
154 inline void compactAttributes(PointDataTreeT& tree);
155
156
157 ////////////////////////////////////////
158
159 /// @cond OPENVDB_DOCS_INTERNAL
160
161 namespace point_attribute_internal {
162
163
164 template <typename ValueType>
165 20932 inline void collapseAttribute(AttributeArray& array,
166 const AttributeSet::Descriptor&, const ValueType& uniformValue)
167 {
168 20932 AttributeWriteHandle<ValueType> handle(array);
169
1/2
✓ Branch 1 taken 10473 times.
✗ Branch 2 not taken.
20932 handle.collapse(uniformValue);
170 20932 }
171
172
173 184 inline void collapseAttribute(AttributeArray& array,
174 const AttributeSet::Descriptor& descriptor, const Name& uniformValue)
175 {
176 368 StringAttributeWriteHandle handle(array, descriptor.getMetadata());
177
1/2
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
184 handle.collapse(uniformValue);
178 184 }
179
180
181 ////////////////////////////////////////
182
183
184 template <typename ValueType, typename CodecType>
185 struct AttributeTypeConversion
186 {
187 static const NamePair& type() {
188 return TypedAttributeArray<ValueType, CodecType>::attributeType();
189 }
190 };
191
192
193 template <typename CodecType>
194 struct AttributeTypeConversion<Name, CodecType>
195 {
196 static const NamePair& type() { return StringAttributeArray::attributeType(); }
197 };
198
199
200 ////////////////////////////////////////
201
202
203 template <typename PointDataTreeT, typename ValueType>
204 struct MetadataStorage
205 {
206 static void add(PointDataTreeT&, const ValueType&) {}
207
208 template<typename AttributeListType>
209 static void add(PointDataTreeT&, const AttributeListType&) {}
210 };
211
212
213 template <typename PointDataTreeT>
214 struct MetadataStorage<PointDataTreeT, Name>
215 {
216 91 static void add(PointDataTreeT& tree, const Name& uniformValue) {
217
1/2
✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
91 MetaMap& metadata = makeDescriptorUnique(tree)->getMetadata();
218 91 StringMetaInserter inserter(metadata);
219
1/2
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
91 inserter.insert(uniformValue);
220 91 }
221
222 template<typename AttributeListType>
223 2 static void add(PointDataTreeT& tree, const AttributeListType& data) {
224
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 MetaMap& metadata = makeDescriptorUnique(tree)->getMetadata();
225 2 StringMetaInserter inserter(metadata);
226 Name value;
227
228
2/2
✓ Branch 0 taken 1000025 times.
✓ Branch 1 taken 2 times.
1000027 for (size_t i = 0; i < data.size(); i++) {
229 data.get(value, i);
230
1/2
✓ Branch 1 taken 1000025 times.
✗ Branch 2 not taken.
1000025 inserter.insert(value);
231 }
232 2 }
233 };
234
235
236 } // namespace point_attribute_internal
237
238 /// @endcond
239
240
241 ////////////////////////////////////////
242
243
244 template <typename PointDataTreeT>
245 7104 inline void appendAttribute(PointDataTreeT& tree,
246 const Name& name,
247 const NamePair& type,
248 const Index strideOrTotalSize,
249 const bool constantStride,
250 const Metadata* defaultValue,
251 const bool hidden,
252 const bool transient)
253 {
254 auto iter = tree.cbeginLeaf();
255
256
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7103 times.
7104 if (!iter) return;
257
258 // do not append a non-unique attribute
259
260 const auto& descriptor = iter->attributeSet().descriptor();
261 7103 const size_t index = descriptor.find(name);
262
263
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7102 times.
7103 if (index != AttributeSet::INVALID_POS) {
264
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5 OPENVDB_THROW(KeyError,
265 "Cannot append an attribute with a non-unique name - " << name << ".");
266 }
267
268 // create a new attribute descriptor
269
270 7102 auto newDescriptor = descriptor.duplicateAppend(name, type);
271
272 // store the attribute default value in the descriptor metadata
273
274
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7099 times.
7101 if (defaultValue) {
275
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 newDescriptor->setDefaultValue(name, *defaultValue);
276 }
277
278 // extract new pos
279
280
1/2
✓ Branch 1 taken 7101 times.
✗ Branch 2 not taken.
7101 const size_t pos = newDescriptor->find(name);
281
282 // acquire registry lock to avoid locking when appending attributes in parallel
283
284
1/2
✓ Branch 1 taken 7101 times.
✗ Branch 2 not taken.
7101 AttributeArray::ScopedRegistryLock lock;
285
286 // insert attributes using the new descriptor
287
288
1/2
✓ Branch 1 taken 7101 times.
✗ Branch 2 not taken.
7101 tree::LeafManager<PointDataTreeT> leafManager(tree);
289
1/2
✓ Branch 1 taken 7101 times.
✗ Branch 2 not taken.
7101 leafManager.foreach(
290 69782 [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
291 auto expected = leaf.attributeSet().descriptorPtr();
292
293
1/2
✓ Branch 1 taken 34891 times.
✗ Branch 2 not taken.
34891 auto attribute = leaf.appendAttribute(*expected, newDescriptor,
294 pos, strideOrTotalSize, constantStride, defaultValue,
295 &lock);
296
297
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 34887 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
34891 if (hidden) attribute->setHidden(true);
298
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 34887 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
34891 if (transient) attribute->setTransient(true);
299 }, /*threaded=*/ true
300 );
301 }
302
303
304 ////////////////////////////////////////
305
306
307 template <typename ValueType, typename CodecType, typename PointDataTreeT>
308 14012 inline void appendAttribute(PointDataTreeT& tree,
309 const std::string& name,
310 const ValueType& uniformValue,
311 const Index strideOrTotalSize,
312 const bool constantStride,
313 const TypedMetadata<ValueType>* defaultValue,
314 const bool hidden,
315 const bool transient)
316 {
317 static_assert(!std::is_base_of<AttributeArray, ValueType>::value,
318 "ValueType must not be derived from AttributeArray");
319
320 using point_attribute_internal::AttributeTypeConversion;
321 using point_attribute_internal::Default;
322 using point_attribute_internal::MetadataStorage;
323
324 14012 appendAttribute(tree, name, AttributeTypeConversion<ValueType, CodecType>::type(),
325 strideOrTotalSize, constantStride, defaultValue, hidden, transient);
326
327 // if the uniform value is equal to either the default value provided
328 // through the metadata argument or the default value for this value type,
329 // it is not necessary to perform the collapse
330
331 const bool uniformIsDefault = math::isExactlyEqual(uniformValue,
332
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7006 times.
18508 bool(defaultValue) ? defaultValue->value() : Default<ValueType>::value());
333
2/2
✓ Branch 0 taken 2348 times.
✓ Branch 1 taken 2407 times.
9508 if (!uniformIsDefault) {
334 182 MetadataStorage<PointDataTreeT, ValueType>::add(tree, uniformValue);
335 7327 collapseAttribute<ValueType>(tree, name, uniformValue);
336 }
337 14008 }
338
339
340 ////////////////////////////////////////
341
342
343 template <typename ValueType, typename PointDataTreeT>
344 3687 inline void collapseAttribute( PointDataTreeT& tree,
345 const Name& name,
346 const ValueType& uniformValue)
347 {
348 static_assert(!std::is_base_of<AttributeArray, ValueType>::value,
349 "ValueType must not be derived from AttributeArray");
350
351 auto iter = tree.cbeginLeaf();
352
353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
3687 if (!iter) return;
354
355 const auto& descriptor = iter->attributeSet().descriptor();
356
357 // throw if attribute name does not exist
358
359 3687 const size_t index = descriptor.find(name);
360
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24 times.
3687 if (index == AttributeSet::INVALID_POS) {
361
2/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
12 OPENVDB_THROW(KeyError, "Cannot find attribute name in PointDataTree.");
362 }
363
364 3684 tree::LeafManager<PointDataTreeT> leafManager(tree);
365
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
3684 leafManager.foreach(
366 31971 [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
367
17/40
✗ Branch 0 not taken.
✓ Branch 1 taken 596 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4301 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 981 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 240 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 247 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 276 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 272 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 276 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 300 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 360 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 240 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 244 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 244 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 700 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 180 times.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 51 not taken.
✓ Branch 52 taken 420 times.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 57 not taken.
✓ Branch 58 taken 780 times.
10657 assert(leaf.hasAttribute(index));
368 10657 AttributeArray& array = leaf.attributeArray(index);
369 10657 point_attribute_internal::collapseAttribute(
370 array, descriptor, uniformValue);
371 }, /*threaded=*/true
372 );
373 }
374
375
376 ////////////////////////////////////////
377
378
379 template <typename PointDataTreeT>
380 29 inline void dropAttributes( PointDataTreeT& tree,
381 const std::vector<size_t>& indices)
382 {
383 auto iter = tree.cbeginLeaf();
384
385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 if (!iter) return;
386
387 const auto& descriptor = iter->attributeSet().descriptor();
388
389 // throw if position index present in the indices as this attribute is mandatory
390
391
2/4
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
29 const size_t positionIndex = descriptor.find("P");
392
3/4
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 27 times.
58 if (positionIndex!= AttributeSet::INVALID_POS &&
393
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
31 std::find(indices.begin(), indices.end(), positionIndex) != indices.end()) {
394
2/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
8 OPENVDB_THROW(KeyError, "Cannot drop mandatory position attribute.");
395 }
396
397 // insert attributes using the new descriptor
398
399 27 auto newDescriptor = descriptor.duplicateDrop(indices);
400
401
1/2
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
27 tree::LeafManager<PointDataTreeT> leafManager(tree);
402
1/2
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
27 leafManager.foreach(
403
1/2
✓ Branch 2 taken 78 times.
✗ Branch 3 not taken.
156 [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
404 auto expected = leaf.attributeSet().descriptorPtr();
405 leaf.dropAttributes(indices, *expected, newDescriptor);
406 }, /*threaded=*/true
407 );
408 }
409
410
411 ////////////////////////////////////////
412
413
414 template <typename PointDataTreeT>
415 15 inline void dropAttributes( PointDataTreeT& tree,
416 const std::vector<Name>& names)
417 {
418 auto iter = tree.cbeginLeaf();
419
420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (!iter) return;
421
422 const AttributeSet& attributeSet = iter->attributeSet();
423 const AttributeSet::Descriptor& descriptor = attributeSet.descriptor();
424
425 std::vector<size_t> indices;
426
427
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 14 times.
30 for (const Name& name : names) {
428
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 const size_t index = descriptor.find(name);
429
430 // do not attempt to drop an attribute that does not exist
431
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 if (index == AttributeSet::INVALID_POS) {
432
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5 OPENVDB_THROW(KeyError,
433 "Cannot drop an attribute that does not exist - " << name << ".");
434 }
435
436
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 indices.push_back(index);
437 }
438
439
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 1 times.
14 dropAttributes(tree, indices);
440 }
441
442
443 ////////////////////////////////////////
444
445
446 template <typename PointDataTreeT>
447 1 inline void dropAttribute( PointDataTreeT& tree,
448 const size_t& index)
449 {
450 1 std::vector<size_t> indices{index};
451
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 dropAttributes(tree, indices);
452 1 }
453
454
455 template <typename PointDataTreeT>
456 12 inline void dropAttribute( PointDataTreeT& tree,
457 const Name& name)
458 {
459
1/4
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
24 std::vector<Name> names{name};
460
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 dropAttributes(tree, names);
461 12 }
462
463
464 ////////////////////////////////////////
465
466
467 template <typename PointDataTreeT>
468
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
10 inline void renameAttributes( PointDataTreeT& tree,
469 const std::vector<Name>& oldNames,
470 const std::vector<Name>& newNames)
471 {
472
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
10 if (oldNames.size() != newNames.size()) {
473
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
4 OPENVDB_THROW(ValueError, "Mis-matching sizes of name vectors, cannot rename attributes.");
474 }
475
476 using Descriptor = AttributeSet::Descriptor;
477
478 auto iter = tree.beginLeaf();
479
480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (!iter) return;
481
482 const AttributeSet& attributeSet = iter->attributeSet();
483 const Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
484
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 auto newDescriptor = std::make_shared<Descriptor>(*descriptor);
485
486
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 6 times.
16 for (size_t i = 0; i < oldNames.size(); i++) {
487 const Name& oldName = oldNames[i];
488
3/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 9 times.
10 if (descriptor->find(oldName) == AttributeSet::INVALID_POS) {
489
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5 OPENVDB_THROW(KeyError, "Cannot find requested attribute - " << oldName << ".");
490 }
491
492 const Name& newName = newNames[i];
493
3/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 7 times.
9 if (descriptor->find(newName) != AttributeSet::INVALID_POS) {
494
2/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
10 OPENVDB_THROW(KeyError,
495 "Cannot rename attribute as new name already exists - " << newName << ".");
496 }
497
498
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 const AttributeArray* array = attributeSet.getConst(oldName);
499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 assert(array);
500
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (isGroup(*array)) {
502 OPENVDB_THROW(KeyError, "Cannot rename group attribute - " << oldName << ".");
503 }
504
505
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 newDescriptor->rename(oldName, newName);
506 }
507
508
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 for (; iter; ++iter) {
509 iter->renameAttributes(*descriptor, newDescriptor);
510 }
511 }
512
513
514 template <typename PointDataTreeT>
515 8 inline void renameAttribute(PointDataTreeT& tree,
516 const Name& oldName,
517 const Name& newName)
518 {
519
13/16
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 5 times.
✓ Branch 12 taken 3 times.
✓ Branch 14 taken 5 times.
✓ Branch 15 taken 5 times.
✓ Branch 18 taken 5 times.
✓ Branch 19 taken 5 times.
✓ Branch 22 taken 3 times.
✓ Branch 23 taken 3 times.
✓ Branch 26 taken 3 times.
✓ Branch 27 taken 3 times.
33 renameAttributes(tree, {oldName}, {newName});
520 5 }
521
522
523 ////////////////////////////////////////
524
525
526 template <typename PointDataTreeT>
527 1 inline void compactAttributes(PointDataTreeT& tree)
528 {
529 auto iter = tree.beginLeaf();
530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!iter) return;
531
532 1 tree::LeafManager<PointDataTreeT> leafManager(tree);
533
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 leafManager.foreach(
534 [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
535 2 leaf.compactAttributes();
536 }, /*threaded=*/ true
537 );
538 }
539
540
541 ////////////////////////////////////////
542
543
544 } // namespace points
545 } // namespace OPENVDB_VERSION_NAME
546 } // namespace openvdb
547
548 #endif // OPENVDB_POINTS_POINT_ATTRIBUTE_HAS_BEEN_INCLUDED
549