[Bf-blender-cvs] [da1323d1c95] master: Fix T60366: texture paint slots not updating when editing material.

Brecht Van Lommel noreply at git.blender.org
Thu Feb 28 19:17:50 CET 2019


Commit: da1323d1c95095feff98e8aa054d73fd323c363d
Author: Brecht Van Lommel
Date:   Thu Feb 28 14:09:19 2019 +0100
Branches: master
https://developer.blender.org/rBda1323d1c95095feff98e8aa054d73fd323c363d

Fix T60366: texture paint slots not updating when editing material.

Now always refresh when the material changes. Depsgraph tag moved out
of the refresh function since that gets called on depsgraph update,
which should not trigger a second depsgraph update.

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

M	source/blender/blenkernel/BKE_material.h
M	source/blender/blenkernel/intern/material.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/render/render_update.c
M	source/blender/editors/sculpt_paint/paint_image.c
M	source/blender/editors/sculpt_paint/paint_image_proj.c
M	source/blender/editors/util/ed_util.c
M	source/blender/makesrna/intern/rna_sculpt_paint.c

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

diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 1c171ef6e7c..84760a522f3 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -83,8 +83,8 @@ bool  BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob);
 
 struct MaterialGPencilStyle *BKE_material_gpencil_settings_get(struct Object *ob, short act);
 
-void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma);
-void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob);
+void BKE_texpaint_slot_refresh_cache(struct Material *ma);
+void BKE_texpaint_slots_refresh_object(struct Object *ob);
 
 /* rna api */
 void BKE_material_resize_id(struct Main *bmain, struct ID *id, short totcol, bool do_id_user);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index f6bd5a8cd06..138a6426b39 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -228,6 +228,7 @@ Material *BKE_material_localize(Material *ma)
 	Material *man = BKE_libblock_copy_for_localize(&ma->id);
 
 	man->texpaintslot = NULL;
+	man->tot_slots = 0;
 	man->preview = NULL;
 
 	if (ma->nodetree != NULL) {
@@ -1046,7 +1047,7 @@ static int count_texture_nodes_recursive(bNodeTree *nodetree)
 	return tex_nodes;
 }
 
-static void fill_texpaint_slots_recursive(bNodeTree *nodetree, bNode *active_node, Material *ma, int *index)
+static void fill_texpaint_slots_recursive(bNodeTree *nodetree, bNode *active_node, Material *ma, TexPaintSlot *slots, int *index)
 {
 	for (bNode *node = nodetree->nodes.first; node; node = node->next) {
 		if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
@@ -1054,99 +1055,77 @@ static void fill_texpaint_slots_recursive(bNodeTree *nodetree, bNode *active_nod
 				ma->paint_active_slot = *index;
 			}
 
-			ma->texpaintslot[*index].ima = (Image *)node->id;
-			ma->texpaintslot[*index].interp = ((NodeTexImage *)node->storage)->interpolation;
+			slots[*index].ima = (Image *)node->id;
+			slots[*index].interp = ((NodeTexImage *)node->storage)->interpolation;
 
 			/* for new renderer, we need to traverse the treeback in search of a UV node */
 			bNode *uvnode = nodetree_uv_node_recursive(node);
 
 			if (uvnode) {
 				NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage;
-				ma->texpaintslot[*index].uvname = storage->uv_map;
+				slots[*index].uvname = storage->uv_map;
 				/* set a value to index so UI knows that we have a valid pointer for the mesh */
-				ma->texpaintslot[*index].valid = true;
+				slots[*index].valid = true;
 			}
 			else {
 				/* just invalidate the index here so UV map does not get displayed on the UI */
-				ma->texpaintslot[*index].valid = false;
+				slots[*index].valid = false;
 			}
 			(*index)++;
 		}
 		else if (node->type == NODE_GROUP) {
 			/* recurse into the node group and see if it contains any textures */
-			fill_texpaint_slots_recursive((bNodeTree *)node->id, active_node, ma, index);
+			fill_texpaint_slots_recursive((bNodeTree *)node->id, active_node, ma, slots, index);
 		}
 	}
 }
 
