Browse Source

Fix: Array Inputs now sort correctly

Before this fix, there was no logic to handle the order of the array node's inputs, so they were added in order of the node_tree.links() list (which is ordered by lifetime, newest first, and this is incidentally the same as sorting by the ram/pointer address). Now we look at the sort index stored in the bpy.types.link object, and use that. My implementation is probably not the most efficient but it's fast enough.
Joseph Brandenburg 9 months ago
parent
commit
e14d36b9f4
3 changed files with 13 additions and 8 deletions
  1. 9 4
      node_container_common.py
  2. 1 1
      readtree.py
  3. 3 3
      utilities.py

+ 9 - 4
node_container_common.py

@@ -623,7 +623,7 @@ class NodeLink:
     to_node = None
     to_node = None
     to_socket = None
     to_socket = None
     
     
-    def __init__(self, from_node, from_socket, to_node, to_socket):
+    def __init__(self, from_node, from_socket, to_node, to_socket, multi_input_sort_id=0):
         if from_node.signature == to_node.signature:
         if from_node.signature == to_node.signature:
             raise RuntimeError("Cannot connect a node to itself.")
             raise RuntimeError("Cannot connect a node to itself.")
         self.from_node = from_node
         self.from_node = from_node
@@ -631,7 +631,10 @@ class NodeLink:
         self.to_node = to_node
         self.to_node = to_node
         self.to_socket = to_socket
         self.to_socket = to_socket
         self.from_node.outputs[self.from_socket].links.append(self)
         self.from_node.outputs[self.from_socket].links.append(self)
+        self.multi_input_sort_id = multi_input_sort_id
         self.to_node.inputs[self.to_socket].links.append(self)
         self.to_node.inputs[self.to_socket].links.append(self)
+        if self.multi_input_sort_id>0:
+            self.to_node.inputs[self.to_socket].links.sort(key=lambda a : -1*a.multi_input_sort_id)
         self.is_hierarchy = detect_hierarchy_link(from_node, from_socket, to_node, to_socket,)
         self.is_hierarchy = detect_hierarchy_link(from_node, from_socket, to_node, to_socket,)
         self.is_alive = True
         self.is_alive = True
     
     
@@ -678,7 +681,7 @@ class NodeSocket:
         if (traverse_target):
         if (traverse_target):
             self.can_traverse = True
             self.can_traverse = True
         
         
-    def connect(self, node, socket):
+    def connect(self, node, socket, sort_id=0):
         if  (self.is_input):
         if  (self.is_input):
             to_node   = self.node; from_node = node
             to_node   = self.node; from_node = node
             to_socket = self.name; from_socket = socket
             to_socket = self.name; from_socket = socket
@@ -692,7 +695,8 @@ class NodeSocket:
                 from_node,
                 from_node,
                 from_socket,
                 from_socket,
                 to_node,
                 to_node,
-                to_socket)
+                to_socket,
+                sort_id)
         
         
         # if (from_node.signature[-2] in ["Chiral Identifier"] and
         # if (from_node.signature[-2] in ["Chiral Identifier"] and
             # from_node.signature[-1] in ['Input_4']):
             # from_node.signature[-1] in ['Input_4']):
@@ -722,11 +726,12 @@ class NodeSocket:
 # do I need this and the link class above?
 # do I need this and the link class above?
 class DummyLink:
 class DummyLink:
     #gonna use this for faking links to keep the interface consistent
     #gonna use this for faking links to keep the interface consistent
-    def __init__(self, from_socket, to_socket, nc_from=None, nc_to=None, original_from=None):
+    def __init__(self, from_socket, to_socket, nc_from=None, nc_to=None, original_from=None, multi_input_sort_id=0):
         self.from_socket = from_socket
         self.from_socket = from_socket
         self.to_socket = to_socket
         self.to_socket = to_socket
         self.nc_from = nc_from
         self.nc_from = nc_from
         self.nc_to = nc_to
         self.nc_to = nc_to
