Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes/shader/node_shader_tree.c')
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c211
1 files changed, 118 insertions, 93 deletions
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 8fde0b9c342..30da509c09d 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -36,6 +36,7 @@
#include "DNA_material_types.h"
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
#include "DNA_world_types.h"
#include "BLI_listbase.h"
@@ -45,11 +46,14 @@
#include "BLF_translation.h"
+#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_scene.h"
+#include "RNA_access.h"
+
#include "GPU_material.h"
#include "RE_shader_ext.h"
@@ -59,23 +63,45 @@
#include "node_util.h"
#include "node_shader_util.h"
-static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func)
+static int shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype))
{
- Material *ma;
- Lamp *la;
- World *wo;
-
- for (ma = main->mat.first; ma; ma = ma->id.next)
- if (ma->nodetree)
- func(calldata, &ma->id, ma->nodetree);
-
- for (la = main->lamp.first; la; la = la->id.next)
- if (la->nodetree)
- func(calldata, &la->id, la->nodetree);
+ Scene *scene = CTX_data_scene(C);
+ /* allow empty engine string too, this is from older versions that didn't have registerable engines yet */
+ return (scene->r.engine[0] == '\0'
+ || strcmp(scene->r.engine, "BLENDER_RENDER")==0
+ || strcmp(scene->r.engine, "CYCLES")==0);
+}
- for (wo = main->world.first; wo; wo = wo->id.next)
- if (wo->nodetree)
- func(calldata, &wo->id, wo->nodetree);
+static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = OBACT;
+
+ if (snode->shaderfrom == SNODE_SHADER_OBJECT) {
+ if (ob) {
+ if (ob->type == OB_LAMP) {
+ *r_from = &ob->id;
+ *r_id = ob->data;
+ *r_ntree = ((Lamp *)ob->data)->nodetree;
+ }
+ else {
+ Material *ma = give_current_material(ob, ob->actcol);
+ if (ma) {
+ *r_from = &ob->id;
+ *r_id = &ma->id;
+ *r_ntree = ma->nodetree;
+ }
+ }
+ }
+ }
+ else { /* SNODE_SHADER_WORLD */
+ if (scene->world) {
+ *r_from = NULL;
+ *r_id = &scene->world->id;
+ *r_ntree = scene->world->nodetree;
+ }
+ }
}
static void foreach_nodeclass(Scene *scene, void *calldata, bNodeClassCallback func)
@@ -93,6 +119,7 @@ static void foreach_nodeclass(Scene *scene, void *calldata, bNodeClassCallback f
func(calldata, NODE_CLASS_CONVERTOR, N_("Convertor"));
func(calldata, NODE_CLASS_SCRIPT, N_("Script"));
func(calldata, NODE_CLASS_GROUP, N_("Group"));
+ func(calldata, NODE_CLASS_INTERFACE, N_("Interface"));
func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
}
@@ -111,24 +138,8 @@ 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)
@@ -136,26 +147,36 @@ static void update(bNodeTree *ntree)
ntreeSetOutput(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_Shader = {
- /* type */ NTREE_SHADER,
- /* id_name */ "NTShader Nodetree",
+bNodeTreeType *ntreeType_Shader;
+
+void register_node_tree_type_sh()
+{
+ bNodeTreeType *tt = ntreeType_Shader = MEM_callocN(sizeof(bNodeTreeType), "shader node tree type");
+
+ tt->type = NTREE_SHADER;
+ strcpy(tt->idname, "ShaderNodeTree");
+ strcpy(tt->ui_name, "Shader");
+ tt->ui_icon = 0; /* defined in drawnode.c */
+ strcpy(tt->ui_description, "");
- /* node_types */ { NULL, NULL },
+ tt->foreach_nodeclass = foreach_nodeclass;
+ tt->localize = localize;
+ tt->local_sync = local_sync;
+ tt->update = update;
+ tt->poll = shader_tree_poll;
+ tt->get_from_context = shader_get_from_context;
- /* 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->ext.srna = &RNA_ShaderNodeTree;
+
+ ntreeTypeAdd(tt);
+}
/* GPU material from shader nodes */
@@ -163,11 +184,11 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat)
{
bNodeTreeExec *exec;
- exec = ntreeShaderBeginExecTree(ntree, 1);
+ exec = ntreeShaderBeginExecTree(ntree);
ntreeExecGPUNodes(exec, mat, 1);
- ntreeShaderEndExecTree(exec, 1);
+ ntreeShaderEndExecTree(exec);
}
/* **************** call to switch lamploop for material node ************ */
@@ -180,27 +201,16 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult
}
-/* 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 *ntreeShaderBeginExecTree(bNodeTree *ntree, int use_tree_data)
+bNodeTreeExec *ntreeShaderBeginExecTree_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;
- }
-
/* ensures only a single output node is enabled */
ntreeSetOutput(ntree);
/* 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");
@@ -208,43 +218,58 @@ bNodeTreeExec *ntreeShaderBeginExecTree(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 *ntreeShaderBeginExecTree(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 = ntreeShaderBeginExecTree_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;
}
-/* 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 ntreeShaderEndExecTree(bNodeTreeExec *exec, int use_tree_data)
+void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
{
- if (exec) {
- bNodeTree *ntree = exec->nodetree;
- bNodeThreadStack *nts;
- int a;
-
- if (exec->threadstack) {
- 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;
+ bNodeThreadStack *nts;
+ int a;
+
+ if (exec->threadstack) {
+ 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 ntreeShaderEndExecTree(bNodeTreeExec *exec)
+{
+ if (exec) {
+ ntreeShaderEndExecTree_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;
}
}
@@ -272,7 +297,7 @@ bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
if (!exec) {
BLI_lock_thread(LOCK_NODES);
if (!ntree->execdata)
- ntree->execdata = ntreeShaderBeginExecTree(ntree, 1);
+ ntree->execdata = ntreeShaderBeginExecTree(ntree);
BLI_unlock_thread(LOCK_NODES);
exec = ntree->execdata;