diff options
-rw-r--r-- | source/blender/blenkernel/BKE_material.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 127 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_material.c | 12 |
3 files changed, 94 insertions, 47 deletions
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 9d8b9218a79..268cf831456 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -28,6 +28,7 @@ extern "C" { #endif +struct bNode; struct ID; struct Main; struct Material; @@ -94,6 +95,7 @@ struct MaterialGPencilStyle *BKE_material_gpencil_settings_get(struct Object *ob void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma); void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob); +struct bNode *BKE_texpaint_slot_material_find_node(struct Material *ma, short texpaint_slot); /* 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 e845271d802..6fdc1995ca5 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1085,65 +1085,93 @@ static bNode *nodetree_uv_node_recursive(bNode *node) return NULL; } -static int count_texture_nodes_recursive(bNodeTree *nodetree) +typedef bool (*ForEachTexNodeCallback)(bNode *node, void *userdata); +static bool ntree_foreach_texnode_recursive(bNodeTree *nodetree, + ForEachTexNodeCallback callback, + void *userdata) { - int tex_nodes = 0; - 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) { - tex_nodes++; + if (!callback(node, userdata)) { + return false; + } } else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) { /* recurse into the node group and see if it contains any textures */ - tex_nodes += count_texture_nodes_recursive((bNodeTree *)node->id); + if (!ntree_foreach_texnode_recursive((bNodeTree *)node->id, callback, userdata)) { + return false; + } } } + return true; +} + +static bool count_texture_nodes_cb(bNode *node, void *userdata) +{ + (*((int *)userdata))++; + return true; +} + +static int count_texture_nodes_recursive(bNodeTree *nodetree) +{ + int tex_nodes = 0; + ntree_foreach_texnode_recursive(nodetree, count_texture_nodes_cb, &tex_nodes); return tex_nodes; } -static void fill_texpaint_slots_recursive(bNodeTree *nodetree, - bNode *active_node, - Material *ma, - int *index) +struct FillTexPaintSlotsData { + bNode *active_node; + Material *ma; + int index; + int slot_len; +}; + +static bool fill_texpaint_slots_cb(bNode *node, void *userdata) { - 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) { - if (active_node == node) { - ma->paint_active_slot = *index; - } + struct FillTexPaintSlotsData *fill_data = userdata; - ma->texpaintslot[*index].ima = (Image *)node->id; - ma->texpaintslot[*index].interp = ((NodeTexImage *)node->storage)->interpolation; + Material *ma = fill_data->ma; + int index = fill_data->index; + fill_data->index++; - /* for new renderer, we need to traverse the treeback in search of a UV node */ - bNode *uvnode = nodetree_uv_node_recursive(node); + if (fill_data->active_node == node) { + ma->paint_active_slot = index; + } - if (uvnode) { - NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage; - ma->texpaintslot[*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; - } - else { - /* just invalidate the index here so UV map does not get displayed on the UI */ - ma->texpaintslot[*index].valid = false; - } - (*index)++; - } - else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) { - /* recurse into the node group and see if it contains any textures */ - fill_texpaint_slots_recursive((bNodeTree *)node->id, active_node, ma, index); - } + ma->texpaintslot[index].ima = (Image *)node->id; + ma->texpaintslot[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; + /* set a value to index so UI knows that we have a valid pointer for the mesh */ + ma->texpaintslot[index].valid = true; + } + else { + /* just invalidate the index here so UV map does not get displayed on the UI */ + ma->texpaintslot[index].valid = false; } + + return fill_data->index != fill_data->slot_len; +} + +static void fill_texpaint_slots_recursive(bNodeTree *nodetree, + bNode *active_node, + Material *ma, + int slot_len) +{ + struct FillTexPaintSlotsData fill_data = {active_node, ma, 0, slot_len}; + ntree_foreach_texnode_recursive(nodetree, fill_texpaint_slots_cb, &fill_data); } void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma) { int count = 0; - int index = 0; if (!ma) { return; @@ -1182,7 +1210,7 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma) bNode *active_node = nodeGetActiveTexture(ma->nodetree); - fill_texpaint_slots_recursive(ma->nodetree, active_node, ma, &index); + fill_texpaint_slots_recursive(ma->nodetree, active_node, ma, count); ma->tot_slots = count; @@ -1207,6 +1235,31 @@ void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob) } } +struct FindTexPaintNodeData { + bNode *node; + short iter_index; + short index; +}; + +static bool texpaint_slot_node_find_cb(bNode *node, void *userdata) +{ + struct FindTexPaintNodeData *find_data = userdata; + if (find_data->iter_index++ == find_data->index) { + find_data->node = node; + return false; + } + + return true; +} + +bNode *BKE_texpaint_slot_material_find_node(Material *ma, short texpaint_slot) +{ + struct FindTexPaintNodeData find_data = {NULL, 0, texpaint_slot}; + ntree_foreach_texnode_recursive(ma->nodetree, texpaint_slot_node_find_cb, &find_data); + + return find_data.node; +} + /* 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/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 28989d1dd5f..162ba6be834 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -147,16 +147,8 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Material *ma = ptr->id.data; if (ma->use_nodes && ma->nodetree) { - struct bNode *node; - int index = 0; - for (node = ma->nodetree->nodes.first; node; node = node->next) { - if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && - node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) { - if (index++ == ma->paint_active_slot) { - break; - } - } - } + struct bNode *node = BKE_texpaint_slot_material_find_node(ma, ma->paint_active_slot); + if (node) { nodeSetActive(ma->nodetree, node); } |