[Bf-blender-cvs] [4601e3a5916] master: Geometry Nodes: refactor internal attribute access architecture

Jacques Lucke noreply at git.blender.org
Tue Feb 9 11:29:15 CET 2021


Commit: 4601e3a5916c7746ad29d20add91651929c6f621
Author: Jacques Lucke
Date:   Tue Feb 9 11:24:28 2021 +0100
Branches: master
https://developer.blender.org/rB4601e3a5916c7746ad29d20add91651929c6f621

Geometry Nodes: refactor internal attribute access architecture

Goals:
* Clarify the distinction between builtin and other attributes at the code level.
* Reduce number of places that need to be modified to add more builtin attributes.
* Reduce number of virtual methods that need to be implemented by e.g. `MeshComponent`.

To achieve these goals, this patch implements the concept of "attribute providers".
An attribute provider knows how to give access to attributes on a geometry component.
Each geometry component can have multiple attribute providers, whereby each provider
manages an different set of attributes.

The separation of builtin and other attributes is now done at the attribute provider level.
There are two types of attribute providers. One for builtin attributes and one for all others.

This refactor also helps with T84297.

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

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

M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/geometry_set.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 2bed1a36ed7..9a871574f6f 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -68,6 +68,10 @@ template<> struct DefaultHash<GeometryComponentType> {
 };
 }  // namespace blender
 
+namespace blender::bke {
+struct ComponentAttributeProviders;
+}
+
 class GeometryComponent;
 
 /**
@@ -152,23 +156,18 @@ class GeometryComponent {
   bool attribute_exists(const blender::StringRef attribute_name) const;
 
   /* Returns true when the geometry component supports this attribute domain. */
-  virtual bool attribute_domain_supported(const AttributeDomain domain) const;
-  /* Returns true when the given data type is supported in the given domain. */
-  virtual bool attribute_domain_with_type_supported(const AttributeDomain domain,
-                                                    const CustomDataType data_type) const;
+  bool attribute_domain_supported(const AttributeDomain domain) const;
   /* Can only be used with supported domain types. */
   virtual int attribute_domain_size(const AttributeDomain domain) const;
-  /* Attributes with these names cannot be created or removed via this api. */
-  virtual bool attribute_is_builtin(const blender::StringRef attribute_name) const;
 
   /* Get read-only access to the highest priority attribute with the given name.
    * Returns null if the attribute does not exist. */
