Sfoglia il codice sorgente

Optimize fill_parameters

Joseph Brandenburg 2 settimane fa
parent
commit
d0a137e691

+ 27 - 25
base_definitions.py

@@ -909,6 +909,12 @@ class MantisExecutionContext():
 
 from typing import Any
 
+# using these frozen sets accelerate lookup when checking for this
+FILL_PARAMETERS_SKIP_ROOTS = frozenset({ 'MANTIS_AUTOGENERATED', 'SCHEMA_AUTOGENERATED', })
+FILL_PARAMETERS_SKIP_NAMES = frozenset({ "NodeGroupOutput", "NodeGroupInput", })
+FILL_PARAMETERS_SKIP_SOCKETS = frozenset({ 'RelationshipSocket', 'xFormSocket', })
+from .socket_definitions import no_default_value
+
 class MantisNode:
     """
         This class contains the basic interface for a Mantis Node.
@@ -1142,40 +1148,36 @@ class MantisNode:
         return prop
 
     def fill_parameters(self, ui_node=None)  -> None:
-        from .utilities.utilities import get_ui_node
-        from .utilities.node_common import get_socket_value
+        from mathutils import Matrix
+        from .utilities.utilities import handle_overlay_detect
         if not ui_node:
-            if ( (self.signature[0] in  ["MANTIS_AUTOGENERATED", "SCHEMA_AUTOGENERATED" ]) or
-                (self.signature[-1] in ["NodeGroupOutput", "NodeGroupInput"]) ): # I think this is harmless
+            if ( (self.signature[0] in FILL_PARAMETERS_SKIP_ROOTS) or
+                (self.signature[-1] in FILL_PARAMETERS_SKIP_NAMES) ): # I think this is harmless
                 return None
-            else: # BUG shouldn't this use ui_signature??
-                ui_node = get_ui_node(self.signature, self.base_tree)
-            if not ui_node:
-                raise RuntimeError(wrapRed("No UI Node found for... %s" % ( [self.base_tree] + list(self.signature[1:]) ) ) )
+            raise RuntimeError(wrapRed("No UI Node found for... %s" % ( [self.base_tree] + list(self.signature[1:]) ) ) )
+        ui_inputs = ui_node.inputs; ui_outputs = ui_node.outputs
         for key in self.parameters.keys():
-            node_socket = ui_node.inputs.get(key)
             if self.parameters[key] is not None: # the parameters are usually initialized as None.
                 continue # will be filled by the node itself
-            if not node_socket: #maybe the node socket has no name
-                if ( ( len(ui_node.inputs) == 0) and ( len(ui_node.outputs) == 1) ):
-                    node_socket = ui_node.outputs[0] # this is a simple input node.
-                elif key == 'Name': # for Links we just use the Node Label, or if there is no label, the name.
-                    self.parameters[key] = ui_node.label if ui_node.label else ui_node.name
-                    continue
-            if node_socket:
-                if node_socket.bl_idname in  ['RelationshipSocket', 'xFormSocket']: continue
+            if node_socket := ui_inputs.get(key):
+                if node_socket.bl_idname in FILL_PARAMETERS_SKIP_SOCKETS: continue
                 elif node_socket.is_linked and (not node_socket.is_output): continue
                 # we will get the value from the link, because this is a linked input port.
                 # very importantly, we do not pass linked outputs
                 # fill these because they are probably Input nodes.
-                elif hasattr(node_socket, "default_value"):
-                    if (value := get_socket_value(node_socket)) is not None:
-                        if isinstance(value, str) and "$" in value:
-                            from .utilities.utilities import handle_overlay_detect
-                            value = handle_overlay_detect(self, node_socket.identifier, value)
-                        self.parameters[key] = value
-                    else:
-                        raise RuntimeError(wrapRed("No value found for " + self.__repr__() + " when filling out node parameters for " + ui_node.name + "::"+node_socket.name))
+                if node_socket.bl_idname in no_default_value: continue
+                if node_socket.bl_idname == 'MatrixSocket':
+                    v = node_socket.default_value
+                    self.parameters[key] = Matrix(( tuple(v[0:4]),
+                                                    tuple(v[4:8]),
+                                                    tuple(v[8:12]),
+                                                    tuple(v[12:16]) ))
+                elif (value := node_socket.default_value) is not None:
+                    if isinstance(value, str) and "$" in value:
+                        value = handle_overlay_detect(self, node_socket.identifier, value)
+                    self.parameters[key] = value
+                else:
+                    raise RuntimeError(wrapRed("No value found for " + self.__repr__() + " when filling out node parameters for " + ui_node.name + "::"+node_socket.name))
 
     # I don't think this works! but I like the idea
     def call_on_all_ancestors(self, *args, **kwargs):

+ 4 - 0
deformer_nodes.py

@@ -71,6 +71,10 @@ class MantisDeformerNode(MantisNode):
         super().reset_execution()
         self.bObject=[]; self.prepared=True
 
+    def fill_parameters(self, ui_node=None):
+        super().fill_parameters(ui_node)
+        self.parameters["Name"] = ui_node.label if ui_node.label else ui_node.name
+
 def standard_modifier_bind(self, bContext=None, operator=None):
     for d in self.bObject:
         # we'll only bind it if it is un-muted.

+ 9 - 4
execution/readtree.py

@@ -66,9 +66,14 @@ def make_connections_to_ng_dummy(base_tree, tree_path_names, local_mantis_nodes,
             #  using UUID signature leads to TERRIBLE CONFUSING BUGS.
             if from_mantis_node is None: 
                 from_mantis_node = autogen_node(base_tree, inp, signature, to_mantis_node.mContext)
-            from ..utilities.node_common import get_socket_value
             if from_mantis_node: # autogen can fail and we should catch it.
-                from_mantis_node.parameters = {inp.name:get_socket_value(inp)}
+                from mathutils import Matrix
+                from_mantis_node.parameters = {inp.name: 
+                                               Matrix(( tuple(inp.default_value[0:4]), \
+                                                        tuple(inp.default_value[4:8]), \
+                                                        tuple(inp.default_value[8:12]), \
+                                                        tuple(inp.default_value[12:16]) )) if inp.bl_idname == 'MatrixSocket' \
+                                                            else inp.default_value}
                 local_mantis_nodes[signature] = from_mantis_node; all_mantis_nodes[signature] = from_mantis_node
                 from_mantis_node.outputs[inp.name].connect(node=to_mantis_node, socket=to_s, sort_id=0)
             else:
@@ -113,8 +118,8 @@ def gen_mantis_nodes(base_tree, current_tree, tree_path_names, mContext, all_man
             prRed(f"Can't make mantis_node for.. {ui_node.bl_idname}")
         # this should be done at init
         mantis_node.mContext = mContext
-        if mantis_node.signature[0] not in ['MANTIS_AUTOGENERATED'] and mantis_node.node_type not in ['SCHEMA', 'DUMMY', 'DUMMY_SCHEMA']:
-            mantis_node.fill_parameters()
+        if mantis_node.signature[0] != 'MANTIS_AUTOGENERATED' and mantis_node.node_type not in {'SCHEMA', 'DUMMY', 'DUMMY_SCHEMA'}:
+            mantis_node.fill_parameters(ui_node)
         mantis_node.is_schema_prototype = in_schema
 
 def data_from_tree(base_tree, tree_path, mContext, dummy_nodes, all_mantis_nodes, all_schema, in_schema):#

+ 1 - 4
execution/schema_solve.py

@@ -65,7 +65,7 @@ class SchemaSolver:
 
         from bpy.types import NodeGroupInput, NodeGroupOutput
         for ui_node in self.tree.nodes:
-            # first we need to fill the parameters of the schema nodes.
+            # Make the mantis nodes for the special interface types
             # we use the bl_idname because all schema nodes should be single-instance
             signature = (*self.tree_path_names, ui_node.bl_idname)
             if isinstance(ui_node, (SchemaUINode, NodeGroupInput, NodeGroupOutput)):
@@ -77,18 +77,15 @@ class SchemaSolver:
                 if not (mantis_node := self.all_nodes.get(get_sig)):
                     raise RuntimeError(wrapRed(f"Not found: {get_sig}"))
                 self.schema_nodes[signature] = mantis_node
-                mantis_node.fill_parameters(ui_node)
             # HACK to make Group Nodes work
             if ui_node.bl_idname == "NodeGroupInput":
                 from ..schema_nodes import SchemaConstInput
                 mantis_node = SchemaConstInput(signature=signature, base_tree=self.node.base_tree, parent_schema_node=self.node)
                 self.schema_nodes[signature] = mantis_node
-                mantis_node.fill_parameters(ui_node)
             if ui_node.bl_idname == "NodeGroupOutput":
                 from ..schema_nodes import SchemaConstOutput
                 mantis_node = SchemaConstOutput(signature=signature, base_tree=self.node.base_tree, parent_schema_node=self.node)
                 self.schema_nodes[signature] = mantis_node
-                mantis_node.fill_parameters(ui_node)
 
     def set_index_strings(self):
         self.index_str = lambda : '.'+str(self.uuid)+'.'+str(self.index).zfill(4)

+ 4 - 0
link_nodes.py

@@ -133,6 +133,10 @@ class MantisLinkNode(MantisNode):
     def bFinalize(self, bContext=None):
         finish_drivers(self)
 
+    def fill_parameters(self, ui_node=None):
+        super().fill_parameters(ui_node)
+        self.parameters["Name"] = ui_node.label if ui_node.label else ui_node.name
+
 #*#-------------------------------#++#-------------------------------#*#
 # L I N K   N O D E S
 #*#-------------------------------#++#-------------------------------#*#

+ 19 - 0
misc_nodes.py

@@ -213,6 +213,15 @@ class SimpleInputNode(MantisMiscNode):
         super().__init__(signature, base_tree, socket_templates, additional_parameters)
         self.prepared, self.executed = True, True
 
+    def fill_parameters(self, ui_node=None):
+        from .utilities.utilities import handle_overlay_detect
+        ui_outputs = ui_node.outputs
+        node_socket = ui_outputs[0] # this is a simple input node.
+        if (value := node_socket.default_value) is not None:
+            if isinstance(value, str) and "$" in value:
+                value = handle_overlay_detect(self, node_socket.identifier, value)
+            self.parameters[node_socket.name] = value
+        
 #*#-------------------------------#++#-------------------------------#*#
 # U T I L I T Y   N O D E S
 #*#-------------------------------#++#-------------------------------#*#
@@ -262,6 +271,16 @@ class InputMatrix(SimpleInputNode):
     __slots__ = ()
     socket_templates = InputMatrixSockets
 
+    def fill_parameters(self, ui_node=None):
+        from mathutils import Matrix
+        ui_outputs = ui_node.outputs
+        node_socket = ui_outputs[0]
+        v = node_socket.default_value
+        self.parameters[node_socket.name] = Matrix(( tuple(v[0:4]),
+                                                     tuple(v[4:8]),
+                                                     tuple(v[8:12]),
+                                                     tuple(v[12:16]) ))
+
 class InputThemeBoneColorSets(SimpleInputNode):
     '''A node representing the theme's colors'''
     __slots__ = ()

+ 0 - 18
socket_definitions.py

@@ -10,7 +10,6 @@ no_default_value= frozenset({
             'xFormSocket',
             'GeometrySocket',
             'GenericRotationSocket',
-            'EnumCustomPropTypeSocket', 
             'CustomPropSocket',
             'FCurveSocket',
             'DriverSocket',
@@ -735,19 +734,6 @@ class MatrixSocket(MantisSocket):
                                 mat[1][0], mat[1][1], mat[1][2], mat[1][3],
                                 mat[2][0], mat[2][1], mat[2][2], mat[2][3],
                                 mat[3][0], mat[3][1], mat[3][2], mat[3][3], )
-    def TellValue(self):
-        from mathutils import Matrix
-        v = self.default_value
-        return Matrix( ( ( v[ 0], v[ 1], v[ 2], v[ 3],),
-                         ( v[ 4], v[ 5], v[ 6], v[ 7],),
-                         ( v[ 8], v[ 9], v[10], v[11],),
-                         ( v[12], v[13], v[14], v[15]), ) )
-                         #NOTE, we're not using the last row
-                         # so we're gonna use it to store data
-                         # unused, unused, unused, bone_length
-                         # but we're not going to make it
-                         # available except by accessor functions
-    # would like to make this stuff easier to deal with tho
     def TellBoneLength(self):
         return self.default_value[15]
 
@@ -903,8 +889,6 @@ class BooleanThreeTupleSocket(MantisSocket):
     color : bpy.props.FloatVectorProperty(default=cBool3, size=4)
     input : bpy.props.BoolProperty(default =False,)
     is_valid_interface_type=True
-    def TellValue(self):
-        return (self.default_value[0], self.default_value[1], self.default_value[2])
 
 class RotationOrderSocket(MantisSocket):
     '''Custom node socket type'''
@@ -1180,8 +1164,6 @@ class EnumCustomPropTypeSocket(MantisSocket):
     color : bpy.props.FloatVectorProperty(default=cString, size=4)
     input : bpy.props.BoolProperty(default =False,)
 
-# what is this one again?
-
 class CustomPropSocket(MantisSocket):
     '''Custom Property'''
     bl_idname = 'CustomPropSocket'

+ 0 - 9
utilities/node_common.py

@@ -28,15 +28,6 @@ def detect_cycle_in_trace(link, link_circle):
                                 print_link_list(link_circle))
         link_circle.append(link)
 
-#TODO: refactor the socket definitions so this becomes unnecessary.
-def get_socket_value(node_socket):
-    value = None
-    if hasattr(node_socket, "default_value"): 
-        value = node_socket.default_value
-    if node_socket.bl_idname == 'MatrixSocket':
-        value =  node_socket.TellValue()
-    return value
-
 # NOTE this is a dupe of trace_single_line, and it must be used
 #      at any time before the tree is parsed (to check for cycles)
 #      I don't want or need to pay the performance cost to check this everywhere

+ 0 - 12
utilities/utilities.py

@@ -849,18 +849,6 @@ def trace_all_nodes_from_root(root, nodes):
 # misc
 ##################################################################################################
 
-# TODO: get the matrix to return a mathutils.Matrix so I don't need a function call here
-def to_mathutils_value(socket):
-    if hasattr(socket, "default_value"):
-        val = socket.default_value
-        if socket.bl_idname in ['MatrixSocket']:
-            return socket.TellValue()
-        else:
-            return val
-    else:
-        return None
-
-
 def all_trees_in_tree(base_tree, selected=False):
     """ Recursively finds all trees referenced in a given base-tree."""
     # note that this is recursive but not by tail-end recursion