[Bf-blender-cvs] [31365c6b9e4] master: Attributes: Use new API for C-API functions

Hans Goudey noreply at git.blender.org
Sun Jul 24 20:19:15 CEST 2022


Commit: 31365c6b9e4cd99a79fe64ebaf016c3d7e0e0c4f
Author: Hans Goudey
Date:   Sun Jul 24 12:46:08 2022 -0500
Branches: master
https://developer.blender.org/rB31365c6b9e4cd99a79fe64ebaf016c3d7e0e0c4f

Attributes: Use new API for C-API functions

Use the C++ API to implement more of the existing C functions.
This corrects the cases where one tries to add a builtin attribute
with the wrong domain or type on curves, though a better warning
message would be helpful in the future, and also reduces duplication
of the internal logic. Not much more is possible without changing
the interface.

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

M	source/blender/blenkernel/intern/attribute.cc

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

diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc
index b277fc39caf..ff40f842349 100644
--- a/source/blender/blenkernel/intern/attribute.cc
+++ b/source/blender/blenkernel/intern/attribute.cc
@@ -203,6 +203,7 @@ bool BKE_id_attribute_calc_unique_name(ID *id, const char *name, char *outname)
 CustomDataLayer *BKE_id_attribute_new(
     ID *id, const char *name, const int type, const eAttrDomain domain, ReportList *reports)
 {
+  using namespace blender::bke;
   DomainInfo info[ATTR_DOMAIN_NUM];
   get_domains(id, info);
 
@@ -215,60 +216,56 @@ CustomDataLayer *BKE_id_attribute_new(
   char uniquename[MAX_CUSTOMDATA_LAYER_NAME];
   BKE_id_attribute_calc_unique_name(id, name, uniquename);
 
-  switch (GS(id->name)) {
-    case ID_ME: {
-      Mesh *me = (Mesh *)id;
-      BMEditMesh *em = me->edit_mesh;
-      if (em != nullptr) {
-        BM_data_layer_add_named(em->bm, customdata, type, uniquename);
-      }
-      else {
-        CustomData_add_layer_named(
-            customdata, type, CD_DEFAULT, nullptr, info[domain].length, uniquename);
-      }
-      break;
-    }
-    default: {
-      CustomData_add_layer_named(
-          customdata, type, CD_DEFAULT, nullptr, info[domain].length, uniquename);
-      break;
+  if (GS(id->name) == ID_ME) {
+    Mesh *mesh = reinterpret_cast<Mesh *>(id);
+    if (BMEditMesh *em = mesh->edit_mesh) {
+      BM_data_layer_add_named(em->bm, customdata, type, uniquename);
+      const int index = CustomData_get_named_layer_index(customdata, type, uniquename);
+      return (index == -1) ? nullptr : &(customdata->layers[index]);
     }
   }
 
+  std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(*id);
+  if (!attributes) {
+    return nullptr;
+  }
+
+  attributes->add(uniquename, domain, eCustomDataType(type), AttributeInitDefault());
+
   const int index = CustomData_get_named_layer_index(customdata, type, uniquename);
   return (index == -1) ? nullptr : &(customdata->layers[index]);
 }
 
 CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList *reports)
 {
-  const CustomDataLayer *src_layer = BKE_id_attribute_search(
-      id, name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
-  if (src_layer == nullptr) {
-    BKE_report(reports, RPT_ERROR, "Attribute is not part of this geometry");
-    return nullptr;
-  }
-
-  const eCustomDataType type = (eCustomDataType)src_layer->type;
-  const eAttrDomain domain = BKE_id_attribute_domain(id, src_layer);
+  using namespace blender::bke;
+  char uniquename[MAX_CUSTOMDATA_LAYER_NAME];
+  BKE_id_attribute_calc_unique_name(id, name, uniquename);
 
-  /* Make a copy of name in case CustomData API reallocates the layers. */
-  const std::string name_copy = name;
+  if (GS(id->name) == ID_ME) {
+    Mesh *mesh = reinterpret_cast<Mesh *>(id);
+    if (BMEditMesh *em = mesh->edit_mesh) {
+      BLI_assert_unreachable();
+      UNUSED_VARS(em);
+      return nullptr;
+    }
+  }
 
-  DomainInfo info[ATTR_DOMAIN_NUM];
-  get_domains(id, info);
-  CustomData *customdata = info[domain].customdata;
+  std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(*id);
+  if (!attributes) {
+    return nullptr;
+  }
 
-  CustomDataLayer *new_layer = BKE_id_attribute_new(id, name_copy.c_str(), type, domain, reports);
-  if (new_layer == nullptr) {
+  GAttributeReader src = attributes->lookup(name);
+  if (!src) {
+    BKE_report(reports, RPT_ERROR, "Attribute is not part of this geometry");
     return nullptr;
   }
 
-  const int from_index = CustomData_get_named_layer_index(customdata, type, name_copy.c_str());
-  const int to_index = CustomData_get_named_layer_index(customdata, type, new_layer->name);
-  CustomData_copy_data_layer(
-      customdata, customdata, from_index, to_index, 0, 0, info[domain].length);
+  const eCustomDataType type = cpp_type_to_custom_data_type(src.varray.type());
+  attributes->add(uniquename, src.domain, type, AttributeInitVArray(src.varray));
 
-  return new_layer;
+  return BKE_id_attribute_search(id, uniquename, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
 }
 
 bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
@@ -282,28 +279,26 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
   DomainInfo info[ATTR_DOMAIN_NUM];
   get_domains(id, info);
 
-  switch (GS(id->name)) {
-    case ID_ME: {
-      Mesh *mesh = reinterpret_cast<Mesh *>(id);
-      if (BMEditMesh *em = mesh->edit_mesh) {
-        for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
-          if (CustomData *data = info[domain].customdata) {
-            if (BM_data_layer_free_named(em->bm, data, name)) {
-              return true;
-            }
+  if (GS(id->name) == ID_ME) {
+    Mesh *mesh = reinterpret_cast<Mesh *>(id);
+    if (BMEditMesh *em = mesh->edit_mesh) {
+      for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
+        if (CustomData *data = info[domain].customdata) {
+          if (BM_data_layer_free_named(em->bm, data, name)) {
+            return true;
           }
         }
-        return false;
-      }
-      ATTR_FALLTHROUGH;
-    }
-    default:
-      if (std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(
-              *id)) {
-        return attributes->remove(name);
       }
       return false;
+    }
   }
+
+  std::optional<MutableAttributeAccessor> attributes = get_attribute_accessor_for_write(*id);
+  if (!attributes) {
+    return false;
+  }
+
+  return attributes->remove(name);
 }
 
 CustomDataLayer *BKE_id_attribute_find(const ID *id,



More information about the Bf-blender-cvs mailing list