diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_material.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 83 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/editors/render/render_update.c | 4 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image_proj.c | 6 | ||||
-rw-r--r-- | source/blender/editors/util/ed_util.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sculpt_paint.c | 2 |
8 files changed, 43 insertions, 61 deletions
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 need to refresh display */ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); |