diff --git a/materialx/bl_nodes/shader.py b/materialx/bl_nodes/shader.py index 219d32135..6ab39ce68 100644 --- a/materialx/bl_nodes/shader.py +++ b/materialx/bl_nodes/shader.py @@ -5,6 +5,7 @@ import math import MaterialX as mx from .node_parser import NodeParser +from ..utils import get_mx_node_input_types from . import log @@ -227,18 +228,31 @@ class ShaderNodeMixShader(NodeParser): shader2 = self.get_input_link(2) mix = None + input_types = get_mx_node_input_types('mix', 'PBR') if shader1 is None and shader2 is None: return None if shader2 is None: - mix = self.create_node('mix', get_node_type(shader1).lower(), prefix='PBR', inputs={ + shader1_type = get_node_type(shader1) + if shader1_type not in input_types: + log.warn(f'Node {self.node.bl_idname} ({self.material.name_full}) ignored. ' + f'Input type must be of types {input_types}, actual: {shader1_type}') + return shader1 + + mix = self.create_node('mix', shader1_type.lower(), prefix='PBR', inputs={ 'fg': shader1, 'mix': factor }) if shader1 is None: - mix = self.create_node('mix', get_node_type(shader2).lower(), prefix='PBR', inputs={ + shader2_type = get_node_type(shader2) + if shader2_type not in input_types: + log.warn(f'Node {self.node.bl_idname} ({self.material.name_full}) ignored. ' + f'Input type must be of types {input_types}, actual: {shader2_type}') + return shader2 + + mix = self.create_node('mix', shader2_type.lower(), prefix='PBR', inputs={ 'bg': shader2, 'mix': factor }) @@ -247,10 +261,15 @@ class ShaderNodeMixShader(NodeParser): shader1_type = get_node_type(shader1) shader2_type = get_node_type(shader2) if shader1_type != shader2_type: - log.warn(f'Types of input shaders must be the same.' - f' First shader type: {shader1_type}, second shader type: {shader2_type}') + log.warn(f'Types of input shaders must be the same. ' + f'First shader type: {shader1_type}, second shader type: {shader2_type}') - return None + return shader1 + + if shader1_type not in input_types: + log.warn(f'Node {self.node.bl_idname} ({self.material.name_full}) ignored. ' + f'Input type must be of types {input_types}, actual: {shader1_type}, {shader2_type}') + return shader1 mix = self.create_node('mix', shader1_type.lower(), prefix='PBR', inputs={ 'fg': shader1, @@ -277,17 +296,30 @@ class ShaderNodeAddShader(NodeParser): shader2 = self.get_input_link(1) add = None + input_types = get_mx_node_input_types('add', 'PBR') if shader1 is None and shader2 is None: return None if shader2 is None: - add = self.create_node('add', get_node_type(shader1).lower(), prefix='PBR', inputs={ + shader1_type = get_node_type(shader1) + if shader1_type not in input_types: + log.warn(f'Node {self.node.bl_idname} ({self.material.name_full}) ignored. ' + f'Input type must be of types {input_types}, actual: {shader1_type}') + return shader1 + + add = self.create_node('add', shader1_type.lower(), prefix='PBR', inputs={ 'in1': shader1 }) if shader1 is None: - add = self.create_node('add', get_node_type(shader2).lower(), prefix='PBR', inputs={ + shader2_type = get_node_type(shader2) + if shader2_type not in input_types: + log.warn(f'Node {self.node.bl_idname} ({self.material.name_full}) ignored. ' + f'Input type must be of types {input_types}, actual: {shader2_type}') + return shader2 + + add = self.create_node('add', shader2_type.lower(), prefix='PBR', inputs={ 'in2': shader2 }) @@ -295,10 +327,15 @@ class ShaderNodeAddShader(NodeParser): shader1_type = get_node_type(shader1) shader2_type = get_node_type(shader2) if shader1_type != shader2_type: - log.warn(f'Types of input shaders must be the same.' - f' First shader type: {shader1_type}, second shader type: {shader2_type}') + log.warn(f'Types of input shaders must be the same. ' + f'First shader type: {shader1_type}, second shader type: {shader2_type}') - return None + return shader1 + + if shader1_type not in input_types: + log.warn(f'Node {self.node.bl_idname} ({self.material.name_full}) ignored. ' + f'Input type must be of types {input_types}, actual: {shader1_type}, {shader2_type}') + return shader1 add = self.create_node('add', shader1_type.lower(), prefix='PBR', inputs={ 'in1': shader1, diff --git a/materialx/utils.py b/materialx/utils.py index fbb1bb21d..6964386a4 100644 --- a/materialx/utils.py +++ b/materialx/utils.py @@ -662,3 +662,19 @@ def get_output_node(material): node.inputs['surfaceshader'].links), None) return mx_output_node + + +def get_mx_node_input_types(node_name, prefix=''): + from .nodes import mx_node_classes + + suffix = f'_{node_name}' + if prefix: + suffix = prefix + suffix + + input_types = set() + classes = tuple(cls for cls in mx_node_classes if cls.__name__.endswith(suffix)) + for cls in classes: + for nodedef, data_type in cls.get_nodedefs(): + input_types |= {p.getType() for p in nodedef.getActiveInputs()} + + return input_types