Sfoglia il codice sorgente

Cleanup: Remove Lots of Boilerplate

Using better OOP to make my node classes much simpler and cleaner
now every node uses socket templates and class methods set up
mantis class at register-time
Joseph Brandenburg 1 mese fa
parent
commit
7b2204669c
9 ha cambiato i file con 274 aggiunte e 623 eliminazioni
  1. 54 22
      base_definitions.py
  2. 13 37
      deformer_nodes_ui.py
  3. 44 149
      link_nodes_ui.py
  4. 7 23
      math_nodes_ui.py
  5. 132 302
      misc_nodes_ui.py
  6. 6 20
      primitives_nodes_ui.py
  7. 10 0
      primitives_sockets.py
  8. 2 8
      schema_nodes_ui.py
  9. 6 62
      xForm_nodes_ui.py

+ 54 - 22
base_definitions.py

@@ -215,6 +215,15 @@ class SchemaTree(NodeTree):
 
 
 #TODO: do a better job explaining how MantisNode and MantisUINode relate.
 #TODO: do a better job explaining how MantisNode and MantisUINode relate.
 
 
+# TODO: I want to avoid doing any kind of class mutation at runtime
+#       so in the future I will try to do this directly rather than
+#       running this function once for each class while registering
+#       however this is not very important for UI classes since they
+#       are not a performance bottleneck.
+def mantis_class_from_library(library, class_name):
+    from importlib import import_module
+    return getattr(import_module(library, package=mantis_root), class_name)
+
 class MantisUINode:
 class MantisUINode:
     """
     """
         This class contains the common user-interface features of Mantis nodes.
         This class contains the common user-interface features of Mantis nodes.
@@ -225,23 +234,17 @@ class MantisUINode:
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     #
     #
-    mantis_node_library=''
     mantis_node_class_name=''
     mantis_node_class_name=''
     mantis_class=None
     mantis_class=None
+    socket_templates=None
+
     @classmethod
     @classmethod
     def poll(cls, ntree):
     def poll(cls, ntree):
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
 
 
-    @classmethod
-    def set_mantis_class(self):
-        from importlib import import_module
-        # do not catch errors, they should cause a failure.
-        try:
-            module = import_module(self.mantis_node_library, package=mantis_root)
-            self.mantis_class=getattr(module, self.mantis_node_class_name)
-        except Exception as e:
-            print(self)
-            raise e
+    def init(self, context):
+        self.init_sockets(self.socket_templates)
+        self.initialized = True
 
 
     def insert_link(self, link):
     def insert_link(self, link):
         if (bpy.app.version >= (4, 4, 0)):
         if (bpy.app.version >= (4, 4, 0)):
@@ -286,30 +289,59 @@ class MantisUINode:
             if template.use_multi_input: # this is an array
             if template.use_multi_input: # this is an array
                 socket.display_shape = 'SQUARE_DOT'
                 socket.display_shape = 'SQUARE_DOT'
 
 
+# NOTE
+# MantisUINode has no proper mantis libraryclass on its own, so:
+# register()'s are in SUBclasses; they have to run AFTER library is defined
+
 class SchemaUINode(MantisUINode):
 class SchemaUINode(MantisUINode):
-    mantis_node_library='.schema_nodes'
     is_updating:BoolProperty(default=False)
     is_updating:BoolProperty(default=False)
     @classmethod
     @classmethod
-    def poll(cls, ntree):
-        return (ntree.bl_idname in ['SchemaTree'])
+    def register(cls):
+        cls.mantis_class = mantis_class_from_library('.schema_nodes', cls.mantis_node_class_name)
 
 
 class LinkNode(MantisUINode):
 class LinkNode(MantisUINode):
     mantis_node_library='.link_nodes'
     mantis_node_library='.link_nodes'
+    category_color=[0.5,0.5,0.5]
     @classmethod
     @classmethod
-    def poll(cls, ntree):
-        return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
+    def register(cls):
+        cls.mantis_class = mantis_class_from_library('.link_nodes', cls.mantis_node_class_name)
+    def init(self, context):
+        super().init(context)
+        self.use_custom_color = True
+        self.color = self.category_color
 
 
 class xFormNode(MantisUINode):
 class xFormNode(MantisUINode):
-    mantis_node_library='.xForm_nodes'
     @classmethod
     @classmethod
-    def poll(cls, ntree):
-        return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
+    def register(cls):
+        print (cls.__name__, cls.mantis_node_class_name)
+        cls.mantis_class = mantis_class_from_library('.xForm_nodes', cls.mantis_node_class_name)
+    def init(self, context):
+        super().init(context)
+        from mathutils import Color
+        xFormColor = Color((0.093172, 0.047735, 0.028036)).from_scene_linear_to_srgb()
+        self.use_custom_color = True
+        self.color = xFormColor # must not have alpha
 
 
 class DeformerNode(MantisUINode):
 class DeformerNode(MantisUINode):
-    mantis_node_library='.deformer_nodes'
     @classmethod
     @classmethod
-    def poll(cls, ntree):
-        return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
+    def register(cls):
+        cls.mantis_class = mantis_class_from_library('.deformer_nodes', cls.mantis_node_class_name)
+
+class GeometryPrimitiveNode(MantisUINode):
+    @classmethod
+    def register(cls):
+        cls.mantis_class = mantis_class_from_library('.primitives_nodes', cls.mantis_node_class_name)
+
+class MantisMiscNode(MantisUINode):
+    @classmethod
+    def register(cls):
+        cls.mantis_class = mantis_class_from_library('.misc_nodes', cls.mantis_node_class_name)
+
+class MantisMathUINode(MantisUINode):
+    @classmethod
+    def register(cls):
+        cls.mantis_class = mantis_class_from_library('.math_nodes', cls.mantis_node_class_name)
+
 
 
 def poll_node_tree(self, object):
 def poll_node_tree(self, object):
     forbid = []
     forbid = []

+ 13 - 37
deformer_nodes_ui.py

@@ -35,10 +35,7 @@ class DeformerArmatureNode(Node, DeformerNode):
     bl_icon = 'MOD_ARMATURE'
     bl_icon = 'MOD_ARMATURE'
     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):
-        self.init_sockets(DeformArmatureSockets)
-        self.initialized = True
+    socket_templates = DeformArmatureSockets
     
     
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         self.inputs["Copy Skin Weights From"].hide = True
         self.inputs["Copy Skin Weights From"].hide = True
@@ -55,10 +52,7 @@ class DeformerHook(Node, DeformerNode):
     bl_icon = 'HOOK'
     bl_icon = 'HOOK'
     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):
-        self.init_sockets(HookSockets)
-        self.initialized = True
+    socket_templates = HookSockets
     
     
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         curve_sockets = [
         curve_sockets = [
@@ -81,6 +75,7 @@ class DeformerHook(Node, DeformerNode):
 from .utilities import get_socket_maps, relink_socket_map
 from .utilities import get_socket_maps, relink_socket_map
 
 
 # TODO this should probably not be in this file but intstead in Utilities or something
 # TODO this should probably not be in this file but intstead in Utilities or something
+# NOTE this is a re-implementation that I had to do here.
 def simple_do_relink(node, map, in_out='INPUT'):
 def simple_do_relink(node, map, in_out='INPUT'):
     from bpy.types import NodeSocket
     from bpy.types import NodeSocket
     for key, val in map.items():
     for key, val in map.items():
@@ -116,13 +111,14 @@ class DeformerMorphTargetDeform(Node, DeformerNode):
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     num_targets : bpy.props.IntProperty(default = 0)
     num_targets : bpy.props.IntProperty(default = 0)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
+    socket_templates = MorphTargetDeformSockets
 
 
     def init(self, context):
     def init(self, context):
+        live_updates = self.id_data.do_live_update
         self.id_data.do_live_update = False
         self.id_data.do_live_update = False
         self.init_sockets(MorphTargetDeformSockets)
         self.init_sockets(MorphTargetDeformSockets)
         self.update_morph_deformer()
         self.update_morph_deformer()
-        self.id_data.do_live_update = True
+        self.id_data.do_live_update = live_updates
 
 
     def update_morph_deformer(self, force=False):
     def update_morph_deformer(self, force=False):
         self.initialized = False
         self.initialized = False
@@ -185,11 +181,7 @@ class DeformerMorphTarget(Node, DeformerNode):
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     num_targets : bpy.props.IntProperty(default = 0)
     num_targets : bpy.props.IntProperty(default = 0)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
-    def init(self, context):
-        self.init_sockets(MorphTargetSockets)
-        self.initialized = True
-
+    socket_templates = MorphTargetSockets
 
 
 class DeformerSurfaceDeform(Node, DeformerNode):
 class DeformerSurfaceDeform(Node, DeformerNode):
     '''A node representing a Surface Deform modifier'''
     '''A node representing a Surface Deform modifier'''
@@ -199,10 +191,7 @@ class DeformerSurfaceDeform(Node, DeformerNode):
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     num_targets : bpy.props.IntProperty(default = 0)
     num_targets : bpy.props.IntProperty(default = 0)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
-    def init(self, context):
-        self.init_sockets(SurfaceDeformSockets)
-        self.initialized = True
+    socket_templates = SurfaceDeformSockets
 
 
 class DeformerMeshDeform(Node, DeformerNode):
 class DeformerMeshDeform(Node, DeformerNode):
     '''A node representing a Mesh Deform modifier'''
     '''A node representing a Mesh Deform modifier'''
@@ -212,10 +201,7 @@ class DeformerMeshDeform(Node, DeformerNode):
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     num_targets : bpy.props.IntProperty(default = 0)
     num_targets : bpy.props.IntProperty(default = 0)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
-    def init(self, context):
-        self.init_sockets(MeshDeformSockets)
-        self.initialized = True
+    socket_templates = MeshDeformSockets
 
 
 class DeformerLatticeDeform(Node, DeformerNode):
 class DeformerLatticeDeform(Node, DeformerNode):
     '''A node representing a Lattice Deformer'''
     '''A node representing a Lattice Deformer'''
@@ -225,10 +211,7 @@ class DeformerLatticeDeform(Node, DeformerNode):
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     num_targets : bpy.props.IntProperty(default = 0)
     num_targets : bpy.props.IntProperty(default = 0)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
-    def init(self, context):
-        self.init_sockets(LatticeDeformSockets)
-        self.initialized = True
+    socket_templates = LatticeDeformSockets
 
 
 class DeformerSmoothCorrectiveDeform(Node, DeformerNode):
 class DeformerSmoothCorrectiveDeform(Node, DeformerNode):
     '''A node representing a Corrective Smooth Deformer'''
     '''A node representing a Corrective Smooth Deformer'''
@@ -238,20 +221,13 @@ class DeformerSmoothCorrectiveDeform(Node, DeformerNode):
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     num_targets : bpy.props.IntProperty(default = 0)
     num_targets : bpy.props.IntProperty(default = 0)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
-    def init(self, context):
-        self.init_sockets(SmoothDeformSockets)
-        self.initialized = True
+    socket_templates = SmoothDeformSockets
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         use_corrective_smooth = self.inputs["Use Corrective Smooth"]
         use_corrective_smooth = self.inputs["Use Corrective Smooth"]
         if ( use_corrective_smooth.is_linked or 
         if ( use_corrective_smooth.is_linked or 
              use_corrective_smooth.default_value == False): # this is inverted
              use_corrective_smooth.default_value == False): # this is inverted
-                    self.inputs['Corrective Smooth Scale'].hide = False
+                self.inputs['Corrective Smooth Scale'].hide = False
         else:
         else:
-                    self.inputs['Corrective Smooth Scale'].hide = True
-
+                self.inputs['Corrective Smooth Scale'].hide = True
 
 
-# Set up the class property that ties the UI classes to the Mantis classes.
-for cls in TellClasses():
-    cls.set_mantis_class()

+ 44 - 149
link_nodes_ui.py

@@ -52,12 +52,8 @@ class LinkInheritNode(Node, LinkNode):
     bl_icon = 'CONSTRAINT_BONE'
     bl_icon = 'CONSTRAINT_BONE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     mantis_node_class_name="LinkInherit"
     mantis_node_class_name="LinkInherit"
-
-    def init(self, context):
-        self.init_sockets(LinkInheritSockets)
-        self.initialized = True
-        self.use_custom_color = True
-        self.color = inheritColor
+    socket_templates = LinkInheritSockets
+    category_color=inheritColor
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         node_tree = context.space_data.path[0].node_tree
         node_tree = context.space_data.path[0].node_tree
@@ -98,13 +94,8 @@ class LinkInverseKinematics(Node, LinkNode):
     bl_icon = 'CON_KINEMATIC'
     bl_icon = 'CON_KINEMATIC'
     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):
-        self.init_sockets(LinkInverseKinematicsSockets)
-        self.initialized = True
-        self.use_custom_color = True
-        self.color = ikColor
-
+    category_color=linkTransformColor
+    socket_templates = LinkInverseKinematicsSockets
 
 
 class LinkCopyLocationNode(Node, LinkNode):
 class LinkCopyLocationNode(Node, LinkNode):
     '''A node representing Copy Location'''
     '''A node representing Copy Location'''
@@ -113,13 +104,8 @@ class LinkCopyLocationNode(Node, LinkNode):
     bl_icon = 'CON_LOCLIKE'
     bl_icon = 'CON_LOCLIKE'
     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):
