Browse Source

Update All Nodes to use Socket Templates

This commit ports all nodes (except dynamic nodes) to use socket templates.
As far as I can tell it works as a drop-in replacement without any bugs.
I'll need to test it a little more thoroughly to be 1000% sure.

My Stegosaurus test rig generates without errors, at least!
Joseph Brandenburg 1 month ago
parent
commit
117e9a2ff8

+ 4 - 0
__init__.py

@@ -51,6 +51,10 @@ if environ.get("ENABLEVIS"):
     from .visualize import MantisVisualizeNode, MantisVisualizeOutput, MantisVisualizeTree
     from .visualize import MantisVisualizeNode, MantisVisualizeOutput, MantisVisualizeTree
     classes.extend([MantisVisualizeTree, MantisVisualizeNode, MantisVisualizeOutput, ])
     classes.extend([MantisVisualizeTree, MantisVisualizeNode, MantisVisualizeOutput, ])
 
 
+DOERROR = False
+if environ.get("DOERROR"):
+    DOERROR = True
+
 import nodeitems_utils
 import nodeitems_utils
 from nodeitems_utils import NodeCategory, NodeItem
 from nodeitems_utils import NodeCategory, NodeItem
 
 

+ 10 - 3
base_definitions.py

@@ -211,7 +211,6 @@ class SchemaTree(NodeTree):
             fix_reroute_colors(self)
             fix_reroute_colors(self)
 
 
 
 
-
 #TODO: do a better job explaining how MantisNode and MantisUINode relate.
 #TODO: do a better job explaining how MantisNode and MantisUINode relate.
 
 
 class MantisUINode:
 class MantisUINode:
@@ -220,6 +219,10 @@ class MantisUINode:
         MantisUINode objects will spawn one or more MantisNode objects when the graph is evaluated.
         MantisUINode objects will spawn one or more MantisNode objects when the graph is evaluated.
         The MantisNode objects will pull the data from the UI node and use it to generate the graph.
         The MantisNode objects will pull the data from the UI node and use it to generate the graph.
     """
     """
+    # blender stuff, I'll need to split this into a mixin class later
+    bl_icon = 'NODE'
+    initialized : bpy.props.BoolProperty(default = False)
+    #
     mantis_node_library=''
     mantis_node_library=''
     mantis_node_class_name=''
     mantis_node_class_name=''
     mantis_class=None
     mantis_class=None
@@ -268,8 +271,12 @@ class MantisUINode:
             )
             )
             socket.hide= template.hide
             socket.hide= template.hide
             if template.category:
             if template.category:
+                from . import DOERROR
                 # a custom property for the UI functions to use.
                 # a custom property for the UI functions to use.
-                socket.category = template.category
+                if hasattr(socket, "category"):
+                    socket.category = template.category
+                elif DOERROR:
+                    print (f"WARN: socket type {socket.bl_idname} has no category attribute")
             if template.default_value is not None:
             if template.default_value is not None:
                 socket.default_value = template.default_value
                 socket.default_value = template.default_value
                 # this can throw a TypeError - it is the caller's
                 # this can throw a TypeError - it is the caller's
@@ -302,7 +309,6 @@ class DeformerNode(MantisUINode):
     def poll(cls, ntree):
     def poll(cls, ntree):
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
 
 
-
 def poll_node_tree(self, object):
 def poll_node_tree(self, object):
     forbid = []
     forbid = []
     context = bpy.context
     context = bpy.context
@@ -1120,6 +1126,7 @@ class MantisNodeSocketCollection(dict):
             if isinstance(socket, str):
             if isinstance(socket, str):
                 self[socket] = NodeSocket(is_input=self.is_input, name=socket, node=self.node)
                 self[socket] = NodeSocket(is_input=self.is_input, name=socket, node=self.node)
             elif isinstance(socket, MantisSocketTemplate):
             elif isinstance(socket, MantisSocketTemplate):
+                if socket.ui_only == True: continue # used in UI but not in generation
                 if socket.is_input != self.is_input: continue
                 if socket.is_input != self.is_input: continue
                 self[socket.name] = NodeSocket(is_input=self.is_input, name=socket.name, node=self.node)
                 self[socket.name] = NodeSocket(is_input=self.is_input, name=socket.name, node=self.node)
             else:
             else:

+ 2 - 35
deformer_nodes.py

