[Bf-blender-cvs] [826a1327919] functions: support nested properties in inferencer

Jacques Lucke noreply at git.blender.org
Tue Dec 10 18:12:59 CET 2019


Commit: 826a1327919ea6a48b4f843984e8b1e350de1e01
Author: Jacques Lucke
Date:   Tue Dec 10 16:46:31 2019 +0100
Branches: functions
https://developer.blender.org/rB826a1327919ea6a48b4f843984e8b1e350de1e01

support nested properties in inferencer

===================================================================

M	release/scripts/startup/nodes/declaration/vectorized.py
M	release/scripts/startup/nodes/inferencing.py
M	release/scripts/startup/nodes/sync.py
M	release/scripts/startup/nodes/utils/generic.py

===================================================================

diff --git a/release/scripts/startup/nodes/declaration/vectorized.py b/release/scripts/startup/nodes/declaration/vectorized.py
index 439dc463205..62bb4b31a8c 100644
--- a/release/scripts/startup/nodes/declaration/vectorized.py
+++ b/release/scripts/startup/nodes/declaration/vectorized.py
@@ -2,6 +2,7 @@ import bpy
 from bpy.props import *
 from . base import SocketDeclBase, NoDefaultValue
 from .. types import type_infos
+from .. utils.generic import getattr_recursive
 
 class VectorizedDeclBase:
     def build(self, node_sockets):
@@ -49,7 +50,7 @@ class VectorizedInputDecl(VectorizedDeclBase, SocketDeclBase):
             socket.restore_state(self.default)
 
     def is_vectorized(self):
-        stored = getattr(self.node, self.prop_name)
+        stored = getattr_recursive(self.node, self.prop_name)
         if stored == "BASE":
             return False
         elif stored == "LIST":
@@ -77,6 +78,6 @@ class VectorizedOutputDecl(VectorizedDeclBase, SocketDeclBase):
 
     def is_vectorized(self):
         for prop_name in self.input_prop_names:
-            if getattr(self.node, prop_name) == "LIST":
+            if getattr_recursive(self.node, prop_name) == "LIST":
                 return True
         return False
diff --git a/release/scripts/startup/nodes/inferencing.py b/release/scripts/startup/nodes/inferencing.py
index eed43488ebe..1d0275216e0 100644
--- a/release/scripts/startup/nodes/inferencing.py
+++ b/release/scripts/startup/nodes/inferencing.py
@@ -12,7 +12,7 @@ from . declaration import (
     VectorizedOutputDecl,
 )
 
-DecisionID = namedtuple("DecisionID", ("node", "group", "prop_name"))
+DecisionID = namedtuple("DecisionID", ("node", "prop_name"))
 
 def get_inferencing_decisions(tree_data: TreeData):
     list_decisions = make_list_decisions(tree_data)
@@ -52,7 +52,7 @@ def get_list_decision_ids_with_users(tree_data):
     for node in tree_data.iter_nodes():
         for decl, sockets in node.decl_map.iter_decl_with_sockets():
             if isinstance(decl, ListSocketDecl):
-                decision_id = DecisionID(node, node, decl.prop_name)
+                decision_id = DecisionID(node, decl.prop_name)
                 decision_users[decision_id][decl.list_or_base].append(sockets[0])
 
     return decision_users
@@ -67,8 +67,8 @@ def get_list_decision_links(tree_data):
         to_decl = to_socket.get_decl(to_node)
         if isinstance(from_decl, ListSocketDecl) and isinstance(to_decl, ListSocketDecl):
             if from_decl.list_or_base == to_decl.list_or_base:
-                from_decision_id = DecisionID(from_node, from_node, from_decl.prop_name)
-                to_decision_id = DecisionID(to_node, to_node, to_decl.prop_name)
+                from_decision_id = DecisionID(from_node, from_decl.prop_name)
+                to_decision_id = DecisionID(to_node, to_decl.prop_name)
                 linked_decisions[from_decision_id].add(to_decision_id)
                 linked_decisions[to_decision_id].add(from_decision_id)
 
@@ -147,7 +147,7 @@ def get_vector_decisions_graph(tree_data):
     for node in tree_data.iter_nodes():
         for decl, sockets in node.decl_map.iter_decl_with_sockets():
             if isinstance(decl, VectorizedInputDecl):
-                decision_id = DecisionID(node, node, decl.prop_name)
+                decision_id = DecisionID(node, decl.prop_name)
                 builder.add_vertex(decision_id)
                 input_sockets.add(sockets[0])
             elif isinstance(decl, VectorizedOutputDecl):
@@ -162,8 +162,8 @@ def get_vector_decisions_graph(tree_data):
 
         if isinstance(from_decl, VectorizedOutputDecl) and isinstance(to_decl, VectorizedInputDecl):
             for prop_name in from_decl.input_prop_names:
-                from_decision_id = DecisionID(from_node, from_node, prop_name)
-                to_decision_id = DecisionID(to_node, to_node, to_decl.prop_name)
+                from_decision_id = DecisionID(from_node, prop_name)
+                to_decision_id = DecisionID(to_node, to_decl.prop_name)
                 builder.add_directed_edge(from_decision_id, to_decision_id)
 
     return builder.build(), input_sockets, output_sockets