-        self.init_sockets(LinkCopyLocationSockets)
-        self.use_custom_color = True
-        self.color = linkTransformColor
-        self.initialized = True
-
+    category_color=linkTransformColor
+    socket_templates = LinkCopyLocationSockets
 
 
 class LinkCopyRotationNode(Node, LinkNode):
 class LinkCopyRotationNode(Node, LinkNode):
     '''A node representing Copy Rotation'''
     '''A node representing Copy Rotation'''
@@ -128,14 +114,8 @@ class LinkCopyRotationNode(Node, LinkNode):
     bl_icon = 'CON_ROTLIKE'
     bl_icon = 'CON_ROTLIKE'
     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):
-        self.init_sockets(LinkCopyRotationSockets)
-        self.use_custom_color = True
-        self.color = linkTransformColor
-        self.initialized = True
-
-
+    category_color=linkTransformColor
+    socket_templates = LinkCopyRotationSockets
 
 
 class LinkCopyScaleNode(Node, LinkNode):
 class LinkCopyScaleNode(Node, LinkNode):
     '''A node representing Copy Scale'''
     '''A node representing Copy Scale'''
@@ -144,14 +124,8 @@ class LinkCopyScaleNode(Node, LinkNode):
     bl_icon = 'CON_SIZELIKE'
     bl_icon = 'CON_SIZELIKE'
     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):
-        self.init_sockets(LinkCopyScaleSockets)
-        self.use_custom_color = True
-        self.color = linkTransformColor
-        self.initialized = True
-
-
+    category_color=linkTransformColor
+    socket_templates = LinkCopyScaleSockets
 
 
 class LinkInheritConstraintNode(Node, LinkNode):
 class LinkInheritConstraintNode(Node, LinkNode):
     # === Basics ===
     # === Basics ===
@@ -162,13 +136,8 @@ class LinkInheritConstraintNode(Node, LinkNode):
     bl_icon = 'CON_CHILDOF'
     bl_icon = 'CON_CHILDOF'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
-    # === Optional Functions ===
-    def init(self, context):
-        self.init_sockets(LinkInheritConstraintSockets)
-        self.use_custom_color = True
-        self.color = inheritColor
-        self.initialized = True
+    category_color=inheritColor
+    socket_templates = LinkInheritConstraintSockets
 
 
 class LinkCopyTransformNode(Node, LinkNode):
 class LinkCopyTransformNode(Node, LinkNode):
     # === Basics ===
     # === Basics ===
@@ -179,15 +148,8 @@ class LinkCopyTransformNode(Node, LinkNode):
     bl_icon = 'CON_TRANSLIKE'
     bl_icon = 'CON_TRANSLIKE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
-    # === Optional Functions ===
-    def init(self, context):
-        self.init_sockets(LinkCopyTransformsSockets)
-        self.use_custom_color = True
-        self.color = linkTransformColor
-        self.initialized = True
-
-
+    category_color=linkTransformColor
+    socket_templates = LinkCopyTransformsSockets
 
 
 class LinkStretchToNode(Node, LinkNode):
 class LinkStretchToNode(Node, LinkNode):
     '''A node representing Stretch-To'''
     '''A node representing Stretch-To'''
@@ -196,12 +158,8 @@ class LinkStretchToNode(Node, LinkNode):
     bl_icon = 'CON_STRETCHTO'
     bl_icon = 'CON_STRETCHTO'
     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):
-        self.init_sockets(LinkStretchToSockets)
-        self.initialized = True
-        self.use_custom_color = True
-        self.color = trackingColor
+    category_color=trackingColor
+    socket_templates = LinkStretchToSockets
 
 
 class LinkDampedTrackNode(Node, LinkNode):
 class LinkDampedTrackNode(Node, LinkNode):
     '''A node representing Stretch-To'''
     '''A node representing Stretch-To'''
@@ -210,12 +168,8 @@ class LinkDampedTrackNode(Node, LinkNode):
     bl_icon = 'CON_TRACKTO'
     bl_icon = 'CON_TRACKTO'
     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):
-        self.init_sockets(LinkDampedTrackSockets)
-        self.initialized = True
-        self.use_custom_color = True
-        self.color = trackingColor
+    category_color=trackingColor
+    socket_templates = LinkDampedTrackSockets
 
 
 class LinkLockedTrackNode(Node, LinkNode):
 class LinkLockedTrackNode(Node, LinkNode):
     '''A node representing Stretch-To'''
     '''A node representing Stretch-To'''
@@ -224,12 +178,8 @@ class LinkLockedTrackNode(Node, LinkNode):
     bl_icon = 'CON_LOCKTRACK'
     bl_icon = 'CON_LOCKTRACK'
     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):
-        self.init_sockets(LinkLockedTrackSockets)
-        self.initialized = True
-        self.use_custom_color = True
-        self.color = trackingColor
+    category_color=trackingColor
+    socket_templates = LinkLockedTrackSockets
 
 
 class LinkTrackToNode(Node, LinkNode):
 class LinkTrackToNode(Node, LinkNode):
     '''A node representing Stretch-To'''
     '''A node representing Stretch-To'''
@@ -238,12 +188,8 @@ class LinkTrackToNode(Node, LinkNode):
     bl_icon = 'CON_TRACKTO'
     bl_icon = 'CON_TRACKTO'
     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):
-        self.init_sockets(LinkTrackToSockets)
-        self.initialized = True
-        self.use_custom_color = True
-        self.color = trackingColor
+    category_color=trackingColor
+    socket_templates = LinkTrackToSockets
 
 
 class LinkLimitLocationNode(Node, LinkNode):
 class LinkLimitLocationNode(Node, LinkNode):
     '''A node representing Limit Location'''
     '''A node representing Limit Location'''
@@ -252,12 +198,8 @@ class LinkLimitLocationNode(Node, LinkNode):
     bl_icon = 'CON_LOCLIMIT'
     bl_icon = 'CON_LOCLIMIT'
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
-
-    def init(self, context):
-        self.init_sockets(LinkLimitLocationScaleSockets)
-        self.initialized = True
-        self.use_custom_color = True
-        self.color = linkTransformColor
+    category_color=linkTransformColor
+    socket_templates = LinkLimitLocationScaleSockets
 
 
 class LinkLimitScaleNode(Node, LinkNode):
 class LinkLimitScaleNode(Node, LinkNode):
     '''A node representing Limit Scale'''
     '''A node representing Limit Scale'''
@@ -266,12 +208,8 @@ class LinkLimitScaleNode(Node, LinkNode):
     bl_icon = 'CON_SIZELIMIT'
     bl_icon = 'CON_SIZELIMIT'
     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):
-        self.init_sockets(LinkLimitLocationScaleSockets)
-        self.initialized = True
-        self.use_custom_color = True
-        self.color = linkTransformColor
+    category_color=linkTransformColor
+    socket_templates = LinkLimitLocationScaleSockets
 
 
 class LinkLimitRotationNode(Node, LinkNode):
 class LinkLimitRotationNode(Node, LinkNode):
     '''A node representing Limit Rotation'''
     '''A node representing Limit Rotation'''