@@ -81,31 +81,12 @@ class DeformerArmature(MantisDeformerNode):
     '''A node representing an armature deformer'''
     '''A node representing an armature deformer'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-            "Input Relationship",
-            "Armature Object",
-            "Blend Vertex Group",
-            "Invert Vertex Group",
-            "Preserve Volume",
-            "Use Multi Modifier",
-            "Use Envelopes",
-            "Use Vertex Groups",
-            "Skinning Method",
-            "Deformer",
-            "Copy Skin Weights From"
-        ]
-        outputs = [
-          "Deformer"
-        ]
-        self.outputs.init_sockets(outputs)
-        self.inputs.init_sockets(inputs)
+        super().__init__(signature, base_tree, DeformArmatureSockets)
         self.init_parameters(additional_parameters={"Name":None})
         self.init_parameters(additional_parameters={"Name":None})
         self.set_traverse([("Deformer", "Deformer")])
         self.set_traverse([("Deformer", "Deformer")])
         self.node_type = "LINK"
         self.node_type = "LINK"
         self.prepared = True
         self.prepared = True
 
 
-
     def GetxForm(self, socket="Deformer"):
     def GetxForm(self, socket="Deformer"):
         if socket == "Deformer":
         if socket == "Deformer":
             return super().GetxForm()
             return super().GetxForm()
@@ -445,22 +426,8 @@ class DeformerHook(MantisDeformerNode):
 class DeformerMorphTarget(MantisDeformerNode):
 class DeformerMorphTarget(MantisDeformerNode):
     '''A node representing an armature deformer'''
     '''A node representing an armature deformer'''
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-            "Relative to",
-            "Object",
-            "Deformer",
-            "Vertex Group",
-        ]
-        outputs = [
-          "Deformer",
-          "Morph Target",
-        ]
-        # now set up the traverse target...
-        self.outputs.init_sockets(outputs)
-        self.inputs.init_sockets(inputs)
+        super().__init__(signature, base_tree, MorphTargetSockets)
         self.init_parameters(additional_parameters={"Name":None})
         self.init_parameters(additional_parameters={"Name":None})
-        self.set_traverse([("Deformer", "Deformer")])
         self.node_type = "LINK"
         self.node_type = "LINK"
         self.prepared = True
         self.prepared = True
     
     

+ 11 - 36
deformer_nodes_ui.py

@@ -11,13 +11,13 @@ from .utilities import (prRed, prGreen, prPurple, prWhite, prOrange,
 def TellClasses():
 def TellClasses():
     return [
     return [
              DeformerArmatureNode,
              DeformerArmatureNode,
-             DeformerHook,
+             DeformerHook, #
              DeformerMorphTargetDeform,
              DeformerMorphTargetDeform,
              DeformerMorphTarget,
              DeformerMorphTarget,
-             DeformerSurfaceDeform,
-             DeformerMeshDeform,
-             DeformerLatticeDeform,
-             DeformerSmoothCorrectiveDeform,
+             DeformerSurfaceDeform, # 
+             DeformerMeshDeform, #
+             DeformerLatticeDeform, #
+             DeformerSmoothCorrectiveDeform, #
            ]
            ]
 
 
 
 
@@ -37,25 +37,7 @@ class DeformerArmatureNode(Node, DeformerNode):
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
 
 
     def init(self, context):
     def init(self, context):
-        # self.inputs.new ("RelationshipSocket", "Input Relationship")
-        self.inputs.new('xFormSocket', "Armature Object")
-        self.inputs.new('StringSocket', "Blend Vertex Group")
-        # self.inputs.new('StringSocket', "Preserve Volume Vertex Group") #TODO figure out the right UX for automatic dual-quat blending
-        self.inputs.new('BooleanSocket', "Invert Vertex Group")
-        
-        self.inputs.new('BooleanSocket', "Preserve Volume")
-        # TODO: make the above controlled by a vertex group instead.
-        self.inputs.new('BooleanSocket', "Use Multi Modifier")# might just set this auto
-        self.inputs.new('BooleanSocket', "Use Envelopes")
-        self.inputs.new('BooleanSocket', "Use Vertex Groups")
-        
-        self.inputs.new("DeformerSocket", "Deformer")
-
-        s = self.inputs.new("xFormSocket", "Copy Skin Weights From")
-        s.hide = True
-        self.inputs.new("EnumSkinning", "Skinning Method")
-        
-        self.outputs.new('DeformerSocket', "Deformer")
+        self.init_sockets(DeformArmatureSockets)
         self.initialized = True
         self.initialized = True
     
     
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
@@ -138,13 +120,9 @@ class DeformerMorphTargetDeform(Node, DeformerNode):
 
 
     def init(self, context):
     def init(self, context):
         self.id_data.do_live_update = False
         self.id_data.do_live_update = False
-        self.inputs.new('DeformerSocket', 'Deformer', )
-        self.inputs.new('BooleanSocket', 'Use Shape Key', )
-        s = self.inputs.new('BooleanSocket', 'Use Offset', )
-        s.default_value = True
-        self.inputs.new('WildcardSocket', '', identifier='__extend__')
-        self.outputs.new('DeformerSocket', "Deformer")
+        self.init_sockets(MorphTargetDeformSockets)
         self.update_morph_deformer()
         self.update_morph_deformer()
+        self.id_data.do_live_update = True
 
 
     def update_morph_deformer(self, force=False):
     def update_morph_deformer(self, force=False):
         self.initialized = False
         self.initialized = False
@@ -197,7 +175,8 @@ class DeformerMorphTargetDeform(Node, DeformerNode):
                 self.inputs["Use Shape Key"].default_value = False
                 self.inputs["Use Shape Key"].default_value = False
 
 
 
 
-# TODO: there is no reason for this to be a separate node!
+# NOTE: in the past I considered jamming this into the above node
+#       as a dynamic node thing. Worth considering later, but it's fine.
 class DeformerMorphTarget(Node, DeformerNode):
 class DeformerMorphTarget(Node, DeformerNode):
     '''A node representing a single Morph Target'''
     '''A node representing a single Morph Target'''
     bl_idname = 'DeformerMorphTarget'
     bl_idname = 'DeformerMorphTarget'
@@ -208,11 +187,7 @@ class DeformerMorphTarget(Node, DeformerNode):
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
 
 
     def init(self, context):
     def init(self, context):
-        self.inputs.new('xFormSocket', "Relative to")
-        self.inputs.new('xFormSocket', "Object")
-        self.inputs.new('StringSocket', "Vertex Group")
-        self.outputs.new('MorphTargetSocket', "Morph Target")
-
+        self.init_sockets(MorphTargetSockets)
         self.initialized = True
         self.initialized = True
 
 
 
 

+ 58 - 25
deformer_socket_templates.py

@@ -1,59 +1,92 @@
-from .mantis_dataclasses import MantisSocketTemplate as SockTemplate
+from .mantis_dataclasses import MantisSocketTemplate as ST
 from dataclasses import replace
 from dataclasses import replace
 
 
 from .misc_nodes_socket_templates import SplineIndexTemplate
 from .misc_nodes_socket_templates import SplineIndexTemplate
 
 
 
 
-Target = SockTemplate(name="Target", bl_idname='xFormSocket',
+Target = ST(name="Target", bl_idname='xFormSocket',
         is_input=True,
         is_input=True,
     )
     )
 
 
+DeformArmatureSockets = [ 
+    ArmatureObject := replace(Target, name="Armature Object"),
+    BlendVertexGroup := ST(name="Blend Vertex Group", bl_idname="StringSocket", is_input=True),
+    InvertBlendVertexGroup := ST(name="Invert Vertex Group", bl_idname="BooleanSocket", is_input=True),
+    # QuatBlendVertexGroup := ST(name="Preserve Volume Vertex Group", bl_idname="StringSocket", is_input=True)
+    # ^ TODO figure out the right UX for automatic dual-quat blending
+    PreserveVolume := ST(name="Preserve Volume", bl_idname="BooleanSocket", is_input=True),
+    # ^ TODO: make the above controlled by a vertex group instead.
+    UseMultiModifier := ST(name="Use Multi Modifier", bl_idname="BooleanSocket", is_input=True), # might just set this auto
+    UseEnvelopes := ST(name="Use Envelopes", bl_idname="BooleanSocket", is_input=True, default_value=False),
+    UseVertexGroups := ST(name="Use Vertex Groups", bl_idname="BooleanSocket", is_input=True, default_value=True),
+    DeformerInput := ST(name="Deformer", bl_idname="DeformerSocket", is_input=True),
+    CopySkinWeightsFrom := ST(name="Copy Skin Weights From", bl_idname="xFormSocket", is_input=True, hide=True),
+    SkinningMethod := ST(name="Skinning Method", bl_idname="EnumSkinning", is_input=True),
+    DeformerOutput := ST(name="Deformer", bl_idname="DeformerSocket", is_input=False),
+
+]
+
 HookSockets= [
 HookSockets= [
-    DeformerInput := SockTemplate(name="Deformer", bl_idname='DeformerSocket',
-        is_input=True,),
+    DeformerInput,
     HookTarget := replace(Target, name="Hook Target"),
     HookTarget := replace(Target, name="Hook Target"),
     replace(SplineIndexTemplate,),
     replace(SplineIndexTemplate,),
-    CurvePointIndex := SockTemplate(name="Point Index", bl_idname='UnsignedIntSocket',
+    CurvePointIndex := ST(name="Point Index", bl_idname='UnsignedIntSocket',
         is_input=True, default_value=0 ),
         is_input=True, default_value=0 ),
-    Influence := SockTemplate(name="Influence", bl_idname='FloatFactorSocket',
+    Influence := ST(name="Influence", bl_idname='FloatFactorSocket',
         is_input=True, default_value=1.0, blender_property='strength'),
         is_input=True, default_value=1.0, blender_property='strength'),
-    HookDrivesRadius := SockTemplate(name="Affect Curve Radius", bl_idname='BooleanSocket',
+    HookDrivesRadius := ST(name="Affect Curve Radius", bl_idname='BooleanSocket',
         is_input=True, default_value=True,),
         is_input=True, default_value=True,),
-    HookAutoBezier := SockTemplate(name="Auto-Bezier", bl_idname='BooleanSocket',
+    HookAutoBezier := ST(name="Auto-Bezier", bl_idname='BooleanSocket',
         is_input=True, default_value=True,),
         is_input=True, default_value=True,),
-    DeformerOutput := SockTemplate(name="Deformer", bl_idname='DeformerSocket',
-        is_input=False,), 
+    DeformerOutput, 
+]
+
+#NOTE that this guy is a dynamic node so this is only its initial state.
+MorphTargetDeformSockets = [
+    DeformerInput,
+    UseShapeKey := ST(name="Use Shape Key", bl_idname="BooleanSocket", is_input=True),
+    UseOffset := ST(name="Use Offset", bl_idname="BooleanSocket", is_input=True, default_value=True),
+    Extend := ST(name="", bl_idname="WildcardSocket", is_input=True, identifier="__extend__", ui_only=True),
+    DeformerOutput,
+]
+
+
+MorphTargetSockets = [
+    RelativeTo := ST(name="Relative to", bl_idname="xFormSocket", is_input=True),
+    Object := ST(name="Object", bl_idname="xFormSocket", is_input=True),
+    VertexGroup := ST(name="Vertex Group", bl_idname="StringSocket", is_input=True),
+    MorphTarget := ST(name="Morph Target", bl_idname="MorphTargetSocket", is_input=False),
 ]
 ]
 
 
 SurfaceDeformSockets= [
 SurfaceDeformSockets= [
     DeformerInput,
     DeformerInput,
     SurfaceDeformTarget := replace(Target, name="Target",),
     SurfaceDeformTarget := replace(Target, name="Target",),
-    Falloff := SockTemplate(name="Falloff", bl_idname='FloatSocket',
+    Falloff := ST(name="Falloff", bl_idname='FloatSocket',
         is_input=True, default_value=4.0, blender_property="falloff", ),
         is_input=True, default_value=4.0, blender_property="falloff", ),
     Strength := replace(Influence, name="Strength", bl_idname='FloatSocket',
     Strength := replace(Influence, name="Strength", bl_idname='FloatSocket',
         is_input=True, default_value=1.0, blender_property='strength'),
         is_input=True, default_value=1.0, blender_property='strength'),
-    SparseBind := SockTemplate(name="Sparse Bind", bl_idname='BooleanSocket',
+    SparseBind := ST(name="Sparse Bind", bl_idname='BooleanSocket',
         is_input=True, default_value=False, blender_property="use_sparse_bind"),
         is_input=True, default_value=False, blender_property="use_sparse_bind"),
-    VertexGroup := SockTemplate(name="Vertex Group", bl_idname='StringSocket',
+    VertexGroup := ST(name="Vertex Group", bl_idname='StringSocket',
         is_input=True, default_value="", blender_property="vertex_group"),
         is_input=True, default_value="", blender_property="vertex_group"),
-    InvertVertexGroup := SockTemplate(name="Invert Vertex Group", bl_idname='BooleanSocket',
+    InvertVertexGroup := ST(name="Invert Vertex Group", bl_idname='BooleanSocket',
         is_input=True, default_value=False, blender_property="invert_vertex_group"),
         is_input=True, default_value=False, blender_property="invert_vertex_group"),
-    EnableViewportTemplate := SockTemplate(
+    EnableViewportTemplate := ST(
         name="Enable in Viewport", is_input=True,  bl_idname='EnableSocket',
         name="Enable in Viewport", is_input=True,  bl_idname='EnableSocket',
         default_value=True, blender_property='show_viewport'),
         default_value=True, blender_property='show_viewport'),
-    EnableRenderTemplate := SockTemplate(
+    EnableRenderTemplate := ST(
         name="Enable in Render", is_input=True,  bl_idname='BooleanSocket',
         name="Enable in Render", is_input=True,  bl_idname='BooleanSocket',
         default_value=True, blender_property='show_render'),
         default_value=True, blender_property='show_render'),
     DeformerOutput,
     DeformerOutput,
 ]
 ]
 
 
 MeshDeformSockets= [
 MeshDeformSockets= [
-    DeformerInput := SockTemplate(name="Deformer", bl_idname='DeformerSocket',
+    DeformerInput := ST(name="Deformer", bl_idname='DeformerSocket',
         is_input=True,),
         is_input=True,),
     MeshDeformTarget := replace(Target, name="Object",),
     MeshDeformTarget := replace(Target, name="Object",),
-    MeshDeformPrecision := SockTemplate(name="Precision", bl_idname='UnsignedIntSocket',
+    MeshDeformPrecision := ST(name="Precision", bl_idname='UnsignedIntSocket',
         is_input=True, default_value=4, blender_property="precision"),
         is_input=True, default_value=4, blender_property="precision"),
-    DynamicBind := SockTemplate(name="Dynamic Bind", bl_idname='BooleanSocket',
+    DynamicBind := ST(name="Dynamic Bind", bl_idname='BooleanSocket',
         is_input=True, default_value=False, blender_property="use_dynamic_bind"),
         is_input=True, default_value=False, blender_property="use_dynamic_bind"),
     VertexGroup,
     VertexGroup,
     InvertVertexGroup,
     InvertVertexGroup,
@@ -63,7 +96,7 @@ MeshDeformSockets= [
 ]
 ]
 
 
 LatticeDeformSockets = [
 LatticeDeformSockets = [
-    DeformerInput := SockTemplate(name="Deformer", bl_idname='DeformerSocket',
+    DeformerInput := ST(name="Deformer", bl_idname='DeformerSocket',
         is_input=True,),
         is_input=True,),
     LatticeDeformTarget := replace(Target, name="Object",),
     LatticeDeformTarget := replace(Target, name="Object",),
     Strength := replace(Strength, bl_idname='FloatFactorSocket',),
     Strength := replace(Strength, bl_idname='FloatFactorSocket',),
@@ -78,15 +111,15 @@ SmoothDeformSockets = [
     DeformerInput,
     DeformerInput,
     Factor := replace(Influence, name="Factor", bl_idname='FloatSocket',
     Factor := replace(Influence, name="Factor", bl_idname='FloatSocket',
                         default_value=0.5, blender_property='factor'),
                         default_value=0.5, blender_property='factor'),
-    iterations := SockTemplate(name='Iterations', bl_idname="UnsignedIntSocket",
+    iterations := ST(name='Iterations', bl_idname="UnsignedIntSocket",
             is_input=True, default_value=4, blender_property='iterations'),
             is_input=True, default_value=4, blender_property='iterations'),
-    SmoothType :=SockTemplate(name="Smoothing Type", bl_idname="EnumCorrectiveSmoothTypeSocket", 
+    SmoothType :=ST(name="Smoothing Type", bl_idname="EnumCorrectiveSmoothTypeSocket", 
               is_input=True, blender_property="smooth_type" ),
               is_input=True, blender_property="smooth_type" ),
-    PinBoundary := SockTemplate(name="Pin Boundary", bl_idname="BooleanSocket",
+    PinBoundary := ST(name="Pin Boundary", bl_idname="BooleanSocket",
             is_input=True, default_value=False, blender_property="use_pin_boundary"),
             is_input=True, default_value=False, blender_property="use_pin_boundary"),
-    OnlySmooth := SockTemplate(name="Use Corrective Smooth", bl_idname="InvertedBooleanSocket",
+    OnlySmooth := ST(name="Use Corrective Smooth", bl_idname="InvertedBooleanSocket",
             is_input=True, default_value=True, blender_property="use_only_smooth"),
             is_input=True, default_value=True, blender_property="use_only_smooth"),
-    DeltaMushScale := SockTemplate(name="Corrective Smooth Scale", bl_idname="FloatSocket",
+    DeltaMushScale := ST(name="Corrective Smooth Scale", bl_idname="FloatSocket",
             is_input=True, default_value=1.0, blender_property="scale", category='corrective_smooth' ),
             is_input=True, default_value=1.0, blender_property="scale", category='corrective_smooth' ),
     VertexGroup,
     VertexGroup,
     InvertVertexGroup,
     InvertVertexGroup,

+ 2 - 0
mantis_dataclasses.py

@@ -14,7 +14,9 @@ class MantisSocketTemplate():
     is_input         : bool = field(default=False)
     is_input         : bool = field(default=False)
     hide             : bool = field(default=False)
     hide             : bool = field(default=False)
     use_multi_input  : bool = field(default=False)
     use_multi_input  : bool = field(default=False)
+    ui_only          : bool = field(default=False)
     default_value    : Any = field(default=None)
     default_value    : Any = field(default=None)
+    # TODO: add versioning fields for Mantis, Blender version min/max
 
 
 @dataclass
 @dataclass
 class xForm_info():
 class xForm_info():

+ 8 - 42
math_nodes.py

@@ -1,5 +1,6 @@
 from .node_common import *
 from .node_common import *
-from .base_definitions import MantisNode, NodeSocket
+from .base_definitions import MantisNode
+from .math_nodes_socket_templates import *
 
 
 def TellClasses():
 def TellClasses():
     return [
     return [
@@ -53,19 +54,8 @@ class MathStaticInt(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Operation",
-          "Int A",
-          "Int B",
-        ]
-        outputs = [
-          "Result Int",
-        ]
-        additional_parameters = {}
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
-        self.init_parameters(additional_parameters=additional_parameters)
+        super().__init__(signature, base_tree, StaticIntSockets)
+        self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
     def bPrepare(self, bContext = None,):
     def bPrepare(self, bContext = None,):
@@ -78,19 +68,8 @@ class MathStaticFloat(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Operation",
-          "Float A",
-          "Float B",
-        ]
-        outputs = [
-          "Result Float",
-        ]
-        additional_parameters = {}
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
-        self.init_parameters(additional_parameters=additional_parameters)
+        super().__init__(signature, base_tree, StaticFloatSockets)
+        self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
     def bPrepare(self, bContext = None,):
     def bPrepare(self, bContext = None,):
@@ -103,21 +82,8 @@ class MathStaticVector(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Operation",
-          "Vector A",
-          "Vector B",
-          "Scalar A",
-        ]
-        outputs = [
-          "Result Vector",
-          "Result Float",
-        ]
-        additional_parameters = {}
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
-        self.init_parameters(additional_parameters=additional_parameters)
+        super().__init__(signature, base_tree, StaticVectorSockets)
+        self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
     def bPrepare(self, bContext = None,):
     def bPrepare(self, bContext = None,):

+ 26 - 0
math_nodes_socket_templates.py

@@ -0,0 +1,26 @@
+from .base_definitions import MantisSocketTemplate as ST
+from dataclasses import replace
+
+
+StaticIntSockets = [
+    Operation := ST(name="Operation", bl_idname="MathFloatOperation", is_input=True),
+    IntA := ST(name="Int A", bl_idname="IntSocket", is_input=True),
+    IntB := ST(name="Int B", bl_idname="IntSocket", is_input=True),
+    ResultInt := ST(name="Result Int", bl_idname="IntSocket", is_input=False),
+]
+
+StaticFloatSockets = [
+    Operation,
+    FloatA := ST(name="Float A", bl_idname="FloatSocket", is_input=True),
+    FloatB := ST(name="Float B", bl_idname="FloatSocket", is_input=True),
+    ResultFloat := ST(name="Result Float", bl_idname="FloatSocket", is_input=False),
+]
+
+StaticVectorSockets = [
+    Operation := ST(name="Operation", bl_idname="MathVectorOperation", is_input=True),
+    VectorA := ST(name="Vector A", bl_idname="VectorSocket", is_input=True),
+    VectorB := ST(name="Vector B", bl_idname="VectorSocket", is_input=True),
+    ScalarA := ST(name="Scalar A", bl_idname="FloatSocket", is_input=True, hide=True),
+    ResultVector := ST(name="Result Vector", bl_idname="VectorSocket", is_input=False),
+    ResultFloat := ST(name="Result Float", bl_idname="FloatSocket", is_input=False, hide=True),
+]

+ 5 - 21
math_nodes_ui.py

@@ -7,17 +7,16 @@ from .utilities import (prRed, prGreen, prPurple, prWhite,
                               wrapOrange,)
                               wrapOrange,)
 from .base_definitions import get_signature_from_edited_tree
 from .base_definitions import get_signature_from_edited_tree
 
 
+from .math_nodes_socket_templates import *
 
 
 def TellClasses():
 def TellClasses():
     return [
     return [
      MathStaticInt,
      MathStaticInt,
      MathStaticFloatNode,
      MathStaticFloatNode,
      MathStaticVectorNode,
      MathStaticVectorNode,
-        ]
+    ]
 
 
 
 
-        
-
 class MathStaticInt(Node, MantisUINode):
 class MathStaticInt(Node, MantisUINode):
     """A node that performs mathematical operations on float numbers as a preprocess step before generating the rig."""
     """A node that performs mathematical operations on float numbers as a preprocess step before generating the rig."""
     bl_idname = "MathStaticInt"
     bl_idname = "MathStaticInt"
@@ -28,12 +27,8 @@ class MathStaticInt(Node, MantisUINode):
 
 
 
 
     def init(self, context):
     def init(self, context):
-        self.inputs.new("MathFloatOperation", "Operation")
-        self.inputs.new("IntSocket", "Int A")
-        self.inputs.new("IntSocket", "Int B")
-        self.outputs.new("IntSocket", "Result Int")
+        self.init_sockets(StaticIntSockets)
         self.initialized = True
         self.initialized = True
-    
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         if context.space_data:
         if context.space_data:
@@ -45,7 +40,6 @@ class MathStaticInt(Node, MantisUINode):
             else:
             else:
                 self.inputs["Int B"].hide = False
                 self.inputs["Int B"].hide = False
 
 
-# do... make the operations now
 class MathStaticFloatNode(Node, MantisUINode):
 class MathStaticFloatNode(Node, MantisUINode):
     """A node that performs mathematical operations on float numbers as a preprocess step before generating the rig."""
     """A node that performs mathematical operations on float numbers as a preprocess step before generating the rig."""
     bl_idname = "MathStaticFloat"
     bl_idname = "MathStaticFloat"
@@ -54,14 +48,9 @@ class MathStaticFloatNode(Node, MantisUINode):
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
 
 
-
     def init(self, context):
     def init(self, context):
-        self.inputs.new("MathFloatOperation", "Operation")
-        self.inputs.new("FloatSocket", "Float A")
-        self.inputs.new("FloatSocket", "Float B")
-        self.outputs.new("FloatSocket", "Result Float")
+        self.init_sockets(StaticFloatSockets)
         self.initialized = True
         self.initialized = True
-    
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         if context.space_data:
         if context.space_data:
@@ -82,12 +71,7 @@ class MathStaticVectorNode(Node, MantisUINode):
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
-        self.inputs.new("MathVectorOperation", "Operation")
-        self.inputs.new("VectorSocket", "Vector A")
-        self.inputs.new("VectorSocket", "Vector B")
-        h = self.inputs.new("FloatSocket", "Scalar A"); h.hide=True
-        self.outputs.new("VectorSocket", "Result Vector")
-        h = self.outputs.new("FloatSocket", "Result Float"); h.hide=True
+        self.init_sockets(StaticVectorSockets)
         self.initialized = True
         self.initialized = True
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):

+ 62 - 396
misc_nodes.py

@@ -214,83 +214,62 @@ class InputFloat(SimpleInputNode):
     '''A node representing float input'''
     '''A node representing float input'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = ["Float Input"]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputFloatSockets)
         self.init_parameters()
         self.init_parameters()
 
 
 class InputIntNode(SimpleInputNode):
 class InputIntNode(SimpleInputNode):
     '''A node representing integer input'''
     '''A node representing integer input'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = ["Integer"]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputIntSockets)
         self.init_parameters()
         self.init_parameters()
 
 
 class InputVector(SimpleInputNode):
 class InputVector(SimpleInputNode):
     '''A node representing vector input'''
     '''A node representing vector input'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = [""]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputVectorSockets)
         self.init_parameters()
         self.init_parameters()
 
 
 class InputBoolean(SimpleInputNode):
 class InputBoolean(SimpleInputNode):
     '''A node representing boolean input'''
     '''A node representing boolean input'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = [""]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputBooleanSockets)
         self.init_parameters()
         self.init_parameters()
 
 
 class InputBooleanThreeTuple(SimpleInputNode):
 class InputBooleanThreeTuple(SimpleInputNode):
     '''A node representing a tuple of three booleans'''
     '''A node representing a tuple of three booleans'''
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = [""]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputBooleanThreeTupleSockets)
         self.init_parameters()
         self.init_parameters()
 
 
 class InputRotationOrder(SimpleInputNode):
 class InputRotationOrder(SimpleInputNode):
     '''A node representing string input for rotation order'''
     '''A node representing string input for rotation order'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = [""]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputRotationOrderSockets)
         self.init_parameters()
         self.init_parameters()
 
 
 class InputTransformSpace(SimpleInputNode):
 class InputTransformSpace(SimpleInputNode):
     '''A node representing string input for transform space'''
     '''A node representing string input for transform space'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = [""]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputTransformSpaceSockets)
         self.init_parameters()
         self.init_parameters()
 
 
-    def evaluate_input(self, input_name):
-        return self.parameters[""]
-
 class InputString(SimpleInputNode):
 class InputString(SimpleInputNode):
     '''A node representing string input'''
     '''A node representing string input'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = [""]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputStringSockets)
         self.init_parameters()
         self.init_parameters()
 
 
 class InputMatrix(SimpleInputNode):
 class InputMatrix(SimpleInputNode):
     '''A node representing axis-angle quaternion input'''
     '''A node representing axis-angle quaternion input'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs  = ["Matrix",]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputMatrixSockets)
         self.init_parameters()
         self.init_parameters()
 
 
 class InputThemeBoneColorSets(SimpleInputNode):
 class InputThemeBoneColorSets(SimpleInputNode):
@@ -554,16 +533,7 @@ class UtilityMatricesFromCurve(MantisNode):
 
 
 class UtilityNumberOfCurveSegments(MantisNode):
 class UtilityNumberOfCurveSegments(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Curve"            ,
-          "Spline Index"     ,
-        ]
-        outputs = [
-          "Number of Segments" ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, NumberOfCurveSegmentsSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -704,19 +674,7 @@ class UtilityGetNearestFactorOnCurve(MantisNode):
 
 
 class UtilityKDChoosePoint(MantisNode):
 class UtilityKDChoosePoint(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Reference Point"  ,
-          "Points"           ,
-          "Number to Find"   ,
-        ]
-        outputs = [
-          "Result Point"     ,
-          "Result Index"     ,
-          "Result Distance"  ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, KDChoosePointSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
         self.rerouted=[]
         self.rerouted=[]
@@ -742,20 +700,7 @@ class UtilityKDChoosePoint(MantisNode):
 
 
 class UtilityKDChooseXForm(MantisNode):
 class UtilityKDChooseXForm(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Reference Point"      ,
-          "xForm Nodes"          ,
-          "Get Point Head/Tail"  ,
-          "Number to Find"       ,
-        ]
-        outputs = [
-          "Result xForm"     ,
-          "Result Index"     ,
-          "Result Distance"  ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, KDChooseXFormSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
         self.rerouted=[]
         self.rerouted=[]
@@ -794,16 +739,7 @@ class UtilityMetaRig(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Meta-Armature" ,
-          "Meta-Bone"     ,
-        ]
-        outputs = [
-          "Matrix" ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, MetaRigSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -845,19 +781,7 @@ class UtilityBoneProperties(SimpleInputNode):
     '''A node representing a bone's gettable properties'''
     '''A node representing a bone's gettable properties'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = [
-            "matrix"        ,
-            "matrix_local"  ,
-            "matrix_basis"  ,
-            "head"          ,
-            "tail"          ,
-            "length"        ,
-            "rotation"      ,
-            "location"      ,
-            "scale"         ,
-        ]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, BonePropertiesSockets)
         self.init_parameters()
         self.init_parameters()
 
 
     def fill_parameters(self, ui_node=None):
     def fill_parameters(self, ui_node=None):
@@ -868,21 +792,7 @@ class UtilityDriverVariable(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-            "Variable Type"   ,
-            "Property"       ,
-            "Property Index" ,
-            "Evaluation Space",
-            "Rotation Mode"   ,
-            "xForm 1"         ,
-            "xForm 2"         ,
-        ]
-        outputs = [
-          "Driver Variable",
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, DriverVariableSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "DRIVER" # MUST be run in Pose mode
         self.node_type = "DRIVER" # MUST be run in Pose mode
         self.prepared = True
         self.prepared = True
@@ -965,18 +875,11 @@ class UtilityKeyframe(MantisNode):
     '''A node representing a keyframe for a F-Curve'''
     '''A node representing a keyframe for a F-Curve'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Frame"   ,