-  virtual blender::bke::ReadAttributePtr attribute_try_get_for_read(
+  blender::bke::ReadAttributePtr attribute_try_get_for_read(
       const blender::StringRef attribute_name) const;
 
   /* Get read and write access to the highest priority attribute with the given name.
    * Returns null if the attribute does not exist. */
-  virtual blender::bke::WriteAttributePtr attribute_try_get_for_write(
+  blender::bke::WriteAttributePtr attribute_try_get_for_write(
       const blender::StringRef attribute_name);
 
   /* Get a read-only attribute for the domain based on the given attribute. This can be used to
@@ -178,14 +177,14 @@ class GeometryComponent {
       blender::bke::ReadAttributePtr attribute, const AttributeDomain domain) const;
 
   /* Returns true when the attribute has been deleted. */
-  virtual bool attribute_try_delete(const blender::StringRef attribute_name);
+  bool attribute_try_delete(const blender::StringRef attribute_name);
 
   /* Returns true when the attribute has been created. */
-  virtual bool attribute_try_create(const blender::StringRef attribute_name,
-                                    const AttributeDomain domain,
-                                    const CustomDataType data_type);
+  bool attribute_try_create(const blender::StringRef attribute_name,
+                            const AttributeDomain domain,
+                            const CustomDataType data_type);
 
-  virtual blender::Set<std::string> attribute_names() const;
+  blender::Set<std::string> attribute_names() const;
   virtual bool is_empty() const;
 
   /* Get a read-only attribute for the given domain and data type.
@@ -257,6 +256,9 @@ class GeometryComponent {
                                                   const AttributeDomain domain,
                                                   const CustomDataType data_type,
                                                   const void *default_value = nullptr);
+
+ private:
+  virtual const blender::bke::ComponentAttributeProviders *get_attribute_providers() const;
 };
 
 template<typename T>
@@ -359,30 +361,20 @@ class MeshComponent : public GeometryComponent {
   Mesh *release();
 
   void copy_vertex_group_names_from_object(const struct Object &object);
+  const blender::Map<std::string, int> &vertex_group_names() const;
+  blender::Map<std::string, int> &vertex_group_names();
 
   const Mesh *get_for_read() const;
   Mesh *get_for_write();
 
-  bool attribute_domain_supported(const AttributeDomain domain) const final;
-  bool attribute_domain_with_type_supported(const AttributeDomain domain,
-                                            const CustomDataType data_type) const final;
   int attribute_domain_size(const AttributeDomain domain) const final;
-  bool attribute_is_builtin(const blender::StringRef attribute_name) const final;
-
-  blender::bke::ReadAttributePtr attribute_try_get_for_read(
-      const blender::StringRef attribute_name) const final;
-  blender::bke::WriteAttributePtr attribute_try_get_for_write(
-      const blender::StringRef attribute_name) final;
 
-  bool attribute_try_delete(const blender::StringRef attribute_name) final;
-  bool attribute_try_create(const blender::StringRef attribute_name,
-                            const AttributeDomain domain,
-                            const CustomDataType data_type) final;
-
-  blender::Set<std::string> attribute_names() const final;
   bool is_empty() const final;
 
   static constexpr inline GeometryComponentType static_type = GeometryComponentType::Mesh;
+
+ private:
+  const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final;
 };
 
 /** A geometry component that stores a point cloud. */
@@ -405,26 +397,14 @@ class PointCloudComponent : public GeometryComponent {
   const PointCloud *get_for_read() const;
   PointCloud *get_for_write();
 
-  bool attribute_domain_supported(const AttributeDomain domain) const final;
-  bool attribute_domain_with_type_supported(const AttributeDomain domain,
-                                            const CustomDataType data_type) const final;
   int attribute_domain_size(const AttributeDomain domain) const final;
-  bool attribute_is_builtin(const blender::StringRef attribute_name) const final;
-
-  blender::bke::ReadAttributePtr attribute_try_get_for_read(
-      const blender::StringRef attribute_name) const final;
-  blender::bke::WriteAttributePtr attribute_try_get_for_write(
-      const blender::StringRef attribute_name) final;
 
-  bool attribute_try_delete(const blender::StringRef attribute_name) final;
-  bool attribute_try_create(const blender::StringRef attribute_name,
-                            const AttributeDomain domain,
-                            const CustomDataType data_type) final;
-
-  blender::Set<std::string> attribute_names() const final;
   bool is_empty() const final;
 
   static constexpr inline GeometryComponentType static_type = GeometryComponentType::PointCloud;
+
+ private:
+  const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final;
 };
 
 /** A geometry component that stores instances. */
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 85dabe4490c..772309349ff 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -323,29 +323,24 @@ template<typename T> class ArrayReadAttribute final : public ReadAttribute {
   }
 };
 
-template<typename StructT, typename ElemT, typename GetFuncT, typename SetFuncT>
+template<typename StructT,
+         typename ElemT,
+         ElemT (*GetFunc)(const StructT &),
+         void (*SetFunc)(StructT &, const ElemT &)>
 class DerivedArrayWriteAttribute final : public WriteAttribute {
  private:
   MutableSpan<StructT> data_;
-  GetFuncT get_function_;
-  SetFuncT set_function_;
 
  public:
-  DerivedArrayWriteAttribute(AttributeDomain domain,
-                             MutableSpan<StructT> data,
-                             GetFuncT get_function,
-                             SetFuncT set_function)
-      : WriteAttribute(domain, CPPType::get<ElemT>(), data.size()),
-        data_(data),
-        get_function_(std::move(get_function)),
-        set_function_(std::move(set_function))
+  DerivedArrayWriteAttribute(AttributeDomain domain, MutableSpan<StructT> data)
+      : WriteAttribute(domain, CPPType::get<ElemT>(), data.size()), data_(data)
   {
   }
 
   void get_internal(const int64_t index, void *r_value) const override
   {
     const StructT &struct_value = data_[index];
-    const ElemT value = get_function_(struct_value);
+    const ElemT value = GetFunc(struct_value);
     new (r_value) ElemT(value);
   }
 
@@ -353,28 +348,25 @@ class DerivedArrayWriteAttribute final : public WriteAttribute {
   {
     StructT &struct_value = data_[index];
     const ElemT &typed_value = *reinterpret_cast<const ElemT *>(value);
-    set_function_(struct_value, typed_value);
+    SetFunc(struct_value, typed_value);
   }
 };
 
-template<typename StructT, typename ElemT, typename GetFuncT>
+template<typename StructT, typename ElemT, ElemT (*GetFunc)(const StructT &)>
 class DerivedArrayReadAttribute final : public ReadAttribute {
  private:
   Span<StructT> data_;
-  GetFuncT get_function_;
 
  public:
-  DerivedArrayReadAttribute(AttributeDomain domain, Span<StructT> data, GetFuncT get_function)
-      : ReadAttribute(domain, CPPType::get<ElemT>(), data.size()),
-        data_(data),
-        get_function_(std::move(get_function))
+  DerivedArrayReadAttribute(AttributeDomain domain, Span<StructT> data)
+      : ReadAttribute(domain, CPPType::get<ElemT>(), data.size()), data_(data)
   {
   }
 
   void get_internal(const int64_t index, void *r_value) const override
   {
     const StructT &struct_value = data_[index];
-    const ElemT value = get_function_(struct_value);
+    const ElemT value = GetFunc(struct_value);
     new (r_value) ElemT(value);
   }
 };
@@ -492,144 +484,835 @@ CustomDataType cpp_type_to_custom_data_type(const blender::fn::CPPType &type)
   return static_cast<CustomDataType>(-1);
 }
 
-}  // namespace blender::bke
+/**
+ * A #BuiltinAttributeProvider is responsible for exactly one attribute on a geometry component.
+ * The attribute is identified by its name and has a fixed domain and type. Builtin attributes do
+ * not follow the same loose rules as other attributes, because they are mapped to internal
+ * "legacy" data structures. For example, some builtin attributes cannot be deleted. */
+class BuiltinAttributeProvider {
+ public:
+  /* Some utility enums to avoid hard to read bools in function calls. */
+  enum Creatabl

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list