[Bf-blender-cvs] [196dfc01a3e] blender-v2.92-release: Fix T84114: Existence of vertex groups slows down mesh editing

Campbell Barton noreply at git.blender.org
Thu Feb 11 14:41:53 CET 2021


Commit: 196dfc01a3e99c3bef0e44acf599bca50ae0300e
Author: Campbell Barton
Date:   Fri Feb 12 00:09:48 2021 +1100
Branches: blender-v2.92-release
https://developer.blender.org/rB196dfc01a3e99c3bef0e44acf599bca50ae0300e

Fix T84114: Existence of vertex groups slows down mesh editing

Having a vertex group in a mesh slowed down unrelated operations
such as selection.

De-duplicating custom-data arrays for layers that contain pointers
can become slow without any benefit as the content never matches.

Use full copies when storing custom-data for edit-mesh undo.

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

M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/editors/mesh/editmesh_undo.c

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

diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 51650d161ea..57fdafaf8d9 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -421,6 +421,7 @@ int CustomData_sizeof(int type);
 /* get the name of a layer type */
 const char *CustomData_layertype_name(int type);
 bool CustomData_layertype_is_singleton(int type);
+bool CustomData_layertype_is_dynamic(int type);
 int CustomData_layertype_layers_max(const int type);
 
 /* make sure the name of layer at index is unique */
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index b0994fb683a..1121df0d568 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -4290,6 +4290,18 @@ bool CustomData_layertype_is_singleton(int type)
   return typeInfo->defaultname == NULL;
 }
 
+/**
+ * Has dynamically allocated members.
+ * This is useful to know if operations such as #memcmp are
+ * valid when comparing data from two layers.
+ */
+bool CustomData_layertype_is_dynamic(int type)
+{
+  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+  return (typeInfo->free != NULL);
+}
+
 /**
  * \return Maximum number of layers of given \a type, -1 means 'no limit'.
  */
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 1cbbbccdfa9..41bb3faa135 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -153,6 +153,23 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
   for (int layer_start = 0, layer_end; layer_start < cdata->totlayer; layer_start = layer_end) {
     const CustomDataType type = cdata->layers[layer_start].type;
 
+    /* Perform a full copy on dynamic layers.
+     *
+     * Unfortunately we can't compare dynamic layer types as they contain allocated pointers,
+     * which burns CPU cycles looking for duplicate data that doesn't exist.
+     * The array data isn't comparable once copied from the mesh,
+     * this bottlenecks on high poly meshes, see T84114.
+     *
+     * Notes:
+     *
+     * - Ideally the data would be expanded into a format that could be de-duplicated effectively,
+     *   this would require a flat representation of each dynamic custom-data layer.
+     *
+     * - The data in the layer could be kept as-is to save on the extra copy,
+     *   it would complicate logic in this function.
+     */
+    const bool layer_type_is_dynamic = CustomData_layertype_is_dynamic(type);
+
     layer_end = layer_start + 1;
     while ((layer_end < cdata->totlayer) && (type == cdata->layers[layer_end].type)) {
       layer_end++;
@@ -209,6 +226,11 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
                                           i < bcd_reference_current->states_len) ?
                                              bcd_reference_current->states[i] :
                                              NULL;
+          /* See comment on `layer_type_is_dynamic` above. */
+          if (layer_type_is_dynamic) {
+            state_reference = NULL;
+          }
+
           bcd->states[i] = BLI_array_store_state_add(
               bs, layer->data, (size_t)data_len * stride, state_reference);
         }



More information about the Bf-blender-cvs mailing list