[Bf-blender-cvs] [c42c1293934] blender2.8: Render: make Cycles and Evee support each other's output material nodes.

Brecht Van Lommel noreply at git.blender.org
Tue Aug 1 22:59:06 CEST 2017


Commit: c42c12939342bdccb98000c195503a78423ddc2c
Author: Brecht Van Lommel
Date:   Tue Aug 1 18:03:16 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBc42c12939342bdccb98000c195503a78423ddc2c

Render: make Cycles and Evee support each other's output material nodes.

This changes the Cycles exporting and Cycles/Eevee UI code to support both
output material nodes, giving priority to the renderer native one. Still
missing is Eevee code to prefer the Eevee output node.

===================================================================

M	intern/cycles/blender/addon/ui.py
M	intern/cycles/blender/blender_shader.cpp
M	release/scripts/modules/bpy_extras/node_utils.py
M	release/scripts/startup/bl_ui/properties_material.py
M	release/scripts/startup/bl_ui/properties_world.py
M	source/blender/nodes/shader/node_shader_tree.c
M	source/blender/nodes/shader/nodes/node_shader_output_material.c

===================================================================

diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 3cff65c9717..9aaa0d1c9c2 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -899,19 +899,22 @@ class CYCLES_OT_use_shading_nodes(Operator):
         return {'FINISHED'}
 
 
-def panel_node_draw(layout, id_data, output_type, input_name):
+def panel_node_draw(layout, id_data, output_types, input_name):
     if not id_data.use_nodes:
         layout.operator("cycles.use_shading_nodes", icon='NODETREE')
         return False
 
     ntree = id_data.node_tree
 
-    node = find_output_node(ntree, output_type)
-    if not node:
-        layout.label(text="No output node")
-    else:
+    node = find_output_node(ntree, output_types)
+    if node:
         input = find_node_input(node, input_name)
-        layout.template_node_view(ntree, node, input)
+        if input:
+            layout.template_node_view(ntree, node, input)
+        else:
+            layout.label(text="Incompatible output node")
+    else:
+        layout.label(text="No output node")
 
     return True
 
@@ -1000,7 +1003,7 @@ class CyclesLamp_PT_nodes(CyclesButtonsPanel, Panel):
         layout = self.layout
 
         lamp = context.lamp
-        if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'):
+        if not panel_node_draw(layout, lamp, ['OUTPUT_LAMP'], 'Surface'):
             layout.prop(lamp, "color")
 
 
@@ -1055,7 +1058,7 @@ class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel):
 
         world = context.world
 
-        if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
+        if not panel_node_draw(layout, world, ['OUTPUT_WORLD'], 'Surface'):
             layout.prop(world, "horizon_color", text="Color")
 
 
@@ -1073,7 +1076,7 @@ class CyclesWorld_PT_volume(CyclesButtonsPanel, Panel):
         layout = self.layout
 
         world = context.world
-        panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
+        panel_node_draw(layout, world, ['OUTPUT_WORLD'], 'Volume')
 
 
 class CyclesWorld_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
@@ -1218,7 +1221,7 @@ class CyclesMaterial_PT_surface(CyclesButtonsPanel, Panel):
         layout = self.layout
 
         mat = context.material
-        if not panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Surface'):
+        if not panel_node_draw(layout, mat, ['OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'], 'Surface'):
             layout.prop(mat, "diffuse_color")
 
 
@@ -1238,7 +1241,7 @@ class CyclesMaterial_PT_volume(CyclesButtonsPanel, Panel):
         mat = context.material
         # cmat = mat.cycles
 
-        panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Volume')
+        panel_node_draw(layout, mat, ['OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'], 'Volume')
 
 
 class CyclesMaterial_PT_displacement(CyclesButtonsPanel, Panel):
@@ -1254,7 +1257,7 @@ class CyclesMaterial_PT_displacement(CyclesButtonsPanel, Panel):
         layout = self.layout
 
         mat = context.material
-        panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Displacement')
+        panel_node_draw(layout, mat, ['OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'], 'Displacement')
 
 
 class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 50202c3f272..bbf7dc720a8 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -231,14 +231,6 @@ static void get_tex_mapping(TextureMapping *mapping,
 		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)