@@ -280,13 +218,8 @@ class LinkLimitRotationNode(Node, LinkNode):
     bl_icon = 'CON_ROTLIMIT'
     bl_icon = 'CON_ROTLIMIT'
     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):
-        self.init_sockets(LinkLimitRotationSockets)
-        self.initialized = True
-        # color
-        self.use_custom_color = True
-        self.color = linkTransformColor
+    category_color=linkTransformColor
+    socket_templates = LinkLimitRotationSockets
 
 
 class LinkLimitDistanceNode(Node, LinkNode):
 class LinkLimitDistanceNode(Node, LinkNode):
     '''A node representing Limit Distance'''
     '''A node representing Limit Distance'''
@@ -295,13 +228,8 @@ class LinkLimitDistanceNode(Node, LinkNode):
     bl_icon = 'CON_DISTLIMIT'
     bl_icon = 'CON_DISTLIMIT'
     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):
-        self.init_sockets(LinkLimitDistanceSockets)
-        self.use_custom_color = True
-        self.color = linkTransformColor
-        self.initialized = True
-
+    category_color=linkTransformColor
+    socket_templates = LinkLimitDistanceSockets
 
 
 class LinkTransformationNode(Node, LinkNode):
 class LinkTransformationNode(Node, LinkNode):
     '''A node representing Transformation (Constraint)'''
     '''A node representing Transformation (Constraint)'''
@@ -310,12 +238,8 @@ class LinkTransformationNode(Node, LinkNode):
     bl_icon = 'CON_TRANSFORM'
     bl_icon = 'CON_TRANSFORM'
     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):
-        self.init_sockets(LinkTransformationSockets)
-        self.use_custom_color = True
-        self.color = linkTransformColor
-        self.initialized = True
+    category_color=linkTransformColor
+    socket_templates = LinkTransformationSockets
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         node_tree = context.space_data.path[0].node_tree
         node_tree = context.space_data.path[0].node_tree
@@ -348,12 +272,8 @@ class LinkArmatureNode(Node, LinkNode):
     bl_icon = "CON_ARMATURE"
     bl_icon = "CON_ARMATURE"
     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):
-        self.init_sockets(LinkArmatureSockets)
-        self.use_custom_color = True
-        self.color = inheritColor
-        self.initialized = True
+    category_color=inheritColor
+    socket_templates = LinkArmatureSockets
 
 
     def draw_buttons(self, context, layout):
     def draw_buttons(self, context, layout):
         # return
         # return
@@ -370,12 +290,8 @@ class LinkSplineIKNode(Node, LinkNode):
     bl_icon = "CON_SPLINEIK"
     bl_icon = "CON_SPLINEIK"
     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):
-        self.init_sockets(LinkSplineIKSockets)
-        self.use_custom_color = True
-        self.color = ikColor
-        self.initialized = True
+    category_color=ikColor
+    socket_templates = LinkSplineIKSockets
 
 
 class LinkFloorNode(Node, LinkNode):
 class LinkFloorNode(Node, LinkNode):
     """A node representing Blender's Floor Constraint"""
     """A node representing Blender's Floor Constraint"""
@@ -384,12 +300,8 @@ class LinkFloorNode(Node, LinkNode):
     bl_icon = "CON_FLOOR"
     bl_icon = "CON_FLOOR"
     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):
-        self.init_sockets(LinkFloorSockets)
-        self.use_custom_color = True
-        self.color = linkTransformColor
-        self.initialized = True
+    category_color=linkTransformColor
+    socket_templates = LinkFloorSockets
 
 
 class LinkShrinkWrapNode(Node, LinkNode):
 class LinkShrinkWrapNode(Node, LinkNode):
     """A node representing Blender's Shrinkwrap Constraint"""
     """A node representing Blender's Shrinkwrap Constraint"""
@@ -398,12 +310,8 @@ class LinkShrinkWrapNode(Node, LinkNode):
     bl_icon = "CON_SHRINKWRAP"
     bl_icon = "CON_SHRINKWRAP"
     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):
-        self.init_sockets(LinkShrinkWrapSockets)
-        self.use_custom_color = True
-        self.color = trackingColor
-        self.initialized = True
+    category_color=trackingColor
+    socket_templates = LinkShrinkWrapSockets
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         # vast majority of the time user doesn't link this.
         # vast majority of the time user doesn't link this.
@@ -445,12 +353,8 @@ class LinkGeometryAttribute(Node, LinkNode):
         bl_icon = "ERROR"
         bl_icon = "ERROR"
     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):
-        self.init_sockets(LinkGeometryAttributeSockets)
-        self.use_custom_color = True
-        self.color = linkTransformColor
-        self.initialized = True
+    category_color=linkTransformColor
+    socket_templates = LinkGeometryAttributeSockets
     
     
     def draw_label(self):
     def draw_label(self):
         if bpy.app.version < (5,0,0):
         if bpy.app.version < (5,0,0):
@@ -465,7 +369,6 @@ class LinkGeometryAttribute(Node, LinkNode):
         elif self.color != linkTransformColor:
         elif self.color != linkTransformColor:
             self.color = linkTransformColor
             self.color = linkTransformColor
 
 
-
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         if bpy.app.version < (5,0,0):
         if bpy.app.version < (5,0,0):
             return
             return
@@ -487,13 +390,5 @@ class LinkDrivenParameterNode(Node, LinkNode):
     bl_icon = "CONSTRAINT_BONE"
     bl_icon = "CONSTRAINT_BONE"
     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):
-        self.init_sockets(LinkDrivenParameterSockets)
-        self.use_custom_color = True
-        self.color = linkTransformColor
-        self.initialized = True
-
-# Set up the class property that ties the UI classes to the Mantis classes.
-for cls in TellClasses():
-    cls.set_mantis_class()
+    category_color=linkTransformColor
+    socket_templates = LinkDrivenParameterSockets

+ 7 - 23
math_nodes_ui.py

@@ -1,5 +1,5 @@
 import bpy
 import bpy
-from .base_definitions import MantisUINode
+from .base_definitions import MantisMathUINode
 from bpy.types import Node
 from bpy.types import Node
 from .utilities import (prRed, prGreen, prPurple, prWhite,
 from .utilities import (prRed, prGreen, prPurple, prWhite,
                               prOrange,
                               prOrange,
@@ -16,19 +16,14 @@ def TellClasses():
      MathStaticVectorNode,
      MathStaticVectorNode,
     ]
     ]
 
 
-
-class MathStaticInt(Node, MantisUINode):
+class MathStaticInt(Node, MantisMathUINode):
     """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"
     bl_label = "Static Int Math"
     bl_label = "Static Int Math"
     bl_icon = "NODE"
     bl_icon = "NODE"
     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):
-        self.init_sockets(StaticIntSockets)
-        self.initialized = True
+    socket_templates = StaticIntSockets
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         if context.space_data:
         if context.space_data:
@@ -40,17 +35,14 @@ class MathStaticInt(Node, MantisUINode):
             else:
             else:
                 self.inputs["Int B"].hide = False
                 self.inputs["Int B"].hide = False
 
 
-class MathStaticFloatNode(Node, MantisUINode):
+class MathStaticFloatNode(Node, MantisMathUINode):
     """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"
     bl_label = "Static Float Math"
     bl_label = "Static Float Math"
     bl_icon = "NODE"
     bl_icon = "NODE"
     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):
-        self.init_sockets(StaticFloatSockets)
-        self.initialized = True
+    socket_templates = StaticFloatSockets
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         if context.space_data:
         if context.space_data:
@@ -62,17 +54,14 @@ class MathStaticFloatNode(Node, MantisUINode):
             else:
             else:
                 self.inputs["Float B"].hide = False
                 self.inputs["Float B"].hide = False
 
 
-class MathStaticVectorNode(Node, MantisUINode):
+class MathStaticVectorNode(Node, MantisMathUINode):
     """Performs a vector math operation as a preprocess before executing the tree."""
     """Performs a vector math operation as a preprocess before executing the tree."""
     bl_idname = "MathStaticVector"
     bl_idname = "MathStaticVector"
     bl_label = "Static Vector Math"
     bl_label = "Static Vector Math"
     bl_icon = "NODE"
     bl_icon = "NODE"
     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):
-        self.init_sockets(StaticVectorSockets)
-        self.initialized = True
+    socket_templates = StaticVectorSockets
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         if context.space_data:
         if context.space_data:
@@ -100,8 +89,3 @@ class MathStaticVectorNode(Node, MantisUINode):
             else:
             else:
                 self.inputs["Vector B"].hide = False
                 self.inputs["Vector B"].hide = False
                 self.inputs["Scalar A"].hide = True
                 self.inputs["Scalar A"].hide = True
-
-# Set up the class property that ties the UI classes to the Mantis classes.
-for cls in TellClasses():
-    cls.mantis_node_library='.math_nodes'
-    cls.set_mantis_class()

+ 132 - 302
misc_nodes_ui.py

@@ -1,6 +1,6 @@
 import bpy
 import bpy
 from bpy.types import Node
 from bpy.types import Node
-from .base_definitions import MantisUINode, get_signature_from_edited_tree
+from .base_definitions import MantisMiscNode, get_signature_from_edited_tree
 from .misc_nodes_socket_templates import *
 from .misc_nodes_socket_templates import *
 
 
 from .utilities import (prRed, prGreen, prPurple, prWhite,
 from .utilities import (prRed, prGreen, prPurple, prWhite,
@@ -92,87 +92,73 @@ def socket_data_from_collection_paths(root_data, root_name, path, socket_data):
         path.pop()
         path.pop()
     return socket_data
     return socket_data
 
 
-class InputFloatNode(Node, MantisUINode):
+#################################################
+# Base Classes for the Misc Nodes
+#################################################
+
+class SimpleInputNode(MantisMiscNode):
+    def init(self, context):
+        super().init(context)
+        for s in self.outputs:
+            s.input=True # give it the property that makes it draw correctly
+
+class InputFloatNode(Node, SimpleInputNode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputFloatNode'
     bl_idname = 'InputFloatNode'
     bl_label = "Float"
     bl_label = "Float"
     mantis_node_class_name=bl_idname[:-4]
     mantis_node_class_name=bl_idname[:-4]
+    socket_templates=InputFloatSockets
 
 
-    def init(self, context):
-        self.init_sockets(InputFloatSockets)
-        self.initialized = True
-
-class InputIntNode(Node, MantisUINode):
+class InputIntNode(Node, SimpleInputNode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputIntNode'
     bl_idname = 'InputIntNode'
     bl_label = "Integer"
     bl_label = "Integer"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
-    def init(self, context):
-        self.init_sockets(InputIntSockets)
-        self.initialized = True
+    socket_templates=InputIntSockets
     
     
-class InputVectorNode(Node, MantisUINode):
+class InputVectorNode(Node, SimpleInputNode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputVectorNode'
     bl_idname = 'InputVectorNode'
     bl_label = "Vector"
     bl_label = "Vector"
     mantis_node_class_name=bl_idname[:-4]
     mantis_node_class_name=bl_idname[:-4]
+    socket_templates=InputVectorSockets
 
 
-    def init(self, context):
-        self.init_sockets(InputVectorSockets)
-        self.initialized = True
-
-class InputBooleanNode(Node, MantisUINode):
+class InputBooleanNode(Node, SimpleInputNode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputBooleanNode'
     bl_idname = 'InputBooleanNode'
     bl_label = "Boolean"
     bl_label = "Boolean"
     mantis_node_class_name=bl_idname[:-4]
     mantis_node_class_name=bl_idname[:-4]
+    socket_templates=InputBooleanSockets
 
 
-    def init(self, context):
-        self.init_sockets(InputBooleanSockets)
-        self.initialized = True
-
-class InputBooleanThreeTupleNode(Node, MantisUINode):
+class InputBooleanThreeTupleNode(Node, SimpleInputNode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputBooleanThreeTupleNode'
     bl_idname = 'InputBooleanThreeTupleNode'
     bl_label = "Boolean Vector"
     bl_label = "Boolean Vector"
     mantis_node_class_name=bl_idname[:-4]
     mantis_node_class_name=bl_idname[:-4]
+    socket_templates=InputBooleanThreeTupleSockets
 
 
-    def init(self, context):
-        self.init_sockets(InputBooleanThreeTupleSockets)
-        self.initialized = True
-
-class InputRotationOrderNode(Node, MantisUINode):
+class InputRotationOrderNode(Node, SimpleInputNode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputRotationOrderNode'
     bl_idname = 'InputRotationOrderNode'
     bl_label = "Rotation Order"
     bl_label = "Rotation Order"
     mantis_node_class_name=bl_idname[:-4]
     mantis_node_class_name=bl_idname[:-4]
+    socket_templates=InputRotationOrderSockets
 
 
-    def init(self, context):
-        self.init_sockets(InputRotationOrderSockets)
-        self.initialized = True
-
-class InputTransformSpaceNode(Node, MantisUINode):
+class InputTransformSpaceNode(Node, SimpleInputNode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputTransformSpaceNode'
     bl_idname = 'InputTransformSpaceNode'
     bl_label = "Transform Space"
     bl_label = "Transform Space"
     mantis_node_class_name=bl_idname[:-4]
     mantis_node_class_name=bl_idname[:-4]
+    socket_templates=InputTransformSpaceSockets
 
 
-    def init(self, context):
-        self.init_sockets(InputTransformSpaceSockets)
-        self.initialized = True
-
-class InputStringNode(Node, MantisUINode):
+class InputStringNode(Node, SimpleInputNode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputStringNode'
     bl_idname = 'InputStringNode'
     bl_label = "String"
     bl_label = "String"
     mantis_node_class_name=bl_idname[:-4]
     mantis_node_class_name=bl_idname[:-4]
+    socket_templates=InputStringSockets
 
 
-    def init(self, context):
-        self.init_sockets(InputStringSockets)
-        self.initialized = True
-
-class InputMatrixNode(Node, MantisUINode):
+class InputMatrixNode(Node, SimpleInputNode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputMatrixNode'
     bl_idname = 'InputMatrixNode'
     bl_label = "Matrix"
     bl_label = "Matrix"
@@ -203,7 +189,7 @@ class InputMatrixNode(Node, MantisUINode):
         mat_sock = self.outputs[0]
         mat_sock = self.outputs[0]
         mat_sock.default_value = self.set_matrix()
         mat_sock.default_value = self.set_matrix()
 
 
-class InputThemeBoneColorSets(Node, MantisUINode):
+class InputThemeBoneColorSets(Node, MantisMiscNode):
     """Displays the theme's colors."""
     """Displays the theme's colors."""
     bl_idname = "InputThemeBoneColorSets"
     bl_idname = "InputThemeBoneColorSets"
     bl_label = "Theme Colors"
     bl_label = "Theme Colors"
@@ -217,7 +203,7 @@ class InputThemeBoneColorSets(Node, MantisUINode):
             s.color_index=i
             s.color_index=i
         self.initialized = True
         self.initialized = True
 
 
-class InputColorSetPallete(Node, MantisUINode):
+class InputColorSetPallete(Node, MantisMiscNode):
     """Displays the theme's colors."""
     """Displays the theme's colors."""
     bl_idname = "InputColorSetPallete"
     bl_idname = "InputColorSetPallete"
     bl_label = "Color Pallete"
     bl_label = "Color Pallete"
@@ -233,64 +219,46 @@ class InputColorSetPallete(Node, MantisUINode):
         ops_props.tree_invoked = self.id_data.name
         ops_props.tree_invoked = self.id_data.name
         ops_props.node_invoked = self.name
         ops_props.node_invoked = self.name
 
 
-class UtilityMatrixFromCurve(Node, MantisUINode):
+class UtilityMatrixFromCurve(Node, MantisMiscNode):
     """Gets a matrix from a curve."""
     """Gets a matrix from a curve."""
     bl_idname = "UtilityMatrixFromCurve"
     bl_idname = "UtilityMatrixFromCurve"
     bl_label = "Matrix from Curve"
     bl_label = "Matrix from Curve"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatrixFromCurveSockets)
-        self.initialized = True
+    socket_templates=MatrixFromCurveSockets
 
 
-class UtilityPointFromCurve(Node, MantisUINode):
+class UtilityPointFromCurve(Node, MantisMiscNode):
     """Gets a point from a curve."""
     """Gets a point from a curve."""
     bl_idname = "UtilityPointFromCurve"
     bl_idname = "UtilityPointFromCurve"
     bl_label = "Point from Curve"
     bl_label = "Point from Curve"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(PointFromCurveSockets)
-        self.initialized = True
+    socket_templates=PointFromCurveSockets
 
 
-class UtilityNumberOfCurveSegments(Node, MantisUINode):
+class UtilityNumberOfCurveSegments(Node, MantisMiscNode):
     """Tells the number of segments in a curve."""
     """Tells the number of segments in a curve."""
     bl_idname = "UtilityNumberOfCurveSegments"
     bl_idname = "UtilityNumberOfCurveSegments"
     bl_label = "Number of Curve Segments"
     bl_label = "Number of Curve Segments"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
+    socket_templates=NumberOfCurveSegmentsSockets
     
     
-    def init(self, context):
-        self.init_sockets(NumberOfCurveSegmentsSockets)
-        self.initialized = True
-    
-class UtilityNumberOfSplines(Node, MantisUINode):
+class UtilityNumberOfSplines(Node, MantisMiscNode):
     """Tells the number of splines in a curve."""
     """Tells the number of splines in a curve."""
     bl_idname = "UtilityNumberOfSplines"
     bl_idname = "UtilityNumberOfSplines"
     bl_label = "Number of Splines"
     bl_label = "Number of Splines"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(NumberOfSplinesSockets)
-        self.initialized = True
+    socket_templates=NumberOfSplinesSockets
 
 
-class UtilityMatrixFromCurveSegment(Node, MantisUINode):
+class UtilityMatrixFromCurveSegment(Node, MantisMiscNode):
     """Gets a matrix from a curve segment."""
     """Gets a matrix from a curve segment."""
     bl_idname = "UtilityMatrixFromCurveSegment"
     bl_idname = "UtilityMatrixFromCurveSegment"
     bl_label = "Matrix from Curve Segment"
     bl_label = "Matrix from Curve Segment"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatrixFromCurveSegmentSockets)
-        self.initialized = True
+    socket_templates=MatrixFromCurveSegmentSockets
 
 
-class UtilityGetCurvePoint(Node, MantisUINode):
+class UtilityGetCurvePoint(Node, MantisMiscNode):
     bl_idname = 'UtilityGetCurvePoint'
     bl_idname = 'UtilityGetCurvePoint'
     bl_label = "Control Point from Curve"
     bl_label = "Control Point from Curve"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-
-    def init(self, context):
-        self.init_sockets(GetCurvePointSockets)
-        self.initialized = True
+    socket_templates=GetCurvePointSockets
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         self.outputs["Point"].hide=False
         self.outputs["Point"].hide=False
@@ -313,15 +281,12 @@ class UtilityGetCurvePoint(Node, MantisUINode):
                 self.outputs["Left Handle"].hide=False
                 self.outputs["Left Handle"].hide=False
                 self.outputs["Right Handle"].hide=False
                 self.outputs["Right Handle"].hide=False
     
     
-class UtilityMatricesFromCurve(Node, MantisUINode):
+class UtilityMatricesFromCurve(Node, MantisMiscNode):
     """Gets a matrix from a curve."""
     """Gets a matrix from a curve."""
     bl_idname = "UtilityMatricesFromCurve"
     bl_idname = "UtilityMatricesFromCurve"
     bl_label = "Matrices from Curve"
     bl_label = "Matrices from Curve"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatricesFromCurveSockets)
-        self.initialized = True
+    socket_templates=MatricesFromCurveSockets
 
 
 def display_update_choose_nearest(self, parsed_tree, context):
 def display_update_choose_nearest(self, parsed_tree, context):
     number_of_points = self.inputs['Number to Find'].default_value
     number_of_points = self.inputs['Number to Find'].default_value
@@ -336,52 +301,40 @@ def display_update_choose_nearest(self, parsed_tree, context):
     else:
     else:
         self.outputs.display_shape = 'CIRCLE'
         self.outputs.display_shape = 'CIRCLE'
 
 
-class UtilityGetNearestFactorOnCurve(Node, MantisUINode):
+class UtilityGetNearestFactorOnCurve(Node, MantisMiscNode):
     bl_idname = 'UtilityGetNearestFactorOnCurve'
     bl_idname = 'UtilityGetNearestFactorOnCurve'
     bl_label = "Get Factor on Curve at Point"
     bl_label = "Get Factor on Curve at Point"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
+    socket_templates=GetNearestFactorOnCurveSockets
 
 
-    def init(self, context):
-        self.init_sockets(GetNearestFactorOnCurveSockets)
-        self.initialized = True
-
-class UtilityKDChoosePoint(Node, MantisUINode):
+class UtilityKDChoosePoint(Node, MantisMiscNode):
     """Chooses the nearest point with a KD Tree."""
     """Chooses the nearest point with a KD Tree."""
     bl_idname = "UtilityKDChoosePoint"
     bl_idname = "UtilityKDChoosePoint"
     bl_label = "Choose Nearest Point"
     bl_label = "Choose Nearest Point"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(KDChoosePointSockets)
-        self.initialized = True
+    socket_templates=KDChoosePointSockets
     
     
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         display_update_choose_nearest(self, parsed_tree, context)
         display_update_choose_nearest(self, parsed_tree, context)
 
 
-class UtilityKDChooseXForm(Node, MantisUINode):
+class UtilityKDChooseXForm(Node, MantisMiscNode):
     """Chooses the nearest xForm with a KD Tree."""
     """Chooses the nearest xForm with a KD Tree."""
     bl_idname = "UtilityKDChooseXForm"
     bl_idname = "UtilityKDChooseXForm"
     bl_label = "Choose Nearest xForm"
     bl_label = "Choose Nearest xForm"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(KDChooseXFormSockets)
-        self.initialized = True
+    socket_templates=KDChooseXFormSockets
     
     
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         display_update_choose_nearest(self, parsed_tree, context)
         display_update_choose_nearest(self, parsed_tree, context)
 
 
-class UtilityMetaRigNode(Node, MantisUINode):
+class UtilityMetaRigNode(Node, MantisMiscNode):
     """Gets a matrix from a meta-rig bone."""
     """Gets a matrix from a meta-rig bone."""
     bl_idname = "UtilityMetaRig"
     bl_idname = "UtilityMetaRig"
     bl_label = "Meta-Rig"
     bl_label = "Meta-Rig"
     armature:bpy.props.StringProperty()
     armature:bpy.props.StringProperty()
     pose_bone:bpy.props.StringProperty()
     pose_bone:bpy.props.StringProperty()
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MetaRigSockets)
-        self.initialized = True
+    socket_templates=MetaRigSockets
     
     
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         mantis_node = parsed_tree.get(get_signature_from_edited_tree(self, context))
         mantis_node = parsed_tree.get(get_signature_from_edited_tree(self, context))
@@ -397,28 +350,22 @@ class UtilityMetaRigNode(Node, MantisUINode):
         if self.inputs["Meta-Bone"].is_linked:
         if self.inputs["Meta-Bone"].is_linked:
             self.inputs["Meta-Bone"].search_prop = None
             self.inputs["Meta-Bone"].search_prop = None
 
 
-class UtilityBonePropertiesNode(Node, MantisUINode):
+class UtilityBonePropertiesNode(Node, MantisMiscNode):
     """Provides as sockets strings identifying bone transform properties."""
     """Provides as sockets strings identifying bone transform properties."""
     bl_idname = "UtilityBoneProperties"
     bl_idname = "UtilityBoneProperties"
     bl_label = "Bone Properties"
     bl_label = "Bone Properties"
     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):
-        self.init_sockets(BonePropertiesSockets)
-        self.initialized = True
+    socket_templates=BonePropertiesSockets
         
         
 
 
-class UtilityDriverVariableNode(Node, MantisUINode):
+class UtilityDriverVariableNode(Node, MantisMiscNode):
     """Creates a variable for use in a driver."""
     """Creates a variable for use in a driver."""
     bl_idname = "UtilityDriverVariable"
     bl_idname = "UtilityDriverVariable"
     bl_label = "Driver Variable"
     bl_label = "Driver Variable"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(DriverVariableSockets)
-        self.initialized = True
-    
+    socket_templates=DriverVariableSockets
+
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         if self.inputs["Variable Type"].is_linked:
         if self.inputs["Variable Type"].is_linked:
             if context.space_data:
             if context.space_data:
@@ -461,17 +408,13 @@ class UtilityDriverVariableNode(Node, MantisUINode):
 # TODO: make a way to edit the fCurve directly.
 # TODO: make a way to edit the fCurve directly.
 # I had a working version of this in the past, but it required doing sinful things like
 # I had a working version of this in the past, but it required doing sinful things like
 # keeping track of the RAM address of the window.
 # keeping track of the RAM address of the window.
-class UtilityFCurveNode(Node, MantisUINode):
+class UtilityFCurveNode(Node, MantisMiscNode):
     """Creates an fCurve for use with a driver."""
     """Creates an fCurve for use with a driver."""
     bl_idname = "UtilityFCurve"
     bl_idname = "UtilityFCurve"
     bl_label = "fCurve"
     bl_label = "fCurve"
-    
-    use_kf_nodes   : bpy.props.BoolProperty(default=True)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(FCurveSockets)
-        self.initialized = True
+    socket_templates=FCurveSockets
+    use_kf_nodes   : bpy.props.BoolProperty(default=True)
             
             
     def draw_buttons(self, context, layout):
     def draw_buttons(self, context, layout):
         layout.operator( 'mantis.fcurve_node_add_kf' )
         layout.operator( 'mantis.fcurve_node_add_kf' )
@@ -479,16 +422,13 @@ class UtilityFCurveNode(Node, MantisUINode):
             layout.operator( 'mantis.fcurve_node_remove_kf' )
             layout.operator( 'mantis.fcurve_node_remove_kf' )
 
 
 
 
-class UtilityDriverNode(Node, MantisUINode):
+class UtilityDriverNode(Node, MantisMiscNode):
     """Represents a Driver relationship"""
     """Represents a Driver relationship"""
     bl_idname = "UtilityDriver"
     bl_idname = "UtilityDriver"
     bl_label = "Driver"
     bl_label = "Driver"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
+    socket_templates=DriverSockets
     
     
-    def init(self, context):
-        self.init_sockets(DriverSockets)
-        self.initialized = True
-        
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         if not self.inputs["Driver Type"].is_linked:
         if not self.inputs["Driver Type"].is_linked:
             dType = self.inputs["Driver Type"].default_value
             dType = self.inputs["Driver Type"].default_value
@@ -506,54 +446,40 @@ class UtilityDriverNode(Node, MantisUINode):
         if (len(self.inputs) > 3):
         if (len(self.inputs) > 3):
             layout.operator( 'mantis.driver_node_remove_variable' )
             layout.operator( 'mantis.driver_node_remove_variable' )
 
 
-class UtilitySwitchNode(Node, MantisUINode):
+class UtilitySwitchNode(Node, MantisMiscNode):
     """Represents a switch relationship between one driver property and one or more driven properties."""
     """Represents a switch relationship between one driver property and one or more driven properties."""
     bl_idname = "UtilitySwitch"
     bl_idname = "UtilitySwitch"
     bl_label = "Switch"
     bl_label = "Switch"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(SwitchSockets)
-        self.initialized = True
+    socket_templates=SwitchSockets
 
 
-class UtilityCombineThreeBoolNode(Node, MantisUINode):
+class UtilityCombineThreeBoolNode(Node, MantisMiscNode):
     """Combines three booleans into a three-bool."""
     """Combines three booleans into a three-bool."""
     bl_idname = "UtilityCombineThreeBool"
     bl_idname = "UtilityCombineThreeBool"
     bl_label = "CombineThreeBool"
     bl_label = "CombineThreeBool"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(CombineThreeBoolSockets)
-        self.initialized = True
+    socket_templates=CombineThreeBoolSockets
 
 
-class UtilityCombineVectorNode(Node, MantisUINode):
+class UtilityCombineVectorNode(Node, MantisMiscNode):
     """Combines three floats into a vector."""
     """Combines three floats into a vector."""
     bl_idname = "UtilityCombineVector"
     bl_idname = "UtilityCombineVector"
     bl_label = "CombineVector"
     bl_label = "CombineVector"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(CombineVectorSockets)
+    socket_templates=CombineVectorSockets
         
         
-class UtilitySeparateVector(Node, MantisUINode):
+class UtilitySeparateVector(Node, MantisMiscNode):
     """Separates a vector into three floats"""
     """Separates a vector into three floats"""
     bl_idname = "UtilitySeparateVector"
     bl_idname = "UtilitySeparateVector"
     bl_label = "Separate Vector"
     bl_label = "Separate Vector"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(SeparateVectorSockets)
-        self.initialized = True
+    socket_templates=SeparateVectorSockets
         
         
-class UtilityCatStringsNode(Node, MantisUINode):
+class UtilityCatStringsNode(Node, MantisMiscNode):
     """Combines multiple strings into one."""
     """Combines multiple strings into one."""
     bl_idname = "UtilityCatStrings"
     bl_idname = "UtilityCatStrings"
     bl_label = "Join Strings"
     bl_label = "Join Strings"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(CatStringsSockets)
-        self.initialized = True
+    socket_templates=CatStringsSockets
 
 
     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
         if self.label:
         if self.label:
@@ -578,27 +504,21 @@ class UtilityCatStringsNode(Node, MantisUINode):
                     return # the tree isn't ready yet.
                     return # the tree isn't ready yet.
                 
                 
 
 
-class InputWidget(Node, MantisUINode):
+class InputWidget(Node, MantisMiscNode):
     """Fetches a Widget from the Widget Library."""
     """Fetches a Widget from the Widget Library."""
     bl_idname = "InputWidget"
     bl_idname = "InputWidget"
     bl_label = "Widget"
     bl_label = "Widget"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
+    socket_templates=InputWidgetSockets
     
     
-    def init(self, context):
-        self.init_sockets(InputWidgetSockets)
-        self.initialized = True
-    
-class InputExistingGeometryObjectNode(Node, MantisUINode):
+class InputExistingGeometryObjectNode(Node, MantisMiscNode):
     """Represents an existing geometry object from within the scene."""
     """Represents an existing geometry object from within the scene."""
     bl_idname = "InputExistingGeometryObject"
     bl_idname = "InputExistingGeometryObject"
     bl_label = "Existing Object"
     bl_label = "Existing Object"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
     # We want Mantis to import widgets and stuff, so we hold a reference to the object
     # We want Mantis to import widgets and stuff, so we hold a reference to the object
-    object_reference : bpy.props.PointerProperty(type=bpy.types.Object,) 
-    
-    def init(self, context):
-        self.init_sockets(InputExistingGeometryObjectSockets)
-        self.initialized = True
+    object_reference : bpy.props.PointerProperty(type=bpy.types.Object,)
+    socket_templates=InputExistingGeometryObjectSockets
     
     
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         mantis_node = parsed_tree.get(get_signature_from_edited_tree(self, context))
         mantis_node = parsed_tree.get(get_signature_from_edited_tree(self, context))
@@ -607,25 +527,20 @@ class InputExistingGeometryObjectNode(Node, MantisUINode):
     
     
 # TODO: maybe I should hold a data reference here, too.
 # TODO: maybe I should hold a data reference here, too.
 #       but it is complicated by the fact that Mantis does not distinguish b/tw geo types
 #       but it is complicated by the fact that Mantis does not distinguish b/tw geo types
-class InputExistingGeometryDataNode(Node, MantisUINode):
+class InputExistingGeometryDataNode(Node, MantisMiscNode):
     """Represents a mesh or curve datablock from the scene."""
     """Represents a mesh or curve datablock from the scene."""
     bl_idname = "InputExistingGeometryData"
     bl_idname = "InputExistingGeometryData"
     bl_label = "Existing Geometry"
     bl_label = "Existing Geometry"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(InputExistingGeometrySockets)
-        self.initialized = True
+    socket_templates=InputExistingGeometrySockets
 
 
-class UtilityCustomProperty(Node, MantisUINode):
+class UtilityCustomProperty(Node, MantisMiscNode):
     """A declaration of a custom property."""
     """A declaration of a custom property."""
     bl_idname = "UtilityCustomProperty"
     bl_idname = "UtilityCustomProperty"
     bl_label  = "Custom Property"
     bl_label  = "Custom Property"
     bl_icon   = "NODE"
     bl_icon   = "NODE"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    def init(self, context):
-        self.init_sockets(UtilityCustomPropertySockets)
-        self.initialized = True
+    socket_templates=UtilityCustomPropertySockets
     
     
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         mantis_node = parsed_tree.get(get_signature_from_edited_tree(self, context))
         mantis_node = parsed_tree.get(get_signature_from_edited_tree(self, context))
@@ -656,7 +571,7 @@ class UtilityCustomProperty(Node, MantisUINode):
             return self.inputs['Name'].display_text
             return self.inputs['Name'].display_text
         return self.name
         return self.name
 
 
-class UtilityDeclareCollections(Node, MantisUINode):
+class UtilityDeclareCollections(Node, MantisMiscNode):
     """A utility used to declare bone collections."""
     """A utility used to declare bone collections."""
     bl_idname = "UtilityDeclareCollections"
     bl_idname = "UtilityDeclareCollections"
     bl_label  = "Collections"
     bl_label  = "Collections"
@@ -707,89 +622,66 @@ class UtilityDeclareCollections(Node, MantisUINode):
         op_props.socket_invoked = '' # this isn't reset between invocations
         op_props.socket_invoked = '' # this isn't reset between invocations
         # so we have to make sure to unset it when running it from the node
         # so we have to make sure to unset it when running it from the node
 
 
-class UtilityCollectionJoin(Node, MantisUINode):
+class UtilityCollectionJoin(Node, MantisMiscNode):
     """A utility used to join bone collection declarations."""
     """A utility used to join bone collection declarations."""
     bl_idname = "UtilityCollectionJoin"
     bl_idname = "UtilityCollectionJoin"
     bl_label  = "Join Collection Declarations"
     bl_label  = "Join Collection Declarations"
     bl_icon   = "NODE"
     bl_icon   = "NODE"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    def init(self, context):
-        self.init_sockets(CollectionJoinSockets)
-        self.initialized = True
+    socket_templates=CollectionJoinSockets
 
 
-class UtilityCollectionHierarchy(Node, MantisUINode):
+class UtilityCollectionHierarchy(Node, MantisMiscNode):
     """A utility used to declare bone collection hierarchies."""
     """A utility used to declare bone collection hierarchies."""
     bl_idname = "UtilityCollectionHierarchy"
     bl_idname = "UtilityCollectionHierarchy"
     bl_label  = "Collection Child Declaration"
     bl_label  = "Collection Child Declaration"
     bl_icon   = "NODE"
     bl_icon   = "NODE"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    def init(self, context):
-        self.init_sockets(CollectionHierarchySockets)
-        self.initialized = True
+    socket_templates=CollectionHierarchySockets
         
         
-class UtilityGeometryOfXForm(Node, MantisUINode):
+class UtilityGeometryOfXForm(Node, MantisMiscNode):
     """Retrieves a mesh or curve datablock from an xForm."""
     """Retrieves a mesh or curve datablock from an xForm."""
     bl_idname = "UtilityGeometryOfXForm"
     bl_idname = "UtilityGeometryOfXForm"
     bl_label = "Geometry of xForm"
     bl_label = "Geometry of xForm"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(GeometryOfXFormSockets)
-        self.initialized = True
-
+    socket_templates=GeometryOfXFormSockets
 
 
-class UtilityNameOfXForm(Node, MantisUINode):
+class UtilityNameOfXForm(Node, MantisMiscNode):
     """Retrieves the name of a xForm."""
     """Retrieves the name of a xForm."""
     bl_idname = "UtilityNameOfXForm"
     bl_idname = "UtilityNameOfXForm"
     bl_label = "Name of xForm"
     bl_label = "Name of xForm"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(NameOfXFormSockets)
-        self.initialized = True
+    socket_templates=NameOfXFormSockets
 
 
-class UtilityGetBoneLength(Node, MantisUINode):
+class UtilityGetBoneLength(Node, MantisMiscNode):
     """Returns the length of the bone from its matrix."""
     """Returns the length of the bone from its matrix."""
     bl_idname = "UtilityGetBoneLength"
     bl_idname = "UtilityGetBoneLength"
     bl_label = "Get Bone Length"
     bl_label = "Get Bone Length"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(GetBoneLengthSockets)
-        self.initialized = True
+    socket_templates=GetBoneLengthSockets
 
 
 # TODO: make it work with BBones!
 # TODO: make it work with BBones!
-class UtilityPointFromBoneMatrix(Node, MantisUINode):
+class UtilityPointFromBoneMatrix(Node, MantisMiscNode):
     """Returns a point representing the location along a bone, given a matrix representing that bone's shape."""
     """Returns a point representing the location along a bone, given a matrix representing that bone's shape."""
     bl_idname = "UtilityPointFromBoneMatrix"
     bl_idname = "UtilityPointFromBoneMatrix"
     bl_label = "Point from Bone Matrix"
     bl_label = "Point from Bone Matrix"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(PointFromBoneMatrixSockets)
-        self.initialized = True
+    socket_templates=PointFromBoneMatrixSockets
 
 
-class UtilitySetBoneLength(Node, MantisUINode):
+class UtilitySetBoneLength(Node, MantisMiscNode):
     """Sets the length of a bone matrix."""
     """Sets the length of a bone matrix."""
     bl_idname = "UtilitySetBoneLength"
     bl_idname = "UtilitySetBoneLength"
     bl_label = "Set Bone Matrix Length"
     bl_label = "Set Bone Matrix Length"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(SetBoneLengthSockets)
-        self.initialized = True
+    socket_templates=SetBoneLengthSockets
 
 
 # TODO: more keyframe types should be supported in the future.
 # TODO: more keyframe types should be supported in the future.
 # Some of the code that can do this is commented out here until I can implement it properly.
 # Some of the code that can do this is commented out here until I can implement it properly.
-class UtilityKeyframe(Node, MantisUINode):
+class UtilityKeyframe(Node, MantisMiscNode):
     """A keyframe for a FCurve"""
     """A keyframe for a FCurve"""
     bl_idname = "UtilityKeyframe"
     bl_idname = "UtilityKeyframe"
     bl_label = "KeyFrame"
     bl_label = "KeyFrame"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(KeyframeSockets)
-        self.initialized = True
+    socket_templates=KeyframeSockets
 
 
     # TODO: I'll implement this when I finish adding the extra features to the Keyframe node
     # TODO: I'll implement this when I finish adding the extra features to the Keyframe node
     # def display_update(self, parsed_tree, context):
     # def display_update(self, parsed_tree, context):
@@ -805,89 +697,61 @@ class UtilityKeyframe(Node, MantisUINode):
     #                 inp.hide = False
     #                 inp.hide = False
 
 
 
 
-class UtilityBoneMatrixHeadTailFlip(Node, MantisUINode):
+class UtilityBoneMatrixHeadTailFlip(Node, MantisMiscNode):
     """Flips a bone matrix so that the head is where the tail was and visa versa."""
     """Flips a bone matrix so that the head is where the tail was and visa versa."""
     bl_idname = "UtilityBoneMatrixHeadTailFlip"
     bl_idname = "UtilityBoneMatrixHeadTailFlip"
     bl_label = "Flip Head/Tail"
     bl_label = "Flip Head/Tail"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(BoneMatrixHeadTailFlipSockets)
-        self.initialized = True
+    socket_templates=BoneMatrixHeadTailFlipSockets
 
 
-class UtilityMatrixTransform(Node, MantisUINode):
+class UtilityMatrixTransform(Node, MantisMiscNode):
     """Transforms a matrix by another."""
     """Transforms a matrix by another."""
     bl_idname = "UtilityMatrixTransform"
     bl_idname = "UtilityMatrixTransform"
     bl_label = "Multiply Matrices"
     bl_label = "Multiply Matrices"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatrixTransformSockets)
-        self.initialized = True
+    socket_templates=MatrixTransformSockets
 
 
-class UtilityMatrixInvert(Node, MantisUINode):
+class UtilityMatrixInvert(Node, MantisMiscNode):
     """Inverts an invertable matrix, otherwise throws an error."""
     """Inverts an invertable matrix, otherwise throws an error."""
     bl_idname = "UtilityMatrixInvert"
     bl_idname = "UtilityMatrixInvert"
     bl_label = "Invert Matrix"
     bl_label = "Invert Matrix"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatrixInvertSockets)
-        self.initialized = True
+    socket_templates=MatrixInvertSockets
 
 
-class UtilityMatrixCompose(Node, MantisUINode):
+class UtilityMatrixCompose(Node, MantisMiscNode):
     """Inverts an invertable matrix, otherwise throws an error."""
     """Inverts an invertable matrix, otherwise throws an error."""
     bl_idname = "UtilityMatrixCompose"
     bl_idname = "UtilityMatrixCompose"
     bl_label = "Compose Matrix"
     bl_label = "Compose Matrix"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatrixComposeSockets)
-        self.initialized = True
+    socket_templates=MatrixComposeSockets
 
 
-class UtilityMatrixAlignRoll(Node, MantisUINode):
+class UtilityMatrixAlignRoll(Node, MantisMiscNode):
     """Aligns the Z axis of a matrix to point in a direction."""
     """Aligns the Z axis of a matrix to point in a direction."""
     bl_idname = "UtilityMatrixAlignRoll"
     bl_idname = "UtilityMatrixAlignRoll"
     bl_label = "Align Matrix Roll"
     bl_label = "Align Matrix Roll"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatrixAlignRollSockets)
-        self.initialized = True
+    socket_templates=MatrixAlignRollSockets
 
 
-class UtilityMatrixSetLocation(Node, MantisUINode):
+class UtilityMatrixSetLocation(Node, MantisMiscNode):
     """Sets a matrix's location."""
     """Sets a matrix's location."""
     bl_idname = "UtilityMatrixSetLocation"
     bl_idname = "UtilityMatrixSetLocation"
     bl_label = "Set Matrix Location"
     bl_label = "Set Matrix Location"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatrixSetLocationSockets)
-        self.initialized = True
+    socket_templates=MatrixSetLocationSockets
 
 
-class UtilityMatrixGetLocation(Node, MantisUINode):
+class UtilityMatrixGetLocation(Node, MantisMiscNode):
     """Gets a matrix's location."""
     """Gets a matrix's location."""
     bl_idname = "UtilityMatrixGetLocation"
     bl_idname = "UtilityMatrixGetLocation"
     bl_label = "Get Matrix Location"
     bl_label = "Get Matrix Location"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatrixGetLocationSockets)
