[Bf-blender-cvs] [c4df8ac1a40] master: Fix T89899: Crashes when accessing vertex groups from objects

Hans Goudey noreply at git.blender.org
Fri Jul 16 18:24:25 CEST 2021


Commit: c4df8ac1a40c7a98a4244c7c14e19791b1e1e99f
Author: Hans Goudey
Date:   Fri Jul 16 12:23:55 2021 -0400
Branches: master
https://developer.blender.org/rBc4df8ac1a40c7a98a4244c7c14e19791b1e1e99f

Fix T89899: Crashes when accessing vertex groups from objects

We need to be more strict about trying to retrieve a list of vertex group
names from objects now, as only three object types support them.
This commit adds a check for vertex group support in a few places, the
data transfer operator/modifier, copying vertex groups to selected
objects, and the vertex group remove and clear functions.

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

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

M	source/blender/editors/object/object_data_transfer.c
M	source/blender/editors/object/object_vgroup.c
M	source/blender/makesrna/intern/rna_object.c

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

diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 2109fe2a822..6251fb799c5 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -123,9 +123,14 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C,
   RNA_enum_items_add_value(
       &item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_ALL_SRC);
 
-  if (data_type == DT_TYPE_MDEFORMVERT) {
-    Object *ob_src = CTX_data_active_object(C);
+  Object *ob_src = CTX_data_active_object(C);
+  if (ob_src == NULL) {
+    RNA_enum_item_end(&item, &totitem);
+    *r_free = true;
+    return item;
+  }
 
+  if (data_type == DT_TYPE_MDEFORMVERT && BKE_object_supports_vertex_groups(ob_src)) {
     if (BKE_object_pose_armature_get(ob_src)) {
       RNA_enum_items_add_value(
           &item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_SELECT);
@@ -133,67 +138,57 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C,
           &item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_DEFORM);
     }
 
-    if (ob_src) {
-      const bDeformGroup *dg;
-      int i;
+    const bDeformGroup *dg;
+    int i;
 
-      RNA_enum_item_add_separator(&item, &totitem);
+    RNA_enum_item_add_separator(&item, &totitem);
 
-      const ListBase *defbase = BKE_object_defgroup_list(ob_src);
-      for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
-        tmp_item.value = i;
-        tmp_item.identifier = tmp_item.name = dg->name;
-        RNA_enum_item_add(&item, &totitem, &tmp_item);
-      }
+    const ListBase *defbase = BKE_object_defgroup_list(ob_src);
+    for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
+      tmp_item.value = i;
+      tmp_item.identifier = tmp_item.name = dg->name;
+      RNA_enum_item_add(&item, &totitem, &tmp_item);
     }
   }
   else if (data_type == DT_TYPE_SHAPEKEY) {
     /* TODO */
   }
   else if (data_type == DT_TYPE_UV) {
-    Object *ob_src = CTX_data_active_object(C);
-
-    if (ob_src) {
-      Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
-      Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
-      Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
+    Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+    Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+    Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
 
-      CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
-      cddata_masks.lmask |= CD_MASK_MLOOPUV;
-      Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
-      int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV);
+    CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
+    cddata_masks.lmask |= CD_MASK_MLOOPUV;
+    Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
+    int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV);
 
-      RNA_enum_item_add_separator(&item, &totitem);
+    RNA_enum_item_add_separator(&item, &totitem);
 
-      for (int i = 0; i < num_data; i++) {
-        tmp_item.value = i;
-        tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
-            &me_eval->ldata, CD_MLOOPUV, i);
-        RNA_enum_item_add(&item, &totitem, &tmp_item);
-      }
+    for (int i = 0; i < num_data; i++) {
+      tmp_item.value = i;
+      tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
+          &me_eval->ldata, CD_MLOOPUV, i);
+      RNA_enum_item_add(&item, &totitem, &tmp_item);
     }
   }
   else if (data_type == DT_TYPE_VCOL) {
-    Object *ob_src = CTX_data_active_object(C);
-
-    if (ob_src) {
-      Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
-      Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
-      Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
+    Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+    Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+    Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
 
-      CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
-      cddata_masks.lmask |= CD_MASK_MLOOPCOL;
-      Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
-      int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPCOL);
+    CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
+    cddata_masks.lmask |= CD_MASK_MLOOPCOL;
+    Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
+    int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPCOL);
 
