Depsgraph: tag relations for update when aterial slots changes
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 12 Aug 2016 12:59:11 +0000 (14:59 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 12 Aug 2016 12:59:11 +0000 (14:59 +0200)
New dependency graph puts materials to the graph in order to deal with animation
assigned to them and things like that. This leads us to a requirement to update
relations when slots changes.

This fixes: T49075 Assignment of a keyframed material using the frame_change_pre handler
                   doesn't update the keyframe using the new dependency graph

source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/intern/material.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/makesrna/intern/rna_ID.c

index df739996c54061b37f079e1988f0c12ec169a810..8ae5c2b3c452b3b33a928d2ac81f0394696c543f 100644 (file)
@@ -49,7 +49,7 @@ void BKE_material_free(struct Material *ma);
 void BKE_material_free_ex(struct Material *ma, bool do_id_user);
 void test_object_materials(struct Object *ob, struct ID *id);
 void test_all_objects_materials(struct Main *bmain, struct ID *id);
-void BKE_material_resize_object(struct Object *ob, const short totcol, bool do_id_user);
+void BKE_material_resize_object(struct Main *bmain, struct Object *ob, const short totcol, bool do_id_user);
 void BKE_material_init(struct Material *ma);
 void BKE_material_remap_object(struct Object *ob, const unsigned int *remap);
 void BKE_material_remap_object_calc(struct  Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst);
@@ -90,10 +90,10 @@ void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma);
 void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob);
 
 /* rna api */
-void BKE_material_resize_id(struct ID *id, short totcol, bool do_id_user);
-void BKE_material_append_id(struct ID *id, struct Material *ma);
-struct Material *BKE_material_pop_id(struct ID *id, int index, bool update_data); /* index is an int because of RNA */
-void BKE_material_clear_id(struct ID *id, bool update_data);
+void BKE_material_resize_id(struct Main *bmain, struct ID *id, short totcol, bool do_id_user);
+void BKE_material_append_id(struct Main *bmain, struct ID *id, struct Material *ma);
+struct Material *BKE_material_pop_id(struct Main *bmain, struct ID *id, int index, bool update_data); /* index is an int because of RNA */
+void BKE_material_clear_id(struct Main *bmain, struct ID *id, bool update_data);
 /* rendering */
 
 void init_render_material(struct Material *, int, float *);
index 470108545b8d2919f0b569c89252a2c98ff79840..54945242fe4064742f128d448af0003f53fe2e4d 100644 (file)
@@ -58,6 +58,7 @@
 #include "BKE_animsys.h"
 #include "BKE_displist.h"
 #include "BKE_global.h"
+#include "BKE_depsgraph.h"
 #include "BKE_icons.h"
 #include "BKE_image.h"
 #include "BKE_library.h"
@@ -398,7 +399,7 @@ static void material_data_index_clear_id(ID *id)
        }
 }
 
-void BKE_material_resize_id(struct ID *id, short totcol, bool do_id_user)
+void BKE_material_resize_id(Main *bmain, ID *id, short totcol, bool do_id_user)
 {
        Material ***matar = give_matarar_id(id);
        short *totcolp = give_totcolp_id(id);
@@ -424,9 +425,11 @@ void BKE_material_resize_id(struct ID *id, short totcol, bool do_id_user)
                *matar = MEM_recallocN(*matar, sizeof(void *) * totcol);
        }
        *totcolp = totcol;
+
+       DAG_relations_tag_update(bmain);
 }
 
-void BKE_material_append_id(ID *id, Material *ma)
+void BKE_material_append_id(Main *bmain, ID *id, Material *ma)
 {
        Material ***matar;
        if ((matar = give_matarar_id(id))) {
@@ -439,11 +442,12 @@ void BKE_material_append_id(ID *id, Material *ma)
                (*matar)[(*totcol)++] = ma;
 
                id_us_plus((ID *)ma);
-               test_all_objects_materials(G.main, id);
+               test_all_objects_materials(bmain, id);
+               DAG_relations_tag_update(bmain);
        }
 }
 
-Material *BKE_material_pop_id(ID *id, int index_i, bool update_data)
+Material *BKE_material_pop_id(Main *bmain, ID *id, int index_i, bool update_data)
 {
        short index = (short)index_i;
        Material *ret = NULL;
@@ -472,13 +476,15 @@ Material *BKE_material_pop_id(ID *id, int index_i, bool update_data)
                                /* decrease mat_nr index */
                                material_data_index_remove_id(id, index);
                        }