-          "Value"   ,
-        ]
-        outputs = [
-          "Keyframe" ,
-        ]
+        super().__init__(signature, base_tree, KeyframeSockets)
         additional_parameters = {"Keyframe":{}}
         additional_parameters = {"Keyframe":{}}
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
         self.init_parameters( additional_parameters=additional_parameters)
         self.init_parameters( additional_parameters=additional_parameters)
+        # I think both of these are wrong.
+        # TODO: try UTILITY type and remove setup_custom_property stuff
         self.node_type = "DRIVER" # MUST be run in Pose mode
         self.node_type = "DRIVER" # MUST be run in Pose mode
         setup_custom_property_inputs_outputs(self)
         setup_custom_property_inputs_outputs(self)
 
 
@@ -995,15 +898,7 @@ class UtilityFCurve(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-            "Extrapolation Mode",
-        ]
-        outputs = [
-          "fCurve",
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, FCurveSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
         setup_custom_property_inputs_outputs(self)
         setup_custom_property_inputs_outputs(self)
@@ -1040,21 +935,11 @@ class UtilityDriver(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Driver Type"   ,
-          "Expression"    ,
-          "fCurve"        ,
-        ]
-        outputs = [
-          "Driver",
-        ]
+        super().__init__(signature, base_tree, DriverSockets)
         from .drivers import MantisDriver
         from .drivers import MantisDriver
         additional_parameters = {
         additional_parameters = {
           "Driver":MantisDriver(),
           "Driver":MantisDriver(),
         }
         }
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
         self.init_parameters(additional_parameters=additional_parameters)
         self.init_parameters(additional_parameters=additional_parameters)
         self.node_type = "DRIVER" # MUST be run in Pose mode
         self.node_type = "DRIVER" # MUST be run in Pose mode
         setup_custom_property_inputs_outputs(self)
         setup_custom_property_inputs_outputs(self)
@@ -1105,21 +990,11 @@ class UtilitySwitch(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = {
-          "Parameter"            ,
-          "Parameter Index"      ,
-          "Invert Switch"        ,
-        }
-        outputs = [
-          "Driver",
-        ]
+        super().__init__(signature, base_tree, SwitchSockets)
         from .drivers import MantisDriver
         from .drivers import MantisDriver
         additional_parameters = {
         additional_parameters = {
           "Driver":MantisDriver(),
           "Driver":MantisDriver(),
         }
         }
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
         self.init_parameters(additional_parameters=additional_parameters)
         self.init_parameters(additional_parameters=additional_parameters)
         self.node_type = "DRIVER" # MUST be run in Pose mode
         self.node_type = "DRIVER" # MUST be run in Pose mode
         self.prepared = True
         self.prepared = True
@@ -1191,17 +1066,7 @@ class UtilityCombineThreeBool(MantisNode):
     '''A node for combining three booleans into a boolean three-tuple'''
     '''A node for combining three booleans into a boolean three-tuple'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "X"   ,
-          "Y"   ,
-          "Z"   ,
-        ]
-        outputs = [
-          "Three-Bool",
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, CombineThreeBoolSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1225,18 +1090,7 @@ class UtilityCombineVector(MantisNode):
     '''A node for combining three floats into a vector'''
     '''A node for combining three floats into a vector'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        super().__init__(signature, base_tree)
-        inputs = [
-          "X"   ,
-          "Y"   ,
-          "Z"   ,
-        ]
-        outputs = [
-          "Vector",
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, CombineVectorSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1260,17 +1114,7 @@ class UtilitySeparateVector(MantisNode):
     '''A node for separating a vector into three floats'''
     '''A node for separating a vector into three floats'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Vector"
-        ]
-        outputs = [
-          "X"   ,
-          "Y"   ,
-          "Z"   ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, SeparateVectorSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1284,16 +1128,7 @@ class UtilityCatStrings(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "String_1"   ,
-          "String_2"   ,
-        ]
-        outputs = [
-          "OutputString" ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, CatStringsSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1393,15 +1228,7 @@ class InputExistingGeometryObject(MantisNode):
     '''A node representing an existing object'''
     '''A node representing an existing object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Name"  ,
-        ]
-        outputs = [
-          "Object" ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputExistingGeometryObjectSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "XFORM"
         self.node_type = "XFORM"
 
 
@@ -1426,15 +1253,7 @@ class InputExistingGeometryData(MantisNode):
     '''A node representing existing object data'''
     '''A node representing existing object data'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Name"  ,
-        ]
-        outputs = [
-          "Geometry" ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, InputExistingGeometrySockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
         self.prepared = True; self.executed = True
         self.prepared = True; self.executed = True
@@ -1457,6 +1276,8 @@ class InputExistingGeometryData(MantisNode):
 class UtilityDeclareCollections(MantisNode):
 class UtilityDeclareCollections(MantisNode):
     '''A node to help manage bone collections'''
     '''A node to help manage bone collections'''
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
+        # NOTE this one does not use socket template because it is special.
+        # The user creates all the sockets for this one.
         super().__init__(signature, base_tree)
         super().__init__(signature, base_tree)
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
         self.prepared, self.executed = True, True
         self.prepared, self.executed = True, True
@@ -1537,15 +1358,7 @@ class UtilityCollectionHierarchy(MantisNode):
 class UtilityGeometryOfXForm(MantisNode):
 class UtilityGeometryOfXForm(MantisNode):
     '''A node representing existing object data'''
     '''A node representing existing object data'''
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "xForm"  ,
-        ]
-        outputs = [
-          "Geometry" ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, GeometryOfXFormSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
         self.prepared = True
         self.prepared = True
@@ -1571,15 +1384,7 @@ class UtilityGeometryOfXForm(MantisNode):
 class UtilityNameOfXForm(MantisNode):
 class UtilityNameOfXForm(MantisNode):
     '''A node representing existing object data'''
     '''A node representing existing object data'''
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "xForm"  ,
-        ]
-        outputs = [
-          "Name" ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, NameOfXFormSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1596,15 +1401,7 @@ class UtilityGetBoneLength(MantisNode):
     '''A node to get the length of a bone matrix'''
     '''A node to get the length of a bone matrix'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Bone Matrix" ,
-        ]
-        outputs = [
-          "Bone Length" ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, GetBoneLengthSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1620,16 +1417,7 @@ class UtilityPointFromBoneMatrix(MantisNode):
     '''A node representing an armature object'''
     '''A node representing an armature object'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Bone Matrix"   ,
-          "Head/Tail"     ,
-        ]
-        outputs = [
-          "Point"     ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, PointFromBoneMatrixSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1646,16 +1434,7 @@ class UtilitySetBoneLength(MantisNode):
     '''Sets the length of a Bone's matrix'''
     '''Sets the length of a Bone's matrix'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Bone Matrix"   ,
-          "Length"        ,
-        ]
-        outputs = [
-          "Bone Matrix"   ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, SetBoneLengthSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1675,16 +1454,7 @@ class UtilityMatrixSetLocation(MantisNode):
     '''Sets the location of a matrix'''
     '''Sets the location of a matrix'''
 
 
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Matrix"        ,
-          "Location"      ,
-        ]
-        outputs = [
-          "Matrix"        ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, MatrixSetLocationSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1701,15 +1471,7 @@ class UtilityMatrixSetLocation(MantisNode):
 class UtilityMatrixGetLocation(MantisNode):
 class UtilityMatrixGetLocation(MantisNode):
     '''Gets the location of a matrix'''
     '''Gets the location of a matrix'''
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Matrix"        ,
-        ]
-        outputs = [
-          "Location"    ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, MatrixGetLocationSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1722,16 +1484,8 @@ class UtilityMatrixGetLocation(MantisNode):
 class UtilityMatrixFromXForm(MantisNode):
 class UtilityMatrixFromXForm(MantisNode):
     """Returns the matrix of the given xForm node."""
     """Returns the matrix of the given xForm node."""
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "xForm"        ,
-        ]
-        outputs = [
-          "Matrix"       ,
-        ]
+        super().__init__(signature, base_tree, MatrixFromXFormSockets)
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
         self.init_parameters()
         self.init_parameters()
 
 
     def GetxForm(self):
     def GetxForm(self):
@@ -1757,17 +1511,7 @@ class UtilityMatrixFromXForm(MantisNode):
 class UtilityAxesFromMatrix(MantisNode):
 class UtilityAxesFromMatrix(MantisNode):
     """Returns the axes of the given matrix."""
     """Returns the axes of the given matrix."""
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Matrix"       ,
-        ]
-        outputs = [
-          "X Axis"      ,
-          "Y Axis"      ,
-          "Z Axis"      ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, AxesFromMatrixSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1782,15 +1526,7 @@ class UtilityAxesFromMatrix(MantisNode):
 
 
 class UtilityBoneMatrixHeadTailFlip(MantisNode):
 class UtilityBoneMatrixHeadTailFlip(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Bone Matrix"     ,
-        ]
-        outputs = [
-          "Bone Matrix"     ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, BoneMatrixHeadTailFlipSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1811,16 +1547,7 @@ class UtilityBoneMatrixHeadTailFlip(MantisNode):
 
 
 class UtilityMatrixTransform(MantisNode):
 class UtilityMatrixTransform(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Matrix 1"   ,
-          "Matrix 2"   ,
-        ]
-        outputs = [
-          "Out Matrix"    ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, MatrixTransformSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1913,17 +1640,7 @@ class UtilityMatrixAlignRoll(MantisNode):
 
 
 class UtilityTransformationMatrix(MantisNode):
 class UtilityTransformationMatrix(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Operation"   ,
-          "Vector"      ,
-          "W"           ,
-        ]
-        outputs = [
-          "Matrix"    ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, TransformationMatrixSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -1945,22 +1662,12 @@ class UtilityTransformationMatrix(MantisNode):
 
 
 class UtilityIntToString(MantisNode):
 class UtilityIntToString(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Number"         ,
-          "Zero Padding"   ,
-        ]
-        outputs = [
-          "String"         ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, IntToStringSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
     def bPrepare(self, bContext = None,):
     def bPrepare(self, bContext = None,):
         number = self.evaluate_input("Number")
         number = self.evaluate_input("Number")
-
         zeroes = self.evaluate_input("Zero Padding")
         zeroes = self.evaluate_input("Zero Padding")
         # I'm casting to int because I want to support any number, even though the node asks for int.
         # I'm casting to int because I want to support any number, even though the node asks for int.
         self.parameters["String"] = str(int(number)).zfill(int(zeroes))
         self.parameters["String"] = str(int(number)).zfill(int(zeroes))
@@ -1968,17 +1675,7 @@ class UtilityIntToString(MantisNode):
 
 
 class UtilityArrayGet(MantisNode):
 class UtilityArrayGet(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Index"           ,
-          "OoB Behaviour"   ,
-          "Array"           ,
-        ]
-        outputs = [
-          "Output"          ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, ArrayGetSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
         self.rerouted=[]
         self.rerouted=[]
@@ -2006,15 +1703,7 @@ class UtilityArrayGet(MantisNode):
 
 
 class UtilityArrayLength(MantisNode):
 class UtilityArrayLength(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Array"           ,
-        ]
-        outputs = [
-          "Length"          ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, UtilityArrayLengthSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -2024,16 +1713,7 @@ class UtilityArrayLength(MantisNode):
 
 
 class UtilitySetBoneMatrixTail(MantisNode):
 class UtilitySetBoneMatrixTail(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = {
-          "Matrix"        ,
-          "Tail Location" ,
-        }
-        outputs = [
-          "Result"       ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, SetBoneMatrixTailSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -2045,26 +1725,6 @@ class UtilitySetBoneMatrixTail(MantisNode):
         self.parameters["Result"] = matrix_from_head_tail(matrix.translation, self.evaluate_input("Tail Location"))
         self.parameters["Result"] = matrix_from_head_tail(matrix.translation, self.evaluate_input("Tail Location"))
         self.prepared = True; self.executed = True
         self.prepared = True; self.executed = True
 
 
-class UtilityPrint(MantisNode):
-    def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Input"         ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.init_parameters()
-        self.node_type = "UTILITY"
-
-    def bPrepare(self, bContext = None,):
-        if my_input := self.evaluate_input("Input"):
-            print("Preparation phase: ", wrapWhite(self), wrapGreen(my_input))
-        self.prepared = True
-
-    def bTransformPass(self, bContext = None,):
-        if my_input := self.evaluate_input("Input"):
-            print("Execution phase: ", wrapWhite(self), wrapGreen(my_input))
-        self.executed = True
-
 class UtilityCompare(MantisNode):
 class UtilityCompare(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, CompareSockets)
         super().__init__(signature, base_tree, CompareSockets)
@@ -2100,17 +1760,7 @@ class UtilityCompare(MantisNode):
 
 
 class UtilityChoose(MantisNode):
 class UtilityChoose(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-          "Condition"   ,
-          "A"           ,
-          "B"           ,
-        ]
-        outputs = [
-          "Result"      ,
-        ]
-        self.inputs.init_sockets(inputs)
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, ChooseSockets)
         self.init_parameters()
         self.init_parameters()
         self.node_type = "UTILITY"
         self.node_type = "UTILITY"
 
 
@@ -2138,3 +1788,19 @@ class UtilityChoose(MantisNode):
             else:
             else:
                 raise GraphError(f"Choose Node {self} has incorrect types.")
                 raise GraphError(f"Choose Node {self} has incorrect types.")
         self.prepared = True; self.executed = True
         self.prepared = True; self.executed = True
+
+class UtilityPrint(MantisNode):
+    def __init__(self, signature, base_tree):
+        super().__init__(signature, base_tree, PrintSockets)
+        self.init_parameters()
+        self.node_type = "UTILITY"
+
+    def bPrepare(self, bContext = None,):
+        if my_input := self.evaluate_input("Input"):
+            print("Preparation phase: ", wrapWhite(self), wrapGreen(my_input))
+        self.prepared = True
+
+    def bTransformPass(self, bContext = None,):
+        if my_input := self.evaluate_input("Input"):
+            print("Execution phase: ", wrapWhite(self), wrapGreen(my_input))
+        self.executed = True

+ 382 - 90
misc_nodes_socket_templates.py

@@ -1,34 +1,64 @@
-from .mantis_dataclasses import MantisSocketTemplate as SockTemplate
+from .mantis_dataclasses import MantisSocketTemplate as ST
 from dataclasses import replace
 from dataclasses import replace
 
 
-SplineIndexTemplate = SockTemplate(name="Spline Index",
+# reused templates
+SplineIndexTemplate = ST(name="Spline Index",
         bl_idname='UnsignedIntSocket', is_input=True, default_value=0,)
         bl_idname='UnsignedIntSocket', is_input=True, default_value=0,)
+FactorTemplate = ST(name="Factor", bl_idname='FloatFactorSocket', is_input=True,)
+MatrixOutput = ST( name="Matrix", is_input=False, bl_idname='MatrixSocket', )
+MatricesOutTemplate = replace(MatrixOutput, name='Matrices', use_multi_input=True)
+StringOutput = ST( name="String", is_input=False, bl_idname='StringSocket', )
+MatrixInput = replace(MatrixOutput, is_input=True)
+VectorOutput = ST(name="Vector", bl_idname="VectorSocket", is_input=False)
+VectorInput = replace(VectorOutput, is_input = True)
 
 
-InputWidgetSockets = [
-    WidgetName := SockTemplate(name='Name', is_input=True,
-        bl_idname="EnumWidgetLibrarySocket",),
-    Scale := SockTemplate(name='Scale', is_input=True,
-        bl_idname="VectorScaleSocket", default_value=(1.0, 1.0, 1.0)),
-    FlipAxes := SockTemplate(name='Flip Axes', is_input=True,
-        bl_idname="BooleanThreeTupleSocket",),
-    xFormOutput := SockTemplate(name='Widget',
-        bl_idname='xFormSocket',is_input=False),
+# input classes
+InputFloatSockets = [
+    FloatInput := ST(name='Float Input',
+        bl_idname='FloatSocket', is_input=False),
+]
+InputIntSockets = [
+    IntInput := ST(name='Integer',
+        bl_idname='IntSocket', is_input=False),
+]
+InputVectorSockets = [
+    replace(VectorOutput, name='',),
+]
+InputBooleanSockets = [
+    BoolInput := ST(name='',
+        bl_idname='BooleanSocket', is_input=False),
+]
+InputBooleanThreeTupleSockets = [
+    BoolThreeTupleInput := ST(name='',
+        bl_idname='BooleanThreeTupleSocket', is_input=False),
+]
+InputRotationOrderSockets = [
+    RotationOrderInput := ST(name='',
+        bl_idname='RotationOrderSocket', is_input=False),
+]
+InputTransformSpaceSockets = [
+    TransformSpaceInput := ST(name='',
+        bl_idname='TransformSpaceSocket', is_input=False),
+]
+InputStringSockets = [
+    StringInput := ST(name='', bl_idname='StringSocket',
+        is_input=False),
+]
+InputMatrixSockets = [
+    MatrixOutput
 ]
 ]
 
 
 MatrixFromCurveSockets=[
 MatrixFromCurveSockets=[
-    CurveTemplate := SockTemplate(name="Curve", bl_idname='EnumCurveSocket', 
+    CurveTemplate := ST(name="Curve", bl_idname='EnumCurveSocket', 
         is_input=True,),
         is_input=True,),
     SplineIndexTemplate,
     SplineIndexTemplate,
-    TotalDivisionsTemplate := SockTemplate(name="Total Divisions",
+    TotalDivisionsTemplate := ST(name="Total Divisions",
         bl_idname='UnsignedIntSocket', is_input=True, default_value=0,),
         bl_idname='UnsignedIntSocket', is_input=True, default_value=0,),
-    MatrixIndexTemplate := SockTemplate(name="Matrix Index",
+    MatrixIndexTemplate := ST(name="Matrix Index",
         bl_idname='UnsignedIntSocket', is_input=True, default_value=0,),
         bl_idname='UnsignedIntSocket', is_input=True, default_value=0,),
-    MatrixOutTemplate := SockTemplate(
-        name="Matrix", is_input=False,  bl_idname='MatrixSocket', ),
+    MatrixOutput,
 ]
 ]
 
 
-MatricesOutTemplate = replace(MatrixOutTemplate,
-        name='Matrices', use_multi_input=True)
 MatricesFromCurveSockets=MatrixFromCurveSockets.copy()
 MatricesFromCurveSockets=MatrixFromCurveSockets.copy()
 MatricesFromCurveSockets[4] = MatricesOutTemplate
 MatricesFromCurveSockets[4] = MatricesOutTemplate
 MatricesFromCurveSockets.pop(3)
 MatricesFromCurveSockets.pop(3)
@@ -37,142 +67,404 @@ MatrixFromCurveSegmentSockets=[
     CurveTemplate,
     CurveTemplate,
     SplineIndexTemplate,
     SplineIndexTemplate,
     SegmentIndexTemplate := replace(SplineIndexTemplate, name="Segment Index"),
     SegmentIndexTemplate := replace(SplineIndexTemplate, name="Segment Index"),
-    MatrixOutTemplate,
+    MatrixOutput,
 ]
 ]
 
 
 PointFromCurveSockets=[
 PointFromCurveSockets=[
     CurveTemplate,
     CurveTemplate,
     SplineIndexTemplate,
     SplineIndexTemplate,
-    FactorTemplate := SockTemplate(name="Factor", bl_idname='FloatFactorSocket', 
-        is_input=True,),
-    PointOutTemplate := SockTemplate(name="Point", bl_idname="VectorSocket",
+    FactorTemplate,
+    PointOutTemplate := ST(name="Point", bl_idname="VectorSocket",
         is_input=False, )
         is_input=False, )
 ]
 ]
 
 
+NumberOfCurveSegmentsSockets = [
+    CurveTemplate,
+    SplineIndexTemplate,
+    NumberOfSegments := ST(name='Number of Segments',
+        bl_idname='UnsignedIntSocket', is_input=False),
+]
+
 GetCurvePointSockets=[
 GetCurvePointSockets=[
     CurveTemplate,
     CurveTemplate,
     SplineIndexTemplate,
     SplineIndexTemplate,
-    IndexTemplate := SockTemplate(name="Index",
+    IndexTemplate := ST(name="Index",
         bl_idname='UnsignedIntSocket', is_input=True, default_value=0,),
         bl_idname='UnsignedIntSocket', is_input=True, default_value=0,),
-    OutputPointTemplate := SockTemplate(name="Point",
+    OutputPointTemplate := ST(name="Point",
         bl_idname='VectorSocket', is_input=False,),
         bl_idname='VectorSocket', is_input=False,),
-    OutputLeftHandleTemplate := SockTemplate(name="Left Handle",
+    OutputLeftHandleTemplate := ST(name="Left Handle",
         bl_idname='VectorSocket', is_input=False, hide=True),
         bl_idname='VectorSocket', is_input=False, hide=True),
-    OutputRightHandleTemplate := SockTemplate(name="Right Handle",
+    OutputRightHandleTemplate := ST(name="Right Handle",
         bl_idname='VectorSocket', is_input=False, hide=True),
         bl_idname='VectorSocket', is_input=False, hide=True),
 ]
 ]
 
 
 GetNearestFactorOnCurveSockets=[
 GetNearestFactorOnCurveSockets=[
     CurveTemplate,
     CurveTemplate,
     SplineIndexTemplate,
     SplineIndexTemplate,
-    ReferencePointTemplate := SockTemplate(name="Reference Point",
+    ReferencePointTemplate := ST(name="Reference Point",
         bl_idname='VectorSocket', is_input=True,),
         bl_idname='VectorSocket', is_input=True,),
-    OutputFactorTemplate := SockTemplate(name="Factor",
+    OutputFactorTemplate := ST(name="Factor",
         bl_idname='FloatSocket', is_input=False,),
         bl_idname='FloatSocket', is_input=False,),
 ]
 ]
 
 
-MatrixInvertSockets=[
-    Matrix1Template := SockTemplate(
-    name="Matrix 1", is_input=True,  bl_idname='MatrixSocket', ),
-    MatrixOutTemplate,
+KDChoosePointSockets = [
+    ReferencePointTemplate,
+    PointsArray := ST(name="Points", bl_idname="VectorSocket",
+        use_multi_input=True,  is_input=True),
+    NumberToFind := ST(name='Number to Find',
+        bl_idname = "UnsignedIntSocket", default_value=1,  is_input=True),
+    ResultPoint :=ST(name='Result Point', bl_idname="VectorSocket",
+        is_input=False, ),
+    ResultIndex :=ST(name='Result Index',
+        bl_idname="UnsignedIntSocket", is_input=False, ),
+    ResultDistance :=ST(name='Result Distance',
+        bl_idname="FloatSocket", is_input=False, ),
 ]
 ]
 
 
-MatrixComposeSockets=[
-    XBasisVector := SockTemplate(
-    name="X Basis Vector", is_input=True,  bl_idname='VectorSocket', 
-        default_value = (1.0, 0.0, 0.0) ),
-    YBasisVector := replace(XBasisVector, name="Y Basis Vector",
-        default_value = (0.0, 1.0, 0.0) ),
-    ZBasisVector := replace(XBasisVector, name="Z Basis Vector",
-        default_value = (0.0, 0.0, 1.0) ),
-    Translation := replace(XBasisVector, name="Translation"),
-    MatrixOutTemplate,
+KDChooseXFormSockets = [
+    ReferencePointTemplate,
+    xFormsArray := ST(name="xForm Nodes", bl_idname="xFormSocket",
+        use_multi_input=True, is_input=True,),
+    GetPointHeadTail := ST(name="Get Point Head/Tail",
+        bl_idname = "FloatFactorSocket",  is_input=True,),
+    NumberToFind,
+    ResultxForm := ST(name='Result xForm', bl_idname='xFormSocket', is_input=False),
+    ResultIndex,
+    ResultDistance,
 ]
 ]
 
 
-MatrixAlignRollSockets=[
-    MatrixInTemplate := replace(Matrix1Template, name="Matrix"),
-    AlignVector := SockTemplate(name="Alignment Vector", is_input=True,
-       bl_idname='VectorSocket', default_value=(0.0,-1.0,0.0)),
-    MatrixOutTemplate,
+MetaRigSockets = [
+    MetaArmature := ST(name='Meta-Armature', bl_idname="EnumMetaRigSocket",
+        is_input = True, ),
+    MetaBone := ST(name='Meta-Bone', bl_idname="EnumMetaBoneSocket",
+        is_input = True, hide=True ),
+    MatrixOutput,
 ]
 ]
 
 
-CompareSockets = [
-    ComparisonOperation := SockTemplate( name='Comparison',
-            is_input=True, bl_idname="EnumCompareOperation",
-            default_value="EQUAL",),
-    WildcardATemplate := SockTemplate(
-        name="A", is_input=True,  bl_idname='WildcardSocket', ),
-    WildcardBTemplate := replace(WildcardATemplate, name="B"),
-    CompareOutputTemplate := SockTemplate(
-        name="Result", is_input=False, bl_idname="BooleanSocket",),
+BonePropertiesSockets = [
+    replace( StringOutput, name='matrix'),
+    replace( StringOutput, name='matrix_local'),
+    replace( StringOutput, name='matrix_basis'),
+    replace( StringOutput, name='head'),
+    replace( StringOutput, name='tail'),
+    replace( StringOutput, name='length'),
+    replace( StringOutput, name='rotation'),
+    replace( StringOutput, name='location'),
+    replace( StringOutput, name='scale'),
 ]
 ]
 
 
-NumberOfSplinesSockets=[
-    CurveTemplate,
-    NumberOfSplinesOut := SockTemplate(name="Number of Splines",
-        bl_idname='UnsignedIntSocket', is_input=False),
+DriverVariableSockets = [
+    VariableType := ST(name='Variable Type', bl_idname="EnumDriverVariableType", is_input=True),
+    Property := ST(name='Property', bl_idname="ParameterStringSocket", is_input=True),
+    PropertyIndex := ST(name='Property Index', bl_idname="IntSocket", is_input=True),
+    EvaluationSpace := ST(name='Evaluation Space', bl_idname="EnumDriverVariableEvaluationSpace", is_input=True,
+        hide = True,),
+    RotationMode := ST(name='Rotation Mode', bl_idname="EnumDriverRotationMode", is_input=True),
+    xForm1 := ST(name='xForm 1', bl_idname="xFormSocket", is_input=True),
+    xForm2 := ST(name='xForm 2', bl_idname="xFormSocket", is_input=True),
+    DriverVariable := ST(name='Driver Variable', bl_idname="DriverVariableSocket", is_input=False),
 ]
 ]
 
 
-CollectionJoinSockets = [
-    JoinCollections := SockTemplate(name='Collections', is_input=True,
-        bl_idname="BoneCollectionSocket", display_shape='SQUARE_DOT',
-        use_multi_input=True,),
-    CollectionDeclarationOutput := SockTemplate(name='Collection',
-        bl_idname="BoneCollectionSocket", is_input=False,)
+FCurveSockets = [
+    ExtrapolationMode := ST( name="Extrapolation Mode",
+        bl_idname="eFCrvExtrapolationMode", is_input=True),
+    fCurveOutput := ST(name="fCurve", bl_idname="FCurveSocket", is_input=False),
 ]
 ]
 
 
-CollectionHierarchySockets = [
-    ParentCollection := SockTemplate(name='Parent Collection', is_input=True,
-        bl_idname="BoneCollectionSocket",),
-    ChildCollection := SockTemplate(name='Child Collection', is_input=True,
-        bl_idname="BoneCollectionSocket",),
-    CollectionDeclarationOutput,
+DriverSockets = [
+    DriverType := ST(name="Driver Type", bl_idname="EnumDriverType", is_input=True),
+    FCurve := ST(name="fCurve", bl_idname="FCurveSocket", is_input=True),
+    Expression := ST(name="Expression", bl_idname="StringSocket", is_input=True),
+    DriverOutput := ST(name="Driver", bl_idname="DriverSocket", is_input=False),
 ]
 ]
 
 
+SwitchSockets = [
+    Parameter := ST(name="Parameter", bl_idname="ParameterStringSocket", is_input=True),
+    ParameterIndex := ST(name="Parameter Index", bl_idname="IntSocket", is_input=True),
+    InvertSwitch := ST(name="Invert Switch", bl_idname="BooleanSocket", is_input=True),
+    DriverOutput,
+]
+
+CombineThreeBoolSockets = [
+    AxisX := ST(name="X", bl_idname="BooleanSocket", is_input=True),
+    AxisY := replace(AxisX, name='Y'),
+    AxisZ := replace(AxisX, name='Z'),
+    ThreeBoolOutput := ST(name="Three-Bool", bl_idname="BooleanThreeTupleSocket", is_input=False),
+]
+
+CombineThreeBoolSockets = [
+    AxisX := ST(name="X", bl_idname="BooleanSocket", is_input=True),
+    AxisY := replace(AxisX, name='Y'),
+    AxisZ := replace(AxisX, name='Z'),
+    ThreeBoolOutput := ST(name="Three-Bool", bl_idname="BooleanThreeTupleSocket", is_input=False),
+]
+
+CombineVectorSockets = [
+    AxisX := replace(AxisX, bl_idname="FloatSocket", name='X'),
+    AxisY := replace(AxisY, bl_idname="FloatSocket", name='Y'),
+    AxisZ := replace(AxisZ, bl_idname="FloatSocket", name='Z'),
+    VectorOutput := ST(name="Vector", bl_idname="VectorSocket", is_input=False),
+]
+
+SeparateVectorSockets = [
+    Vector := ST(name="Vector", bl_idname="VectorSocket", is_input=True),
+    AxisXOutput := replace(AxisX, bl_idname="FloatSocket", is_input=False),
+    AxisYOutput := replace(AxisXOutput, name='Y'),
+    AxisZOutput := replace(AxisXOutput, name='Z'),
+]
+
+CatStringsSockets = [
+    String_1 := ST(name="String_1", bl_idname="StringSocket", is_input=True),
+    String_2 := replace(String_1, name="String_2"),
+    OutputString := ST(name="OutputString", bl_idname="StringSocket", is_input=False),
+]
+
+InputWidgetSockets = [
+    WidgetName := ST(name='Name', is_input=True,
+        bl_idname="EnumWidgetLibrarySocket",),
+    Scale := ST(name='Scale', is_input=True,
+        bl_idname="VectorScaleSocket", default_value=(1.0, 1.0, 1.0)),
+    FlipAxes := ST(name='Flip Axes', is_input=True,
+        bl_idname="BooleanThreeTupleSocket",),
+    xFormOutput := ST(name='Widget',
+        bl_idname='xFormSocket', is_input=False),
+]
+
+InputExistingGeometryObjectSockets = [
+    Name := ST(name="Name", bl_idname="StringSocket", is_input=True),
+    ObjectOutput := ST(name="Object", bl_idname="xFormSocket", is_input=False),
+]
+
+InputExistingGeometrySockets = [
+    Name,
+    GeometryOutput := ST(name="Geometry", bl_idname="GeometrySocket", is_input=False),
+]
 
 
 UtilityCustomPropertySockets = [
 UtilityCustomPropertySockets = [
-    Name := SockTemplate(name='Name', is_input=True,
+    Name := ST(name='Name', is_input=True,
         bl_idname="StringSocket", category='general'),
         bl_idname="StringSocket", category='general'),
     
     
-    CustomPropType := SockTemplate(name='Type', is_input=True,
+    CustomPropType := ST(name='Type', is_input=True,
         bl_idname="EnumCustomPropTypeSocket", category='general'),
         bl_idname="EnumCustomPropTypeSocket", category='general'),
     # Subtype - add this later
     # Subtype - add this later
 
 
     # float properties
     # float properties
-    DefaultFloatValue := SockTemplate(name='Default (Float)', is_input=True,
+    DefaultFloatValue := ST(name='Default (Float)', is_input=True,
         bl_idname="FloatSocket",  category='float'),
         bl_idname="FloatSocket",  category='float'),
-    Min := SockTemplate(name='Min (Float)', is_input=True,
+    Min := ST(name='Min (Float)', is_input=True,
         bl_idname="FloatSocket", category='float'),
         bl_idname="FloatSocket", category='float'),
-    Max := SockTemplate(name='Max (Float)', is_input=True,
+    Max := ST(name='Max (Float)', is_input=True,
         bl_idname="FloatSocket", category='float'),
         bl_idname="FloatSocket", category='float'),
-    SoftMin := SockTemplate(name='Soft Min (Float)', is_input=True,
+    SoftMin := ST(name='Soft Min (Float)', is_input=True,
         bl_idname="FloatSocket", category='float'),
         bl_idname="FloatSocket", category='float'),
-    SoftMax := SockTemplate(name='Soft Max (Float)', is_input=True,
+    SoftMax := ST(name='Soft Max (Float)', is_input=True,
         bl_idname="FloatSocket", category='float'),
         bl_idname="FloatSocket", category='float'),
     
     
     # bool properties
     # bool properties
-    DefaultVectorValue := SockTemplate(name='Default (Bool)', is_input=True,
+    DefaultVectorValue := ST(name='Default (Bool)', is_input=True,
         bl_idname="BooleanSocket", hide=True, category='bool'),
         bl_idname="BooleanSocket", hide=True, category='bool'),
     # int properties
     # int properties
-    DefaultIntValue := SockTemplate(name='Default (Int)', is_input=True,
+    DefaultIntValue := ST(name='Default (Int)', is_input=True,
         bl_idname="IntSocket", hide=True, category='int'),
         bl_idname="IntSocket", hide=True, category='int'),
-    IntMin := SockTemplate(name='Min (Int)', is_input=True,
+    IntMin := ST(name='Min (Int)', is_input=True,
         bl_idname="IntSocket", hide=True, category='int'),
         bl_idname="IntSocket", hide=True, category='int'),
-    IntMax := SockTemplate(name='Max (Int)', is_input=True,
+    IntMax := ST(name='Max (Int)', is_input=True,
         bl_idname="IntSocket", hide=True, category='int'),
         bl_idname="IntSocket", hide=True, category='int'),
-    IntSoftMin := SockTemplate(name='Soft Min (Int)', is_input=True,
+    IntSoftMin := ST(name='Soft Min (Int)', is_input=True,
         bl_idname="IntSocket", hide=True, category='int'),
         bl_idname="IntSocket", hide=True, category='int'),
-    IntSoftMax := SockTemplate(name='Soft Max (Int)', is_input=True,
+    IntSoftMax := ST(name='Soft Max (Int)', is_input=True,
         bl_idname="IntSocket", hide=True, category='int'),
         bl_idname="IntSocket", hide=True, category='int'),
     # vector properties
     # vector properties
-    DefaultVectorValue := SockTemplate(name='Default (Vector)', is_input=True,
+    DefaultVectorValue := ST(name='Default (Vector)', is_input=True,
         bl_idname="VectorSocket", hide=True, category='vector'),
         bl_idname="VectorSocket", hide=True, category='vector'),
     # String Properties
     # String Properties
-    DefaultStringValue := SockTemplate(name='Default (String)', is_input=True,
+    DefaultStringValue := ST(name='Default (String)', is_input=True,
         bl_idname="StringSocket", hide=True, category='string'),
         bl_idname="StringSocket", hide=True, category='string'),
     # general:
     # general:
-    Description := SockTemplate(name='Description', is_input=True,
+    Description := ST(name='Description', is_input=True,
         bl_idname="StringSocket", category='general'),
         bl_idname="StringSocket", category='general'),
-    PropertyDeclaration := SockTemplate(name='Custom Property',
+    PropertyDeclaration := ST(name='Custom Property',
         is_input=False, bl_idname="CustomPropSocket", category='general'),
         is_input=False, bl_idname="CustomPropSocket", category='general'),
-]
+]
+
+CollectionJoinSockets = [
+    JoinCollections := ST(name='Collections', is_input=True,
+        bl_idname="BoneCollectionSocket", display_shape='SQUARE_DOT',
+        use_multi_input=True,),
+    CollectionDeclarationOutput := ST(name='Collection',
+        bl_idname="BoneCollectionSocket", is_input=False,)
+]
+
+CollectionHierarchySockets = [
+    ParentCollection := ST(name='Parent Collection', is_input=True,
+        bl_idname="BoneCollectionSocket",),
+    ChildCollection := ST(name='Child Collection', is_input=True,
+        bl_idname="BoneCollectionSocket",),
+    CollectionDeclarationOutput,
+]
+
+GeometryOfXFormSockets = [
+    xForm := ST(name="xForm", bl_idname="xFormSocket", is_input=True),
+    GeometryOutput,
+]
+
+NameOfXFormSockets = [
+    xForm,
+    replace(Name, is_input=False),
+]
+
+GetBoneLengthSockets = [
+    BoneMatrix := ST(name="Bone Matrix", bl_idname="MatrixSocket", is_input=True),
+    BoneLength := ST(name="Bone Length", bl_idname="FloatSocket", is_input=False),
+]
+
+PointFromBoneMatrixSockets = [
+    replace(MatrixInput, name = "Bone Matrix",),
+    HeadTail := ST(name="Head/Tail", bl_idname = "FloatFactorSocket", is_input=True) ,
+    replace(VectorOutput, name="Point"),
+]
+
+SetBoneLengthSockets = [
+    replace(MatrixInput, name = "Bone Matrix"),
+    Length := ST(name="Length", bl_idname = "FloatSocket", is_input=True) ,
+    replace(MatrixOutput, name = "Bone Matrix"),
+]
+
+# there will eventually be inputs for e.g. key type, key handles, etc.
+# right now I am gonna hardcode LINEAR keyframes so I don't have to deal with anything else
+# TODO TODO TODO
+KeyframeSockets = [
+    # Interpolation := ST(name="Interpolation", bl_idname="EnumKeyframeInterpolationTypeSocket", is_input=True),
+    # LeftHandleType := ST(name="Left Handle Type", bl_idname="EnumKeyframeBezierHandleType", is_input=True),
+    # RightHandleType := ST(name="Right Handle Type", bl_idname="EnumKeyframeBezierHandleType", is_input=True),
+    # LeftHandleDistance := ST(name="Left Handle Distance", bl_idname="FloatSocket", is_input=True),
+    # LeftHandleValue := ST(name="Left Handle Value", bl_idname="FloatSocket", is_input=True),
+    # RightHandleFrame := ST(name="Right Handle Frame", bl_idname="FloatSocket", is_input=True),
+    # RightHandleValue := ST(name="Right Handle Value", bl_idname="FloatSocket", is_input=True),
+    Frame := ST(name="Frame", bl_idname="FloatSocket", is_input=True),
+    Value := ST(name="Value", bl_idname="FloatSocket", is_input=True),
+    Keyframe := ST(name="Keyframe", bl_idname="KeyframeSocket", is_input=False),
+]
+
+BoneMatrixHeadTailFlipSockets = [
+    replace(MatrixInput, name = "Bone Matrix",),
+    replace(MatrixOutput, name = "Bone Matrix"),
+]
+
+MatrixTransformSockets = [
+    Matrix1Template := ST( name="Matrix 1", is_input=True,
+        bl_idname='MatrixSocket', ),
+    Matrix2Template := replace(Matrix1Template, name = "Matrix 2"),
+    replace(MatrixOutput, name = "Out Matrix"),
+]
+
+MatrixInvertSockets=[
+    Matrix1Template,
+    MatrixOutput,
+]
+
+MatrixComposeSockets=[
+    XBasisVector := ST(
+    name="X Basis Vector", is_input=True,  bl_idname='VectorSocket', 
+        default_value = (1.0, 0.0, 0.0) ),
+    YBasisVector := replace(XBasisVector, name="Y Basis Vector",
+        default_value = (0.0, 1.0, 0.0) ),
+    ZBasisVector := replace(XBasisVector, name="Z Basis Vector",
+        default_value = (0.0, 0.0, 1.0) ),
+    Translation := replace(XBasisVector, name="Translation"),
+    MatrixOutput,
+]
+
+MatrixAlignRollSockets = [
+    MatrixInTemplate := replace(Matrix1Template, name="Matrix"),
+    AlignVector := ST(name="Alignment Vector", is_input=True,
+       bl_idname='VectorSocket', default_value=(0.0,-1.0,0.0)),
+    MatrixOutput,
+]
+
+MatrixSetLocationSockets = [
+    MatrixInput,
+    replace(VectorInput, name="Location"),
+    MatrixOutput,
+]
+
+MatrixGetLocationSockets = [
+    MatrixInput,
+    replace(VectorInput, is_input=False, name="Location"),
+]
+
+TransformationMatrixSockets = [
+    MatrixTransformOperation := ST(name="Operation",
+        bl_idname="MatrixTransformOperation", is_input=True),
+    Vector,
+    AxisW := replace(AxisX, name="W"),
+    MatrixOutput,
+]
+
+SetBoneMatrixTailSockets = [
+    MatrixInput,
+    replace(VectorInput, name="Tail Location"),
+    replace(MatrixOutput, name = "Result"),
+]
+
+MatrixFromXFormSockets = [
+    xForm,
+    MatrixOutput,
+]
+
+AxesFromMatrixSockets = [
+    MatrixInput,
+    replace(VectorOutput, name='X Axis',),
+    replace(VectorOutput, name='Y Axis',),
+    replace(VectorOutput, name='Z Axis',),
+]
+
+IntToStringSockets = [
+    Number := ST(name = 'Number', bl_idname = 'IntSocket',
+        is_input = True),
+    Number := ST(name = 'Zero Padding', bl_idname = 'IntSocket',
+        is_input = True),
+    StringOutput,
+]
+
+ArrayGetSockets = [
+    OoBBehaviour := ST(name="OoB Behaviour", bl_idname="EnumArrayGetOptions",
+        is_input=True),
+    Index := ST(name="Index", bl_idname="IntSocket", is_input=True),
+    Array := ST(name="Array", bl_idname="WildcardSocket", is_input=True,
+        use_multi_input=True, display_shape='SQUARE_DOT'),
+    WildcardOutput := ST(name="Output", bl_idname="WildcardSocket", is_input=False),
+]
+
+UtilityArrayLengthSockets = [
+    Array,
+    replace(NumberOfSegments, name="Length"),
+]
+
+CompareSockets = [
+    ComparisonOperation := ST( name='Comparison',
+            is_input=True, bl_idname="EnumCompareOperation",
+            default_value="EQUAL",),
+    WildcardATemplate := ST(
+        name="A", is_input=True,  bl_idname='WildcardSocket', ),
+    WildcardBTemplate := replace(WildcardATemplate, name="B"),
+    CompareOutputTemplate := ST(
+        name="Result", is_input=False, bl_idname="BooleanSocket",),
+]
+
+ChooseSockets = [
+    Condition := ST(name="Condition", bl_idname="BooleanSocket", is_input=True),
+    ChooseA := ST(name="A", bl_idname="WildcardSocket", is_input=True),
+    ChooseB := ST(name="B", bl_idname="WildcardSocket", is_input=True),
+    replace(WildcardOutput, name='Result'),
+]
+
+PrintSockets = [
+    replace(ChooseA, name='Input'),
+]
+
+NumberOfSplinesSockets=[
+    CurveTemplate,
+    NumberOfSplinesOut := ST(name="Number of Splines",
+        bl_idname='UnsignedIntSocket', is_input=False),
+]

File diff suppressed because it is too large
+ 82 - 363
misc_nodes_ui.py


+ 5 - 13
schema_nodes.py

@@ -1,6 +1,8 @@
 from .node_common import *
 from .node_common import *
 from math import pi, tau
 from math import pi, tau
-from .base_definitions import MantisNode, NodeSocket
+from .base_definitions import MantisNode
+
+from .schema_nodes_socket_templates import *
 
 
 def TellClasses():
 def TellClasses():
     return [
     return [
@@ -47,12 +49,7 @@ class SchemaNode(MantisNode):
 
 
 class SchemaIndex(SchemaNode):
 class SchemaIndex(SchemaNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = [
-          "Index",
-          "Schema Length",
-        ]
-        self.outputs.init_sockets(outputs)
+        super().__init__(signature, base_tree, SchemaIndexSockets)
         self.init_parameters()
         self.init_parameters()
 
 
 class SchemaArrayInput(SchemaNode):
 class SchemaArrayInput(SchemaNode):
@@ -63,12 +60,7 @@ class SchemaArrayInput(SchemaNode):
 
 
 class SchemaArrayInputGet(SchemaNode):
 class SchemaArrayInputGet(SchemaNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        inputs = [
-            "OoB Behaviour" ,
-            "Index"         ,
-        ]
-        self.inputs.init_sockets(inputs)
+        super().__init__(signature, base_tree, SchemaArrayInputGetSockets)
         schema_init_sockets(self, is_input=False, in_out='INPUT', category='Array')
         schema_init_sockets(self, is_input=False, in_out='INPUT', category='Array')
 
 
 class SchemaArrayInputAll(SchemaNode):
 class SchemaArrayInputAll(SchemaNode):

+ 14 - 0
schema_nodes_socket_templates.py

@@ -0,0 +1,14 @@
+from .base_definitions import MantisSocketTemplate as ST
+from dataclasses import replace
+
+# NOTE most Schema nodes are fully dynamic, and the rest are
+#      mostly dynamic, so they don't use Socket Templates much.
+SchemaIndexSockets = [
+    Index := ST(name="Index", bl_idname="IntSocket", is_input=False),
+    SchemaLength := ST(name="Schema Length", bl_idname="IntSocket", is_input=False),
+]
+
+SchemaArrayInputGetSockets = [
+    OoBBehaviour := ST(name="OoB Behaviour", bl_idname="EnumArrayGetOptions", is_input=True),
+    Index := ST(name="Index", bl_idname="IntSocket", is_input=True),
+]

+ 3 - 4
schema_nodes_ui.py

@@ -10,6 +10,7 @@ from bpy.props import BoolProperty
 from .utilities import (get_socket_maps, relink_socket_map,
 from .utilities import (get_socket_maps, relink_socket_map,
                         do_relink, read_schema_type)
                         do_relink, read_schema_type)
 
 
+from .schema_nodes_socket_templates import *
 
 
 def TellClasses():
 def TellClasses():
     return [
     return [
@@ -39,8 +40,7 @@ class SchemaIndex(Node, SchemaUINode):
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
-        self.outputs.new("IntSocket", "Index")
-        self.outputs.new("IntSocket", "Schema Length")
+        self.init_sockets(SchemaIndexSockets)
         self.initialized = True
         self.initialized = True
 
 
 class SchemaArrayInput(Node, SchemaUINode):
 class SchemaArrayInput(Node, SchemaUINode):
@@ -118,8 +118,7 @@ class SchemaArrayInputGet(Node, SchemaUINode):
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
 
 
     def init(self, context):
     def init(self, context):
-        self.inputs.new('EnumArrayGetOptions', 'OoB Behaviour')
-        self.inputs.new("IntSocket", "Index")
+        self.init_sockets(SchemaArrayInputGetSockets)
         self.update()
         self.update()
 
 
     def update(self):
     def update(self):

+ 4 - 73
xForm_nodes.py

@@ -236,85 +236,15 @@ class xFormArmature(xFormNode):
     def bGetObject(self, mode = ''):
     def bGetObject(self, mode = ''):
         import bpy; return bpy.data.objects[self.parameters['xForm Out'].self_pose_name]
         import bpy; return bpy.data.objects[self.parameters['xForm Out'].self_pose_name]
 
 
-bone_inputs= [
-         "Name",
-         "Rotation Order",
-         "Matrix",
-         "Relationship",
-         # IK settings
-         "IK Stretch",
-         "Lock IK",
-         "IK Stiffness",
-         "Limit IK",
-         "X Min",
-         "X Max",
-         "Y Min",
-         "Y Max",
-         "Z Min",
-         "Z Max",
-         # Visual stuff
-         "Bone Collection",
-         "Hide",
-         "Custom Object",
-         "Custom Object xForm Override",
-         "Custom Object Scale to Bone Length",
-         "Custom Object Wireframe",
-         "Custom Object Scale",
-         "Custom Object Translation",
-         "Custom Object Rotation",
-         "Color",
-         "Inherit Color",
-         # Deform Stuff
-         "Deform",
-         "Envelope Distance",
-         "Envelope Weight",
-         "Envelope Multiply",
-         "Envelope Head Radius",
-         "Envelope Tail Radius",
-         # BBone stuff:
-         "BBone Segments",
-         "BBone X Size",
-         "BBone Z Size",
-         "BBone HQ Deformation",
-         "BBone X Curve-In",
-         "BBone Z Curve-In",
-         "BBone X Curve-Out",
-         "BBone Z Curve-Out",
-         "BBone Roll-In",
-         "BBone Roll-Out",
-         "BBone Inherit End Roll",
-         "BBone Scale-In",
-         "BBone Scale-Out",
-         "BBone Ease-In",
-         "BBone Ease-Out",
-         "BBone Easing",
-         "BBone Start Handle Type",
-         "BBone Custom Start Handle",
-         "BBone Start Handle Scale",
-         "BBone Start Handle Ease",
-         "BBone End Handle Type",
-         "BBone Custom End Handle",
-         "BBone End Handle Scale",
-         "BBone End Handle Ease",
-         # locks
-         "Lock Location",
-         "Lock Rotation",
-         "Lock Scale",
-         "Custom Properties",
-]
 class xFormBone(xFormNode):
 class xFormBone(xFormNode):
     '''A node representing a bone in an armature'''
     '''A node representing a bone in an armature'''
     # DO: make a way to identify which armature this belongs to
     # DO: make a way to identify which armature this belongs to
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
-        super().__init__(signature, base_tree)
-        outputs = [
-         "xForm Out",
-        ]
-        self.inputs.init_sockets(bone_inputs)
-        self.outputs.init_sockets(outputs)
-        self.socket_templates=xFormBoneSockets
+        super().__init__(signature, base_tree, xFormBoneSockets)
         # TODO: implement socket templates completely for Bone
         # TODO: implement socket templates completely for Bone
         # currently it is waiting on BBone and refactoring/cleanup.
         # currently it is waiting on BBone and refactoring/cleanup.
+        # the socket templates are being used now but not for mantis node execution.
+        # because of edit/pose/objcet bone this will be a bit complex
         self.init_parameters()
         self.init_parameters()
         self.set_traverse([("Relationship", "xForm Out")])
         self.set_traverse([("Relationship", "xForm Out")])
         setup_custom_property_inputs_outputs(self)
         setup_custom_property_inputs_outputs(self)
@@ -595,6 +525,7 @@ class xFormBone(xFormNode):
         evaluate_sockets(self, pb, props_sockets)
         evaluate_sockets(self, pb, props_sockets)
 
 
         # this could probably be moved to bTransformPass
         # this could probably be moved to bTransformPass
+        # TODO VERSIONING: newer (5.0+ ?) Blenders need to use PoseBone for this
         props_sockets = {
         props_sockets = {
             'hide'      : ("Hide", False),
             'hide'      : ("Hide", False),
             'show_wire' : ("Custom Object Wireframe", False),
             'show_wire' : ("Custom Object Wireframe", False),

+ 16 - 153
xForm_nodes_ui.py

@@ -132,93 +132,9 @@ def custom_prop_display_update(self, mantis_node = None):
             do_relink(self, socket, socket_map_out, in_out='OUTPUT')
             do_relink(self, socket, socket_map_out, in_out='OUTPUT')
 
 
 
 
-# I had chat gpt flip these so they may be a little innacurate
-# always visible
-main_names = {
-"Name":'StringSocket',
-"Rotation Order":'RotationOrderSocket',
-"Relationship":'RelationshipSocket',
-"Matrix":'MatrixSocket',}
-
-# IK SETTINGS
-ik_names = {
-"IK Stretch":'FloatFactorSocket',
-"Lock IK":'BooleanThreeTupleSocket',
-"IK Stiffness":'NodeSocketVector',
-"Limit IK":'BooleanThreeTupleSocket',
-"X Min":'NodeSocketFloatAngle',
-"X Max":'NodeSocketFloatAngle',
-"Y Min":'NodeSocketFloatAngle',
-"Y Max":'NodeSocketFloatAngle',
-"Z Min":'NodeSocketFloatAngle',
-"Z Max":'NodeSocketFloatAngle',
-}
-
-#display settings
-display_names = {
-"Bone Collection":'BoneCollectionSocket',
-"Custom Object":'xFormSocket',
-"Custom Object xForm Override":'xFormSocket',
-"Custom Object Scale to Bone Length":'BooleanSocket',
-"Custom Object Wireframe":'BooleanSocket',
-"Custom Object Scale":'VectorScaleSocket',
-"Custom Object Translation":'VectorSocket',
-"Custom Object Rotation":'VectorEulerSocket',
-"Color":'ColorSetSocket',
-"Inherit Color":'BooleanSocket',
-}
-
-# deform_names
-deform_names = {
-"Deform":'BooleanSocket',
-"Envelope Distance":'FloatPositiveSocket',
-"Envelope Weight":'FloatFactorSocket',
-"Envelope Multiply":'BooleanSocket',
-"Envelope Head Radius":'FloatPositiveSocket',
-"Envelope Tail Radius":'FloatPositiveSocket',
-}
-
-bbone_names = {
-    "BBone Segments":"IntSocket", # BONE
-    "BBone X Size":"FloatSocket", # BONE
-    "BBone Z Size":"FloatSocket", # BONE
-    # "bbone_mapping_mode":"StringSocket", <== BONE
-    "BBone HQ Deformation":"BooleanSocket", # BONE bbone_mapping_mode
-    "BBone X Curve-In":"FloatSocket", # BONE AND POSE
-    "BBone Z Curve-In":"FloatSocket", # BONE AND POSE
-    "BBone X Curve-Out":"FloatSocket", # BONE AND POSE
-    "BBone Z Curve-Out":"FloatSocket", # BONE AND POSE
-    "BBone Roll-In":"FloatSocket", # BONE AND POSE
-    "BBone Roll-Out":"FloatSocket", # BONE AND POSE
-    "BBone Inherit End Roll":"BooleanSocket", # BONE
-    "BBone Scale-In":"VectorSocket", # BONE AND POSE
-    "BBone Scale-Out":"VectorSocket", # BONE AND POSE
-    "BBone Ease-In":"FloatSocket", # BONE AND POSE
-    "BBone Ease-Out":"FloatSocket", # BONE AND POSE
-    "BBone Easing":"BooleanSocket", # BONE
-    "BBone Start Handle Type":"EnumBBoneHandleType", # BONE
-    "BBone Custom Start Handle":"StringSocket", # BONE
-    "BBone Start Handle Scale":"BooleanThreeTupleSocket", # BONE
-    "BBone Start Handle Ease":"BooleanSocket", # BONE
-    "BBone End Handle Type":"EnumBBoneHandleType", # BONE
-    "BBone Custom End Handle":"StringSocket", # BONE
-    "BBone End Handle Scale":"BooleanThreeTupleSocket", # BONE
-    "BBone End Handle Ease":"BooleanSocket", # BONE
-
-}
-
-other_names = {
-    "Lock Location":'BooleanThreeTupleSocket',
-    "Lock Rotation":'BooleanThreeTupleSocket',
-    "Lock Scale":'BooleanThreeTupleSocket',
-    "Hide":'HideSocket',
-}
-
 from mathutils import Color
 from mathutils import Color
 xFormColor = Color((0.093172, 0.047735, 0.028036)).from_scene_linear_to_srgb()
 xFormColor = Color((0.093172, 0.047735, 0.028036)).from_scene_linear_to_srgb()
 
 
-
-
 class xFormBoneNode(Node, xFormNode):
 class xFormBoneNode(Node, xFormNode):
     '''A node representing a Bone'''
     '''A node representing a Bone'''
     bl_idname = 'xFormBoneNode'
     bl_idname = 'xFormBoneNode'
@@ -232,70 +148,17 @@ class xFormBoneNode(Node, xFormNode):
     socket_count : bpy.props.IntProperty()
     socket_count : bpy.props.IntProperty()
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     mantis_node_class_name=bl_idname[:-4]
     mantis_node_class_name=bl_idname[:-4]
+    socket_templates = xFormBoneSockets
     
     
     def init(self, context):
     def init(self, context):
-
-        for name, sock_type in main_names.items():
-            self.inputs.new(sock_type, name)
-
-        for name, sock_type in ik_names.items():
-            s = self.inputs.new(sock_type, name)
-            s.hide = True
-        
-        for name, sock_type in display_names.items():
-            if name == 'Bone Collection': # HACK because I am not using Socket Templates yet
-                s = self.inputs.new(sock_type, name, use_multi_input=True)
-            else:
-                s = self.inputs.new(sock_type, name)
-            if s.name in ['Custom Object', 'Bone Collection']:
-                continue
-            s.hide = True
-        
-        for name, sock_type in deform_names.items():
-            s = self.inputs.new(sock_type, name)
-            if s.name == 'Deform':
-                continue
-            s.hide = True
-        
-        for name, sock_type in bbone_names.items():
-            s = self.inputs.new(sock_type, name)
-            if s.name == "BBone Segments":
-                continue
-            s.hide = True
-
-        for name, sock_type in other_names.items():
-            self.inputs.new(sock_type, name)
-        # could probably simplify this further with iter_tools.chain() but meh
-
-        self.inputs.new("CustomPropSocket", "Custom Properties", use_multi_input=True)
-
+        self.init_sockets(self.__class__.socket_templates)
         self.socket_count = len(self.inputs)
         self.socket_count = len(self.inputs)
-        #
-        self.outputs.new('xFormSocket', "xForm Out")
-
-
-        # set up some defaults...
-        self.inputs['Rotation Order'].default_value = "XYZ"
-        self.inputs['Lock Location'].default_value[0] = True
-        self.inputs['Lock Location'].default_value[1] = True
-        self.inputs['Lock Location'].default_value[2] = True
-        self.inputs['Lock Rotation'].default_value[0] = True
-        self.inputs['Lock Rotation'].default_value[1] = True
-        self.inputs['Lock Rotation'].default_value[2] = True
-        self.inputs['Lock Scale'].default_value[0] = True
-        self.inputs['Lock Scale'].default_value[1] = True
-        self.inputs['Lock Scale'].default_value[2] = True
-        self.inputs['Inherit Color'].default_value = True
-        
-        # color
         self.use_custom_color = True
         self.use_custom_color = True
         self.color = xFormColor
         self.color = xFormColor
-        #
         self.initialized=True
         self.initialized=True
     
     
     def draw_label(self): # this will prefer a user-set label, or return the evaluated name
     def draw_label(self): # this will prefer a user-set label, or return the evaluated name
         return main_draw_label(self)
         return main_draw_label(self)
-
         
         
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         # let's setup the outputs for the custom properties:
         # let's setup the outputs for the custom properties:
@@ -319,20 +182,20 @@ class xFormBoneNode(Node, xFormNode):
                 except KeyError:
                 except KeyError:
                     return # the tree isn't ready yet.
                     return # the tree isn't ready yet.
             
             
-            for name in ik_names.keys():
-                self.inputs[name].hide = not self.display_ik_settings
-            
-            for name in display_names.keys():
-                if name in ['Custom Object', 'Bone Collection']: continue
-                self.inputs[name].hide = not self.display_vp_settings
-            
-            for name in deform_names.keys():
-                if name in ['Deform']: continue
-                self.inputs[name].hide = not self.display_def_settings
-
-            for name in bbone_names.keys():
-                if name in ['BBone Segments']: continue
-                self.inputs[name].hide = not self.display_bb_settings
+            for template in self.socket_templates:
+                name = template.name
+                category = template.category
+                if category == "IK":
+                    self.inputs[name].hide = not self.display_ik_settings
+                if category == "Display":
+                    if name in ['Custom Object', 'Bone Collection']: continue
+                    self.inputs[name].hide = not self.display_vp_settings
+                if category == "Deform":
+                    if name in ['Deform']: continue
+                    self.inputs[name].hide = not self.display_def_settings
+                if category == "bbone":
+                    if name in ['BBone Segments']: continue
+                    self.inputs[name].hide = not self.display_bb_settings
 
 
 def object_displaty_update(self, parsed_tree, context):
 def object_displaty_update(self, parsed_tree, context):
     custom_prop_display_update(self)
     custom_prop_display_update(self)

+ 20 - 18
xForm_socket_templates.py

@@ -102,7 +102,7 @@ xFormBoneSockets = [
         blender_property=('lock_ik_x', 'lock_ik_y', 'lock_ik_z'),),
         blender_property=('lock_ik_x', 'lock_ik_y', 'lock_ik_z'),),
     IKStiffness := SockTemplate(
     IKStiffness := SockTemplate(
         name="IK Stiffness", is_input=True,  bl_idname='BooleanThreeTupleSocket',
         name="IK Stiffness", is_input=True,  bl_idname='BooleanThreeTupleSocket',
-        default_value=(0, 0, 0), category='IK',
+        default_value=(False, False, False), category='IK',
         blender_property=('ik_stiffness_x', 'ik_stiffness_y', 'ik_stiffness_z')),
         blender_property=('ik_stiffness_x', 'ik_stiffness_y', 'ik_stiffness_z')),
     IKLimit := SockTemplate(
     IKLimit := SockTemplate(
         name="Limit IK", is_input=True,  bl_idname='BooleanThreeTupleSocket',
         name="Limit IK", is_input=True,  bl_idname='BooleanThreeTupleSocket',
@@ -134,10 +134,10 @@ xFormBoneSockets = [
     CustomObjectScaleTemplate := SockTemplate(name="Custom Object Scale",
     CustomObjectScaleTemplate := SockTemplate(name="Custom Object Scale",
             is_input=True, bl_idname='VectorScaleSocket',
             is_input=True, bl_idname='VectorScaleSocket',
             category='Display', default_value=(1.0,1.0,1.0),),
             category='Display', default_value=(1.0,1.0,1.0),),
-    CustomObjectScaleTemplate := SockTemplate(name="Custom Object Translation",
+    CustomObjectTranslationTemplate := SockTemplate(name="Custom Object Translation",
             is_input=True, bl_idname='VectorSocket',
             is_input=True, bl_idname='VectorSocket',
             category='Display', default_value=(0.0,0.0,0.0),),
             category='Display', default_value=(0.0,0.0,0.0),),
-    CustomObjectScaleTemplate := SockTemplate(name="Custom Object Rotation",
+    CustomObjectRotationTemplate := SockTemplate(name="Custom Object Rotation",
             is_input=True, bl_idname='VectorEulerSocket',
             is_input=True, bl_idname='VectorEulerSocket',
             category='Display', default_value=(0.0,0.0,0.0),),
             category='Display', default_value=(0.0,0.0,0.0),),
     CustomColor := SockTemplate(name="Color",
     CustomColor := SockTemplate(name="Color",
@@ -151,7 +151,8 @@ xFormBoneSockets = [
         category='Deform', blender_property='use_deform', default_value=False,),
         category='Deform', blender_property='use_deform', default_value=False,),
     EnvelopeDistanceTemplate := SockTemplate( name='Envelope Distance',
     EnvelopeDistanceTemplate := SockTemplate( name='Envelope Distance',
             bl_idname='FloatPositiveSocket', category='Deform',
             bl_idname='FloatPositiveSocket', category='Deform',
-            blender_property='envelope_distance', default_value=0,),
+            blender_property='envelope_distance', default_value=0,
+            is_input=True,),
     EnvelopeWeightTemplate := replace(EnvelopeDistanceTemplate,
     EnvelopeWeightTemplate := replace(EnvelopeDistanceTemplate,
             name='Envelope Weight', bl_idname = 'FloatFactorSocket',
             name='Envelope Weight', bl_idname = 'FloatFactorSocket',
             blender_property='envelope_weight', default_value=1.0,),
             blender_property='envelope_weight', default_value=1.0,),
@@ -168,8 +169,8 @@ xFormBoneSockets = [
         blender_property='bbone_segments', default_value=1 ),
         blender_property='bbone_segments', default_value=1 ),
     BBoneXSizeTemplate := replace(BBoneSegmentsTemplate, name='BBone X Size',
     BBoneXSizeTemplate := replace(BBoneSegmentsTemplate, name='BBone X Size',
         bl_idname='FloatSocket', blender_property='bbone_x', default_value=0.0025, ),
         bl_idname='FloatSocket', blender_property='bbone_x', default_value=0.0025, ),
-    BBoneYSizeTemplate := replace(BBoneXSizeTemplate, name='BBone Z Size',
-        blender_property='bbone_y', ),
+    BBoneZSizeTemplate := replace(BBoneXSizeTemplate, name='BBone Z Size',
+        blender_property='bbone_z', ),
     BBoneHQDeformation := replace(BBoneSegmentsTemplate, name='BBone HQ Deformation',
     BBoneHQDeformation := replace(BBoneSegmentsTemplate, name='BBone HQ Deformation',
         bl_idname='BooleanSocket', blender_property='', default_value=None ),
         bl_idname='BooleanSocket', blender_property='', default_value=None ),
     BBoneXCurveInTemplate := replace( BBoneXSizeTemplate, name="BBone X Curve-In",
     BBoneXCurveInTemplate := replace( BBoneXSizeTemplate, name="BBone X Curve-In",
@@ -184,37 +185,38 @@ xFormBoneSockets = [
     replace(BBoneXCurveInTemplate, name="BBone Roll-In", blender_property='bbone_rollin', ), # CURRENTLY UNIMPLEMENTED
     replace(BBoneXCurveInTemplate, name="BBone Roll-In", blender_property='bbone_rollin', ), # CURRENTLY UNIMPLEMENTED
     replace(BBoneXCurveInTemplate, name="BBone Roll-Out", blender_property='bbone_rollout', ), # CURRENTLY UNIMPLEMENTED
     replace(BBoneXCurveInTemplate, name="BBone Roll-Out", blender_property='bbone_rollout', ), # CURRENTLY UNIMPLEMENTED
     replace(BBoneXCurveInTemplate, name="BBone Inherit End Roll",
     replace(BBoneXCurveInTemplate, name="BBone Inherit End Roll",
-            bl_idname='BooleanSocket',), # CURRENTLY UNIMPLEMENTED
+            bl_idname='BooleanSocket', default_value=False,), # CURRENTLY UNIMPLEMENTED
     replace(BBoneXCurveInTemplate, name="BBone Scale-In",
     replace(BBoneXCurveInTemplate, name="BBone Scale-In",
-            bl_idname='VectorSocket',), # CURRENTLY DOESN'T WORK
+            bl_idname='VectorSocket', default_value=(0.0,0.0,0.0),), # CURRENTLY DOESN'T WORK
     replace(BBoneXCurveInTemplate, name="BBone Scale-Out",
     replace(BBoneXCurveInTemplate, name="BBone Scale-Out",
-            bl_idname='VectorSocket',), # CURRENTLY DOESN'T WORK
+            bl_idname='VectorSocket', default_value=(0.0,0.0,0.0)), # CURRENTLY DOESN'T WORK
     replace(BBoneXCurveInTemplate, name="BBone Ease-In",), # CURRENTLY DOESN'T WORK
     replace(BBoneXCurveInTemplate, name="BBone Ease-In",), # CURRENTLY DOESN'T WORK
     replace(BBoneXCurveInTemplate, name="BBone Ease-Out",), # CURRENTLY DOESN'T WORK
     replace(BBoneXCurveInTemplate, name="BBone Ease-Out",), # CURRENTLY DOESN'T WORK
     replace(BBoneXCurveInTemplate, name="BBone Easing",
     replace(BBoneXCurveInTemplate, name="BBone Easing",
-            bl_idname='BooleanSocket',), # CURRENTLY DOESN'T WORK
+            bl_idname='BooleanSocket', default_value=False,), # CURRENTLY DOESN'T WORK
     replace(BBoneXCurveInTemplate, name="BBone Start Handle Type",
     replace(BBoneXCurveInTemplate, name="BBone Start Handle Type",
             bl_idname="EnumBBoneHandleType",
             bl_idname="EnumBBoneHandleType",
-            blender_property='bbone_handle_type_start',),
+            blender_property='bbone_handle_type_start', default_value=None, ),
     replace(BBoneXCurveInTemplate, name="BBone Custom Start Handle",
     replace(BBoneXCurveInTemplate, name="BBone Custom Start Handle",
             bl_idname="StringSocket",
             bl_idname="StringSocket",
-            blender_property='bbone_custom_handle_start',),
+            blender_property='bbone_custom_handle_start', default_value=None, ),
     replace(BBoneXCurveInTemplate, name="BBone Start Handle Scale",
     replace(BBoneXCurveInTemplate, name="BBone Start Handle Scale",
             bl_idname="BooleanThreeTupleSocket",
             bl_idname="BooleanThreeTupleSocket",
-            blender_property='bbone_handle_use_scale_start',),
+            blender_property='bbone_handle_use_scale_start', default_value=None, ),
     replace(BBoneXCurveInTemplate, name="BBone Start Handle Ease",
     replace(BBoneXCurveInTemplate, name="BBone Start Handle Ease",
-            bl_idname='BooleanSocket',),# CURRENTLY DOESN'T WORK),
+            bl_idname='BooleanSocket', default_value=False),# CURRENTLY DOESN'T WORK),
     replace(BBoneXCurveInTemplate, name="BBone End Handle Type",
     replace(BBoneXCurveInTemplate, name="BBone End Handle Type",
             bl_idname="EnumBBoneHandleType",
             bl_idname="EnumBBoneHandleType",
-            blender_property='bbone_handle_type_end',),
+            blender_property='bbone_handle_type_end', default_value=None, ),
     replace(BBoneXCurveInTemplate, name="BBone Custom End Handle",
     replace(BBoneXCurveInTemplate, name="BBone Custom End Handle",
             bl_idname="StringSocket",
             bl_idname="StringSocket",
-            blender_property='bbone_custom_handle_end',),
+            blender_property='bbone_custom_handle_end', default_value=None, ),
     replace(BBoneXCurveInTemplate, name="BBone End Handle Scale",
     replace(BBoneXCurveInTemplate, name="BBone End Handle Scale",
             bl_idname="BooleanThreeTupleSocket",
             bl_idname="BooleanThreeTupleSocket",
-            blender_property='bbone_handle_use_scale_end',),
+            blender_property='bbone_handle_use_scale_end',
+            default_value= (False, False, False)),
     replace(BBoneXCurveInTemplate, name="BBone End Handle Ease",
     replace(BBoneXCurveInTemplate, name="BBone End Handle Ease",
-            bl_idname='BooleanSocket',),# CURRENTLY DOESN'T WORK),
+            bl_idname='BooleanSocket', default_value=False),# CURRENTLY DOESN'T WORK),
     # locks
     # locks
     LockLocationTemplate := SockTemplate(name="Lock Location",
     LockLocationTemplate := SockTemplate(name="Lock Location",
         is_input=True, bl_idname='BooleanThreeTupleSocket', category = 'lock',
         is_input=True, bl_idname='BooleanThreeTupleSocket', category = 'lock',

Some files were not shown because too many files changed in this diff