-        self.initialized = True
+    socket_templates=MatrixGetLocationSockets
 
 
-class UtilityTransformationMatrix(Node, MantisUINode):
+class UtilityTransformationMatrix(Node, MantisMiscNode):
     """Constructs a matrix representing a transformation"""
     """Constructs a matrix representing a transformation"""
     bl_idname = "UtilityTransformationMatrix"
     bl_idname = "UtilityTransformationMatrix"
     bl_label = "Transformation Matrix"
     bl_label = "Transformation Matrix"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        # first input is a transformation type - translation, rotation, or scale
-        #                         rotation is an especially annoying feature because it can take multiple types
-        #   so Euler, axis/angle, quaternion, matrix...
-        #   for now I am only going to implement axis-angle
-        self.init_sockets(TransformationMatrixSockets)
-        self.initialized = True
+    socket_templates=TransformationMatrixSockets
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         operation = self.inputs['Operation'].default_value
         operation = self.inputs['Operation'].default_value
@@ -910,58 +774,41 @@ class UtilityTransformationMatrix(Node, MantisUINode):
 # So instead, we need to avoid calculating the roll for now.
 # So instead, we need to avoid calculating the roll for now.
 # but I want to make that its own node and add roll-recalc to this node, too.
 # but I want to make that its own node and add roll-recalc to this node, too.
 
 