+
+                       DAG_relations_tag_update(bmain);
                }
        }
        
        return ret;
 }
 
-void BKE_material_clear_id(struct ID *id, bool update_data)
+void BKE_material_clear_id(Main *bmain, ID *id, bool update_data)
 {
        Material ***matar;
        if ((matar = give_matarar_id(id))) {
@@ -497,6 +503,8 @@ void BKE_material_clear_id(struct ID *id, bool update_data)
                        /* decrease mat_nr index */
                        material_data_index_clear_id(id);
                }
+
+               DAG_relations_tag_update(bmain);
        }
 }
 
@@ -553,7 +561,7 @@ Material *give_node_material(Material *ma)
        return NULL;
 }
 
-void BKE_material_resize_object(Object *ob, const short totcol, bool do_id_user)
+void BKE_material_resize_object(Main *bmain, Object *ob, const short totcol, bool do_id_user)
 {
        Material **newmatar;
        char *newmatbits;
@@ -590,6 +598,8 @@ void BKE_material_resize_object(Object *ob, const short totcol, bool do_id_user)
        ob->totcol = totcol;
        if (ob->totcol && ob->actcol == 0) ob->actcol = 1;
        if (ob->actcol > ob->totcol) ob->actcol = ob->totcol;
+
+       DAG_relations_tag_update(bmain);
 }
 
 void test_object_materials(Object *ob, ID *id)
@@ -601,7 +611,7 @@ void test_object_materials(Object *ob, ID *id)
                return;
        }
 
-       BKE_material_resize_object(ob, *totcol, false);
+       BKE_material_resize_object(G.main, ob, *totcol, false);
 }
 
 void test_all_objects_materials(Main *bmain, ID *id)
@@ -617,7 +627,7 @@ void test_all_objects_materials(Main *bmain, ID *id)
        BKE_main_lock(bmain);
        for (ob = bmain->object.first; ob; ob = ob->id.next) {
                if (ob->data == id) {
-                       BKE_material_resize_object(ob, *totcol, false);
+                       BKE_material_resize_object(bmain, ob, *totcol, false);
                }
        }
        BKE_main_unlock(bmain);
@@ -1881,7 +1891,7 @@ static short mesh_getmaterialnumber(Mesh *me, Material *ma)
 /* append material */
 static short mesh_addmaterial(Mesh *me, Material *ma)
 {
-       BKE_material_append_id(&me->id, NULL);
+       BKE_material_append_id(G.main, &me->id, NULL);
        me->mat[me->totcol - 1] = ma;
 
        id_us_plus(&ma->id);
@@ -2020,7 +2030,7 @@ static void convert_tfacematerial(Main *main, Material *ma)
                /* remove material from mesh */
                for (a = 0; a < me->totcol; ) {
                        if (me->mat[a] == ma) {
-                               BKE_material_pop_id(&me->id, a, true);
+                               BKE_material_pop_id(main, &me->id, a, true);
                        }
                        else {
                                a++;
index eb94c91389c43ec83aa1909a269a05a989db2a07..161ab3a2b82fbd519f9456b3af97dae55d01a3a3 100644 (file)
@@ -4774,7 +4774,7 @@ static void lib_link_object(FileData *fd, Main *main)
                                /* Only expand so as not to loose any object materials that might be set. */
                                if (totcol_data && (*totcol_data > ob->totcol)) {
                                        /* printf("'%s' %d -> %d\n", ob->id.name, ob->totcol, *totcol_data); */
-                                       BKE_material_resize_object(ob, *totcol_data, false);
+                                       BKE_material_resize_object(main, ob, *totcol_data, false);
                                }
                        }
                        
index 1a14fad865088ca980e227b9b5d98c9f28b92527..999d5b278eeb127ee32668315ad12d7e1f864ad4 100644 (file)
@@ -3080,7 +3080,7 @@ static void bm_mesh_hflag_flush_vert(BMesh *bm, const char hflag)
  * \note This could be used for split-by-material for non mesh types.
  * \note This could take material data from another object or args.
  */
-static void mesh_separate_material_assign_mat_nr(Object *ob, const short mat_nr)
+static void mesh_separate_material_assign_mat_nr(Main *bmain, Object *ob, const short mat_nr)
 {
        ID *obdata = ob->data;
 
@@ -3116,18 +3116,18 @@ static void mesh_separate_material_assign_mat_nr(Object *ob, const short mat_nr)
                        ma_obdata = NULL;
                }
 
-               BKE_material_clear_id(obdata, true);
-               BKE_material_resize_object(ob, 1, true);
-               BKE_material_resize_id(obdata, 1, true);
+               BKE_material_clear_id(bmain, obdata, true);
+               BKE_material_resize_object(bmain, ob, 1, true);
+               BKE_material_resize_id(bmain, obdata, 1, true);
 
                ob->mat[0] = ma_ob;
                ob->matbits[0] = matbit;
                (*matarar)[0] = ma_obdata;
        }
        else {
-               BKE_material_clear_id(obdata, true);
-               BKE_material_resize_object(ob, 0, true);
-               BKE_material_resize_id(obdata, 0, true);
+               BKE_material_clear_id(bmain, obdata, true);
+               BKE_material_resize_object(bmain, ob, 0, true);
+               BKE_material_resize_id(bmain, obdata, 0, true);
        }
 }
 
