[Bf-blender-cvs] [7234fd5b313] attribute-accessor: initial WriteAttribute

Jacques Lucke noreply at git.blender.org
Tue Nov 17 16:40:11 CET 2020


Commit: 7234fd5b313215b4a9103f000bd09b4f6100b9b3
Author: Jacques Lucke
Date:   Tue Nov 17 16:39:36 2020 +0100
Branches: attribute-accessor
https://developer.blender.org/rB7234fd5b313215b4a9103f000bd09b4f6100b9b3

initial WriteAttribute

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

M	source/blender/blenkernel/BKE_attribute_accessor.hh
M	source/blender/blenkernel/intern/attribute_accessor.cc
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/geometry/nodes/node_geo_random_attribute.cc

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

diff --git a/source/blender/blenkernel/BKE_attribute_accessor.hh b/source/blender/blenkernel/BKE_attribute_accessor.hh
index 3cf2fd4f865..0905f81d472 100644
--- a/source/blender/blenkernel/BKE_attribute_accessor.hh
+++ b/source/blender/blenkernel/BKE_attribute_accessor.hh
@@ -39,7 +39,7 @@ class ReadAttribute {
   {
   }
 
-  virtual ~ReadAttribute() = default;
+  virtual ~ReadAttribute();
 
   AttributeDomain domain() const
   {
@@ -67,7 +67,54 @@ class ReadAttribute {
   virtual void get_internal(const int64_t index, void *r_value) const = 0;
 };
 
+class WriteAttribute {
+ protected:
+  const AttributeDomain domain_;
+  const CPPType &cpp_type_;
+  const int64_t size_;
+
+ public:
+  WriteAttribute(AttributeDomain domain, const CPPType &cpp_type, const int64_t size)
+      : domain_(domain), cpp_type_(cpp_type), size_(size)
+  {
+  }
+
+  virtual ~WriteAttribute();
+
+  AttributeDomain domain() const
+  {
+    return domain_;
+  }
+
+  const CPPType &cpp_type() const
+  {
+    return cpp_type_;
+  }
+
+  int64_t size() const
+  {
+    return size_;
+  }
+
+  void get(const int64_t index, void *r_value) const
+  {
+    BLI_assert(index < size_);
+    this->get_internal(index, r_value);
+  }
+
+  void set(const int64_t index, const void *value)
+  {
+    BLI_assert(index < size_);
+    this->set_internal(index, value);
+  }
+
+ protected:
+  virtual void get_internal(const int64_t index, void *r_value) const = 0;
+  virtual void set_internal(const int64_t index, const void *value) = 0;
+};
+
 using ReadAttributePtr = std::unique_ptr<ReadAttribute>;
+using WriteAttributePtr = std::unique_ptr<WriteAttribute>;
 
 template<typename T> class TypedReadAttribute {
  private:
@@ -95,11 +142,46 @@ template<typename T> class TypedReadAttribute {
   }
 };
 
+template<typename T> class TypedWriteAttribute {
+ private:
+  WriteAttributePtr attribute_;
+
+ public:
+  TypedWriteAttribute(WriteAttributePtr attribute) : attribute_(std::move(attribute))
+  {
+    BLI_assert(attribute_);
+    BLI_assert(attribute_->cpp_type().is<T>());
+  }
+
+  int64_t size() const
+  {
+    return attribute_->size();
+  }
+
+  T operator[](const int64_t index) const
+  {
+    BLI_assert(index < attribute_->size());
+    T value;
+    value.~T();
+    attribute_->get(index, &value);
+    return value;
+  }
+
+  void set(const int64_t index, const T &value)
+  {
+    attribute_->set(index, &value);
+  }
+};
+
 using FloatReadAttribute = TypedReadAttribute<float>;
 using Float3ReadAttribute = TypedReadAttribute<float3>;
+using FloatWriteAttribute = TypedWriteAttribute<float>;
+using Float3WriteAttribute = TypedWriteAttribute<float3>;
 
 ReadAttributePtr mesh_attribute_get_for_read(const MeshComponent &mesh_component,
                                              const StringRef attribute_name);
+std::optional<WriteAttributePtr> mesh_attribute_get_for_write(MeshComponent &mesh_component,
+                                                              const StringRef attribute_name);
 
 ReadAttributePtr mesh_attribute_adapt_domain(const MeshComponent &mesh_component,
                                              ReadAttributePtr attribute,
diff --git a/source/blender/blenkernel/intern/attribute_accessor.cc b/source/blender/blenkernel/intern/attribute_accessor.cc
index ee1cf2acf36..46618e49826 100644
--- a/source/blender/blenkernel/intern/attribute_accessor.cc
+++ b/source/blender/blenkernel/intern/attribute_accessor.cc
@@ -28,14 +28,17 @@
 
 namespace blender::bke {
 
-class VertexWeightReadAttribute final : public ReadAttribute {
+ReadAttribute::~ReadAttribute() = default;
+WriteAttribute::~WriteAttribute() = default;
+
+class VertexWeightWriteAttribute final : public WriteAttribute {
  private:
-  Span<MDeformVert> dverts_;
-  int dvert_index_;
+  MutableSpan<MDeformVert> dverts_;
+  const int dvert_index_;
 
  public:
-  VertexWeightReadAttribute(const MDeformVert *dverts, const int totvert, const int dvert_index)
-      : ReadAttribute(ATTR_DOMAIN_VERTEX, CPPType::get<float>(), totvert),
+  VertexWeightWriteAttribute(MDeformVert *dverts, const int totvert, const int dvert_index)
+      : WriteAttribute(ATTR_DOMAIN_VERTEX, CPPType::get<float>(), totvert),
         dverts_(dverts, totvert),
         dvert_index_(dvert_index)
   {
@@ -43,9 +46,23 @@ class VertexWeightReadAttribute final : public ReadAttribute {
 
   void get_internal(const int64_t index, void *r_value) const override
   {
-    const MDeformVert &dvert = dverts_[index];
+    this->get_internal(dverts_, dvert_index_, index, r_value);
+  }
+
+  void set_internal(const int64_t index, const void *value) override
+  {
+    MDeformWeight *weight = BKE_defvert_ensure_index(&dverts_[index], dvert_index_);
+    weight->weight = *reinterpret_cast<const float *>(value);
+  }
+
+  static void get_internal(const Span<MDeformVert> dverts,
+                           const int dvert_index,
+                           const int64_t index,
+                           void *r_value)
+  {
+    const MDeformVert &dvert = dverts[index];
     for (const MDeformWeight &weight : Span(dvert.dw, dvert.totweight)) {
-      if (weight.def_nr == dvert_index_) {
+      if (weight.def_nr == dvert_index) {
         *(float *)r_value = weight.weight;
         return;
       }
@@ -54,6 +71,46 @@ class VertexWeightReadAttribute final : public ReadAttribute {
   }
 };
 
+class VertexWeightReadAttribute final : public ReadAttribute {
+ private:
+  const Span<MDeformVert> dverts_;
+  const int dvert_index_;
+
+ public:
+  VertexWeightReadAttribute(const MDeformVert *dverts, const int totvert, const int dvert_index)
+      : ReadAttribute(ATTR_DOMAIN_VERTEX, CPPType::get<float>(), totvert),
+        dverts_(dverts, totvert),
+        dvert_index_(dvert_index)
+  {
+  }
+
+  void get_internal(const int64_t index, void *r_value) const override
+  {
+    VertexWeightWriteAttribute::get_internal(dverts_, dvert_index_, index, r_value);
+  }
+};
+
+template<typename T> class ArrayWriteAttribute final : public WriteAttribute {
+ private:
+  MutableSpan<T> data_;
+
+ public:
+  ArrayWriteAttribute(AttributeDomain domain, MutableSpan<T> data)
+      : WriteAttribute(domain, CPPType::get<T>(), data.size()), data_(data)
+  {
+  }
+
+  void get_internal(const int64_t index, void *r_value) const override
+  {
+    new (r_value) T(data_[index]);
+  }
+
+  void set_internal(const int64_t index, const void *value) override
+  {
+    data_[index] = *reinterpret_cast<const T *>(value);
+  }
+};
+
 template<typename T> class ArrayReadAttribute final : public ReadAttribute {
  private:
   Span<T> data_;
@@ -70,26 +127,58 @@ template<typename T> class ArrayReadAttribute final : public ReadAttribute {
   }
 };
 
-template<typename StructT, typename FuncT>
-class DerivedArrayReadAttribute final : public ReadAttribute {
+template<typename StructT, typename ElemT, typename GetFuncT, typename SetFuncT>
+class DerivedArrayWriteAttribute final : public WriteAttribute {
  private:
-  using ElemT = decltype(std::declval<FuncT>()(std::declval<StructT>()));
+  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))
+  {
+  }
+
+  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);
+    new (r_value) ElemT(value);
+  }
+
+  void set_internal(const int64_t index, const void *value) override
+  {
+    StructT &struct_value = data_[index];
+    const ElemT &typed_value = *reinterpret_cast<const ElemT *>(value);
+    set_function_(struct_value, typed_value);
+  }
+};
 
+template<typename StructT, typename ElemT, typename GetFuncT>
+class DerivedArrayReadAttribute final : public ReadAttribute {
+ private:
   Span<StructT> data_;
-  FuncT function_;
+  GetFuncT get_function_;
 
  public:
-  DerivedArrayReadAttribute(AttributeDomain domain, Span<StructT> data, FuncT function)
+  DerivedArrayReadAttribute(AttributeDomain domain, Span<StructT> data, GetFuncT get_function)
       : ReadAttribute(domain, CPPType::get<ElemT>(), data.size()),
         data_(data),
-        function_(std::move(function))
+        get_function_(std::move(get_function))
   {
   }
 
   void get_internal(const int64_t index, void *r_value) const override
   {
     const StructT &struct_value = data_[index];
-    const ElemT value = function_(struct_value);
+    const ElemT value = get_function_(struct_value);
     new (r_value) ElemT(value);
   }
 };
@@ -115,10 +204,10 @@ class ConstantReadAttribute final : public ReadAttribute {
   }
 };
 
-static ReadAttributePtr get_custom_data_read_attribute(const CustomData &custom_data,
-                                                       const int size,
-                                                       const StringRef attribute_name,
-                                                       const AttributeDomain domain)
+static ReadAttributePtr mesh_attribute_custom_data_read(const CustomData &custom_data,
+                                                        const int size,
+                                                        const StringRef attribute_name,
+                                                        const AttributeDomain domain)
 {
   for (const CustomDataLayer &layer : Span(custom_data.layers, custom_data.totlayer)) {
     if (layer.name != nullptr && layer.name == attribute_name) {
@@ -144,29 +233,53 @@ static ReadAttributePtr get_custom_data_read_attribute(const CustomData &custom_
   return {};
 }
 
-static ReadAttributePtr get_mesh_read_attribute__corner(const MeshComponent &mesh_component,
-                                                        const StringRef attribute_name)
+static WriteAttributePtr mesh_attribute_custom_data_write(CustomData custom_data,
+                              

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list