diff options
Diffstat (limited to 'source/blender/nodes/texture/node_texture_tree.c')
-rw-r--r-- | source/blender/nodes/texture/node_texture_tree.c | 206 |
1 files changed, 124 insertions, 82 deletions
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index ba94531c259..0690ccdd19f 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -34,6 +34,7 @@ #include "DNA_texture_types.h" #include "DNA_node_types.h" +#include "DNA_space_types.h" #include "BLI_listbase.h" #include "BLI_threads.h" @@ -41,9 +42,11 @@ #include "BLF_translation.h" +#include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_paint.h" #include "node_common.h" #include "node_exec.h" @@ -51,16 +54,57 @@ #include "NOD_texture.h" #include "node_texture_util.h" +#include "RNA_access.h" + #include "RE_pipeline.h" #include "RE_shader_ext.h" -static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func) +static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from) { - Tex *tx; - for (tx = main->tex.first; tx; tx = tx->id.next) { - if (tx->nodetree) { - func(calldata, &tx->id, tx->nodetree); + SpaceNode *snode = CTX_wm_space_node(C); + Scene *scene = CTX_data_scene(C); + Object *ob = OBACT; + Tex *tx = NULL; + + if (snode->texfrom == SNODE_TEX_OBJECT) { + if (ob) { + tx = give_current_object_texture(ob); + if (tx) { + if (ob->type == OB_LAMP) + *r_from = (ID*)ob->data; + else + *r_from = (ID*)give_current_material(ob, ob->actcol); + + /* from is not set fully for material nodes, should be ID + Node then */ + *r_id = &tx->id; + *r_ntree = tx->nodetree; + } + } + } + else if (snode->texfrom == SNODE_TEX_WORLD) { + tx = give_current_world_texture(scene->world); + if (tx) { + *r_from = (ID *)scene->world; + *r_id = &tx->id; + *r_ntree = tx->nodetree; + } + } + else { + struct Brush *brush = NULL; + + if (ob && (ob->mode & OB_MODE_SCULPT)) + brush = paint_brush(&scene->toolsettings->sculpt->paint); + else + brush = paint_brush(&scene->toolsettings->imapaint.paint); + + if (brush) { + *r_from = (ID *)brush; + tx = give_current_brush_texture(brush); + if (tx) { + *r_id = &tx->id; + *r_ntree = tx->nodetree; + } } } } @@ -75,6 +119,7 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa func(calldata, NODE_CLASS_CONVERTOR, N_("Convertor")); func(calldata, NODE_CLASS_DISTORT, N_("Distort")); func(calldata, NODE_CLASS_GROUP, N_("Group")); + func(calldata, NODE_CLASS_INTERFACE, N_("Interface")); func(calldata, NODE_CLASS_LAYOUT, N_("Layout")); } @@ -93,49 +138,42 @@ static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree)) } } -static void local_sync(bNodeTree *localtree, bNodeTree *ntree) +static void local_sync(bNodeTree *UNUSED(localtree), bNodeTree *UNUSED(ntree)) { - bNode *lnode; - - /* copy over contents of previews */ - for (lnode = localtree->nodes.first; lnode; lnode = lnode->next) { - if (ntreeNodeExists(ntree, lnode->new_node)) { - bNode *node = lnode->new_node; - - if (node->preview && node->preview->rect) { - if (lnode->preview && lnode->preview->rect) { - int xsize = node->preview->xsize; - int ysize = node->preview->ysize; - memcpy(node->preview->rect, lnode->preview->rect, 4 * xsize + xsize * ysize * sizeof(char) * 4); - } - } - } - } } static void update(bNodeTree *ntree) { ntree_update_reroute_nodes(ntree); + + if (ntree->update & NTREE_UPDATE_NODES) { + /* clean up preview cache, in case nodes have been removed */ + BKE_node_preview_remove_unused(ntree); + } } -bNodeTreeType ntreeType_Texture = { - /* type */ NTREE_TEXTURE, - /* id_name */ "NTTexture Nodetree", +bNodeTreeType *ntreeType_Texture; + +void register_node_tree_type_tex() +{ + bNodeTreeType *tt = ntreeType_Texture = MEM_callocN(sizeof(bNodeTreeType), "texture node tree type"); - /* node_types */ { NULL, NULL }, + tt->type = NTREE_TEXTURE; + strcpy(tt->idname, "TextureNodeTree"); + strcpy(tt->ui_name, "Texture"); + tt->ui_icon = 0; /* defined in drawnode.c */ + strcpy(tt->ui_description, ""); - /* free_cache */ NULL, - /* free_node_cache */ NULL, - /* foreach_nodetree */ foreach_nodetree, - /* foreach_nodeclass */ foreach_nodeclass, - /* localize */ localize, - /* local_sync */ local_sync, - /* local_merge */ NULL, - /* update */ update, - /* update_node */ NULL, - /* validate_link */ NULL, - /* update_internal_links */ node_update_internal_links_default -}; + tt->foreach_nodeclass = foreach_nodeclass; + tt->update = update; + tt->localize = localize; + tt->local_sync = local_sync; + tt->get_from_context = texture_get_from_context; + + tt->ext.srna = &RNA_TextureNodeTree; + + ntreeTypeAdd(tt); +} int ntreeTexTagAnimated(bNodeTree *ntree) { @@ -158,24 +196,13 @@ int ntreeTexTagAnimated(bNodeTree *ntree) return 0; } -/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes. - * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees. - */ -bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree, int use_tree_data) +bNodeTreeExec *ntreeTexBeginExecTree_internal(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key) { bNodeTreeExec *exec; bNode *node; - if (use_tree_data) { - /* XXX hack: prevent exec data from being generated twice. - * this should be handled by the renderer! - */ - if (ntree->execdata) - return ntree->execdata; - } - /* common base initialization */ - exec = ntree_exec_begin(ntree); + exec = ntree_exec_begin(context, ntree, parent_key); /* allocate the thread stack listbase array */ exec->threadstack = MEM_callocN(BLENDER_MAX_THREADS * sizeof(ListBase), "thread stack array"); @@ -183,12 +210,28 @@ bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree, int use_tree_data) for (node = exec->nodetree->nodes.first; node; node = node->next) node->need_exec = 1; - if (use_tree_data) { - /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes, - * which only store the ntree pointer. Should be fixed at some point! - */ - ntree->execdata = exec; - } + return exec; +} + +bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree) +{ + bNodeExecContext context; + bNodeTreeExec *exec; + + /* XXX hack: prevent exec data from being generated twice. + * this should be handled by the renderer! + */ + if (ntree->execdata) + return ntree->execdata; + + context.previews = ntree->previews; + + exec = ntreeTexBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE); + + /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes, + * which only store the ntree pointer. Should be fixed at some point! + */ + ntree->execdata = exec; return exec; } @@ -207,35 +250,34 @@ static void tex_free_delegates(bNodeTreeExec *exec) MEM_freeN(ns->data); } -/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes. - * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees. - */ -void ntreeTexEndExecTree(bNodeTreeExec *exec, int use_tree_data) +void ntreeTexEndExecTree_internal(bNodeTreeExec *exec) { - if (exec) { - bNodeTree *ntree = exec->nodetree; - bNodeThreadStack *nts; - int a; + bNodeThreadStack *nts; + int a; + + if (exec->threadstack) { + tex_free_delegates(exec); - if (exec->threadstack) { - tex_free_delegates(exec); - - for (a = 0; a < BLENDER_MAX_THREADS; a++) { - for (nts = exec->threadstack[a].first; nts; nts = nts->next) - if (nts->stack) MEM_freeN(nts->stack); - BLI_freelistN(&exec->threadstack[a]); - } - - MEM_freeN(exec->threadstack); - exec->threadstack = NULL; + for (a = 0; a < BLENDER_MAX_THREADS; a++) { + for (nts = exec->threadstack[a].first; nts; nts = nts->next) + if (nts->stack) MEM_freeN(nts->stack); + BLI_freelistN(&exec->threadstack[a]); } - ntree_exec_end(exec); + MEM_freeN(exec->threadstack); + exec->threadstack = NULL; + } + + ntree_exec_end(exec); +} + +void ntreeTexEndExecTree(bNodeTreeExec *exec) +{ + if (exec) { + ntreeTexEndExecTree_internal(exec); - if (use_tree_data) { - /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */ - ntree->execdata = NULL; - } + /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */ + exec->nodetree->execdata = NULL; } } @@ -275,7 +317,7 @@ int ntreeTexExecTree( if (!exec) { BLI_lock_thread(LOCK_NODES); if (!nodes->execdata) - ntreeTexBeginExecTree(nodes, 1); + ntreeTexBeginExecTree(nodes); BLI_unlock_thread(LOCK_NODES); exec = nodes->execdata; |