[Bf-blender-cvs] [d4e4dd42982] refactor-mesh-uv-map-generic: Add function to CustomData for getting the max length of a layer name

Hans Goudey noreply at git.blender.org
Tue Jan 10 06:40:17 CET 2023


Commit: d4e4dd429820c36041aa0409637d8ba741a6e7ea
Author: Hans Goudey
Date:   Tue Jan 10 00:40:08 2023 -0500
Branches: refactor-mesh-uv-map-generic
https://developer.blender.org/rBd4e4dd429820c36041aa0409637d8ba741a6e7ea

Add function to CustomData for getting the max length of a layer name

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

M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/intern/attribute.cc
M	source/blender/blenkernel/intern/customdata.cc

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

diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index fa18bb8208e..b97ac9cc9b9 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -31,7 +31,7 @@ struct CustomData_MeshMasks;
 struct ID;
 typedef uint64_t eCustomDataMask;
 
-/* These names are used as prefixes for UV layer names to find the associated bool
+/* These names are used as prefixes for UV layer names to find the associated boolean
  * layers. They should never be longer than 2 chars, as MAX_CUSTOMDATA_LAYER_NAME
  * has 4 extra bytes above what can be used for the base layer name, and these
  * prefixes are placed between 2 '.'s at the start of the layer name.
@@ -554,6 +554,13 @@ bool CustomData_layertype_is_dynamic(int type);
  */
 int CustomData_layertype_layers_max(int type);
 
+#ifdef __cplusplus
+
+/** \return The maximum length for a layer name with the given prefix. */
+int CustomData_name_max_length_calc(blender::StringRef name);
+
+#endif
+
 /**
  * Make sure the name of layer at index is unique.
  */
diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc
index 6e6aaf32aa1..4b090e710f5 100644
--- a/source/blender/blenkernel/intern/attribute.cc
+++ b/source/blender/blenkernel/intern/attribute.cc
@@ -168,8 +168,18 @@ bool BKE_id_attribute_rename(ID *id,
     BKE_report(reports, RPT_ERROR, "Attribute name can not be empty");
     return false;
   }
-  if (STREQ(old_name, new_name)) {
-    return false;
+
+  /* NOTE: Checking if the new name matches the old name only makes sense when the name
+   * is clamped to it's maximum length, otherwise assigning an over-long name multiple times
+   * will add `.001` suffix unnecessarily. */
+  {
+    const int maxlength = CustomData_name_max_length_calc(new_name);
+    /* NOTE: A function that performs a clamped comparison without copying would be handy here. */
+    char new_name_clamped[MAX_CUSTOMDATA_LAYER_NAME];
+    BLI_strncpy_utf8(new_name_clamped, new_name, maxlength);
+    if (STREQ(old_name, new_name_clamped)) {
+      return false;
+    }
   }
 
   CustomDataLayer *layer = BKE_id_attribute_search(
@@ -244,12 +254,7 @@ static bool unique_name_cb(void *arg, const char *name)
 bool BKE_id_attribute_calc_unique_name(ID *id, const char *name, char *outname)
 {
   AttrUniqueData data{id};
-  int maxlength = MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX;
-
-  if (STRPREFIX(name, "." UV_VERTSEL_NAME ".") || STRPREFIX(name, "." UV_EDGESEL_NAME ".") ||
-      STRPREFIX(name, "." UV_PINNED_NAME ".")) {
-    maxlength = MAX_CUSTOMDATA_LAYER_NAME;
-  }
+  const int maxlength = CustomData_name_max_length_calc(name);
 
   /* Set default name if none specified.
    * NOTE: We only call IFACE_() if needed to avoid locale lookup overhead. */
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index 1db7142a972..8444598d7d8 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -4309,6 +4309,20 @@ static bool customdata_unique_check(void *arg, const char *name)
   return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg->index);
 }
 
+int CustomData_name_max_length_calc(const blender::StringRef name)
+{
+  if (name.startswith(".")) {
+    return MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX;
+  }
+  for (const blender::StringRef prefix :
+       {"." UV_VERTSEL_NAME, UV_EDGESEL_NAME ".", UV_PINNED_NAME "."}) {
+    if (name.startswith(prefix)) {
+      return MAX_CUSTOMDATA_LAYER_NAME;
+    }
+  }
+  return MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX;
+}
+
 void CustomData_set_layer_unique_name(CustomData *data, const int index)
 {
   CustomDataLayer *nlayer = &data->layers[index];
@@ -4320,13 +4334,7 @@ void CustomData_set_layer_unique_name(CustomData *data, const int index)
     return;
   }
 
-  int maxlength = MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX;
-
-  if (STREQLEN("." UV_VERTSEL_NAME ".", nlayer->name, 4) ||
-      STREQLEN("." UV_EDGESEL_NAME ".", nlayer->name, 4) ||
-      STREQLEN("." UV_PINNED_NAME ".", nlayer->name, 4)) {
-    maxlength = MAX_CUSTOMDATA_LAYER_NAME;
-  }
+  const int max_length = CustomData_name_max_length_calc(nlayer->name);
 
   /* Set default name if none specified. Note we only call DATA_() when
    * needed to avoid overhead of locale lookups in the depsgraph. */
@@ -4334,7 +4342,7 @@ void CustomData_set_layer_unique_name(CustomData *data, const int index)
     STRNCPY(nlayer->name, DATA_(typeInfo->defaultname));
   }
 
-  BLI_uniquename_cb(customdata_unique_check, &data_arg, nullptr, '.', nlayer->name, maxlength);
+  BLI_uniquename_cb(customdata_unique_check, &data_arg, nullptr, '.', nlayer->name, max_length);
 }
 
 void CustomData_validate_layer_name(const CustomData *data,



More information about the Bf-blender-cvs mailing list