-class UtilitySetBoneMatrixTail(Node, MantisUINode):
+class UtilitySetBoneMatrixTail(Node, MantisMiscNode):
     """Constructs a matrix representing a transformation"""
     """Constructs a matrix representing a transformation"""
     bl_idname = "UtilitySetBoneMatrixTail"
     bl_idname = "UtilitySetBoneMatrixTail"
     bl_label = "Set Bone Matrix Tail"
     bl_label = "Set Bone Matrix Tail"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(SetBoneMatrixTailSockets)
-        self.initialized = True
+    socket_templates=SetBoneMatrixTailSockets
 
 
-
-class UtilityMatrixFromXForm(Node, MantisUINode):
+class UtilityMatrixFromXForm(Node, MantisMiscNode):
     """Returns the matrix of the given xForm node."""
     """Returns the matrix of the given xForm node."""
     bl_idname = "UtilityMatrixFromXForm"
     bl_idname = "UtilityMatrixFromXForm"
     bl_label = "Matrix of xForm"
     bl_label = "Matrix of xForm"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(MatrixFromXFormSockets)
-        self.initialized = True
+    socket_templates=MatrixFromXFormSockets
 
 
-class UtilityAxesFromMatrix(Node, MantisUINode):
+class UtilityAxesFromMatrix(Node, MantisMiscNode):
     """Returns the axes of the matrix."""
     """Returns the axes of the matrix."""
     bl_idname = "UtilityAxesFromMatrix"
     bl_idname = "UtilityAxesFromMatrix"
     bl_label = "Axes of Matrix"
     bl_label = "Axes of Matrix"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(AxesFromMatrixSockets)
