GSOC 2013 paint
[blender-staging.git] / source / blender / blenkernel / intern / material.c
index b8788a2bffb58fa83d4ab4c69f67bb3f78332f94..b3e0f16f6042abd6e58d02990c55bec5e7474778 100644 (file)
@@ -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])