|  | @@ -145,22 +145,16 @@ def array_choose_relink(node, indices, array_input, output, ):
 | 
	
		
			
				|  |  |      """
 | 
	
		
			
				|  |  |          Used to choose the correct link to send out of an array-choose node.
 | 
	
		
			
				|  |  |      """
 | 
	
		
			
				|  |  | -    prGreen(node)
 | 
	
		
			
				|  |  | -    for l in node.inputs[array_input].links:
 | 
	
		
			
				|  |  | -        print(l)
 | 
	
		
			
				|  |  |      keep_links = []
 | 
	
		
			
				|  |  |      for index in indices:
 | 
	
		
			
				|  |  | -        prOrange(index)
 | 
	
		
			
				|  |  |          l = node.inputs[array_input].links[index]
 | 
	
		
			
				|  |  |          keep_links.append(l)
 | 
	
		
			
				|  |  |      for link in node.outputs[output].links:
 | 
	
		
			
				|  |  | -        prOrange(link)
 | 
	
		
			
				|  |  |          to_node = link.to_node
 | 
	
		
			
				|  |  |          for l in keep_links:
 | 
	
		
			
				|  |  |              new_link = l.from_node.outputs[l.from_socket].connect(to_node, link.to_socket)
 | 
	
		
			
				|  |  |              array_link_init_hierarchy(new_link)
 | 
	
		
			
				|  |  |              node.rerouted.append(new_link) # so I can access this in Schema Solve
 | 
	
		
			
				|  |  | -            prPurple(new_link)
 | 
	
		
			
				|  |  |          link.die()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -217,7 +211,7 @@ class SimpleInputNode(MantisNode):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class InputFloat(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing float input'''
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  |          outputs = ["Float Input"]
 | 
	
	
		
			
				|  | @@ -226,16 +220,16 @@ class InputFloat(SimpleInputNode):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class InputIntNode(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing integer input'''
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  |          outputs = ["Integer"]
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class InputVector(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing vector input'''
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  |          outputs = [""]
 | 
	
	
		
			
				|  | @@ -244,7 +238,7 @@ class InputVector(SimpleInputNode):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class InputBoolean(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing boolean input'''
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  |          outputs = [""]
 | 
	
	
		
			
				|  | @@ -258,31 +252,31 @@ class InputBooleanThreeTuple(SimpleInputNode):
 | 
	
		
			
				|  |  |          outputs = [""]
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class InputRotationOrder(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing string input for rotation order'''
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  |          outputs = [""]
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class InputTransformSpace(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing string input for transform space'''
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  |          outputs = [""]
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def evaluate_input(self, input_name):
 | 
	
		
			
				|  |  |          return self.parameters[""]
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class InputString(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing string input'''
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  |          outputs = [""]
 | 
	
	
		
			
				|  | @@ -291,7 +285,7 @@ class InputString(SimpleInputNode):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class InputMatrix(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing axis-angle quaternion input'''
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  |          outputs  = ["Matrix",]
 | 
	
	
		
			
				|  | @@ -300,7 +294,7 @@ class InputMatrix(SimpleInputNode):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class InputThemeBoneColorSets(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing the theme's colors'''
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  |          from .base_definitions import MantisSocketTemplate
 | 
	
	
		
			
				|  | @@ -325,7 +319,7 @@ class InputColorSetPallete(SimpleInputNode):
 | 
	
		
			
				|  |  |      '''A node representing the theme's colors'''
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def fill_parameters(self, ui_node=None):
 | 
	
		
			
				|  |  |          if not ui_node:
 | 
	
		
			
				|  |  |              from .utilities import get_node_prototype
 | 
	
	
		
			
				|  | @@ -403,7 +397,7 @@ class UtilityMatrixFromCurve(MantisNode):
 | 
	
		
			
				|  |  |          self.parameters["Matrix"] = mat
 | 
	
		
			
				|  |  |          self.prepared = True
 | 
	
		
			
				|  |  |          self.executed = True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bFinalize(self, bContext=None):
 | 
	
		
			
				|  |  |          cleanup_curve(self.evaluate_input("Curve"), self.base_tree.execution_id)
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -437,7 +431,7 @@ class UtilityPointFromCurve(MantisNode):
 | 
	
		
			
				|  |  |              p = data[spline_index][0][0] - curve.location
 | 
	
		
			
				|  |  |          self.parameters["Point"] = p
 | 
	
		
			
				|  |  |          self.prepared, self.executed = True, True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bFinalize(self, bContext=None):
 | 
	
		
			
				|  |  |          cleanup_curve(self.evaluate_input("Curve"), self.base_tree.execution_id)
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -500,7 +494,7 @@ class UtilityMatricesFromCurve(MantisNode):
 | 
	
		
			
				|  |  |          self.prepared = True
 | 
	
		
			
				|  |  |          self.executed = True
 | 
	
		
			
				|  |  |          # prGreen(f"Matrices from curves took {time.time() - start_time} seconds.")
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bFinalize(self, bContext=None):
 | 
	
		
			
				|  |  |          import bpy
 | 
	
		
			
				|  |  |          curve_name = self.evaluate_input("Curve")
 | 
	
	
		
			
				|  | @@ -524,7 +518,7 @@ class UtilityNumberOfCurveSegments(MantisNode):
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          curve_name = self.evaluate_input("Curve")
 | 
	
		
			
				|  |  |          curve = bpy_object_get_guarded( curve_name, self)
 | 
	
	
		
			
				|  | @@ -541,7 +535,7 @@ class UtilityNumberOfSplines(MantisNode):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree, NumberOfSplinesSockets)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          curve_name = self.evaluate_input("Curve")
 | 
	
		
			
				|  |  |          curve = bpy_object_get_guarded( curve_name, self)
 | 
	
	
		
			
				|  | @@ -602,7 +596,7 @@ class UtilityMatrixFromCurveSegment(MantisNode):
 | 
	
		
			
				|  |  |              m.translation = head - curve.location
 | 
	
		
			
				|  |  |              self.parameters["Matrix"] = m
 | 
	
		
			
				|  |  |          self.prepared, self.executed = True, True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bFinalize(self, bContext=None):
 | 
	
		
			
				|  |  |          cleanup_curve(self.evaluate_input("Curve"), self.base_tree.execution_id)
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -611,7 +605,7 @@ class UtilityGetCurvePoint(MantisNode):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree, GetCurvePointSockets)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext=None):
 | 
	
		
			
				|  |  |          import bpy
 | 
	
		
			
				|  |  |          curve_name = self.evaluate_input("Curve")
 | 
	
	
		
			
				|  | @@ -636,7 +630,7 @@ class UtilityGetNearestFactorOnCurve(MantisNode):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree, GetNearestFactorOnCurveSockets)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          import bpy
 | 
	
		
			
				|  |  |          curve_name = self.evaluate_input("Curve")
 | 
	
	
		
			
				|  | @@ -770,14 +764,14 @@ class UtilityMetaRig(MantisNode):
 | 
	
		
			
				|  |  |          import bpy
 | 
	
		
			
				|  |  |          from mathutils import Matrix
 | 
	
		
			
				|  |  |          m = Matrix.Identity(4)
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          meta_rig  = self.evaluate_input("Meta-Armature")
 | 
	
		
			
				|  |  |          if meta_rig is None:
 | 
	
		
			
				|  |  |              raise RuntimeError("Invalid input for Meta-Armature.")
 | 
	
		
			
				|  |  |          meta_bone = self.evaluate_input("Meta-Bone")
 | 
	
		
			
				|  |  |          if meta_rig is None or meta_bone is None:
 | 
	
		
			
				|  |  |              raise RuntimeError("Invalid input for Meta-Bone.")
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          if meta_rig:
 | 
	
		
			
				|  |  |              if ( armOb := bpy.data.objects.get(meta_rig) ):
 | 
	
		
			
				|  |  |                  m = armOb.matrix_world
 | 
	
	
		
			
				|  | @@ -794,7 +788,7 @@ class UtilityMetaRig(MantisNode):
 | 
	
		
			
				|  |  |                  #     prRed("no bone for MetaRig node ", self)
 | 
	
		
			
				|  |  |          else:
 | 
	
		
			
				|  |  |              raise RuntimeError(wrapRed(f"No meta-rig input for MetaRig node {self}"))
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          self.parameters["Matrix"] = m
 | 
	
		
			
				|  |  |          self.prepared = True
 | 
	
		
			
				|  |  |          self.executed = True
 | 
	
	
		
			
				|  | @@ -820,7 +814,7 @@ class UtilityBoneProperties(SimpleInputNode):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def fill_parameters(self, prototype=None):
 | 
	
		
			
				|  |  |          return
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  # TODO this should probably be moved to Links
 | 
	
		
			
				|  |  |  class UtilityDriverVariable(MantisNode):
 | 
	
		
			
				|  |  |      '''A node representing an armature object'''
 | 
	
	
		
			
				|  | @@ -844,23 +838,24 @@ class UtilityDriverVariable(MantisNode):
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "DRIVER" # MUST be run in Pose mode
 | 
	
		
			
				|  |  |          self.prepared = True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def reset_execution(self):
 | 
	
		
			
				|  |  |          super().reset_execution()
 | 
	
		
			
				|  |  |          # clear this to ensure there are no stale reference pointers
 | 
	
		
			
				|  |  |          self.parameters["Driver Variable"] = None
 | 
	
		
			
				|  |  |          self.prepared=True
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def evaluate_input(self, input_name):
 | 
	
		
			
				|  |  |          if input_name == 'Property':
 | 
	
		
			
				|  |  |              if self.inputs.get('Property'):
 | 
	
		
			
				|  |  |                  if self.inputs['Property'].is_linked:
 | 
	
		
			
				|  |  | -                # get the name instead...
 | 
	
		
			
				|  |  |                      trace = trace_single_line(self, input_name)
 | 
	
		
			
				|  |  | -                    return trace[1].name # the name of the socket
 | 
	
		
			
				|  |  | +                    # CANNOT UNDERSTATE HOW CRITICAL THIS CHECK IS
 | 
	
		
			
				|  |  | +                    if trace[0][-1].node_type == 'XFORM':
 | 
	
		
			
				|  |  | +                        return trace[1].name # the name of the socket
 | 
	
		
			
				|  |  |              return self.parameters["Property"]
 | 
	
		
			
				|  |  |          return super().evaluate_input(input_name)
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def GetxForm(self, index=1):
 | 
	
		
			
				|  |  |          trace = trace_single_line(self, "xForm 1" if index == 1 else "xForm 2")
 | 
	
		
			
				|  |  |          for node in trace[0]:
 | 
	
	
		
			
				|  | @@ -903,7 +898,7 @@ class UtilityDriverVariable(MantisNode):
 | 
	
		
			
				|  |  |              if self.evaluate_input("Property") == 'scale_average':
 | 
	
		
			
				|  |  |                  dVarChannel = "SCALE_AVG"
 | 
	
		
			
				|  |  |          if dVarChannel: v_type = "TRANSFORMS"
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          my_var = {
 | 
	
		
			
				|  |  |              "owner"         : xForm1, # will be filled in by Driver
 | 
	
		
			
				|  |  |              "prop"          : self.evaluate_input("Property"), # will be filled in by Driver
 | 
	
	
		
			
				|  | @@ -913,10 +908,11 @@ class UtilityDriverVariable(MantisNode):
 | 
	
		
			
				|  |  |              "xForm 1"       : xForm1,#self.GetxForm(index = 1),
 | 
	
		
			
				|  |  |              "xForm 2"       : xForm2,#self.GetxForm(index = 2),
 | 
	
		
			
				|  |  |              "channel"       : dVarChannel,}
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          self.parameters["Driver Variable"] = my_var
 | 
	
		
			
				|  |  | +        print (my_var['prop'])
 | 
	
		
			
				|  |  |          self.executed = True
 | 
	
		
			
				|  |  | -            
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class UtilityKeyframe(MantisNode):
 | 
	
		
			
				|  |  |      '''A node representing a keyframe for a F-Curve'''
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -964,7 +960,7 @@ class UtilityFCurve(MantisNode):
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  |          setup_custom_props(self)
 | 
	
		
			
				|  |  |          self.prepared = True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def reset_execution(self):
 | 
	
		
			
				|  |  |          super().reset_execution()
 | 
	
		
			
				|  |  |          self.prepared=True
 | 
	
	
		
			
				|  | @@ -990,7 +986,7 @@ class UtilityFCurve(MantisNode):
 | 
	
		
			
				|  |  |          keys.append(extrap_mode)
 | 
	
		
			
				|  |  |          self.parameters["fCurve"] = keys
 | 
	
		
			
				|  |  |          self.executed = True
 | 
	
		
			
				|  |  | -#TODO make the fCurve data a data class instead of a dict 
 | 
	
		
			
				|  |  | +#TODO make the fCurve data a data class instead of a dict
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class UtilityDriver(MantisNode):
 | 
	
		
			
				|  |  |      '''A node representing an armature object'''
 | 
	
	
		
			
				|  | @@ -1007,7 +1003,7 @@ class UtilityDriver(MantisNode):
 | 
	
		
			
				|  |  |          ]
 | 
	
		
			
				|  |  |          from .drivers import MantisDriver
 | 
	
		
			
				|  |  |          additional_parameters = {
 | 
	
		
			
				|  |  | -          "Driver":MantisDriver(), 
 | 
	
		
			
				|  |  | +          "Driver":MantisDriver(),
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          self.inputs.init_sockets(inputs)
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
	
		
			
				|  | @@ -1015,13 +1011,13 @@ class UtilityDriver(MantisNode):
 | 
	
		
			
				|  |  |          self.node_type = "DRIVER" # MUST be run in Pose mode
 | 
	
		
			
				|  |  |          setup_custom_props(self)
 | 
	
		
			
				|  |  |          self.prepared = True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def reset_execution(self):
 | 
	
		
			
				|  |  |          super().reset_execution()
 | 
	
		
			
				|  |  |          from .drivers import MantisDriver
 | 
	
		
			
				|  |  |          self.parameters["Driver"]=MantisDriver()
 | 
	
		
			
				|  |  |          self.prepared=True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bRelationshipPass(self, bContext = None,):
 | 
	
		
			
				|  |  |          prepare_parameters(self)
 | 
	
		
			
				|  |  |          from .drivers import MantisDriver
 | 
	
	
		
			
				|  | @@ -1049,9 +1045,9 @@ class UtilityDriver(MantisNode):
 | 
	
		
			
				|  |  |                       "vars"          :  my_vars,
 | 
	
		
			
				|  |  |                       "keys"          :  keys[:-1],
 | 
	
		
			
				|  |  |                       "extrapolation" :  keys[-1] }
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          my_driver = MantisDriver(my_driver)
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          self.parameters["Driver"].update(my_driver)
 | 
	
		
			
				|  |  |          print("Initializing driver %s " % (wrapPurple(self.__repr__())) )
 | 
	
		
			
				|  |  |          self.executed = True
 | 
	
	
		
			
				|  | @@ -1071,7 +1067,7 @@ class UtilitySwitch(MantisNode):
 | 
	
		
			
				|  |  |          ]
 | 
	
		
			
				|  |  |          from .drivers import MantisDriver
 | 
	
		
			
				|  |  |          additional_parameters = {
 | 
	
		
			
				|  |  | -          "Driver":MantisDriver(), 
 | 
	
		
			
				|  |  | +          "Driver":MantisDriver(),
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          self.inputs.init_sockets(inputs)
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
	
		
			
				|  | @@ -1093,7 +1089,7 @@ class UtilitySwitch(MantisNode):
 | 
	
		
			
				|  |  |              if (node.__class__ in [xFormArmature, xFormBone]):
 | 
	
		
			
				|  |  |                  return node #this will fetch the first one, that's good!
 | 
	
		
			
				|  |  |          return None
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def reset_execution(self):
 | 
	
		
			
				|  |  |          super().reset_execution()
 | 
	
		
			
				|  |  |          from .drivers import MantisDriver
 | 
	
	
		
			
				|  | @@ -1104,12 +1100,12 @@ class UtilitySwitch(MantisNode):
 | 
	
		
			
				|  |  |          #prepare_parameters(self)
 | 
	
		
			
				|  |  |          #prPurple ("Executing Switch Node")
 | 
	
		
			
				|  |  |          xForm = self.GetxForm()
 | 
	
		
			
				|  |  | -        if xForm : xForm = xForm.bGetObject() 
 | 
	
		
			
				|  |  | +        if xForm : xForm = xForm.bGetObject()
 | 
	
		
			
				|  |  |          if not xForm:
 | 
	
		
			
				|  |  |              raise RuntimeError("Could not evaluate xForm for %s" % self)
 | 
	
		
			
				|  |  |          from .drivers import MantisDriver
 | 
	
		
			
				|  |  |          my_driver ={ "owner" : None,
 | 
	
		
			
				|  |  | -                     "prop"  : None, # will be filled out in the node that uses the driver 
 | 
	
		
			
				|  |  | +                     "prop"  : None, # will be filled out in the node that uses the driver
 | 
	
		
			
				|  |  |                       "ind"   : -1, # same here
 | 
	
		
			
				|  |  |                       "type"  : "SCRIPTED",
 | 
	
		
			
				|  |  |                       "vars"  : [ { "owner" : xForm,
 | 
	
	
		
			
				|  | @@ -1124,13 +1120,13 @@ class UtilitySwitch(MantisNode):
 | 
	
		
			
				|  |  |                                     "type":"KEYFRAME",},],
 | 
	
		
			
				|  |  |                        "extrapolation": 'CONSTANT', }
 | 
	
		
			
				|  |  |          my_driver   ["expression"] = "a"
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          my_driver = MantisDriver(my_driver)
 | 
	
		
			
				|  |  |      # this makes it so I can check for type later!
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          if self.evaluate_input("Invert Switch") == True:
 | 
	
		
			
				|  |  |              my_driver   ["expression"] = "1 - a"
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          # this way, regardless of what order things are handled, the
 | 
	
		
			
				|  |  |          #  driver is sent to the next node.
 | 
	
		
			
				|  |  |          # In the case of some drivers, the parameter may be sent out
 | 
	
	
		
			
				|  | @@ -1159,7 +1155,7 @@ class UtilityCombineThreeBool(MantisNode):
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def reset_execution(self): # need to make sure any references are deleted
 | 
	
		
			
				|  |  |          super().reset_execution() # so we prepare the node again to reset them
 | 
	
		
			
				|  |  |          if self.parameters["Three-Bool"] is not None:
 | 
	
	
		
			
				|  | @@ -1201,7 +1197,7 @@ class UtilityCombineVector(MantisNode):
 | 
	
		
			
				|  |  |              for param in self.parameters["Vector"]:
 | 
	
		
			
				|  |  |                  if isinstance(param, dict):
 | 
	
		
			
				|  |  |                      self.prepared=False; break
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          #prPurple("Executing CombineVector Node")
 | 
	
		
			
				|  |  |          prepare_parameters(self)
 | 
	
	
		
			
				|  | @@ -1210,7 +1206,7 @@ class UtilityCombineVector(MantisNode):
 | 
	
		
			
				|  |  |            self.evaluate_input("Y"),
 | 
	
		
			
				|  |  |            self.evaluate_input("Z"), )
 | 
	
		
			
				|  |  |          self.prepared, self.executed = True, True
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class UtilitySeparateVector(MantisNode):
 | 
	
		
			
				|  |  |      '''A node for separating a vector into three floats'''
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1251,7 +1247,7 @@ class UtilityCatStrings(MantisNode):
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          self.parameters["OutputString"] = self.evaluate_input("String_1")+self.evaluate_input("String_2")
 | 
	
		
			
				|  |  |          self.prepared, self.executed = True, True
 | 
	
	
		
			
				|  | @@ -1263,7 +1259,7 @@ class InputWidget(MantisNode):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree, InputWidgetSockets)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "XFORM"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def reset_execution(self):
 | 
	
		
			
				|  |  |          super().reset_execution()
 | 
	
		
			
				|  |  |          self.prepared=False
 | 
	
	
		
			
				|  | @@ -1338,10 +1334,10 @@ class InputWidget(MantisNode):
 | 
	
		
			
				|  |  |              flip_modifier["Socket_3"]=axes_flipped[1]
 | 
	
		
			
				|  |  |              flip_modifier["Socket_4"]=axes_flipped[2]
 | 
	
		
			
				|  |  |          self.prepared, self.executed = True, True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bGetObject(self, mode=''):
 | 
	
		
			
				|  |  |          return self.bObject
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  # TODO move this to the Xform file
 | 
	
		
			
				|  |  |  class InputExistingGeometryObject(MantisNode):
 | 
	
		
			
				|  |  |      '''A node representing an existing object'''
 | 
	
	
		
			
				|  | @@ -1358,7 +1354,7 @@ class InputExistingGeometryObject(MantisNode):
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "XFORM"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def reset_execution(self):
 | 
	
		
			
				|  |  |          super().reset_execution()
 | 
	
		
			
				|  |  |          self.prepared=False
 | 
	
	
		
			
				|  | @@ -1372,7 +1368,7 @@ class InputExistingGeometryObject(MantisNode):
 | 
	
		
			
				|  |  |              prRed(f"No object found with name {name} in {self}")
 | 
	
		
			
				|  |  |          self.bObject=ob
 | 
	
		
			
				|  |  |          self.prepared, self.executed = True, True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bGetObject(self, mode=''):
 | 
	
		
			
				|  |  |          return self.bObject
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1418,7 +1414,7 @@ class UtilityDeclareCollections(MantisNode):
 | 
	
		
			
				|  |  |      def reset_execution(self):
 | 
	
		
			
				|  |  |          super().reset_execution()
 | 
	
		
			
				|  |  |          self.prepared, self.executed = True, True
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def fill_parameters(self, ui_node=None):
 | 
	
		
			
				|  |  |          if ui_node is None:
 | 
	
		
			
				|  |  |              from .utilities import get_node_prototype
 | 
	
	
		
			
				|  | @@ -1428,7 +1424,7 @@ class UtilityDeclareCollections(MantisNode):
 | 
	
		
			
				|  |  |          for out in ui_node.outputs:
 | 
	
		
			
				|  |  |              if not (out.name in self.outputs.keys()) :
 | 
	
		
			
				|  |  |                  templates.append(SockTemplate(name=out.name,
 | 
	
		
			
				|  |  | -                        identifier=out.identifier, is_input=False,))    
 | 
	
		
			
				|  |  | +                        identifier=out.identifier, is_input=False,))
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(templates)
 | 
	
		
			
				|  |  |          # now we have our parameters, fill them. This is a little inefficient I guess.
 | 
	
		
			
				|  |  |          for out in ui_node.outputs:
 | 
	
	
		
			
				|  | @@ -1445,7 +1441,7 @@ class UtilityCollectionJoin(MantisNode):
 | 
	
		
			
				|  |  |      def reset_execution(self):
 | 
	
		
			
				|  |  |          super().reset_execution()
 | 
	
		
			
				|  |  |          self.prepared, self.executed = False, False
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          if self.inputs['Collections'].links:
 | 
	
		
			
				|  |  |              bCol_groups = []
 | 
	
	
		
			
				|  | @@ -1613,7 +1609,7 @@ class UtilitySetBoneLength(MantisNode):
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          from mathutils import Vector
 | 
	
		
			
				|  |  |          if matrix := self.evaluate_input("Bone Matrix"):
 | 
	
	
		
			
				|  | @@ -1642,7 +1638,7 @@ class UtilityMatrixSetLocation(MantisNode):
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          from mathutils import Vector
 | 
	
		
			
				|  |  |          if matrix := self.evaluate_input("Matrix"):
 | 
	
	
		
			
				|  | @@ -1667,7 +1663,7 @@ class UtilityMatrixGetLocation(MantisNode):
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          from mathutils import Vector
 | 
	
		
			
				|  |  |          if matrix := self.evaluate_input("Matrix"):
 | 
	
	
		
			
				|  | @@ -1688,14 +1684,14 @@ class UtilityMatrixFromXForm(MantisNode):
 | 
	
		
			
				|  |  |          self.inputs.init_sockets(inputs)
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def GetxForm(self):
 | 
	
		
			
				|  |  |          trace = trace_single_line(self, "xForm")
 | 
	
		
			
				|  |  |          for node in trace[0]:
 | 
	
		
			
				|  |  |              if (node.node_type == 'XFORM'):
 | 
	
		
			
				|  |  |                  return node
 | 
	
		
			
				|  |  |          raise GraphError("%s is not connected to an xForm" % self)
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          from mathutils import Vector, Matrix
 | 
	
		
			
				|  |  |          self.parameters["Matrix"] = Matrix.Identity(4)
 | 
	
	
		
			
				|  | @@ -1725,7 +1721,7 @@ class UtilityAxesFromMatrix(MantisNode):
 | 
	
		
			
				|  |  |          self.outputs.init_sockets(outputs)
 | 
	
		
			
				|  |  |          self.init_parameters()
 | 
	
		
			
				|  |  |          self.node_type = "UTILITY"
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  |          from mathutils import Vector
 | 
	
		
			
				|  |  |          if matrix := self.evaluate_input("Matrix"):
 | 
	
	
		
			
				|  | @@ -1865,7 +1861,7 @@ class UtilityMatrixAlignRoll(MantisNode):
 | 
	
		
			
				|  |  |          #  it directly from the Y axis, the normalized projection of the align
 | 
	
		
			
				|  |  |          #  axis, and their cross-product. That only nearly worked.
 | 
	
		
			
				|  |  |          # this calculation should not work better, but it does. Why?
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class UtilityTransformationMatrix(MantisNode):
 | 
	
		
			
				|  |  |      def __init__(self, signature, base_tree):
 | 
	
		
			
				|  |  |          super().__init__(signature, base_tree)
 | 
	
	
		
			
				|  | @@ -1939,13 +1935,14 @@ class UtilityArrayGet(MantisNode):
 | 
	
		
			
				|  |  |          self.rerouted=[]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def bPrepare(self, bContext = None,):
 | 
	
		
			
				|  |  | +        from .base_definitions import links_sort_key
 | 
	
		
			
				|  |  |          if len(self.rerouted)>0:
 | 
	
		
			
				|  |  |              self.prepared, self.executed = True, True
 | 
	
		
			
				|  |  |              return #Either it is already done or it doesn't matter.
 | 
	
		
			
				|  |  |          elif self.prepared == False:
 | 
	
		
			
				|  |  |              # sort the array entries
 | 
	
		
			
				|  |  |              for inp in self.inputs.values():
 | 
	
		
			
				|  |  | -                inp.links.sort(key=lambda a : -a.multi_input_sort_id)
 | 
	
		
			
				|  |  | +                inp.links.sort(key=links_sort_key)
 | 
	
		
			
				|  |  |              oob   = self.evaluate_input("OoB Behaviour")
 | 
	
		
			
				|  |  |              index = self.evaluate_input("Index")
 | 
	
		
			
				|  |  |  
 |