[Bf-blender-cvs] [fae338bf7ce] functions: initial variadic list declaration
Jacques Lucke
noreply at git.blender.org
Tue Mar 19 12:03:59 CET 2019
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. @@
More information about the Bf-blender-cvs
mailing list