diff options
Diffstat (limited to 'release/scripts/modules/bpy_types.py')
-rw-r--r-- | release/scripts/modules/bpy_types.py | 155 |
1 files changed, 144 insertions, 11 deletions
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 4398b1721f7..f42fd8e3107 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -485,17 +485,6 @@ class Text(bpy_types.ID): ) -class NodeSocket(StructRNA): # , metaclass=RNAMeta - __slots__ = () - - @property - def links(self): - """List of node links from or to this socket""" - return tuple(link for link in self.id_data.links - if (link.from_socket == self or - link.to_socket == self)) - - # values are module: [(cls, path, line), ...] TypeMap = {} @@ -757,3 +746,147 @@ class Region(StructRNA): return None + +class NodeTree(bpy_types.ID, metaclass=RNAMetaPropGroup): + __slots__ = () + + +class NodeSocketTemplate(): + type = 'UNDEFINED' + + # Default implementation: + # Create a single property using the socket template's 'value_property' attribute + # value_property should be created in the __init__ function + # + # If necessary this function can be overloaded in subclasses, e.g. to create multiple value properties + def define_node_properties(self, node_type, prefix): + if hasattr(self, "value_property"): + setattr(node_type, prefix+"value", self.value_property) + + def init_socket(self, socket): + socket.type = self.type + if hasattr(self, "value_property"): + socket.value_property = self.value_property[1]['attr'] + + +def gen_valid_identifier(seq): + # get an iterator + itr = iter(seq) + # pull characters until we get a legal one for first in identifer + for ch in itr: + if ch == '_' or ch.isalpha(): + yield ch + break + # pull remaining characters and yield legal ones for identifier + for ch in itr: + if ch == '_' or ch.isalpha() or ch.isdigit(): + yield ch + +def sanitize_identifier(name): + return ''.join(gen_valid_identifier(name)) + +def unique_identifier(name, identifier_list): + # First some basic sanitation, to make a usable identifier string from the name + base = sanitize_identifier(name) + # Now make a unique identifier by appending an unused index + identifier = base + index = 0 + while identifier in identifier_list: + index += 1 + identifier = base + str(index) + return identifier + +class RNAMetaNode(RNAMetaPropGroup): + def __new__(cls, name, bases, classdict, **args): + # Wrapper for node.init, to add sockets from templates + + def create_sockets(self): + inputs = getattr(self, 'input_templates', None) + if inputs: + for temp in inputs: + socket = self.inputs.new(type=temp.bl_socket_idname, name=temp.name, identifier=temp.identifier) + temp.init_socket(socket) + outputs = getattr(self, 'output_templates', None) + if outputs: + for temp in outputs: + socket = self.outputs.new(type=temp.bl_socket_idname, name=temp.name, identifier=temp.identifier) + temp.init_socket(socket) + + init_base = classdict.get('init', None) + if init_base: + def init_node(self, context): + create_sockets(self) + init_base(self, context) + else: + def init_node(self, context): + create_sockets(self) + + classdict['init'] = init_node + + # Create the regular class + result = RNAMetaPropGroup.__new__(cls, name, bases, classdict) + + # Add properties from socket templates + inputs = classdict.get('input_templates', None) + if inputs: + for i, temp in enumerate(inputs): + temp.identifier = unique_identifier(temp.name, [t.identifier for t in inputs[0:i]]) + temp.define_node_properties(result, "input_"+temp.identifier+"_") + outputs = classdict.get('output_templates', None) + if outputs: + for i, temp in enumerate(outputs): + temp.identifier = unique_identifier(temp.name, [t.identifier for t in outputs[0:i]]) + temp.define_node_properties(result, "output_"+temp.identifier+"_") + + return result + + +class Node(StructRNA, metaclass=RNAMetaNode): + __slots__ = () + + @classmethod + def poll(cls, ntree): + return True + + +class NodeSocket(StructRNA, metaclass=RNAMetaPropGroup): + __slots__ = () + + @property + def links(self): + """List of node links from or to this socket""" + return tuple(link for link in self.id_data.links + if (link.from_socket == self or + link.to_socket == self)) + + +class NodeSocketInterface(StructRNA, metaclass=RNAMetaPropGroup): + __slots__ = () + + +# These are intermediate subclasses, need a bpy type too +class CompositorNode(Node): + __slots__ = () + + @classmethod + def poll(cls, ntree): + return ntree.bl_idname == 'CompositorNodeTree' + + def update(self): + self.tag_need_exec() + +class ShaderNode(Node): + __slots__ = () + + @classmethod + def poll(cls, ntree): + return ntree.bl_idname == 'ShaderNodeTree' + + +class TextureNode(Node): + __slots__ = () + + @classmethod + def poll(cls, ntree): + return ntree.bl_idname == 'TextureNodeTree' + |