From fc3be511f07a8107da5f9b0c8778d16295ced7cb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 20 Jan 2014 20:29:05 +0100 Subject: Fix T37978: cycles nodes with multiple Material Output nodes not predictable. Now it uses the last activated node like compositing does. This should have no effect on existing files until you activate another output node there. --- intern/cycles/blender/blender_shader.cpp | 46 ++++++++++++++++++++++----- source/blender/editors/space_node/node_edit.c | 5 +-- source/blender/makesrna/intern/rna_nodetree.c | 10 ++++++ source/blender/nodes/NOD_static_types.h | 8 ++--- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 6100c8a7c64..f97407100db 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -172,6 +172,13 @@ static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_map mapping->max = get_float3(b_mapping.max()); } +static bool is_output_node(BL::Node b_node) +{ + return (b_node.is_a(&RNA_ShaderNodeOutputMaterial) + || b_node.is_a(&RNA_ShaderNodeOutputWorld) + || b_node.is_a(&RNA_ShaderNodeOutputLamp)); +} + static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::ShaderNode b_node) { ShaderNode *node = NULL; @@ -280,12 +287,6 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen node = mapping; } - /* new nodes */ - else if (b_node.is_a(&RNA_ShaderNodeOutputMaterial) - || b_node.is_a(&RNA_ShaderNodeOutputWorld) - || b_node.is_a(&RNA_ShaderNodeOutputLamp)) { - node = graph->output(); - } else if (b_node.is_a(&RNA_ShaderNodeFresnel)) { node = new FresnelNode(); } @@ -667,7 +668,7 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen node = tangent; } - if(node && node != graph->output()) + if(node) graph->add(node); return node; @@ -754,6 +755,26 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha BL::Node::inputs_iterator b_input; BL::Node::outputs_iterator b_output; + /* find the node to use for output if there are multiple */ + bool found_active_output = false; + BL::ShaderNode output_node(PointerRNA_NULL); + + for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) { + if (is_output_node(*b_node)) { + BL::ShaderNodeOutputMaterial b_output_node(*b_node); + + if(b_output_node.is_active_output()) { + output_node = b_output_node; + found_active_output = true; + break; + } + else if(!output_node.ptr.data && !found_active_output) { + output_node = b_output_node; + } + } + } + + /* add nodes */ for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) { if (b_node->mute() || b_node->is_a(&RNA_NodeReroute)) { /* replace muted node with internal links */ @@ -833,7 +854,16 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha } } else { - ShaderNode *node = add_node(scene, b_data, b_scene, graph, b_ntree, BL::ShaderNode(*b_node)); + ShaderNode *node = NULL; + + if (is_output_node(*b_node)) { + if (b_node->ptr.data == output_node.ptr.data) { + node = graph->output(); + } + } + else { + node = add_node(scene, b_data, b_scene, graph, b_ntree, BL::ShaderNode(*b_node)); + } if(node) { /* map node sockets for linking */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 6ff3b2b256c..ee18f945316 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -654,11 +654,12 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) if (node->id && ELEM3(GS(node->id->name), ID_MA, ID_LA, ID_WO)) nodeClearActiveID(ntree, ID_TE); - if (node->type == SH_NODE_OUTPUT) { + if (ELEM4(node->type, SH_NODE_OUTPUT, SH_NODE_OUTPUT_MATERIAL, + SH_NODE_OUTPUT_WORLD, SH_NODE_OUTPUT_LAMP)) { bNode *tnode; for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) - if (tnode->type == SH_NODE_OUTPUT) + if (tnode->type == node->type) tnode->flag &= ~NODE_DO_OUTPUT; node->flag |= NODE_DO_OUTPUT; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 08b86b574b0..b6a031f527f 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3162,6 +3162,16 @@ static void def_texture(StructRNA *srna) /* -- Shader Nodes ---------------------------------------------------------- */ +static void def_sh_output(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "is_active_output", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_DO_OUTPUT); + RNA_def_property_ui_text(prop, "Active Output", "True if this node is used as the active output"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + static void def_sh_material(StructRNA *srna) { PropertyRNA *prop; diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 260323d368c..f7f7118822f 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -40,7 +40,7 @@ DefNode( Node, NODE_GROUP_INPUT, def_group_input, "GROUP DefNode( Node, NODE_GROUP_OUTPUT, def_group_output, "GROUP_OUTPUT", GroupOutput, "Group Output", "" ) DefNode( Node, NODE_REROUTE, 0, "REROUTE", Reroute, "Reroute", "" ) -DefNode( ShaderNode, SH_NODE_OUTPUT, 0, "OUTPUT", Output, "Output", "" ) +DefNode( ShaderNode, SH_NODE_OUTPUT, def_sh_output, "OUTPUT", Output, "Output", "" ) DefNode( ShaderNode, SH_NODE_MATERIAL, def_sh_material, "MATERIAL", Material, "Material", "" ) DefNode( ShaderNode, SH_NODE_RGB, 0, "RGB", RGB, "RGB", "" ) DefNode( ShaderNode, SH_NODE_VALUE, 0, "VALUE", Value, "Value", "" ) @@ -66,9 +66,9 @@ DefNode( ShaderNode, SH_NODE_SEPRGB, 0, "SEPRG DefNode( ShaderNode, SH_NODE_COMBRGB, 0, "COMBRGB", CombineRGB, "Combine RGB", "" ) DefNode( ShaderNode, SH_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" ) -DefNode( ShaderNode, SH_NODE_OUTPUT_MATERIAL, 0, "OUTPUT_MATERIAL", OutputMaterial, "Material Output", "" ) -DefNode( ShaderNode, SH_NODE_OUTPUT_LAMP, 0, "OUTPUT_LAMP", OutputLamp, "Lamp Output", "" ) -DefNode( ShaderNode, SH_NODE_OUTPUT_WORLD, 0, "OUTPUT_WORLD", OutputWorld, "World Output", "" ) +DefNode( ShaderNode, SH_NODE_OUTPUT_MATERIAL, def_sh_output, "OUTPUT_MATERIAL", OutputMaterial, "Material Output", "" ) +DefNode( ShaderNode, SH_NODE_OUTPUT_LAMP, def_sh_output, "OUTPUT_LAMP", OutputLamp, "Lamp Output", "" ) +DefNode( ShaderNode, SH_NODE_OUTPUT_WORLD, def_sh_output, "OUTPUT_WORLD", OutputWorld, "World Output", "" ) DefNode( ShaderNode, SH_NODE_FRESNEL, 0, "FRESNEL", Fresnel, "Fresnel", "" ) DefNode( ShaderNode, SH_NODE_LAYER_WEIGHT, 0, "LAYER_WEIGHT", LayerWeight, "Layer Weight", "" ) DefNode( ShaderNode, SH_NODE_MIX_SHADER, 0, "MIX_SHADER", MixShader, "Mix Shader", "" ) -- cgit v1.2.3