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
This commit is contained in:
parent
6025897cd6
commit
c4df8ac1a4
Notes:
blender-bot
2023-02-14 05:43:04 +01:00
Referenced by issue #89899, BLI_assert failed: BKE_id_defgroup_list_get()
|
@ -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);
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue