feat: use basic uuid to identify node inputs
This commit is contained in:
parent
30d734c2c1
commit
cef45dad3c
@ -36,6 +36,7 @@ Currently, not all data-block are supported for replication over the wire. The f
|
|||||||
| image | ✔️ | |
|
| image | ✔️ | |
|
||||||
| mesh | ✔️ | |
|
| mesh | ✔️ | |
|
||||||
| material | ✔️ | |
|
| material | ✔️ | |
|
||||||
|
| node_groups | ❗ | Material only |
|
||||||
| metaball | ✔️ | |
|
| metaball | ✔️ | |
|
||||||
| object | ✔️ | |
|
| object | ✔️ | |
|
||||||
| texts | ✔️ | |
|
| texts | ✔️ | |
|
||||||
|
@ -21,6 +21,8 @@ import mathutils
|
|||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
from .dump_anything import Loader, Dumper
|
from .dump_anything import Loader, Dumper
|
||||||
from .bl_datablock import BlDatablock, get_datablock_from_uuid
|
from .bl_datablock import BlDatablock, get_datablock_from_uuid
|
||||||
|
|
||||||
@ -48,21 +50,23 @@ def load_node(node_data, node_tree):
|
|||||||
if node_tree_uuid:
|
if node_tree_uuid:
|
||||||
target_node.node_tree = get_datablock_from_uuid(node_tree_uuid, None)
|
target_node.node_tree = get_datablock_from_uuid(node_tree_uuid, None)
|
||||||
|
|
||||||
for idx, inpt in enumerate(node_data['inputs']):
|
inputs = node_data.get('inputs')
|
||||||
|
if inputs:
|
||||||
|
for idx, inpt in enumerate(inputs):
|
||||||
if hasattr(target_node.inputs[idx], "default_value"):
|
if hasattr(target_node.inputs[idx], "default_value"):
|
||||||
try:
|
try:
|
||||||
target_node.inputs[idx].default_value = inpt["default_value"]
|
target_node.inputs[idx].default_value = inpt["default_value"]
|
||||||
except:
|
except:
|
||||||
logging.error(
|
logging.error(f"Material input {inpt.keys()} parameter not supported, skipping")
|
||||||
f"Material {inpt.keys()} parameter not supported, skipping")
|
|
||||||
|
|
||||||
for idx, output in enumerate(node_data['outputs']):
|
outputs = node_data.get('outputs')
|
||||||
|
if outputs:
|
||||||
|
for idx, output in enumerate(outputs):
|
||||||
if hasattr(target_node.outputs[idx], "default_value"):
|
if hasattr(target_node.outputs[idx], "default_value"):
|
||||||
try:
|
try:
|
||||||
target_node.outputs[idx].default_value = output["default_value"]
|
target_node.outputs[idx].default_value = output["default_value"]
|
||||||
except:
|
except:
|
||||||
logging.error(
|
logging.error(f"Material output {output.keys()} parameter not supported, skipping")
|
||||||
f"Material {output.keys()} parameter not supported, skipping")
|
|
||||||
|
|
||||||
|
|
||||||
def load_links(links_data, node_tree):
|
def load_links(links_data, node_tree):
|
||||||
@ -152,9 +156,6 @@ def dump_node(node):
|
|||||||
io_dumper.depth = 2
|
io_dumper.depth = 2
|
||||||
io_dumper.include_filter = ["default_value"]
|
io_dumper.include_filter = ["default_value"]
|
||||||
|
|
||||||
if node.type in ['GROUP_INPUT', 'GROUP_OUTPUT']:
|
|
||||||
io_dumper.include_filter.extend(['name','type'])
|
|
||||||
|
|
||||||
for idx, inpt in enumerate(node.inputs):
|
for idx, inpt in enumerate(node.inputs):
|
||||||
if hasattr(inpt, 'default_value'):
|
if hasattr(inpt, 'default_value'):
|
||||||
dumped_node['inputs'].append(io_dumper.dump(inpt))
|
dumped_node['inputs'].append(io_dumper.dump(inpt))
|
||||||
@ -204,20 +205,68 @@ def dump_shader_node_tree(node_tree:bpy.types.ShaderNodeTree)->dict:
|
|||||||
'type': type(node_tree).__name__
|
'type': type(node_tree).__name__
|
||||||
}
|
}
|
||||||
|
|
||||||
if node_tree.inputs:
|
for socket_id in ['inputs', 'outputs']:
|
||||||
node_tree_data['inputs'] = [(i.name, i.bl_socket_idname, i.identifier) for i in node_tree.inputs]
|
socket_collection = getattr(node_tree, socket_id)
|
||||||
if node_tree.outputs:
|
node_tree_data[socket_id] = dump_node_tree_sockets(socket_collection)
|
||||||
node_tree_data['outputs'] = [(o.name, o.bl_socket_idname)for o in node_tree.outputs]
|
|
||||||
|
|
||||||
return node_tree_data
|
return node_tree_data
|
||||||
|
|
||||||
def load_shader_node_tree(node_tree_data:dict, target_node_tree:bpy.types.ShaderNodeTree)->dict:
|
|
||||||
"""
|
|
||||||
|
|
||||||
:arg node_tree: dumped node data
|
def dump_node_tree_sockets(sockets: bpy.types.Collection)->dict:
|
||||||
:type node_data: dict
|
""" dump sockets of a shader_node_tree
|
||||||
:arg node_tree: target node_tree
|
|
||||||
:type node_tree: bpy.types.NodeTree
|
:arg target_node_tree: target node_tree
|
||||||
|
:type target_node_tree: bpy.types.NodeTree
|
||||||
|
:arg socket_id: socket identifer
|
||||||
|
:type socket_id: str
|
||||||
|
:return: dict
|
||||||
|
"""
|
||||||
|
sockets_data = []
|
||||||
|
for socket in sockets:
|
||||||
|
try:
|
||||||
|
socket_uuid = socket['uuid']
|
||||||
|
except Exception:
|
||||||
|
socket_uuid = str(uuid4())
|
||||||
|
socket['uuid'] = socket_uuid
|
||||||
|
|
||||||
|
sockets_data.append((socket.name, socket.bl_socket_idname, socket_uuid))
|
||||||
|
|
||||||
|
return sockets_data
|
||||||
|
|
||||||
|
def load_node_tree_sockets(sockets: bpy.types.Collection,
|
||||||
|
sockets_data: dict):
|
||||||
|
""" load sockets of a shader_node_tree
|
||||||
|
|
||||||
|
:arg target_node_tree: target node_tree
|
||||||
|
:type target_node_tree: bpy.types.NodeTree
|
||||||
|
:arg socket_id: socket identifer
|
||||||
|
:type socket_id: str
|
||||||
|
:arg socket_data: dumped socket data
|
||||||
|
:type socket_data: dict
|
||||||
|
"""
|
||||||
|
# Check for removed sockets
|
||||||
|
for socket in sockets:
|
||||||
|
if not [s for s in sockets_data if socket['uuid'] == s[2]]:
|
||||||
|
sockets.remove(socket)
|
||||||
|
|
||||||
|
# Check for new sockets
|
||||||
|
for idx, socket_data in enumerate(sockets_data):
|
||||||
|
try:
|
||||||
|
checked_socket = sockets[idx]
|
||||||
|
if checked_socket.name != socket_data[0]:
|
||||||
|
checked_socket.name = socket_data[0]
|
||||||
|
except Exception:
|
||||||
|
s = sockets.new(socket_data[1], socket_data[0])
|
||||||
|
s['uuid'] = socket_data[2]
|
||||||
|
|
||||||
|
|
||||||
|
def load_shader_node_tree(node_tree_data:dict, target_node_tree:bpy.types.ShaderNodeTree)->dict:
|
||||||
|
"""Load a shader node_tree from dumped data
|
||||||
|
|
||||||
|
:arg node_tree_data: dumped node data
|
||||||
|
:type node_tree_data: dict
|
||||||
|
:arg target_node_tree: target node_tree
|
||||||
|
:type target_node_tree: bpy.types.NodeTree
|
||||||
"""
|
"""
|
||||||
# TODO: load only required nodes
|
# TODO: load only required nodes
|
||||||
target_node_tree.nodes.clear()
|
target_node_tree.nodes.clear()
|
||||||
@ -226,30 +275,12 @@ def load_shader_node_tree(node_tree_data:dict, target_node_tree:bpy.types.Shader
|
|||||||
target_node_tree.name = node_tree_data['name']
|
target_node_tree.name = node_tree_data['name']
|
||||||
|
|
||||||
if 'inputs' in node_tree_data:
|
if 'inputs' in node_tree_data:
|
||||||
for inpt in target_node_tree.inputs:
|
socket_collection = getattr(target_node_tree, 'inputs')
|
||||||
if not [i for i in node_tree_data['inputs'] if inpt.identifier == i[2]]:
|
load_node_tree_sockets(socket_collection, node_tree_data['inputs'])
|
||||||
target_node_tree.inputs.remove(inpt)
|
|
||||||
|
|
||||||
for idx, socket_data in enumerate(node_tree_data['inputs']):
|
|
||||||
try:
|
|
||||||
checked_input = target_node_tree.inputs[idx]
|
|
||||||
if checked_input.name != socket_data[0]:
|
|
||||||
checked_input.name = socket_data[0]
|
|
||||||
except Exception:
|
|
||||||
target_node_tree.inputs.new(socket_data[1], socket_data[0])
|
|
||||||
|
|
||||||
if 'outputs' in node_tree_data:
|
if 'outputs' in node_tree_data:
|
||||||
for inpt in target_node_tree.outputs:
|
socket_collection = getattr(target_node_tree, 'outputs')
|
||||||
if not [o for o in node_tree_data['outputs'] if inpt.identifier == o[2]]:
|
load_node_tree_sockets(socket_collection,node_tree_data['outputs'])
|
||||||
target_node_tree.outputs.remove(inpt)
|
|
||||||
|
|
||||||
for idx, socket_data in enumerate(node_tree_data['outputs']):
|
|
||||||
try:
|
|
||||||
checked_outputs = target_node_tree.outputs[idx]
|
|
||||||
if checked_outputs.name != socket_data[0]:
|
|
||||||
checked_outputs.name = socket_data[0]
|
|
||||||
except Exception:
|
|
||||||
target_node_tree.outputs.new(socket_data[1], socket_data[0])
|
|
||||||
|
|
||||||
# Load nodes
|
# Load nodes
|
||||||
for node in node_tree_data["nodes"]:
|
for node in node_tree_data["nodes"]:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user