10#ifndef OPENVDB_POINTS_POINT_ATTRIBUTE_HAS_BEEN_INCLUDED
11#define OPENVDB_POINTS_POINT_ATTRIBUTE_HAS_BEEN_INCLUDED
26namespace point_attribute_internal {
28template <
typename ValueType>
31 static inline ValueType
value() {
return zeroVal<ValueType>(); }
48template <
typename Po
intDataTreeT>
49inline void appendAttribute(PointDataTreeT& tree,
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);
68template <
typename ValueType,
69 typename CodecType = NullCodec,
70 typename PointDataTreeT>
71inline 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,
78 const bool hidden =
false,
79 const bool transient =
false);
86template <
typename ValueType,
typename Po
intDataTreeT>
87inline void collapseAttribute( PointDataTreeT& tree,
89 const ValueType& uniformValue =
90 point_attribute_internal::Default<ValueType>::value());
96template <
typename Po
intDataTreeT>
97inline void dropAttributes( PointDataTreeT& tree,
98 const std::vector<size_t>& indices);
104template <
typename Po
intDataTreeT>
105inline void dropAttributes( PointDataTreeT& tree,
106 const std::vector<Name>& names);
112template <
typename Po
intDataTreeT>
113inline void dropAttribute( PointDataTreeT& tree,
114 const size_t& index);
120template <
typename Po
intDataTreeT>
121inline void dropAttribute( PointDataTreeT& tree,
133template <
typename Po
intDataTreeT>
134inline void renameAttributes(PointDataTreeT& tree,
135 const std::vector<Name>& oldNames,
136 const std::vector<Name>& newNames);
145template <
typename Po
intDataTreeT>
146inline void renameAttribute(PointDataTreeT& tree,
148 const Name& newName);
153template <
typename Po
intDataTreeT>
154inline void compactAttributes(PointDataTreeT& tree);
161namespace point_attribute_internal {
164template <
typename ValueType>
165inline void collapseAttribute(AttributeArray& array,
166 const AttributeSet::Descriptor&,
const ValueType& uniformValue)
168 AttributeWriteHandle<ValueType> handle(array);
169 handle.collapse(uniformValue);
173inline void collapseAttribute(AttributeArray& array,
174 const AttributeSet::Descriptor& descriptor,
const Name& uniformValue)
176 StringAttributeWriteHandle handle(array, descriptor.getMetadata());
177 handle.collapse(uniformValue);
184template <
typename ValueType,
typename CodecType>
185struct AttributeTypeConversion
187 static const NamePair& type() {
188 return TypedAttributeArray<ValueType, CodecType>::attributeType();
193template <
typename CodecType>
194struct AttributeTypeConversion<
Name, CodecType>
196 static const NamePair& type() {
return StringAttributeArray::attributeType(); }
203template <
typename Po
intDataTreeT,
typename ValueType>
204struct MetadataStorage
206 static void add(PointDataTreeT&,
const ValueType&) {}
208 template<
typename AttributeListType>
209 static void add(PointDataTreeT&,
const AttributeListType&) {}
213template <
typename Po
intDataTreeT>
214struct MetadataStorage<PointDataTreeT,
Name>
216 static void add(PointDataTreeT& tree,
const Name& uniformValue) {
218 StringMetaInserter inserter(metadata);
219 inserter.insert(uniformValue);
222 template<
typename AttributeListType>
223 static void add(PointDataTreeT& tree,
const AttributeListType& data) {
225 StringMetaInserter inserter(metadata);
228 for (
size_t i = 0; i < data.size(); i++) {
230 inserter.insert(
value);
244template <
typename Po
intDataTreeT>
248 const Index strideOrTotalSize,
249 const bool constantStride,
252 const bool transient)
254 auto iter = tree.cbeginLeaf();
260 const auto& descriptor = iter->attributeSet().descriptor();
261 const size_t index = descriptor.find(name);
263 if (index != AttributeSet::INVALID_POS) {
265 "Cannot append an attribute with a non-unique name - " << name <<
".");
270 auto newDescriptor = descriptor.duplicateAppend(name, type);
275 newDescriptor->setDefaultValue(name, *defaultValue);
280 const size_t pos = newDescriptor->find(name);
290 [&](
typename PointDataTreeT::LeafNodeType& leaf,
size_t ) {
291 auto expected = leaf.attributeSet().descriptorPtr();
293 auto attribute = leaf.appendAttribute(*expected, newDescriptor,
294 pos, strideOrTotalSize, constantStride, defaultValue,
297 if (hidden) attribute->setHidden(
true);
298 if (transient) attribute->setTransient(
true);
307template <
typename ValueType,
typename CodecType,
typename Po
intDataTreeT>
309 const std::string& name,
310 const ValueType& uniformValue,
311 const Index strideOrTotalSize,
312 const bool constantStride,
315 const bool transient)
317 static_assert(!std::is_base_of<AttributeArray, ValueType>::value,
318 "ValueType must not be derived from AttributeArray");
320 using point_attribute_internal::AttributeTypeConversion;
322 using point_attribute_internal::MetadataStorage;
324 appendAttribute(tree, name, AttributeTypeConversion<ValueType, CodecType>::type(),
325 strideOrTotalSize, constantStride, defaultValue, hidden, transient);
331 const bool uniformIsDefault = math::isExactlyEqual(uniformValue,
332 bool(defaultValue) ? defaultValue->
value() : Default<ValueType>::value());
333 if (!uniformIsDefault) {
334 MetadataStorage<PointDataTreeT, ValueType>::add(tree, uniformValue);
335 collapseAttribute<ValueType>(tree, name, uniformValue);
343template <
typename ValueType,
typename Po
intDataTreeT>
346 const ValueType& uniformValue)
348 static_assert(!std::is_base_of<AttributeArray, ValueType>::value,
349 "ValueType must not be derived from AttributeArray");
351 auto iter = tree.cbeginLeaf();
355 const auto& descriptor = iter->attributeSet().descriptor();
359 const size_t index = descriptor.find(name);
360 if (index == AttributeSet::INVALID_POS) {
366 [&](
typename PointDataTreeT::LeafNodeType& leaf,
size_t ) {
367 assert(leaf.hasAttribute(index));
369 point_attribute_internal::collapseAttribute(
370 array, descriptor, uniformValue);
379template <
typename Po
intDataTreeT>
381 const std::vector<size_t>& indices)
383 auto iter = tree.cbeginLeaf();
387 const auto& descriptor = iter->attributeSet().descriptor();
391 const size_t positionIndex = descriptor.find(
"P");
392 if (positionIndex!= AttributeSet::INVALID_POS &&
393 std::find(indices.begin(), indices.end(), positionIndex) != indices.end()) {
399 auto newDescriptor = descriptor.duplicateDrop(indices);
403 [&](
typename PointDataTreeT::LeafNodeType& leaf,
size_t ) {
404 auto expected = leaf.attributeSet().descriptorPtr();
405 leaf.dropAttributes(indices, *expected, newDescriptor);
414template <
typename Po
intDataTreeT>
416 const std::vector<Name>& names)
418 auto iter = tree.cbeginLeaf();
422 const AttributeSet& attributeSet = iter->attributeSet();
423 const AttributeSet::Descriptor& descriptor = attributeSet.
descriptor();
425 std::vector<size_t> indices;
427 for (
const Name& name : names) {
428 const size_t index = descriptor.find(name);
431 if (index == AttributeSet::INVALID_POS) {
433 "Cannot drop an attribute that does not exist - " << name <<
".");
436 indices.push_back(index);
446template <
typename Po
intDataTreeT>
450 std::vector<size_t> indices{index};
455template <
typename Po
intDataTreeT>
459 std::vector<Name> names{name};
467template <
typename Po
intDataTreeT>
469 const std::vector<Name>& oldNames,
470 const std::vector<Name>& newNames)
472 if (oldNames.size() != newNames.size()) {
476 using Descriptor = AttributeSet::Descriptor;
478 auto iter = tree.beginLeaf();
482 const AttributeSet& attributeSet = iter->attributeSet();
483 const Descriptor::Ptr descriptor = attributeSet.
descriptorPtr();
484 auto newDescriptor = std::make_shared<Descriptor>(*descriptor);
486 for (
size_t i = 0; i < oldNames.size(); i++) {
487 const Name& oldName = oldNames[i];
488 if (descriptor->find(oldName) == AttributeSet::INVALID_POS) {
492 const Name& newName = newNames[i];
493 if (descriptor->find(newName) != AttributeSet::INVALID_POS) {
495 "Cannot rename attribute as new name already exists - " << newName <<
".");
505 newDescriptor->rename(oldName, newName);
508 for (; iter; ++iter) {
509 iter->renameAttributes(*descriptor, newDescriptor);
514template <
typename Po
intDataTreeT>
526template <
typename Po
intDataTreeT>
529 auto iter = tree.beginLeaf();
534 [&](
typename PointDataTreeT::LeafNodeType& leaf,
size_t ) {
535 leaf.compactAttributes();
Attribute array storage for string data using Descriptor Metadata.
Attribute Group access and filtering for iteration.
Set of Attribute Arrays which tracks metadata about each array.
ValueT value
Definition: GridBuilder.h:1290
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Definition: Exceptions.h:59
Definition: Exceptions.h:65
Definition: AttributeArray.h:119
Base class for storing attribute data.
Definition: AttributeArray.h:93
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:39
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:108
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.
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets.
Definition: AttributeSet.h:102
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
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
void compactAttributes(PointDataTreeT &tree)
Compact attributes in a VDB tree (if possible).
Definition: PointAttribute.h:527
void dropAttribute(PointDataTreeT &tree, const size_t &index)
Drop one attribute from the VDB tree (convenience method).
Definition: PointAttribute.h:447
void collapseAttribute(PointDataTreeT &tree, const Name &name, const ValueType &uniformValue=point_attribute_internal::Default< ValueType >::value())
Collapse the attribute into a uniform value.
Definition: PointAttribute.h:344
bool isGroup(const AttributeArray &array)
Definition: AttributeGroup.h:63
void appendAttribute(PointDataTreeT &tree, const Name &name, const NamePair &type, const Index strideOrTotalSize=1, const bool constantStride=true, const Metadata *defaultValue=nullptr, const bool hidden=false, const bool transient=false)
Appends a new attribute to the VDB tree (this method does not require a templated AttributeType)
Definition: PointAttribute.h:245
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:380
void renameAttributes(PointDataTreeT &tree, const std::vector< Name > &oldNames, const std::vector< Name > &newNames)
Rename attributes in a VDB tree.
Definition: PointAttribute.h:468
void renameAttribute(PointDataTreeT &tree, const Name &oldName, const Name &newName)
Rename an attribute in a VDB tree.
Definition: PointAttribute.h:515
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1589
std::string Name
Definition: Name.h:17
Index32 Index
Definition: Types.h:54
std::pair< Name, Name > NamePair
Definition: AttributeArray.h:39
Definition: Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Definition: PointAttribute.h:30
static ValueType value()
Definition: PointAttribute.h:31
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212