@@ -176,7 +176,7 @@ def iter_obligatory_vector_decisions(graph, input_sockets, output_sockets, tree_
 
         node = tree_data.get_node(socket)
         decl = socket.get_decl(node)
-        decision_id = DecisionID(node, node, decl.prop_name)
+        decision_id = DecisionID(node, decl.prop_name)
 
         other_decl = other_socket.get_decl(other_node)
         if data_sockets_are_static(other_decl):
@@ -185,7 +185,7 @@ def iter_obligatory_vector_decisions(graph, input_sockets, output_sockets, tree_
                 yield decision_id, "LIST"
         elif isinstance(other_decl, ListSocketDecl):
             if other_decl.list_or_base == "LIST":
-                list_decision_id = DecisionID(other_node, other_node, other_decl.prop_name)
+                list_decision_id = DecisionID(other_node, other_decl.prop_name)
                 if list_decision_id in list_decisions:
                     other_base_type = list_decisions[list_decision_id]
                     if type_infos.is_link_allowed(other_base_type, decl.base_type):
@@ -198,7 +198,7 @@ def iter_obligatory_vector_decisions(graph, input_sockets, output_sockets, tree_
     for socket in output_sockets:
         node = tree_data.get_node(socket)
         decl = socket.get_decl(node)
-        decision_ids = [DecisionID(node, node, p) for p in decl.input_prop_names]
+        decision_ids = [DecisionID(node, p) for p in decl.input_prop_names]
 
         for other_node, other_socket in tree_data.iter_connected_sockets_with_nodes(socket):
             other_decl = other_socket.get_decl(other_node)
@@ -209,7 +209,7 @@ def iter_obligatory_vector_decisions(graph, input_sockets, output_sockets, tree_
                         yield decision_id, "BASE"
             elif isinstance(other_decl, ListSocketDecl):
                 if other_decl.list_or_base == "BASE":
-                    list_decision_id = DecisionID(other_node, other_node, other_decl.prop_name)
+                    list_decision_id = DecisionID(other_node, other_decl.prop_name)
                     if list_decision_id in list_decisions:
                         other_base_type = list_decisions[list_decision_id]
                         if type_infos.is_link_allowed(decl.base_type, other_base_type):
@@ -246,7 +246,7 @@ def make_base_list_variadic_decisions(tree_data, list_decisions, vector_decision
             else:
                 decisions[decision_id] = "BASE"
         elif isinstance(origin_decl, ListSocketDecl):
-            list_decision_id = DecisionID(origin_node, origin_node, origin_decl.prop_name)
+            list_decision_id = DecisionID(origin_node, origin_decl.prop_name)
             if list_decision_id in list_decisions:
                 other_base_type = list_decisions[list_decision_id]
                 if type_infos.is_link_allowed(other_base_type, decl.base_type):
@@ -265,7 +265,7 @@ def make_base_list_variadic_decisions(tree_data, list_decisions, vector_decision
             other_base_type = origin_decl.base_type
             if type_infos.is_link_allowed(other_base_type, decl.base_type):
                 for input_prop_name in origin_decl.input_prop_names:
-                    input_decision_id = DecisionID(origin_node, origin_node, input_prop_name)
+                    input_decision_id = DecisionID(origin_node, input_prop_name)
                     if input_decision_id in vector_decisions:
                         if vector_decisions[input_decision_id] == "LIST":
                             decisions[decision_id] = "LIST"
@@ -288,5 +288,5 @@ def iter_base_list_variadic_sockets(tree_data):
             if isinstance(decl, BaseListVariadic):
                 collection = decl.get_collection()
                 for i, socket in enumerate(sockets[:-1]):
-                    decision_id = DecisionID(node, collection[i], "state")
+                    decision_id = DecisionID(node, f"{decl.prop_name}[{i}].state")
                     yield decision_id, decl, socket
diff --git a/release/scripts/startup/nodes/sync.py b/release/scripts/startup/nodes/sync.py
index c3f2f744db6..84b10566a5d 100644
--- a/release/scripts/startup/nodes/sync.py
+++ b/release/scripts/startup/nodes/sync.py
@@ -1,10 +1,12 @@
 import bpy
 from pprint import pprint
+from contextlib import contextmanager
+
 from . base import BaseNode
 from . tree_data import TreeData
 from . graph import DirectedGraphBuilder
 from . function_tree import FunctionTree
-from contextlib import contextmanager
+from . utils.generic import getattr_recursive, setattr_recursive
 
 _is_syncing = False
 
@@ -127,9 +129,9 @@ def do_inferencing_and_update_nodes(tree_data):
 
     nodes_to_rebuild = set()
 
-    for decision_id, base_type in decisions.items():
-        if getattr(decision_id.group, decision_id.prop_name) != base_type:
-            setattr(decision_id.group, decision_id.prop_name, base_type)
+    for decision_id, value in decisions.items():
+        if getattr_recursive(decision_id.node, decision_id.prop_name) != value:
+            setattr_recursive(decision_id.node, decision_id.prop_name, value)
             nodes_to_rebuild.add(decision_id.node)
 
     rebuild_nodes_and_try_keep_state(nodes_to_rebuild)
diff --git a/release/scripts/startup/nodes/utils/generic.py b/release/scripts/startup/nodes/utils/generic.py
index b4e6a6a200b..166fc0eaaf1 100644
--- a/release/scripts/startup/nodes/utils/generic.py
+++ b/release/scripts/startup/nodes/utils/generic.py
@@ -5,3 +5,17 @@ def iter_subclasses_recursive(cls):
     for sub in cls.__subclasses__():
         yield sub
         yield from iter_subclasses_recursive(sub)
+
+def getattr_recursive(obj, name: str):
+    if "." not in name and "[" not in name:
+        return getattr(obj, name)
+    else:
+        # TODO: implement without eval
+        return eval("obj." + name, globals(), locals())
+
+def setattr_recursive(obj, name: str, value):
+    if "." not in name and "[" not in name:
+        setattr(obj, name, value)
+    else:
+        # TODO: implement without exec
+        exec("obj." + name + " = valu

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list