Explorar el Código

Cleanup: All node containers are now MantisNode's

Rename the old MantisNode class to MantisUINode
Now all node containers are MantisNode sub-classes. The MantisNode class
has the basic methods for every MantisNode - fill_parameters, evaluate_input,
__repr__, flush_links, and noops for the methods that should be overridden if
they are needed (bPrepare, bExecute, bFinalize).
Accordingly, the definitions of these methods have been removed from the container classes and node_container_common and defined in the MantisNode class instead.

Further work:
 - Continue to unify methods behind inheritance or composition
 - Default __init__() in MantisNode (and other defaults/useful methods, maybe)
 - UI Classes should be constructed & registered by MantisNode class methods
 - Remove boilerplate, rename files & delete unneeded files
 - new classes for MantisNodeSocket collections (inputs, outputs)
 - Parameters should be renamed EvaluatedOutputs or something like

Once node definitions are unified and organized under a reasonable class hierarchy,
it will be time to split some of the bigger files and refactor the Socket definitions.

This patch has been tested against the Mech Rig and the Component Pack v1.2.
It also fixes a small bug in driver node execution so I could test it against the face
rig. Finally, it updates the version string.
Joseph Brandenburg hace 7 meses
padre
commit
f09488fb97

+ 1 - 1
__init__.py

@@ -17,7 +17,7 @@ from .utilities import prRed
 
 MANTIS_VERSION_MAJOR=0
 MANTIS_VERSION_MINOR=9