@@ -3162,7 +3162,7 @@ static bool mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BM
 
                /* leave the current object with some materials */
                if (tot == bm_old->totface) {
-                       mesh_separate_material_assign_mat_nr(base_old->object, mat_nr);
+                       mesh_separate_material_assign_mat_nr(bmain, base_old->object, mat_nr);
 
                        /* since we're in editmode, must set faces here */
                        BM_ITER_MESH (f, &iter, bm_old, BM_FACES_OF_MESH) {
@@ -3174,7 +3174,7 @@ static bool mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BM
                /* Move selection into a separate object */
                base_new = mesh_separate_tagged(bmain, scene, base_old, bm_old);
                if (base_new) {
-                       mesh_separate_material_assign_mat_nr(base_new->object, mat_nr);
+                       mesh_separate_material_assign_mat_nr(bmain, base_new->object, mat_nr);
                }
 
                result |= (base_new != NULL);
index fdb93ac1a18f400e8f36e937695994414ca92efe..ab124b361f1e5b33a855efab618d3490afc33078 100644 (file)
@@ -386,15 +386,15 @@ int rna_IDMaterials_assign_int(PointerRNA *ptr, int key, const PointerRNA *assig
        }
 }
 
-static void rna_IDMaterials_append_id(ID *id, Material *ma)
+static void rna_IDMaterials_append_id(ID *id, Main *bmain, Material *ma)
 {
-       BKE_material_append_id(id, ma);
+       BKE_material_append_id(bmain, id, ma);
 
        WM_main_add_notifier(NC_OBJECT | ND_DRAW, id);
        WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, id);
 }
 
-static Material *rna_IDMaterials_pop_id(ID *id, ReportList *reports, int index_i, int remove_material_slot)
+static Material *rna_IDMaterials_pop_id(ID *id, Main *bmain, ReportList *reports, int index_i, int remove_material_slot)
 {
        Material *ma;
        short *totcol = give_totcolp_id(id);
@@ -408,7 +408,7 @@ static Material *rna_IDMaterials_pop_id(ID *id, ReportList *reports, int index_i
                return NULL;
        }
 
-       ma = BKE_material_pop_id(id, index_i, remove_material_slot);
+       ma = BKE_material_pop_id(bmain, id, index_i, remove_material_slot);
 
        if (*totcol == totcol_orig) {
                BKE_report(reports, RPT_ERROR, "No material to removed");
@@ -424,7 +424,7 @@ static Material *rna_IDMaterials_pop_id(ID *id, ReportList *reports, int index_i
 
 static void rna_IDMaterials_clear_id(ID *id, int remove_material_slot)
 {
-       BKE_material_clear_id(id, remove_material_slot);
+       BKE_material_clear_id(G.main, id, remove_material_slot);
 
        DAG_id_tag_update(id, OB_RECALC_DATA);
        WM_main_add_notifier(NC_OBJECT | ND_DRAW, id);
@@ -820,12 +820,13 @@ static void rna_def_ID_materials(BlenderRNA *brna)
        RNA_def_struct_ui_text(srna, "ID Materials", "Collection of materials");
 
        func = RNA_def_function(srna, "append", "rna_IDMaterials_append_id");
+       RNA_def_function_flag(func, FUNC_USE_MAIN);
        RNA_def_function_ui_description(func, "Add a new material to the data block");
        parm = RNA_def_pointer(func, "material", "Material", "", "Material to add");
        RNA_def_property_flag(parm, PROP_REQUIRED);
 
        func = RNA_def_function(srna, "pop", "rna_IDMaterials_pop_id");
-       RNA_def_function_flag(func, FUNC_USE_REPORTS);
+       RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN);
        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");