| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125 | # generic node classes#everything here sucks and is dumb and needs renaiming# this is stupid, loldef TellClasses():             # xForm    return [ xFormRoot,             xFormArmature,             xFormBone,             # special             LinkInherit,             # copy             LinkCopyLocation,             LinkCopyRotation,             LinkCopyScale,             LinkCopyTransforms,             # limit             LinkLimitLocation,             LinkLimitRotation,             LinkLimitScale,             LinkLimitDistance,             # tracking             LinkStretchTo,             LinkDampedTrack,             LinkLockedTrack,             LinkTrackTo,             #misc             LinkInheritConstraint,             # IK             LinkInverseKinematics,             # utility             InputFloat,             InputVector,             InputBoolean,             InputBooleanThreeTuple,             InputRotationOrder,             InputTransformSpace,             InputString,             InputQuaternion,             InputQuaternionAA,             InputMatrix,            ]    #kinda a dumb way to do this but it werks so whatever                        # have these so far  # simple nodes:             # InputFloatNode,             # InputVectorNode,             # InputBooleanNode,             # InputBooleanThreeTupleNode,             # InputRotationOrderNode,             # InputTransformSpaceNode,             # InputStringNode,             # InputQuaternionNode,             # InputQuaternionNodeAA,             # InputMatrixNode,  # xForm nodes:        # xFormNullNode,        # xFormBoneNode,        # xFormRootNode,        # xFormArmatureNode,          # Link nodes:             # LinkInheritNode,             # LinkInverseKinematics,             # LinkCopyLocationNode,             # LinkCopyRotationNode,             # LinkCopyScaleNode,             # LinkInheritConstraintNode,             # LinkCopyTransformNode,             # LinkStretchToNode,             # LinkDampedTrackNode,             # LinkLockedTrackNode,             # LinkTrackToNode,             # LinkLimitLocationNode,             # LinkLimitScaleNode,             # LinkLimitRotationNode,             # LinkLimitDistanceNode,]                          #eventually add this:    # def print_to_mantis_script():        # #gonna eventually make this into a script        # # that can be written and read from a text file        # # and loaded into the interpretor        # pass# # DO THIS:#  each node should have a name or UUID, since there must be a way to#   associate them with the lines that are read from the input-graph#  actually I cna and should just use the signature, since it can gimme#   any prototype node I need, and it encodes relationships, too.def fill_parameters(node_container, node_prototype):    from .utilities import to_mathutils_value    for key, value in node_container.parameters.items():        node_socket = node_prototype.inputs.get(key)        if not node_socket:            #maybe the node socket has no name            if ( ( len(node_prototype.inputs) == 0) and ( len(node_prototype.outputs) == 1) ):                # this is a simple input node.                node_socket = node_prototype.outputs[0]            elif key == 'Mute':                node_container.parameters[key] = node_prototype.mute                continue            else: # really don't know!                raise RuntimeError("No node socket found for " + key + " when filling out node parameters.")                continue                if node_socket.bl_idname in  ['RelationshipSocket', 'xFormSocket']:            continue                elif hasattr(node_socket, "default_value"):            default_value_type = type(node_socket.default_value)            #print (default_value_type)            math_val = to_mathutils_value(node_socket)            if math_val:                node_container.parameters[key] = math_val            # maybe we can use it directly.. ?            elif ( (default_value_type == str) or (default_value_type == bool) or                 (default_value_type == float) or (default_value_type == int) ):                node_container.parameters[key] = node_socket.default_value            # HACK: there should be no sets, I think, but...            elif default_value_type == set:                node_container.parameters[key] = node_socket.default_value                # TODO: make this make sense sometime in the future!                # There should not be any sets!            else:                raise RuntimeError("No value found for " + key + " when filling out node parameters for " + node_prototype.name)        else:                print (key, node_socket)                # do: remove these from parameters maybe                # since they are always None if not connected    # for key, value in node_container.parameters.items():        # if value:            # print (key, value)def evaluate_input(node_container, input_name):    # for simple cases    trace = trace_single_line(node_container, input_name)    prop = trace[0][-1].parameters.get(trace[1].to_socket)    # WHY doesn't this work for the Matrix inputs .. ?        return propdef trace_node_lines(node_container):    """ Tells the depth of a node within the node tree. """    node_lines = []    if hasattr(node_container, "inputs"):        for key, socket in node_container.inputs.items():            # Recrusive search through the tree.            #  * checc each relevant input socket in the node            #  * for EACH input, find the node it's connected to            #    * repeat from here until you get all the lines            if ( ( key in ["Relationship", "Parent", "Input Relationship", "Target"])                          and (socket.is_connected) ):                # it is necesary to check the key because of Link nodes,                #   which don't really traverse like normal.                # TODO: see if I can refactor this to make it traverse                other = socket.from_node                if (other):                    other_lines = trace_node_lines(other)                    if not other_lines:                        node_lines.append([other])                    for line in other_lines:                        node_lines.append( [other] + line )    return node_lines        def trace_single_line(node_container, input_name):    """ Tells the depth of a node within the node tree. """    nodes = [node_container]    if hasattr(node_container, "inputs"):        # Trace a single line        if (socket := node_container.inputs.get(input_name) ):            while (socket.is_connected):                other = socket.from_node.outputs.get(socket.from_socket)                if (other):                    socket = other                    if socket.can_traverse:                        socket = socket.traverse_target                        nodes.append(socket.to_node)                    else: # this is an output.                        nodes.append(socket.from_node)                        break                else:                    break    return nodes, socket# this is same as the other, just flip from/to and in/outdef trace_single_line_up(node_container, output_name):    """ Tells the depth of a node within the node tree. """    nodes = [node_container]    if hasattr(node_container, "outputs"):        # Trace a single line        if (socket := node_container.outputs.get(output_name) ):            while (socket.is_connected):                other = socket.to_node.inputs.get(socket.to_socket)                if (other):                    socket = other                    if socket.can_traverse:                        socket = socket.traverse_target                        nodes.append(socket.from_node)                    else: # this is an input.                        nodes.append(socket.to_node)                        break                else:                    break    return nodes, socketdef node_depth(node_container):    maxlen = 0    for nodes in trace_node_lines(node_container):        if (len(nodes) > maxlen):            maxlen = len(nodes)    return maxlen        def get_parent(node_container):    node_line, socket = trace_single_line(node_container, "Relationship")    parent_nc = None    for i in range(len(node_line)):        print (node_line[i])        # check each of the possible parent types.        if ( isinstance(node_line[ i ], LinkInherit) ):            try: # it's the next one                return node_line[ i + 1 ]            except IndexError: # if there is no next one...                return None # then there's no parent!    return None    # TO DO!    #    # make this do shorthand parenting - if no parent, then use World    #  if the parent node is skipped, use the previous node (an xForm)    #  with default settings.    # it is OK to generate a new, "fake" node container for this!def get_target_and_subtarget(node_container, constraint, input_name = "Target"):    from bpy.types import PoseBone, Object    subtarget = ''; target = node_container.evaluate_input(input_name)    if target:        if (isinstance(target.bGetObject(), PoseBone)):            subtarget = target.bGetObject().name            target = target.bGetParentArmature()        elif (isinstance(target.bGetObject(), Object) ):            target = target.bGetObject()        else:            raise RuntimeError("Cannot interpret constraint target!")    if (input_name == 'Target'): # this is sloppy, but it werks        constraint.target, constraint.subtarget = target, subtarget    elif (input_name == 'Pole Target'):        constraint.pole_target, constraint.pole_subtarget = target, subtargetclass NodeSocket:    # this is not meant to be a particularly robust class    # e.g., there will be no disconnect() method since it isn't needed    # I just wanna have something persistent (an object)    # I'd perfer to use pointers and structs, whatever    is_input = False    is_connected = False    from_node = None    to_node = None    from_socket = None    to_socket = None    can_traverse = False    traverse_target = None        def __init__(self, is_input = False,                 from_socket = None, to_socket = None,                 from_node = None, to_node = None,                 traverse_target = None):        self.from_socket = from_socket        self.to_socket   = to_socket        self.from_node   = from_node        self.to_node     = to_node        self.is_input    = is_input        if (self.is_input and (self.from_node or self.from_socket)):            self.is_connected = True        elif ( not self.is_input and (self.to_node or self.to_socket)):            self.is_connected = True        self.set_traverse_target(traverse_target)            def connect(self, node, socket):        if (self.is_input):            self.from_node   = node            self.from_socket = socket        else:            self.to_node   =  node            self.to_socket = socket        self.is_connected = True        def set_traverse_target(self, traverse_target):        if (traverse_target):            self.traverse_target = traverse_target            self.can_traverse = True        def __repr__(self):        if self.is_input:            return ( self.to_node.__repr__() + "::" + self.to_socket )        else:            return (self.from_node.__repr__() + "::" + self.from_socket)        #*#-------------------------------#++#-------------------------------#*## X - F O R M   N O D E S#*#-------------------------------#++#-------------------------------#*## class xFormNull:    # '''A node representing an Empty object'''    # inputs =    # {     # "Name":None,     # "Rotation Order":None,     # "Matrix":None,     # "Relationship":None,    # }    # outputs =    # {     # "xFormOut":None,    # }    # parameters =    # {     # "Name":None,     # "Rotation Order":None,     # "Matrix":None,     # "Relationship":None,    # }        # def evaluate_input(self, input):        # pass        # def instantiate_blender_object(self):        # pass# for whatever reason, the above isn't implemented yet in the node-tree# so I'm not implementing it here, eitherclass xFormRoot:    '''A node representing the root of the scene.'''        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {}        self.outputs = {"xForm Out":NodeSocket(from_socket="xForm Out", from_node = self),}        self.parameters = {}        self.links = {} # leave this empty for now!        self.node_type = 'XFORM'        def init_to_node_line(line,):        pass        def evaluate_input(self, input_name):        return "ROOT"        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class xFormArmature:    '''A node representing an armature object'''        bObject = None        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.executed = False        self.signature = signature        self.inputs = {         "Name"           : NodeSocket(is_input = True, to_socket = "Name", to_node = self),         "Rotation Order" : NodeSocket(is_input = True, to_socket = "Rotation Order", to_node = self),         "Matrix"         : NodeSocket(is_input = True, to_socket = "Matrix", to_node = self),         "Relationship"   : NodeSocket(is_input = True, to_socket = "Relationship", to_node = self),        }        self.outputs = {         "xForm Out" : NodeSocket(from_socket="xForm Out", from_node = self),        }        self.parameters = {         "Name":None,         "Rotation Order":None,         "Matrix":None,         "Relationship":None,        }        self.links = {} # leave this empty for now!        # now set up the traverse target...        self.inputs["Relationship"].set_traverse_target(self.outputs["xForm Out"])        self.outputs["xForm Out"].set_traverse_target(self.inputs["Relationship"])        self.node_type = 'XFORM'                def evaluate_input(self, input_name):        return evaluate_input(self, input_name)        def bExecute(self, bContext = None,):        from .utilities import get_node_prototype                import bpy        if (not isinstance(bContext, bpy.types.Context)):            raise RuntimeError("Incorrect context")        name = self.evaluate_input("Name")        matrix = self.evaluate_input('Matrix')        #check if an object by the name exists        if (name) and (ob := bpy.data.objects.get(name)):            for pb in ob.pose.bones:                # clear it, even after deleting the edit bones,                 #  if we create them again the pose bones will be reused                while (pb.constraints):                    pb.constraints.remove(pb.constraints[-1])                pb.location = (0,0,0)                pb.rotation_euler = (0,0,0)                pb.rotation_quaternion = (1.0,0,0,0)                pb.rotation_axis_angle = (0,0,1.0,0)                pb.scale = (1.0,1.0,1.0)        else:            # Create the Object            ob = bpy.data.objects.new(name, bpy.data.armatures.new(name)) #create ob            if (ob.name != name):                raise RuntimeError("Could not create xForm object", name)                    self.bObject = ob.name                ob.matrix_world = matrix                        # first, get the parent object        parent_node = get_parent(self)        if hasattr(parent_node, "bObject"):            # this won't work of course, TODO            self.bObject.parent = parent_node.bObject                # Link to Scene:        if (ob.name not in bContext.view_layer.active_layer_collection.collection.objects):            bContext.view_layer.active_layer_collection.collection.objects.link(ob)        #self.bParent(bContext)                # Finalize the action        # prevAct = bContext.view_layer.objects.active        bContext.view_layer.objects.active = ob        bpy.ops.object.mode_set(mode='EDIT')        print ("Changing Armature Mode to EDIT")        # clear it        while (len(ob.data.edit_bones) > 0):            ob.data.edit_bones.remove(ob.data.edit_bones[0])        # bContext.view_layer.objects.active = prevAct        print ("Created Armature object: \""+ ob.name +"\"")                        self.executed = True        # # not used yet    # #    # def bFinalize(self, bContext = None):        # import bpy        # ob = self.bGetObject()        # prevAct = bContext.view_layer.objects.active        # bContext.view_layer.objects.active = ob        # bpy.ops.object.mode_set(mode='OBJECT')        # print ("Changing Armature Mode to OBJECT")        # bContext.view_layer.objects.active = prevAct    def bGetObject(self, mode = ''):        import bpy        return bpy.data.objects[self.bObject]    def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class xFormBone:    '''A node representing a bone in an armature'''    # DO: make a way to identify which armature this belongs to    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.executed = False        self.signature = signature        self.inputs = {         "Name"           : NodeSocket(is_input = True, to_socket = "Name", to_node = self,),         "Rotation Order" : NodeSocket(is_input = True, to_socket = "Rotation Order", to_node = self,),         "Matrix"         : NodeSocket(is_input = True, to_socket = "Matrix", to_node = self,),         "Relationship"   : NodeSocket(is_input = True, to_socket = "Relationship", to_node = self,),         # IK settings         "IK Stretch"     : NodeSocket(is_input = True, to_socket = "IK Stretch", to_node = self,),         "Lock IK"        : NodeSocket(is_input = True, to_socket = "Lock IK", to_node = self,),         "IK Stiffness"   : NodeSocket(is_input = True, to_socket = "IK Stiffness", to_node = self,),         "Limit IK"       : NodeSocket(is_input = True, to_socket = "Limit IK", to_node = self,),         "X Min"          : NodeSocket(is_input = True, to_socket = "X Min", to_node = self,),         "X Max"          : NodeSocket(is_input = True, to_socket = "X Max", to_node = self,),         "Y Min"          : NodeSocket(is_input = True, to_socket = "Y Min", to_node = self,),         "Y Max"          : NodeSocket(is_input = True, to_socket = "Y Max", to_node = self,),         "Z Min"          : NodeSocket(is_input = True, to_socket = "Z Min", to_node = self,),         "Z Max"          : NodeSocket(is_input = True, to_socket = "Z Max", to_node = self,),        }        self.outputs = {         "xForm Out"       : NodeSocket(from_socket = "xForm Out", from_node = self),        }        self.parameters = {         "Name":None,         "Rotation Order":None,         "Matrix":None,         "Relationship":None,         # IK settings         "IK Stretch":None,         "Lock IK":None,         "IK Stiffness":None,         "Limit IK":None,         "X Min":None,         "X Max":None,         "Y Min":None,         "Y Max":None,         "Z Min":None,         "Z Max":None,        }        self.links = {} # leave this empty for now!        # now set up the traverse target...        self.inputs["Relationship"].set_traverse_target(self.outputs["xForm Out"])        self.outputs["xForm Out"].set_traverse_target(self.inputs["Relationship"])        self.node_type = 'XFORM'            def evaluate_input(self, input_name):        return evaluate_input(self, input_name)        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)        def bGetParentArmature(self):        finished = False        if (trace := trace_single_line(self, "Relationship")[0] ) :            for i in range(len(trace)):                # have to look in reverse, actually                if ( isinstance(trace[ i ], xFormArmature ) ):                    return trace[ i ].bGetObject()        return None        #should do the trick...        def bSetParent(self, eb):        from bpy.types import EditBone        parent_nc = get_parent(self)        parent = parent_nc.bGetObject(mode = 'EDIT')        if isinstance(parent, EditBone):            print (parent.name)            eb.parent = parent        else:            print(parent)        # otherwise, no need to do anything.                     def bExecute(self, bContext = None,): #possibly will need to pass context?        import bpy        from mathutils import Vector        if (not isinstance(bContext, bpy.types.Context)):            raise RuntimeError("Incorrect context")        xF = self.bGetParentArmature()                name = self.evaluate_input("Name")        matrix = self.evaluate_input("Matrix")                length = matrix[3][3]        matrix[3][3] = 1.0 # set this bacc, could cause problems otherwise.                if (xF):            if (xF.mode != "EDIT"):                raise RuntimeError("Armature Object Not in Edit Mode, exiting...")        else:            raise RuntimeError("No armature object to add bone to.")        #        # Create the Object        d = xF.data        eb = d.edit_bones.new(name)                if (eb.name != name):            raise RuntimeError("Could not create bone ", name, "; Perhaps there is a duplicate bone name in the node tree?")        eb.matrix  = matrix.copy()        tailoffset = Vector((0,length,0)) #Vector((0,self.tailoffset, 0))        tailoffset = matrix.copy().to_3x3() @ tailoffset        eb.tail    = eb.head + tailoffset                if (eb.name != name):            raise RuntimeError("Could not create edit bone: ", name)        self.bObject = eb.name        # The bone should have relationships going in at this point.                                    self.bSetParent(eb)                        return        self.bParent(bContext)        print ("Created Bone: \""+ eb.name+ "\" in \"" + self.bGetParentArmature().name +"\"")        self.executed = True    def bFinalize(self, bContext = None):        # prevAct = bContext.view_layer.objects.active        # bContext.view_layer.objects.active = ob        # bpy.ops.object.mode_set(mode='OBJECT')        # bContext.view_layer.objects.active = prevAct        #        #get relationship        # ensure we have a pose bone...        # set the ik parameters        pass    def bGetObject(self, mode = 'POSE'):        if (mode == 'EDIT'):            try:                return self.bGetParentArmature().data.edit_bones[self.bObject]            except KeyError:                return None        if (mode == 'OBJECT'):            try:                return self.bGetParentArmature().data.bones[self.bObject]            except KeyError:                return None        if (mode == 'POSE'):            try:                return self.bGetParentArmature().pose.bones[self.bObject]            except KeyError:                return None                    #*#-------------------------------#++#-------------------------------#*## L I N K   N O D E S#*#-------------------------------#++#-------------------------------#*#class LinkInherit:    '''A node representing inheritance'''        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {         "Parent"           : NodeSocket(is_input = True, to_socket = "Parent", to_node = self,),         # bone only:         "Inherit Rotation" : NodeSocket(is_input = True, to_socket = "Inherit Rotation", to_node = self,),         "Inherit Scale"    : NodeSocket(is_input = True, to_socket = "Inherit Scale", to_node = self,),         "Connected"        : NodeSocket(is_input = True, to_socket = "Connected", to_node = self,),        }        self.outputs = { "Inheritance" : NodeSocket(from_socket = "Inheritance", from_node = self) }        self.parameters = {         "Parent":None,         # bone only:         "Inherit Rotation":None,         "Inherit Scale":None,         "Connected":None,         "Mute":None,        }        self.links = {} # leave this empty for now!        # now set up the traverse target...        self.inputs["Parent"].set_traverse_target(self.outputs["Inheritance"])        self.outputs["Inheritance"].set_traverse_target(self.inputs["Parent"])        self.node_type = 'LINK'                def evaluate_input(self, input_name):        return evaluate_input(self, input_name)        def bExecute(self, bContext = None,):        # this is handled by the xForm objects, since it isn't really        #  a constraint.        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class LinkCopyLocation:    '''A node representing Copy Location'''        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Head/Tail"          : NodeSocket(is_input = True, to_socket = "Head/Tail", to_node = self,),            "UseBBone"           : NodeSocket(is_input = True, to_socket = "UseBBone", to_node = self,),            "Axes"               : NodeSocket(is_input = True, to_socket = "Axes", to_node = self,),            "Invert"             : NodeSocket(is_input = True, to_socket = "Invert", to_node = self,),            "Target Space"       : NodeSocket(is_input = True, to_socket = "Target Space", to_node = self,),            "Owner Space"        : NodeSocket(is_input = True, to_socket = "Owner Space", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Head/Tail":None,            "UseBBone":None,            "Axes":None,            "Invert":None,            "Target Space":None,            "Owner Space":None,            "Influence":None,            "Target":None,            "Mute":None, }        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'                            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)                def GetxForm(self):        # I don't think I have a function for getting children yet!        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('COPY_LOCATION')        get_target_and_subtarget(self, c)        c.head_tail = self.evaluate_input("Head/Tail")        c.use_bbone_shape = self.evaluate_input("UseBBone")        c.owner_space = self.evaluate_input("Owner Space")        c.target_space = self.evaluate_input("Target Space")        c.invert_x = self.evaluate_input("Invert")[0]        c.invert_y = self.evaluate_input("Invert")[1]        c.invert_z = self.evaluate_input("Invert")[2]                c.use_x = self.evaluate_input("Axes")[0]        c.use_y = self.evaluate_input("Axes")[1]        c.use_z = self.evaluate_input("Axes")[2]        c.influence = self.evaluate_input("Influence")        print ("Creating Copy Location Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)        class LinkCopyRotation:    '''A node representing Copy Rotation'''        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "RotationOrder"      : NodeSocket(is_input = True, to_socket = "RotationOrder", to_node = self,),            "Rotation Mix"       : NodeSocket(is_input = True, to_socket = "Rotation Mix", to_node = self,),            "Axes"               : NodeSocket(is_input = True, to_socket = "Axes", to_node = self,),            "Invert"             : NodeSocket(is_input = True, to_socket = "Invert", to_node = self,),            "Target Space"       : NodeSocket(is_input = True, to_socket = "Target Space", to_node = self,),            "Owner Space"        : NodeSocket(is_input = True, to_socket = "Owner Space", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "RotationOrder":None,            "Rotation Mix":None,            "Axes":None,            "Invert":None,            "Target Space":None,            "Owner Space":None,            "Influence":None,            "Target":None,            "Mute":None, }        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)        def GetxForm(self):        # I don't think I have a function for getting children yet!        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('COPY_ROTATION')                get_target_and_subtarget(self, c)                rotation_order = self.evaluate_input("RotationOrder")                        if ((rotation_order == 'QUATERNION') or (rotation_order == 'AXIS_ANGLE')):            c.euler_order = 'AUTO'        else:            c.euler_order = rotation_order                #c.mix_mode = self.evaluate_input("Rotation Mix")        # kek, deal with this later        # TODO HACK        # dumb enums        c.owner_space = self.evaluate_input("Owner Space")        c.target_space = self.evaluate_input("Target Space")        c.invert_x = self.evaluate_input("Invert")[0]        c.invert_y = self.evaluate_input("Invert")[1]        c.invert_z = self.evaluate_input("Invert")[2]                c.use_x = self.evaluate_input("Axes")[0]        c.use_y = self.evaluate_input("Axes")[1]        c.use_z = self.evaluate_input("Axes")[2]        c.influence = self.evaluate_input("Influence")        print ("Creating Copy Rotation Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)        class LinkCopyScale:    '''A node representing Copy Scale'''        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Offset"             : NodeSocket(is_input = True, to_socket = "Offset", to_node = self,),            "Average"            : NodeSocket(is_input = True, to_socket = "Average", to_node = self,),            "Additive"           : NodeSocket(is_input = True, to_socket = "Additive", to_node = self,),            "Axes"               : NodeSocket(is_input = True, to_socket = "Axes", to_node = self,),            #"Invert"             : NodeSocket(is_input = True, to_socket = "Invert", to_node = self,),            "Target Space"       : NodeSocket(is_input = True, to_socket = "Target Space", to_node = self,),            "Owner Space"        : NodeSocket(is_input = True, to_socket = "Owner Space", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Offset":None,            "Average":None,            "Axes":None,            #"Invert":None,            "Target Space":None,            "Owner Space":None,            "Influence":None,            "Target":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)        def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('COPY_SCALE')                get_target_and_subtarget(self, c)                c.use_offset       = self.evaluate_input("Offset")        c.use_make_uniform = self.evaluate_input("Average")        c.owner_space = self.evaluate_input("Owner Space")        c.target_space = self.evaluate_input("Target Space")        c.use_x = self.evaluate_input("Axes")[0]        c.use_y = self.evaluate_input("Axes")[1]        c.use_z = self.evaluate_input("Axes")[2]        c.influence = self.evaluate_input("Influence")        print ("Creating Copy Location Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class LinkCopyTransforms:    '''A node representing Copy Transfoms'''        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Head/Tail"          : NodeSocket(is_input = True, to_socket = "Head/Tail", to_node = self,),            "UseBBone"           : NodeSocket(is_input = True, to_socket = "UseBBone", to_node = self,),            "Additive"           : NodeSocket(is_input = True, to_socket = "Additive", to_node = self,),            "Mix"                : NodeSocket(is_input = True, to_socket = "Mix", to_node = self,),            "Target Space"       : NodeSocket(is_input = True, to_socket = "Target Space", to_node = self,),            "Owner Space"        : NodeSocket(is_input = True, to_socket = "Owner Space", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Head/Tail":None,            "UseBBone":None,            "Mix":None,            "Target Space":None,            "Owner Space":None,            "Influence":None,            "Target":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)        def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('COPY_TRANSFORMS')                get_target_and_subtarget(self, c)                c.head_tail       = self.evaluate_input("Head/Tail")        c.use_bbone_shape = self.evaluate_input("UseBBone")        c.mix_mode = self.evaluate_input("Mix")        c.owner_space = self.evaluate_input("Owner Space")        c.target_space = self.evaluate_input("Target Space")        c.influence = self.evaluate_input("Influence")        print ("Creating Copy Transforms Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class LinkLimitLocation:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Use Max X"          : NodeSocket(is_input = True, to_socket = "Use Max X", to_node = self,),            "Max X"              : NodeSocket(is_input = True, to_socket = "Max X", to_node = self,),            "Use Max Y"          : NodeSocket(is_input = True, to_socket = "Use Max Y", to_node = self,),            "Max Y"              : NodeSocket(is_input = True, to_socket = "Max Y", to_node = self,),            "Use Max Z"          : NodeSocket(is_input = True, to_socket = "Use Max Z", to_node = self,),            "Max Z"              : NodeSocket(is_input = True, to_socket = "Max Z", to_node = self,),            "Use Min X"          : NodeSocket(is_input = True, to_socket = "Use Min X", to_node = self,),            "Min X"              : NodeSocket(is_input = True, to_socket = "Min X", to_node = self,),            "Use Min Y"          : NodeSocket(is_input = True, to_socket = "Use Min Y", to_node = self,),            "Min Y"              : NodeSocket(is_input = True, to_socket = "Min Y", to_node = self,),            "Use Min Z"          : NodeSocket(is_input = True, to_socket = "Use Min Z", to_node = self,),            "Min Z"              : NodeSocket(is_input = True, to_socket = "Min Z", to_node = self,),            "Affect Transform"   : NodeSocket(is_input = True, to_socket = "Affect Transform", to_node = self,),            "Owner Space"        : NodeSocket(is_input = True, to_socket = "Owner Space", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Use Max X":None,            "Max X":None,            "Use Max Y":None,            "Max Y":None,            "Use Max Z":None,            "Max Z":None,            "Use Min X":None,            "Min X":None,            "Use Min Y":None,            "Min Y":None,            "Use Min Z":None,            "Min Z":None,            "Affect Transform":None,            "Owner Space":None,            "Influence":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        return evaluate_input(self, input_name)        def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):        c = self.GetxForm().bGetObject().constraints.new('LIMIT_LOCATION')        #        c.max_x       = self.evaluate_input("Max X")        c.max_y       = self.evaluate_input("Max Y")        c.max_z       = self.evaluate_input("Max Z")        #        c.min_x       = self.evaluate_input("Min X")        c.min_y       = self.evaluate_input("Min Y")        c.min_z       = self.evaluate_input("Min Z")                c.use_max_x       = self.evaluate_input("Use Max X")        c.use_max_y       = self.evaluate_input("Use Max Y")        c.use_max_z       = self.evaluate_input("Use Max Z")        #        c.use_min_x       = self.evaluate_input("Use Min X")        c.use_min_y       = self.evaluate_input("Use Min Y")        c.use_min_z       = self.evaluate_input("Use Min Z")                c.use_transform_limit = self.evaluate_input("Affect Transform")        c.owner_space = self.evaluate_input("Owner Space")        c.influence = self.evaluate_input("Influence")        print ("Creating Limit Location Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)        class LinkLimitRotation:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Use X"              : NodeSocket(is_input = True, to_socket = "Use X", to_node = self,),            "Use Y"              : NodeSocket(is_input = True, to_socket = "Use Y", to_node = self,),            "Use Z"              : NodeSocket(is_input = True, to_socket = "Use Z", to_node = self,),            "Max X"              : NodeSocket(is_input = True, to_socket = "Max X", to_node = self,),            "Max Y"              : NodeSocket(is_input = True, to_socket = "Max Y", to_node = self,),            "Max Z"              : NodeSocket(is_input = True, to_socket = "Max Z", to_node = self,),            "Min X"              : NodeSocket(is_input = True, to_socket = "Min X", to_node = self,),            "Min Y"              : NodeSocket(is_input = True, to_socket = "Min Y", to_node = self,),            "Min Z"              : NodeSocket(is_input = True, to_socket = "Min Z", to_node = self,),            "Affect Transform"   : NodeSocket(is_input = True, to_socket = "Affect Transform", to_node = self,),            "Owner Space"        : NodeSocket(is_input = True, to_socket = "Owner Space", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Use X":None,            "Use Y":None,            "Use Z":None,            "Max X":None,            "Max Y":None,            "Max Z":None,            "Min X":None,            "Min Y":None,            "Min Z":None,            "Affect Transform":None,            "Owner Space":None,            "Influence":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        return evaluate_input(self, input_name)        def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):        c = self.GetxForm().bGetObject().constraints.new('LIMIT_ROTATION')        #        c.max_x       = self.evaluate_input("Max X")        c.max_y       = self.evaluate_input("Max Y")        c.max_z       = self.evaluate_input("Max Z")        #        c.min_x       = self.evaluate_input("Min X")        c.min_y       = self.evaluate_input("Min Y")        c.min_z       = self.evaluate_input("Min Z")        #        c.use_limit_x       = self.evaluate_input("Use X")        c.use_limit_y       = self.evaluate_input("Use Y")        c.use_limit_z       = self.evaluate_input("Use Z")        #        c.use_transform_limit = self.evaluate_input("Affect Transform")        #        c.owner_space = self.evaluate_input("Owner Space")        c.influence = self.evaluate_input("Influence")        print ("Creating Limit Rotation Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)        class LinkLimitScale:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Use Max X"          : NodeSocket(is_input = True, to_socket = "Use Max X", to_node = self,),            "Max X"              : NodeSocket(is_input = True, to_socket = "Max X", to_node = self,),            "Use Max Y"          : NodeSocket(is_input = True, to_socket = "Use Max Y", to_node = self,),            "Max Y"              : NodeSocket(is_input = True, to_socket = "Max Y", to_node = self,),            "Use Max Z"          : NodeSocket(is_input = True, to_socket = "Use Max Z", to_node = self,),            "Max Z"              : NodeSocket(is_input = True, to_socket = "Max Z", to_node = self,),            "Use Min X"          : NodeSocket(is_input = True, to_socket = "Use Min X", to_node = self,),            "Min X"              : NodeSocket(is_input = True, to_socket = "Min X", to_node = self,),            "Use Min Y"          : NodeSocket(is_input = True, to_socket = "Use Min Y", to_node = self,),            "Min Y"              : NodeSocket(is_input = True, to_socket = "Min Y", to_node = self,),            "Use Min Z"          : NodeSocket(is_input = True, to_socket = "Use Min Z", to_node = self,),            "Min Z"              : NodeSocket(is_input = True, to_socket = "Min Z", to_node = self,),            "Affect Transform"   : NodeSocket(is_input = True, to_socket = "Affect Transform", to_node = self,),            "Owner Space"        : NodeSocket(is_input = True, to_socket = "Owner Space", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Use Max X":None,            "Max X":None,            "Use Max Y":None,            "Max Y":None,            "Use Max Z":None,            "Max Z":None,            "Use Min X":None,            "Min X":None,            "Use Min Y":None,            "Min Y":None,            "Use Min Z":None,            "Min Z":None,            "Affect Transform":None,            "Owner Space":None,            "Influence":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        return evaluate_input(self, input_name)        def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):        c = self.GetxForm().bGetObject().constraints.new('LIMIT_SCALE')        #        c.max_x       = self.evaluate_input("Max X")        c.max_y       = self.evaluate_input("Max Y")        c.max_z       = self.evaluate_input("Max Z")        #        c.min_x       = self.evaluate_input("Min X")        c.min_y       = self.evaluate_input("Min Y")        c.min_z       = self.evaluate_input("Min Z")                c.use_max_x       = self.evaluate_input("Use Max X")        c.use_max_y       = self.evaluate_input("Use Max Y")        c.use_max_z       = self.evaluate_input("Use Max Z")        #        c.use_min_x       = self.evaluate_input("Use Min X")        c.use_min_y       = self.evaluate_input("Use Min Y")        c.use_min_z       = self.evaluate_input("Use Min Z")                c.use_transform_limit = self.evaluate_input("Affect Transform")        c.owner_space = self.evaluate_input("Owner Space")        c.influence = self.evaluate_input("Influence")        print ("Creating Limit Scale Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)        class LinkLimitDistance:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Head/Tail"          : NodeSocket(is_input = True, to_socket = "Head/Tail", to_node = self,),            "UseBBone"           : NodeSocket(is_input = True, to_socket = "UseBBone", to_node = self,),            "Distance"           : NodeSocket(is_input = True, to_socket = "Distance", to_node = self,),            "Clamp Region"       : NodeSocket(is_input = True, to_socket = "Clamp Region", to_node = self,),            "Affect Transform"   : NodeSocket(is_input = True, to_socket = "Affect Transform", to_node = self,),            "Owner Space"        : NodeSocket(is_input = True, to_socket = "Owner Space", to_node = self,),            "Target Space"       : NodeSocket(is_input = True, to_socket = "Target Space", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Head/Tail":None,            "UseBBone":None,            "Distance":None,            "Clamp Region":None,            "Affect Transform":None,            "Owner Space":None,            "Target Space":None,            "Influence":None,            "Target":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)    def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('LIMIT_DISTANCE')                get_target_and_subtarget(self, c)        #        c.distance            = self.evaluate_input("Distance")        c.head_tail           = self.evaluate_input("Head/Tail")        c.limit_mode          = self.evaluate_input("Clamp Region")        c.use_bbone_shape     = self.evaluate_input("UseBBone")        c.use_transform_limit = self.evaluate_input("Affect Transform")        c.owner_space         = self.evaluate_input("Owner Space")        c.target_space        = self.evaluate_input("Target Space")        c.influence           = self.evaluate_input("Influence")        print ("Creating Limit Distance Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)# Trackingclass LinkStretchTo:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Head/Tail"          : NodeSocket(is_input = True, to_socket = "Head/Tail", to_node = self,),            "UseBBone"           : NodeSocket(is_input = True, to_socket = "UseBBone", to_node = self,),            "Original Length"    : NodeSocket(is_input = True, to_socket = "Original Length", to_node = self,),            "Volume Variation"   : NodeSocket(is_input = True, to_socket = "Volume Variation", to_node = self,),            "Use Volume Min"     : NodeSocket(is_input = True, to_socket = "Use Volume Min", to_node = self,),            "Volume Min"         : NodeSocket(is_input = True, to_socket = "Volume Min", to_node = self,),            "Use Volume Max"     : NodeSocket(is_input = True, to_socket = "Use Volume Max", to_node = self,),            "Volume Max"         : NodeSocket(is_input = True, to_socket = "Volume Max", to_node = self,),            "Smooth"             : NodeSocket(is_input = True, to_socket = "Smooth", to_node = self,),            "Maintain Volume"    : NodeSocket(is_input = True, to_socket = "Maintain Volume", to_node = self,),            "Rotation"           : NodeSocket(is_input = True, to_socket = "Rotation", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Head/Tail":None,            "UseBBone":None,            "Original Length":None,            "Volume Variation":None,            "Use Volume Min":None,            "Volume Min":None,            "Use Volume Max":None,            "Volume Max":None,            "Smooth":None,            "Maintain Volume":None,            "Rotation":None,            "Influence":None,            "Target":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)    def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('STRETCH_TO')                get_target_and_subtarget(self, c)                c.head_tail       = self.evaluate_input("Head/Tail")        c.use_bbone_shape = self.evaluate_input("UseBBone")        c.bulge           = self.evaluate_input("Volume Variation")        c.use_bulge_min   = self.evaluate_input("Use Volume Min")        c.bulge_min       = self.evaluate_input("Volume Min")        c.use_bulge_max   = self.evaluate_input("Use Volume Max")        c.bulge_max       = self.evaluate_input("Volume Max")        c.bulge_smooth    = self.evaluate_input("Smooth")        c.keep_axis       = self.evaluate_input("Rotation")        c.volume          = self.evaluate_input("Maintain Volume")        c.rest_length     = self.evaluate_input("Original Length")        c.influence       = self.evaluate_input("Influence")                if (c.rest_length == 0):            # this is meant to be set automatically.            c.rest_length = self.GetxForm().bGetObject().bone.length                print ("Creating Stretch-To Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class LinkDampedTrack:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Head/Tail"          : NodeSocket(is_input = True, to_socket = "Head/Tail", to_node = self,),            "UseBBone"           : NodeSocket(is_input = True, to_socket = "UseBBone", to_node = self,),            "Track Axis"         : NodeSocket(is_input = True, to_socket = "Track Axis", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Head/Tail":None,            "UseBBone":None,            "Track Axis":None,            "Influence":None,            "Target":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)    def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('DAMPED_TRACK')                get_target_and_subtarget(self, c)                c.head_tail       = self.evaluate_input("Head/Tail")        c.use_bbone_shape = self.evaluate_input("UseBBone")        c.track_axis      = self.evaluate_input("Track Axis")        c.influence       = self.evaluate_input("Influence")        print ("Creating Damped-Track Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class LinkLockedTrack:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Head/Tail"          : NodeSocket(is_input = True, to_socket = "Head/Tail", to_node = self,),            "UseBBone"           : NodeSocket(is_input = True, to_socket = "UseBBone", to_node = self,),            "Track Axis"         : NodeSocket(is_input = True, to_socket = "Track Axis", to_node = self,),            "Lock Axis"          : NodeSocket(is_input = True, to_socket = "Lock Axis", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Head/Tail":None,            "UseBBone":None,            "Track Axis":None,            "Lock Axis":None,            "Influence":None,            "Target":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)    def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('LOCKED_TRACK')                get_target_and_subtarget(self, c)                c.head_tail       = self.evaluate_input("Head/Tail")        c.use_bbone_shape = self.evaluate_input("UseBBone")        c.track_axis      = self.evaluate_input("Track Axis")        c.lock_axis       = self.evaluate_input("Lock Axis")        c.influence       = self.evaluate_input("Influence")        print ("Creating Locked-Track Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class LinkTrackTo:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Head/Tail"          : NodeSocket(is_input = True, to_socket = "Head/Tail", to_node = self,),            "UseBBone"           : NodeSocket(is_input = True, to_socket = "UseBBone", to_node = self,),            "Track Axis"         : NodeSocket(is_input = True, to_socket = "Track Axis", to_node = self,),            "Up Axis"            : NodeSocket(is_input = True, to_socket = "Up Axis", to_node = self,),            "Use Target Z"       : NodeSocket(is_input = True, to_socket = "Use Target Z", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Head/Tail":None,            "UseBBone":None,            "Track Axis":None,            "Up Axis":None,            "Use Target Z":None,             "Influence":None,            "Target":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)    def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('TRACK_TO')                get_target_and_subtarget(self, c)                c.head_tail       = self.evaluate_input("Head/Tail")        c.use_bbone_shape = self.evaluate_input("UseBBone")        c.track_axis      = self.evaluate_input("Track Axis")        c.up_axis         = self.evaluate_input("Up Axis")        c.use_target_z    = self.evaluate_input("Use Target Z")        c.influence       = self.evaluate_input("Influence")        print ("Creating Track-To Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)# relationships & misc.class LinkInheritConstraint:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            "Input Relationship" : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Location"           : NodeSocket(is_input = True, to_socket = "Location", to_node = self,),            "Rotation"           : NodeSocket(is_input = True, to_socket = "Rotation", to_node = self,),            "Scale"              : NodeSocket(is_input = True, to_socket = "Scale", to_node = self,),            "Influence"          : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"             : NodeSocket(is_input = True, to_socket = "Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Location":None,            "Rotation":None,            "Scale":None,            "Influence":None,            "Target":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target'):                        socket = self.inputs.get(input_name)            return socket.from_node                    else:            return evaluate_input(self, input_name)    def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):                c = self.GetxForm().bGetObject().constraints.new('CHILD_OF')                get_target_and_subtarget(self, c)                c.use_location_x = self.evaluate_input("Location")[0]        c.use_location_y = self.evaluate_input("Location")[1]        c.use_location_z = self.evaluate_input("Location")[2]        c.use_rotation_x = self.evaluate_input("Rotation")[0]        c.use_rotation_y = self.evaluate_input("Rotation")[1]        c.use_rotation_z = self.evaluate_input("Rotation")[2]        c.use_scale_x    = self.evaluate_input("Scale")[0]        c.use_scale_y    = self.evaluate_input("Scale")[1]        c.use_scale_z    = self.evaluate_input("Scale")[2]        c.influence      = self.evaluate_input("Influence")        c.set_inverse_pending        print ("Creating Child-of Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)# Inverse Kinematics:## r = self.inputs.new('BooleanSocket', "Inherit Rotation")# c = self.inputs.new('BooleanSocket', "Connected")# s = self.inputs.new('EnumInheritScale', "Inherit Scale")# self.inputs.new ('xFormSocket', "Target")# self.inputs.new ('xFormSocket', "Pole Target")# self.inputs.new ('IKChainLengthSocket', "Chain Length")# self.inputs.new ('BooleanSocket', "Use Tail")# self.inputs.new ('BooleanSocket', "Stretch")# self.inputs.new ('FloatFactorSocket', "Position")# self.inputs.new ('FloatFactorSocket', "Rotation")# self.inputs.new ('FloatFactorSocket', "Influence")# self.outputs.new('RelationshipSocket', "Inheritance")# self.inputs.new('xFormSocket', "Parent")## Ugghh, this one is a little weird# I treat IK as a kind of inheritance#  that is mutually exclusive with other inheritance#  since Blender and other softwares treat it specially, anyway#  e.g. in Blender it's always treated as the last constraint# While it may be annoying to have it always appear first in each bones'#  stack, because this does not affect behaviour, I do not really care.class LinkInverseKinematics:    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.inputs = {            # Inheritance bits            "Input Relationship"  : NodeSocket(is_input = True, to_socket = "Input Relationship", to_node = self,),            "Inherit Rotation"    : NodeSocket(is_input = True, to_socket = "Inherit Rotation", to_node = self,),            "Inherit Scale"       : NodeSocket(is_input = True, to_socket = "Inherit Scale", to_node = self,),            "Connected"           : NodeSocket(is_input = True, to_socket = "Connected", to_node = self,),            # Constraint stuff            "Chain Length"        : NodeSocket(is_input = True, to_socket = "Chain Length", to_node = self,),            "Use Tail"            : NodeSocket(is_input = True, to_socket = "Use Tail", to_node = self,),            "Stretch"             : NodeSocket(is_input = True, to_socket = "Stretch", to_node = self,),            "Position"            : NodeSocket(is_input = True, to_socket = "Position", to_node = self,),            "Rotation"            : NodeSocket(is_input = True, to_socket = "Rotation", to_node = self,),            "Influence"           : NodeSocket(is_input = True, to_socket = "Influence", to_node = self,),            "Target"              : NodeSocket(is_input = True, to_socket = "Target", to_node = self,),            "Pole Target"         : NodeSocket(is_input = True, to_socket = "Pole Target", to_node = self,), }        self.outputs = {            "Output Relationship" : NodeSocket(from_socket = "Output Relationship", from_node=self) }        self.parameters = {            "Input Relationship":None,            "Inherit Rotation":None,            "Inherit Scale":None,            "Connected":None,            "Chain Length":None,            "Use Tail":None,            "Stretch":None,            "Position":None,            "Rotation":None,            "Influence":None,            "Target":None,             "Pole Target":None,            "Mute":None,}        # now set up the traverse target...        self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])        self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])        self.node_type = 'LINK'            def evaluate_input(self, input_name):        if (input_name == 'Target') or (input_name == 'Pole Target'):            socket = self.inputs.get(input_name)            return socket.from_node        else:            return evaluate_input(self, input_name)    def GetxForm(self):        trace = trace_single_line_up(self, "Output Relationship")        for node in trace[0]:            if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):                return node        return None    def bExecute(self, context):        # do not handle any inheritance stuff here, that is dealt with        #  by the xForm nodes instead!        myOb = self.GetxForm().bGetObject()        c = self.GetxForm().bGetObject().constraints.new('IK')                get_target_and_subtarget(self, c)        get_target_and_subtarget(self, c, input_name = 'Pole Target')                        if (c.pole_target): # Calculate the pole angle, the user shouldn't have to.            pole_object = c.pole_target            pole_location = pole_object.matrix_world.decompose()[0]            if (c.pole_subtarget):                pole_object = c.pole_target.pose.bones[c.subtarget]                pole_location = pole_object.matrix.decompose()[0]            #HACK HACK            handle_location = myOb.bone.tail_local if (self.evaluate_input("Use Tail")) else myOb.bone.head_local            counter = 0            parent = myOb            base_bone = myOb            while (parent is not None):                if ((self.evaluate_input("Chain Length") != 0) and (counter > self.evaluate_input("Chain Length"))):                    break                base_bone = parent                parent = parent.parent                counter+=1            head_location = base_bone.bone.head_local            pole_normal = (handle_location - head_location).cross(pole_location - head_location)            vector_u = myOb.bone.x_axis            vector_v = pole_normal.cross(base_bone.bone.y_axis)            angle = vector_u.angle(vector_v)            if (vector_u.cross(vector_v).angle(base_bone.bone.y_axis) < 1):                angle = -angle                        c.pole_angle = angle                c.chain_count    = self.evaluate_input("Chain Length")        c.use_tail       = self.evaluate_input("Use Tail")        c.use_stretch    = self.evaluate_input("Stretch")        c.weight         = self.evaluate_input("Position")        c.orient_weight  = self.evaluate_input("Rotation")        c.influence      = self.evaluate_input("Influence")        # this should be sufficient, I think use_location and use_rotation        #  are meaningless if the weight is 0, anyway.        # Well, the minimum weight is 0.01, so we have to get the input again.        c.use_location   = self.evaluate_input("Position") > 0         c.use_rotation   = self.evaluate_input("Rotation") > 0        # this is a little annoying because the constraint can have a        #  positive value for position/rotation without it being enabled.        print ("Creating IK Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")                if self.parameters["Mute"]:            c.enabled = False        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)#*#-------------------------------#++#-------------------------------#*## G E N E R I C   N O D E S#*#-------------------------------#++#-------------------------------#*## in reality, none of these inputs have names#  so I am using the socket name for now#  I suppose I could use any name :3class InputFloat:    '''A node representing float input'''        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs = {"Float Input" : NodeSocket(from_socket = "Float Input", from_node=self) }        self.parameters = {"Float Input":None, "Mute":None}        self.node_type = 'UTILITY'            def evaluate_input(self, input_name):        return self.parameters["Float Input"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)    class InputVector:    '''A node representing vector input'''        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs = {"VectorSocket" : NodeSocket(from_socket = 'VectorSocket', from_node=self) }        self.parameters = {'VectorSocket':None, "Mute":None}        self.node_type = 'UTILITY'            def evaluate_input(self, input_name):        return self.parameters["VectorSocket"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class InputBoolean:    '''A node representing boolean input'''        def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs = {"BooleanSocket" : NodeSocket(from_socket = 'BooleanSocket', from_node=self) }        self.parameters = {'BooleanSocket':None, "Mute":None}        self.node_type = 'UTILITY'            def evaluate_input(self, input_name):        return self.parameters["BooleanSocket"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class InputBooleanThreeTuple:    '''A node representing inheritance'''            def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs = {"BooleanThreeTupleSocket" : NodeSocket(from_socket = 'BooleanThreeTupleSocket', from_node=self) }        self.parameters = {'BooleanThreeTupleSocket':None, "Mute":None}        self.node_type = 'UTILITY'            def evaluate_input(self, input_name):        return self.parameters["BooleanThreeTupleSocket"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class InputRotationOrder:    '''A node representing string input for rotation order'''            def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs = {"RotationOrderSocket" : NodeSocket(from_socket = 'RotationOrderSocket', from_node=self) }        self.parameters = {'RotationOrderSocket':None, "Mute":None}        self.node_type = 'UTILITY'            def evaluate_input(self, input_name):        return self.parameters["RotationOrderSocket"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class InputTransformSpace:    '''A node representing string input for transform space'''            def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs = {"TransformSpaceSocket" : NodeSocket(from_socket = 'TransformSpaceSocket', from_node=self) }        self.parameters = {'TransformSpaceSocket':None, "Mute":None}        self.node_type = 'UTILITY'            def evaluate_input(self, input_name):        return self.parameters["TransformSpaceSocket"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class InputString:    '''A node representing string input'''            def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs = {"StringSocket" : NodeSocket(from_socket = 'StringSocket', from_node=self) }        self.parameters = {'StringSocket':None, "Mute":None}        self.node_type = 'UTILITY'            def evaluate_input(self, input_name):        return self.parameters["StringSocket"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class InputQuaternion:    '''A node representing quaternion input'''    def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs = {"QuaternionSocket" : NodeSocket(from_socket = 'QuaternionSocket', from_node=self) }        self.parameters = {'QuaternionSocket':None, "Mute":None}        self.node_type = 'UTILITY'                    def evaluate_input(self, input_name):        return self.parameters["QuaternionSocket"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class InputQuaternionAA:    '''A node representing axis-angle quaternion input'''            def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs  = {"QuaternionSocketAA" : NodeSocket(from_socket = 'QuaternionSocketAA', from_node=self) }        self.parameters = {'QuaternionSocketAA':None, "Mute":None}        self.node_type = 'UTILITY'            def evaluate_input(self, input_name):        return self.parameters["QuaternionSocketAA"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        fill_parameters(self, node_prototype)class InputMatrix:    '''A node representing axis-angle quaternion input'''            def __init__(self, signature, base_tree):        self.base_tree=base_tree        self.signature = signature        self.outputs  = {"Matrix" : NodeSocket(from_socket = 'Matrix', from_node=self) }        self.parameters = {'Matrix':None, "Mute":None}        self.node_type = 'UTILITY'            def evaluate_input(self, input_name):        return self.parameters["Matrix"]        def bExecute(self, bContext = None,):        pass        def __repr__(self):        return self.signature.__repr__()            def fill_parameters(self, node_prototype):        # this node is peculiar for how its data is input        # It uses node properties that are not addressable as sockets.        from mathutils import Matrix                matrix = ( node_prototype.first_row[ 0], node_prototype.first_row[ 1], node_prototype.first_row[ 2], node_prototype.first_row[ 3],                   node_prototype.second_row[0], node_prototype.second_row[1], node_prototype.second_row[2], node_prototype.second_row[3],                   node_prototype.third_row[ 0], node_prototype.third_row[ 1], node_prototype.third_row[ 2], node_prototype.third_row[ 3],                   node_prototype.fourth_row[0], node_prototype.fourth_row[1], node_prototype.fourth_row[2], node_prototype.fourth_row[3], )        self.parameters["Matrix"] = Matrix([matrix[0:4], matrix[4:8], matrix[8:12], matrix[12:16]])        print (self.parameters["Matrix"])        # # NOT YET IMPLEMENTED:# class InputMatrixNode(Node, MantisNode):    # '''A node representing matrix input'''    # inputs =     # # the node is implemented as a set of sixteen float inputs    # # but I think I can boil it down to one matrix input# class ScaleBoneLengthNode(Node, MantisNode):    # '''Scale Bone Length'''    # pass
 |