diff options
Diffstat (limited to 'source/blender/blenkernel/intern/material.c')
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 115 |
1 files changed, 114 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index b8788a2bffb..b3e0f16f604 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -111,6 +111,9 @@ void BKE_material_free_ex(Material *ma, bool do_id_user) MEM_freeN(ma->nodetree); } + if (ma->texpaintslot) + MEM_freeN(ma->texpaintslot); + if (ma->gpumaterial.first) GPU_material_free(ma); } @@ -269,7 +272,9 @@ Material *localize_material(Material *ma) if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col); if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec); - + + if (ma->texpaintslot) man->texpaintslot = MEM_dupallocN(man->texpaintslot); + man->preview = NULL; if (ma->nodetree) @@ -1301,6 +1306,114 @@ bool object_remove_material_slot(Object *ob) return true; } +void BKE_texpaint_slots_clear(struct Material *ma) +{ + + if (ma->texpaintslot) { + MEM_freeN(ma->texpaintslot); + ma->texpaintslot = NULL; + } + ma->tot_slots = 0; + ma->paint_active_slot = 0; + ma->paint_clone_slot = 0; +} + + +static bool get_mtex_slot_valid_texpaint(struct MTex *mtex) +{ + return (mtex && (mtex->texco == TEXCO_UV) && + mtex->tex && (mtex->tex->type == TEX_IMAGE) && + mtex->tex->ima); +} + +void BKE_texpaint_slot_refresh_cache(Material *ma, bool use_nodes) +{ + MTex **mtex; + short count = 0; + short index = 0, i; + + if (!ma) + return; + + if (ma->texpaintslot) { + MEM_freeN(ma->texpaintslot); + ma->texpaintslot = NULL; + } + + if (use_nodes) { + bNode *node, *active_node; + + if (!(ma->use_nodes && ma->nodetree)) + return; + + for (node = ma->nodetree->nodes.first; node; node = node->next) { + if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) + count++; + } + + ma->tot_slots = count; + + if (count == 0) { + ma->paint_active_slot = 0; + return; + } + ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots"); + + active_node = nodeGetActiveTexture(ma->nodetree); + + for (node = ma->nodetree->nodes.first; node; node = node->next) { + if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) { + if (active_node == node) + ma->paint_active_slot = index; + ma->texpaintslot[index++].ima = (Image *)node->id; + } + } + } + else { + for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) { + if (get_mtex_slot_valid_texpaint(*mtex)) { + count++; + } + } + + ma->tot_slots = count; + + if (count == 0) { + ma->paint_active_slot = 0; + return; + } + + ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots"); + + for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) { + if (get_mtex_slot_valid_texpaint(*mtex)) { + ma->texpaintslot[index].ima = (*mtex)->tex->ima; + BLI_strncpy(ma->texpaintslot[index++].uvname, (*mtex)->uvname, 64); + } + } + } + + if (ma->paint_active_slot >= count) { + ma->paint_active_slot = count - 1; + } + + if (ma->paint_clone_slot >= count) { + ma->paint_clone_slot = count - 1; + } + + return; +} + +void BKE_texpaint_slots_refresh_object(struct Object *ob, bool use_nodes) +{ + int i; + + for (i = 1; i < ob->totcol + 1; i++) { + Material *ma = give_current_material(ob, i); + BKE_texpaint_slot_refresh_cache(ma, use_nodes); + } +} + /* 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]) |