[Bf-blender-cvs] [c94c0d988a5] master: Fix: Removing attributes from UI invalidates caches

Hans Goudey noreply at git.blender.org
Sun Jul 24 03:00:09 CEST 2022


Commit: c94c0d988a5640ab7c6fb815462792dcf8dd863b
Author: Hans Goudey
Date:   Sat Jul 23 19:59:59 2022 -0500
Branches: master
https://developer.blender.org/rBc94c0d988a5640ab7c6fb815462792dcf8dd863b

Fix: Removing attributes from UI invalidates caches

Use the new attribute API to implement the attribute remove function
used by RNA, except for BMesh attributes. Currently, removing curve
attributes from the panel in the property editor does not mark the
relevant caches dirty (for example, the cache of curve type counts),
because that behavior is implemented with the new attribute API.
Also, eventually we want to merge the two APIs, and removing an
attribute is the first function that can be partially implemented
with the new API.

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

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

M	source/blender/blenkernel/intern/attribute.cc
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/attribute_access_intern.hh

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

diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc
index 030e4941874..b277fc39caf 100644
--- a/source/blender/blenkernel/intern/attribute.cc
+++ b/source/blender/blenkernel/intern/attribute.cc
@@ -8,6 +8,7 @@
  */
 
 #include <cstring>
+#include <optional>
 
 #include "MEM_guardedalloc.h"
 
@@ -24,7 +25,7 @@
 
 #include "BKE_attribute.h"
 #include "BKE_attribute.hh"
-#include "BKE_curves.h"
+#include "BKE_curves.hh"
 #include "BKE_customdata.h"
 #include "BKE_editmesh.h"
 #include "BKE_pointcloud.h"
@@ -89,6 +90,36 @@ static void get_domains(const ID *id, DomainInfo info[ATTR_DOMAIN_NUM])
   }
 }
 
+namespace blender::bke {
+
+static std::optional<blender::bke::MutableAttributeAccessor> get_attribute_accessor_for_write(
+    ID &id)
+{
+  switch (GS(id.name)) {
+    case ID_ME: {
+      Mesh &mesh = reinterpret_cast<Mesh &>(id);
+      /* The attribute API isn't implemented for BMesh, so edit mode meshes are not supported. */
+      BLI_assert(mesh.edit_mesh == nullptr);
+      return mesh_attributes_for_write(mesh);
+    }
+    case ID_PT: {
+      PointCloud &pointcloud = reinterpret_cast<PointCloud &>(id);
+      return pointcloud_attributes_for_write(pointcloud);
+    }
+    case ID_CV: {
+      Curves &curves_id = reinterpret_cast<Curves &>(id);
+      CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
+      return curves.attributes_for_write();
+    }
+    default: {
+      BLI_assert_unreachable();
+      return {};
+    }
+  }
+}
+
+}  // namespace blender::bke
+
 bool BKE_id_attributes_supported(const ID *id)
 {
   DomainInfo info[ATTR_DOMAIN_NUM];
@@ -242,6 +273,7 @@ CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList
 
 bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
 {
+  using namespace blender::bke;
   if (BKE_id_attribute_required(id, name)) {
     BKE_report(reports, RPT_ERROR, "Attribute is required and can't be removed");
     return false;
@@ -266,12 +298,9 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
       ATTR_FALLTHROUGH;
     }
     default:
-      for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
-        if (CustomData *data = info[domain].customdata) {
-          if (CustomData_free_layer_named(data, name, info[domain].length)) {
-            return true;
-          }
-        }
+      if (std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(
+              *id)) {
+        return attributes->remove(name);
       }
       return false;
   }
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 19faddc5727..8d21c6fe792 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -319,8 +319,8 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner)
   }
 
   std::function<void()> tag_modified_fn;
-  if (update_on_write_ != nullptr) {
-    tag_modified_fn = [owner, update = update_on_write_]() { update(owner); };
+  if (update_on_change_ != nullptr) {
+    tag_modified_fn = [owner, update = update_on_change_]() { update(owner); };
   }
 
   return {as_write_attribute_(data, element_num), domain_, std::move(tag_modified_fn)};
@@ -336,12 +336,19 @@ bool BuiltinCustomDataLayerProvider::try_delete(void *owner) const
     return {};
   }
 
+  auto update = [&]() {
+    if (update_on_change_ != nullptr) {
+      update_on_change_(owner);
+    }
+  };
+
   const int element_num = custom_data_access_.get_element_num(owner);
   if (stored_as_named_attribute_) {
     if (CustomData_free_layer_named(custom_data, name_.c_str(), element_num)) {
       if (custom_data_access_.update_custom_data_pointers) {
         custom_data_access_.update_custom_data_pointers(owner);
       }
+      update();
       return true;
     }
     return false;
@@ -352,8 +359,10 @@ bool BuiltinCustomDataLayerProvider::try_delete(void *owner) const
     if (custom_data_access_.update_custom_data_pointers) {
       custom_data_access_.update_custom_data_pointers(owner);
     }
+    update();
     return true;
   }
+
   return false;
 }
 
diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh
index 17432fa2726..1a2607d9403 100644
--- a/source/blender/blenkernel/intern/attribute_access_intern.hh
+++ b/source/blender/blenkernel/intern/attribute_access_intern.hh
@@ -226,12 +226,12 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
   using AsReadAttribute = GVArray (*)(const void *data, int element_num);
   using AsWriteAttribute = GVMutableArray (*)(void *data, int element_num);
   using UpdateOnRead = void (*)(const void *owner);
-  using UpdateOnWrite = void (*)(void *owner);
+  using UpdateOnChange = void (*)(void *owner);
   const eCustomDataType stored_type_;
   const CustomDataAccessInfo custom_data_access_;
   const AsReadAttribute as_read_attribute_;
   const AsWriteAttribute as_write_attribute_;
-  const UpdateOnWrite update_on_write_;
+  const UpdateOnChange update_on_change_;
   bool stored_as_named_attribute_;
 
  public:
@@ -245,14 +245,14 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
                                  const CustomDataAccessInfo custom_data_access,
                                  const AsReadAttribute as_read_attribute,
                                  const AsWriteAttribute as_write_attribute,
-                                 const UpdateOnWrite update_on_write)
+                                 const UpdateOnChange update_on_write)
       : BuiltinAttributeProvider(
             std::move(attribute_name), domain, attribute_type, creatable, writable, deletable),
         stored_type_(stored_type),
         custom_data_access_(custom_data_access),
         as_read_attribute_(as_read_attribute),
         as_write_attribute_(as_write_attribute),
-        update_on_write_(update_on_write),
+        update_on_change_(update_on_write),
         stored_as_named_attribute_(data_type_ == stored_type_)
   {
   }



More information about the Bf-blender-cvs mailing list