-void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
+void BKE_texpaint_slot_refresh_cache(Material *ma)
 {
-	int count = 0;
-	int index = 0;
-
-	if (!ma)
-		return;
-
-	/* COW needed when adding texture slot on an object with no materials. */
-	DEG_id_tag_update(&ma->id, ID_RECALC_SHADING | ID_RECALC_COPY_ON_WRITE);
-
-	if (ma->texpaintslot) {
-		MEM_freeN(ma->texpaintslot);
-		ma->tot_slots = 0;
-		ma->texpaintslot = NULL;
-	}
-
-	if (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_IMAGE) {
-		ma->paint_active_slot = 0;
-		ma->paint_clone_slot = 0;
+	if (ma == NULL) {
 		return;
 	}
 
-	if (!(ma->nodetree)) {
-		ma->paint_active_slot = 0;
-		ma->paint_clone_slot = 0;
-		return;
-	}
+	/* Compute texture paint slots. */
+	TexPaintSlot *texpaintslot = NULL;
+	int tot_slots = (ma->nodetree) ? count_texture_nodes_recursive(ma->nodetree) : 0;
 
-	count = count_texture_nodes_recursive(ma->nodetree);
+	if (tot_slots) {
+		texpaintslot = MEM_callocN(sizeof(*texpaintslot) * tot_slots, "texpaint_slots");
 
-	if (count == 0) {
-		ma->paint_active_slot = 0;
-		ma->paint_clone_slot = 0;
-		return;
+		bNode *active_node = nodeGetActiveTexture(ma->nodetree);
+		int index = 0;
+		fill_texpaint_slots_recursive(ma->nodetree, active_node, ma, texpaintslot, &index);
 	}
 
-	ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
-
-	bNode *active_node = nodeGetActiveTexture(ma->nodetree);
-
-	fill_texpaint_slots_recursive(ma->nodetree, active_node, ma, &index);
-
-	ma->tot_slots = count;
-
+	/* Keep active slots within range. */
+	if (ma->paint_active_slot >= tot_slots) {
+		ma->paint_active_slot = MAX2(tot_slots - 1, 0);
+	}
 
-	if (ma->paint_active_slot >= count) {
-		ma->paint_active_slot = count - 1;
+	if (ma->paint_clone_slot >= tot_slots) {
+		ma->paint_clone_slot = MAX2(tot_slots - 1, 0);
 	}
 
-	if (ma->paint_clone_slot >= count) {
-		ma->paint_clone_slot = count - 1;
+	/* Replace slots. */
+	if (ma->texpaintslot) {
+		MEM_freeN(ma->texpaintslot);
 	}
 
-	return;
+	ma->texpaintslot = texpaintslot;
+	ma->tot_slots = tot_slots;
 }
 
-void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
+void BKE_texpaint_slots_refresh_object(struct Object *ob)
 {
 	int i;
 
 	for (i = 1; i < ob->totcol + 1; i++) {
 		Material *ma = give_current_material(ob, i);
-		BKE_texpaint_slot_refresh_cache(scene, ma);
+		BKE_texpaint_slot_refresh_cache(ma);
 	}
 }
 
-
 /* r_col = current value, col = new value, (fac == 0) is no change */
 void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
 {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 250c4aacfc6..7145e67a4f2 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4513,6 +4513,7 @@ static void direct_link_material(FileData *fd, Material *ma)
 	direct_link_animdata(fd, ma->adt);
 
 	ma->texpaintslot = NULL;
+	ma->tot_slots = 0;
 
 	ma->nodetree = newdataadr(fd, ma->nodetree);
 	if (ma->nodetree) {
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 462fd997fc5..6e6154e638a 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -206,6 +206,8 @@ void ED_render_engine_changed(Main *bmain)
 
 static void material_changed(Main *UNUSED(bmain), Material *ma)
 {
+	BKE_texpaint_slot_refresh_cache(ma);
+
 	/* icons */
 	BKE_icon_changed(BKE_icon_id_ensure(&ma->id));
 }
@@ -266,7 +268,7 @@ static void scene_changed(Main *bmain, Scene *scene)
 	/* glsl */
 	for (ob = bmain->object.first; ob; ob = ob->id.next) {
 		if (ob->mode & OB_MODE_TEXTURE_PAINT) {
-			BKE_texpaint_slots_refresh_object(scene, ob);
+			BKE_texpaint_slots_refresh_object(ob);
 			BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
 		}
 	}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 44f05c39a25..9d90b6fcd5f 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -1095,7 +1095,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
 
 		/* This has to stay here to regenerate the texture paint
 		 * cache in case we are loading a file */
-		BKE_texpaint_slots_refresh_object(scene, ob);
+		BKE_texpaint_slots_refresh_object(ob);
 
 		BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
 
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index d803b4d0aa8..b4abab0fabd 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -5757,7 +5757,7 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m
 					hasmat = true;
 					if (!ma->texpaintslot) {
 						/* refresh here just in case */
-						BKE_texpaint_slot_refresh_cache(scene, ma);
+						BKE_texpaint_slot_refresh_cache(ma);
 
 						/* if still no slots, we have to add */
 						if (ma->texpaintslot) {
@@ -6017,13 +6017,13 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
 		nodePositionPropagate(out_node);
 
 		if (ima) {
-			BKE_texpaint_slot_refresh_cache(scene, ma);
+			BKE_texpaint_slot_refresh_cache(ma);
 			BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE);
 			WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima);
 		}
 
 		DEG_id_tag_update(&ntree->id, 0);
-		DEG_id_tag_update(&ma->id, ID_RECALC_SHADING);
+		DEG_id_tag_update(&ma->id, ID_RECALC_SHADING | ID_RECALC_COPY_ON_WRITE);
 		ED_area_tag_redraw(CTX_wm_area(C));
 
 		BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 6f0c8594446..ea99dd9996e 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -90,7 +90,7 @@ void ED_editors_init_for_undo(Main *bmain)
 			if (ob->mode & OB_MODE_TEXTURE_PAINT) {
 				Scene *scene = WM_window_get_active_scene(win);
 
-				BKE_texpaint_slots_refresh_object(scene, ob);
+				BKE_texpaint_slots_refresh_object(ob);
 				BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
 			}
 		}
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index ed51129dfc5..c8722005927 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -455,7 +455,7 @@ static void rna_ImaPaint_mode_update(bContext *C, PointerRNA *UNUSED(ptr))
 
 	if (ob && ob->type == OB_MESH) {
 		/* of course we need to invalidate here */
-		BKE_texpaint_slots_refresh_object(scene, ob);
+		BKE_texpaint_slots_refresh_object(ob);
 
 		/* we assume that changing the current mode will invalidate the uv layers so we n

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list