+        self.multi_input_sort_id = multi_input_sort_id
         # self.from_node = from_socket.node
         # self.from_node = from_socket.node
         # self.to_node = to_socket.node
         # self.to_node = to_socket.node
         if (original_from):
         if (original_from):

+ 1 - 1
readtree.py

@@ -143,7 +143,7 @@ def make_connections_to_ng_dummy(base_tree, tree_path_names, local_nc, all_nc, n
                 from_s = inp.name
                 from_s = inp.name
             else: # should this be an error instead?
             else: # should this be an error instead?
                 prRed("No available auto-generated class for input", *tree_path_names, np.name, inp.name)
                 prRed("No available auto-generated class for input", *tree_path_names, np.name, inp.name)
-            nc_from.outputs[from_s].connect(node=nc_to, socket=to_s)
+            nc_from.outputs[from_s].connect(node=nc_to, socket=to_s, sort_id=0)
 
 
 def gen_node_containers(base_tree, current_tree, tree_path_names, all_nc, local_nc, dummy_nodes, group_nodes, schema_nodes ):
 def gen_node_containers(base_tree, current_tree, tree_path_names, all_nc, local_nc, dummy_nodes, group_nodes, schema_nodes ):
     from .internal_containers import DummyNode
     from .internal_containers import DummyNode

+ 3 - 3
utilities.py

@@ -171,7 +171,7 @@ def clear_reroutes(links):
             kept_links.append(link)
             kept_links.append(link)
     for start in rerouted_starts:
     for start in rerouted_starts:
         from_socket = socket_seek(start, rerouted)
         from_socket = socket_seek(start, rerouted)
-        new_link = DummyLink(from_socket=from_socket, to_socket=start.to_socket, nc_from=None, nc_to=None)
+        new_link = DummyLink(from_socket=from_socket, to_socket=start.to_socket, nc_from=None, nc_to=None, )
         kept_links.append(new_link)
         kept_links.append(new_link)
     return kept_links
     return kept_links
 
 
@@ -496,7 +496,7 @@ def link_node_containers(tree_path_names, link, local_nc, from_suffix='', to_suf
         if nc_to.node_type in dummy_types: to_s = link.to_socket.identifier
         if nc_to.node_type in dummy_types: to_s = link.to_socket.identifier
         if nc_from.node_type in dummy_types: from_s = link.from_socket.identifier
         if nc_from.node_type in dummy_types: from_s = link.from_socket.identifier
         try:
         try:
-            connection = nc_from.outputs[from_s].connect(node=nc_to, socket=to_s)
+            connection = nc_from.outputs[from_s].connect(node=nc_to, socket=to_s, sort_id=link.multi_input_sort_id)
             if connection is None:
             if connection is None:
                 prWhite(f"Already connected: {from_name}:{from_s}->{to_name}:{to_s}")
                 prWhite(f"Already connected: {from_name}:{from_s}->{to_name}:{to_s}")
             return connection
             return connection
@@ -847,7 +847,7 @@ def gen_nc_input_for_data(socket):
                         "EnumDriverVariableEvaluationSpace"    : classes["InputString"],
                         "EnumDriverVariableEvaluationSpace"    : classes["InputString"],
                         "EnumDriverRotationMode"               : classes["InputString"],
                         "EnumDriverRotationMode"               : classes["InputString"],
                         "EnumDriverType"                       : classes["InputString"],
                         "EnumDriverType"                       : classes["InputString"],
-                        "EnumKeyframeInterpolationTypeSocket"  : classes["InputString"],
+                        "EnumKeyframeInterpTypeSocket"  : classes["InputString"],
                         "EnumKeyframeBezierHandleTypeSocket"   : classes["InputString"],
                         "EnumKeyframeBezierHandleTypeSocket"   : classes["InputString"],
                         # Math
                         # Math
                         "MathFloatOperation"                   : classes["InputString"],
                         "MathFloatOperation"                   : classes["InputString"],