-MANTIS_VERSION_SUB=12
+MANTIS_VERSION_SUB=13
 
 classLists = [module.TellClasses() for module in [
  link_definitions,

+ 86 - 6
base_definitions.py

@@ -131,8 +131,87 @@ class SchemaTree(NodeTree):
             
 
 
+#TODO: do a better job explaining how the following two classes relate.
 
 class MantisNode:
+    """
+        This class contains the basic interface for a Mantis Node.
+        A MantisNode is used internally by Mantis to represent the final evaluated node graph.
+        It gets generated with data from a MantisUINode when the graph is read.
+    """
+    def flush_links(self):
+        for inp in self.inputs.values():
+            inp.flush_links()
+        for out in self.outputs.values():
+            out.flush_links()
+    
+    def evaluate_input(self, input_name, index=0):
+        from .node_container_common import trace_single_line
+        if not (self.inputs.get(input_name)): # get the named parameter if there is no input
+            if input_name == 'Meta-Armature':
+                prOrange("beans are not frogs")
+            return self.parameters.get(input_name) # this will return None if the parameter does not exist.
+        # this trace() should give a key error if there is a problem
+        #  it is NOT handled here because it should NOT happen - so I want the error message.
+        trace = trace_single_line(self, input_name, index)
+        prop = trace[0][-1].parameters[trace[1].name] #trace[0] = the list of traced nodes; read its parameters
+        return prop
+    
+    def fill_parameters(self, ui_node=None):
+        from .utilities import get_node_prototype
+        from .node_container_common import get_socket_value
+        if not ui_node:
+            if ( (self.signature[0] in  ["MANTIS_AUTOGENERATED", "SCHEMA_AUTOGENERATED" ]) or 
+                (self.signature[-1] in ["NodeGroupOutput", "NodeGroupInput"]) ): # I think this is harmless
+                return None
+            else:
+                ui_node = get_node_prototype(self.signature, self.base_tree)
+            if not ui_node:
+                raise RuntimeError(wrapRed("No node prototype found for... %s" % ( [self.base_tree] + list(self.signature[1:]) ) ) )
+        for key in self.parameters.keys():
+            node_socket = ui_node.inputs.get(key)
+            if self.parameters[key] is not None: # the parameters are usually initialized as None.
+                continue # will be filled by the node itself
+            if not node_socket: #maybe the node socket has no name
+                if ( ( len(ui_node.inputs) == 0) and ( len(ui_node.outputs) == 1) ):
+                    # this is a simple input node.
+                    node_socket = ui_node.outputs[0]
+                elif key == 'Name': # for Links we just use the Node Label, or if there is no label, the name.
+                    self.parameters[key] = ui_node.label if ui_node.label else ui_node.name
+                    continue
+                else:
+                    pass
+            if node_socket:
+                if node_socket.bl_idname in  ['RelationshipSocket', 'xFormSocket']:
+                    continue
+                elif node_socket.is_linked and (not node_socket.is_output):
+                    pass # we will get the value from the link, because this is a linked input port.
+                # very importantly, we do not pass linked outputs- fill these because they are probably Input nodes.
+                elif hasattr(node_socket, "default_value"):
+                    if (value := get_socket_value(node_socket)) is not None:
+                        self.parameters[key] = value
+                        # TODO: try and remove the input if it is not needed (for performance speed)
+                    else:
+                        raise RuntimeError(wrapRed("No value found for " + self.__repr__() + " when filling out node parameters for " + ui_node.name + "::"+node_socket.name))
+                else:
+                    pass
+    
+    def bPrepare(self, bContext=None):
+        return
+    def bExecute(self, bContext=None):
+        return
+    def bFinalize(self, bContext=None):
+        return
+    def __repr__(self): 
+        return self.signature.__repr__()
+
+
+class MantisUINode:
+    """
+        This class contains the common user-interface features of Mantis nodes.
+        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.
+    """
     @classmethod
     def poll(cls, ntree):
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
@@ -148,23 +227,24 @@ class MantisNode:
                     node_tree.num_links+=1
                 elif (link.to_socket.is_multi_input):
                     node_tree.num_links+=1
+        
             
-class SchemaNode:
+class SchemaUINode:
     @classmethod
     def poll(cls, ntree):
         return (ntree.bl_idname in ['SchemaTree'])
 
-class LinkNode(MantisNode):
+class LinkNode(MantisUINode):
     @classmethod
     def poll(cls, ntree):
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
 
-class xFormNode(MantisNode):
+class xFormNode(MantisUINode):
     @classmethod
     def poll(cls, ntree):
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
 
-class DeformerNode(MantisNode):
+class DeformerNode(MantisUINode):
     @classmethod
     def poll(cls, ntree):
         return (ntree.bl_idname in ['MantisTree', 'SchemaTree'])
@@ -281,7 +361,7 @@ def node_tree_prop_update(self, context):
 
 from bpy.types import NodeCustomGroup
 
-class MantisNodeGroup(Node, MantisNode):
+class MantisNodeGroup(Node, MantisUINode):
     bl_idname = "MantisNodeGroup"
     bl_label = "Node Group"
 
@@ -323,7 +403,7 @@ def poll_node_tree_schema(self, object):
 
 # TODO tiny UI problem - inserting new links into the tree will not place them in the right place.
 
-class SchemaGroup(Node, MantisNode):
+class SchemaGroup(Node, MantisUINode):
     bl_idname = "MantisSchemaGroup"
     bl_label = "Node Schema"
     

+ 1 - 1
blender_manifest.toml

@@ -3,7 +3,7 @@ schema_version = "1.0.0"
 # Example of manifest file for a Blender extension
 # Change the values according to your extension
 id = "mantis"
-version = "0.9.12"
+version = "0.9.13"
 name = "Mantis"
 tagline = "Mantis is a rigging nodes toolkit"
 maintainer = "Nodespaghetti <josephbburg@protonmail.com>"

+ 8 - 19
deformer_containers.py

@@ -1,7 +1,6 @@
 from .node_container_common import *
 from .xForm_containers import xFormGeometryObject
 from .misc_containers import InputExistingGeometryObject
-from bpy.types import Node
 from .base_definitions import MantisNode
 
 from .utilities import (prRed, prGreen, prPurple, prWhite, prOrange,
@@ -49,7 +48,7 @@ def GetxForm(nc):
             return node
     raise GraphError("%s is not connected to a downstream xForm" % nc)
 
-class DeformerArmature:
+class DeformerArmature(MantisNode):
     '''A node representing an armature deformer'''
 
     def __init__(self, signature, base_tree):
@@ -92,8 +91,6 @@ class DeformerArmature:
         self.prepared = True
         self.executed = False
 
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
 
     def GetxForm(self, socket="Deformer"):
         if socket == "Deformer":
@@ -231,7 +228,7 @@ class DeformerArmature:
             self.copy_weights()
 
 
-class DeformerHook:
+class DeformerHook(MantisNode):
     '''A node representing a hook deformer'''
 
     def __init__(self, signature, base_tree):
@@ -259,8 +256,7 @@ class DeformerHook:
         self.prepared = True
         self.executed = False
 
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def GetxForm(self, socket="Deformer"):
         if socket == "Deformer":
@@ -299,9 +295,12 @@ class DeformerHook:
         vertices_used.append(self.evaluate_input("Index"))
         d.vertex_indices_set(vertices_used)
         # todo: this should be able to take many indices in the future.
+        # since this only takes a single index, I can always hack together a shape-key solution to tilt...
+        # GN solution would work too, provided a separate object is made for it
+        # I like this, it is perhaps a little innefficient but can be improved later on
 
 
-class DeformerMorphTarget:
+class DeformerMorphTarget(MantisNode):
     '''A node representing an armature deformer'''
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -366,7 +365,7 @@ class DeformerMorphTarget:
 
 
 
-class DeformerMorphTargetDeform:
+class DeformerMorphTargetDeform(MantisNode):
     '''A node representing an armature deformer'''
 
     def __init__(self, signature, base_tree):
@@ -522,13 +521,3 @@ class DeformerMorphTargetDeform:
             self.gen_shape_key(bContext)
         else:
             self.gen_morph_target_modifier(bContext)
-
-
-        
-        
-            
-
-        
-
-for c in TellClasses():
-    setup_container(c)

+ 1 - 1
deformer_definitions.py

@@ -1,6 +1,6 @@
 import bpy
 from bpy.types import NodeTree, Node, NodeSocket
-from .base_definitions import MantisNode, DeformerNode, get_signature_from_edited_tree
+from .base_definitions import MantisUINode, DeformerNode, get_signature_from_edited_tree
 
 from .utilities import (prRed, prGreen, prPurple, prWhite, prOrange,
                         wrapRed, wrapGreen, wrapPurple, wrapWhite,

+ 5 - 8
internal_containers.py

@@ -3,7 +3,7 @@ from bpy.types import Node
 from .base_definitions import MantisNode
 from uuid import uuid4
 
-class DummyNode:
+class DummyNode(MantisNode):
     def __init__(self, signature, base_tree, prototype = None, natural_signature=None):
         self.signature = signature
         self.base_tree = base_tree
@@ -27,20 +27,19 @@ class DummyNode:
                     continue
                 self.outputs[sock.identifier] = NodeSocket(is_input = False, name = sock.identifier, node = self)
                 self.parameters[sock.identifier]=None
-        #HACK
+        # keep track of the "natural signature" of Schema nodes - so that they are unambiguous
         if natural_signature:
             self.natural_signature=natural_signature
-        #HACK
+        # This is necessary for Schema to work if there are multiple Schema nodes using the same Schema tree.
+        # this is ugly and I hate it.
         self.hierarchy_connections = []
         self.connections = []
         self.hierarchy_dependencies = []
         self.dependencies = []
         self.executed = False
 
-setup_container(DummyNode)
 
-
-class NoOpNode:
+class NoOpNode(MantisNode):
     def __init__(self, signature, base_tree):
         self.signature = signature
         self.base_tree = base_tree
@@ -63,5 +62,3 @@ class NoOpNode:
         self.executed = True
     
     # this node is useful for me to insert in the tree and use for debugging especially connections.
-
-setup_container(NoOpNode)

+ 50 - 77
link_containers.py

@@ -1,5 +1,5 @@
 from .node_container_common import *
-from bpy.types import Node, Bone
+from bpy.types import Bone
 from .base_definitions import MantisNode, GraphError
 
 def TellClasses():
@@ -32,18 +32,17 @@ def TellClasses():
              LinkDrivenParameter,
             ]
 
-
-
-def default_evaluate_input(nc, input_name):
-    # should catch 'Target', 'Pole Target' and ArmatureConstraint targets, too
-    if ('Target' in input_name) and input_name not in  ["Target Space", "Use Target Z"]:
-        socket = nc.inputs.get(input_name)
-        if socket.is_linked:
-            return socket.links[0].from_node
-        return None
-        
-    else:
-        return evaluate_input(nc, input_name)
+class MantisLinkNode(MantisNode):
+    def evaluate_input(self, input_name, index=0):
+        # should catch 'Target', 'Pole Target' and ArmatureConstraint targets, too
+        if ('Target' in input_name) and input_name not in  ["Target Space", "Use Target Z"]:
+            socket = self.inputs.get(input_name)
+            if socket.is_linked:
+                return socket.links[0].from_node
+            return None
+            
+        else:
+            return super().evaluate_input(input_name)
 
 # set the name if it is available, otherwise just use the constraint's nice name
 set_constraint_name = lambda nc : nc.evaluate_input("Name") if nc.evaluate_input("Name") else nc.__class__.__name__
@@ -60,7 +59,7 @@ def GetxForm(nc):
             return node
     raise GraphError("%s is not connected to a downstream xForm" % nc)
 
-class LinkInherit:
+class LinkInherit(MantisLinkNode):
     '''A node representing inheritance'''
     
     def __init__(self, signature, base_tree):
@@ -93,10 +92,6 @@ class LinkInherit:
         self.prepared = True
         self.executed = True
     
-        
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
-        
     def GetxForm(self): # DUPLICATED, TODO fix this
         # I think this is only run in display update.
         trace = trace_single_line_up(self, "Inheritance")
@@ -109,7 +104,7 @@ class LinkInherit:
         
 
 
-class LinkCopyLocation:
+class LinkCopyLocation(MantisLinkNode):
     '''A node representing Copy Location'''
     
     def __init__(self, signature, base_tree):
@@ -155,8 +150,7 @@ class LinkCopyLocation:
         
         
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
     
     def GetxForm(self):
         return GetxForm(self)
@@ -215,7 +209,7 @@ class LinkCopyLocation:
         
         
 
-class LinkCopyRotation:
+class LinkCopyRotation(MantisLinkNode):
     '''A node representing Copy Rotation'''
     
     def __init__(self, signature, base_tree):
@@ -257,8 +251,7 @@ class LinkCopyRotation:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
     
     def GetxForm(self):
         return GetxForm(self)
@@ -324,7 +317,7 @@ class LinkCopyRotation:
     
         
         
-class LinkCopyScale:
+class LinkCopyScale(MantisLinkNode):
     '''A node representing Copy Scale'''
     
     def __init__(self, signature, base_tree):
@@ -367,8 +360,7 @@ class LinkCopyScale:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
     
     def GetxForm(self):
         return GetxForm(self)
@@ -422,7 +414,7 @@ class LinkCopyScale:
     
         
 
-class LinkCopyTransforms:
+class LinkCopyTransforms(MantisLinkNode):
     '''A node representing Copy Transfoms'''
     
     def __init__(self, signature, base_tree):
@@ -463,8 +455,7 @@ class LinkCopyTransforms:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
     
     def GetxForm(self):
         return GetxForm(self)
@@ -571,7 +562,7 @@ transformation_props_sockets = {
             'mute'                   : ("Enable", False),
         }
 
-class LinkTransformation:
+class LinkTransformation(MantisLinkNode):
     '''A node representing Copy Transfoms'''
     
     def __init__(self, signature, base_tree):
@@ -652,8 +643,7 @@ class LinkTransformation:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
     
     def GetxForm(self):
         return GetxForm(self)
@@ -697,7 +687,7 @@ class LinkTransformation:
     
         
 
-class LinkLimitLocation:
+class LinkLimitLocation(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -751,8 +741,7 @@ class LinkLimitLocation:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
     
     def GetxForm(self):
         return GetxForm(self)
@@ -805,7 +794,7 @@ class LinkLimitLocation:
     
         
         
-class LinkLimitRotation:
+class LinkLimitRotation(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -853,8 +842,7 @@ class LinkLimitRotation:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
     
     def GetxForm(self):
         return GetxForm(self)
@@ -903,7 +891,7 @@ class LinkLimitRotation:
     
         
         
-class LinkLimitScale:
+class LinkLimitScale(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -957,8 +945,7 @@ class LinkLimitScale:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
     
     def GetxForm(self):
         return GetxForm(self)
@@ -1010,7 +997,7 @@ class LinkLimitScale:
     
         
         
-class LinkLimitDistance:
+class LinkLimitDistance(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -1052,8 +1039,7 @@ class LinkLimitDistance:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def GetxForm(self):
         return GetxForm(self)
@@ -1113,7 +1099,7 @@ class LinkLimitDistance:
 
 # Tracking
 
-class LinkStretchTo:
+class LinkStretchTo(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -1163,8 +1149,7 @@ class LinkStretchTo:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def GetxForm(self):
         return GetxForm(self)
@@ -1206,7 +1191,7 @@ class LinkStretchTo:
     
         
 
-class LinkDampedTrack:
+class LinkDampedTrack(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -1240,8 +1225,7 @@ class LinkDampedTrack:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def GetxForm(self):
         return GetxForm(self)
@@ -1271,7 +1255,7 @@ class LinkDampedTrack:
         
         
 
-class LinkLockedTrack:
+class LinkLockedTrack(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -1307,8 +1291,7 @@ class LinkLockedTrack:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def GetxForm(self):
         return GetxForm(self)
@@ -1339,7 +1322,7 @@ class LinkLockedTrack:
     
         
 
-class LinkTrackTo:
+class LinkTrackTo(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -1377,8 +1360,7 @@ class LinkTrackTo:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def GetxForm(self):
         return GetxForm(self)
@@ -1412,7 +1394,7 @@ class LinkTrackTo:
 
 # relationships & misc.
 
-class LinkInheritConstraint:
+class LinkInheritConstraint(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -1447,8 +1429,7 @@ class LinkInheritConstraint:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def GetxForm(self):
         return GetxForm(self)
@@ -1488,7 +1469,7 @@ class LinkInheritConstraint:
     def bFinalize(self, bContext = None):
         finish_drivers(self)
 
-class LinkInverseKinematics:
+class LinkInverseKinematics(MantisLinkNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -1530,8 +1511,7 @@ class LinkInverseKinematics:
         self.prepared = True
         self.executed = False
         
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def GetxForm(self):
         return GetxForm(self)
@@ -1642,7 +1622,7 @@ class LinkInverseKinematics:
         
 
 # This is kinda a weird design decision?
-class LinkDrivenParameter:
+class LinkDrivenParameter(MantisLinkNode):
     '''A node representing an armature object'''
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -1673,8 +1653,7 @@ class LinkDrivenParameter:
     def GetxForm(self):
         return GetxForm(self)
 
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def bExecute(self, bContext = None,):
         prepare_parameters(self)
@@ -1724,7 +1703,7 @@ class LinkDrivenParameter:
         
 
         
-class LinkArmature:
+class LinkArmature(MantisLinkNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree,):
@@ -1762,8 +1741,7 @@ class LinkArmature:
     def GetxForm(self):
         return GetxForm(self)
 
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def bExecute(self, bContext = None,):
         prGreen("Creating Armature Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")
@@ -1808,7 +1786,7 @@ class LinkArmature:
 
 
 
-class LinkSplineIK:
+class LinkSplineIK(MantisLinkNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -1849,8 +1827,7 @@ class LinkSplineIK:
         self.hierarchy_dependencies, self.dependencies = [], []
         self.prepared, self.executed = True, False
 
-    def evaluate_input(self, input_name):
-        return default_evaluate_input(self, input_name)
+
 
     def GetxForm(self):
         return GetxForm(self)
@@ -1875,8 +1852,4 @@ class LinkSplineIK:
         }
 
         evaluate_sockets(self, c, props_sockets)
-        self.executed = True
-
-
-for c in TellClasses():
-    setup_container(c)
+        self.executed = True

+ 1 - 1
link_definitions.py

@@ -1,6 +1,6 @@
 import bpy
 from bpy.types import NodeTree, Node, NodeSocket
-from .base_definitions import MantisNode, LinkNode, GraphError
+from .base_definitions import MantisUINode, LinkNode, GraphError
 from .utilities import (prRed, prGreen, prPurple, prWhite,
                               prOrange,
                               wrapRed, wrapGreen, wrapPurple, wrapWhite,

+ 4 - 7
math_containers.py

@@ -1,4 +1,5 @@
 from .node_container_common import *
+from .base_definitions import MantisNode
 
 def TellClasses():
     return [
@@ -10,7 +11,7 @@ def TellClasses():
 #*#-------------------------------#++#-------------------------------#*#
 # M A T H  N O D E S
 #*#-------------------------------#++#-------------------------------#*#
-class MathStaticInt:
+class MathStaticInt(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -68,7 +69,7 @@ class MathStaticInt:
         self.prepared = True
         self.executed = True
 
-class MathStaticFloat:
+class MathStaticFloat(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -131,7 +132,7 @@ class MathStaticFloat:
         self.prepared = True
         self.executed = True
 
-class MathStaticVector:
+class MathStaticVector(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -203,7 +204,3 @@ class MathStaticVector:
         self.parameters["Result Vector"] = v_result
         self.prepared = True
         self.executed = True
-
-
-for c in TellClasses():
-    setup_container(c)

+ 4 - 4
math_definitions.py

@@ -1,5 +1,5 @@
 import bpy
-from .base_definitions import MantisNode
+from .base_definitions import MantisUINode
 from bpy.types import Node
 from .utilities import (prRed, prGreen, prPurple, prWhite,
                               prOrange,
@@ -18,7 +18,7 @@ def TellClasses():
 
         
 
-class MathStaticInt(Node, MantisNode):
+class MathStaticInt(Node, MantisUINode):
     """A node that performs mathematical operations on float numbers as a preprocess step before generating the rig."""
     bl_idname = "MathStaticInt"
     bl_label = "Static Int Math"
@@ -45,7 +45,7 @@ class MathStaticInt(Node, MantisNode):
                 self.inputs["Int B"].hide = False
 
 # do... make the operations now
-class MathStaticFloatNode(Node, MantisNode):
+class MathStaticFloatNode(Node, MantisUINode):
     """A node that performs mathematical operations on float numbers as a preprocess step before generating the rig."""
     bl_idname = "MathStaticFloat"
     bl_label = "Static Float Math"
@@ -71,7 +71,7 @@ class MathStaticFloatNode(Node, MantisNode):
             else:
                 self.inputs["Float B"].hide = False
 
-class MathStaticVectorNode(Node, MantisNode):
+class MathStaticVectorNode(Node, MantisUINode):
     """Performs a vector math operation as a preprocess before executing the tree."""
     bl_idname = "MathStaticVector"
     bl_label = "Static Vector Math"

+ 51 - 70
misc_containers.py

@@ -1,7 +1,6 @@
 from .node_container_common import *
+from .base_definitions import MantisNode
 
-# The fact that I need this means that some of these classes should
-#  probably be moved to link_containers.py
 from .xForm_containers import xFormArmature, xFormBone
 
 from math import pi, tau
@@ -68,7 +67,7 @@ def matrix_from_head_tail(head, tail):
 # U T I L I T Y   N O D E S
 #*#-------------------------------#++#-------------------------------#*#
 
-class InputFloat:
+class InputFloat(MantisNode):
     '''A node representing float input'''
     
     def __init__(self, signature, base_tree):
@@ -88,7 +87,7 @@ class InputFloat:
     def evaluate_input(self, input_name):
         return self.parameters["Float Input"]
 
-class InputIntNode:
+class InputIntNode(MantisNode):
     '''A node representing integer input'''
     
     def __init__(self, signature, base_tree):
@@ -108,7 +107,7 @@ class InputIntNode:
     def evaluate_input(self, input_name):
         return self.parameters["Integer"]
     
-class InputVector:
+class InputVector(MantisNode):
     '''A node representing vector input'''
     
     def __init__(self, signature, base_tree):
@@ -129,7 +128,7 @@ class InputVector:
         return self.parameters[""]
     
 
-class InputBoolean:
+class InputBoolean(MantisNode):
     '''A node representing boolean input'''
     
     def __init__(self, signature, base_tree):
@@ -149,7 +148,7 @@ class InputBoolean:
     def evaluate_input(self, input_name):
         return self.parameters[""]
 
-class InputBooleanThreeTuple:
+class InputBooleanThreeTuple(MantisNode):
     '''A node representing a tuple of three booleans'''
         
     def __init__(self, signature, base_tree):
@@ -169,7 +168,7 @@ class InputBooleanThreeTuple:
     def evaluate_input(self, input_name):
         return self.parameters[""]
     
-class InputRotationOrder:
+class InputRotationOrder(MantisNode):
     '''A node representing string input for rotation order'''
         
     def __init__(self, signature, base_tree):
@@ -190,7 +189,7 @@ class InputRotationOrder:
         return self.parameters[""]
     
 
-class InputTransformSpace:
+class InputTransformSpace(MantisNode):
     '''A node representing string input for transform space'''
         
     def __init__(self, signature, base_tree):
@@ -210,7 +209,7 @@ class InputTransformSpace:
     def evaluate_input(self, input_name):
         return self.parameters[""]
     
-class InputString:
+class InputString(MantisNode):
     '''A node representing string input'''
         
     def __init__(self, signature, base_tree):
@@ -230,7 +229,7 @@ class InputString:
     def evaluate_input(self, input_name):
         return self.parameters[""]
     
-class InputMatrix:
+class InputMatrix(MantisNode):
     '''A node representing axis-angle quaternion input'''
         
     def __init__(self, signature, base_tree):
@@ -263,7 +262,7 @@ class InputMatrix:
     def fill_parameters(self):
         return
 
-class UtilityMatrixFromCurve:
+class UtilityMatrixFromCurve(MantisNode):
     '''Get a matrix from a curve'''
 
     def __init__(self, signature, base_tree):
@@ -333,11 +332,8 @@ class UtilityMatrixFromCurve:
         if (mesh := bpy.data.meshes.get(m_name)):
             bpy.data.meshes.remove(mesh)
 
-    def fill_parameters(self):
-        fill_parameters(self)
-
 
-class UtilityPointFromCurve:
+class UtilityPointFromCurve(MantisNode):
     '''Get a point from a curve'''
 
     def __init__(self, signature, base_tree):
@@ -394,10 +390,7 @@ class UtilityPointFromCurve:
         if (mesh := bpy.data.meshes.get(m_name)):
             bpy.data.meshes.remove(mesh)
 
-    def fill_parameters(self):
-        fill_parameters(self)
-
-class UtilityMatricesFromCurve:
+class UtilityMatricesFromCurve(MantisNode):
     '''Get matrices from a curve'''
 
     def __init__(self, signature, base_tree):
@@ -478,10 +471,7 @@ class UtilityMatricesFromCurve:
             prGreen(f"Freeing mesh data {m_name}...")
             bpy.data.meshes.remove(mesh)
 
-    def fill_parameters(self):
-        fill_parameters(self)
-
-class UtilityMetaRig:
+class UtilityMetaRig(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -537,13 +527,9 @@ class UtilityMetaRig:
         self.prepared = True
         self.executed = True
 
-    def fill_parameters(self):
-        fill_parameters(self)
-        # self.parameters["Matrix"] = None # why in the
 
-
-class UtilityBoneProperties:
-    '''A node representing an armature object'''
+class UtilityBoneProperties(MantisNode):
+    '''A node representing a bone's gettable properties'''
 
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -583,10 +569,10 @@ class UtilityBoneProperties:
         self.executed = True
 
     def fill_parameters(self):
-        pass#fill_parameters(self)
+        return
         
 # TODO this should probably be moved to Links
-class UtilityDriverVariable:
+class UtilityDriverVariable(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -631,7 +617,7 @@ class UtilityDriverVariable:
                     trace = trace_single_line(self, input_name)
                     return trace[1].name # the name of the socket
             return self.parameters["Property"]
-        return evaluate_input(self, input_name)
+        return super().evaluate_input(input_name)
         
     def GetxForm(self, index=1):
         trace = trace_single_line(self, "xForm 1" if index == 1 else "xForm 2")
@@ -693,7 +679,7 @@ class UtilityDriverVariable:
 
 
 
-class UtilityKeyframe:
+class UtilityKeyframe(MantisNode):
     '''A node representing a keyframe for a F-Curve'''
 
     def __init__(self, signature, base_tree):
@@ -734,7 +720,7 @@ class UtilityKeyframe:
         self.executed = True
 
 
-class UtilityFCurve:
+class UtilityFCurve(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -761,7 +747,7 @@ class UtilityFCurve:
         self.executed = False
 
     def evaluate_input(self, input_name):
-        return evaluate_input(self, input_name)
+        return super().evaluate_input(input_name)
 
     def bExecute(self, bContext = None,):
         prepare_parameters(self)
@@ -787,7 +773,7 @@ class UtilityFCurve:
         self.executed = True
 #TODO make the fCurve data a data class instead of a dict 
 
-class UtilityDriver:
+class UtilityDriver(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -824,7 +810,7 @@ class UtilityDriver:
         #prPurple("Executing Driver Node")
         my_vars = []
         keys = self.evaluate_input("fCurve")
-        if len(keys) <2:
+        if keys is None or len(keys) <2:
             prWhite(f"INFO: no fCurve connected to {self}; using default fCurve.")
             from mathutils import Vector
             keys = [
@@ -853,7 +839,7 @@ class UtilityDriver:
         self.executed = True
 
 
-class UtilitySwitch:
+class UtilitySwitch(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -891,7 +877,7 @@ class UtilitySwitch:
                 trace = trace_single_line(self, input_name)
                 return trace[1].name # the name of the socket
             return self.parameters["Parameter"]
-        return evaluate_input(self, input_name)
+        return super().evaluate_input(input_name)
 
     def GetxForm(self,):
         trace = trace_single_line(self, "Parameter" )
@@ -946,7 +932,7 @@ class UtilitySwitch:
 
 
 
-class UtilityCombineThreeBool:
+class UtilityCombineThreeBool(MantisNode):
     '''A node for combining three booleans into a boolean three-tuple'''
 
     def __init__(self, signature, base_tree):
@@ -992,7 +978,7 @@ class UtilityCombineThreeBool:
 # Note this is a copy of the above. This needs to be de-duplicated into
   # a simpler CombineVector node_container.
   # TODO
-class UtilityCombineVector:
+class UtilityCombineVector(MantisNode):
     '''A node for combining three floats into a vector'''
 
     def __init__(self, signature, base_tree):
@@ -1031,7 +1017,7 @@ class UtilityCombineVector:
   
 
   # TODO
-class UtilitySeparateVector:
+class UtilitySeparateVector(MantisNode):
     '''A node for separating a vector into three floats'''
 
     def __init__(self, signature, base_tree):
@@ -1063,7 +1049,7 @@ class UtilitySeparateVector:
         self.prepared = True
         self.executed = True
 
-class UtilityCatStrings:
+class UtilityCatStrings(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -1094,7 +1080,7 @@ class UtilityCatStrings:
         self.prepared = True
         self.executed = True
 
-class InputLayerMask:
+class InputLayerMask(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -1119,7 +1105,7 @@ class InputLayerMask:
         self.executed = True
 
 
-class InputExistingGeometryObject:
+class InputExistingGeometryObject(MantisNode):
     '''A node representing an existing object'''
 
     def __init__(self, signature, base_tree):
@@ -1157,7 +1143,7 @@ class InputExistingGeometryObject:
     def bGetObject(self, mode=''):
         return self.bObject
 
-class InputExistingGeometryData:
+class InputExistingGeometryData(MantisNode):
     '''A node representing existing object data'''
 
     def __init__(self, signature, base_tree):
@@ -1193,7 +1179,7 @@ class InputExistingGeometryData:
             raise RuntimeError(f"Could not find a mesh or curve datablock named \"{self.evaluate_input('Name')}\" for node {self}")
         return bObject
 
-class UtilityGeometryOfXForm:
+class UtilityGeometryOfXForm(MantisNode):
     '''A node representing existing object data'''
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -1229,7 +1215,7 @@ class UtilityGeometryOfXForm:
         return None
 
 
-class UtilityNameOfXForm:
+class UtilityNameOfXForm(MantisNode):
     '''A node representing existing object data'''
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -1260,7 +1246,7 @@ class UtilityNameOfXForm:
         self.parameters["Name"] = xf.evaluate_input('Name')
         self.prepared, self.executed = True, True
 
-class UtilityGetBoneLength:
+class UtilityGetBoneLength(MantisNode):
     '''A node to get the length of a bone matrix'''
 
     def __init__(self, signature, base_tree):
@@ -1292,7 +1278,7 @@ class UtilityGetBoneLength:
         self.prepared = True
         self.executed = True
 
-class UtilityPointFromBoneMatrix:
+class UtilityPointFromBoneMatrix(MantisNode):
     '''A node representing an armature object'''
 
     def __init__(self, signature, base_tree):
@@ -1331,7 +1317,7 @@ class UtilityPointFromBoneMatrix:
         self.executed = True
 
 
-class UtilitySetBoneLength:
+class UtilitySetBoneLength(MantisNode):
     '''Sets the length of a Bone's matrix'''
 
     def __init__(self, signature, base_tree):
@@ -1370,7 +1356,7 @@ class UtilitySetBoneLength:
         self.executed = True
 
   
-class UtilityMatrixSetLocation:
+class UtilityMatrixSetLocation(MantisNode):
     '''Sets the location of a matrix'''
 
     def __init__(self, signature, base_tree):
@@ -1405,7 +1391,7 @@ class UtilityMatrixSetLocation:
         self.prepared = True
         self.executed = True
 
-class UtilityMatrixGetLocation:
+class UtilityMatrixGetLocation(MantisNode):
     '''Gets the location of a matrix'''
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -1433,7 +1419,7 @@ class UtilityMatrixGetLocation:
         self.prepared = True; self.executed = True
 
 
-class UtilityMatrixFromXForm:
+class UtilityMatrixFromXForm(MantisNode):
     """Returns the matrix of the given xForm node."""
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -1473,7 +1459,7 @@ class UtilityMatrixFromXForm:
         self.prepared = True; self.executed = True
 
 
-class UtilityAxesFromMatrix:
+class UtilityAxesFromMatrix(MantisNode):
     """Returns the axes of the given matrix."""
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -1507,7 +1493,7 @@ class UtilityAxesFromMatrix:
         self.prepared = True; self.executed = True
 
 
-class UtilityBoneMatrixHeadTailFlip:
+class UtilityBoneMatrixHeadTailFlip(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.executed = False
@@ -1545,7 +1531,7 @@ class UtilityBoneMatrixHeadTailFlip:
         self.prepared, self.executed = True, True
 
 
-class UtilityMatrixTransform:
+class UtilityMatrixTransform(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.executed = False
@@ -1584,7 +1570,7 @@ class UtilityMatrixTransform:
 
 
 
-class UtilityTransformationMatrix:
+class UtilityTransformationMatrix(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.executed = False
@@ -1631,7 +1617,7 @@ class UtilityTransformationMatrix:
 
 
 
-class UtilityIntToString:
+class UtilityIntToString(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.executed = False
@@ -1665,7 +1651,7 @@ class UtilityIntToString:
         self.prepared = True
         self.executed = True
 
-class UtilityArrayGet:
+class UtilityArrayGet(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.executed = False
@@ -1733,7 +1719,7 @@ class UtilityArrayGet:
         self.prepared = True
         self.executed = True
 
-class UtilitySetBoneMatrixTail:
+class UtilitySetBoneMatrixTail(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.executed = False
@@ -1764,7 +1750,7 @@ class UtilitySetBoneMatrixTail:
 
 
 
-class UtilityPrint:
+class UtilityPrint(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.executed = False
@@ -1799,7 +1785,7 @@ class UtilityPrint:
         self.executed = True
 
 
-class UtilityCompare:
+class UtilityCompare(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.executed = False
@@ -1826,7 +1812,7 @@ class UtilityCompare:
         self.prepared = True; self.executed = True
 
 
-class UtilityChoose:
+class UtilityChoose(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.executed = False
@@ -1858,8 +1844,3 @@ class UtilityChoose:
             self.parameters["Result"] = self.evaluate_input("A")
         self.prepared = True
         self.executed = True
-
-
-
-for c in TellClasses():
-    setup_container(c)

+ 4 - 100
node_container_common.py

@@ -8,78 +8,17 @@ from .base_definitions import GraphError
 # so all the top-level imports are carried over
 
 
+#TODO: refactor the socket definitions so this becomes unnecessary.
 def get_socket_value(node_socket):
-    # if node_socket.bl_idname in  ['RelationshipSocket', 'xFormSocket']:
     value = None
-    if hasattr(node_socket, "default_value"):
+    if hasattr(node_socket, "default_value"): 
         value = node_socket.default_value
     if node_socket.bl_idname == 'MatrixSocket':
         value =  node_socket.TellValue()
     return value
 
-
-# TODO: unify the fill_paramaters for auto-gen nodes
-def fill_parameters(nc, np = None):
-    from .utilities import get_node_prototype
-    if not np:
-        if ( (nc.signature[0] in  ["MANTIS_AUTOGENERATED", "SCHEMA_AUTOGENERATED" ]) or 
-             (nc.signature[-1] in ["NodeGroupOutput", "NodeGroupInput"]) ): # I think this is harmless
-            return None
-        else:
-            np = get_node_prototype(nc.signature, nc.base_tree)
-        if not np:
-            raise RuntimeError(wrapRed("No node prototype found for... %s" % ( [nc.base_tree] + list(nc.signature[1:]) ) ) )
-    for key in nc.parameters.keys():
-        node_socket = np.inputs.get(key)
-        # if (nc.signature[0] is "MANTIS_AUTOGENERATED"):
-            # node_socket = None
-            # for node_socket in np.inputs:
-                # if node_socket.identifier == nc.signature[-1]:
-                    # break
-        if nc.parameters[key] is not None:
-            continue # will be filled by the node itself
-        if not node_socket:
-            #maybe the node socket has no name
-            if ( ( len(np.inputs) == 0) and ( len(np.outputs) == 1) ):
-                # this is a simple input node.
-                node_socket = np.outputs[0]
-            elif key == 'Name': # for Links we just use the Node Label, or if there is no label, the name.
-                nc.parameters[key] = np.label if np.label else np.name
-                continue
-            else:
-                pass
-        if node_socket:
-            if node_socket.bl_idname in  ['RelationshipSocket', 'xFormSocket']:
-                continue
-            elif hasattr(node_socket, "default_value"):
-                if (value := get_socket_value(node_socket)) is not None:
-                    nc.parameters[key] = value
-                else:
-                    raise RuntimeError(wrapRed("No value found for " + nc.__repr__() + " when filling out node parameters for " + np.name + "::"+node_socket.name))
-            else:
-                pass
-        # if key in ['Use Target Z']:
-        #     prRed (nc, key, nc.parameters[key])
-
-
-
-def evaluate_input(node_container, input_name, index=0):
-    if not (node_container.inputs.get(input_name)):
-        # just return the parameter, there is no socket associated
-        # prOrange("No input: %s, %s" %(node_container, input_name))
-        return node_container.parameters.get(input_name)
-    trace = trace_single_line(node_container, input_name, index)
-    # this should give a key error if there is a problem
-    #  it is NOT handled here because it should NOT happen
-    try:
-        prop = trace[0][-1].parameters[trace[1].name] #[0] = nodes [-1] = last node, read its parameters
-    except Exception as e:
-        prRed (trace[1].name, trace[0][-1], "prepared" if trace[0][-1].prepared else "NO","executed" if trace[0][-1].executed else "NO")
-        raise e
-    return prop # this should not be necessary...but dicts will be dicts
-
 def check_for_driver(node_container, input_name, index = None):
-    prop = evaluate_input(node_container, input_name)
+    prop = node_container.evaluate_input(input_name)
     if (index is not None):
         prop = prop[index]
     return (prop.__class__.__name__ == 'MantisDriver')
@@ -703,39 +642,4 @@ class DummyLink:
         else:
             self.original_from = self.from_socket
     def __repr__(self):
-        return(self.nc_from.__repr__()+":"+self.from_socket.name + " -> " + self.nc_to.__repr__()+":"+self.to_socket.name)
-
-
-# Here we setup some properties that we want every class to have
-# I am not using inheritance because I don't like it, I think it adds a bunch of weird complexity
-# This, on the otherhand, is basically just extending the class definitions I have with some boilerplate
-# and that means I can avoid writing the boilerplate, get the benefits of class inheritance, and none of the bad
-# 
-# I don't want these classes to share a superclass, because I want them to be nothing more than a way to
-#    package some methods and data together, so my node tree can be like a linked list using basic types like dict
-# essentially, I don't have any use for a superclass, but I do need these properties and attributes.
-# and now, instead of declaring it, inheriting it, and shadowing it elsewhere, I simply do not declare it unless I need it
-#
-# I've looked in to using an interface or abstract metaclass but all of those seem more complicated than doing this.
-def setup_container(some_class):
-    # NOTE: DO NOT use default properties except for None, we don't want to share data between classes.
-
-    def flush_links(self):
-        for inp in self.inputs.values():
-            inp.flush_links()
-        for out in self.outputs.values():
-            out.flush_links()
-
-    functions = {
-        # importantly: these below are not properties.
-        "evaluate_input" :  lambda self, input_name, index=0 : evaluate_input(self, input_name, index),
-        "fill_parameters" : lambda self : fill_parameters(self),
-        'flush_links': flush_links,
-        "bPrepare" : lambda self, bContext=None : None,
-        "bExecute" : lambda self, bContext=None : None,
-        "bFinalize" : lambda self, bContext=None : None,
-    }
-    for n, f in functions.items():
-        if not hasattr(some_class, n):
-            setattr(some_class, n, f)
-    some_class.__repr__ = lambda self : self.signature.__repr__()
+        return(self.nc_from.__repr__()+":"+self.from_socket.name + " -> " + self.nc_to.__repr__()+":"+self.to_socket.name)

+ 49 - 49
nodes_generic.py

@@ -1,6 +1,6 @@
 import bpy
 from bpy.types import Node
-from .base_definitions import MantisNode
+from .base_definitions import MantisUINode
 
 
 from .utilities import (prRed, prGreen, prPurple, prWhite,
@@ -69,7 +69,7 @@ def default_traverse(self,socket):
     return None
 
 
-class InputFloatNode(Node, MantisNode):
+class InputFloatNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputFloatNode'
     bl_label = "Float"
@@ -80,7 +80,7 @@ class InputFloatNode(Node, MantisNode):
         self.outputs.new('FloatSocket', "Float Input").input = True
         self.initialized = True
 
-class InputIntNode(Node, MantisNode):
+class InputIntNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputIntNode'
     bl_label = "Integer"
@@ -91,7 +91,7 @@ class InputIntNode(Node, MantisNode):
         self.outputs.new('IntSocket', "Integer").input = True
         self.initialized = True
     
-class InputVectorNode(Node, MantisNode):
+class InputVectorNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputVectorNode'
     bl_label = "Vector"
@@ -102,7 +102,7 @@ class InputVectorNode(Node, MantisNode):
         self.outputs.new('VectorSocket', "").input = True
         self.initialized = True
 
-class InputBooleanNode(Node, MantisNode):
+class InputBooleanNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputBooleanNode'
     bl_label = "Boolean"
@@ -113,7 +113,7 @@ class InputBooleanNode(Node, MantisNode):
         self.outputs.new('BooleanSocket', "").input = True
         self.initialized = True
 
-class InputBooleanThreeTupleNode(Node, MantisNode):
+class InputBooleanThreeTupleNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputBooleanThreeTupleNode'
     bl_label = "Boolean Vector"
@@ -124,7 +124,7 @@ class InputBooleanThreeTupleNode(Node, MantisNode):
         self.outputs.new('BooleanThreeTupleSocket', "")
         self.initialized = True
 
-class InputRotationOrderNode(Node, MantisNode):
+class InputRotationOrderNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputRotationOrderNode'
     bl_label = "Rotation Order"
@@ -135,7 +135,7 @@ class InputRotationOrderNode(Node, MantisNode):
         self.outputs.new('RotationOrderSocket', "").input = True
         self.initialized = True
 
-class InputTransformSpaceNode(Node, MantisNode):
+class InputTransformSpaceNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputTransformSpaceNode'
     bl_label = "Transform Space"
@@ -146,7 +146,7 @@ class InputTransformSpaceNode(Node, MantisNode):
         self.outputs.new('TransformSpaceSocket', "").input = True
         self.initialized = True
 
-class InputStringNode(Node, MantisNode):
+class InputStringNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputStringNode'
     bl_label = "String"
@@ -157,7 +157,7 @@ class InputStringNode(Node, MantisNode):
         self.outputs.new('StringSocket', "").input = True
         self.initialized = True
 
-class InputQuaternionNode(Node, MantisNode):
+class InputQuaternionNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputQuaternionNode'
     bl_label = "Quaternion"
@@ -168,7 +168,7 @@ class InputQuaternionNode(Node, MantisNode):
         self.outputs.new('QuaternionSocket', "").input = True
         self.initialized = True
 
-class InputQuaternionNodeAA(Node, MantisNode):
+class InputQuaternionNodeAA(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputQuaternionNodeAA'
     bl_label = "Axis Angle"
@@ -180,7 +180,7 @@ class InputQuaternionNodeAA(Node, MantisNode):
         self.initialized = True
 
 
-class InputMatrixNode(Node, MantisNode):
+class InputMatrixNode(Node, MantisUINode):
     '''A node representing inheritance'''
     bl_idname = 'InputMatrixNode'
     bl_label = "Matrix"
@@ -212,7 +212,7 @@ class InputMatrixNode(Node, MantisNode):
         mat_sock = self.outputs[0]
         mat_sock.default_value = self.set_matrix()
 
-class ScaleBoneLengthNode(Node, MantisNode):
+class ScaleBoneLengthNode(Node, MantisUINode):
     '''Scale Bone Length'''
     bl_idname = 'ScaleBoneLength'
     bl_label = "Scale Bone Length"
@@ -228,7 +228,7 @@ class ScaleBoneLengthNode(Node, MantisNode):
 
 
 
-class MetaRigMatrixNode(Node, MantisNode):
+class MetaRigMatrixNode(Node, MantisUINode):
     # Identical to the above, except
     '''A node representing a bone's matrix'''
     bl_idname = 'MetaRigMatrixNode'
@@ -264,7 +264,7 @@ class MetaRigMatrixNode(Node, MantisNode):
         mat_sock.default_value = self.set_matrix()
 
 
-class UtilityMatrixFromCurve(Node, MantisNode):
+class UtilityMatrixFromCurve(Node, MantisUINode):
     """Gets a matrix from a curve."""
     bl_idname = "UtilityMatrixFromCurve"
     bl_label = "Matrix from Curve"
@@ -281,7 +281,7 @@ class UtilityMatrixFromCurve(Node, MantisNode):
         self.initialized = True
 
 
-class UtilityPointFromCurve(Node, MantisNode):
+class UtilityPointFromCurve(Node, MantisUINode):
     """Gets a point from a curve."""
     bl_idname = "UtilityPointFromCurve"
     bl_label = "Point from Curve"
@@ -296,7 +296,7 @@ class UtilityPointFromCurve(Node, MantisNode):
         self.outputs.new("VectorSocket", "Point")
         self.initialized = True
 
-class UtilityMatricesFromCurve(Node, MantisNode):
+class UtilityMatricesFromCurve(Node, MantisUINode):
     """Gets a matrix from a curve."""
     bl_idname = "UtilityMatricesFromCurve"
     bl_label = "Matrices from Curve"
@@ -312,7 +312,7 @@ class UtilityMatricesFromCurve(Node, MantisNode):
         o.display_shape = 'SQUARE_DOT'
         self.initialized = True
 
-class UtilityMetaRigNode(Node, MantisNode):
+class UtilityMetaRigNode(Node, MantisUINode):
     """Gets a matrix from a meta-rig bone."""
     bl_idname = "UtilityMetaRig"
     bl_label = "Meta-Rig"
@@ -346,7 +346,7 @@ class UtilityMetaRigNode(Node, MantisNode):
         if self.inputs["Meta-Bone"].is_linked:
             self.inputs["Meta-Bone"].search_prop = None
 
-class UtilityBonePropertiesNode(Node, MantisNode):
+class UtilityBonePropertiesNode(Node, MantisUINode):
     """Provides as sockets strings identifying bone transform properties."""
     bl_idname = "UtilityBoneProperties"
     bl_label = "Bone Properties"
@@ -369,7 +369,7 @@ class UtilityBonePropertiesNode(Node, MantisNode):
         for o in self.outputs:
             o.text_only = True
 
-class UtilityDriverVariableNode(Node, MantisNode):
+class UtilityDriverVariableNode(Node, MantisUINode):
     """Creates a variable for use in a driver."""
     bl_idname = "UtilityDriverVariable"
     bl_label = "Driver Variable"
@@ -432,7 +432,7 @@ class UtilityDriverVariableNode(Node, MantisNode):
 # 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
 # keeping track of the RAM address of the window.
-class UtilityFCurveNode(Node, MantisNode):
+class UtilityFCurveNode(Node, MantisUINode):
     """Creates an fCurve for use with a driver."""
     bl_idname = "UtilityFCurve"
     bl_label = "fCurve"
@@ -452,7 +452,7 @@ class UtilityFCurveNode(Node, MantisNode):
             layout.operator( 'mantis.fcurve_node_remove_kf' )
 
 
-class UtilityDriverNode(Node, MantisNode):
+class UtilityDriverNode(Node, MantisUINode):
     """Represents a Driver relationship"""
     bl_idname = "UtilityDriver"
     bl_label = "Driver"
@@ -484,7 +484,7 @@ class UtilityDriverNode(Node, MantisNode):
         if (len(self.inputs) > 3):
             layout.operator( 'mantis.driver_node_remove_variable' )
 
-class UtilitySwitchNode(Node, MantisNode):
+class UtilitySwitchNode(Node, MantisUINode):
     """Represents a switch relationship between one driver property and one or more driven properties."""
     bl_idname = "UtilitySwitch"
     bl_label = "Switch"
@@ -499,7 +499,7 @@ class UtilitySwitchNode(Node, MantisNode):
         self.outputs.new("DriverSocket", "Driver")
         self.initialized = True
 
-class UtilityCombineThreeBoolNode(Node, MantisNode):
+class UtilityCombineThreeBoolNode(Node, MantisUINode):
     """Combines three booleans into a three-bool."""
     bl_idname = "UtilityCombineThreeBool"
     bl_label = "CombineThreeBool"
@@ -513,7 +513,7 @@ class UtilityCombineThreeBoolNode(Node, MantisNode):
         self.outputs.new("BooleanThreeTupleSocket", "Three-Bool")
         self.initialized = True
 
-class UtilityCombineVectorNode(Node, MantisNode):
+class UtilityCombineVectorNode(Node, MantisUINode):
     """Combines three floats into a vector."""
     bl_idname = "UtilityCombineVector"
     bl_label = "CombineVector"
@@ -527,7 +527,7 @@ class UtilityCombineVectorNode(Node, MantisNode):
         self.outputs.new("VectorSocket", "Vector")
         self.initialized = True
         
-class UtilitySeparateVector(Node, MantisNode):
+class UtilitySeparateVector(Node, MantisUINode):
     """Separates a vector into three floats"""
     bl_idname = "UtilitySeparateVector"
     bl_label = "Separate Vector"
@@ -541,7 +541,7 @@ class UtilitySeparateVector(Node, MantisNode):
         self.outputs.new("FloatSocket", "Z")
         self.initialized = True
         
-class UtilityCatStringsNode(Node, MantisNode):
+class UtilityCatStringsNode(Node, MantisUINode):
     """Adds a suffix to a string"""
     bl_idname = "UtilityCatStrings"
     bl_label = "Concatenate Strings"
@@ -578,7 +578,7 @@ class UtilityCatStringsNode(Node, MantisNode):
                     return # the tree isn't ready yet.
                 
     
-class InputLayerMaskNode(Node, MantisNode):
+class InputLayerMaskNode(Node, MantisUINode):
     """Represents a layer mask for a bone."""
     bl_idname = "InputLayerMaskNode"
     bl_label = "Layer Mask"
@@ -589,7 +589,7 @@ class InputLayerMaskNode(Node, MantisNode):
         self.outputs.new("LayerMaskInputSocket", "Layer Mask")
         self.initialized = True
 
-class InputExistingGeometryObjectNode(Node, MantisNode):
+class InputExistingGeometryObjectNode(Node, MantisUINode):
     """Represents an existing geometry object from within the scene."""
     bl_idname = "InputExistingGeometryObject"
     bl_label = "Existing Object"
@@ -611,7 +611,7 @@ class InputExistingGeometryObjectNode(Node, MantisNode):
     
 # 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
-class InputExistingGeometryDataNode(Node, MantisNode):
+class InputExistingGeometryDataNode(Node, MantisUINode):
     """Represents a mesh or curve datablock from the scene."""
     bl_idname = "InputExistingGeometryData"
     bl_label = "Existing Geometry"
@@ -623,7 +623,7 @@ class InputExistingGeometryDataNode(Node, MantisNode):
         self.outputs.new("GeometrySocket", "Geometry")
         self.initialized = True
 
-class UtilityGeometryOfXForm(Node, MantisNode):
+class UtilityGeometryOfXForm(Node, MantisUINode):
     """Retrieves a mesh or curve datablock from an xForm."""
     bl_idname = "UtilityGeometryOfXForm"
     bl_label = "Geometry of xForm"
@@ -636,7 +636,7 @@ class UtilityGeometryOfXForm(Node, MantisNode):
         self.initialized = True
 
 
-class UtilityNameOfXForm(Node, MantisNode):
+class UtilityNameOfXForm(Node, MantisUINode):
     """Retrieves the name of a xForm."""
     bl_idname = "UtilityNameOfXForm"
     bl_label = "Name of xForm"
@@ -648,7 +648,7 @@ class UtilityNameOfXForm(Node, MantisNode):
         self.outputs.new("StringSocket", "Name")
         self.initialized = True
 
-class UtilityGetBoneLength(Node, MantisNode):
+class UtilityGetBoneLength(Node, MantisUINode):
     """Returns the length of the bone from its matrix."""
     bl_idname = "UtilityGetBoneLength"
     bl_label = "Get Bone Length"
@@ -661,7 +661,7 @@ class UtilityGetBoneLength(Node, MantisNode):
         self.initialized = True
 
 # TODO: make it work with BBones!
-class UtilityPointFromBoneMatrix(Node, MantisNode):
+class UtilityPointFromBoneMatrix(Node, MantisUINode):
     """Returns a point representing the location along a bone, given a matrix representing that bone's shape."""
     bl_idname = "UtilityPointFromBoneMatrix"
     bl_label = "Point from Bone Matrix"
@@ -673,7 +673,7 @@ class UtilityPointFromBoneMatrix(Node, MantisNode):
         self.inputs.new("FloatFactorSocket", "Head/Tail")
         self.outputs.new("VectorSocket", "Point")
         self.initialized = True
-class UtilitySetBoneLength(Node, MantisNode):
+class UtilitySetBoneLength(Node, MantisUINode):
     """Sets the length of a bone matrix."""
     bl_idname = "UtilitySetBoneLength"
     bl_label = "Set Bone Matrix Length"
@@ -688,7 +688,7 @@ class UtilitySetBoneLength(Node, MantisNode):
 
 # 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.
-class UtilityKeyframe(Node, MantisNode):
+class UtilityKeyframe(Node, MantisUINode):
     """A keyframe for a FCurve"""
     bl_idname = "UtilityKeyframe"
     bl_label = "KeyFrame"
@@ -728,7 +728,7 @@ class UtilityKeyframe(Node, MantisNode):
         self.initialized = True
 
 
-class UtilityBoneMatrixHeadTailFlip(Node, MantisNode):
+class UtilityBoneMatrixHeadTailFlip(Node, MantisUINode):
     """Flips a bone matrix so that the head is where the tail was and visa versa."""
     bl_idname = "UtilityBoneMatrixHeadTailFlip"
     bl_label = "Flip Head/Tail"
@@ -740,7 +740,7 @@ class UtilityBoneMatrixHeadTailFlip(Node, MantisNode):
         self.outputs.new("MatrixSocket", "Bone Matrix")
         self.initialized = True
 
-class UtilityMatrixTransform(Node, MantisNode):
+class UtilityMatrixTransform(Node, MantisUINode):
     """Transforms a matrix by another."""
     bl_idname = "UtilityMatrixTransform"
     bl_label = "Matrix Transform"
@@ -753,7 +753,7 @@ class UtilityMatrixTransform(Node, MantisNode):
         self.outputs.new("MatrixSocket", "Out Matrix")
         self.initialized = True
 
-class UtilityMatrixSetLocation(Node, MantisNode):
+class UtilityMatrixSetLocation(Node, MantisUINode):
     """Sets a matrix's location."""
     bl_idname = "UtilityMatrixSetLocation"
     bl_label = "Set Matrix Location"
@@ -766,7 +766,7 @@ class UtilityMatrixSetLocation(Node, MantisNode):
         self.outputs.new("MatrixSocket", "Matrix")
         self.initialized = True
 
-class UtilityMatrixGetLocation(Node, MantisNode):
+class UtilityMatrixGetLocation(Node, MantisUINode):
     """Gets a matrix's location."""
     bl_idname = "UtilityMatrixGetLocation"
     bl_label = "Get Matrix Location"
@@ -778,7 +778,7 @@ class UtilityMatrixGetLocation(Node, MantisNode):
         self.outputs.new("VectorSocket", "Location")
         self.initialized = True
 
-class UtilityTransformationMatrix(Node, MantisNode):
+class UtilityTransformationMatrix(Node, MantisUINode):
     """Constructs a matrix representing a transformation"""
     bl_idname = "UtilityTransformationMatrix"
     bl_label = "Transformation Matrix"
@@ -822,7 +822,7 @@ class UtilityTransformationMatrix(Node, MantisNode):
 # 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.
 
-class UtilitySetBoneMatrixTail(Node, MantisNode):
+class UtilitySetBoneMatrixTail(Node, MantisUINode):
     """Constructs a matrix representing a transformation"""
     bl_idname = "UtilitySetBoneMatrixTail"
     bl_label = "Set Bone Matrix Tail"
@@ -836,7 +836,7 @@ class UtilitySetBoneMatrixTail(Node, MantisNode):
         self.initialized = True
 
 
-class UtilityMatrixFromXForm(Node, MantisNode):
+class UtilityMatrixFromXForm(Node, MantisUINode):
     """Returns the matrix of the given xForm node."""
     bl_idname = "UtilityMatrixFromXForm"
     bl_label = "Matrix of xForm"
@@ -848,7 +848,7 @@ class UtilityMatrixFromXForm(Node, MantisNode):
         self.outputs.new("MatrixSocket", "Matrix")
         self.initialized = True
 
-class UtilityAxesFromMatrix(Node, MantisNode):
+class UtilityAxesFromMatrix(Node, MantisUINode):
     """Returns the axes of the matrix."""
     bl_idname = "UtilityAxesFromMatrix"
     bl_label = "Axes of Matrix"
@@ -862,7 +862,7 @@ class UtilityAxesFromMatrix(Node, MantisNode):
         self.outputs.new("VectorSocket", "Z Axis")
         self.initialized = True
 
-class UtilityIntToString(Node, MantisNode):
+class UtilityIntToString(Node, MantisUINode):
     """Converts a number to a string"""
     bl_idname = "UtilityIntToString"
     bl_label = "Number String"
@@ -877,7 +877,7 @@ class UtilityIntToString(Node, MantisNode):
         self.initialized = True
 
 
-class UtilityArrayGet(Node, MantisNode):
+class UtilityArrayGet(Node, MantisUINode):
     """Gets a value from an array at a specified index."""
     bl_idname = "UtilityArrayGet"
     bl_label  = "Array Get"
@@ -909,7 +909,7 @@ class UtilityArrayGet(Node, MantisNode):
                 self.outputs['Output'].color = from_socket.color
 
 
-class UtilityCompare(Node, MantisNode):
+class UtilityCompare(Node, MantisUINode):
     """Compares two inputs and produces a boolean output"""
     bl_idname = "UtilityCompare"
     bl_label = "Compare"
@@ -940,7 +940,7 @@ class UtilityCompare(Node, MantisNode):
             if hasattr(link.from_socket, "color"):
                 self.inputs['B'].color = link.from_socket.color
 
-class UtilityChoose(Node, MantisNode):
+class UtilityChoose(Node, MantisUINode):
     """Chooses an output"""
     bl_idname = "UtilityChoose"
     bl_label = "Choose"
@@ -988,7 +988,7 @@ class UtilityChoose(Node, MantisNode):
 
 
 
-class UtilityPrint(Node, MantisNode):
+class UtilityPrint(Node, MantisUINode):
     """A utility used to print arbitrary values."""
     bl_idname = "UtilityPrint"
     bl_label  = "Print"

+ 2 - 8
primitives_containers.py

@@ -1,5 +1,4 @@
 from .node_container_common import *
-from bpy.types import Node
 from .base_definitions import MantisNode
 
 def TellClasses():
@@ -14,8 +13,8 @@ def TellClasses():
 
 
 
-class CirclePrimitive:
-    '''A node representing float input'''
+class CirclePrimitive(MantisNode):
+    '''A node representing a Circle Primitive mesh'''
 
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -74,8 +73,3 @@ class CirclePrimitive:
         # done with this, push it to the data and free the bmesh.
         bm.to_mesh(data); bm.free()
         self.executed = True
-
-
-
-for c in TellClasses():
-    setup_container(c)

+ 2 - 2
primitives_definitions.py

@@ -1,6 +1,6 @@
 import bpy
 from bpy.types import NodeTree, Node, NodeSocket
-from .base_definitions import MantisNode
+from .base_definitions import MantisUINode
 
 def TellClasses():
     return [
@@ -11,7 +11,7 @@ def default_traverse(self,socket):
     return None
 
 
-class GeometryCirclePrimitive(Node, MantisNode):
+class GeometryCirclePrimitive(Node, MantisUINode):
     '''A node representing a circle primitive'''
     bl_idname = 'GeometryCirclePrimitive'
     bl_label = "Circle Primitive"

+ 2 - 2
readtree.py

@@ -142,7 +142,7 @@ def make_connections_to_ng_dummy(base_tree, tree_path_names, local_nc, all_nc, n
 
 def gen_node_containers(base_tree, current_tree, tree_path_names, all_nc, local_nc, dummy_nodes, group_nodes, schema_nodes ):
     from .internal_containers import DummyNode
-    from .base_definitions import SchemaNode
+    from .base_definitions import SchemaUINode
     for np in current_tree.nodes:
         # TODO: find out why I had to add this in. these should be taken care of already? BUG
         if np.bl_idname in ["NodeFrame", "NodeReroute"]:
@@ -150,7 +150,7 @@ def gen_node_containers(base_tree, current_tree, tree_path_names, all_nc, local_
         if (nc_cls := class_for_mantis_prototype_node(np)):
             sig = (None, *tree_path_names, np.name)
             # but I will probably choose to handle this elsewhere
-            # if isinstance(np, SchemaNode):
+            # if isinstance(np, SchemaUINode):
             #     continue # we won't do this one here.
             if np.bl_idname in replace_types:
                 # prPurple(np.bl_idname)

+ 10 - 12
schema_containers.py

@@ -1,5 +1,6 @@
 from .node_container_common import *
 from math import pi, tau
+from .base_definitions import MantisNode
 
 def TellClasses():
     return [
@@ -34,7 +35,7 @@ def init_parameters(nc, is_input = True, in_out='INPUT', category=''):
 
 
 
-class SchemaIndex:
+class SchemaIndex(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -57,7 +58,7 @@ class SchemaIndex:
 
 
 
-class SchemaArrayInput:
+class SchemaArrayInput(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -74,7 +75,7 @@ class SchemaArrayInput:
         self.executed = True
 
 
-class SchemaArrayInputGet:
+class SchemaArrayInputGet(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -98,7 +99,7 @@ class SchemaArrayInputGet:
         self.executed = True
 
 
-class SchemaArrayOutput:
+class SchemaArrayOutput(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -117,7 +118,7 @@ class SchemaArrayOutput:
 
         
 
-class SchemaConstInput:
+class SchemaConstInput(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -137,7 +138,7 @@ class SchemaConstInput:
 
 
 
-class SchemaConstOutput:
+class SchemaConstOutput(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -155,7 +156,7 @@ class SchemaConstOutput:
 
 
         
-class SchemaOutgoingConnection:
+class SchemaOutgoingConnection(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -173,7 +174,7 @@ class SchemaOutgoingConnection:
 
 
         
-class SchemaIncomingConnection:
+class SchemaIncomingConnection(MantisNode):
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
         self.signature = signature
@@ -187,7 +188,4 @@ class SchemaIncomingConnection:
         self.hierarchy_dependencies = []
         self.dependencies = []
         self.prepared = True
-        self.executed = True
-
-for c in TellClasses():
-    setup_container(c)
+        self.executed = True

+ 9 - 9
schema_definitions.py

@@ -1,5 +1,5 @@
 import bpy
-from .base_definitions import SchemaNode
+from .base_definitions import SchemaUINode
 from bpy.types import Node
 from .utilities import (prRed, prGreen, prPurple, prWhite,
                               prOrange,
@@ -28,7 +28,7 @@ def TellClasses():
 # - check what happens when these get plugged into each other
 # - probably disallow all or most of these connections in insert_link or update
 
-class SchemaIndex(Node, SchemaNode):
+class SchemaIndex(Node, SchemaUINode):
     '''The current index of the schema execution'''
     bl_idname = 'SchemaIndex'
     bl_label = "Index"
@@ -41,7 +41,7 @@ class SchemaIndex(Node, SchemaNode):
         self.initialized = True
 
 
-class SchemaArrayInput(Node, SchemaNode):
+class SchemaArrayInput(Node, SchemaUINode):
     '''Array Inputs'''
     bl_idname = 'SchemaArrayInput'
     bl_label = "Array Input"
@@ -65,7 +65,7 @@ class SchemaArrayInput(Node, SchemaNode):
             self.outputs.new('WildcardSocket', '', identifier='__extend__')
         # self.initialized = True
 
-class SchemaArrayInputGet(Node, SchemaNode):
+class SchemaArrayInputGet(Node, SchemaUINode):
     '''Array Inputs'''
     bl_idname = 'SchemaArrayInputGet'
     bl_label = "Array Input at Index"
@@ -91,7 +91,7 @@ class SchemaArrayInputGet(Node, SchemaNode):
             self.outputs.new('WildcardSocket', '', identifier='__extend__')
         # self.initialized = True
 
-class SchemaArrayOutput(Node, SchemaNode):
+class SchemaArrayOutput(Node, SchemaUINode):
     '''Array Inputs'''
     bl_idname = 'SchemaArrayOutput'
     bl_label = "Array Output"
@@ -117,7 +117,7 @@ class SchemaArrayOutput(Node, SchemaNode):
             s.input= True
         self.initialized = True
 
-class SchemaConstInput(Node, SchemaNode):
+class SchemaConstInput(Node, SchemaUINode):
     '''Constant Inputs'''
     bl_idname = 'SchemaConstInput'
     bl_label = "Constant Input"
@@ -143,7 +143,7 @@ class SchemaConstInput(Node, SchemaNode):
 
 
 
-class SchemaConstOutput(Node, SchemaNode):
+class SchemaConstOutput(Node, SchemaUINode):
     '''Constant Outputs'''
     bl_idname = 'SchemaConstOutput'
     bl_label = "Constant Output"
@@ -174,7 +174,7 @@ class SchemaConstOutput(Node, SchemaNode):
 
 
 
-class SchemaOutgoingConnection(Node, SchemaNode):
+class SchemaOutgoingConnection(Node, SchemaUINode):
     '''Outgoing Connections'''
     bl_idname = 'SchemaOutgoingConnection'
     bl_label = "Outgoing Connection"
@@ -204,7 +204,7 @@ class SchemaOutgoingConnection(Node, SchemaNode):
 
 
 
-class SchemaIncomingConnection(Node, SchemaNode):
+class SchemaIncomingConnection(Node, SchemaUINode):
     '''Incoming Connections'''
     bl_idname = 'SchemaIncomingConnection'
     bl_label = "Incoming Connection"

+ 6 - 6
schema_solve.py

@@ -4,8 +4,8 @@ from .utilities import (prRed, prGreen, prPurple, prWhite,
                               wrapOrange,)
 from .utilities import init_connections, init_dependencies
 from .utilities import class_for_mantis_prototype_node
-from .base_definitions import SchemaNode, replace_types, custom_props_types
-from .node_container_common import fill_parameters, setup_custom_props_from_np
+from .base_definitions import SchemaUINode, replace_types, custom_props_types
+from .node_container_common import setup_custom_props_from_np
 # a class that solves Schema nodes
 from uuid import uuid4
 
@@ -145,7 +145,7 @@ class SchemaSolver:
         # prGreen(self.tree_path_names)
 
         for n in self.tree.nodes:
-            if isinstance(n, SchemaNode):
+            if isinstance(n, SchemaUINode):
                 # first we need to fill the parameters of the schema nodes.
                 # the node is actually in the Schema group so we include the schema_dummy name
                 # and we use the bl_idname because I think all schema nodes should be single-instance
@@ -158,7 +158,7 @@ class SchemaSolver:
                 self.schema_nodes[signature] = nc
                 # nc.signature = signature # I don't really intend for this value to be mutable... but... HACK
                 # there is no need to mutate this. also I may need to reuse it later
-                fill_parameters(nc, n)
+                nc.fill_parameters(n)
                 # print (nc)
         
     
@@ -296,7 +296,7 @@ class SchemaSolver:
         frame_nc = {}
         # At this point, GENERATE all the nodes for the frame
         for n in self.tree.nodes:
-            if isinstance(n, SchemaNode) or isinstance(n, NodeFrame):
+            if isinstance(n, SchemaUINode) or isinstance(n, NodeFrame):
                 continue
             if n.bl_idname in ['NodeReroute']:
                 continue
@@ -330,7 +330,7 @@ class SchemaSolver:
             #
             if nc.__class__.__name__ in custom_props_types:
                 setup_custom_props_from_np(nc, n)
-            fill_parameters(nc, n) # this is the best place to do this..
+            nc.fill_parameters(n) # this is the best place to do this..
 
 
         # This is where we handle node connections BETWEEN frames

+ 7 - 14
xForm_containers.py

@@ -1,5 +1,4 @@
 from .node_container_common import *
-from bpy.types import Node
 from .base_definitions import MantisNode
 
 def TellClasses():
@@ -22,7 +21,7 @@ def reset_object_data(ob):
     ob.animation_data_clear() # this is a little dangerous. TODO find a better solution since this can wipe animation the user wants to keep
     ob.modifiers.clear() # I would also like a way to copy modifiers and their settings, or bake them down. oh well
 
-class xFormArmature:
+class xFormArmature(MantisNode):
     '''A node representing an armature object'''
     
     bObject = None
@@ -217,7 +216,7 @@ bone_inputs= [
          "Lock Rotation",
          "Lock Scale",
 ]
-class xFormBone:
+class xFormBone(MantisNode):
     '''A node representing a bone in an armature'''
     # DO: make a way to identify which armature this belongs to
     def __init__(self, signature, base_tree):
@@ -399,7 +398,7 @@ class xFormBone:
         eb.inherit_scale = parent_nc.evaluate_input("Inherit Scale")
         # otherwise, no need to do anything.
         
-         
+    
     def bExecute(self, bContext = None,): #possibly will need to pass context?
         import bpy
         from mathutils import Vector
@@ -735,10 +734,11 @@ class xFormBone:
     def fill_parameters(self):
         # this is the fill_parameters that is run if it isn't a schema
         setup_custom_props(self)
-        fill_parameters(self)
+        super().fill_parameters()
         # otherwise we will do this from the schema 
+        # LEGIBILITY TODO - why? explain this?
 
-class xFormGeometryObject:
+class xFormGeometryObject(MantisNode):
     '''A node representing an armature object'''
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -863,7 +863,7 @@ class xFormGeometryObject:
         return self.bObject
 
 
-class xFormObjectInstance:
+class xFormObjectInstance(MantisNode):
     """Represents an instance of an existing geometry object."""
     def __init__(self, signature, base_tree):
         self.base_tree=base_tree
@@ -987,10 +987,3 @@ class xFormObjectInstance:
         
     def bGetObject(self, mode = 'POSE'):
         return self.bObject
-
-
-
-
-
-for c in TellClasses():
-    setup_container(c)