98 lines
2.6 KiB
Python
98 lines
2.6 KiB
Python
|
from .sockets import Input, Output
|
||
|
|
||
|
|
||
|
class Node:
|
||
|
"""Blender Node abstraction."""
|
||
|
|
||
|
def __init__(self, bl_node, parent):
|
||
|
|
||
|
self.bl_node = bl_node
|
||
|
self.tree = parent
|
||
|
self.id = hex(id(self.bl_node))
|
||
|
|
||
|
self.data = {}
|
||
|
self.parameters = []
|
||
|
|
||
|
for prop in self.bl_node.bl_rna.properties:
|
||
|
if prop.is_readonly:
|
||
|
continue
|
||
|
|
||
|
prop_id = prop.identifier
|
||
|
|
||
|
setattr(self, prop_id, getattr(self.bl_node, prop_id))
|
||
|
self.parameters.append(prop_id)
|
||
|
|
||
|
self.inputs = [Input(ipt, self.tree) for ipt in self.bl_node.inputs]
|
||
|
self.outputs = [Output(opt, self.tree) for opt in self.bl_node.outputs]
|
||
|
|
||
|
@classmethod
|
||
|
def from_dict(cls, data, tree):
|
||
|
"""Create all nodes from their dict representation.
|
||
|
|
||
|
Args:
|
||
|
data (dict): dict nodes representation.
|
||
|
tree (Tree): blender node tree abstraction.
|
||
|
|
||
|
Returns:
|
||
|
Node: Create abstract node.
|
||
|
"""
|
||
|
|
||
|
new_bl_node = tree.nodes.new(type=data['bl_idname'])
|
||
|
node = cls(new_bl_node, parent=tree)
|
||
|
|
||
|
for p in node.parameters:
|
||
|
setattr(node, p, data[p])
|
||
|
setattr(node.bl_node, p, data[p])
|
||
|
|
||
|
node.inputs = [Input.from_dict(ipt_data, node) for ipt_data in data['inputs'].values()]
|
||
|
node.outputs = [Output.from_dict(opt_data, node) for opt_data in data['outputs'].values()]
|
||
|
return node
|
||
|
|
||
|
def to_dict(self):
|
||
|
"""Export currrent Node to its dict representation.
|
||
|
|
||
|
Returns:
|
||
|
dict: Node dict representation.
|
||
|
"""
|
||
|
|
||
|
for prop_id in self.parameters:
|
||
|
|
||
|
if not hasattr(self, prop_id):
|
||
|
continue
|
||
|
|
||
|
attr_value = getattr(self, prop_id)
|
||
|
if attr_value is None:
|
||
|
attr_value = None
|
||
|
|
||
|
elif not isinstance(attr_value, (str, int, float, list, tuple)):
|
||
|
attr_value = list(attr_value)
|
||
|
|
||
|
self.data[prop_id] = attr_value
|
||
|
|
||
|
self.data['id'] = self.id
|
||
|
self.data['inputs'] = {ipt.id: ipt.to_dict() for ipt in self.inputs}
|
||
|
self.data['outputs'] = {opt.id: opt.to_dict() for opt in self.outputs}
|
||
|
|
||
|
return self.data
|
||
|
|
||
|
|
||
|
class Link:
|
||
|
"""Blender Link abstraction."""
|
||
|
|
||
|
def __init__(self, bl_link, parent):
|
||
|
|
||
|
self.bl_link = bl_link
|
||
|
self.tree = parent
|
||
|
self.id = hex(id(self.bl_link))
|
||
|
|
||
|
self.input = self.bl_link.to_socket
|
||
|
self.output = self.bl_link.from_socket
|
||
|
|
||
|
self.data = {}
|
||
|
|
||
|
def to_dict(self):
|
||
|
|
||
|
self.data['id'] = self.id
|
||
|
|
||
|
return self.data
|