-		    || b_node.is_a(&RNA_ShaderNodeOutputEeveeMaterial));
-}
-
 static ShaderNode *add_node(Scene *scene,
                             BL::RenderEngine& b_engine,
                             BL::BlendData& b_data,
@@ -951,6 +943,42 @@ static ShaderOutput *node_find_output_by_name(ShaderNode *node,
 	return node->output(name.c_str());
 }
 
+static BL::ShaderNode find_output_node(BL::ShaderNodeTree& b_ntree)
+{
+	BL::ShaderNodeTree::nodes_iterator b_node;
+	BL::ShaderNode output_node(PointerRNA_NULL);
+	BL::ShaderNode eevee_output_node(PointerRNA_NULL);
+
+	for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
+		BL::ShaderNodeOutputMaterial b_output_node(*b_node);
+
+		if (b_output_node.is_a(&RNA_ShaderNodeOutputMaterial) ||
+		    b_output_node.is_a(&RNA_ShaderNodeOutputWorld) ||
+		    b_output_node.is_a(&RNA_ShaderNodeOutputLamp)) {
+			/* regular Cycles output node */
+			if(b_output_node.is_active_output()) {
+				output_node = b_output_node;
+				break;
+			}
+			else if(!output_node.ptr.data) {
+				output_node = b_output_node;
+			}
+		}
+		else if (b_output_node.is_a(&RNA_ShaderNodeOutputEeveeMaterial)) {
+			/* Eevee output used  if no Cycles node exists */
+			if(b_output_node.is_active_output()) {
+				eevee_output_node = b_output_node;
+			}
+			else if(!eevee_output_node.ptr.data) {
+				eevee_output_node = b_output_node;
+			}
+
+		}
+	}
+
+	return (output_node.ptr.data) ? output_node : eevee_output_node;
+}
+
 static void add_nodes(Scene *scene,
                       BL::RenderEngine& b_engine,
                       BL::BlendData& b_data,
@@ -971,23 +999,7 @@ static void add_nodes(Scene *scene,
 	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;
-			}
-		}
-	}
+	BL::ShaderNode output_node = find_output_node(b_ntree);
 
 	/* add nodes */
 	for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
@@ -1085,10 +1097,8 @@ static void add_nodes(Scene *scene,
 		else {
 			ShaderNode *node = NULL;
 
-			if(is_output_node(*b_node)) {
-				if(b_node->ptr.data == output_node.ptr.data) {
-					node = graph->output();
-				}
+			if(b_node->ptr.data == output_node.ptr.data) {
+				node = graph->output();
 			}
 			else {
 				BL::ShaderNode b_shader_node(*b_node);
diff --git a/release/scripts/modules/bpy_extras/node_utils.py b/release/scripts/modules/bpy_extras/node_utils.py
index 3b8d4ad7c2a..9a2be5b9f68 100644
--- a/release/scripts/modules/bpy_extras/node_utils.py
+++ b/release/scripts/modules/bpy_extras/node_utils.py
@@ -32,16 +32,19 @@ def find_node_input(node, name):
 
     return None
 
-# Return the output node to display in the UI
-def find_output_node(ntree, nodetype):
+# Return the output node to display in the UI. In case multiple node types are
+# specified, node types earlier in the list get priority.
+def find_output_node(ntree, nodetypes):
     if ntree:
-        active_output_node = None
-        for node in ntree.nodes:
-            if getattr(node, "type", None) == nodetype:
-                if getattr(node, "is_active_output", True):
-                    return node
-                if not active_output_node:
-                    active_output_node = node
-        return active_output_node
+        output_node = None
+        for nodetype in nodetypes:
+            for node in ntree.nodes:
+                if getattr(node, "type", None) == nodetype:
+                    if getattr(node, "is_active_output", True):
+                        return node
+                    if not output_node:
+                        output_node = node
+            if output_node:
+                return output_node
 
     return None
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index e7e92000723..0e130b20566 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -1120,10 +1120,12 @@ def panel_node_draw(layout, ntree, output_type):
 
     if node:
         input = find_node_input(node, 'Surface')
-        layout.template_node_view(ntree, node, input)
-        return True
-
-    return False
+        if input:
+            layout.template_node_view(ntree, node, input)
+        else:
+            layout.label(text="Incompatible output node")
+    else:
+        layout.label(text="No output node")
 
 
 class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
@@ -1145,8 +1147,7 @@ class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
         layout.separator()
 
         if mat.use_nodes:
-            if not panel_node_draw(layout, mat.node_tree, 'OUTPUT_EEVEE_MATERIAL'):
-                layout.label(text="No output node")
+            panel_node_draw(layout, mat.node_tree, ['OUTPUT_EEVEE_MATERIAL', 'OUTPUT_MATERIAL'])
         else:
             raym = mat.raytrace_mirror
             layout.prop(mat, "diffuse_color", text="Base Color")
diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py
index fc5835d23d0..ed5cfaa22d2 100644
--- a/release/scripts/startup/bl_ui/properties_world.py
+++ b/release/scripts/startup/bl_ui/properties_world.py
@@ -270,13 +270,16 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel):
 
         if world.use_nodes:
             ntree = world.node_tree
-            node = find_output_node(ntree, 'OUTPUT_WORLD')
+            node = find_output_node(ntree, ['OUTPUT_WORLD'])
 
-            if not node:
-                layout.label(text="No output node")
-            else:
+            if node:
                 input = find_node_input(node, 'Surface')
-                layout.template_node_view(ntree, node, input)
+                if input:
+                    layout.template_node_view(ntree, node, input)
+                else:
+                    layout.label(text="Incompatible output node")
+ 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list