Browse Source

Fix: DriverVariable fails when linked to non-xForm

I forgot to check if the socket it was connected to was actually
a custom property. really really bad blunder this one

seriously this one is inexcusable. Absolutely critical fail.
Brandenburg 2 weeks ago
parent
commit
1a642ea8bb
1 changed files with 70 additions and 68 deletions
  1. 70 68
      misc_nodes.py

+ 70 - 68
misc_nodes.py

@@ -211,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"]
@@ -220,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 = [""]
@@ -238,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 = [""]
@@ -252,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 = [""]
@@ -285,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",]
@@ -294,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
@@ -319,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
@@ -397,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)
 
@@ -431,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)
 
@@ -494,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")
@@ -518,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)
@@ -535,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)
@@ -596,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)
 
@@ -605,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")
@@ -630,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")
@@ -764,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
@@ -788,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
@@ -814,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'''
@@ -838,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]:
@@ -897,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
@@ -907,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'''
 
@@ -958,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
@@ -984,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'''
@@ -1001,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)
@@ -1009,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
@@ -1043,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
@@ -1065,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)
@@ -1087,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
@@ -1098,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,
@@ -1118,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
@@ -1153,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:
@@ -1195,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)
@@ -1204,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'''
 
@@ -1245,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
@@ -1257,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
@@ -1332,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'''
@@ -1352,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
@@ -1366,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
 
@@ -1412,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
@@ -1422,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:
@@ -1439,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 = []
@@ -1607,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"):
@@ -1636,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"):
@@ -1661,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"):
@@ -1682,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)
@@ -1719,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"):
@@ -1859,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)