[Bf-blender-cvs] [34f99bc6be3] master: Geometry Nodes: Allow reading converted attribute directly from spline

Hans Goudey noreply at git.blender.org
Wed Jun 2 14:24:53 CEST 2021


Commit: 34f99bc6be3c343dd371e1f877e972cc80dd396d
Author: Hans Goudey
Date:   Wed Jun 2 08:24:42 2021 -0400
Branches: master
https://developer.blender.org/rB34f99bc6be3c343dd371e1f877e972cc80dd396d

Geometry Nodes: Allow reading converted attribute directly from spline

Often it would be beneficial to avoid the virtual array implementation
in `geometry_component_curve.cc` that flattens an attribute for every
spline and instead read an attribute separately for every input spline.
This commit implements functions to do that.

The downside is some code duplication-- we now have two places handling
this conversion. However, we can head in this general direction for the
attribute API anyway and support accessing attributes in smaller
contiguous chunks where necessary.

No functional changes in this commit.

Differential Revision: https://developer.blender.org/D11456

===================================================================

M	source/blender/blenkernel/BKE_attribute_access.hh
M	source/blender/blenkernel/intern/attribute_access.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index c3bc4d3ca4a..381a03d29d7 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -333,6 +333,21 @@ class CustomDataAttributes {
   void reallocate(const int size);
 
   std::optional<blender::fn::GSpan> get_for_read(const blender::StringRef name) const;
+
+  blender::fn::GVArrayPtr get_for_read(const StringRef name,
+                                       const CustomDataType data_type,
+                                       const void *default_value) const;
+
+  template<typename T>
+  blender::fn::GVArray_Typed<T> get_for_read(const blender::StringRef name,
+                                             const T &default_value) const
+  {
+    const blender::fn::CPPType &cpp_type = blender::fn::CPPType::get<T>();
+    const CustomDataType type = blender::bke::cpp_type_to_custom_data_type(cpp_type);
+    GVArrayPtr varray = this->get_for_read(name, type, &default_value);
+    return blender::fn::GVArray_Typed<T>(std::move(varray));
+  }
+
   std::optional<blender::fn::GMutableSpan> get_for_write(const blender::StringRef name);
   bool create(const blender::StringRef name, const CustomDataType data_type);
   bool create_by_move(const blender::StringRef name, const CustomDataType data_type, void *buffer);
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index d36e9ed3e86..1495eb23254 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -46,6 +46,8 @@ using blender::StringRef;
 using blender::StringRefNull;
 using blender::fn::GMutableSpan;
 using blender::fn::GSpan;
+using blender::fn::GVArray_For_GSpan;
+using blender::fn::GVArray_For_SingleValue;
 
 namespace blender::bke {
 
@@ -628,6 +630,32 @@ std::optional<GSpan> CustomDataAttributes::get_for_read(const StringRef name) co
   return {};
 }
 
+/**
+ * Return a virtual array for a stored attribute, or a single value virtual array with the default
+ * value if the attribute doesn't exist. If no default value is provided, the default value for the
+ * type will be used.
+ */
+GVArrayPtr CustomDataAttributes::get_for_read(const StringRef name,
+                                              const CustomDataType data_type,
+                                              const void *default_value) const
+{
+  const CPPType *type = blender::bke::custom_data_type_to_cpp_type(data_type);
+
+  std::optional<GSpan> attribute = this->get_for_read(name);
+  if (!attribute) {
+    const int domain_size = this->size_;
+    return std::make_unique<GVArray_For_SingleValue>(
+        *type, domain_size, (default_value == nullptr) ? type->default_value() : default_value);
+  }
+
+  if (attribute->type() == *type) {
+    return std::make_unique<GVArray_For_GSpan>(*attribute);
+  }
+  const blender::nodes::DataTypeConversions &conversions =
+      blender::nodes::get_implicit_type_conversions();
+  return conversions.try_convert(std::make_unique<GVArray_For_GSpan>(*attribute), *type);
+}
+
 std::optional<GMutableSpan> CustomDataAttributes::get_for_write(const StringRef name)
 {
   BLI_assert(size_ != 0);



More information about the Bf-blender-cvs mailing list