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", "" )