Cleanup: Remove old Blender abstraction class files

refactor
Jonas Holzman 2025-03-24 15:49:27 +01:00
parent cbf1ea64e6
commit 876511c435
3 changed files with 0 additions and 379 deletions

View File

@ -1,211 +0,0 @@
import bpy
from mathutils import Color, Vector
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 = []
self._parent = None
self._scene = None
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]
@property
def parent(self):
"""Get the Node from all the other nodes in the tree checking that the
parent of its blender node is the same as the blender node we are comparing.
Returns:
Node: Node parent.
"""
if self._parent:
return self._parent
# if blender node doesn't have a parent
if not self.bl_node.parent:
self._parent = None
return self._parent
for node in self.tree.nodes:
if node.bl_node == self.bl_node.parent:
self._parent = node
return self._parent
@parent.setter
def parent(self, value):
"""Set the Node parent, using the python object, it's id or the blender node.
Args:
value (Node|str|bpy.types.Node): Node, id or blender node to set as parent.
"""
# Node object case
if isinstance(value, Node):
self._parent = value
# Node id case
elif isinstance(value, str) and value.startswith("0x"):
for node in self.tree.nodes:
if node.id == value:
self._parent = node
else:
print("Cannot find parent")
# blender node case
elif isinstance(value, bpy.types.Node):
for node in self.tree.nodes:
if node.bl_node == value:
self._parent = node
if self._parent:
self.bl_node.parent = self._parent.bl_node
@classmethod
def from_blender_node(cls, bl_node, tree):
"""Instanciate an abstract class based of the blender node idname.
Args:
bl_node (bpy.types.Node): Blender Node To create abstraction from.
tree (NodeTree): Node tree object node belongs to.
Returns:
Node: Node abstract according to the blender node type.
"""
if bl_node.bl_idname == "CompositorNodeRLayers":
return RenderLayersNode(bl_node, tree)
elif bl_node.bl_idname == "CompositorNodeValToRGB":
return ColorRampNode(bl_node, tree)
else:
return cls(bl_node, tree)
@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.bl_node_tree.nodes.new(type=data["bl_idname"])
node = cls.from_blender_node(new_bl_node, tree)
node.id = data["id"]
for p in node.parameters:
setattr(node, p, data[p])
# set attribute on the blender node only if correct type is retrieve
if p not in ("parent", "scene"):
setattr(node.bl_node, p, getattr(node, 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 dump(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 isinstance(attr_value, Node):
attr_value = attr_value.id
elif isinstance(attr_value, (Color, Vector)):
attr_value = list(attr_value)
self.data[prop_id] = attr_value
self.data["id"] = self.id
self.data["inputs"] = {ipt.id: ipt.dump() for ipt in self.inputs}
self.data["outputs"] = {opt.id: opt.dump() for opt in self.outputs}
return self.data
class RenderLayersNode(Node):
"""Blender Render Layers Node abstraction"""
@property
def scene(self):
"""Get the name of the scene used by the node.
Returns:
str: scene name.
"""
if self._scene:
return self._scene.name
@scene.setter
def scene(self, value):
"""Set the blender scene using the bpy Scene object or its name.
Args:
value (str|bpy.types.Scene): scene name or scene object to set the node.
"""
if isinstance(value, str):
self._scene = bpy.data.scenes[value]
elif isinstance(value, bpy.types.Scene):
self._scene = value
if self._scene:
self.bl_node.scene = self._scene
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 dump(self):
self.data["id"] = self.id
return self.data

View File

@ -1,71 +0,0 @@
import json
from pathlib import Path
from .node import Node, Link
class NodeTree:
"""Blender node tree abstraction."""
def __init__(self, bl_node_tree):
self.bl_node_tree = bl_node_tree
self.data = {}
self.links = [Link(lnk, parent=self) for lnk in self.bl_node_tree.links]
self.nodes = []
for n in self.bl_node_tree.nodes:
self.nodes.append(Node.from_blender_node(n, self))
def dump(self, select_only=False):
"""Convert all blender nodes and links inside the tree into a dictionnary.
Args:
select_only (bool, optional): True to convert only selected nodes.
Defaults to False.
Returns:
dict: Nodes and links as dict.
"""
self.data["nodes"] = {
n.id: n.dump()
for n in self.nodes
if not select_only or (select_only and n.select)
}
self.data["links"] = [l.id for l in self.links]
return self.data
def load(self, data):
"""From a Tree dict representation, create new nodes with their attributes.
Then create a connection dict by comparing link id from inputs and outputs of each nodes.
Use this dict to link nodes between each others.
Args:
data (dict): Tree dict representation to generate nodes and links from.
"""
connections = {}
self.data = data
for node_id, node_data in self.data["nodes"].items():
new_node = Node.from_dict(node_data, self)
self.nodes.append(new_node)
new_node.bl_node.select = True
for ipt in new_node.inputs:
if ipt.is_linked:
connections.setdefault(ipt.link, {})["input"] = ipt.bl_input
for opt in new_node.outputs:
if opt.is_linked:
for link in opt.link:
connections.setdefault(link, {})["output"] = opt.bl_output
for link_id in self.data["links"]:
ipt = connections[link_id]["input"]
opt = connections[link_id]["output"]
self.bl_node_tree.links.new(ipt, opt)

View File

@ -1,97 +0,0 @@
class Socket:
def __init__(self, bl_socket, tree):
self.tree = tree
self.bl_socket = bl_socket
self.data = {}
self.id = hex(id(bl_socket))
self.identifier = bl_socket.identifier
self.is_linked = bl_socket.is_linked
self._value = None
if hasattr(bl_socket, "default_value"):
self._value = bl_socket.default_value
@property
def value(self):
if not isinstance(self._value, (str, int, float, bool)):
self._value = [v for v in self._value]
return self._value
@value.setter
def value(self, v):
self.bl_socket.default_value = v
self._value = v
return self._value
def to_dict(self):
self.data["id"] = self.id
self.data["value"] = self.value
self.data["identifier"] = self.identifier
self.data["is_linked"] = self.is_linked
self.data["link"] = self.get_link()
return self.data
class Input(Socket):
def __init__(self, bl_input, tree):
super().__init__(bl_input, tree)
self.bl_input = bl_input
@classmethod
def from_dict(cls, data, node):
for bl_ipt in node.bl_node.inputs:
if bl_ipt.identifier != data["identifier"]:
continue
new_ipt = cls(bl_ipt, node.tree)
for k, v in data.items():
setattr(new_ipt, k, v)
return new_ipt
def get_link(self):
if not self.is_linked:
return None
for ipt_link in self.bl_input.links:
for tree_link in self.tree.links:
if ipt_link == tree_link.bl_link:
return tree_link.id
class Output(Socket):
def __init__(self, bl_output, tree):
super().__init__(bl_output, tree)
self.bl_output = bl_output
@classmethod
def from_dict(cls, data, node):
for bl_opt in node.bl_node.outputs:
if bl_opt.identifier != data["identifier"]:
continue
new_opt = cls(bl_opt, node.tree)
for k, v in data.items():
setattr(new_opt, k, v)
return new_opt
def get_link(self):
links = []
if not self.is_linked:
return None
for opt_link in self.bl_output.links:
for tree_link in self.tree.links:
if opt_link == tree_link.bl_link:
links.append(tree_link.id)
return links