-        self.initialized = True
+    socket_templates=AxesFromMatrixSockets
 
 
-class UtilityIntToString(Node, MantisUINode):
+class UtilityIntToString(Node, MantisMiscNode):
     """Converts a number to a string"""
     """Converts a number to a string"""
     bl_idname = "UtilityIntToString"
     bl_idname = "UtilityIntToString"
     bl_label = "Number String"
     bl_label = "Number String"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(IntToStringSockets)
-        self.initialized = True
-
+    socket_templates=IntToStringSockets
 
 
-class UtilityArrayGet(Node, MantisUINode):
+class UtilityArrayGet(Node, MantisMiscNode):
     """Gets a value from an array at a specified index."""
     """Gets a value from an array at a specified index."""
     bl_idname = "UtilityArrayGet"
     bl_idname = "UtilityArrayGet"
     bl_label  = "Array Get"
     bl_label  = "Array Get"
     bl_icon   = "NODE"
     bl_icon   = "NODE"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(ArrayGetSockets)
-        self.initialized = True
+    socket_templates=ArrayGetSockets
     
     
     def update(self):
     def update(self):
         wildcard_color = (0.0,0.0,0.0,0.0)
         wildcard_color = (0.0,0.0,0.0,0.0)
@@ -977,16 +824,13 @@ class UtilityArrayGet(Node, MantisUINode):
                 self.inputs['Array'].color = from_socket.color
                 self.inputs['Array'].color = from_socket.color
                 self.outputs['Output'].color = from_socket.color
                 self.outputs['Output'].color = from_socket.color
 
 
-class UtilityArrayLength(Node, MantisUINode):
+class UtilityArrayLength(Node, MantisMiscNode):
     """Gets The length of an array."""
     """Gets The length of an array."""
     bl_idname = "UtilityArrayLength"
     bl_idname = "UtilityArrayLength"
     bl_label  = "Array Length"
     bl_label  = "Array Length"
     bl_icon   = "NODE"
     bl_icon   = "NODE"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        s = self.init_sockets(UtilityArrayLengthSockets)
-        self.initialized = True
+    socket_templates=UtilityArrayLengthSockets
     
     
     def update(self):
     def update(self):
         wildcard_color = (0.0,0.0,0.0,0.0)
         wildcard_color = (0.0,0.0,0.0,0.0)
@@ -1001,15 +845,12 @@ class UtilityArrayLength(Node, MantisUINode):
                 self.inputs['Array'].color = from_socket.color
                 self.inputs['Array'].color = from_socket.color
 
 
 
 
-class UtilityCompare(Node, MantisUINode):
+class UtilityCompare(Node, MantisMiscNode):
     """Compares two inputs and produces a boolean output"""
     """Compares two inputs and produces a boolean output"""
     bl_idname = "UtilityCompare"
     bl_idname = "UtilityCompare"
     bl_label = "Compare"
     bl_label = "Compare"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(CompareSockets)
-        self.initialized = True
+    socket_templates=CompareSockets
     
     
     def update(self):
     def update(self):
         wildcard_color = (0.0,0.0,0.0,0.0)
         wildcard_color = (0.0,0.0,0.0,0.0)
@@ -1029,15 +870,12 @@ class UtilityCompare(Node, MantisUINode):
             if hasattr(link.from_socket, "color"):
             if hasattr(link.from_socket, "color"):
                 self.inputs['B'].color = link.from_socket.color
                 self.inputs['B'].color = link.from_socket.color
 
 
-class UtilityChoose(Node, MantisUINode):
+class UtilityChoose(Node, MantisMiscNode):
     """Chooses an output"""
     """Chooses an output"""
     bl_idname = "UtilityChoose"
     bl_idname = "UtilityChoose"
     bl_label = "Choose"
     bl_label = "Choose"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(ChooseSockets)
-        self.initialized = True
+    socket_templates=ChooseSockets
     
     
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         wildcard_color = (0.0,0.0,0.0,0.0)
         wildcard_color = (0.0,0.0,0.0,0.0)
@@ -1071,18 +909,10 @@ class UtilityChoose(Node, MantisUINode):
                 self.inputs['B'].color = link.from_socket.color
                 self.inputs['B'].color = link.from_socket.color
 
 
 
 
-class UtilityPrint(Node, MantisUINode):
+class UtilityPrint(Node, MantisMiscNode):
     """A utility used to print arbitrary values."""
     """A utility used to print arbitrary values."""
     bl_idname = "UtilityPrint"
     bl_idname = "UtilityPrint"
     bl_label  = "Print"
     bl_label  = "Print"
     bl_icon   = "NODE"
     bl_icon   = "NODE"
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(PrintSockets)
-        self.initialized = True
-
-# Set up the class property that ties the UI classes to the Mantis classes.
-for cls in TellClasses():
-    cls.mantis_node_library='.misc_nodes'
-    cls.set_mantis_class()
+    socket_templates=PrintSockets