-      RNA_enum_item_add_separator(&item, &totitem);
+    RNA_enum_item_add_separator(&item, &totitem);
 
-      for (int i = 0; i < num_data; i++) {
-        tmp_item.value = i;
-        tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
-            &me_eval->ldata, CD_MLOOPCOL, i);
-        RNA_enum_item_add(&item, &totitem, &tmp_item);
-      }
+    for (int i = 0; i < num_data; i++) {
+      tmp_item.value = i;
+      tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
+          &me_eval->ldata, CD_MLOOPCOL, i);
+      RNA_enum_item_add(&item, &totitem, &tmp_item);
     }
   }
 
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 4ea599fd30e..f64f95c5322 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -3892,7 +3892,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
   int fail = 0;
 
   CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
-    if (obact != ob) {
+    if (obact != ob && BKE_object_supports_vertex_groups(ob)) {
       if (ED_vgroup_array_copy(ob, obact)) {
         DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
         DEG_relations_tag_update(CTX_data_main(C));
@@ -3909,8 +3909,8 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
   if ((changed_tot == 0 && fail == 0) || fail) {
     BKE_reportf(op->reports,
                 RPT_ERROR,
-                "Copy vertex groups to selected: %d done, %d failed (object data must have "
-                "matching indices)",
+                "Copy vertex groups to selected: %d done, %d failed (object data must support "
+                "vertex groups and have matching indices)",
                 changed_tot,
                 fail);
   }
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index e110459eeea..ed681291e29 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1997,16 +1997,25 @@ static void rna_Object_boundbox_get(PointerRNA *ptr, float *values)
   }
 }
 
+static bool check_object_vgroup_support_and_warn(const Object *ob,
+                                                 const char *op_name,
+                                                 ReportList *reports)
+{
+  if (!BKE_object_supports_vertex_groups(ob)) {
+    const char *ob_type_name = "Unknown";
+    RNA_enum_name_from_value(rna_enum_object_type_items, ob->type, &ob_type_name);
+    BKE_reportf(reports, RPT_ERROR, "%s is not supported for '%s' objects", op_name, ob_type_name);
+    return false;
+  }
+  return true;
+}
+
 static bDeformGroup *rna_Object_vgroup_new(Object *ob,
                                            Main *bmain,
                                            ReportList *reports,
                                            const char *name)
 {
-  if (!OB_TYPE_SUPPORT_VGROUP(ob->type)) {
-    const char *ob_type_name = "Unknown";
-    RNA_enum_name_from_value(rna_enum_object_type_items, ob->type, &ob_type_name);
-    BKE_reportf(
-        reports, RPT_ERROR, "VertexGroups.new(): is not supported for '%s' objects", ob_type_name);
+  if (!check_object_vgroup_support_and_warn(ob, "VertexGroups.new()", reports)) {
     return NULL;
   }
 
@@ -2023,6 +2032,10 @@ static void rna_Object_vgroup_remove(Object *ob,
                                      ReportList *reports,
                                      PointerRNA *defgroup_ptr)
 {
+  if (!check_object_vgroup_support_and_warn(ob, "VertexGroups.remove()", reports)) {
+    return;
+  }
+
   bDeformGroup *defgroup = defgroup_ptr->data;
   ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
 
@@ -2042,8 +2055,12 @@ static void rna_Object_vgroup_remove(Object *ob,
   WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
 }
 
-static void rna_Object_vgroup_clear(Object *ob, Main *bmain)
+static void rna_Object_vgroup_clear(Object *ob, Main *bmain, ReportList *reports)
 {
+  if (!check_object_vgroup_support_and_warn(ob, "VertexGroups.clear()", reports)) {
+    return;
+  }
+
   BKE_object_defgroup_remove_all(ob);
 
   DEG_relations_tag_update(bmain);
@@ -2777,7 +2794,7 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
   RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
 
   func = RNA_def_function(srna, "clear", "rna_Object_vgroup_clear");
-  RNA_def_function_flag(func, FUNC_USE_MAIN);
+  RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
   RNA_def_function_ui_description(func, "Delete all vertex groups from object");
 }



More information about the Bf-blender-cvs mailing list