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.
This commit is contained in:
Brecht Van Lommel 2014-01-20 20:29:05 +01:00
parent 04f81c8225
commit fc3be511f0
Notes: blender-bot 2023-02-14 11:25:15 +01:00
Referenced by issue #37978, Switching material output nodes is unpredictable
4 changed files with 55 additions and 14 deletions

View 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 */

View 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;

View 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;

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