+ 6 - 20
primitives_nodes_ui.py

@@ -1,6 +1,7 @@
 import bpy
 import bpy
 from bpy.types import Node
 from bpy.types import Node
-from .base_definitions import MantisUINode
+from .base_definitions import GeometryPrimitiveNode
+from .primitives_sockets import *
 
 
 def TellClasses():
 def TellClasses():
     return [
     return [
@@ -11,36 +12,21 @@ def TellClasses():
 def default_traverse(self,socket):
 def default_traverse(self,socket):
     return None
     return None
 
 
-
-class GeometryCirclePrimitive(Node, MantisUINode):
+class GeometryCirclePrimitive(Node, GeometryPrimitiveNode):
     '''A node representing a circle primitive'''
     '''A node representing a circle primitive'''
     bl_idname = 'GeometryCirclePrimitive'
     bl_idname = 'GeometryCirclePrimitive'
     bl_label = "Circle Primitive"
     bl_label = "Circle Primitive"
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     mantis_node_class_name="CirclePrimitive"
     mantis_node_class_name="CirclePrimitive"
-
-    def init(self, context):
-        self.inputs.new('StringSocket', "Name")
-        self.inputs.new('FloatPositiveSocket', "Radius")
-        self.inputs.new('IntSocket', "Number of Points")
-        self.outputs.new('GeometrySocket', "Circle")
-        self.initialized = True
+    socket_templates = CirclePrimitiveSockets
 
 
 from .primitives_sockets import LatticeSockets
 from .primitives_sockets import LatticeSockets
-class GeometryLattice(Node, MantisUINode):
+class GeometryLattice(Node, GeometryPrimitiveNode):
     '''A node representing a lattice geometry'''
     '''A node representing a lattice geometry'''
     bl_idname = "GeometryLattice"
     bl_idname = "GeometryLattice"
     bl_label = "Lattice"
     bl_label = "Lattice"
     bl_icon = "NODE"
     bl_icon = "NODE"
     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):
-        self.init_sockets(LatticeSockets)
-        self.initialized = True
-
-
-for cls in TellClasses():
-    cls.mantis_node_library='.primitives_nodes'
-    cls.set_mantis_class()
+    socket_templates = LatticeSockets

+ 10 - 0
primitives_sockets.py

@@ -24,4 +24,14 @@ LatticeSockets = [
             blender_property="interpolation_type_w",
             blender_property="interpolation_type_w",
             is_input=True, default_value='KEY_BSPLINE'),
             is_input=True, default_value='KEY_BSPLINE'),
     GeometryOutput := SockTemplate(name="Lattice Geometry", bl_idname="GeometrySocket")
     GeometryOutput := SockTemplate(name="Lattice Geometry", bl_idname="GeometrySocket")
+]
+
+CirclePrimitiveSockets = [
+    replace(Name, default_value='Circle',),
+    Radius :=SockTemplate(name = "Radius", bl_idname="FloatPositiveSocket",
+            is_input=True, default_value=1.0),
+    # TODO: this should be an UnsignedIntSocket
+    NumberOfPoints :=SockTemplate(name = "Number of Points", bl_idname="IntSocket",
+            is_input=True, default_value=32),
+    GeometryOutput := SockTemplate(name="Circle", bl_idname="GeometrySocket"),
 ]
 ]

+ 2 - 8
schema_nodes_ui.py

@@ -38,10 +38,7 @@ class SchemaIndex(Node, SchemaUINode):
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     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):
-        self.init_sockets(SchemaIndexSockets)
-        self.initialized = True
+    socket_templates = SchemaIndexSockets
 
 
 class SchemaArrayInput(Node, SchemaUINode):
 class SchemaArrayInput(Node, SchemaUINode):
     '''Array Inputs'''
     '''Array Inputs'''
@@ -116,6 +113,7 @@ class SchemaArrayInputGet(Node, SchemaUINode):
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
+    socket_templates = SchemaArrayInputGetSockets
 
 
     def init(self, context):
     def init(self, context):
         self.init_sockets(SchemaArrayInputGetSockets)
         self.init_sockets(SchemaArrayInputGetSockets)
@@ -322,7 +320,3 @@ class SchemaIncomingConnection(Node, SchemaUINode):
             self.outputs.new('WildcardSocket', '', identifier='__extend__')
             self.outputs.new('WildcardSocket', '', identifier='__extend__')
         self.initialized = True
         self.initialized = True
         self.is_updating = False
         self.is_updating = False
-
-
-for cls in TellClasses():
-    cls.set_mantis_class()

+ 6 - 62
xForm_nodes_ui.py

@@ -26,22 +26,6 @@ def default_traverse(self, socket):
         return self.outputs["xForm Out"]
         return self.outputs["xForm Out"]
     return None
     return None
 
 
-# Representing an Empty or non-armature-Object
-# class xFormNullNode(Node, xFormNode):
-#     '''A node representing a Null node'''
-#     bl_idname = 'xFormNullNode'
-#     bl_label = "Null"
-#     bl_icon = 'EMPTY_AXIS'
-
-#     # === Optional Functions ===
-#     def init(self, context):
-#         self.inputs.new('StringSocket', "Name")
-#         self.inputs.new('RelationshipSocket', "Relationship")
-#         self.inputs.new('RotationOrderSocket', "Rotation Order")
-#         self.inputs.new('MatrixSocket', "Matrix")
-#         self.outputs.new('xFormSocket', "xForm Out")
-
-
 def check_if_connected(start, end, line):
 def check_if_connected(start, end, line):
     started=False
     started=False
     for path_mantis_node in line:
     for path_mantis_node in line:
@@ -132,9 +116,6 @@ 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')
 
 
 
 
-from mathutils import Color
-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'
@@ -145,18 +126,10 @@ class xFormBoneNode(Node, xFormNode):
     display_vp_settings : bpy.props.BoolProperty(default=False)
     display_vp_settings : bpy.props.BoolProperty(default=False)
     display_def_settings : bpy.props.BoolProperty(default=False)
     display_def_settings : bpy.props.BoolProperty(default=False)
     display_bb_settings : bpy.props.BoolProperty(default=False)
     display_bb_settings : bpy.props.BoolProperty(default=False)
-    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
     socket_templates = xFormBoneSockets
     
     
-    def init(self, context):
-        self.init_sockets(self.__class__.socket_templates)
-        self.socket_count = len(self.inputs)
-        self.use_custom_color = True
-        self.color = xFormColor
-        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)
         
         
@@ -213,12 +186,7 @@ class xFormArmatureNode(Node, xFormNode):
     bl_icon = 'OUTLINER_OB_ARMATURE'
     bl_icon = 'OUTLINER_OB_ARMATURE'
     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]
-
-    def init(self, context):
-        self.init_sockets(xFormArmatureSockets)
-        self.use_custom_color = True
-        self.color = xFormColor
-        self.initialized=True
+    socket_templates = xFormArmatureSockets
 
 
     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)
@@ -233,12 +201,7 @@ class xFormGeometryObjectNode(Node, xFormNode):
     bl_icon = "EMPTY_AXIS"
     bl_icon = "EMPTY_AXIS"
     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):
-        self.init_sockets(xFormGeometryObjectSockets)
-        self.use_custom_color = True
-        self.color = xFormColor
-        self.initialized=True
+    socket_templates = xFormGeometryObjectSockets
 
 
     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)
@@ -253,12 +216,7 @@ class xFormObjectInstance(Node, xFormNode):
     bl_icon = "EMPTY_AXIS"
     bl_icon = "EMPTY_AXIS"
     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):
-        self.init_sockets(xFormGeometryObjectInstanceSockets)
-        self.use_custom_color = True
-        self.color = xFormColor
-        self.initialized=True
+    socket_templates = xFormGeometryObjectInstanceSockets
 
 
     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)
@@ -266,7 +224,6 @@ class xFormObjectInstance(Node, xFormNode):
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         object_displaty_update(self, parsed_tree, context)
         object_displaty_update(self, parsed_tree, context)
 
 
-from .xForm_nodes import xFormCurvePinSockets
 class xFormCurvePin(Node, xFormNode):
 class xFormCurvePin(Node, xFormNode):
     """"A node representing a curve pin"""
     """"A node representing a curve pin"""
     bl_idname = "xFormCurvePin"
     bl_idname = "xFormCurvePin"
@@ -274,12 +231,7 @@ class xFormCurvePin(Node, xFormNode):
     bl_icon = "FORCE_CURVE"
     bl_icon = "FORCE_CURVE"
     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):
-        self.init_sockets(xFormCurvePinSockets)
-        self.use_custom_color = True
-        self.color = xFormColor
-        self.initialized = True
+    socket_templates = xFormCurvePinSockets
 
 
 class xFormGetBone(Node, xFormNode):
 class xFormGetBone(Node, xFormNode):
     """"A node representing an existing bone"""
     """"A node representing an existing bone"""
@@ -289,19 +241,11 @@ class xFormGetBone(Node, xFormNode):
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
     armature : bpy.props.StringProperty(default="")
     armature : bpy.props.StringProperty(default="")
     mantis_node_class_name=bl_idname
     mantis_node_class_name=bl_idname
-    
-    def init(self, context):
-        self.init_sockets(xFormGetBoneSockets)
-        self.use_custom_color = True
-        self.color = xFormColor
-        self.initialized = True
+    socket_templates = xFormGetBoneSockets
 
 
     def display_update(self, parsed_tree, context):
     def display_update(self, parsed_tree, context):
         if context.space_data:
         if context.space_data:
             mantis_node = parsed_tree.get(get_signature_from_edited_tree(self, context))
             mantis_node = parsed_tree.get(get_signature_from_edited_tree(self, context))
             if mantis_node:
             if mantis_node:
                 # need this parent armature to use the bone picker.
                 # need this parent armature to use the bone picker.
-                self.inputs["Bone"].armature = mantis_node.bGetParentArmature()
-
-for cls in TellClasses():
-    cls.set_mantis_class()
+                self.inputs["Bone"].armature = mantis_node.bGetParentArmature()