From c70f975d5c3b961e0c77eba3a35c8a892f39214d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 16 Aug 2019 14:36:57 +0200 Subject: Fix T67999: calling Mesh.materials.clear() crashes Blender The `BKE_material_pop_id()` and `BKE_material_clear_id()` functions had a parameter `update_data` that, when `false`, would cause the mesh polys to keep their material index, even when the indexed material slots were removed. This behaviour was never used in the C code and not supported by the drawing code, making polygons disappear and causing crashes. The Python binding in RNA, however, defaulted to `update_data=False`. This commit removes the `update_data` parameter altogether, and makes the functions always fix up the material indices. Reviewed by: mont29, brecht --- source/blender/blenkernel/BKE_material.h | 5 ++--- source/blender/blenkernel/intern/material.c | 16 +++++----------- source/blender/editors/mesh/editmesh_tools.c | 4 ++-- source/blender/makesrna/intern/rna_ID.c | 13 ++++--------- 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 5bb69c7166e..44a8f98e994 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -104,9 +104,8 @@ void BKE_material_append_id(struct Main *bmain, struct ID *id, struct Material * struct Material *BKE_material_pop_id(struct Main *bmain, struct ID *id, /* index is an int because of RNA. */ - int index, - bool update_data); -void BKE_material_clear_id(struct Main *bmain, struct ID *id, bool update_data); + int index); +void BKE_material_clear_id(struct Main *bmain, struct ID *id); /* rendering */ void ramp_blend(int type, float r_col[3], const float fac, const float col[3]); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index b01c1189fd1..1545ae4f48f 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -461,7 +461,7 @@ void BKE_material_append_id(Main *bmain, ID *id, Material *ma) } } -Material *BKE_material_pop_id(Main *bmain, ID *id, int index_i, bool update_data) +Material *BKE_material_pop_id(Main *bmain, ID *id, int index_i) { short index = (short)index_i; Material *ret = NULL; @@ -489,10 +489,7 @@ Material *BKE_material_pop_id(Main *bmain, ID *id, int index_i, bool update_data test_all_objects_materials(bmain, id); } - if (update_data) { - /* decrease mat_nr index */ - material_data_index_remove_id(id, index); - } + material_data_index_remove_id(id, index); DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE); DEG_relations_tag_update(bmain); @@ -502,7 +499,7 @@ Material *BKE_material_pop_id(Main *bmain, ID *id, int index_i, bool update_data return ret; } -void BKE_material_clear_id(Main *bmain, ID *id, bool update_data) +void BKE_material_clear_id(Main *bmain, ID *id) { Material ***matar; if ((matar = give_matarar_id(id))) { @@ -516,12 +513,9 @@ void BKE_material_clear_id(Main *bmain, ID *id, bool update_data) MEM_freeN(*matar); *matar = NULL; } - test_all_objects_materials(bmain, id); - if (update_data) { - /* decrease mat_nr index */ - material_data_index_clear_id(id); - } + test_all_objects_materials(bmain, id); + material_data_index_clear_id(id); DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE); DEG_relations_tag_update(bmain); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index f57e8141f27..4e58fee61a2 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4040,7 +4040,7 @@ static void mesh_separate_material_assign_mat_nr(Main *bmain, Object *ob, const ma_obdata = NULL; } - BKE_material_clear_id(bmain, obdata, true); + BKE_material_clear_id(bmain, obdata); BKE_material_resize_object(bmain, ob, 1, true); BKE_material_resize_id(bmain, obdata, 1, true); @@ -4051,7 +4051,7 @@ static void mesh_separate_material_assign_mat_nr(Main *bmain, Object *ob, const id_us_plus((ID *)ma_obdata); } else { - BKE_material_clear_id(bmain, obdata, true); + BKE_material_clear_id(bmain, obdata); BKE_material_resize_object(bmain, ob, 0, true); BKE_material_resize_id(bmain, obdata, 0, true); } diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 57cdbbadeb8..7996750a1b8 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -642,8 +642,7 @@ static void rna_IDMaterials_append_id(ID *id, Main *bmain, Material *ma) WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, id); } -static Material *rna_IDMaterials_pop_id( - ID *id, Main *bmain, ReportList *reports, int index_i, bool remove_material_slot) +static Material *rna_IDMaterials_pop_id(ID *id, Main *bmain, ReportList *reports, int index_i) { Material *ma; short *totcol = give_totcolp_id(id); @@ -657,7 +656,7 @@ static Material *rna_IDMaterials_pop_id( return NULL; } - ma = BKE_material_pop_id(bmain, id, index_i, remove_material_slot); + ma = BKE_material_pop_id(bmain, id, index_i); if (*totcol == totcol_orig) { BKE_report(reports, RPT_ERROR, "No material to removed"); @@ -671,9 +670,9 @@ static Material *rna_IDMaterials_pop_id( return ma; } -static void rna_IDMaterials_clear_id(ID *id, Main *bmain, bool remove_material_slot) +static void rna_IDMaterials_clear_id(ID *id, Main *bmain) { - BKE_material_clear_id(bmain, id, remove_material_slot); + BKE_material_clear_id(bmain, id); DEG_id_tag_update(id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_OBJECT | ND_DRAW, id); @@ -1116,16 +1115,12 @@ static void rna_def_ID_materials(BlenderRNA *brna) RNA_def_function_ui_description(func, "Remove a material from the data-block"); parm = RNA_def_int( func, "index", -1, -MAXMAT, MAXMAT, "", "Index of material to remove", 0, MAXMAT); - RNA_def_boolean( - func, "update_data", 0, "", "Update data by re-adjusting the material slots assigned"); parm = RNA_def_pointer(func, "material", "Material", "", "Material to remove"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "clear", "rna_IDMaterials_clear_id"); RNA_def_function_flag(func, FUNC_USE_MAIN); RNA_def_function_ui_description(func, "Remove all materials from the data-block"); - RNA_def_boolean( - func, "update_data", 0, "", "Update data by re-adjusting the material slots assigned"); } static void rna_def_image_preview(BlenderRNA *brna) -- cgit v1.2.3