OpenVDB  6.2.0
PointAttribute.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 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_ATTRIBUTE_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_ATTRIBUTE_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/openvdb.h>
41 
42 #include "AttributeArrayString.h"
43 #include "AttributeSet.h"
44 #include "AttributeGroup.h"
45 #include "PointDataGrid.h"
46 
47 
48 namespace openvdb {
50 namespace OPENVDB_VERSION_NAME {
51 namespace points {
52 
53 namespace point_attribute_internal {
54 
55 template <typename ValueType>
56 struct Default
57 {
58  static inline ValueType value() { return zeroVal<ValueType>(); }
59 };
60 
61 } // namespace point_attribute_internal
62 
63 
75 template <typename PointDataTreeT>
76 inline void appendAttribute(PointDataTreeT& tree,
77  const Name& name,
78  const NamePair& type,
79  const Index strideOrTotalSize = 1,
80  const bool constantStride = true,
81  Metadata::Ptr metaDefaultValue = Metadata::Ptr(),
82  const bool hidden = false,
83  const bool transient = false);
84 
95 template <typename ValueType,
96  typename CodecType = NullCodec,
97  typename PointDataTreeT = PointDataTree>
98 inline void appendAttribute(PointDataTreeT& tree,
99  const std::string& name,
100  const ValueType& uniformValue =
102  const Index strideOrTotalSize = 1,
103  const bool constantStride = true,
104  Metadata::Ptr metaDefaultValue = Metadata::Ptr(),
105  const bool hidden = false,
106  const bool transient = false);
107 
113 template <typename ValueType, typename PointDataTreeT>
114 inline void collapseAttribute( PointDataTreeT& tree,
115  const Name& name,
116  const ValueType& uniformValue =
118 
123 template <typename PointDataTreeT>
124 inline void dropAttributes( PointDataTreeT& tree,
125  const std::vector<size_t>& indices);
126 
131 template <typename PointDataTreeT>
132 inline void dropAttributes( PointDataTreeT& tree,
133  const std::vector<Name>& names);
134 
139 template <typename PointDataTreeT>
140 inline void dropAttribute( PointDataTreeT& tree,
141  const size_t& index);
142 
147 template <typename PointDataTreeT>
148 inline void dropAttribute( PointDataTreeT& tree,
149  const Name& name);
150 
160 template <typename PointDataTreeT>
161 inline void renameAttributes(PointDataTreeT& tree,
162  const std::vector<Name>& oldNames,
163  const std::vector<Name>& newNames);
164 
172 template <typename PointDataTreeT>
173 inline void renameAttribute(PointDataTreeT& tree,
174  const Name& oldName,
175  const Name& newName);
176 
180 template <typename PointDataTreeT>
181 inline void compactAttributes(PointDataTreeT& tree);
182 
183 
185 
186 
187 namespace point_attribute_internal {
188 
189 
190 template <typename ValueType>
192  const AttributeSet::Descriptor&, const ValueType& uniformValue)
193 {
194  AttributeWriteHandle<ValueType> handle(array);
195  handle.collapse(uniformValue);
196 }
197 
198 
200  const AttributeSet::Descriptor& descriptor, const Name& uniformValue)
201 {
202  StringAttributeWriteHandle handle(array, descriptor.getMetadata());
203  handle.collapse(uniformValue);
204 }
205 
206 
208 
209 
210 template <typename ValueType, typename CodecType>
212 {
213  static const NamePair& type() {
215  }
216 };
217 
218 
219 template <typename CodecType>
220 struct AttributeTypeConversion<Name, CodecType>
221 {
222  static const NamePair& type() { return StringAttributeArray::attributeType(); }
223 };
224 
225 
227 
228 
229 template <typename PointDataTreeT, typename ValueType>
231 {
232  static void add(PointDataTreeT&, const ValueType&) {}
233 
234  template<typename AttributeListType>
235  static void add(PointDataTreeT&, const AttributeListType&) {}
236 };
237 
238 
239 template <typename PointDataTreeT>
240 struct MetadataStorage<PointDataTreeT, Name>
241 {
242  static void add(PointDataTreeT& tree, const Name& uniformValue) {
243  MetaMap& metadata = makeDescriptorUnique(tree)->getMetadata();
244  StringMetaInserter inserter(metadata);
245  inserter.insert(uniformValue);
246  }
247 
248  template<typename AttributeListType>
249  static void add(PointDataTreeT& tree, const AttributeListType& data) {
250  MetaMap& metadata = makeDescriptorUnique(tree)->getMetadata();
251  StringMetaInserter inserter(metadata);
252  Name value;
253 
254  for (size_t i = 0; i < data.size(); i++) {
255  data.get(value, i);
256  inserter.insert(value);
257  }
258  }
259 };
260 
261 
262 } // namespace point_attribute_internal
263 
264 
266 
267 
268 template <typename PointDataTreeT>
269 inline void appendAttribute(PointDataTreeT& tree,
270  const Name& name,
271  const NamePair& type,
272  const Index strideOrTotalSize,
273  const bool constantStride,
274  Metadata::Ptr metaDefaultValue,
275  const bool hidden,
276  const bool transient)
277 {
278  auto iter = tree.cbeginLeaf();
279 
280  if (!iter) return;
281 
282  // do not append a non-unique attribute
283 
284  const auto& descriptor = iter->attributeSet().descriptor();
285  const size_t index = descriptor.find(name);
286 
287  if (index != AttributeSet::INVALID_POS) {
289  "Cannot append an attribute with a non-unique name - " << name << ".");
290  }
291 
292  // create a new attribute descriptor
293 
294  auto newDescriptor = descriptor.duplicateAppend(name, type);
295 
296  // store the attribute default value in the descriptor metadata
297 
298  if (metaDefaultValue) {
299  newDescriptor->setDefaultValue(name, *metaDefaultValue);
300  }
301 
302  // extract new pos
303 
304  const size_t pos = newDescriptor->find(name);
305 
306  // acquire registry lock to avoid locking when appending attributes in parallel
307 
309 
310  // insert attributes using the new descriptor
311 
312  tree::LeafManager<PointDataTreeT> leafManager(tree);
313  leafManager.foreach(
314  [&](typename PointDataTree::LeafNodeType& leaf, size_t /*idx*/) {
315  auto expected = leaf.attributeSet().descriptorPtr();
316 
317  auto attribute = leaf.appendAttribute(*expected, newDescriptor,
318  pos, strideOrTotalSize, constantStride, &lock);
319 
320  if (hidden) attribute->setHidden(true);
321  if (transient) attribute->setTransient(true);
322  }, /*threaded=*/ true
323  );
324 }
325 
326 
328 
329 
330 template <typename ValueType, typename CodecType, typename PointDataTreeT>
331 inline void appendAttribute(PointDataTreeT& tree,
332  const std::string& name,
333  const ValueType& uniformValue,
334  const Index strideOrTotalSize,
335  const bool constantStride,
336  Metadata::Ptr metaDefaultValue,
337  const bool hidden,
338  const bool transient)
339 {
340  static_assert(!std::is_base_of<AttributeArray, ValueType>::value,
341  "ValueType must not be derived from AttributeArray");
342 
346 
347  appendAttribute(tree, name, AttributeTypeConversion<ValueType, CodecType>::type(),
348  strideOrTotalSize, constantStride, metaDefaultValue, hidden, transient);
349 
350  if (!math::isExactlyEqual(uniformValue, Default<ValueType>::value())) {
351  MetadataStorage<PointDataTreeT, ValueType>::add(tree, uniformValue);
352  collapseAttribute<ValueType>(tree, name, uniformValue);
353  }
354 }
355 
356 
358 
359 
360 template <typename ValueType, typename PointDataTreeT>
361 inline void collapseAttribute( PointDataTreeT& tree,
362  const Name& name,
363  const ValueType& uniformValue)
364 {
365  static_assert(!std::is_base_of<AttributeArray, ValueType>::value,
366  "ValueType must not be derived from AttributeArray");
367 
368  auto iter = tree.cbeginLeaf();
369 
370  if (!iter) return;
371 
372  const auto& descriptor = iter->attributeSet().descriptor();
373 
374  // throw if attribute name does not exist
375 
376  const size_t index = descriptor.find(name);
377  if (index == AttributeSet::INVALID_POS) {
378  OPENVDB_THROW(KeyError, "Cannot find attribute name in PointDataTree.");
379  }
380 
381  tree::LeafManager<PointDataTreeT> leafManager(tree);
382  leafManager.foreach(
383  [&](typename PointDataTree::LeafNodeType& leaf, size_t /*idx*/) {
384  assert(leaf.hasAttribute(index));
385  AttributeArray& array = leaf.attributeArray(index);
387  array, descriptor, uniformValue);
388  }, /*threaded=*/true
389  );
390 }
391 
392 
394 
395 
396 template <typename PointDataTreeT>
397 inline void dropAttributes( PointDataTreeT& tree,
398  const std::vector<size_t>& indices)
399 {
400  auto iter = tree.cbeginLeaf();
401 
402  if (!iter) return;
403 
404  const auto& descriptor = iter->attributeSet().descriptor();
405 
406  // throw if position index present in the indices as this attribute is mandatory
407 
408  const size_t positionIndex = descriptor.find("P");
409  if (positionIndex!= AttributeSet::INVALID_POS &&
410  std::find(indices.begin(), indices.end(), positionIndex) != indices.end()) {
411  OPENVDB_THROW(KeyError, "Cannot drop mandatory position attribute.");
412  }
413 
414  // insert attributes using the new descriptor
415 
416  auto newDescriptor = descriptor.duplicateDrop(indices);
417 
418  tree::LeafManager<PointDataTreeT> leafManager(tree);
419  leafManager.foreach(
420  [&](typename PointDataTree::LeafNodeType& leaf, size_t /*idx*/) {
421  auto expected = leaf.attributeSet().descriptorPtr();
422  leaf.dropAttributes(indices, *expected, newDescriptor);
423  }, /*threaded=*/true
424  );
425 }
426 
427 
429 
430 
431 template <typename PointDataTreeT>
432 inline void dropAttributes( PointDataTreeT& tree,
433  const std::vector<Name>& names)
434 {
435  auto iter = tree.cbeginLeaf();
436 
437  if (!iter) return;
438 
439  const AttributeSet& attributeSet = iter->attributeSet();
440  const AttributeSet::Descriptor& descriptor = attributeSet.descriptor();
441 
442  std::vector<size_t> indices;
443 
444  for (const Name& name : names) {
445  const size_t index = descriptor.find(name);
446 
447  // do not attempt to drop an attribute that does not exist
448  if (index == AttributeSet::INVALID_POS) {
450  "Cannot drop an attribute that does not exist - " << name << ".");
451  }
452 
453  indices.push_back(index);
454  }
455 
456  dropAttributes(tree, indices);
457 }
458 
459 
461 
462 
463 template <typename PointDataTreeT>
464 inline void dropAttribute( PointDataTreeT& tree,
465  const size_t& index)
466 {
467  std::vector<size_t> indices{index};
468  dropAttributes(tree, indices);
469 }
470 
471 
472 template <typename PointDataTreeT>
473 inline void dropAttribute( PointDataTreeT& tree,
474  const Name& name)
475 {
476  std::vector<Name> names{name};
477  dropAttributes(tree, names);
478 }
479 
480 
482 
483 
484 template <typename PointDataTreeT>
485 inline void renameAttributes( PointDataTreeT& tree,
486  const std::vector<Name>& oldNames,
487  const std::vector<Name>& newNames)
488 {
489  if (oldNames.size() != newNames.size()) {
490  OPENVDB_THROW(ValueError, "Mis-matching sizes of name vectors, cannot rename attributes.");
491  }
492 
493  using Descriptor = AttributeSet::Descriptor;
494 
495  auto iter = tree.beginLeaf();
496 
497  if (!iter) return;
498 
499  const AttributeSet& attributeSet = iter->attributeSet();
500  const Descriptor::Ptr descriptor = attributeSet.descriptorPtr();
501  auto newDescriptor = std::make_shared<Descriptor>(*descriptor);
502 
503  for (size_t i = 0; i < oldNames.size(); i++) {
504  const Name& oldName = oldNames[i];
505  if (descriptor->find(oldName) == AttributeSet::INVALID_POS) {
506  OPENVDB_THROW(KeyError, "Cannot find requested attribute - " << oldName << ".");
507  }
508 
509  const Name& newName = newNames[i];
510  if (descriptor->find(newName) != AttributeSet::INVALID_POS) {
512  "Cannot rename attribute as new name already exists - " << newName << ".");
513  }
514 
515  const AttributeArray* array = attributeSet.getConst(oldName);
516  assert(array);
517 
518  if (isGroup(*array)) {
519  OPENVDB_THROW(KeyError, "Cannot rename group attribute - " << oldName << ".");
520  }
521 
522  newDescriptor->rename(oldName, newName);
523  }
524 
525  for (; iter; ++iter) {
526  iter->renameAttributes(*descriptor, newDescriptor);
527  }
528 }
529 
530 
531 template <typename PointDataTreeT>
532 inline void renameAttribute(PointDataTreeT& tree,
533  const Name& oldName,
534  const Name& newName)
535 {
536  renameAttributes(tree, {oldName}, {newName});
537 }
538 
539 
541 
542 
543 template <typename PointDataTreeT>
544 inline void compactAttributes(PointDataTreeT& tree)
545 {
546  auto iter = tree.beginLeaf();
547  if (!iter) return;
548 
549  tree::LeafManager<PointDataTreeT> leafManager(tree);
550  leafManager.foreach(
551  [&](typename PointDataTree::LeafNodeType& leaf, size_t /*idx*/) {
552  leaf.compactAttributes();
553  }, /*threaded=*/ true
554  );
555 }
556 
557 
559 
560 
561 template <typename PointDataTreeT>
562 OPENVDB_DEPRECATED inline void bloscCompressAttribute( PointDataTreeT&,
563  const Name&)
564 {
565  // in-memory compression is no longer supported
566 }
567 
568 
570 
571 
572 } // namespace points
573 } // namespace OPENVDB_VERSION_NAME
574 } // namespace openvdb
575 
576 #endif // OPENVDB_POINTS_POINT_ATTRIBUTE_HAS_BEEN_INCLUDED
577 
578 // Copyright (c) DreamWorks Animation LLC
579 // All rights reserved. This software is distributed under the
580 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
static void add(PointDataTreeT &tree, const Name &uniformValue)
Definition: PointAttribute.h:242
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:415
Attribute Group access and filtering for iteration.
#define OPENVDB_DEPRECATED
Definition: Platform.h:69
Typed class for storing attribute data.
Definition: AttributeArray.h:608
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...
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
Definition: AttributeArrayString.h:85
Index32 Index
Definition: Types.h:61
void compactAttributes(PointDataTreeT &tree)
Compact attributes in a VDB tree (if possible).
Definition: PointAttribute.h:544
Container that maps names (strings) to values of arbitrary types.
Definition: MetaMap.h:46
void collapse()
Replace the existing array with a uniform value (zero if none provided).
Definition: AttributeArray.h:2292
void dropAttributes(PointDataTreeT &tree, const std::vector< Name > &names)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:432
Write-able version of AttributeHandle.
Definition: AttributeArray.h:944
DescriptorPtr descriptorPtr() const
Return a pointer to this attribute set&#39;s descriptor, which might be shared with other sets...
Definition: AttributeSet.h:131
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1618
void collapseAttribute(AttributeArray &array, const AttributeSet::Descriptor &descriptor, const Name &uniformValue)
Definition: PointAttribute.h:199
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:62
std::pair< Name, Name > NamePair
Definition: AttributeArray.h:65
void insert(const Name &name)
Insert the string into the metadata.
void collapse()
Set membership for the whole array and attempt to collapse.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:128
std::string Name
Definition: Name.h:44
static void add(PointDataTreeT &, const AttributeListType &)
Definition: PointAttribute.h:235
static void add(PointDataTreeT &, const ValueType &)
Definition: PointAttribute.h:232
Definition: Tree.h:203
Definition: Exceptions.h:40
void renameAttributes(PointDataTreeT &tree, const std::vector< Name > &oldNames, const std::vector< Name > &newNames)
Rename attributes in a VDB tree.
Definition: PointAttribute.h:485
Descriptor & descriptor()
Return a reference to this attribute set&#39;s descriptor, which might be shared with other sets...
Definition: AttributeSet.h:125
static const NamePair & type()
Definition: PointAttribute.h:213
Definition: AttributeArrayString.h:168
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:109
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:212
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
OPENVDB_DEPRECATED void bloscCompressAttribute(PointDataTreeT &, const Name &)
Definition: PointAttribute.h:562
void dropAttribute(PointDataTreeT &tree, const Name &name)
Drop one attribute from the VDB tree (convenience method).
Definition: PointAttribute.h:473
Attribute array storage for string data using Descriptor Metadata.
SharedPtr< Metadata > Ptr
Definition: Metadata.h:53
Definition: Exceptions.h:92
bool isGroup(const AttributeArray &array)
Definition: AttributeGroup.h:93
Definition: AttributeArray.h:532
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:180
Definition: Exceptions.h:86
Base class for storing attribute data.
Definition: AttributeArray.h:118
Set of Attribute Arrays which tracks metadata about each array.
void renameAttribute(PointDataTreeT &tree, const Name &oldName, const Name &newName)
Rename an attribute in a VDB tree.
Definition: PointAttribute.h:532
static ValueType value()
Definition: PointAttribute.h:58
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, Metadata::Ptr metaDefaultValue=Metadata::Ptr(), const bool hidden=false, const bool transient=false)
Appends a new attribute to the VDB tree.
Definition: PointAttribute.h:331
static void add(PointDataTreeT &tree, const AttributeListType &data)
Definition: PointAttribute.h:249
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:523