WIP: MaterialX addon #104594
@ -56,14 +56,14 @@ def get_mx_node_cls(mx_node):
|
||||
raise KeyError(f"Unable to find MxNode class for {mx_node}")
|
||||
|
||||
def params_set(node, out_type):
|
||||
return {f"in_{p.getName()}:{p.getType()}" for p in node.getInputs()} | \
|
||||
return {f"in_{p.getName()}:{p.getType()}" for p in node.getActiveInputs()} | \
|
||||
{out_type}
|
||||
|
||||
node_params_set = params_set(mx_node, mx_node.getType())
|
||||
|
||||
for cls in classes:
|
||||
for nodedef, data_type in cls.get_nodedefs():
|
||||
nd_outputs = nodedef.getOutputs()
|
||||
nd_outputs = nodedef.getActiveOutputs()
|
||||
nd_params_set = params_set(nodedef, 'multioutput' if len(nd_outputs) > 1 else
|
||||
nd_outputs[0].getType())
|
||||
if node_params_set.issubset(nd_params_set):
|
||||
|
@ -145,21 +145,21 @@ def nodedef_data_type(nodedef):
|
||||
node_name = nodedef.getNodeString()
|
||||
|
||||
if nd_name.startswith('rpr_'):
|
||||
return nodedef.getOutputs()[0].getType()
|
||||
return nodedef.getActiveOutputs()[0].getType()
|
||||
|
||||
m = re.fullmatch(rf'ND_{node_name}_(.+)', nd_name)
|
||||
if m:
|
||||
return m[1]
|
||||
|
||||
return nodedef.getOutputs()[0].getType()
|
||||
return nodedef.getActiveOutputs()[0].getType()
|
||||
|
||||
|
||||
def generate_data_type(nodedef):
|
||||
outputs = nodedef.getOutputs()
|
||||
outputs = nodedef.getActiveOutputs()
|
||||
if len(outputs) != 1:
|
||||
return f"{{'multitypes': {{'{nodedef.getName()}': None, 'nodedef_name': '{nodedef.getName()}'}}}}"
|
||||
|
||||
return f"{{'{nodedef.getOutputs()[0].getType()}': {{'{nodedef.getName()}': None, 'nodedef_name': '{nodedef.getName()}'}}}}"
|
||||
return f"{{'{nodedef.getActiveOutputs()[0].getType()}': {{'{nodedef.getName()}': None, 'nodedef_name': '{nodedef.getName()}'}}}}"
|
||||
|
||||
|
||||
def input_prop_name(nd_type, name):
|
||||
@ -204,7 +204,7 @@ class {class_name}(MxNode):
|
||||
""")
|
||||
|
||||
ui_folders = []
|
||||
for mx_param in [*nodedef.getParameters(), *nodedef.getInputs()]:
|
||||
for mx_param in [*nodedef.getParameters(), *nodedef.getActiveInputs()]:
|
||||
f = mx_param.getAttribute("uifolder")
|
||||
if f and f not in ui_folders:
|
||||
ui_folders.append(f)
|
||||
@ -242,11 +242,11 @@ class {class_name}(MxNode):
|
||||
nd_type = nodedef_data_type(nd)
|
||||
code_strings.append("")
|
||||
|
||||
for input in nd.getInputs():
|
||||
for input in nd.getActiveInputs():
|
||||
prop_code = generate_property_code(input, category)
|
||||
code_strings.append(f" {input_prop_name(nd_type, input.getName())}: {prop_code}")
|
||||
|
||||
for output in nd.getOutputs():
|
||||
for output in nd.getActiveOutputs():
|
||||
prop_code = generate_property_code(output, category)
|
||||
code_strings.append(f" {output_prop_name(nd_type, output.getName())}: {prop_code}")
|
||||
|
||||
|
@ -10,6 +10,8 @@ from .. import utils
|
||||
from .. import logging
|
||||
log = logging.Log("nodes.node")
|
||||
|
||||
mtlx_documents = {}
|
||||
|
||||
|
||||
class MxNodeInputSocket(bpy.types.NodeSocket):
|
||||
bl_idname = utils.with_prefix('MxNodeInputSocket')
|
||||
@ -20,7 +22,7 @@ class MxNodeInputSocket(bpy.types.NodeSocket):
|
||||
return
|
||||
|
||||
nd = node.nodedef
|
||||
nd_input = nd.getInput(self.name)
|
||||
nd_input = nd.getActiveInput(self.name)
|
||||
nd_type = nd_input.getType()
|
||||
|
||||
uiname = utils.get_attr(nd_input, 'uiname', utils.title_str(nd_input.getName()))
|
||||
@ -36,7 +38,7 @@ class MxNodeInputSocket(bpy.types.NodeSocket):
|
||||
|
||||
|
||||
def draw_color(self, context, node):
|
||||
return utils.get_socket_color(node.nodedef.getInput(self.name).getType()
|
||||
return utils.get_socket_color(node.nodedef.getActiveInput(self.name).getType()
|
||||
if is_mx_node_valid(node) else 'undefined')
|
||||
|
||||
|
||||
@ -49,16 +51,16 @@ class MxNodeOutputSocket(bpy.types.NodeSocket):
|
||||
return
|
||||
|
||||
nd = node.nodedef
|
||||
mx_output = nd.getOutput(self.name)
|
||||
mx_output = nd.getActiveOutput(self.name)
|
||||
uiname = utils.get_attr(mx_output, 'uiname', utils.title_str(mx_output.getName()))
|
||||
uitype = utils.title_str(mx_output.getType())
|
||||
if uiname.lower() == uitype.lower() or len(nd.getOutputs()) == 1:
|
||||
if uiname.lower() == uitype.lower() or len(nd.getActiveOutputs()) == 1:
|
||||
layout.label(text=uitype)
|
||||
else:
|
||||
layout.label(text=f"{uiname}: {uitype}")
|
||||
|
||||
def draw_color(self, context, node):
|
||||
return utils.get_socket_color(node.nodedef.getOutput(self.name).getType()
|
||||
return utils.get_socket_color(node.nodedef.getActiveOutput(self.name).getType()
|
||||
if is_mx_node_valid(node) else 'undefined')
|
||||
|
||||
|
||||
@ -80,9 +82,14 @@ class MxNode(bpy.types.ShaderNode):
|
||||
def get_nodedef(cls, data_type):
|
||||
if not cls._data_types[data_type]['nd']:
|
||||
# loading nodedefs
|
||||
doc = mx.createDocument()
|
||||
search_path = mx.FileSearchPath(str(utils.MX_LIBS_DIR))
|
||||
mx.readFromXmlFile(doc, str(utils.ADDON_ROOT_DIR / cls._file_path), searchPath=search_path)
|
||||
if cls._file_path not in mtlx_documents:
|
||||
doc = mx.createDocument()
|
||||
search_path = mx.FileSearchPath(str(utils.MX_LIBS_DIR))
|
||||
mx.readFromXmlFile(doc, str(utils.MX_LIBS_DIR / cls._file_path), searchPath=search_path)
|
||||
mtlx_documents[cls._file_path] = doc
|
||||
|
||||
doc = mtlx_documents[cls._file_path]
|
||||
|
||||
for val in cls._data_types.values():
|
||||
val['nd'] = doc.getNodeDef(val['nd_name'])
|
||||
|
||||
@ -100,7 +107,7 @@ class MxNode(bpy.types.ShaderNode):
|
||||
@property
|
||||
def mx_node_path(self):
|
||||
nd = self.nodedef
|
||||
if '/' in self.name or utils.is_shader_type(nd.getOutputs()[0].getType()):
|
||||
if '/' in self.name or utils.is_shader_type(nd.getActiveOutputs()[0].getType()):
|
||||
return self.name
|
||||
|
||||
return f"NG/{self.name}"
|
||||
@ -126,8 +133,8 @@ class MxNode(bpy.types.ShaderNode):
|
||||
for link in nodetree.links:
|
||||
if hasattr(link.from_socket.node, 'nodedef') and hasattr(link.to_socket.node, 'nodedef'):
|
||||
|
||||
socket_from_type = link.from_socket.node.nodedef.getOutput(link.from_socket.name).getType()
|
||||
socket_to_type = link.to_socket.node.nodedef.getInput(link.to_socket.name).getType()
|
||||
socket_from_type = link.from_socket.node.nodedef.getActiveOutput(link.from_socket.name).getType()
|
||||
socket_to_type = link.to_socket.node.nodedef.getActiveInput(link.to_socket.name).getType()
|
||||
|
||||
if socket_to_type != socket_from_type:
|
||||
link.is_valid = False
|
||||
@ -140,7 +147,7 @@ class MxNode(bpy.types.ShaderNode):
|
||||
nodedef = self.nodedef
|
||||
for i, nd_input in enumerate(utils.get_nodedef_inputs(nodedef, False)):
|
||||
self.inputs[i].name = nd_input.getName()
|
||||
for i, nd_output in enumerate(nodedef.getOutputs()):
|
||||
for i, nd_output in enumerate(nodedef.getActiveOutputs()):
|
||||
self.outputs[i].name = nd_output.getName()
|
||||
|
||||
def init(self, context):
|
||||
@ -149,7 +156,7 @@ class MxNode(bpy.types.ShaderNode):
|
||||
for nd_input in utils.get_nodedef_inputs(nodedef, False):
|
||||
self.create_input(nd_input)
|
||||
|
||||
for nd_output in nodedef.getOutputs():
|
||||
for nd_output in nodedef.getActiveOutputs():
|
||||
self.create_output(nd_output)
|
||||
|
||||
if self._ui_folders:
|
||||
@ -264,7 +271,7 @@ class MxNode(bpy.types.ShaderNode):
|
||||
mx_param = mx_node.addInput(nd_input.getName(), nd_type)
|
||||
utils.set_param_value(mx_param, val, nd_type)
|
||||
|
||||
if len(nodedef.getOutputs()) > 1:
|
||||
if len(nodedef.getActiveOutputs()) > 1:
|
||||
mx_node.setType('multioutput')
|
||||
return mx_node, nd_output
|
||||
|
||||
@ -340,10 +347,10 @@ class MxNode(bpy.types.ShaderNode):
|
||||
return getattr(self, self._input_prop_name(name))
|
||||
|
||||
def get_nodedef_input(self, in_key: [str, int]):
|
||||
return self.nodedef.getInput(self.inputs[in_key].name)
|
||||
return self.nodedef.getActiveInput(self.inputs[in_key].name)
|
||||
|
||||
def get_nodedef_output(self, out_key: [str, int]):
|
||||
return self.nodedef.getOutput(self.outputs[out_key].name)
|
||||
return self.nodedef.getActiveOutput(self.outputs[out_key].name)
|
||||
|
||||
def set_input_value(self, in_key, value):
|
||||
setattr(self, self._input_prop_name(self.inputs[in_key].name), value)
|
||||
|
@ -74,7 +74,7 @@ def set_param_value(mx_param, val, nd_type, nd_output=None):
|
||||
if nd_output:
|
||||
mx_output_name += f'_{nd_output.getName()}'
|
||||
|
||||
mx_output = val_nodegraph.getOutput(mx_output_name)
|
||||
mx_output = val_nodegraph.getActiveOutput(mx_output_name)
|
||||
if not mx_output:
|
||||
mx_output = val_nodegraph.addOutput(mx_output_name, val.getType())
|
||||
mx_output.setNodeName(node_name)
|
||||
@ -182,7 +182,7 @@ def parse_value_str(val_str, mx_type, *, first_only=False, is_enum=False):
|
||||
|
||||
|
||||
def get_nodedef_inputs(nodedef, uniform=None):
|
||||
for nd_input in nodedef.getInputs():
|
||||
for nd_input in nodedef.getActiveInputs():
|
||||
if (uniform is True and nd_input.getAttribute('uniform') != 'true') or \
|
||||
(uniform is False and nd_input.getAttribute('uniform') == 'true'):
|
||||
continue
|
||||
@ -523,7 +523,7 @@ def import_materialx_from_file(node_tree, doc: mx.Document, file_path):
|
||||
new_mx_nodegraph = next(ng for ng in doc.getNodeGraphs()
|
||||
if ng.getNodeDefString() == nodedef.getName())
|
||||
|
||||
mx_output = new_mx_nodegraph.getOutput(mx_output_name)
|
||||
mx_output = new_mx_nodegraph.getActiveOutput(mx_output_name)
|
||||
node_name = mx_output.getNodeName()
|
||||
new_mx_node = new_mx_nodegraph.getNode(node_name)
|
||||
|
||||
@ -534,9 +534,9 @@ def import_materialx_from_file(node_tree, doc: mx.Document, file_path):
|
||||
node.data_type = data_type
|
||||
nodedef = node.nodedef
|
||||
|
||||
for mx_input in mx_node.getInputs():
|
||||
for mx_input in mx_node.getActiveInputs():
|
||||
input_name = mx_input.getName()
|
||||
nd_input = nodedef.getInput(input_name)
|
||||
nd_input = nodedef.getActiveInput(input_name)
|
||||
if nd_input.getAttribute('uniform') == 'true':
|
||||
node.set_param_value(input_name, parse_value(
|
||||
node, mx_input.getValue(), mx_input.getType(), file_prefix))
|
||||
@ -563,7 +563,7 @@ def import_materialx_from_file(node_tree, doc: mx.Document, file_path):
|
||||
new_node = import_node(new_mx_node)
|
||||
|
||||
out_name = mx_input.getAttribute('output')
|
||||
if len(new_node.nodedef.getOutputs()) > 1 and out_name:
|
||||
if len(new_node.nodedef.getActiveOutputs()) > 1 and out_name:
|
||||
new_node_output = new_node.outputs[out_name]
|
||||
else:
|
||||
new_node_output = new_node.outputs[0]
|
||||
@ -575,7 +575,7 @@ def import_materialx_from_file(node_tree, doc: mx.Document, file_path):
|
||||
if new_nodegraph_name:
|
||||
mx_output_name = mx_input.getAttribute('output')
|
||||
new_mx_nodegraph = mx_nodegraph.getNodeGraph(new_nodegraph_name)
|
||||
mx_output = new_mx_nodegraph.getOutput(mx_output_name)
|
||||
mx_output = new_mx_nodegraph.getActiveOutput(mx_output_name)
|
||||
node_name = mx_output.getNodeName()
|
||||
new_mx_node = new_mx_nodegraph.getNode(node_name)
|
||||
new_node = import_node(new_mx_node, mx_output_name)
|
||||
@ -583,7 +583,7 @@ def import_materialx_from_file(node_tree, doc: mx.Document, file_path):
|
||||
continue
|
||||
|
||||
out_name = mx_output.getAttribute('output')
|
||||
if len(new_node.nodedef.getOutputs()) > 1 and out_name:
|
||||
if len(new_node.nodedef.getActiveOutputs()) > 1 and out_name:
|
||||
new_node_output = new_node.outputs[out_name]
|
||||
else:
|
||||
new_node_output = new_node.outputs[0]
|
||||
|
Loading…
Reference in New Issue
Block a user