Fix T37978: cycles nodes with multiple Material Output nodes not predictable.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Mon, 20 Jan 2014 19:29:05 +0000 (20:29 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Mon, 20 Jan 2014 19:31:10 +0000 (20:31 +0100)
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
source/blender/editors/space_node/node_edit.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/nodes/NOD_static_types.h

index 6100c8a7c642459b313f5d4f2f1bdb140e6ede6b..f97407100db47f67ba6915e5432a67898169f4bf 100644 (file)
@@ -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 */
index 6ff3b2b256c793413fd6a4ee0dd746bf768bbd34..ee18f945316a578908aa26e98b9923b6fe8c6f15 100644 (file)
@@ -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;
index 08b86b574b079fb082c15c029b556b5382acd4eb..b6a031f527f1072da85443afc6f7f94a28b0bbf8 100644 (file)
@@ -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;
index 260323d368cc54402be2345435785e7eec9ec125..f7f7118822f8f456699064a212aa7e780693a838 100644 (file)
@@ -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",        ""       )