Эх сурвалжийг харах

Refactor & Optimize: UI classes now have a mantis class reference

This commit ends up saving ~10% time in the component_groups test file. (from ~1.1s to ~0.9s).
The biggest change is the fact that there is no costly lookup function finding mantis classes during
tree parsing. Now, the classes get a class reference assigned at init - even better, if the class reference
is not found, the class won't init and the addon will fail to load. Thus, it is also an effective error-
finding solution for the problem it solves.
The code is a little ugly, but not terribly so, and it provides a stopgap solution while I prepare the
much bigger change of generating UI classes programatically. So the ugliness is temporary.

There is also a tiny change in MantisNodeSocketCollection which removes a custom __setitem__
which, though harmless, was costing me precious milliseconds.

the change in schema_containers is formatting/cleanup.
Joseph Brandenburg 7 сар өмнө
parent
commit
e6a08d79b8

+ 25 - 9
base_definitions.py

@@ -23,6 +23,8 @@ def TellClasses():
 def error_popup_draw(self, context):
 def error_popup_draw(self, context):
     self.layout.label(text="Error executing tree. See Console.")
     self.layout.label(text="Error executing tree. See Console.")
 
 
+mantis_root = ".".join(__name__.split('.')[:-1]) # absolute HACK
+
 class MantisTree(NodeTree):
 class MantisTree(NodeTree):
     '''A custom node tree type that will show up in the editor type list'''
     '''A custom node tree type that will show up in the editor type list'''
     bl_idname = 'MantisTree'
     bl_idname = 'MantisTree'
@@ -139,10 +141,24 @@ class MantisUINode:
         MantisUINode objects will spawn one or more MantisNode objects when the graph is evaluated.
         MantisUINode objects will spawn one or more MantisNode objects when the graph is evaluated.
         The MantisNode objects will pull the data from the UI node and use it to generate the graph.
         The MantisNode objects will pull the data from the UI node and use it to generate the graph.
     """
     """
+    mantis_node_library=''
+    mantis_node_class_name=''
+    mantis_class=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 insert_link(self, link):
     def insert_link(self, link):
         context = bpy.context
         context = bpy.context
         if context.space_data:
         if context.space_data:
@@ -156,22 +172,26 @@ class MantisUINode:
                     node_tree.num_links+=1
                     node_tree.num_links+=1
         
         
             
             
-class SchemaUINode:
+class SchemaUINode(MantisUINode):
+    mantis_node_library='.schema_containers'
     @classmethod
     @classmethod
     def poll(cls, ntree):
     def poll(cls, ntree):
         return (ntree.bl_idname in ['SchemaTree'])
         return (ntree.bl_idname in ['SchemaTree'])
 
 
 class LinkNode(MantisUINode):
 class LinkNode(MantisUINode):
+    mantis_node_library='.link_containers'
     @classmethod
     @classmethod
     def poll(cls, ntree):
     def poll(cls, ntree):
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
-
+    
 class xFormNode(MantisUINode):
 class xFormNode(MantisUINode):
+    mantis_node_library='.xForm_containers'
     @classmethod
     @classmethod
     def poll(cls, ntree):
     def poll(cls, ntree):
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
 
 
 class DeformerNode(MantisUINode):
 class DeformerNode(MantisUINode):
+    mantis_node_library='.deformer_containers'
     @classmethod
     @classmethod
     def poll(cls, ntree):
     def poll(cls, ntree):
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
@@ -406,13 +426,13 @@ class MantisNode:
         self.signature = signature
         self.signature = signature
         self.inputs = MantisNodeSocketCollection(node=self, is_input=True)
         self.inputs = MantisNodeSocketCollection(node=self, is_input=True)
         self.outputs = MantisNodeSocketCollection(node=self, is_input=False)
         self.outputs = MantisNodeSocketCollection(node=self, is_input=False)
-        self.parameters = dict()
+        self.parameters = {}
+        self.drivers = {}
         self.node_type='UNINITIALIZED'
         self.node_type='UNINITIALIZED'
         self.hierarchy_connections, self.connections = [], []
         self.hierarchy_connections, self.connections = [], []
         self.hierarchy_dependencies, self.dependencies = [], []
         self.hierarchy_dependencies, self.dependencies = [], []
         self.prepared = False
         self.prepared = False
         self.executed = False
         self.executed = False
-        self.drivers = {}
 
 
     def init_parameters(self, additional_parameters = {}):
     def init_parameters(self, additional_parameters = {}):
         for socket in self.inputs:
         for socket in self.inputs:
@@ -658,11 +678,7 @@ class MantisNodeSocketCollection(dict):
         for socket in sockets:
         for socket in sockets:
             if not isinstance(socket, str): raise RuntimeError("NodeSocketCollection keys must be str.")
             if not isinstance(socket, str): raise RuntimeError("NodeSocketCollection keys must be str.")
             self[socket] = NodeSocket(is_input=self.is_input, name=socket, node=self.node)
             self[socket] = NodeSocket(is_input=self.is_input, name=socket, node=self.node)
-
-    def __setitem__(self, key, value=None):
-        """Allows setting items using square brackets: obj[key] = value"""
-        super().__setitem__(key, value)
-    
+            
     def __delitem__(self, key):
     def __delitem__(self, key):
         """Deletes a node socket by name, and all its links."""
         """Deletes a node socket by name, and all its links."""
         socket = self[key]
         socket = self[key]

+ 8 - 1
deformer_definitions.py

@@ -29,6 +29,7 @@ class DeformerArmatureNode(Node, DeformerNode):
     bl_label = "Armature Deform"
     bl_label = "Armature Deform"
     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
 
 
     def init(self, context):
     def init(self, context):
         # self.inputs.new ("RelationshipSocket", "Input Relationship")
         # self.inputs.new ("RelationshipSocket", "Input Relationship")
@@ -66,6 +67,7 @@ class DeformerHook(Node, DeformerNode):
     bl_label = "Hook Deform"
     bl_label = "Hook Deform"
     bl_icon = 'HOOK'
     bl_icon = 'HOOK'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new("DeformerSocket", "Deformer")
         self.inputs.new("DeformerSocket", "Deformer")
