| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960 |
- from .node_container_common import *
- # The fact that I need this means that some of these classes should
- # probably be moved to link_containers.py
- from .xForm_containers import xFormRoot, xFormArmature, xFormBone
- def TellClasses():
- return [
- # utility
- InputFloat,
- InputVector,
- InputBoolean,
- InputBooleanThreeTuple,
- InputRotationOrder,
- InputTransformSpace,
- InputString,
- InputQuaternion,
- InputQuaternionAA,
- InputMatrix,
- InputLayerMask,
- # InputGeometry,
- InputExistingGeometryObject,
- InputExistingGeometryData,
- UtilityMetaRig,
- UtilityBoneProperties,
- UtilityDriverVariable,
- UtilityDriver,
- UtilityFCurve,
- UtilitySwitch,
- UtilityCombineThreeBool,
- UtilityCombineVector,
- UtilityCatStrings,
- ]
- #*#-------------------------------#++#-------------------------------#*#
- # 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 :3
- # TODO: the inputs that do not have names should have an empty string
- # TODO after that: make this work with identifiers instead, stupid.
- class InputFloat:
- '''A node representing float input'''
-
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.signature = signature
- self.inputs = {}
- self.outputs = {"Float Input" : NodeSocket(name = "Float Input", 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):
- fill_parameters(self)
-
- class InputVector:
- '''A node representing vector input'''
-
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.signature = signature
- self.inputs = {}
- self.outputs = {"VectorSocket" : NodeSocket(name = 'VectorSocket', 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):
- fill_parameters(self)
- class InputBoolean:
- '''A node representing boolean input'''
-
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.signature = signature
- self.inputs = {}
- self.outputs = {"BooleanSocket" : NodeSocket(name = 'BooleanSocket', 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):
- fill_parameters(self)
- class InputBooleanThreeTuple:
- '''A node representing inheritance'''
-
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.signature = signature
- self.inputs = {}
- self.outputs = {"BooleanThreeTupleSocket" : NodeSocket(name = 'BooleanThreeTupleSocket', 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):
- fill_parameters(self)
- 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.inputs = {}
- self.outputs = {"RotationOrderSocket" : NodeSocket(name = 'RotationOrderSocket', 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):
- fill_parameters(self)
- 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.inputs = {}
- self.outputs = {"TransformSpaceSocket" : NodeSocket(name = 'TransformSpaceSocket', 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):
- fill_parameters(self)
- class InputString:
- '''A node representing string input'''
-
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.signature = signature
- self.inputs = {}
- self.outputs = {"" : NodeSocket(name = '', node=self) }
- self.parameters = {'':None, "Mute":None}
- self.node_type = 'UTILITY'
-
- def evaluate_input(self, input_name):
- return self.parameters[""]
-
- def bExecute(self, bContext = None,):
- pass
-
- def __repr__(self):
- return self.signature.__repr__()
-
- def fill_parameters(self):
- fill_parameters(self)
- class InputQuaternion:
- '''A node representing quaternion input'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.signature = signature
- self.inputs = {}
- self.outputs = {"QuaternionSocket" : NodeSocket(name = 'QuaternionSocket', 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):
- fill_parameters(self)
- class InputQuaternionAA:
- '''A node representing axis-angle quaternion input'''
-
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.signature = signature
- self.inputs = {}
- self.outputs = {"QuaternionSocketAA" : NodeSocket(name = 'QuaternionSocketAA', 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):
- fill_parameters(self)
- class InputMatrix:
- '''A node representing axis-angle quaternion input'''
-
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.signature = signature
- self.inputs = {}
- self.outputs = {"Matrix" : NodeSocket(name = 'Matrix', 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
-
- class UtilityMetaRig:
- '''A node representing an armature object'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- "Meta-Armature" : NodeSocket(is_input = True, name = "Meta-Armature", node=self),
- "Meta-Bone" : NodeSocket(is_input = True, name = "Meta-Bone", node=self),
- }
- self.outputs = {
- "Matrix" : NodeSocket(name = "Matrix", node=self),
- }
- self.parameters = {
- "Meta-Armature" : None,
- "Meta-Bone" : None,
- }
- self.node_type = "UTILITY"
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bExecute(self, bContext = None,):
- #kinda clumsy, whatever
- import bpy
- from mathutils import Matrix
- m = Matrix.Identity(4)
-
- meta_rig = self.evaluate_input("Meta-Armature")
- meta_bone = self.evaluate_input("Meta-Bone")
-
- if meta_rig:
- if ( armOb := bpy.data.objects.get(meta_rig) ):
- m = armOb.matrix_world
- if ( b := armOb.data.bones.get(meta_bone)):
- # calculate the correct object-space matrix
- m = Matrix.Identity(3)
- bones = []
- while (b): bones.append(b); b = b.parent
- while (bones): b = bones.pop(); m = m @ b.matrix
- m = Matrix.Translation(b.head_local) @ m.to_4x4()
- m[3][3] = b.length # this is where I arbitrarily decided to store length
-
-
- self.parameters["Matrix"] = m
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
- self.parameters["Matrix"] = None
- class UtilityBoneProperties:
- '''A node representing an armature object'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {}
- self.outputs = {
- "matrix" : NodeSocket(name = "matrix", node=self),
- "matrix_local" : NodeSocket(name = "matrix_local", node=self),
- "matrix_basis" : NodeSocket(name = "matrix_basis", node=self),
- "head" : NodeSocket(name = "head", node=self),
- "tail" : NodeSocket(name = "tail", node=self),
- "length" : NodeSocket(name = "length", node=self),
- "rotation" : NodeSocket(name = "rotation", node=self),
- "location" : NodeSocket(name = "location", node=self),
- "scale" : NodeSocket(name = "scale", node=self),
- }
- self.parameters = {
- "matrix":None,
- "matrix_local":None,
- "matrix_basis":None,
- "head":None,
- "tail":None,
- "length":None,
- "rotation":None,
- "location":None,
- "scale":None,
- }
- self.node_type = "UTILITY"
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bExecute(self, bContext = None,):
- pass
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- pass#fill_parameters(self)
-
- class UtilityDriverVariable:
- '''A node representing an armature object'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- "Variable Type" : NodeSocket(is_input = True, name = "Variable Type", node = self),
- "Property" : NodeSocket(is_input = True, name = "Property", node = self),
- "Property Index" : NodeSocket(is_input = True, name = "Property Index", node = self),
- "Evaluation Space" : NodeSocket(is_input = True, name = "Evaluation Space", node = self),
- "Rotation Mode" : NodeSocket(is_input = True, name = "Rotation Mode", node = self),
- "xForm 1" : NodeSocket(is_input = True, name = "xForm 1", node = self),
- "xForm 2" : NodeSocket(is_input = True, name = "xForm 2", node = self),
- }
- self.outputs = {
- "Driver Variable" : NodeSocket(name = "Driver Variable", node=self),
- }
- self.parameters = {
- "Variable Type":None,
- "Property":None,
- "Property Index":None,
- "Evaluation Space":None,
- "Rotation Mode":None,
- "xForm 1":None,
- "xForm 2":None,
- }
- self.node_type = "LINK" # MUST be run in Pose mode
-
- def evaluate_input(self, input_name):
- if input_name == 'Property':
- if self.inputs['Property'].is_linked:
- # get the name instead...
- trace = trace_single_line(self, input_name)
- return trace[1].name # the name of the socket
- return self.parameters["Property"]
- return evaluate_input(self, input_name)
-
- def GetxForm(self, index=1):
- trace = trace_single_line(self, "xForm 1" if index == 1 else "xForm 2")
- for node in trace[0]:
- if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):
- return node #this will fetch the first one, that's good!
- return None
- def bExecute(self, bContext = None,):
- prepare_parameters(self)
- #prPurple ("Executing Driver Variable Node")
- xForm1 = self.GetxForm()
- xForm2 = self.GetxForm(index=2)
- # kinda clumsy
- if xForm1 : xForm1 = xForm1.bGetObject()
- if xForm2 : xForm2 = xForm2.bGetObject()
-
- v_type = self.evaluate_input("Variable Type")
- i = self.evaluate_input("Property Index"); dVarChannel = ""
- if (i >= 0): #negative values will use the vector property.
- if self.evaluate_input("Property") == 'location':
- if i == 0: dVarChannel = "LOC_X"
- elif i == 1: dVarChannel = "LOC_Y"
- elif i == 2: dVarChannel = "LOC_Z"
- else: raise RuntimeError("Invalid property index for %s" % self)
- if self.evaluate_input("Property") == 'rotation':
- if i == 0: dVarChannel = "ROT_X"
- elif i == 1: dVarChannel = "ROT_Y"
- elif i == 2: dVarChannel = "ROT_Z"
- elif i == 3: dVarChannel = "ROT_W"
- else: raise RuntimeError("Invalid property index for %s" % self)
- if self.evaluate_input("Property") == 'scale':
- if i == 0: dVarChannel = "SCALE_X"
- elif i == 1: dVarChannel = "SCALE_Y"
- elif i == 2: dVarChannel = "SCALE_Z"
- elif i == 3: dVarChannel = "SCALE_AVG"
- else: raise RuntimeError("Invalid property index for %s" % self)
- if dVarChannel: v_type = "TRANSFORMS"
-
- my_var = {
- "owner" : xForm1, # will be filled in by Driver
- "prop" : self.evaluate_input("Property"), # will be filled in by Driver
- "type" : v_type,
- "space" : self.evaluate_input("Evaluation Space"),
- "rotation_mode" : self.evaluate_input("Rotation Mode"),
- "xForm 1" : self.GetxForm(index = 1),
- "xForm 2" : self.GetxForm(index = 2),
- "channel" : dVarChannel,}
-
- # Push parameter to downstream connected node.connected:
- if (out := self.outputs["Driver Variable"]).is_linked:
- self.parameters[out.name] = my_var
- for link in out.links:
- link.to_node.parameters[link.to_socket] = my_var
-
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
- class UtilityFCurve:
- '''A node representing an armature object'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {}
- self.outputs = {
- "fCurve" : NodeSocket(name = "fCurve", node=self),
- }
- self.parameters = {
- "fCurve":None,
- }
- self.node_type = "UTILITY"
- setup_custom_props(self)
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bExecute(self, bContext = None,):
- prepare_parameters(self)
- from .utilities import get_node_prototype
- np = get_node_prototype(self.signature, self.base_tree)
- keys = []
- #['amplitude', 'back', 'bl_rna', 'co', 'co_ui', 'easing', 'handle_left', 'handle_left_type', 'handle_right', 'handle_right_type',
- # 'interpolation', 'period', 'rna_type', 'select_control_point', 'select_left_handle', 'select_right_handle', 'type']
- if np.use_kf_nodes:
- pass # for now
- else:
- fc_ob = np.fake_fcurve_ob
- fc = fc_ob.animation_data.action.fcurves[0]
- for k in fc.keyframe_points:
- key = {}
- for prop in dir(k):
- if ("__" in prop) or ("bl_" in prop): continue
- #it's __name__ or bl_rna or something
- key[prop] = getattr(k, prop)
- keys.append(key)
-
- # Push parameter to downstream connected node.connected:
- # TODO: find out if this is necesary, even
- if (out := self.outputs["fCurve"]).is_linked:
- self.parameters[out.name] = keys
- for link in out.links:
- link.to_node.parameters[link.to_socket] = keys
-
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
- class UtilityDriver:
- '''A node representing an armature object'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- "Driver Type" : NodeSocket(is_input = True, name = "Driver Type", node = self),
- "Expression" : NodeSocket(is_input = True, name = "Expression", node = self),
- "fCurve" : NodeSocket(is_input = True, name = "fCurve", node = self),
- }
- self.outputs = {
- "Driver" : NodeSocket(name = "Driver", node=self),
- }
- from .drivers import MantisDriver
- self.parameters = {
- "Driver Type":None,
- "Expression":None,
- "fCurve":None,
- "Driver":MantisDriver(),
- }
- self.node_type = "DRIVER" # MUST be run in Pose mode
- setup_custom_props(self)
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bExecute(self, bContext = None,):
- prepare_parameters(self)
- from .drivers import MantisDriver
- #prPurple("Executing Driver Node")
- my_vars = []
-
- for inp in list(self.inputs.keys() )[3:]:
- if (new_var := self.evaluate_input(inp)):
- new_var["name"] = inp
- my_vars.append(new_var)
- else:
- raise RuntimeError("Failed to initialize Driver variable")
- my_driver ={ "owner" : None,
- "prop" : None, # will be filled out in the node that uses the driver
- "expression" : self.evaluate_input("Expression"),
- "ind" : -1, # same here
- "type" : self.evaluate_input("Driver Type"),
- "vars" : my_vars,
- "keys" : self.evaluate_input("fCurve"), }
-
- my_driver = MantisDriver(my_driver)
-
- self.parameters["Driver"].update(my_driver)
- print("Initializing driver %s " % (wrapPurple(self.__repr__())) )
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
- class UtilitySwitch:
- '''A node representing an armature object'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- "xForm" : NodeSocket(is_input = True, name = "xForm", node = self),
- "Parameter" : NodeSocket(is_input = True, name = "Parameter", node = self),
- "Parameter Index" : NodeSocket(is_input = True, name = "Parameter Index", node = self),
- "Invert Switch" : NodeSocket(is_input = True, name = "Invert Switch", node = self),
- }
- self.outputs = {
- "Driver" : NodeSocket(name = "Driver", node=self),
- }
- from .drivers import MantisDriver
- self.parameters = {
- "xForm":None,
- "Parameter":None,
- "Parameter Index":None,
- "Invert Switch":None,
- "Driver":MantisDriver(), # empty for now
- }
- self.node_type = "DRIVER" # MUST be run in Pose mode
- def evaluate_input(self, input_name):
- if input_name == 'Parameter':
- if self.inputs['Parameter'].is_connected:
- trace = trace_single_line(self, input_name)
- return trace[1].name # the name of the socket
- return self.parameters["Parameter"]
- return evaluate_input(self, input_name)
- def GetxForm(self,):
- trace = trace_single_line(self, "xForm" )
- for node in trace[0]:
- if (node.__class__ in [xFormRoot, xFormArmature, xFormBone]):
- return node #this will fetch the first one, that's good!
- return None
- def bExecute(self, bContext = None,):
- #prepare_parameters(self)
- #prPurple ("Executing Switch Node")
- xForm = self.GetxForm()
- if xForm : xForm = xForm.bGetObject()
- if not xForm:
- raise RuntimeError("Could not evaluate xForm for %s" % self)
- from .drivers import MantisDriver
- my_driver ={ "owner" : None,
- "prop" : None, # will be filled out in the node that uses the driver
- "ind" : -1, # same here
- "type" : "SCRIPTED",
- "vars" : [ { "owner" : xForm,
- "prop" : self.evaluate_input("Parameter"),
- "name" : "a",
- "type" : "SINGLE_PROP", } ],
- "keys" : [ { "co":(0,0),
- "interpolation": "LINEAR",
- "type":"KEYFRAME",}, #display type
- { "co":(1,1),
- "interpolation": "LINEAR",
- "type":"KEYFRAME",},], }
- my_driver ["expression"] = "a"
-
- my_driver = MantisDriver(my_driver)
- # this makes it so I can check for type later!
-
- if self.evaluate_input("Invert Switch") == True:
- my_driver ["expression"] = "1 - a"
-
- # this way, regardless of what order things are handled, the
- # driver is sent to the next node.
- # In the case of some drivers, the parameter may be sent out
- # before it's filled in (because there is a circular dependency)
- # I want to support this behaviour because Blender supports it,
- # but I also do not want to support it because it makes things
- # more complex and IMO it's bad practice.
- # We do not make a copy. We update the driver, so that
- # the same instance is filled out.
- self.parameters["Driver"].update(my_driver)
- print("Initializing driver %s " % (wrapPurple(self.__repr__())) )
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
-
- class UtilityCombineThreeBool:
- '''A node for combining three booleans into a boolean three-tuple'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- "X" : NodeSocket(is_input = True, name = "X", node = self),
- "Y" : NodeSocket(is_input = True, name = "Y", node = self),
- "Z" : NodeSocket(is_input = True, name = "Z", node = self),
- }
- self.outputs = {
- "Three-Bool" : NodeSocket(name = "Three-Bool", node=self),
- }
- self.parameters = {
- "X":None,
- "Y":None,
- "Z":None, }
- self.node_type = "UTILITY"
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bExecute(self, bContext = None,):
- #prPurple("Executing CombineThreeBool Node")
- #prepare_parameters(self)
- self.parameters["Three-Bool"] = (
- self.evaluate_input("X"),
- self.evaluate_input("Y"),
- self.evaluate_input("Z"), )
- # DO:
- # figure out how to get the driver at execute-time
- # because Blender allows circular dependencies in drivers
- # (sort of), I need to adopt a more convoluted way of doing
- # things here or elsewhere.
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
- # Note this is a copy of the above. This needs to be de-duplicated into
- # a simpler CombineVector node_container.
- # TODO
- class UtilityCombineVector:
- '''A node for combining three floats into a vector'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- "X" : NodeSocket(is_input = True, name = "X", node = self),
- "Y" : NodeSocket(is_input = True, name = "Y", node = self),
- "Z" : NodeSocket(is_input = True, name = "Z", node = self),
- }
- self.outputs = {
- "Vector" : NodeSocket(name = "Vector", node=self),
- }
- self.parameters = {
- "X":None,
- "Y":None,
- "Z":None, }
- self.node_type = "UTILITY"
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bExecute(self, bContext = None,):
- #prPurple("Executing CombineVector Node")
- prepare_parameters(self)
- self.parameters["Vector"] = (
- self.evaluate_input("X"),
- self.evaluate_input("Y"),
- self.evaluate_input("Z"), )
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
- class UtilityCatStrings:
- '''A node representing an armature object'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- "String_1" : NodeSocket(is_input = True, name = "String_1", node = self),
- "String_2" : NodeSocket(is_input = True, name = "String_2", node = self),
- }
- self.outputs = {
- "OutputString" : NodeSocket(name = "OutputString", node=self),
- }
- self.parameters = {
- "String_1":None,
- "String_2":None,
- }
- self.node_type = "UTILITY"
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bExecute(self, bContext = None,):
- self.parameters["OutputString"] = self.evaluate_input("String_1")+self.evaluate_input("String_2")
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
- class InputLayerMask:
- '''A node representing an armature object'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- }
- self.outputs = {
- "Layer Mask" : NodeSocket(is_input = True, name = "Layer Mask", node = self),
- }
- self.parameters = {
- "Layer Mask":None,
- }
- self.node_type = "UTILITY"
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bExecute(self, bContext = None,):
- pass
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
- # class InputGeometry:
- # '''A node representing an armature object'''
- # def __init__(self, signature, base_tree):
- # self.base_tree=base_tree
- # self.executed = False
- # self.signature = signature
- # self.inputs = {
- # "Geometry Name" : NodeSocket(is_input = True, to_socket = "Geometry Name", to_node = self),
- # }
- # self.outputs = {
- # "Geometry" : NodeSocket(from_socket = "Geometry", from_node=self),
- # }
- # self.parameters = {
- # "Geometry Name":None,
- # "Geometry":None,
- # }
- # self.node_type = "UTILITY"
- # def evaluate_input(self, input_name):
- # return evaluate_input(self, input_name)
- # 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 InputExistingGeometryObject:
- '''A node representing an existing object'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- "Name" : NodeSocket(is_input = True, name = "Name", node = self),
- }
- self.outputs = {
- "Object" : NodeSocket(is_input = False, name = "Object", node=self),
- }
- self.parameters = {
- "Name":None,
- "Object":None,
- }
- self.node_type = "UTILITY"
-
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bGetObject(self):
- from bpy import data
- return data.objects.get( self.evaluate_input("Name") )
-
- def bExecute(self, bContext = None,):
- pass
- # DO: make this data, of course
- # try curve and then mesh
- # probably should print a warning on the node if it is ambiguous
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
- class InputExistingGeometryData:
- '''A node representing existing object data'''
- def __init__(self, signature, base_tree):
- self.base_tree=base_tree
- self.executed = False
- self.signature = signature
- self.inputs = {
- "Name" : NodeSocket(is_input = True, name = "Name", node = self),
- }
- self.outputs = {
- "Geometry" : NodeSocket(is_input = False, name = "Geometry", node=self),
- }
- self.parameters = {
- "Name":None,
- "Geometry":None,
- }
- self.node_type = "UTILITY"
- def evaluate_input(self, input_name):
- return evaluate_input(self, input_name)
- def bGetObject(self):
- from bpy import data
- # first try Curve, then try Mesh
- bObject = data.curves.get(self.evaluate_input("Name"))
- if not bObject:
- bObject = data.meshes.get(self.evaluate_input("Name"))
- return bObject
-
- def bExecute(self, bContext = None,):
- pass
- def __repr__(self):
- return self.signature.__repr__()
- def fill_parameters(self):
- fill_parameters(self)
|