Commit: fae338bf7ce7e9fb7f7e8abc7921095a4a861308 Author: Jacques Lucke Date: Tue Mar 19 12:03:47 2019 +0100 Branches: functions https://developer.blender.org/rBfae338bf7ce7e9fb7f7e8abc7921095a4a861308
initial variadic list declaration =================================================================== M release/scripts/startup/function_nodes/inferencer.py A release/scripts/startup/function_nodes/nodes/create_list.py M release/scripts/startup/function_nodes/socket_decl.py M release/scripts/startup/function_nodes/test_inferencer.py M release/scripts/startup/function_nodes/update_sockets.py =================================================================== diff --git a/release/scripts/startup/function_nodes/inferencer.py b/release/scripts/startup/function_nodes/inferencer.py index 925f46dcd72..e720f1fb179 100644 --- a/release/scripts/startup/function_nodes/inferencer.py +++ b/release/scripts/startup/function_nodes/inferencer.py @@ -1,6 +1,7 @@ +from . sockets import type_infos + class Inferencer: - def __init__(self, type_infos): - self.type_infos = type_infos + def __init__(self): self.finalized_ids = dict() self.constraints = set() self.decisions = dict() @@ -13,13 +14,17 @@ class Inferencer: self.constraints.add(constraint) def insert_list_constraint(self, list_ids, base_ids=tuple(), decision_id=None): - constraint = ListConstraint(list_ids, base_ids, decision_id, self.type_infos) + constraint = ListConstraint(list_ids, base_ids, decision_id) self.constraints.add(constraint) def insert_union_constraint(self, ids, allowed_types, decision_id=None): constraint = UnionConstraint(ids, decision_id, allowed_types) self.constraints.add(constraint) + def insert_list_or_base_constraint(self, id, base_type, decision_id=None): + constraint = ListOrBaseConstraint(id, decision_id, base_type) + self.constraints.add(constraint) + def finalize_id(self, id, data_type): if id in self.finalized_ids: if self.finalized_ids[id] != data_type: @@ -33,6 +38,8 @@ class Inferencer: self.finalize_id(id, data_type) def make_decision(self, decision_id, value): + if decision_id is None: + return assert decision_id not in self.decisions self.decisions[decision_id] = value @@ -79,8 +86,7 @@ class EqualityConstraint(Constraint): if id in finalized_ids: data_type = finalized_ids[id] finalize_do(self.ids, data_type) - if self.decision_id is not None: - make_decision(self.decision_id, data_type) + make_decision(self.decision_id, data_type) return True return False @@ -97,43 +103,61 @@ class UnionConstraint(Constraint): if data_type not in self.allowed_types: raise InferencingError() finalize_do(self.ids, data_type) - if self.decision_id is not None: - make_decision(self.decision_id, data_type) + make_decision(self.decision_id, data_type) return True return False class ListConstraint(Constraint): - def __init__(self, list_ids, base_ids, decision_id, type_infos): + def __init__(self, list_ids, base_ids, decision_id): self.list_ids = set(list_ids) self.base_ids = set(base_ids) self.decision_id = decision_id - self.type_infos = type_infos def try_finalize(self, finalized_ids, finalize_do, make_decision): for id in self.list_ids: if id in finalized_ids: list_type = finalized_ids[id] - if not self.type_infos.is_list(list_type): + if not type_infos.is_list(list_type): raise NoListTypeError() - base_type = self.type_infos.to_base(list_type) + base_type = type_infos.to_base(list_type) finalize_do(self.list_ids, list_type) finalize_do(self.base_ids, base_type) - if self.decision_id is not None: - make_decision(self.decision_id, base_type) + make_decision(self.decision_id, base_type) return True for id in self.base_ids: if id in finalized_ids: base_type = finalized_ids[id] - if not self.type_infos.is_base(base_type): + if not type_infos.is_base(base_type): raise NoBaseTypeError() - list_type = self.type_infos.to_list(base_type) + list_type = type_infos.to_list(base_type) finalize_do(self.base_ids, base_type) finalize_do(self.list_ids, list_type) - if self.decision_id is not None: - make_decision(self.decision_id, base_type) + make_decision(self.decision_id, base_type) + return True + return False + +class ListOrBaseConstraint(Constraint): + def __init__(self, id, decision_id, base_type): + self.id = id + self.decision_id = decision_id + self.base_type = base_type + self.list_type = type_infos.to_list(base_type) + + def try_finalize(self, finalized_ids, finalize_do, make_decision): + if self.id in finalized_ids: + data_type = finalized_ids[self.id] + if data_type == self.base_type: + make_decision(self.decision_id, "BASE") return True + elif data_type == self.list_type: + make_decision(self.decision_id, "LIST") + return True + else: + msg = f"{data_type} is not {self.base_type} or {self.list_type}" + raise ConflictingTypesError(msg) return False + class InferencingError(Exception): pass diff --git a/release/scripts/startup/function_nodes/nodes/create_list.py b/release/scripts/startup/function_nodes/nodes/create_list.py new file mode 100644 index 00000000000..0216f36f3ea --- /dev/null +++ b/release/scripts/startup/function_nodes/nodes/create_list.py @@ -0,0 +1,19 @@ +import bpy +from bpy.props import * +from .. base import FunctionNode +from .. socket_decl import VariadicListDecl, FixedSocketDecl +from .. sockets import type_infos + +class CreateListNode(bpy.types.Node, FunctionNode): + bl_idname = "fn_CreateListNode" + bl_label = "Create List" + + active_type: StringProperty(default="Float") + variadic: VariadicListDecl.Property() + + def get_sockets(self): + return [ + VariadicListDecl("inputs", "variadic", self.active_type), + ], [ + FixedSocketDecl("output", "List", type_infos.to_list(self.active_type)), + ] \ No newline at end of file diff --git a/release/scripts/startup/function_nodes/socket_decl.py b/release/scripts/startup/function_nodes/socket_decl.py index c49bfb858ea..a89e18f301b 100644 --- a/release/scripts/startup/function_nodes/socket_decl.py +++ b/release/scripts/startup/function_nodes/socket_decl.py @@ -103,6 +103,77 @@ class AnyOfDecl(SocketDeclBase): def Property(cls, default_type): return StringProperty(default=default_type) +class VariadicListDecl(SocketDeclBase): + def __init__(self, identifier: str, prop_name: str, base_type: str): + self.identifier_suffix = identifier + self.prop_name = prop_name + self.base_type = base_type + self.list_type = type_infos.to_list(base_type) + + def build(self, node, node_sockets): + return list(self._build(node, node_sockets)) + + def _build(self, node, node_sockets): + for item in self.get_collection(node): + data_type = self.base_type if item.state == "BASE" else self.list_type + yield type_infos.build( + data_type, + node_sockets, + "", + item.identifier_prefix + self.identifier_suffix) + yield node_sockets.new("fn_OperatorSocket", "Operator") + + def draw_socket(self, layout, node, socket, index): + if isinstance(socket, OperatorSocket): + layout.label(text="New") + else: + socket.draw_self(layout, node) + + def operator_socket_call(self, node, own_socket, other_socket): + if not isinstance(other_socket, DataSocket): + return + + is_output = own_socket.is_output + data_type = other_socket.data_type + + if type_infos.is_base(data_type): + if data_type != self.base_type: + return + state = "BASE" + elif type_infos.is_list(data_type): + if data_type != self.list_type: + return + state = "LIST" + else: + return + + collection = self.get_collection(node) + item = collection.add() + item.state = state + item.identifier_prefix = str(uuid.uuid4()) + + node.rebuild_and_try_keep_state() + + identifier = item.identifier_prefix + self.identifier_suffix + new_socket = node.find_socket(identifier, is_output) + node.tree.new_link(other_socket, new_socket) + + def amount(self, node): + return len(self.get_collection(node)) + 1 + + def get_collection(self, node): + return getattr(node, self.prop_name) + + @classmethod + def Property(cls): + return CollectionProperty(type=VariadicListPropertyGroup) + +class VariadicListPropertyGroup(bpy.types.PropertyGroup): + bl_idname = "fn_VariadicListPropertyGroup" + + state: StringProperty(default="BASE") + identifier_prefix: StringProperty() + class AnyVariadicDecl(SocketDeclBase): def __init__(self, identifier: str, prop_name: str, message: str): self.identifier_suffix = identifier @@ -113,7 +184,7 @@ class AnyVariadicDecl(SocketDeclBase): return list(self._build(node, node_sockets)) def _build(self, node, node_sockets): - for item in getattr(node, self.prop_name): + for item in self.get_collection(node): yield type_infos.build( item.data_type, node_sockets, @@ -122,7 +193,7 @@ class AnyVariadicDecl(SocketDeclBase): yield node_sockets.new("fn_OperatorSocket", "Operator") def amount(self, node): - return len(getattr(node, self.prop_name)) + 1 + return len(self.get_collection(node)) + 1 def draw_socket(self, layout, node, socket, index): if isinstance(socket, OperatorSocket): @@ -149,7 +220,7 @@ class AnyVariadicDecl(SocketDeclBase): is_output = own_socket.is_output data_type = other_socket.data_type - collection = getattr(node, self.prop_name) + collection = self.get_collection(no @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs