Răsfoiți Sursa

make everything use __slots__

should result in a performance boost. doesn't actually seem like it does tho
Joseph Brandenburg 2 săptămâni în urmă
părinte
comite
600d59cff3
11 a modificat fișierele cu 251 adăugiri și 84 ștergeri
  1. 34 4
      base_definitions.py
  2. 16 0
      deformer_nodes.py
  3. 5 74
      execution/readtree.py
  4. 82 0
      internal_nodes.py
  5. 22 0
      link_nodes.py
  6. 6 6
      mantis_dataclasses.py
  7. 3 0
      math_nodes.py
  8. 63 0
      misc_nodes.py
  9. 3 0
      primitives_nodes.py
  10. 10 0
      schema_nodes.py
  11. 7 0
      xForm_nodes.py

+ 34 - 4
base_definitions.py

@@ -733,6 +733,16 @@ class MantisNode:
         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.
     """
+    __slots__ = (
+        "base_tree", "signature", "ui_signature",
+        "inputs", "outputs",
+        "parameters", "drivers", "bObject",
+        "hierarchy_connections", "connections",
+        "hierarchy_dependencies", "dependencies",
+        "unmet_hierarchy_dependency_count",
+        "prepared", "executed", "execution_prepared",
+        "socket_templates", "mContext",
+        )
     node_type='UNINITIALIZED'
     def __init__(self, signature : tuple,
                  base_tree : bpy.types.NodeTree,
@@ -1049,6 +1059,10 @@ class MantisNode:
 
 # do I need this and the link class above?
 class DummyLink:
+    __slots__ = ("from_socket", "to_socket",
+                 "from_mantis_node", "to_mantis_node",
+                 "multi_input_sort_id",
+                 "original_from")
     #gonna use this for faking links to keep the interface consistent
     def __init__(self, from_socket, to_socket, from_mantis_node=None, to_mantis_node=None, original_from=None, multi_input_sort_id=0):
         self.from_socket = from_socket
@@ -1084,10 +1098,16 @@ def detect_hierarchy_link(from_node, from_socket, to_node, to_socket,):
     return True
 
 class NodeLink:
-    from_node = None
-    from_socket = None
-    to_node = None
-    to_socket = None
+    __slots__ = (
+        "from_node",
+        "from_socket",
+        "to_node",
+        "to_socket",
+        "multi_input_sort_id",
+        "sub_sort_id",
+        "is_hierarchy",
+        "is_alive",
+    )
 
     def __init__(self, from_node, from_socket, to_node, to_socket, multi_input_sort_id=0, sub_sort_id=0):
         if from_node.signature == to_node.signature:
@@ -1131,6 +1151,15 @@ class NodeLink:
             init_dependencies(to_node)
 
 class NodeSocket:
+    __slots__ = (
+        "can_traverse",
+        "traverse_target",
+        "node",
+        "name",
+        "is_input",
+        "links",
+        "is_linked",
+    )
     def __init__(self, is_input = False,
                  node = None, name = None,
                  traverse_target = None):
@@ -1184,6 +1213,7 @@ class NodeSocket:
         return self.node.__repr__() + "::" + self.name
 
 class MantisNodeSocketCollection(dict):
+    __slots__ = ("is_input", "node",)
     def __init__(self, node, is_input=False):
         self.is_input = is_input
         self.node = node

+ 16 - 0
deformer_nodes.py

@@ -36,6 +36,7 @@ def trace_xForm_back(mantis_node, socket):
 
 class MantisDeformerNode(MantisNode):
     node_type = 'LINK'
+    __slots__ = ()
     def __init__(self, signature : tuple,
                  base_tree : NodeTree,
                  socket_templates : list[MantisSocketTemplate]=[]):
@@ -79,6 +80,7 @@ def standard_modifier_bind(self, bContext=None, operator=None):
 
 class DeformerArmature(MantisDeformerNode):
     '''A node representing an armature deformer'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, DeformArmatureSockets)
@@ -282,6 +284,8 @@ class DeformerArmature(MantisDeformerNode):
 
 class DeformerHook(MantisDeformerNode):
     '''A node representing a hook deformer'''
+    __slots__ = ()
+    
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, HookSockets)
@@ -417,6 +421,8 @@ class DeformerHook(MantisDeformerNode):
 
 class DeformerMorphTarget(MantisDeformerNode):
     '''A node representing an armature deformer'''
+    __slots__ = ()
+    
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MorphTargetSockets)
         self.init_parameters(additional_parameters={"Name":None})
@@ -458,6 +464,8 @@ class DeformerMorphTarget(MantisDeformerNode):
 
 class DeformerMorphTargetDeform(MantisDeformerNode):
     '''A node representing an armature deformer'''
+    __slots__ = ()
+    
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
@@ -701,6 +709,8 @@ class DeformerMorphTargetDeform(MantisDeformerNode):
 
 class DeformerSurfaceDeform(MantisDeformerNode):
     '''A node representing an surface deform modifier'''
+    __slots__ = ()
+    
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, SurfaceDeformSockets)
@@ -738,6 +748,8 @@ class DeformerSurfaceDeform(MantisDeformerNode):
 
 class DeformerMeshDeform(MantisDeformerNode):
     '''A node representing a mesh deform modifier'''
+    __slots__ = ()
+    
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MeshDeformSockets)
@@ -774,6 +786,8 @@ class DeformerMeshDeform(MantisDeformerNode):
 
 class DeformerLatticeDeform(MantisDeformerNode):
     '''A node representing a lattice deform modifier'''
+    __slots__ = ()
+    
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LatticeDeformSockets)
@@ -806,6 +820,8 @@ class DeformerLatticeDeform(MantisDeformerNode):
 
 class DeformerSmoothCorrectiveDeform(MantisDeformerNode):
     '''A node representing a corrective smooth deform modifier'''
+    __slots__ = ()
+    
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, SmoothDeformSockets)

+ 5 - 74
execution/readtree.py

@@ -1,74 +1,6 @@
 from ..utilities.utilities import prRed, prGreen, prPurple, prWhite, prOrange, \
                         wrapRed, wrapGreen, wrapPurple, wrapWhite, wrapOrange
 
-
-# this function is kind of confusing and is very important,
-# so it bears a full explanation: its purpose is to connect
-# the links going into a group to the nodes in that group.
-# FIRST we connect all the incoming links into the Group Node to
-# a Group Interface node that does nothing but mark the entrance.
-# Then, we connect all the outgoing links back to the nodes
-# that had incoming links, so the nodes OUTSIDE the Node Group
-# are connected directly to BOTH the GroupInterface and the
-# nodes INSIDE the node group.
-# we give the GroupInterface nodes an obscenely high
-# multi_input_sort_id so that they are always last.
-# but since these links are going IN, they shouldn't cause any problems.
-# the sub_sort_id is set here in case there are UI links which represent
-# multiple Mantis links - the mantis links are sorted within the UI links
-# and the UI links are sorted as normal, so all the links are in the right
-# order.... probably. BUG here?
-# I want the Group Interface nodes to be part of the hierarchy...
-# but I want to cut the links. hmmm what to do? Fix it if it causes problems.
-# solution to hypothetical BUG could be to do traversal on the links
-# instead of the sockets.
-def grp_node_reroute_common(in_node, out_node, interface):
-    from ..base_definitions import links_sort_key
-    for in_node_input in in_node.inputs:
-        i = 0
-        if len(in_node_input.links)>1: # sort here to ensure correct sub_sort_id
-            in_node_input.links.sort(key=links_sort_key)
-        while (in_node_input.links):
-            in_link = in_node_input.links.pop()
-            from_node = in_link.from_node; from_socket = in_link.from_socket
-            link = from_node.outputs[from_socket].connect(
-                interface,in_node_input.name, sort_id = 2**16, sub_sort_id=i)
-            i += 1; in_link.die()
-    for out_node_output in out_node.outputs:
-        while (out_node_output.links):
-            out_link = out_node_output.links.pop()
-            to_node = out_link.to_node; to_socket = out_link.to_socket
-            for j, l in enumerate(interface.inputs[out_node_output.name].links):
-                # we are connecting the link from the ORIGINAL output to the FINAL input.
-                link = l.from_node.outputs[l.from_socket].connect(
-                    to_node, to_socket, sort_id = out_link.multi_input_sort_id)
-                link.sub_sort_id = j
-            out_link.die()
-
-def reroute_links_grp(group, all_nodes):
-    from ..internal_nodes import GroupInterface
-    interface = GroupInterface(
-        ( *group.signature, "InputInterface"),
-        group.base_tree, group.ui_node, 'INPUT',)
-    all_nodes[interface.signature] = interface
-    if group.inputs:
-        if group_input := all_nodes.get(( *group.signature, "NodeGroupInput")):
-            grp_node_reroute_common(group, group_input, interface)
-        else:
-            raise RuntimeError("internal error: failed to enter a node group ")
-
-def reroute_links_grpout(group_output, all_nodes):
-    if (group := all_nodes.get( ( *group_output.signature[:-1],) )):
-        from ..internal_nodes import GroupInterface
-        interface = GroupInterface(
-            ( *group.signature, "OutputInterface"),
-            group.base_tree, group.ui_node, 'OUTPUT',)
-        all_nodes[interface.signature] = interface
-        grp_node_reroute_common(group_output, group, interface)
-    else:
-        prOrange(f"WARN: unconnected outputs from a node group "
-                 "(maybe you are running the tree from inside a node group?)")
-
 # FIXME I don't think these signatures are unique.
 # TODO this is a really silly and bad and also really dumb way to do this
 def insert_lazy_parents(mantis_node):
@@ -158,16 +90,16 @@ def gen_mantis_nodes(base_tree, current_tree, tree_path_names, mContext, all_man
                 mantis_node = DummyNode( signature=sig , base_tree=base_tree, ui_node=ui_node, ui_signature=ui_sig )
                 local_mantis_nodes[sig] = mantis_node; all_mantis_nodes[sig] = mantis_node; dummy_nodes[sig] = mantis_node
                 if ui_node.bl_idname in ["NodeGroupOutput"]:
-                    mantis_node.reroute_links = reroute_links_grpout
+                    mantis_node.reroute_links_type = 'out'
         elif ui_node.bl_idname in  ["MantisNodeGroup", "MantisSchemaGroup"]:
             mantis_node = DummyNode( signature= (sig := (None, *tree_path_names, ui_node.name) ), base_tree=base_tree, ui_node=ui_node )
             local_mantis_nodes[sig] = mantis_node; all_mantis_nodes[sig] = mantis_node; dummy_nodes[sig] = mantis_node
             make_connections_to_ng_dummy(base_tree, tree_path_names, local_mantis_nodes, all_mantis_nodes, mantis_node)
+            group_nodes.append(mantis_node)
             if ui_node.bl_idname == "MantisNodeGroup":
-                group_nodes.append(mantis_node)
-                mantis_node.reroute_links = reroute_links_grp
+                mantis_node.reroute_links_type = 'group'
             else:
-                group_nodes.append(mantis_node)
+                mantis_node.reroute_links_type = 'schema'
                 schema_nodes[sig] = mantis_node
         # 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 (mantis_class := ui_node.mantis_class):
@@ -506,8 +438,7 @@ def parse_tree(base_tree, error_popups=False):
     # it's REALLY confusing when you run into this sort of problem. So it warrants four entire lines of comments!      
     dummy_nodes, all_mantis_nodes, all_schema =  data_from_tree(base_tree, tree_path = [None], mContext=mContext, dummy_nodes = {}, all_mantis_nodes = {}, all_schema={})
     for dummy in dummy_nodes.values():    # reroute the links in the group nodes
-        if (hasattr(dummy, "reroute_links")):
-            dummy.reroute_links(dummy, all_mantis_nodes)
+        dummy.reroute_links(all_mantis_nodes)
     prGreen(f"Pulling data from tree took {time.time() - data_start_time} seconds")
 
     start_time = time.time()

+ 82 - 0
internal_nodes.py

@@ -3,10 +3,79 @@ from bpy.types import Node
 from .base_definitions import MantisNode, MantisSocketTemplate
 from uuid import uuid4
 
+
+# this function is kind of confusing and is very important,
+# so it bears a full explanation: its purpose is to connect
+# the links going into a group to the nodes in that group.
+# FIRST we connect all the incoming links into the Group Node to
+# a Group Interface node that does nothing but mark the entrance.
+# Then, we connect all the outgoing links back to the nodes
+# that had incoming links, so the nodes OUTSIDE the Node Group
+# are connected directly to BOTH the GroupInterface and the
+# nodes INSIDE the node group.
+# we give the GroupInterface nodes an obscenely high
+# multi_input_sort_id so that they are always last.
+# but since these links are going IN, they shouldn't cause any problems.
+# the sub_sort_id is set here in case there are UI links which represent
+# multiple Mantis links - the mantis links are sorted within the UI links
+# and the UI links are sorted as normal, so all the links are in the right
+# order.... probably. BUG here?
+# I want the Group Interface nodes to be part of the hierarchy...
+# but I want to cut the links. hmmm what to do? Fix it if it causes problems.
+# solution to hypothetical BUG could be to do traversal on the links
+# instead of the sockets.
+# NOTE: using NodeSocket.links is slow, it should be cached
+def grp_node_reroute_common(in_node, out_node, interface):
+    from .base_definitions import links_sort_key
+    for in_node_input in in_node.inputs:
+        i = 0
+        if len(in_node_input.links)>1: # sort here to ensure correct sub_sort_id
+            in_node_input.links.sort(key=links_sort_key)
+        while (in_node_input.links):
+            in_link = in_node_input.links.pop()
+            from_node = in_link.from_node; from_socket = in_link.from_socket
+            link = from_node.outputs[from_socket].connect(
+                interface,in_node_input.name, sort_id = 2**16, sub_sort_id=i)
+            i += 1; in_link.die()
+    for out_node_output in out_node.outputs:
+        while (out_node_output.links):
+            out_link = out_node_output.links.pop()
+            to_node = out_link.to_node; to_socket = out_link.to_socket
+            for j, l in enumerate(interface.inputs[out_node_output.name].links):
+                # we are connecting the link from the ORIGINAL output to the FINAL input.
+                link = l.from_node.outputs[l.from_socket].connect(
+                    to_node, to_socket, sort_id = out_link.multi_input_sort_id)
+                link.sub_sort_id = j
+            out_link.die()
+
+def reroute_links_grp(group, all_nodes):
+    interface = GroupInterface(
+        ( *group.signature, "InputInterface"),
+        group.base_tree, group.ui_node, 'INPUT',)
+    all_nodes[interface.signature] = interface
+    if group.inputs:
+        if group_input := all_nodes.get(( *group.signature, "NodeGroupInput")):
+            grp_node_reroute_common(group, group_input, interface)
+        else:
+            raise RuntimeError("internal error: failed to enter a node group ")
+
+def reroute_links_grpout(group_output, all_nodes):
+    if (group := all_nodes.get( ( *group_output.signature[:-1],) )):
+        interface = GroupInterface(
+            ( *group.signature, "OutputInterface"),
+            group.base_tree, group.ui_node, 'OUTPUT',)
+        all_nodes[interface.signature] = interface
+        grp_node_reroute_common(group_output, group, interface)
+    else:
+        prOrange(f"WARN: unconnected outputs from a node group "
+                 "(maybe you are running the tree from inside a node group?)")
+
+
 # TODO: make node_type a class property like it is for everything else
 # I can't do this without making some changes to schema and anything that
 # checks for DUMMY SCHEMA
 class DummyNode(MantisNode):
+    __slots__ = ("node_type", "ui_node", "solver", "uuid", "reroute_links_type")
     def __init__(self, signature, base_tree, ui_node = None, ui_signature=None):
         super().__init__(signature, base_tree)
         self.ui_node = ui_node
@@ -14,6 +83,7 @@ class DummyNode(MantisNode):
         self.uuid = uuid4()
         self.solver = None
         self.node_type = 'DUMMY'
+        self.reroute_links_type='group' # group, out, schema
         if ui_node:
             if ui_node.bl_idname in ["MantisSchemaGroup"]:
                 self.node_type = 'DUMMY_SCHEMA'
@@ -35,7 +105,17 @@ class DummyNode(MantisNode):
         # this is ugly and I hate it.
         self.execution_prepared=True # in case it gets left behind in the tree as a dependency
 
+    def reroute_links(self, all_nodes):
+        match self.reroute_links_type:
+            case "group":
+                reroute_links_grp(self, all_nodes)
+            case "schema":
+                pass # gonna implement this later
+            case "out":
+                reroute_links_grpout(self, all_nodes)
+
 class NoOpNode(MantisNode):
+    __slots__ = ()
     node_type = 'UTILITY'
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
@@ -48,6 +128,7 @@ class NoOpNode(MantisNode):
     # this node is useful for me to insert in the tree and use for debugging especially connections.
 
 class AutoGenNode(MantisNode):
+    __slots__ = ()
     node_type = 'UTILITY'
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
@@ -63,6 +144,7 @@ class AutoGenNode(MantisNode):
 #   going in or out of the group and connecting back out the other side
 # this is also where caching and overlays live
 class GroupInterface(MantisNode):
+    __slots__ = ("in_out")
     node_type = 'INTERFACE'
     def __init__(self, signature, base_tree, ui_node, in_out):
         super().__init__(signature, base_tree)

+ 22 - 0
link_nodes.py

@@ -42,6 +42,7 @@ set_constraint_name = lambda mantis_node : mantis_node.evaluate_input("Name") if
 
 
 class MantisLinkNode(MantisNode):
+    __slots__ = ()
     node_type = 'LINK'
     def __init__(self, signature : tuple,
                  base_tree : NodeTree,
@@ -136,6 +137,7 @@ class MantisLinkNode(MantisNode):
 
 class LinkInherit(MantisLinkNode):
     '''A node representing inheritance'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkInheritSockets)
@@ -183,6 +185,7 @@ class LinkCopyLocation(MantisLinkNode):
 
 class LinkCopyRotation(MantisLinkNode):
     '''A node representing Copy Rotation'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkCopyRotationSockets)
@@ -217,6 +220,7 @@ class LinkCopyRotation(MantisLinkNode):
 
 class LinkCopyScale(MantisLinkNode):
     '''A node representing Copy Scale'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkCopyScaleSockets)
@@ -243,6 +247,7 @@ class LinkCopyScale(MantisLinkNode):
 
 class LinkCopyTransforms(MantisLinkNode):
     '''A node representing Copy Transfoms'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkCopyTransformsSockets)
@@ -268,6 +273,7 @@ class LinkCopyTransforms(MantisLinkNode):
 
 class LinkTransformation(MantisLinkNode):
     '''A node representing Copy Transfoms'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkTransformationSockets)
@@ -339,6 +345,7 @@ class LinkTransformation(MantisLinkNode):
         self.executed = True
 
 class LinkLimitLocation(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkLimitLocationScaleSockets)
         self.init_parameters(additional_parameters={ "Name":None })
@@ -360,6 +367,7 @@ class LinkLimitLocation(MantisLinkNode):
         self.executed = True
 
 class LinkLimitRotation(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkLimitRotationSockets)
         self.init_parameters(additional_parameters={ "Name":None })
@@ -382,6 +390,7 @@ class LinkLimitRotation(MantisLinkNode):
         self.executed = True
 
 class LinkLimitScale(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkLimitLocationScaleSockets)
         self.init_parameters(additional_parameters={ "Name":None })
@@ -404,6 +413,7 @@ class LinkLimitScale(MantisLinkNode):
         self.executed = True
 
 class LinkLimitDistance(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkLimitDistanceSockets)
         self.init_parameters(additional_parameters={ "Name":None })
@@ -428,6 +438,7 @@ class LinkLimitDistance(MantisLinkNode):
 # Tracking
 
 class LinkStretchTo(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkStretchToSockets)
         self.init_parameters(additional_parameters={ "Name":None })
@@ -453,6 +464,7 @@ class LinkStretchTo(MantisLinkNode):
         self.executed = True
 
 class LinkDampedTrack(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkDampedTrackSockets)
         self.init_parameters(additional_parameters={ "Name":None })
@@ -474,6 +486,7 @@ class LinkDampedTrack(MantisLinkNode):
         self.executed = True
 
 class LinkLockedTrack(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree,LinkLockedTrackSockets)
         self.init_parameters(additional_parameters={"Name":None })
@@ -495,6 +508,7 @@ class LinkLockedTrack(MantisLinkNode):
         self.executed = True
 
 class LinkTrackTo(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkTrackToSockets)
         self.init_parameters(additional_parameters={"Name":None })
@@ -516,6 +530,7 @@ class LinkTrackTo(MantisLinkNode):
         self.executed = True
 
 class LinkInheritConstraint(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkInheritConstraintSockets)
         self.init_parameters(additional_parameters={"Name":None })
@@ -539,6 +554,7 @@ class LinkInheritConstraint(MantisLinkNode):
             self.executed = True
 
 class LinkInverseKinematics(MantisLinkNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkInverseKinematicsSockets)
         self.init_parameters(additional_parameters={"Name":None })
@@ -739,6 +755,7 @@ def ik_report_error(pb, context, do_print=False):
 
 # This is kinda a weird design decision?
 class LinkDrivenParameter(MantisLinkNode):
+    __slots__ = ()
     '''A node representing an armature object'''
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkDrivenParameterSockets)
@@ -796,6 +813,7 @@ class LinkDrivenParameter(MantisLinkNode):
 
 class LinkArmature(MantisLinkNode):
     '''A node representing an armature object'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree,):
         super().__init__(signature, base_tree, LinkArmatureSockets)
@@ -848,6 +866,7 @@ class LinkArmature(MantisLinkNode):
 
 class LinkSplineIK(MantisLinkNode):
     '''A node representing an armature object'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LinkSplineIKSockets)
@@ -886,6 +905,7 @@ class LinkSplineIK(MantisLinkNode):
 
 class LinkFloor(MantisLinkNode):
     '''A node representing an armature object'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree,):
         super().__init__(signature, base_tree, LinkFloorSockets)
@@ -910,6 +930,7 @@ class LinkFloor(MantisLinkNode):
 
 class LinkShrinkWrap(MantisLinkNode):
     '''A node representing a shrinkwrap relationship.'''
+    __slots__ = ()
     def __init__(self, signature, base_tree,):
         super().__init__(signature, base_tree, LinkShrinkWrapSockets)
         self.init_parameters(additional_parameters={"Name":None })
@@ -934,6 +955,7 @@ class LinkShrinkWrap(MantisLinkNode):
 
 class LinkGeometryAttribute(MantisLinkNode):
     '''A node representing a geometry attribute relationship.'''
+    __slots__ = ()
     def __init__(self, signature, base_tree,):
         super().__init__(signature, base_tree, LinkGeometryAttributeSockets)
         self.init_parameters(additional_parameters={"Name":None })

+ 6 - 6
mantis_dataclasses.py

@@ -1,7 +1,7 @@
 from dataclasses import dataclass, field
 from typing import List, Any, Tuple, Optional
 
-@dataclass
+@dataclass(slots=True)
 class MantisSocketTemplate():
     name             : str = field(default="")
     bl_idname        : str = field(default="")
@@ -23,7 +23,7 @@ class MantisSocketTemplate():
     min_bpy_version  : Optional[tuple[int]] = field(default=None)
     max_bpy_version  : Optional[tuple[int]] = field(default=None)
 
-@dataclass
+@dataclass(slots=True)
 class xForm_info():
     object_type          :  str = field(default="")
     root_armature        :  str = field(default="")
@@ -33,7 +33,7 @@ class xForm_info():
     self_edit_name      :  str = field(default="")
 # should I add node signatures to this?
 
-@dataclass
+@dataclass(slots=True)
 class custom_prop_template():
     name      : str = field(default="")
     prop_type : str = field(default="")
@@ -48,7 +48,7 @@ class custom_prop_template():
     soft_max : float|int = field(default=1)
     description : str = field(default="")
 
-@dataclass
+@dataclass(slots=True)
 class MantisBoneTransform():
     matrix    : Any = field(default=[1,0,0,0,
                                      0,1,0,0,
@@ -59,7 +59,7 @@ class MantisBoneTransform():
     matrix_space  : str = field(default="OBJECT")
     length    : float = field(default=1.0),
 
-@dataclass
+@dataclass(slots=True)
 class MantisBBoneTransform():
     num_bbone_segmetns: int = field(default=1)
     # Offsets & Curve Handles
@@ -84,7 +84,7 @@ class MantisBBoneTransform():
     bbone_custom_handle_end: str = field(default=None)
 
 # used to apply values or drivers to blender properties in a generic way
-@dataclass
+@dataclass(slots=True)
 class MantisSocketFiller():
     socket_name: str = field(default="")
     property_name : str = field(default="")

+ 3 - 0
math_nodes.py

@@ -52,6 +52,7 @@ def math_operation(operation, a, b):
 #*#-------------------------------#++#-------------------------------#*#
 class MathStaticInt(MantisNode):
     '''A node representing an integer math operation'''
+    __slots__ = ()
     node_type = "UTILITY"
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, StaticIntSockets)
@@ -65,6 +66,7 @@ class MathStaticInt(MantisNode):
 
 class MathStaticFloat(MantisNode):
     '''A node representing a float math operation'''
+    __slots__ = ()
     node_type = "UTILITY"
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, StaticFloatSockets)
@@ -78,6 +80,7 @@ class MathStaticFloat(MantisNode):
 
 class MathStaticVector(MantisNode):
     '''A node representing a vector math operation'''
+    __slots__ = ()
     node_type = "UTILITY"
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, StaticVectorSockets)

+ 63 - 0
misc_nodes.py

@@ -201,9 +201,11 @@ def bpy_object_get_guarded(get_name, node=None):
 #*#-------------------------------#++#-------------------------------#*#
 
 class MantisMiscNode(MantisNode):
+    __slots__ = ()
     node_type='UTILITY'
 
 class SimpleInputNode(MantisMiscNode):
+    __slots__ = ()
     node_type = 'UTILITY'
     def __init__(self, signature, base_tree, socket_templates=[]):
         super().__init__(signature, base_tree, socket_templates)
@@ -215,6 +217,7 @@ class SimpleInputNode(MantisMiscNode):
 
 class InputFloat(SimpleInputNode):
     '''A node representing float input'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputFloatSockets)
@@ -222,6 +225,7 @@ class InputFloat(SimpleInputNode):
 
 class InputIntNode(SimpleInputNode):
     '''A node representing integer input'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputIntSockets)
@@ -229,6 +233,7 @@ class InputIntNode(SimpleInputNode):
 
 class InputVector(SimpleInputNode):
     '''A node representing vector input'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputVectorSockets)
@@ -236,6 +241,7 @@ class InputVector(SimpleInputNode):
 
 class InputBoolean(SimpleInputNode):
     '''A node representing boolean input'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputBooleanSockets)
@@ -243,12 +249,14 @@ class InputBoolean(SimpleInputNode):
 
 class InputBooleanThreeTuple(SimpleInputNode):
     '''A node representing a tuple of three booleans'''
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputBooleanThreeTupleSockets)
         self.init_parameters()
 
 class InputRotationOrder(SimpleInputNode):
     '''A node representing string input for rotation order'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputRotationOrderSockets)
@@ -256,6 +264,7 @@ class InputRotationOrder(SimpleInputNode):
 
 class InputTransformSpace(SimpleInputNode):
     '''A node representing string input for transform space'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputTransformSpaceSockets)
@@ -263,6 +272,7 @@ class InputTransformSpace(SimpleInputNode):
 
 class InputString(SimpleInputNode):
     '''A node representing string input'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputStringSockets)
@@ -270,6 +280,7 @@ class InputString(SimpleInputNode):
 
 class InputMatrix(SimpleInputNode):
     '''A node representing axis-angle quaternion input'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputMatrixSockets)
@@ -277,6 +288,7 @@ class InputMatrix(SimpleInputNode):
 
 class InputThemeBoneColorSets(SimpleInputNode):
     '''A node representing the theme's colors'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
@@ -300,6 +312,7 @@ class InputThemeBoneColorSets(SimpleInputNode):
 
 class InputColorSetPallete(SimpleInputNode):
     '''A node representing the theme's colors'''
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
 
@@ -319,6 +332,7 @@ class InputColorSetPallete(SimpleInputNode):
 
 
 class UtilityCustomProperty(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, UtilityCustomPropertySockets)
         self.init_parameters()
@@ -365,6 +379,7 @@ class UtilityCustomProperty(MantisMiscNode):
 
 class UtilityMatrixFromCurve(MantisMiscNode):
     '''Get a matrix from a curve'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatrixFromCurveSockets)
@@ -449,6 +464,7 @@ class UtilityMatrixFromCurve(MantisMiscNode):
 
 class UtilityPointFromCurve(MantisMiscNode):
     '''Get a point from a curve'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, PointFromCurveSockets)
@@ -482,6 +498,7 @@ class UtilityPointFromCurve(MantisMiscNode):
 
 class UtilityMatricesFromCurve(MantisMiscNode):
     '''Get matrices from a curve'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatricesFromCurveSockets)
@@ -549,6 +566,7 @@ class UtilityMatricesFromCurve(MantisMiscNode):
             bpy.data.meshes.remove(mesh)
 
 class UtilityNumberOfCurveSegments(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, NumberOfCurveSegmentsSockets)
         self.init_parameters()
@@ -565,6 +583,7 @@ class UtilityNumberOfCurveSegments(MantisMiscNode):
         self.executed = True
 
 class UtilityNumberOfSplines(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, NumberOfSplinesSockets)
         self.init_parameters()
@@ -576,6 +595,7 @@ class UtilityNumberOfSplines(MantisMiscNode):
         self.prepared, self.executed = True, True
 
 class UtilityMatrixFromCurveSegment(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatrixFromCurveSegmentSockets)
         self.init_parameters()
@@ -633,6 +653,7 @@ class UtilityMatrixFromCurveSegment(MantisMiscNode):
         cleanup_curve(self.evaluate_input("Curve"), self.base_tree.execution_id)
 
 class UtilityGetCurvePoint(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, GetCurvePointSockets)
         self.init_parameters()
@@ -657,6 +678,7 @@ class UtilityGetCurvePoint(MantisMiscNode):
         self.prepared, self.executed = True, True
 
 class UtilityGetNearestFactorOnCurve(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, GetNearestFactorOnCurveSockets)
         self.init_parameters()
@@ -685,6 +707,7 @@ class UtilityGetNearestFactorOnCurve(MantisMiscNode):
         self.prepared, self.executed = True, True
 
 class UtilityKDChoosePoint(MantisMiscNode):
+    __slots__ = ('rerouted')
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, KDChoosePointSockets)
         self.init_parameters()
@@ -710,6 +733,7 @@ class UtilityKDChoosePoint(MantisMiscNode):
         self.prepared, self.executed = True, True
 
 class UtilityKDChooseXForm(MantisMiscNode):
+    __slots__ = ('rerouted')
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, KDChooseXFormSockets)
         self.init_parameters()
@@ -747,6 +771,7 @@ class UtilityKDChooseXForm(MantisMiscNode):
 
 class UtilityMetaRig(MantisMiscNode):
     '''A node representing an armature object'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MetaRigSockets)
@@ -788,6 +813,7 @@ class UtilityMetaRig(MantisMiscNode):
 
 class UtilityBoneProperties(SimpleInputNode):
     '''A node representing a bone's gettable properties'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, BonePropertiesSockets)
@@ -799,6 +825,7 @@ class UtilityBoneProperties(SimpleInputNode):
 # TODO this should probably be moved to Links
 class UtilityDriverVariable(MantisMiscNode):
     '''A node representing an armature object'''
+    __slots__ = ()
     node_type = "DRIVER"
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, DriverVariableSockets)
@@ -882,6 +909,7 @@ class UtilityDriverVariable(MantisMiscNode):
 
 class UtilityKeyframe(MantisMiscNode):
     '''A node representing a keyframe for a F-Curve'''
+    __slots__ = ()
     # TODO: try UTILITY type and remove setup_custom_property stuff
     node_type = "DRIVER" # MUST be run in Pose mode
     def __init__(self, signature, base_tree):
@@ -903,6 +931,7 @@ class UtilityKeyframe(MantisMiscNode):
 
 class UtilityFCurve(MantisMiscNode):
     '''A node representing an armature object'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, FCurveSockets)
@@ -929,6 +958,7 @@ class UtilityFCurve(MantisMiscNode):
 
 class UtilityDriver(MantisMiscNode):
     '''A node representing an armature object'''
+    __slots__ = ()
     node_type = "DRIVER" # MUST be run in Pose mode
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, DriverSockets)
@@ -983,6 +1013,7 @@ class UtilityDriver(MantisMiscNode):
 
 class UtilitySwitch(MantisMiscNode):
     '''A node representing an armature object'''
+    __slots__ = ()
     node_type = "DRIVER" # MUST be run in Pose mode
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, SwitchSockets)
@@ -1059,6 +1090,7 @@ class UtilitySwitch(MantisMiscNode):
 
 class UtilityCombineThreeBool(MantisMiscNode):
     '''A node for combining three booleans into a boolean three-tuple'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, CombineThreeBoolSockets)
@@ -1082,6 +1114,7 @@ class UtilityCombineThreeBool(MantisMiscNode):
 # Note this is a copy of the above. This needs to be de-duplicated.
 class UtilityCombineVector(MantisMiscNode):
     '''A node for combining three floats into a vector'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, CombineVectorSockets)
@@ -1105,6 +1138,7 @@ class UtilityCombineVector(MantisMiscNode):
 
 class UtilitySeparateVector(MantisMiscNode):
     '''A node for separating a vector into three floats'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, SeparateVectorSockets)
@@ -1118,6 +1152,7 @@ class UtilitySeparateVector(MantisMiscNode):
 
 class UtilityCatStrings(MantisMiscNode):
     '''A node representing an armature object'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, CatStringsSockets)
@@ -1130,6 +1165,7 @@ class UtilityCatStrings(MantisMiscNode):
 # TODO move this to the Xform file
 class InputWidget(MantisMiscNode):
     '''A node representing an existing object'''
+    __slots__ = ()
     node_type = "XFORM"
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputWidgetSockets)
@@ -1217,6 +1253,7 @@ class InputWidget(MantisMiscNode):
 # TODO move this to the Xform file
 class InputExistingGeometryObject(MantisMiscNode):
     '''A node representing an existing object'''
+    __slots__ = ()
     node_type = "XFORM"
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputExistingGeometryObjectSockets)
@@ -1243,6 +1280,7 @@ class InputExistingGeometryObject(MantisMiscNode):
 
 class InputExistingGeometryData(MantisMiscNode):
     '''A node representing existing object data'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, InputExistingGeometrySockets)
@@ -1266,6 +1304,7 @@ class InputExistingGeometryData(MantisMiscNode):
 
 class UtilityDeclareCollections(MantisMiscNode):
     '''A node to help manage bone collections'''
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         # NOTE this one does not use socket template because it is special.
         # The user creates all the sockets for this one.
@@ -1292,6 +1331,7 @@ class UtilityDeclareCollections(MantisMiscNode):
 
 class UtilityCollectionJoin(MantisMiscNode):
     '''A node to help manage bone collections'''
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, CollectionJoinSockets)
         self.init_parameters()
@@ -1321,6 +1361,7 @@ class UtilityCollectionJoin(MantisMiscNode):
 
 class UtilityCollectionHierarchy(MantisMiscNode):
     '''A node to help manage bone collections'''
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, CollectionHierarchySockets)
         self.init_parameters()
@@ -1345,6 +1386,7 @@ class UtilityCollectionHierarchy(MantisMiscNode):
 
 class UtilityGeometryOfXForm(MantisMiscNode):
     '''A node representing existing object data'''
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, GeometryOfXFormSockets)
         self.init_parameters()
@@ -1370,6 +1412,7 @@ class UtilityGeometryOfXForm(MantisMiscNode):
 
 class UtilityNameOfXForm(MantisMiscNode):
     '''A node representing existing object data'''
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, NameOfXFormSockets)
         self.init_parameters()
@@ -1385,6 +1428,7 @@ class UtilityNameOfXForm(MantisMiscNode):
 
 class UtilityGetBoneLength(MantisMiscNode):
     '''A node to get the length of a bone matrix'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, GetBoneLengthSockets)
@@ -1400,6 +1444,7 @@ class UtilityGetBoneLength(MantisMiscNode):
 
 class UtilityPointFromBoneMatrix(MantisMiscNode):
     '''A node representing an armature object'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, PointFromBoneMatrixSockets)
@@ -1416,6 +1461,7 @@ class UtilityPointFromBoneMatrix(MantisMiscNode):
 
 class UtilitySetBoneLength(MantisMiscNode):
     '''Sets the length of a Bone's matrix'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, SetBoneLengthSockets)
@@ -1435,6 +1481,7 @@ class UtilitySetBoneLength(MantisMiscNode):
 
 class UtilityMatrixSetLocation(MantisMiscNode):
     '''Sets the location of a matrix'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatrixSetLocationSockets)
@@ -1452,6 +1499,7 @@ class UtilityMatrixSetLocation(MantisMiscNode):
 
 class UtilityMatrixGetLocation(MantisMiscNode):
     '''Gets the location of a matrix'''
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatrixGetLocationSockets)
         self.init_parameters()
@@ -1464,6 +1512,7 @@ class UtilityMatrixGetLocation(MantisMiscNode):
 
 class UtilityMatrixFromXForm(MantisMiscNode):
     """Returns the matrix of the given xForm node."""
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatrixFromXFormSockets)
         self.init_parameters()
@@ -1490,6 +1539,7 @@ class UtilityMatrixFromXForm(MantisMiscNode):
 
 class UtilityAxesFromMatrix(MantisMiscNode):
     """Returns the axes of the given matrix."""
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, AxesFromMatrixSockets)
         self.init_parameters()
@@ -1504,6 +1554,7 @@ class UtilityAxesFromMatrix(MantisMiscNode):
         self.prepared = True; self.executed = True
 
 class UtilityBoneMatrixHeadTailFlip(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, BoneMatrixHeadTailFlipSockets)
         self.init_parameters()
@@ -1524,6 +1575,7 @@ class UtilityBoneMatrixHeadTailFlip(MantisMiscNode):
         self.prepared, self.executed = True, True
 
 class UtilityMatrixTransform(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatrixTransformSockets)
         self.init_parameters()
@@ -1541,6 +1593,7 @@ class UtilityMatrixTransform(MantisMiscNode):
         self.prepared, self.executed = True, True
 
 class UtilityMatrixInvert(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatrixInvertSockets)
         self.init_parameters()
@@ -1561,6 +1614,7 @@ class UtilityMatrixInvert(MantisMiscNode):
         self.prepared, self.executed = True, True
 
 class UtilityMatrixCompose(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatrixComposeSockets)
         self.init_parameters()
@@ -1587,6 +1641,7 @@ class UtilityMatrixCompose(MantisMiscNode):
         self.prepared = True; self.executed = True
 
 class UtilityMatrixAlignRoll(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, MatrixAlignRollSockets)
         self.init_parameters()
@@ -1623,6 +1678,7 @@ class UtilityMatrixAlignRoll(MantisMiscNode):
         # this calculation should not work better, but it does. Why?
 
 class UtilityTransformationMatrix(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, TransformationMatrixSockets)
         self.init_parameters()
@@ -1644,6 +1700,7 @@ class UtilityTransformationMatrix(MantisMiscNode):
         self.prepared = True; self.executed = True
 
 class UtilityIntToString(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, IntToStringSockets)
         self.init_parameters()
@@ -1656,6 +1713,7 @@ class UtilityIntToString(MantisMiscNode):
         self.prepared = True; self.executed = True
 
 class UtilityArrayGet(MantisMiscNode):
+    __slots__ = ('rerouted')
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, ArrayGetSockets)
         self.init_parameters()
@@ -1683,6 +1741,7 @@ class UtilityArrayGet(MantisMiscNode):
         self.prepared, self.executed = True, True
 
 class UtilityArrayLength(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, UtilityArrayLengthSockets)
         self.init_parameters()
@@ -1692,6 +1751,7 @@ class UtilityArrayLength(MantisMiscNode):
         self.prepared, self.executed = True, True
 
 class UtilitySetBoneMatrixTail(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, SetBoneMatrixTailSockets)
         self.init_parameters()
@@ -1705,6 +1765,7 @@ class UtilitySetBoneMatrixTail(MantisMiscNode):
         self.prepared = True; self.executed = True
 
 class UtilityCompare(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, CompareSockets)
         self.init_parameters()
@@ -1737,6 +1798,7 @@ class UtilityCompare(MantisMiscNode):
         self.prepared = True; self.executed = True
 
 class UtilityChoose(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, ChooseSockets)
         self.init_parameters()
@@ -1767,6 +1829,7 @@ class UtilityChoose(MantisMiscNode):
         self.prepared = True; self.executed = True
 
 class UtilityPrint(MantisMiscNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, PrintSockets)
         self.init_parameters()

+ 3 - 0
primitives_nodes.py

@@ -13,6 +13,7 @@ def TellClasses():
 #*#-------------------------------#++#-------------------------------#*#
 
 class PrimitiveNode(MantisNode):
+    __slots__ = ()
     node_type = "UTILITY"
     
     def __init__(self, signature, base_tree, socket_templates=[]):
@@ -25,6 +26,7 @@ class PrimitiveNode(MantisNode):
 
 class CirclePrimitive(PrimitiveNode):
     '''A node representing a Circle Primitive mesh'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
@@ -76,6 +78,7 @@ class CirclePrimitive(PrimitiveNode):
 from .primitives_sockets import LatticeSockets
 class GeometryLattice(PrimitiveNode):
     '''A node representing a Circle Primitive mesh'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, LatticeSockets)

+ 10 - 0
schema_nodes.py

@@ -34,6 +34,7 @@ def schema_init_sockets(mantis_node, is_input = True, in_out='INPUT', category='
 
 
 class SchemaNode(MantisNode):
+    __slots__ = ()
     node_type = 'SCHEMA'
     def __init__(self, signature, base_tree, socket_templates=[]):
         super().__init__(signature, base_tree, socket_templates)
@@ -48,32 +49,38 @@ class SchemaNode(MantisNode):
 
 
 class SchemaIndex(SchemaNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, SchemaIndexSockets)
         self.init_parameters()
 
 class SchemaArrayInput(SchemaNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         schema_init_sockets(self, is_input=False, in_out='INPUT', category='Array')
 
 
 class SchemaArrayInputGet(SchemaNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, SchemaArrayInputGetSockets)
         schema_init_sockets(self, is_input=False, in_out='INPUT', category='Array')
 
 class SchemaArrayInputAll(SchemaNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         schema_init_sockets(self, is_input=False, in_out='INPUT', category='Array')
 
 class SchemaArrayOutput(SchemaNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         schema_init_sockets(self, is_input=True, in_out='OUTPUT', category='Array')
 
 class SchemaConstInput(SchemaNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree, parent_schema_node=None):
         super().__init__(signature, base_tree)
         if parent_schema_node:
@@ -92,6 +99,7 @@ class SchemaConstInput(SchemaNode):
 
 
 class SchemaConstOutput(SchemaNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree, parent_schema_node=None):
         super().__init__(signature, base_tree)
         inputs = [
@@ -116,12 +124,14 @@ class SchemaConstOutput(SchemaNode):
 
         
 class SchemaOutgoingConnection(SchemaNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         schema_init_sockets(self, is_input=True, in_out='INPUT', category='Connection')
 
         
 class SchemaIncomingConnection(SchemaNode):
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree)
         schema_init_sockets(self, is_input=False, in_out='OUTPUT', category='Connection')

+ 7 - 0
xForm_nodes.py

@@ -67,6 +67,7 @@ def set_object_parent(node):
         node_ob.parent_bone = parent_xForm_info.self_edit_name
 
 class xFormNode(MantisNode):
+    __slots__ = ()
     node_type = 'XFORM'
     def __init__(self, signature, base_tree, socket_templates=[]):
         super().__init__(signature, base_tree, socket_templates)
@@ -156,6 +157,7 @@ class xFormNode(MantisNode):
 # TODO this should use the socket templates / prop_sockets system!
 class xFormArmature(xFormNode):
     '''A node representing an armature object'''
+    __slots__ = ()
 
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, xFormArmatureSockets)
@@ -276,6 +278,7 @@ class xFormArmature(xFormNode):
 
 class xFormBone(xFormNode):
     '''A node representing a bone in an armature'''
+    __slots__ = ()
     # DO: make a way to identify which armature this belongs to
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, xFormBoneSockets)
@@ -524,6 +527,7 @@ class xFormBone(xFormNode):
 
 class xFormGeometryObject(xFormNode):
     '''A node representing an armature object'''
+    __slots__ = ("has_shape_keys")
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, xFormGeometryObjectSockets)
         self.init_parameters()
@@ -635,6 +639,7 @@ class xFormGeometryObject(xFormNode):
 
 class xFormObjectInstance(xFormNode):
     """Represents an instance of an existing geometry object."""
+    __slots__ = ("has_shape_keys")
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, xFormGeometryObjectInstanceSockets)
         self.init_parameters()
@@ -734,6 +739,7 @@ class xFormObjectInstance(xFormNode):
 
 class xFormCurvePin(xFormNode):
     """An xForm pinned to a specific location on a curve."""
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree,xFormCurvePinSockets)
         self.init_parameters(additional_parameters={"Matrix":None})
@@ -874,6 +880,7 @@ class xFormCurvePin(xFormNode):
 # now you get a special thank-you in Mantis instead!
 class xFormGetBone(xFormNode):
     """Represents an instance of an existing geometry object."""
+    __slots__ = ()
     def __init__(self, signature, base_tree):
         super().__init__(signature, base_tree, xFormGetBoneSockets)
         self.init_parameters()