@@ -116,6 +118,7 @@ class DeformerMorphTargetDeform(Node, DeformerNode):
     bl_icon = 'MOD_ARMATURE'
     bl_icon = 'MOD_ARMATURE'
     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
 
 
 
 
     def init(self, context):
     def init(self, context):
@@ -183,6 +186,7 @@ class DeformerMorphTarget(Node, DeformerNode):
     bl_icon = 'SHAPEKEY_DATA'
     bl_icon = 'SHAPEKEY_DATA'
     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
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new('xFormSocket', "Relative to")
         self.inputs.new('xFormSocket', "Relative to")
@@ -191,4 +195,7 @@ class DeformerMorphTarget(Node, DeformerNode):
         self.outputs.new('MorphTargetSocket', "Morph Target")
         self.outputs.new('MorphTargetSocket', "Morph Target")
 
 
         self.initialized = True
         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()

+ 25 - 18
link_definitions.py

@@ -1,6 +1,6 @@
 import bpy
 import bpy
 from bpy.types import NodeTree, Node, NodeSocket
 from bpy.types import NodeTree, Node, NodeSocket
-from .base_definitions import MantisUINode, LinkNode, GraphError
+from .base_definitions import LinkNode, GraphError
 from .utilities import (prRed, prGreen, prPurple, prWhite,
 from .utilities import (prRed, prGreen, prPurple, prWhite,
                               prOrange,
                               prOrange,
                               wrapRed, wrapGreen, wrapPurple, wrapWhite,
                               wrapRed, wrapGreen, wrapPurple, wrapWhite,
@@ -37,7 +37,6 @@ def default_traverse(self, socket):
             return self.outputs["Output Relationship"]
             return self.outputs["Output Relationship"]
         return None
         return None
 
 
-
 from mathutils import Color # these colors were sampled from Blender's UI
 from mathutils import Color # these colors were sampled from Blender's UI
 # TODO: maybe read the relevant colors from the Theme
 # TODO: maybe read the relevant colors from the Theme
 linkColor = Color((0.028034, 0.093164, 0.070379)).from_scene_linear_to_srgb()
 linkColor = Color((0.028034, 0.093164, 0.070379)).from_scene_linear_to_srgb()
@@ -55,6 +54,7 @@ class LinkInheritNode(Node, LinkNode):
     bl_label = "Inherit"
     bl_label = "Inherit"
     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"
     
     
     
     
     # bone_prev : bpy.props.BoolProperty(default=False)
     # bone_prev : bpy.props.BoolProperty(default=False)
@@ -117,7 +117,7 @@ class LinkInverseKinematics(Node, LinkNode):
     bl_label = "Inverse Kinematics"
     bl_label = "Inverse Kinematics"
     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
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new('RelationshipSocket', "Input Relationship")
         self.inputs.new('RelationshipSocket', "Input Relationship")
@@ -148,8 +148,8 @@ class LinkCopyLocationNode(Node, LinkNode):
     bl_idname = 'LinkCopyLocation'
     bl_idname = 'LinkCopyLocation'
     bl_label = "Copy Location"
     bl_label = "Copy Location"
     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
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('RelationshipSocket', "Input Relationship")
@@ -176,8 +176,8 @@ class LinkCopyRotationNode(Node, LinkNode):
     bl_idname = 'LinkCopyRotation'
     bl_idname = 'LinkCopyRotation'
     bl_label = "Copy Rotation"
     bl_label = "Copy Rotation"
     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
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('RelationshipSocket', "Input Relationship")
@@ -204,8 +204,8 @@ class LinkCopyScaleNode(Node, LinkNode):
     bl_idname = 'LinkCopyScale'
     bl_idname = 'LinkCopyScale'
     bl_label = "Copy Scale"
     bl_label = "Copy Scale"
     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
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('RelationshipSocket', "Input Relationship")
@@ -235,8 +235,8 @@ class LinkInheritConstraintNode(Node, LinkNode):
     bl_idname = 'LinkInheritConstraint'
     bl_idname = 'LinkInheritConstraint'
     bl_label = "Inherit (constraint)"
     bl_label = "Inherit (constraint)"
     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
 
 
     # === Optional Functions ===
     # === Optional Functions ===
     def init(self, context):
     def init(self, context):
@@ -263,9 +263,8 @@ class LinkCopyTransformNode(Node, LinkNode):
     bl_idname = 'LinkCopyTransforms'
     bl_idname = 'LinkCopyTransforms'
     bl_label = "Copy Transform"
     bl_label = "Copy Transform"
     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
 
 
     # === Optional Functions ===
     # === Optional Functions ===
     def init(self, context):
     def init(self, context):
@@ -292,8 +291,9 @@ class LinkStretchToNode(Node, LinkNode):
     bl_idname = 'LinkStretchTo'
     bl_idname = 'LinkStretchTo'
     bl_label = "Stretch To"
     bl_label = "Stretch To"
     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
+
     def init(self, context):
     def init(self, context):
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('FloatFactorSocket', "Head/Tail")
         self.inputs.new ('FloatFactorSocket', "Head/Tail")
@@ -325,8 +325,9 @@ class LinkDampedTrackNode(Node, LinkNode):
     bl_idname = 'LinkDampedTrack'
     bl_idname = 'LinkDampedTrack'
     bl_label = "Damped Track"
     bl_label = "Damped Track"
     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
+
     def init(self, context):
     def init(self, context):
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('FloatFactorSocket', "Head/Tail")
         self.inputs.new ('FloatFactorSocket', "Head/Tail")
@@ -350,8 +351,8 @@ class LinkLockedTrackNode(Node, LinkNode):
     bl_idname = 'LinkLockedTrack'
     bl_idname = 'LinkLockedTrack'
     bl_label = "Locked Track"
     bl_label = "Locked Track"
     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
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('RelationshipSocket', "Input Relationship")
@@ -377,8 +378,8 @@ class LinkTrackToNode(Node, LinkNode):
     bl_idname = 'LinkTrackTo'
     bl_idname = 'LinkTrackTo'
     bl_label = "Track To"
     bl_label = "Track To"
     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
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('RelationshipSocket', "Input Relationship")
@@ -407,7 +408,7 @@ class LinkLimitLocationNode(Node, LinkNode):
     bl_idname = 'LinkLimitLocation'
     bl_idname = 'LinkLimitLocation'
     bl_label = "Limit Location"
     bl_label = "Limit Location"
     bl_icon = 'CON_LOCLIMIT'
     bl_icon = 'CON_LOCLIMIT'
-    
+    mantis_node_class_name=bl_idname
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
 
 
     def init(self, context):
     def init(self, context):
@@ -442,8 +443,8 @@ class LinkLimitScaleNode(Node, LinkNode):
     bl_idname = 'LinkLimitScale'
     bl_idname = 'LinkLimitScale'
     bl_label = "Limit Scale"
     bl_label = "Limit Scale"
     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
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('RelationshipSocket', "Input Relationship")
@@ -479,8 +480,8 @@ class LinkLimitRotationNode(Node, LinkNode):
     bl_idname = 'LinkLimitRotation'
     bl_idname = 'LinkLimitRotation'
     bl_label = "Limit Rotation"
     bl_label = "Limit Rotation"
     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
 
 
     # === Optional Functions ===
     # === Optional Functions ===
     def init(self, context):
     def init(self, context):
@@ -512,8 +513,8 @@ class LinkLimitDistanceNode(Node, LinkNode):
     bl_idname = 'LinkLimitDistance'
     bl_idname = 'LinkLimitDistance'
     bl_label = "Limit Distance"
     bl_label = "Limit Distance"
     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
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new ('RelationshipSocket', "Input Relationship")
         self.inputs.new ('RelationshipSocket', "Input Relationship")
@@ -541,8 +542,8 @@ class LinkTransformationNode(Node, LinkNode):
     bl_idname = 'LinkTransformation'
     bl_idname = 'LinkTransformation'
     bl_label = "Transformation"
     bl_label = "Transformation"
     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
 
 
     def init(self, context):
     def init(self, context):
         hide_me = []
         hide_me = []
@@ -619,6 +620,7 @@ class LinkArmatureNode(Node, LinkNode):
     bl_label = "Armature (Constraint)"
     bl_label = "Armature (Constraint)"
     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
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new ("RelationshipSocket", "Input Relationship")
         self.inputs.new ("RelationshipSocket", "Input Relationship")
@@ -651,6 +653,7 @@ class LinkSplineIKNode(Node, LinkNode):
     bl_label = "Spline IK"
     bl_label = "Spline IK"
     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
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new ("RelationshipSocket", "Input Relationship")
         self.inputs.new ("RelationshipSocket", "Input Relationship")
@@ -681,6 +684,7 @@ class LinkDrivenParameterNode(Node, LinkNode):
     bl_label = "Driven Parameter"
     bl_label = "Driven Parameter"
     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
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new ( "RelationshipSocket", "Input Relationship" )
         self.inputs.new ( "RelationshipSocket", "Input Relationship" )
@@ -698,3 +702,6 @@ class LinkDrivenParameterNode(Node, LinkNode):
         self.use_custom_color = True
         self.use_custom_color = True
         self.color = driverColor
         self.color = driverColor
 
 
+# Set up the class property that ties the UI classes to the Mantis classes.
+for cls in TellClasses():
+    cls.set_mantis_class()

+ 9 - 1
math_definitions.py

@@ -24,6 +24,7 @@ class MathStaticInt(Node, MantisUINode):
     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
 
 
 
 
     def init(self, context):
     def init(self, context):
@@ -51,6 +52,7 @@ class MathStaticFloatNode(Node, MantisUINode):
     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
 
 
 
 
     def init(self, context):
     def init(self, context):
@@ -77,6 +79,7 @@ class MathStaticVectorNode(Node, MantisUINode):
     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
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MathVectorOperation", "Operation")
         self.inputs.new("MathVectorOperation", "Operation")
@@ -112,4 +115,9 @@ class MathStaticVectorNode(Node, MantisUINode):
                 self.inputs["Scalar A"].hide = False
                 self.inputs["Scalar A"].hide = False
             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_containers'
+    cls.set_mantis_class()

+ 50 - 28
nodes_generic.py

@@ -17,10 +17,7 @@ def TellClasses():
              InputRotationOrderNode,
              InputRotationOrderNode,
              InputTransformSpaceNode,
              InputTransformSpaceNode,
              InputStringNode,
              InputStringNode,
-             InputQuaternionNode,
-             InputQuaternionNodeAA,
              InputMatrixNode,
              InputMatrixNode,
-             InputLayerMaskNode,
              # InputGeometryNode,
              # InputGeometryNode,
              InputExistingGeometryObjectNode,
              InputExistingGeometryObjectNode,
              InputExistingGeometryDataNode,
              InputExistingGeometryDataNode,
@@ -75,6 +72,7 @@ class InputFloatNode(Node, MantisUINode):
     bl_label = "Float"
     bl_label = "Float"
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname[:-4]
 
 
     def init(self, context):
     def init(self, context):
         self.outputs.new('FloatSocket', "Float Input").input = True
         self.outputs.new('FloatSocket', "Float Input").input = True
@@ -86,6 +84,7 @@ class InputIntNode(Node, MantisUINode):
     bl_label = "Integer"
     bl_label = "Integer"
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
 
 
     def init(self, context):
     def init(self, context):
         self.outputs.new('IntSocket', "Integer").input = True
         self.outputs.new('IntSocket', "Integer").input = True
@@ -97,6 +96,7 @@ class InputVectorNode(Node, MantisUINode):
     bl_label = "Vector"
     bl_label = "Vector"
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname[:-4]
 
 
     def init(self, context):
     def init(self, context):
         self.outputs.new('VectorSocket', "").input = True
         self.outputs.new('VectorSocket', "").input = True
@@ -108,6 +108,7 @@ class InputBooleanNode(Node, MantisUINode):
     bl_label = "Boolean"
     bl_label = "Boolean"
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname[:-4]
 
 
     def init(self, context):
     def init(self, context):
         self.outputs.new('BooleanSocket', "").input = True
         self.outputs.new('BooleanSocket', "").input = True
@@ -119,6 +120,7 @@ class InputBooleanThreeTupleNode(Node, MantisUINode):
     bl_label = "Boolean Vector"
     bl_label = "Boolean Vector"
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname[:-4]
 
 
     def init(self, context):
     def init(self, context):
         self.outputs.new('BooleanThreeTupleSocket', "")
         self.outputs.new('BooleanThreeTupleSocket', "")
@@ -130,6 +132,7 @@ class InputRotationOrderNode(Node, MantisUINode):
     bl_label = "Rotation Order"
     bl_label = "Rotation Order"
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname[:-4]
 
 
     def init(self, context):
     def init(self, context):
         self.outputs.new('RotationOrderSocket', "").input = True
         self.outputs.new('RotationOrderSocket', "").input = True
@@ -141,6 +144,7 @@ class InputTransformSpaceNode(Node, MantisUINode):
     bl_label = "Transform Space"
     bl_label = "Transform Space"
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname[:-4]
 
 
     def init(self, context):
     def init(self, context):
         self.outputs.new('TransformSpaceSocket', "").input = True
         self.outputs.new('TransformSpaceSocket', "").input = True
@@ -152,34 +156,11 @@ class InputStringNode(Node, MantisUINode):
     bl_label = "String"
     bl_label = "String"
     bl_icon = 'NODE'
     bl_icon = 'NODE'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname[:-4]
 
 
     def init(self, context):
     def init(self, context):
         self.outputs.new('StringSocket', "").input = True
         self.outputs.new('StringSocket', "").input = True
         self.initialized = True
         self.initialized = True
-
-class InputQuaternionNode(Node, MantisUINode):
-    '''A node representing inheritance'''
-    bl_idname = 'InputQuaternionNode'
-    bl_label = "Quaternion"
-    bl_icon = 'NODE'
-    initialized : bpy.props.BoolProperty(default = False)
-
-    def init(self, context):
-        self.outputs.new('QuaternionSocket', "").input = True
-        self.initialized = True
-
-class InputQuaternionNodeAA(Node, MantisUINode):
-    '''A node representing inheritance'''
-    bl_idname = 'InputQuaternionNodeAA'
-    bl_label = "Axis Angle"
-    bl_icon = 'NODE'
-    initialized : bpy.props.BoolProperty(default = False)
-
-    def init(self, context):
-        self.outputs.new('QuaternionSocketAA', "").input = True
-        self.initialized = True
-
-
 class InputMatrixNode(Node, MantisUINode):
 class InputMatrixNode(Node, MantisUINode):
     '''A node representing inheritance'''
     '''A node representing inheritance'''
     bl_idname = 'InputMatrixNode'
     bl_idname = 'InputMatrixNode'
@@ -190,6 +171,7 @@ class InputMatrixNode(Node, MantisUINode):
     third_row  : bpy.props.FloatVectorProperty(name="", size=4, default = (0.0, 0.0, 1.0, 0.0,))
     third_row  : bpy.props.FloatVectorProperty(name="", size=4, default = (0.0, 0.0, 1.0, 0.0,))
     fourth_row : bpy.props.FloatVectorProperty(name="", size=4, default = (0.0, 0.0, 0.0, 1.0,))
     fourth_row : bpy.props.FloatVectorProperty(name="", size=4, default = (0.0, 0.0, 0.0, 1.0,))
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname[:-4]
 
 
     def set_matrix(self):
     def set_matrix(self):
         return (self.first_row[ 0], self.first_row[ 1], self.first_row[ 2], self.first_row[ 3],
         return (self.first_row[ 0], self.first_row[ 1], self.first_row[ 2], self.first_row[ 3],
@@ -239,6 +221,7 @@ class MetaRigMatrixNode(Node, MantisUINode):
     third_row  : bpy.props.FloatVectorProperty(name="", size=4, default = (0.0, 0.0, 1.0, 0.0,))
     third_row  : bpy.props.FloatVectorProperty(name="", size=4, default = (0.0, 0.0, 1.0, 0.0,))
     fourth_row : bpy.props.FloatVectorProperty(name="", size=4, default = (0.0, 0.0, 0.0, 1.0,))
     fourth_row : bpy.props.FloatVectorProperty(name="", size=4, default = (0.0, 0.0, 0.0, 1.0,))
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name="UtilityMetaRig"
 
 
     def set_matrix(self):
     def set_matrix(self):
         return (self.first_row[ 0], self.first_row[ 1], self.first_row[ 2], self.first_row[ 3],
         return (self.first_row[ 0], self.first_row[ 1], self.first_row[ 2], self.first_row[ 3],
@@ -271,6 +254,7 @@ class UtilityMatrixFromCurve(Node, MantisUINode):
     bl_icon = "NODE"
     bl_icon = "NODE"
     
     
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         curv = self.inputs.new("EnumCurveSocket", "Curve")
         curv = self.inputs.new("EnumCurveSocket", "Curve")
@@ -288,6 +272,7 @@ class UtilityPointFromCurve(Node, MantisUINode):
     bl_icon = "NODE"
     bl_icon = "NODE"
     
     
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         curv = self.inputs.new("EnumCurveSocket", "Curve")
         curv = self.inputs.new("EnumCurveSocket", "Curve")
@@ -303,6 +288,7 @@ class UtilityMatricesFromCurve(Node, MantisUINode):
     bl_icon = "NODE"
     bl_icon = "NODE"
     
     
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         curv = self.inputs.new("EnumCurveSocket", "Curve")
         curv = self.inputs.new("EnumCurveSocket", "Curve")
@@ -321,6 +307,7 @@ class UtilityMetaRigNode(Node, MantisUINode):
     armature:bpy.props.StringProperty()
     armature:bpy.props.StringProperty()
     pose_bone:bpy.props.StringProperty()
     pose_bone:bpy.props.StringProperty()
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         armt = self.inputs.new("EnumMetaRigSocket", "Meta-Armature")
         armt = self.inputs.new("EnumMetaRigSocket", "Meta-Armature")
@@ -353,6 +340,7 @@ class UtilityBonePropertiesNode(Node, MantisUINode):
     bl_icon = "NODE"
     bl_icon = "NODE"
     #bl_width_default = 250
     #bl_width_default = 250
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.outputs.new("ParameterStringSocket", "matrix")
         self.outputs.new("ParameterStringSocket", "matrix")
@@ -375,6 +363,7 @@ class UtilityDriverVariableNode(Node, MantisUINode):
     bl_label = "Driver Variable"
     bl_label = "Driver Variable"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     
     
     def init(self, context):
     def init(self, context):
@@ -440,6 +429,7 @@ class UtilityFCurveNode(Node, MantisUINode):
     
     
     use_kf_nodes   : bpy.props.BoolProperty(default=True)
     use_kf_nodes   : bpy.props.BoolProperty(default=True)
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("eFCrvExtrapolationMode", "Extrapolation Mode")
         self.inputs.new("eFCrvExtrapolationMode", "Extrapolation Mode")
@@ -458,6 +448,7 @@ class UtilityDriverNode(Node, MantisUINode):
     bl_label = "Driver"
     bl_label = "Driver"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("EnumDriverType", "Driver Type")
         self.inputs.new("EnumDriverType", "Driver Type")
@@ -490,6 +481,7 @@ class UtilitySwitchNode(Node, MantisUINode):
     bl_label = "Switch"
     bl_label = "Switch"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         # self.inputs.new("xFormSocket", "xForm")
         # self.inputs.new("xFormSocket", "xForm")
@@ -505,6 +497,7 @@ class UtilityCombineThreeBoolNode(Node, MantisUINode):
     bl_label = "CombineThreeBool"
     bl_label = "CombineThreeBool"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("BooleanSocket", "X")
         self.inputs.new("BooleanSocket", "X")
@@ -519,6 +512,7 @@ class UtilityCombineVectorNode(Node, MantisUINode):
     bl_label = "CombineVector"
     bl_label = "CombineVector"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("FloatSocket", "X")
         self.inputs.new("FloatSocket", "X")
@@ -533,6 +527,7 @@ class UtilitySeparateVector(Node, MantisUINode):
     bl_label = "Separate Vector"
     bl_label = "Separate Vector"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("VectorSocket", "Vector")
         self.inputs.new("VectorSocket", "Vector")
@@ -547,6 +542,7 @@ class UtilityCatStringsNode(Node, MantisUINode):
     bl_label = "Concatenate Strings"
     bl_label = "Concatenate Strings"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("StringSocket", "String_1")
         self.inputs.new("StringSocket", "String_1")
@@ -584,6 +580,7 @@ class InputLayerMaskNode(Node, MantisUINode):
     bl_label = "Layer Mask"
     bl_label = "Layer Mask"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.outputs.new("LayerMaskInputSocket", "Layer Mask")
         self.outputs.new("LayerMaskInputSocket", "Layer Mask")
@@ -595,6 +592,7 @@ class InputExistingGeometryObjectNode(Node, MantisUINode):
     bl_label = "Existing Object"
     bl_label = "Existing Object"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    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,) 
     object_reference : bpy.props.PointerProperty(type=bpy.types.Object,) 
     
     
@@ -617,6 +615,7 @@ class InputExistingGeometryDataNode(Node, MantisUINode):
     bl_label = "Existing Geometry"
     bl_label = "Existing Geometry"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("StringSocket", "Name")
         self.inputs.new("StringSocket", "Name")
@@ -629,6 +628,7 @@ class UtilityGeometryOfXForm(Node, MantisUINode):
     bl_label = "Geometry of xForm"
     bl_label = "Geometry of xForm"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("xFormSocket", "xForm")
         self.inputs.new("xFormSocket", "xForm")
@@ -642,6 +642,7 @@ class UtilityNameOfXForm(Node, MantisUINode):
     bl_label = "Name of xForm"
     bl_label = "Name of xForm"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("xFormSocket", "xForm")
         self.inputs.new("xFormSocket", "xForm")
@@ -654,6 +655,7 @@ class UtilityGetBoneLength(Node, MantisUINode):
     bl_label = "Get Bone Length"
     bl_label = "Get Bone Length"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MatrixSocket", "Bone Matrix")
         self.inputs.new("MatrixSocket", "Bone Matrix")
@@ -667,6 +669,7 @@ class UtilityPointFromBoneMatrix(Node, MantisUINode):
     bl_label = "Point from Bone Matrix"
     bl_label = "Point from Bone Matrix"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MatrixSocket", "Bone Matrix")
         self.inputs.new("MatrixSocket", "Bone Matrix")
@@ -679,6 +682,7 @@ class UtilitySetBoneLength(Node, MantisUINode):
     bl_label = "Set Bone Matrix Length"
     bl_label = "Set Bone Matrix Length"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MatrixSocket", "Bone Matrix")
         self.inputs.new("MatrixSocket", "Bone Matrix")
@@ -694,6 +698,7 @@ class UtilityKeyframe(Node, MantisUINode):
     bl_label = "KeyFrame"
     bl_label = "KeyFrame"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         # x and y
         # x and y
@@ -734,6 +739,7 @@ class UtilityBoneMatrixHeadTailFlip(Node, MantisUINode):
     bl_label = "Flip Head/Tail"
     bl_label = "Flip Head/Tail"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MatrixSocket", "Bone Matrix")
         self.inputs.new("MatrixSocket", "Bone Matrix")
@@ -746,6 +752,7 @@ class UtilityMatrixTransform(Node, MantisUINode):
     bl_label = "Matrix Transform"
     bl_label = "Matrix Transform"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MatrixSocket", "Matrix 1")
         self.inputs.new("MatrixSocket", "Matrix 1")
@@ -759,6 +766,7 @@ class UtilityMatrixSetLocation(Node, MantisUINode):
     bl_label = "Set Matrix Location"
     bl_label = "Set Matrix Location"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MatrixSocket", "Matrix")
         self.inputs.new("MatrixSocket", "Matrix")
@@ -772,6 +780,7 @@ class UtilityMatrixGetLocation(Node, MantisUINode):
     bl_label = "Get Matrix Location"
     bl_label = "Get Matrix Location"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MatrixSocket", "Matrix")
         self.inputs.new("MatrixSocket", "Matrix")
@@ -784,6 +793,7 @@ class UtilityTransformationMatrix(Node, MantisUINode):
     bl_label = "Transformation Matrix"
     bl_label = "Transformation Matrix"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         # first input is a transformation type - translation, rotation, or scale
         # first input is a transformation type - translation, rotation, or scale
@@ -828,6 +838,7 @@ class UtilitySetBoneMatrixTail(Node, MantisUINode):
     bl_label = "Set Bone Matrix Tail"
     bl_label = "Set Bone Matrix Tail"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MatrixSocket", "Matrix")
         self.inputs.new("MatrixSocket", "Matrix")
@@ -842,6 +853,7 @@ class UtilityMatrixFromXForm(Node, MantisUINode):
     bl_label = "Matrix of xForm"
     bl_label = "Matrix of xForm"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("xFormSocket", "xForm")
         self.inputs.new("xFormSocket", "xForm")
@@ -854,6 +866,7 @@ class UtilityAxesFromMatrix(Node, MantisUINode):
     bl_label = "Axes of Matrix"
     bl_label = "Axes of Matrix"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("MatrixSocket", "Matrix")
         self.inputs.new("MatrixSocket", "Matrix")
@@ -868,6 +881,7 @@ class UtilityIntToString(Node, MantisUINode):
     bl_label = "Number String"
     bl_label = "Number String"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         
         
@@ -883,6 +897,7 @@ class UtilityArrayGet(Node, MantisUINode):
     bl_label  = "Array Get"
     bl_label  = "Array Get"
     bl_icon   = "NODE"
     bl_icon   = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new('EnumArrayGetOptions', 'OoB Behaviour')
         self.inputs.new('EnumArrayGetOptions', 'OoB Behaviour')
@@ -915,6 +930,7 @@ class UtilityCompare(Node, MantisUINode):
     bl_label = "Compare"
     bl_label = "Compare"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("WildcardSocket", "A")
         self.inputs.new("WildcardSocket", "A")
@@ -946,6 +962,7 @@ class UtilityChoose(Node, MantisUINode):
     bl_label = "Choose"
     bl_label = "Choose"
     bl_icon = "NODE"
     bl_icon = "NODE"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         
         
@@ -987,15 +1004,20 @@ 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, MantisUINode):
     """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"
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new("WildcardSocket", "Input")
         self.inputs.new("WildcardSocket", "Input")
         self.initialized = True
         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_containers'
+    cls.set_mantis_class()

+ 5 - 0
primitives_definitions.py

@@ -17,6 +17,7 @@ class GeometryCirclePrimitive(Node, MantisUINode):
     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"
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new('StringSocket', "Name")
         self.inputs.new('StringSocket', "Name")
@@ -24,3 +25,7 @@ class GeometryCirclePrimitive(Node, MantisUINode):
         self.inputs.new('IntSocket', "Number of Points")
         self.inputs.new('IntSocket', "Number of Points")
         self.outputs.new('GeometrySocket', "Circle")
         self.outputs.new('GeometrySocket', "Circle")
         self.initialized = True
         self.initialized = True
+
+for cls in TellClasses():
+    cls.mantis_node_library='.primitives_containers'
+    cls.set_mantis_class()

+ 12 - 12
readtree.py

@@ -1,7 +1,6 @@
 from .utilities import prRed, prGreen, prPurple, prWhite, prOrange, \
 from .utilities import prRed, prGreen, prPurple, prWhite, prOrange, \
                         wrapRed, wrapGreen, wrapPurple, wrapWhite, wrapOrange
                         wrapRed, wrapGreen, wrapPurple, wrapWhite, wrapOrange
-from .utilities import get_node_prototype, class_for_mantis_prototype_node, \
-                        gen_nc_input_for_data
+from .utilities import  gen_nc_input_for_data
 
 
     
     
 
 
@@ -139,15 +138,7 @@ def gen_node_containers(base_tree, current_tree, tree_path_names, all_nc, local_
     for np in current_tree.nodes:
     for np in current_tree.nodes:
         if np.bl_idname in ["NodeFrame", "NodeReroute"]:
         if np.bl_idname in ["NodeFrame", "NodeReroute"]:
             continue # not a Mantis Node
             continue # not a Mantis Node
-        if (nc_cls := class_for_mantis_prototype_node(np)):
-            sig = (None, *tree_path_names, np.name)
-            if np.bl_idname in replace_types:
-                sig = (None, *tree_path_names, np.bl_idname)
-                if local_nc.get(sig):
-                    continue # already made
-            nc = nc_cls( sig , base_tree)
-            local_nc[sig] = nc; all_nc[sig] = nc
-        elif np.bl_idname in ["NodeGroupInput", "NodeGroupOutput"]: # make a Dummy Node
+        if np.bl_idname in ["NodeGroupInput", "NodeGroupOutput"]: # make a Dummy Node
             # we only want ONE dummy in/out per tree_path, so use the bl_idname
             # we only want ONE dummy in/out per tree_path, so use the bl_idname
             sig = (None, *tree_path_names, np.bl_idname)
             sig = (None, *tree_path_names, np.bl_idname)
             if not local_nc.get(sig):
             if not local_nc.get(sig):
@@ -165,6 +156,15 @@ def gen_node_containers(base_tree, current_tree, tree_path_names, all_nc, local_
             else:
             else:
                 group_nodes.append(nc)
                 group_nodes.append(nc)
                 schema_nodes[sig] = nc
                 schema_nodes[sig] = nc
+        # if it wasn't the types we ignore or the types we make a Dummy for, use this to catch all non-special cases.
+        elif (nc_cls := np.mantis_class):
+            sig = (None, *tree_path_names, np.name)
+            if np.bl_idname in replace_types:
+                sig = (None, *tree_path_names, np.bl_idname)
+                if local_nc.get(sig):
+                    continue # already made
+            nc = nc_cls( sig , base_tree)
+            local_nc[sig] = nc; all_nc[sig] = nc
         else:
         else:
             nc = None
             nc = None
             prRed(f"Can't make nc for.. {np.bl_idname}")
             prRed(f"Can't make nc for.. {np.bl_idname}")
@@ -172,7 +172,7 @@ def gen_node_containers(base_tree, current_tree, tree_path_names, all_nc, local_
         if nc.signature[0] not in ['MANTIS_AUTOGENERATED'] and nc.node_type not in ['SCHEMA', 'DUMMY', 'DUMMY_SCHEMA']:
         if nc.signature[0] not in ['MANTIS_AUTOGENERATED'] and nc.node_type not in ['SCHEMA', 'DUMMY', 'DUMMY_SCHEMA']:
             nc.fill_parameters()
             nc.fill_parameters()
 
 
-def data_from_tree(base_tree, tree_path, dummy_nodes, all_nc, all_schema):
+def data_from_tree(base_tree, tree_path, dummy_nodes, all_nc, all_schema):#
     # TODO: it should be relatively easy to make this use a while loop instead of recursion.
     # TODO: it should be relatively easy to make this use a while loop instead of recursion.
     local_nc, group_nodes = {}, []
     local_nc, group_nodes = {}, []
     tree_path_names = [tree.name for tree in tree_path if hasattr(tree, "name")]
     tree_path_names = [tree.name for tree in tree_path if hasattr(tree, "name")]

+ 1 - 9
schema_containers.py

@@ -33,6 +33,7 @@ def schema_init_sockets(nc, is_input = True, in_out='INPUT', category=''):
                         node=nc)
                         node=nc)
     nc.init_parameters()
     nc.init_parameters()
 
 
+
 class SchemaNode(MantisNode):
 class SchemaNode(MantisNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         super().__init__(signature, base_tree)
@@ -51,8 +52,6 @@ class SchemaIndex(SchemaNode):
         self.outputs.init_sockets(outputs)
         self.outputs.init_sockets(outputs)
         self.init_parameters()
         self.init_parameters()
 
 
-
-
 class SchemaArrayInput(SchemaNode):
 class SchemaArrayInput(SchemaNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         super().__init__(signature, base_tree)
@@ -69,24 +68,17 @@ class SchemaArrayInputGet(SchemaNode):
         self.inputs.init_sockets(inputs)
         self.inputs.init_sockets(inputs)
         schema_init_sockets(self, is_input=False, in_out='INPUT', category='Array')
         schema_init_sockets(self, is_input=False, in_out='INPUT', category='Array')
 
 
-
 class SchemaArrayOutput(SchemaNode):
 class SchemaArrayOutput(SchemaNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         super().__init__(signature, base_tree)
         schema_init_sockets(self, is_input=True, in_out='OUTPUT', category='Array')
         schema_init_sockets(self, is_input=True, in_out='OUTPUT', category='Array')
 
 
-
-        
-
 class SchemaConstInput(SchemaNode):
 class SchemaConstInput(SchemaNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         super().__init__(signature, base_tree)
         schema_init_sockets(self, is_input=False, in_out='INPUT', category='Constant')
         schema_init_sockets(self, is_input=False, in_out='INPUT', category='Constant')
 
 
 
 
-
-
-
 class SchemaConstOutput(SchemaNode):
 class SchemaConstOutput(SchemaNode):
     def __init__(self, signature, base_tree):
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         super().__init__(signature, base_tree)

+ 11 - 2
schema_definitions.py

@@ -34,6 +34,7 @@ class SchemaIndex(Node, SchemaUINode):
     bl_label = "Index"
     bl_label = "Index"
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.outputs.new("IntSocket", "Index")
         self.outputs.new("IntSocket", "Index")
@@ -47,6 +48,7 @@ class SchemaArrayInput(Node, SchemaUINode):
     bl_label = "Array Input"
     bl_label = "Array Input"
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
 
 
     def init(self, context):
     def init(self, context):
         self.update()
         self.update()
@@ -71,6 +73,7 @@ class SchemaArrayInputGet(Node, SchemaUINode):
     bl_label = "Array Input at Index"
     bl_label = "Array Input at Index"
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new('EnumArrayGetOptions', 'OoB Behaviour')
         self.inputs.new('EnumArrayGetOptions', 'OoB Behaviour')
@@ -97,6 +100,7 @@ class SchemaArrayOutput(Node, SchemaUINode):
     bl_label = "Array Output"
     bl_label = "Array Output"
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
 
 
     def init(self, context):
     def init(self, context):
         self.update()
         self.update()
@@ -123,6 +127,7 @@ class SchemaConstInput(Node, SchemaUINode):
     bl_label = "Constant Input"
     bl_label = "Constant Input"
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.update()
         self.update()
@@ -149,6 +154,7 @@ class SchemaConstOutput(Node, SchemaUINode):
     bl_label = "Constant Output"
     bl_label = "Constant Output"
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
         self.update()
         self.update()
@@ -180,10 +186,9 @@ class SchemaOutgoingConnection(Node, SchemaUINode):
     bl_label = "Outgoing Connection"
     bl_label = "Outgoing Connection"
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
     
     
     def init(self, context):
     def init(self, context):
-        # self.inputs.new('IntSocket', 'Valid From')
-        # self.inputs.new('IntSocket', 'Valid Until')
         self.update()
         self.update()
 
 
     def update(self):
     def update(self):
@@ -210,6 +215,7 @@ class SchemaIncomingConnection(Node, SchemaUINode):
     bl_label = "Incoming Connection"
     bl_label = "Incoming Connection"
     bl_icon = 'GIZMO'
     bl_icon = 'GIZMO'
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname
 
 
     def init(self, context):
     def init(self, context):
         self.update()
         self.update()
@@ -228,3 +234,6 @@ class SchemaIncomingConnection(Node, SchemaUINode):
             self.outputs.new('WildcardSocket', '', identifier='__extend__')
             self.outputs.new('WildcardSocket', '', identifier='__extend__')
         self.initialized = True
         self.initialized = True
 
 
+
+for cls in TellClasses():
+    cls.set_mantis_class()

+ 0 - 1
schema_solve.py

@@ -3,7 +3,6 @@ from .utilities import (prRed, prGreen, prPurple, prWhite,
                               wrapRed, wrapGreen, wrapPurple, wrapWhite,
                               wrapRed, wrapGreen, wrapPurple, wrapWhite,
                               wrapOrange,)
                               wrapOrange,)
 from .utilities import init_connections, init_dependencies
 from .utilities import init_connections, init_dependencies
-from .utilities import class_for_mantis_prototype_node
 from .base_definitions import SchemaUINode, GraphError, replace_types, custom_props_types
 from .base_definitions import SchemaUINode, GraphError, replace_types, custom_props_types
 from .node_container_common import setup_custom_props_from_np
 from .node_container_common import setup_custom_props_from_np
 # a class that solves Schema nodes
 # a class that solves Schema nodes

+ 0 - 74
utilities.py

@@ -602,80 +602,6 @@ def project_point_to_plane(point, origin, normal):
 # stuff I should probably refactor!!
 # stuff I should probably refactor!!
 ##################################################################################################
 ##################################################################################################
 
 
-# what in the cuss is this horrible abomination??
-def class_for_mantis_prototype_node(prototype_node):
-    """ This is a class which returns a class to instantiate for
-        the given prototype node."""
-    #from .node_container_classes import TellClasses
-    from . import xForm_containers, link_containers, misc_containers, primitives_containers, deformer_containers, math_containers, schema_containers
-    classes = {}
-    for module in [xForm_containers, link_containers, misc_containers, primitives_containers, deformer_containers, math_containers, schema_containers]:
-        for cls in module.TellClasses():
-            classes[cls.__name__] = cls
-    # I could probably do a string.replace() here
-    # But I actually think this is a bad idea since I might not
-    #  want to use this name convention in the future
-    #  this is easy enough for now, may refactor.
-    if prototype_node.bl_idname == 'xFormArmatureNode':
-        return classes["xFormArmature"]
-    elif prototype_node.bl_idname == 'xFormBoneNode':
-        return classes["xFormBone"]
-    elif prototype_node.bl_idname == 'xFormGeometryObject':
-        return classes["xFormGeometryObject"]
-    elif prototype_node.bl_idname == 'linkInherit':
-        return classes["LinkInherit"]
-    elif prototype_node.bl_idname == 'InputFloatNode':
-        return classes["InputFloat"]
-    elif prototype_node.bl_idname == 'InputVectorNode':
-        return classes["InputVector"]
-    elif prototype_node.bl_idname == 'InputBooleanNode':
-        return classes["InputBoolean"]
-    elif prototype_node.bl_idname == 'InputBooleanThreeTupleNode':
-        return classes["InputBooleanThreeTuple"]
-    elif prototype_node.bl_idname == 'InputRotationOrderNode':
-        return classes["InputRotationOrder"]
-    elif prototype_node.bl_idname == 'InputTransformSpaceNode':
-        return classes["InputTransformSpace"]
-    elif prototype_node.bl_idname == 'InputStringNode':
-        return classes["InputString"]
-    elif prototype_node.bl_idname == 'InputQuaternionNode':
-        return classes["InputQuaternion"]
-    elif prototype_node.bl_idname == 'InputQuaternionNodeAA':
-        return classes["InputQuaternionAA"]
-    elif prototype_node.bl_idname == 'InputMatrixNode':
-        return classes["InputMatrix"]
-    elif prototype_node.bl_idname == 'MetaRigMatrixNode':
-        return classes["InputMatrix"]
-    elif prototype_node.bl_idname == 'InputLayerMaskNode':
-        return classes["InputLayerMask"]
-    elif prototype_node.bl_idname == 'GeometryCirclePrimitive':
-        return classes["CirclePrimitive"]
-        
-    # every node before this point is not guarenteed to follow the pattern
-    # but every node not checked above does follow the pattern.
-    
-    try:
-        return classes[ prototype_node.bl_idname ]
-    except KeyError:
-        # prGreen(prototype_node.bl_idname)
-        # prWhite(classes.keys())
-        pass
-    
-    if prototype_node.bl_idname in [ 
-                                    "NodeReroute",
-                                    "NodeGroupInput",
-                                    "NodeGroupOutput",
-                                    "MantisNodeGroup",
-                                    "NodeFrame",
-                                    "MantisSchemaGroup",
-                                   ]:
-           return None
-    
-    prRed(prototype_node.bl_idname)
-    raise RuntimeError(wrapOrange("Failed to create node container for: ")+wrapRed("%s" % prototype_node.bl_idname))
-    return None
-
-
 # This is really, really stupid way to do this
 # This is really, really stupid way to do this
 def gen_nc_input_for_data(socket):
 def gen_nc_input_for_data(socket):
     # Class List #TODO deduplicate
     # Class List #TODO deduplicate

+ 7 - 0
xForm_definitions.py

@@ -162,6 +162,7 @@ class xFormBoneNode(Node, xFormNode):
     display_bb_settings : bpy.props.BoolProperty(default=False)
     display_bb_settings : bpy.props.BoolProperty(default=False)
     socket_count : bpy.props.IntProperty()
     socket_count : bpy.props.IntProperty()
     initialized : bpy.props.BoolProperty(default = False)
     initialized : bpy.props.BoolProperty(default = False)
+    mantis_node_class_name=bl_idname[:-4]
     
     
     def init(self, context):
     def init(self, context):
 
 
@@ -270,6 +271,7 @@ class xFormArmatureNode(Node, xFormNode):
     bl_label = "Armature"
     bl_label = "Armature"
     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]
 
 
     def init(self, context):
     def init(self, context):
         self.inputs.new('StringSocket', "Name")
         self.inputs.new('StringSocket', "Name")
@@ -301,6 +303,7 @@ class xFormGeometryObjectNode(Node, xFormNode):
     bl_label = "Geometry Object"
     bl_label = "Geometry Object"
     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
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new('StringSocket', "Name")
         self.inputs.new('StringSocket', "Name")
@@ -334,6 +337,7 @@ class xFormObjectInstance(Node, xFormNode):
     bl_label = "Object Instance"
     bl_label = "Object Instance"
     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
     
     
     def init(self, context):
     def init(self, context):
         self.inputs.new('StringSocket', "Name")
         self.inputs.new('StringSocket', "Name")
@@ -361,3 +365,6 @@ class xFormObjectInstance(Node, xFormNode):
             self.inputs['Name'].display_text = ""
             self.inputs['Name'].display_text = ""
             if nc:
             if nc:
                 self.inputs['Name'].display_text = nc.evaluate_input("Name")
                 self.inputs['Name'].display_text = nc.evaluate_input("Name")
+
+for cls in TellClasses():
+    cls.set_mantis_class()