OpenVDB: PointAttribute.h Source File

OpenVDB 8.1.0

PointAttribute.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_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 static inline ValueType value() { return zeroVal<ValueType>(); }
32 };
33
34 } // namespace point_attribute_internal
35
36
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
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 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
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
96 template <typename PointDataTreeT>
97 inline void dropAttributes( PointDataTreeT& tree,
98 const std::vector<size_t>& indices);
99
104 template <typename PointDataTreeT>
105 inline void dropAttributes( PointDataTreeT& tree,
106 const std::vector<Name>& names);
107
112 template <typename PointDataTreeT>
113 inline void dropAttribute( PointDataTreeT& tree,
114 const size_t& index);
115
120 template <typename PointDataTreeT>
121 inline void dropAttribute( PointDataTreeT& tree,
122 const Name& name);
123
133 template <typename PointDataTreeT>
134 inline void renameAttributes(PointDataTreeT& tree,
135 const std::vector<Name>& oldNames,
136 const std::vector<Name>& newNames);
137
145 template <typename PointDataTreeT>
146 inline void renameAttribute(PointDataTreeT& tree,
147 const Name& oldName,
148 const Name& newName);
149
153 template <typename PointDataTreeT>
154 inline void compactAttributes(PointDataTreeT& tree);
155
156
158
159
160 namespace point_attribute_internal {
161
162
163 template <typename ValueType>
164 inline void collapseAttribute(AttributeArray& array,
165 const AttributeSet::Descriptor&, const ValueType& uniformValue)
166 {
167 AttributeWriteHandle<ValueType> handle(array);
168 handle.collapse(uniformValue);
169 }
170
171
172 inline void collapseAttribute(AttributeArray& array,
173 const AttributeSet::Descriptor& descriptor, const Name& uniformValue)
174 {
175 StringAttributeWriteHandle handle(array, descriptor.getMetadata());
176 handle.collapse(uniformValue);
177 }
178
179
181
182
183 template <typename ValueType, typename CodecType>
184 struct AttributeTypeConversion
185 {
186 static const NamePair& type() {
187 return TypedAttributeArray<ValueType, CodecType>::attributeType();
188 }
189 };
190
191
192 template <typename CodecType>
193 struct AttributeTypeConversion<Name, CodecType>
194 {
195 static const NamePair& type() { return StringAttributeArray::attributeType(); }
196 };
197
198
200
201
202 template <typename PointDataTreeT, typename ValueType>
203 struct MetadataStorage
204 {
205 static void add(PointDataTreeT&, const ValueType&) {}
206
207 template<typename AttributeListType>
208 static void add(PointDataTreeT&, const AttributeListType&) {}
209 };
210
211
212 template <typename PointDataTreeT>
213 struct MetadataStorage<PointDataTreeT, Name>
214 {
215 static void add(PointDataTreeT& tree, const Name& uniformValue) {
216 MetaMap& metadata = makeDescriptorUnique(tree)->getMetadata();
217 StringMetaInserter inserter(metadata);
218 inserter.insert(uniformValue);
219 }
220
221 template<typename AttributeListType>
222 static void add(PointDataTreeT& tree, const AttributeListType& data) {
223 MetaMap& metadata = makeDescriptorUnique(tree)->getMetadata();
224 StringMetaInserter inserter(metadata);
225 Name value;
226
227 for (size_t i = 0; i < data.size(); i++) {
228 data.get(value, i);
229 inserter.insert(value);
230 }
231 }
232 };
233
234
235 } // namespace point_attribute_internal
236
237
239
240
241 template <typename PointDataTreeT>
242 inline void appendAttribute(PointDataTreeT& tree,
243 const Name& name,
244 const NamePair& type,
245 const Index strideOrTotalSize,
246 const bool constantStride,
247 const Metadata* defaultValue,
248 const bool hidden,
249 const bool transient)
250 {
251 auto iter = tree.cbeginLeaf();
252
253 if (!iter) return;
254
255 // do not append a non-unique attribute
256
257 const auto& descriptor = iter->attributeSet().descriptor();
258 const size_t index = descriptor.find(name);
259
260 if (index != AttributeSet::INVALID_POS) {
261 OPENVDB_THROW(KeyError,
262 "Cannot append an attribute with a non-unique name - " << name << ".");
263 }
264
265 // create a new attribute descriptor
266
267 auto newDescriptor = descriptor.duplicateAppend(name, type);
268
269 // store the attribute default value in the descriptor metadata
270
271 if (defaultValue) {
272 newDescriptor->setDefaultValue(name, *defaultValue);
273 }
274
275 // extract new pos
276
277 const size_t pos = newDescriptor->find(name);
278
279 // acquire registry lock to avoid locking when appending attributes in parallel
280
281 AttributeArray::ScopedRegistryLock lock;
282
283 // insert attributes using the new descriptor
284
285 tree::LeafManager<PointDataTreeT> leafManager(tree);
286 leafManager.foreach(
287 [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
288 auto expected = leaf.attributeSet().descriptorPtr();
289
290 auto attribute = leaf.appendAttribute(*expected, newDescriptor,
291 pos, strideOrTotalSize, constantStride, defaultValue,
292 &lock);
293
294 if (hidden) attribute->setHidden(true);
295 if (transient) attribute->setTransient(true);
296 }, /*threaded=*/ true
297 );
298 }
299
300
302
303
304 template <typename ValueType, typename CodecType, typename PointDataTreeT>
305 inline void appendAttribute(PointDataTreeT& tree,
306 const std::string& name,
307 const ValueType& uniformValue,
308 const Index strideOrTotalSize,
309 const bool constantStride,
310 const TypedMetadata<ValueType>* defaultValue,
311 const bool hidden,
312 const bool transient)
313 {
314 static_assert(!std::is_base_of<AttributeArray, ValueType>::value,
315 "ValueType must not be derived from AttributeArray");
316
317 using point_attribute_internal::AttributeTypeConversion;
318 using point_attribute_internal::Default;
319 using point_attribute_internal::MetadataStorage;
320
321 appendAttribute(tree, name, AttributeTypeConversion<ValueType, CodecType>::type(),
322 strideOrTotalSize, constantStride, defaultValue, hidden, transient);
323
324 // if the uniform value is equal to either the default value provided
325 // through the metadata argument or the default value for this value type,
326 // it is not necessary to perform the collapse
327
328 const bool uniformIsDefault = math::isExactlyEqual(uniformValue,
329 bool(defaultValue) ? defaultValue->value() : Default<ValueType>::value());
330 if (!uniformIsDefault) {
331 MetadataStorage<PointDataTreeT, ValueType>::add(tree, uniformValue);
332 collapseAttribute<ValueType>(tree, name, uniformValue);
333 }
334 }
335
336
338
339
340 template <typename ValueType, typename PointDataTreeT>
341 inline void collapseAttribute( PointDataTreeT& tree,
342 const Name& name,
343 const ValueType& uniformValue)
344 {
345 static_assert(!std::is_base_of<AttributeArray, ValueType>::value,
346 "ValueType must not be derived from AttributeArray");
347
348 auto iter = tree.cbeginLeaf();
349
350 if (!iter) return;
351
352 const auto& descriptor = iter->attributeSet().descriptor();
353
354 // throw if attribute name does not exist
355
356 const size_t index = descriptor.find(name);
357 if (index == AttributeSet::INVALID_POS) {
358 OPENVDB_THROW(KeyError, "Cannot find attribute name in PointDataTree.");
359 }
360
361 tree::LeafManager<PointDataTreeT> leafManager(tree);
362 leafManager.foreach(
363 [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
364 assert(leaf.hasAttribute(index));
365 AttributeArray& array = leaf.attributeArray(index);
366 point_attribute_internal::collapseAttribute(
367 array, descriptor, uniformValue);
368 }, /*threaded=*/true
369 );
370 }
371
372
374
375
376 template <typename PointDataTreeT>
377 inline void dropAttributes( PointDataTreeT& tree,
378 const std::vector<size_t>& indices)
379 {
380 auto iter = tree.cbeginLeaf();
381
382 if (!iter) return;
383
384 const auto& descriptor = iter->attributeSet().descriptor();
385
386 // throw if position index present in the indices as this attribute is mandatory
387
388 const size_t positionIndex = descriptor.find("P");
389 if (positionIndex!= AttributeSet::INVALID_POS &&
390 std::find(indices.begin(), indices.end(), positionIndex) != indices.end()) {
391 OPENVDB_THROW(KeyError, "Cannot drop mandatory position attribute.");
392 }
393
394 // insert attributes using the new descriptor
395
396 auto newDescriptor = descriptor.duplicateDrop(indices);
397
398 tree::LeafManager<PointDataTreeT> leafManager(tree);
399 leafManager.foreach(
400 [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
401 auto expected = leaf.attributeSet().descriptorPtr();
402 leaf.dropAttributes(indices, *expected, newDescriptor);
403 }, /*threaded=*/true
404 );
405 }
406
407
409
410
411 template <typename PointDataTreeT>
412 inline void dropAttributes( PointDataTreeT& tree,
413 const std::vector<Name>& names)
414 {
415 auto iter = tree.cbeginLeaf();
416
417 if (!iter) return;
418
419 const AttributeSet& attributeSet = iter->attributeSet();
420 const AttributeSet::Descriptor& descriptor = attributeSet.descriptor();
421
422 std::vector<size_t> indices;
423
424 for (const Name& name : names) {
425 const size_t index = descriptor.find(name);
426
427 // do not attempt to drop an attribute that does not exist
428 if (index == AttributeSet::INVALID_POS) {
429 OPENVDB_THROW(KeyError,
430 "Cannot drop an attribute that does not exist - " << name << ".");
431 }
432
433 indices.push_back(index);
434 }
435
436 dropAttributes(tree, indices);
437 }
438
439
441
442
443 template <typename PointDataTreeT>
444 inline void dropAttribute( PointDataTreeT& tree,
445 const size_t& index)
446 {
447 std::vector<size_t> indices{index};
448 dropAttributes(tree, indices);
449 }
450
451
452 template <typename PointDataTreeT>
453 inline void dropAttribute( PointDataTreeT& tree,
454 const Name& name)
455 {
456 std::vector<Name> names{name};
457 dropAttributes(tree, names);
458 }
459
460
462
463
464 template <typename PointDataTreeT>
465 inline void renameAttributes( PointDataTreeT& tree,
466 const std::vector<Name>& oldNames,
467 const std::vector<Name>& newNames)
468 {
469 if (oldNames.size() != newNames.size()) {
470 OPENVDB_THROW(ValueError, "Mis-matching sizes of name vectors, cannot rename attributes.");
471 }
472
473 using Descriptor = AttributeSet::Descriptor;
474
475 auto iter = tree.beginLeaf();
476
477 if (!iter) return;
478
479 const AttributeSet& attributeSet = iter->attributeSet();
480 const Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
481 auto newDescriptor = std::make_shared<Descriptor>(*descriptor);
482
483 for (size_t i = 0; i < oldNames.size(); i++) {
484 const Name& oldName = oldNames[i];
485 if (descriptor->find(oldName) == AttributeSet::INVALID_POS) {
486 OPENVDB_THROW(KeyError, "Cannot find requested attribute - " << oldName << ".");
487 }
488
489 const Name& newName = newNames[i];
490 if (descriptor->find(newName) != AttributeSet::INVALID_POS) {
491 OPENVDB_THROW(KeyError,
492 "Cannot rename attribute as new name already exists - " << newName << ".");
493 }
494
495 const AttributeArray* array = attributeSet.getConst(oldName);
496 assert(array);
497
498 if (isGroup(*array)) {
499 OPENVDB_THROW(KeyError, "Cannot rename group attribute - " << oldName << ".");
500 }
501
502 newDescriptor->rename(oldName, newName);
503 }
504
505 for (; iter; ++iter) {
506 iter->renameAttributes(*descriptor, newDescriptor);
507 }
508 }
509
510
511 template <typename PointDataTreeT>
512 inline void renameAttribute(PointDataTreeT& tree,
513 const Name& oldName,
514 const Name& newName)
515 {
516 renameAttributes(tree, {oldName}, {newName});
517 }
518
519
521
522
523 template <typename PointDataTreeT>
524 inline void compactAttributes(PointDataTreeT& tree)
525 {
526 auto iter = tree.beginLeaf();
527 if (!iter) return;
528
529 tree::LeafManager<PointDataTreeT> leafManager(tree);
530 leafManager.foreach(
531 [&](typename PointDataTreeT::LeafNodeType& leaf, size_t /*idx*/) {
532 leaf.compactAttributes();
533 }, /*threaded=*/ true
534 );
535 }
536
537
539
540
541 } // namespace points
542 } // namespace OPENVDB_VERSION_NAME
543 } // namespace openvdb
544
545 #endif // OPENVDB_POINTS_POINT_ATTRIBUTE_HAS_BEEN_INCLUDED
AttributeArrayString.h
Attribute array storage for string data using Descriptor Metadata.
AttributeGroup.h
Attribute Group access and filtering for iteration.
AttributeSet.h
Set of Attribute Arrays which tracks metadata about each array.
PointDataGrid.h
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
openvdb::v8_1::KeyError
Definition: openvdb/Exceptions.h:59
openvdb::v8_1::MetaMap
Container that maps names (strings) to values of arbitrary types.
Definition: MetaMap.h:20
openvdb::v8_1::Metadata
Base class for storing metadata information in a grid.
Definition: Metadata.h:24
openvdb::v8_1::TypedMetadata
Templated metadata class to hold specific types.
Definition: Metadata.h:122
openvdb::v8_1::TypedMetadata::value
T & value()
Return this metadata's value.
Definition: Metadata.h:249
openvdb::v8_1::ValueError
Definition: openvdb/Exceptions.h:65
openvdb::v8_1::points::AttributeArray::ScopedRegistryLock
Definition: AttributeArray.h:119
openvdb::v8_1::points::AttributeArray
Base class for storing attribute data.
Definition: AttributeArray.h:93
openvdb::v8_1::points::AttributeSet
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:39
openvdb::v8_1::points::AttributeSet::descriptorPtr
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:108
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::AttributeSet::descriptor
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:102
openvdb::v8_1::points::AttributeWriteHandle
Write-able version of AttributeHandle.
Definition: AttributeArray.h:872
openvdb::v8_1::points::AttributeWriteHandle::collapse
void collapse()
Replace the existing array with a uniform value (zero if none provided).
Definition: AttributeArray.h:2214
openvdb::v8_1::points::StringAttributeWriteHandle
Definition: AttributeArrayString.h:187
openvdb::v8_1::points::StringAttributeWriteHandle::collapse
void collapse()
Set membership for the whole array and attempt to collapse.
openvdb::v8_1::points::StringMetaInserter
Class to help with insertion of keyed string values into metadata.
Definition: AttributeArrayString.h:89
openvdb::v8_1::points::StringMetaInserter::insert
Index insert(const Name &name, Index hint=Index(0))
Insert the string into the metadata using the hint if non-zero.
openvdb::v8_1::points::TypedAttributeArray
Typed class for storing attribute data.
Definition: AttributeArray.h:528
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:85
openvdb::v8_1::tree::LeafManager::foreach
void foreach(const LeafOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to each leaf node in the LeafManager.
Definition: LeafManager.h:483
openvdb::v8_1::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:444
openvdb::v8_1::points::point_attribute_internal::collapseAttribute
void collapseAttribute(AttributeArray &array, const AttributeSet::Descriptor &descriptor, const Name &uniformValue)
Definition: PointAttribute.h:172
openvdb::v8_1::points::appendAttribute
void appendAttribute(PointDataTreeT &tree, const std::string &name, const ValueType &uniformValue=point_attribute_internal::Default< ValueType >::value(), const Index strideOrTotalSize=1, const bool constantStride=true, const TypedMetadata< ValueType > *defaultValue=nullptr, const bool hidden=false, const bool transient=false)
Appends a new attribute to the VDB tree.
Definition: PointAttribute.h:305
openvdb::v8_1::points::isGroup
bool isGroup(const AttributeArray &array)
Definition: AttributeGroup.h:63
openvdb::v8_1::points::compactAttributes
void compactAttributes(PointDataTreeT &tree)
Compact attributes in a VDB tree (if possible).
Definition: PointAttribute.h:524
openvdb::v8_1::points::dropAttributes
void dropAttributes(PointDataTreeT &tree, const std::vector< Name > &names)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:412
openvdb::v8_1::points::dropAttribute
void dropAttribute(PointDataTreeT &tree, const Name &name)
Drop one attribute from the VDB tree (convenience method).
Definition: PointAttribute.h:453
openvdb::v8_1::points::renameAttributes
void renameAttributes(PointDataTreeT &tree, const std::vector< Name > &oldNames, const std::vector< Name > &newNames)
Rename attributes in a VDB tree.
Definition: PointAttribute.h:465
openvdb::v8_1::points::renameAttribute
void renameAttribute(PointDataTreeT &tree, const Name &oldName, const Name &newName)
Rename an attribute in a VDB tree.
Definition: PointAttribute.h:512
openvdb::v8_1::points::makeDescriptorUnique
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1577
openvdb::v8_1::Name
std::string Name
Definition: Name.h:17
openvdb::v8_1::Index
Index32 Index
Definition: openvdb/Types.h:50
openvdb::v8_1::NamePair
std::pair< Name, Name > NamePair
Definition: AttributeArray.h:39
openvdb
Definition: openvdb/Exceptions.h:13
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
openvdb.h
openvdb::v8_1::points::point_attribute_internal::AttributeTypeConversion< Name, CodecType >::type
static const NamePair & type()
Definition: PointAttribute.h:195
openvdb::v8_1::points::point_attribute_internal::AttributeTypeConversion
Definition: PointAttribute.h:185
openvdb::v8_1::points::point_attribute_internal::AttributeTypeConversion::type
static const NamePair & type()
Definition: PointAttribute.h:186
openvdb::v8_1::points::point_attribute_internal::Default
Definition: PointAttribute.h:30
openvdb::v8_1::points::point_attribute_internal::Default::value
static ValueType value()
Definition: PointAttribute.h:31
openvdb::v8_1::points::point_attribute_internal::MetadataStorage< PointDataTreeT, Name >::add
static void add(PointDataTreeT &tree, const Name &uniformValue)
Definition: PointAttribute.h:215
openvdb::v8_1::points::point_attribute_internal::MetadataStorage< PointDataTreeT, Name >::add
static void add(PointDataTreeT &tree, const AttributeListType &data)
Definition: PointAttribute.h:222
openvdb::v8_1::points::point_attribute_internal::MetadataStorage
Definition: PointAttribute.h:204
openvdb::v8_1::points::point_attribute_internal::MetadataStorage::add
static void add(PointDataTreeT &, const ValueType &)
Definition: PointAttribute.h:205
openvdb::v8_1::points::point_attribute_internal::MetadataStorage::add
static void add(PointDataTreeT &, const AttributeListType &)
Definition: PointAttribute.h:208
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178