def deserialise(self, data): # -- Start by creating the node node = pm.createNode(data['node_type']) pm.PyNode(data['driver']).connect(node.attr('input'), force=True) node.attr('output').connect(data['driven'], force=True) # -- Set the curve data node.preInfinity.set(data['pre_infinity_type']) node.postInfinity.set(data['post_infinity_type']) # -- Now build the curve for key_data in data['key_data']: pm.setDrivenKeyframe( data['driven'], currentDriver=data['driver'], driverValue=key_data['time'], value=key_data['value'], ) # -- Get the key index key_idx = node.numKeys() - 1 # -- Set the key properties node.setInTangentType(key_idx, key_data['in_tangent_type']) node.setOutTangentType(key_idx, key_data['out_tangent_type']) pm.keyTangent( index=[key_idx, key_idx], ix=key_data['in_tangent'][0], iy=key_data['in_tangent'][1], ox=key_data['out_tangent'][0], oy=key_data['out_tangent'][1], )
def sdk_channel(self, channel, mode): u"""驱动通道 Args: channel (str): 被驱动的通道 mode (str): 驱动模式 """ attr_list = ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"] if len(self.ar_data.get_channel_joints(channel)) > 0: for jnt in self.ar_data.get_channel_joints(channel): print(u"开始为{}->{}设置sdk".format(channel, jnt)) for dv_attr in attr_list: pm.setDrivenKeyframe("%s.%s" % (jnt, dv_attr), cd="{}.{}".format(mode, channel), dv=0) value = self.ar_data.get_channel_joint_attr(channel, jnt) for dv_attr in attr_list: dv_value = [ value[0] * 100, value[1] * 100, value[2] * 100, value[3], value[4], value[5], value[6], value[7], value[8], ] helper.position_joint(jnt, value=dv_value) pm.setDrivenKeyframe("%s.%s" % (jnt, dv_attr), cd="{}.{}".format(mode, channel), dv=1) pm.setAttr("{}.{}".format(mode, channel), 0) return
def spread(): tmp = const(True) if tmp: objs = pm.ls(sl=True) cons = [] subSpread(objs[-1], len(objs)-2) cons += pm.listRelatives(pm.ls(objs[-1]), ad=True, typ='constraint') attrs = [] sel = -1 for con in cons: attrs.append(pm.listAttr(con, ud=True)) for con_count in range(len(cons)): if tmp: if sel+3 < len(objs) and con_count < len(objs)-1: if objs[sel] != cons[con_count].split("_")[0]: sel += 3 attr = attrs[con_count] for x in range(len(attr)): pm.setAttr(objs[sel]+".spread", x) pm.setAttr(cons[con_count]+"."+attr[x], 1) for y in range(len(attr)): if x != y: pm.setAttr(cons[con_count]+"."+attr[y], 0) for z in range(len(attr)): pm.setDrivenKeyframe(cons[con_count]+"."+attr[z], cd=objs[sel]+".spread")
def createNewPose(self, poseAttr=None): if not self.poseNode: pmc.warning("SDK pose node not defined!") return ctrls = self.getAllControls() sel = pmc.ls(selection=True) ctrls = list(set(ctrls) & set(sel)) # if not passed an attribute (on the pose node) to RE-connect, # create in-scene single-value node # which drives ctrls if not poseAttr: a = pmc.addAttr(self.poseNode, at="float", ln="newPose") poseAttr = pmc.pyNode(self.poseNode + "." + a) poseAttr.set(1) # setDrivenKey ALL values on ALL ctrls # with poseAttr @ 1 and ctrl @ their current values pmc.setDrivenKeyframe(ctrls, currentDriver=poseAttr) # reset poseAttr THEN reset ctrls poseAttr.set(0) for c in ctrls: au.resetCtrl(c) pmc.setDrivenKeyframe(ctrls, currentDriver=poseAttr) # make connected slider slider = MayaFloatSlider(self, poseAttr) self.poseSliders.append(slider) slider.setValue(1)
def connect_sdk(driverAttr, drivenObj, attribute, driverValues=[], drivenValues=[]): for driverValue, drivenValue in zip(driverValues, drivenValues): pm.setDrivenKeyframe(drivenObj, currentDriver=driverAttr, at=attribute, driverValue=driverValue, value=drivenValue)
def rig_animDrivenKey(driver, driverValues, driven, drivenValues): for i in range(0, len(driverValues)): pm.setDrivenKeyframe(driven, cd=driver, v=drivenValues[i], dv=driverValues[i])
def sdk_slider_to_rig(self, channel, attr="sliderX"): attr_list = ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"] for jnt in self.ar_data.get_channel_joints(channel): value = self.ar_data.get_channel_joint_attr(channel, jnt) for dv_attr in attr_list: helper.position_joint(jnt, value=[0, 0, 0, 0, 0, 0, 1, 1, 1]) pm.setDrivenKeyframe("%s.%s" % (jnt, dv_attr), cd="%s.%s" % (channel, attr), dv=0) dv_value = [ value[0] * 100, value[1] * 100, value[2] * 100, value[3], value[4], value[5], value[6], value[7], value[8], ] helper.position_joint(jnt, value=dv_value) pm.setDrivenKeyframe("%s.%s" % (jnt, dv_attr), cd="%s.%s" % (channel, attr), dv=1) pm.setAttr("%s.%s" % (channel, attr), 0) return
def applySetDrivenKeys(ctrl, infos): ''' Create the setDrivenKeys on the ctrl with the specially formatted string list from `findSetDrivenKeys`. ''' for info in infos: drivenAttr, driveNode, driveAttr, data = info node = findFromIds(driveNode) cutKey(ctrl.attr(drivenAttr), cl=True) #keyData = [KeyData(*d) for d in data] if isinstance(data, list): setDrivenKeyframe(ctrl, at=[drivenAttr], v=-.14, cd=node.attr(driveAttr), dv=[data[0]['time']]) else: setDrivenKeyframe(ctrl, at=[drivenAttr], v=-.14, cd=node.attr(driveAttr), dv=[data['keys'][0]['time']]) dataToCurve(data, ctrl.attr(drivenAttr))
def sg_connectAttr(self): main = pm.PyNode(self.ctrName) rbg = pm.PyNode(self.nodeName) if not self.geoName: OpenMaya.MGlobal_displayError( 'not select tou object , please again select') return geo = pm.PyNode(self.geoName) self.linkeAttr(main, geo, rbg) rbg.hue[0].hue_FloatValue.set(float(self.linetxt3.text())) if rbg.hasAttribute('fileTextureName'): pm.setDrivenKeyframe(rbg.hue[0].hue_FloatValue, currentDriver=rbg.fileTextureName, itt='linear', ott='linear') pm.setDrivenKeyframe(rbg.color, currentDriver=rbg.fileTextureName, itt='linear', ott='linear') OpenMaya.MGlobal_displayInfo('------ add setKey OK -----') else: OpenMaya.MGlobal_displayError( 'remapHsv node not fileTextureName attribute') return
def handControlSetup(self, *args): """ Create attributes on hand_cnt and connect them as needed. """ pm.addAttr(self.hand_cnt,ln='FK_IK',at='float',dv=0,min=0,max=1,k=True) # IK/FK blend color nodes pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.shldr_node1 ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.elbow1_node1 ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.elbow1_node2 ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.wrist_node1 ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.wrist_node2 ) #IK/FK controls vis switch pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.visibility'%self.ikChain[0] ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.visibility'%self.ikControl[0] ) pm.setDrivenKeyframe(self.fkChain[0], cd='%s.FK_IK' % self.hand_cnt, at='visibility', dv=1, v=0) pm.setDrivenKeyframe(self.fkChain[0], cd='%s.FK_IK' % self.hand_cnt, at='visibility', dv=0, v=1) # Zero hand control and parent to the following joint chian. self.zero(self.hand_cnt) bufferNode = pm.listRelatives(self.hand_cnt,parent=True) pm.parentConstraint(self.jointChain[2],bufferNode,mo=True)
def connect(filter=None, conns="MEm.shapes.conns"): """ conenct shape control panel with blendshapes based on map """ for ctl, chan, drv, tgt, alias, val in iterConns(conns): if filter is None or tgt in filter: try: oSHP = Shapes(tgt) except Exception as e: print e continue drvAttr = "{0}.{1}".format(ctl, chan) print "tgt, alias:", tgt, alias tgtAttr = oSHP[alias] print "Create key from", print "{0}:{1} to {2}:{3}".format(drvAttr, drv, tgtAttr.name(), val) oDrvAttr = pym.PyNode(drvAttr) print "Value:", oDrvAttr.get() oDrvAttr.set(drv) tgtAttr.set(val) pym.setDrivenKeyframe(tgtAttr.name(), cd=drvAttr, ott="linear", itt="linear")
def cbsHookup(*args, **kwargs): base = kwargs.setdefault('base') #(string) The base mesh for the character bs = kwargs.setdefault('bs') #(string) The blendshape deformer to which the shape should be added (if blank, a new deformer will be created shape = kwargs.setdefault('shape') #(string) The new target to add to the blendshape driver = kwargs.setdefault('driver') #(string) Node and attribute to have drive the blendshape target weight driveRange = kwargs.setdefault('driveRange', [0, 1]) #(2 float list) The range of the driver to go from 0-1. [0]=target weight of 0, [1]=weight of 1 tan = kwargs.setdefault('tan', ['spline', 'spline']) # (2 string list) The tangent types for the set driven keys. [0]=start, [1]=end infinity = kwargs.setdefault('infinity', [False, False]) # (2 bool list) sets whether or not to give the set driven key pre or post infinity. [0]=pre, [1]=post #create a blendshape deformer if one hasn't been specified if not bs: bs = pm.blendShape(base, frontOfChain=True, n='%s_corrective_bs'%base)[0] #add the new target to the blendshape targs = pm.blendShape(bs, q=True, t=True) for targ in targs: if str(shape).split('|')[-1] == str(targ).split('|')[-1]: pm.error('It appears you already have a blendshape target named %s in the node %s. Please rename the new target with a unique name.'%(shape, bs)) pm.blendShape(bs, e=True, t=[base, len(targs), shape, 1]) #set up the set driven key to drive the blendshape pm.setDrivenKeyframe('%s.%s'%(bs, shape), cd=driver, dv=driveRange[0], v=0, itt=tan[0], ott=tan[0]) pm.setDrivenKeyframe('%s.%s'%(bs, shape), cd=driver, dv=driveRange[1], v=1, itt=tan[1], ott=tan[1]) #set up infinity if requested if infinity[0]: pm.setInfinity('%s.%s'%(bs, shape), pri='linear') if infinity[1]: pm.setInfinity('%s.%s'%(bs, shape), poi='linear') return bs
def rp_grip(): """..............................................................................................//""" s = pm.ls(sl=1) if pm.mel.gmatch(s[0], "*_grip*"): ps = pm.listRelatives(s[0], p=1) pm.delete(ps[0]) else: rp_check(s) cj = pm.ls((s[0] + "_tw_*"), typ="joint") for y in range(0, (len(cj))): if pm.objExists("ctgrp_" + s[0] + "_grip" + str((y + 1))) == 0: ct = pm.circle(ch=0, nr=(1, 0, 0), r=0.8, d=3, n=("CT_" + s[0] + "_grip" + str((y + 1)))) ctg = str(pm.group(ct[0], n=("ctgrp_" + s[0] + "_grip" + str((y + 1))))) pm.parent(ctg, (s[0] + "_rig")) pm.setAttr((ct[0] + ".tx"), k=0, l=1) pm.setAttr((ct[0] + ".ty"), k=0, l=1) pm.setAttr((ct[0] + ".tz"), k=0, l=1) pm.setAttr((ct[0] + ".rx"), k=0, l=1) pm.setAttr((ct[0] + ".ry"), k=0, l=1) pm.setAttr((ct[0] + ".rz"), k=0, l=1) pm.setAttr((ct[0] + ".sx"), k=0, l=1) pm.setAttr((ct[0] + ".sy"), k=0, l=1) pm.setAttr((ct[0] + ".sz"), k=0, l=1) pm.setAttr((ct[0] + ".v"), k=0) pm.setAttr((ct[0] + "Shape.ove"), 1) pm.setAttr((ct[0] + "Shape.ovc"), 13) pm.addAttr(ct[0], min=0, ln="move", max=(len(cj)), k=1, at="long", dv=0) pm.parentConstraint(cj, ctg, w=1) for i in range(0, (len(cj))): pm.setAttr((ct[0] + ".move"), i) for x in range(0, (len(cj))): pm.setAttr((ctg + "_parentConstraint1." + cj[x] + "W" + str(x)), 0) pm.setAttr((ctg + "_parentConstraint1." + cj[i] + "W" + str(i)), 1) pm.setDrivenKeyframe((ctg + "_parentConstraint1." + cj[x] + "W" + str(x)), cd=(ct[0] + ".move")) pm.setAttr((ct[0] + ".move"), (y + 1)) pm.select(s[0]) break
def sdk_display_enum(dvr_attr, dvn_attr): dvn_attr.node().overrideEnabled.set(1) sdk_linear(dvr_attr, dvn_attr.node().overrideDisplayType) pm.setDrivenKeyframe(dvn_attr, v=1, cd=dvr_attr, dv=2, itt='linear', ott='linear') pm.setDrivenKeyframe(dvn_attr, v=0, cd=dvr_attr, dv=3, itt='linear', ott='linear')
def cbsHookup(*args, **kwargs): base = kwargs.setdefault('base') #(string) The base mesh for the character bs = kwargs.setdefault( 'bs' ) #(string) The blendshape deformer to which the shape should be added (if blank, a new deformer will be created shape = kwargs.setdefault( 'shape') #(string) The new target to add to the blendshape driver = kwargs.setdefault( 'driver' ) #(string) Node and attribute to have drive the blendshape target weight driveRange = kwargs.setdefault( 'driveRange', [0, 1] ) #(2 float list) The range of the driver to go from 0-1. [0]=target weight of 0, [1]=weight of 1 tan = kwargs.setdefault( 'tan', ['spline', 'spline'] ) # (2 string list) The tangent types for the set driven keys. [0]=start, [1]=end infinity = kwargs.setdefault( 'infinity', [False, False] ) # (2 bool list) sets whether or not to give the set driven key pre or post infinity. [0]=pre, [1]=post #create a blendshape deformer if one hasn't been specified if not bs: bs = pm.blendShape(base, frontOfChain=True, n='%s_corrective_bs' % base)[0] #add the new target to the blendshape targs = pm.blendShape(bs, q=True, t=True) for targ in targs: if str(shape).split('|')[-1] == str(targ).split('|')[-1]: pm.error( 'It appears you already have a blendshape target named %s in the node %s. Please rename the new target with a unique name.' % (shape, bs)) pm.blendShape(bs, e=True, t=[base, len(targs), shape, 1]) #set up the set driven key to drive the blendshape pm.setDrivenKeyframe('%s.%s' % (bs, shape), cd=driver, dv=driveRange[0], v=0, itt=tan[0], ott=tan[0]) pm.setDrivenKeyframe('%s.%s' % (bs, shape), cd=driver, dv=driveRange[1], v=1, itt=tan[1], ott=tan[1]) #set up infinity if requested if infinity[0]: pm.setInfinity('%s.%s' % (bs, shape), pri='linear') if infinity[1]: pm.setInfinity('%s.%s' % (bs, shape), poi='linear') return bs
def sdk_switch(dvr_attr, dvn_attrs): for i in range(len(dvn_attrs)): for dvn_attr in dvn_attrs: if dvn_attr == dvn_attrs[i]: value = 1 else: value = 0 pm.setDrivenKeyframe(dvn_attr, v=value, cd=dvr_attr, dv=i, itt='flat', ott='flat')
def sdk(driverPlug, drivenPlug, driveDrivenPairs, itt='linear', ott='linear'): ''' setDrivenKeyframe wrapper, takes pairs of (<drive value>, <driven value>) ''' for driveValue, drivenValue in driveDrivenPairs: setDrivenKeyframe(drivenPlug, v=drivenValue, currentDriver=driverPlug, driverValue=driveValue, itt=itt, ott=ott)
def add_display_enum(dvr, ln, dvn=""): enumName = "on:template:reference:off" pm.addAttr(dvr, ln=ln, at='enum', enumName=enumName, k=True) dvr_attr = pm.PyNode("%s.%s" %(dvr.name(), ln)) if dvn: dvn.overrideEnabled.set(1) dvr_attr >> dvn.overrideDisplayType pm.setDrivenKeyframe(dvn.visibility, v=1, cd=dvr_attr, dv=2, itt='linear', ott='linear') pm.setDrivenKeyframe(dvn.visibility, v=0, cd=dvr_attr, dv=3, itt='linear', ott='linear')
def sdk_index(driver, driverAttr, drivens, drivenAttr, drivenMinMax): for driven,i in zip(drivens,range(len(drivens))): print "Setting driven key for object %s.%s from driver %s.%s" % (driver, driverAttr, driven, drivenAttr) for j in range(len(drivens)): print 'i=%d,j=%d'%(i,j) pm.setAttr(driver+'.'+driverAttr, j) pm.setAttr(driven+'.'+drivenAttr,drivenMinMax[0]) if j==i: pm.setAttr(driven+'.'+drivenAttr,drivenMinMax[1]) print 'setting to %s.%s to maximum %d' % (driven, drivenAttr, drivenMinMax[1]) pm.setDrivenKeyframe(driven, at=drivenAttr, cd=(driver+'.'+driverAttr))
def rig_connectChains(self): for chain in self.chainNames: consts = [] pm.select('%s_hr_sh_0'%chain, hi=True, r=True) shJnts = pm.ls(sl=True) for jnt in shJnts: const = pm.parentConstraint(jnt.replace('sh','dynJnt'), jnt.replace('sh','fkJnt'), jnt, mo=True) pm.connectAttr('HairRig_MainCnt.%s_dynamic'%chain,'%s.%sW0'%(const,jnt.replace('sh','dynJnt')),f=True) pm.setDrivenKeyframe( '%s.%sW1'%(const, jnt.replace('sh','fkJnt')), cd='HairRig_MainCnt.%s_dynamic'%chain, dv=0, v=1 ) pm.setDrivenKeyframe( '%s.%sW1'%(const, jnt.replace('sh','fkJnt')), cd='HairRig_MainCnt.%s_dynamic'%chain, dv=1, v=0 )
def __init__(self, name): self.side = '' if name.startswith('l_'): self.side = 'l' if name.startswith('r_'): self.side = 'r' self.top = pm.PyNode(rig_transform(0, name=name+'Module').object) self.controls = pm.PyNode(rig_transform(0, name=name+'Controls', parent=self.top).object) self.controlsSec = pm.PyNode(rig_transform(0, name=name + 'ControlsSecondary', parent=self.controls).object) self.skeleton = pm.PyNode(rig_transform(0, name=name+'Skeleton', parent=self.top).object) self.parts = pm.PyNode(rig_transform(0, name=name+'Parts', parent=self.top).object) pm.hide(self.parts) pm.addAttr(self.top, longName='skeletonVis', at='long', k=True, min=0, max=1) pm.connectAttr(self.top.skeletonVis, self.skeleton.visibility) pm.addAttr(self.top, longName='controlsVis', at='long', k=True, min=0, max=1) pm.connectAttr(self.top.controlsVis, self.controls.visibility) pm.addAttr(self.top, longName='ikFkSwitch', at='long', k=True, min=0, max=1) if pm.objExists('global_CTRL'): globalCtrl = pm.PyNode('global_CTRL') pm.connectAttr(globalCtrl.skeletonVis, self.top.skeletonVis) pm.connectAttr(globalCtrl.controlsVis, self.top.controlsVis) pm.setAttr(self.skeleton.overrideEnabled, 1) pm.setDrivenKeyframe(self.skeleton.overrideDisplayType, cd=globalCtrl.skeleton, dv=0, v=0) pm.setDrivenKeyframe(self.skeleton.overrideDisplayType, cd=globalCtrl.skeleton, dv=1, v=2) self.controlsList = [] self.skeletonList = [] self.partsList = [] rigModule = 'rigModules_GRP' if pm.objExists(rigModule): pm.parent(self.top, rigModule) pm.addAttr(rigModule, longName=name+'Module', at='long', k=True, min=0, max=1, dv=1) pm.connectAttr( rigModule+'.'+name+'Module', self.top.visibility )
def create_animCurveU(type, kt, kv, kit=None, kot=None, kix=None, kiy=None, kox=None, koy=None, pre=0, pst=0): """ :param type: :param keys: A tuple containing the following values: key time, key value :param pre: :param post: :return: """ # Use a temporary node to create the curve tmp = pymel.createNode('transform') # Resolve the attributes we'll want to "connect" att_src = tmp.sx att_dst = None if type == 'animCurveUU': att_dst = tmp.sy elif type == 'animCurveUL': att_dst = tmp.tx elif type == 'animCurveUA': att_dst = tmp.rx else: raise NotImplemented("Unexpected animCurve type. Got {0}.".format(type)) # Create keys for key_time, key_val in zip(kt, kv): att_src.set(key_time) att_dst.set(key_val) pymel.setDrivenKeyframe(att_dst, cd=att_src) # Get curve and delete tmp object curve = next(iter(att_dst.inputs())) pymel.disconnectAttr(curve.output, att_dst) pymel.disconnectAttr(att_src, curve.input) pymel.delete(tmp) curve.setPreInfinityType(pre) curve.setPostInfinityType(pst) num_keys = len(kt) if kit: for i, ti in zip(range(num_keys), kit): curve.setInTangentType(i, ti) if kot: for i, to in zip(range(num_keys), kot): curve.setOutTangentType(i, to) if kix and kiy: for i, tix, tiy in zip(range(num_keys), kix, kiy): curve.setTangent(i, tix, tiy, True) if kox and koy: for i, tox, toy in zip(range(num_keys), kox, koy): curve.setTangent(i, tox, toy, False) return curve
def sdk_full_rotation(dvr_attr, dvn_attr): pm.setDrivenKeyframe(dvn_attr, v=0, cd=dvr_attr, dv=0, itt='linear', ott='linear') pm.setDrivenKeyframe(dvn_attr, v=180, cd=dvr_attr, dv=180, itt='linear', ott='linear') pm.setDrivenKeyframe(dvn_attr, v=180, cd=dvr_attr, dv=-180, itt='linear', ott='linear') pm.setDrivenKeyframe(dvn_attr, v=360, cd=dvr_attr, dv=-0.001, itt='linear', ott='linear')
def makeFkIk(*args): bindRoot = pm.ls(selection = True)[0] bindChain = pm.ls(bindRoot, dag = True) fkChain = pm.duplicate(bindRoot) replaceSuffix(fkChain, 'fk') makeFk(False, fkChain) ikChain = pm.duplicate(bindRoot) replaceSuffix(ikChain, 'ik') makeIk(False, ikChain) fkChainList = pm.ls(fkChain, dag = True) ikChainList = pm.ls(ikChain, dag = True) createPad(bindRoot) suffixIndex = bindChain[0].rfind('_') hanldeName = bindChain[0][:suffixIndex] + '_switch' handle = createHandle(hanldeName) pm.rename(handle, hanldeName) pm.parentConstraint(bindChain[-1], handle) constraintList = [] for i, item in enumerate(bindChain): newConstraint = pm.orientConstraint(fkChainList[i], ikChainList[i], bindChain[i], mo = False) fkCon = pm.orientConstraint(newConstraint, q = True, wal = True)[1] ikCon = pm.orientConstraint(newConstraint, q = True, wal = True)[0] pm.setDrivenKeyframe(fkCon, cd = handle + '.switch', v = 1, dv = 10) pm.setDrivenKeyframe(fkCon, cd = handle + '.switch', v = 0, dv = 0) pm.setDrivenKeyframe(ikCon, cd = handle + '.switch', v = 0, dv = 10) pm.setDrivenKeyframe(ikCon, cd = handle + '.switch', v = 1, dv = 0)
def rrFkCntSDK(cnt=None, attr=None, driver=None, v=[], dv=[]): ''' Given selected rr fk control, create SDK on parent group. ''' pm.select(cnt, r=1) cnt = pm.ls(sl=1)[0] prnt = cnt.getParent() unlock(obj=prnt) for val, dval in zip(v, dv): pm.setDrivenKeyframe(prnt, cd=driver, dv=dval, v=val, at=attr)
def sg_connectAttr(self): mian = pm.PyNode(self.ctrName) rbg = pm.PyNode(self.nodeName) rbg.hue[0].hue_FloatValue.set(float(self.linetxt3.text())) if mian.hasAttr('tex'): pm.setDrivenKeyframe(rbg.hue[0].hue_FloatValue, currentDriver=mian.tex, itt='linear', ott='linear') pm.setDrivenKeyframe(rbg.color, currentDriver=mian.tex, itt='linear', ott='linear')
def addOrientsToCtrl(noSnap=False): sel = pmc.ls(selection=True) # make sure selection is valid if len(sel) < 2: pmc.error("Select more shit.") return for s in sel: if s.type() != "transform": pmc.error("Invalid selection: {0}".format(s)) return target = sel[-1] sources = sel[0:-1] par = target.getParent() if not par or par.type() != "transform": pmc.error("Parent of target is not transformable.") return # Create a world object to constrain to # User must choose how to organize this new group worldLoc = pmc.spaceLocator(n=target+"_WorldOrientLoc") pmc.delete(pmc.parentConstraint(par, worldLoc, mo=False)) # currently maintainOffset is on - is this right? pCon = pmc.parentConstraint(worldLoc, par, mo=False) # create string of enum options spaces = "World" for s in sources: # this is the format that enumNames wants spaces += ":"+s.name() # create parent constraint pmc.parentConstraint(s, par, mo=False) target.addAttr("Orient", at="enum", keyable=True, enumName=spaces) # need to wait to set driven keys until ALL constraints have been added weights = pCon.getWeightAliasList() for i, w in enumerate(weights): # w is the weight attr itself # set enum, and match attributes to correct 0 or 1 values target.Orient.set(i) for x in weights: if w == x: x.set(1) else: x.set(0) # SDK to connect the enum to parent constraint weight pmc.setDrivenKeyframe(x, currentDriver=target.Orient)
def handControlSetup(self, *args): """ Create attributes on hand_cnt and connect them as needed. """ pm.addAttr(self.hand_cnt, ln='FK_IK', at='float', dv=0, min=0, max=1, k=True) # IK/FK blend color nodes pm.connectAttr('%s.FK_IK' % self.hand_cnt, '%s.blender' % self.shldr_node1) pm.connectAttr('%s.FK_IK' % self.hand_cnt, '%s.blender' % self.elbow1_node1) pm.connectAttr('%s.FK_IK' % self.hand_cnt, '%s.blender' % self.elbow1_node2) pm.connectAttr('%s.FK_IK' % self.hand_cnt, '%s.blender' % self.wrist_node1) pm.connectAttr('%s.FK_IK' % self.hand_cnt, '%s.blender' % self.wrist_node2) #IK/FK controls vis switch pm.connectAttr('%s.FK_IK' % self.hand_cnt, '%s.visibility' % self.ikChain[0]) pm.connectAttr('%s.FK_IK' % self.hand_cnt, '%s.visibility' % self.ikControl[0]) pm.setDrivenKeyframe(self.fkChain[0], cd='%s.FK_IK' % self.hand_cnt, at='visibility', dv=1, v=0) pm.setDrivenKeyframe(self.fkChain[0], cd='%s.FK_IK' % self.hand_cnt, at='visibility', dv=0, v=1) # Zero hand control and parent to the following joint chian. self.zero(self.hand_cnt) bufferNode = pm.listRelatives(self.hand_cnt, parent=True) pm.parentConstraint(self.jointChain[2], bufferNode, mo=True)
def rigCharacterGrp(): ''' 캐릭터 베이스 생성 ''' # # 최상위 그룹 리깅 Group = pm.group(n='Group', em=True) Root = pm.curve( d=3, p=[ (-0.068059129190802453, 0.0, 0.49515769319022762), (-0.045372752829582474, 0.0, 0.52918733713445421), (-0.022686376468362496, 0.0, 0.56321698107868068), (-1.0714251708066058e-10, 0.0, 0.59724662502290737), (0.022686376254077462, 0.0, 0.56321698107868068), (0.04537275261529744, 0.0, 0.52918733713445421), (0.068059128976517419, 0.0, 0.49515769319022762), (0.17494851557291896, 0.0, 0.47998907510370475), (0.37963820444740304, 0.0, 0.37963820444740298), (0.47998907510370487, 0.0, 0.17494851557291891), (0.49515769355710038, 0.0, 0.068059128879015496), (0.52918733713445409, 0.0, 0.045372752615297385), (0.56321698107868079, 0.0, 0.022686376254077378), (0.59724662502290737, 0.0, -1.0714257259181181e-10), (0.56321698107868079, 0.0, -0.022686376468362524), (0.52918733713445409, 0.0, -0.04537275282958253), (0.49515769319022745, 0.0, -0.068059129190802536), (0.47998907510370487, 0.0, -0.17494851578720411), (0.37963820444740304, 0.0, -0.37963820466168813), (0.17494851557291899, 0.0, -0.4799890753179899), (0.068059128879015551, 0.0, -0.49515769377138547), (0.045372752567678483, 0.0, -0.52918733763445291), (0.022686376230267983, 0.0, -0.56321698154296529), (-1.0714251708066058e-10, 0.0, -0.59724662545147766), (-0.022686376444553017, 0.0, -0.56321698154296529), (-0.045372752781963517, 0.0, -0.52918733763445291), (-0.068059129119374021, 0.0, -0.49515769372594071), (-0.174948515787204, 0.0, -0.4799890753179899), (-0.37963820466168807, 0.0, -0.37963820466168813), (-0.4799890753179899, 0.0, -0.17494851578720411), (-0.49515769377138541, 0.0, -0.068059129093300641), (-0.5291873376344528, 0.0, -0.045372752781963621), (-0.56321698154296518, 0.0, -0.022686376444553125), (-0.59724662545147744, 0.0, -1.0714257259181181e-10), (-0.56321698154296518, 0.0, 0.022686376230267979), (-0.5291873376344528, 0.0, 0.045372752567678476), (-0.49515769372594048, 0.0, 0.068059128905088973), (-0.47998907531798995, 0.0, 0.17494851557291877), (-0.37963820466168807, 0.0, 0.37963820444740298), (-0.17494851578720391, 0.0, 0.47998907510370475), (-0.068059129093300405, 0.0, 0.49515769355710032) ], k=[ 14.04717124, 14.04717124, 14.04717124, 15.0, 15.0, 15.0, 15.95282876, 15.95282876, 15.95282876, 16.778606267, 17.604383774, 17.604383774, 17.604383774, 18.557212534, 18.557212534, 18.557212534, 19.510041294, 19.510041294, 19.510041294, 20.335818801, 21.161596308, 21.161596308, 21.161596308, 22.114425067, 22.114425067, 22.114425067, 23.067253826, 23.067253826, 23.067253826, 23.893031333, 24.71880884, 24.71880884, 24.71880884, 25.671637599, 25.671637599, 25.671637599, 26.624466358, 26.624466358, 26.624466358, 27.450243865, 28.276021372, 28.276021372, 28.276021372 ] ) Motion = pm.group(n='Motion', em=True) Deformer = pm.group(n='Deformer', em=True) Geometry = pm.group(n='Geometry', em=True) previewGeo_grp = pm.group(n='PreviewGeo_grp', em=True) renderGeo_grp = pm.group(n='RenderGeo_grp', em=True) # # Root 리깅 Root.s.set(100,100,100) pm.makeIdentity( Root, apply=True, t=1,r=1,s=1,n=0) Root.rename( 'Reference' ) # diplayGeo Root.addAttr( "displayGeo", at="enum", en="Preview:Render:", keyable=False ) Root.addAttr( "displayPreviewGeo", at="bool", keyable=False ) Root.addAttr( "displayRenderGeo", at="bool", keyable=False ) Root.displayGeo.showInChannelBox(True) Root.displayPreviewGeo >> previewGeo_grp.v Root.displayRenderGeo >> renderGeo_grp.v pm.setDrivenKeyframe( Root.displayPreviewGeo, currentDriver=Root.displayGeo, driverValue=0, value=1, inTangentType='linear', outTangentType='linear' ) pm.setDrivenKeyframe( Root.displayPreviewGeo, currentDriver=Root.displayGeo, driverValue=1, value=0, inTangentType='linear', outTangentType='linear' ) pm.setDrivenKeyframe( Root.displayRenderGeo, currentDriver=Root.displayGeo, driverValue=0, value=0, inTangentType='linear', outTangentType='linear' ) pm.setDrivenKeyframe( Root.displayRenderGeo, currentDriver=Root.displayGeo, driverValue=1, value=1, inTangentType='linear', outTangentType='linear' ) Root.addAttr( 'scaleFix', at='double') Root.scaleFix.showInChannelBox(True) scaleFix_DIV = pm.createNode( 'multiplyDivide', n='scaleFix_DIV') scaleFix_DIV.op.set(2) # div scaleFix_DIV.input1.set( 1,1,1 ) Root.sy >> scaleFix_DIV.input2X scaleFix_DIV.outputX >> Root.scaleFix Root.overrideEnabled.set( True ) Root.overrideColor.set( 13 ) # # 그루핑 pm.parent( previewGeo_grp, renderGeo_grp, Geometry) pm.parent( Motion, Deformer, Root ) pm.parent( Root, Geometry, Group) # # 어트리뷰트 조정 Geometry.it.set(False) for obj in [Group, Geometry]: for attr in ['tx','ty','tz', 'rx','ry','rz', 'sx','sy','sz']: obj.setAttr(attr, keyable=False, lock=True, channelBox=False )
def connectWithLimits(AttrX, AttrY, keys): AttrX = validate_pymel_nodes(AttrX) AttrY = validate_pymel_nodes(AttrY) value = pm.listConnections(AttrY, destination=False, plugs=True, skipConversionNodes=True) if value: print value[0].node() if pm.objectType(value[0].node()) == 'plusMinusAverage': plusMinus = value[0].node() if AttrX.get(type=True) in ['float', 'doubleLinear', 'doubleAngle']: for eachKey in keys: pm.setDrivenKeyframe('%s' % plusMinus.input1D[len(plusMinus.input1D.elements())], currentDriver='%s' % AttrX, dv=eachKey[0], v=eachKey[1]) # elif attribute_source.get(type=True) in [vector]: # print 'connecting vector' elif AttrX.get(type=True) in ['double3']: for eachKey in keys: pm.setDrivenKeyframe('%s' % plusMinus.input3D[len(plusMinus.input3D.elements()) % 3], currentDriver='%s' % AttrX, dv=eachKey[0], v=eachKey[1]) else: print 'could not add data type: %s' % AttrX.get(type=True) else: if AttrX.get(type=True) in ['float','doubleLinear', 'doubleAngle']: plusMinus = pm.shadingNode("plusMinusAverage", asUtility=True, name="additiveConnection") value[0] // AttrY value[0] >> plusMinus.input1D[0] plusMinus.output1D >> AttrY for eachKey in keys: pm.setDrivenKeyframe('%s' % plusMinus.input1D[1], currentDriver='%s' % AttrX, dv=eachKey[0], v=eachKey[1]) elif AttrX.get(type=True) in ['double3']: plusMinus = pm.shadingNode("plusMinusAverage", asUtility=True, name="additiveConnection") value[0] // AttrY value[0] >> plusMinus.input3D[0] plusMinus.output3D >> AttrY for eachKey in keys: pm.setDrivenKeyframe('%s' % plusMinus.input3D[1], currentDriver='%s' % AttrX, dv=eachKey[0], v=eachKey[1]) else: print 'could not add data type: %s' % AttrX.get(type=True) else: for eachKey in keys: pm.setDrivenKeyframe('%s'%AttrY, currentDriver='%s' % AttrX, dv=eachKey[0], v=eachKey[1])
def createEasySmooth(): sel = pm.selected() objs = sel[0:] cruveGen = generateCurve(sel[-1]) slider = cruveGen[0] sliderField = cruveGen[1] smoothCtls = [cruveGen[2]] ctl = sliderField for currentSel in (sel[:-1]): smoothCtls.append(generateChildCurve(currentSel)) pm.group(smoothCtls, n=smoothCtls[0] + '_Group') # ctl = sel[-1] #[-1]で要素の末尾を取得 #新しいアトリビュートを作成する pm.addAttr(ctl, ln='divisions', nn='div', at='long', min=0, max=4, dv=0) #作成したアトリビュートの編集を有効可する ctlDiv = pm.Attribute(ctl + '.divisions') pm.setAttr( ctlDiv, e=True, keyable=True, ) for obj in objs: smthChk = False for cnct in set(obj.getShape().inputs()): if isinstance( cnct, pm.nt.PolySmoothFace ): #セットでinputsノードの重複を無くし、cnctの方がpolysmoothfaceだった場合(すでにスムースノードがある場合)はsmthckをtrueにする smthChk = True break if smthChk: ctlDiv >> cnct.divisions #すでにスムースノードがある場合は、それをctlDivアトリビュートと接続 else: smthNode = pm.polySmooth(obj) #objに新しくスムースを追加し ctlDiv >> smthNode[ 0].divisions #スムースノードのdivisionsアトリビュートとctlのdivisionアトリビュート(ctlDiv)をつなぐ pm.transformLimits(slider, tx=(0, 1.23), etx=(True, True)) pm.setDrivenKeyframe("%s.divisions" % ctl, cd="%s.tx" % slider, dv=0, v=0) pm.setDrivenKeyframe("%s.divisions" % ctl, cd="%s.tx" % slider, dv=1.23, v=4)
def create(self, node): """Add a parameter to property using the parameter definition. Arguments: node (dagNode): The node to add the attribute """ attr_name = addAttribute(node, self.scriptName, "double", 0) attrDummy_name = addAttribute( node, self.scriptName + "_dummy", "double", 0) for key in self.keys: pm.setDrivenKeyframe( attr_name, cd=attrDummy_name, dv=key[0], v=key[1]) # clean dummy attr pm.deleteAttr(attrDummy_name) return node, attr_name
def setDrivenKey(driver, driverValueList, driven, drivenValueList, cvType='linear'): """ Set Driven Key utility :param driver: str, driver + driving attribute (ctrl.attr) :param driverValueList: list, value list :param driven: str, driven + driven attribute (ctrl.attr) :param drivenValueList: list, value list :param cvType: str, auto, clamped, fast, flat, linear, plateau, slow, spline, step, and stepnext :return: """ for driverV, drivenV in zip(driverValueList, drivenValueList): pm.setDrivenKeyframe(driven, currentDriver=driver, driverValue=driverV, value=drivenV, inTangentType=cvType, outTangentType=cvType)
def bdAddCurl(side, finger, attr): fingerAnim = pm.ls(side + '*toes_ctrl', type='transform')[0] targetValuesDown = [-100, -90, -125] targetValuesDownThumb = [100, 90, 125] sdkFingers = pm.ls(side + '*' + finger + '_*_sdk') rev = 1 if side == 'right': rev = -1 for sdk in sdkFingers: print 'Add curl for %s %s' % (side, finger) pm.setDrivenKeyframe(sdk, at='rotateZ', cd=fingerAnim.name() + '.' + attr, dv=0, v=0) pm.setDrivenKeyframe(sdk, at='rotateZ', cd=fingerAnim.name() + '.' + attr, dv=10, v=targetValuesDown[sdkFingers.index(sdk)]) pm.setDrivenKeyframe(sdk, at='rotateZ', cd=fingerAnim.name() + '.' + attr, dv=-10, v=25)
def squash_stretch_ik(direction): driver = direction + "Leg_IK_Length.distance" thigh_length = pm.getAttr(direction + "Knee_IK_JNT.translateX") shin_length = pm.getAttr(direction + "Foot_IK_JNT.translateX") sum_length = thigh_length + shin_length if sum_length < 0: sum_length *= -1 knee_joint = direction + "Knee_IK_JNT" foot_joint = direction + "Foot_IK_JNT" pm.setDrivenKeyframe(knee_joint, cd=driver, dv=sum_length, at="translateX", v=thigh_length) pm.setDrivenKeyframe(knee_joint, cd=driver, dv=sum_length * 2, at="translateX", v=thigh_length * 2) pm.setDrivenKeyframe(foot_joint, cd=driver, dv=sum_length, at="translateX", v=shin_length) pm.setDrivenKeyframe(foot_joint, cd=driver, dv=sum_length * 2, at="translateX", v=shin_length * 2)
def bdAddSpreadMeta(side,finger,attr): fingerAnim = pm.ls(side + 'Fingers_CON',type='transform')[0] if finger != 'Thumb': startFingerJnt = pm.ls(side + finger + '_00_JNT')[0] pm.setDrivenKeyframe(startFingerJnt, at='rotateY', cd = fingerAnim.name() + '.' + attr , dv= 0 , v = 0) pm.setDrivenKeyframe(startFingerJnt, at='rotateY', cd = fingerAnim.name() + '.' + attr , dv= 10 , v = -10) pm.setDrivenKeyframe(startFingerJnt, at='rotateY', cd = fingerAnim.name() + '.' + attr , dv= -10 , v = 10)
def bdAddSpreadMeta(side,finger,attr): fingerAnim = pm.ls(side + '*fingers_ctrl',type='transform')[0] if finger != 'thumb': startFingerJnt = pm.ls(side + '*' + finger.lower() + '*_01_bnd')[0] pm.setDrivenKeyframe(startFingerJnt, at='rotateY', cd = fingerAnim.name() + '.' + attr , dv= 0 , v = 0) pm.setDrivenKeyframe(startFingerJnt, at='rotateY', cd = fingerAnim.name() + '.' + attr , dv= 10 , v = -10) pm.setDrivenKeyframe(startFingerJnt, at='rotateY', cd = fingerAnim.name() + '.' + attr , dv= -10 , v = 10)
def reversAttrRig(driverAttr=None, drivenAttr=None): ''' Attribute Reverse Rig ''' if not driverAttr and not drivenAttr: driverAttr, drivenAttr = getAttrsFromChannelbox() if not driverAttr and not drivenAttr: raise AttributeError(u"") driverAttr = pm.PyNode(driverAttr) drivenAttr = pm.PyNode(drivenAttr) pm.setDrivenKeyframe(drivenAttr, currentDriver=driverAttr, dv=0, v=1, inTangentType='linear', outTangentType='linear') pm.setDrivenKeyframe(drivenAttr, currentDriver=driverAttr, dv=1, v=0, inTangentType='linear', outTangentType='linear')
def bdAddBend(side,finger,attr): fingerAnim = pm.ls(side + '*toes_ctrl',type='transform')[0] startFingerSdk = pm.ls(side + '*'+ finger + '*_01_ctrl_sdk')[0] startFingerJnt = pm.ls(side + '*'+ finger + '*_01_ctrl_sdk')[0] pm.setDrivenKeyframe(startFingerJnt, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= 0 , v = 0) pm.setDrivenKeyframe(startFingerJnt, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= 10 , v = -90) pm.setDrivenKeyframe(startFingerJnt, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= -10 , v = 90)
def bdAddCurl(side,finger,attr): fingerAnim = pm.ls(side + 'Fingers_CON',type='transform')[0] targetValuesDown = [-100,-90,-125] sdkFingers = pm.ls(side + finger + '_*_SDK') for finger in sdkFingers: pm.setDrivenKeyframe(finger, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= 0 , v = 0) pm.setDrivenKeyframe(finger, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= 10 , v = targetValuesDown[sdkFingers.index(finger)]) pm.setDrivenKeyframe(finger, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= -10 , v = 25)
def bdAddBend(side, finger, attr): fingerAnim = pm.ls(side + '*toes_ctrl', type='transform')[0] startFingerSdk = pm.ls(side + '*' + finger + '*_01_ctrl_sdk')[0] startFingerJnt = pm.ls(side + '*' + finger + '*_01_ctrl_sdk')[0] pm.setDrivenKeyframe(startFingerJnt, at='rotateZ', cd=fingerAnim.name() + '.' + attr, dv=0, v=0) pm.setDrivenKeyframe(startFingerJnt, at='rotateZ', cd=fingerAnim.name() + '.' + attr, dv=10, v=-90) pm.setDrivenKeyframe(startFingerJnt, at='rotateZ', cd=fingerAnim.name() + '.' + attr, dv=-10, v=90)
def bdAddScrunch(side,finger,attr): fingerAnim = pm.ls(side + '*toes_ctrl',type='transform')[0] targetValuesUp = [70,-85,-60] targetValuesDown = [-45,45,45] sdkFingers = pm.ls(side+ '*' + finger + '_*_sdk') for finger in sdkFingers: pm.setDrivenKeyframe(finger, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= 0 , v = 0) pm.setDrivenKeyframe(finger, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= 10 , v = targetValuesUp[sdkFingers.index(finger)]) pm.setDrivenKeyframe(finger, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= -10 , v = targetValuesDown[sdkFingers.index(finger)])
def addFCurve(node, name="fcurve", keys=[]): """FCurve attribute Just a animCurveUU node connected to an attribute Warning: This Method is deprecated. Arguments: node (dagNode): The object to add the new fcurve attribute name (str): The attribute name key (list): list of keyframes and values Returns: Fcurve and attribute name """ attr_name = addAttribute(node, name, "double", 0) attrDummy_name = addAttribute(node, name + "_dummy", "double", 0) for key in keys: # we use setDrivenKeyframe, because is the only workaround that I found # to create an animCurveUU with keyframes pm.setDrivenKeyframe(attr_name, cd=attrDummy_name, dv=key[0], v=key[1], itt=key[2], ott=key[2]) # clean dummy attr pm.deleteAttr(attrDummy_name) fCurve = pm.PyNode(attr_name).listConnections(type="animCurveUU")[0] return fCurve, attr_name
def rig_connectChains(self): for chain in self.chainNames: consts = [] pm.select('%s_hr_sh_0' % chain, hi=True, r=True) shJnts = pm.ls(sl=True) for jnt in shJnts: const = pm.parentConstraint(jnt.replace('sh', 'dynJnt'), jnt.replace('sh', 'fkJnt'), jnt, mo=True) pm.connectAttr('HairRig_MainCnt.%s_dynamic' % chain, '%s.%sW0' % (const, jnt.replace('sh', 'dynJnt')), f=True) pm.setDrivenKeyframe('%s.%sW1' % (const, jnt.replace('sh', 'fkJnt')), cd='HairRig_MainCnt.%s_dynamic' % chain, dv=0, v=1) pm.setDrivenKeyframe('%s.%sW1' % (const, jnt.replace('sh', 'fkJnt')), cd='HairRig_MainCnt.%s_dynamic' % chain, dv=1, v=0)
def bdAddSpread(side,finger,attr): print 'adding spread for %s %s'%(side,finger) fingerAnim = pm.ls(side + '*toes_ctrl',type='transform')[0] startFingerSdk = pm.ls(side + '*' + finger.lower() + '*_01_ctrl_sdk')[0] pm.setDrivenKeyframe(startFingerSdk, at='rotatey', cd = fingerAnim.name() + '.' + attr , dv= 0 , v = 0) pm.setDrivenKeyframe(startFingerSdk, at='rotateY', cd = fingerAnim.name() + '.' + attr , dv= 10 , v = 30) pm.setDrivenKeyframe(startFingerSdk, at='rotateY', cd = fingerAnim.name() + '.' + attr , dv= -10 , v = -30) '''
def bdAddSpread(side, finger, attr): print 'adding spread for %s %s' % (side, finger) fingerAnim = pm.ls(side + '*toes_ctrl', type='transform')[0] startFingerSdk = pm.ls(side + '*' + finger.lower() + '*_01_ctrl_sdk')[0] pm.setDrivenKeyframe(startFingerSdk, at='rotatey', cd=fingerAnim.name() + '.' + attr, dv=0, v=0) pm.setDrivenKeyframe(startFingerSdk, at='rotateY', cd=fingerAnim.name() + '.' + attr, dv=10, v=30) pm.setDrivenKeyframe(startFingerSdk, at='rotateY', cd=fingerAnim.name() + '.' + attr, dv=-10, v=-30) '''
def bdAddScrunch(side, finger, attr): fingerAnim = pm.ls(side + '*toes_ctrl', type='transform')[0] targetValuesUp = [70, -85, -60] targetValuesDown = [-45, 45, 45] sdkFingers = pm.ls(side + '*' + finger + '_*_sdk') for finger in sdkFingers: pm.setDrivenKeyframe(finger, at='rotateZ', cd=fingerAnim.name() + '.' + attr, dv=0, v=0) pm.setDrivenKeyframe(finger, at='rotateZ', cd=fingerAnim.name() + '.' + attr, dv=10, v=targetValuesUp[sdkFingers.index(finger)]) pm.setDrivenKeyframe(finger, at='rotateZ', cd=fingerAnim.name() + '.' + attr, dv=-10, v=targetValuesDown[sdkFingers.index(finger)])
def bdAddCurl(side,finger,attr): fingerAnim = pm.ls(side + '*toes_ctrl',type='transform')[0] targetValuesDown = [-100,-90,-125] targetValuesDownThumb = [100,90,125] sdkFingers = pm.ls(side + '*'+ finger + '_*_sdk') rev = 1; if side == 'right': rev = -1 for sdk in sdkFingers: print 'Add curl for %s %s'%(side,finger) pm.setDrivenKeyframe(sdk, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= 0 , v = 0) pm.setDrivenKeyframe(sdk, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= 10 , v = targetValuesDown[sdkFingers.index(sdk)]) pm.setDrivenKeyframe(sdk, at='rotateZ', cd = fingerAnim.name() + '.' + attr , dv= -10 , v = 25)
def bdAddTwist(side, finger, attr): fingerAnim = pm.ls(side + '*fingers_ctrl', type='transform')[0] startFingerSdk = pm.ls(side + '*' + finger.lower() + '*_01_ctrl_sdk')[0] pm.setDrivenKeyframe(startFingerSdk, at='rotateX', cd=fingerAnim.name() + '.' + attr, dv=0, v=0) pm.setDrivenKeyframe(startFingerSdk, at='rotateX', cd=fingerAnim.name() + '.' + attr, dv=10, v=-90) pm.setDrivenKeyframe(startFingerSdk, at='rotateX', cd=fingerAnim.name() + '.' + attr, dv=-10, v=90)
def bdAddTwist(side, finger, attr): fingerAnim = pm.ls(side + 'Fingers_CON', type='transform')[0] startFingerSdk = pm.ls(side + finger + '_01_SDK')[0] pm.setDrivenKeyframe(startFingerSdk, at='rotateX', cd=fingerAnim.name() + '.' + attr, dv=0, v=0) pm.setDrivenKeyframe(startFingerSdk, at='rotateX', cd=fingerAnim.name() + '.' + attr, dv=10, v=-90) pm.setDrivenKeyframe(startFingerSdk, at='rotateX', cd=fingerAnim.name() + '.' + attr, dv=-10, v=90)
def keyController(ctrlList): """ 回傳有 keyframe 的 controller 字典 { ctrl : { ctrl.attr : animCurveNode } } """ ctrlKey = {} for ctrl in ctrlList: hasKey = False driven = pm.setDrivenKeyframe(ctrl, q= 1, dn= 1) keyNum = pm.keyframe(ctrl, q= 1, kc= 1) drnNum = 0 if keyNum: if driven[0] == 'No driven attributes found on the selected item.': # has key hasKey = True else: # has drivenKey for dn in driven: drnNum += pm.keyframe(dn, q= 1, kc= 1) if drnNum < keyNum: # has key hasKey = True if hasKey: atKey = {} ats = pm.listConnections(ctrl, d= 0, c= 1, scn= 1, t= 'animCurve') for at in ats: at = at[0] # skip driven if drnNum and at in driven: continue at = at.name() ac = pm.listConnections(at, d= 0, scn= 1, t= 'animCurve') atKey[str(at)] = str(ac[0].name()) ctrlKey[str(ctrl)] = atKey return ctrlKey
def bdAddSpreadMeta(side, finger, attr): fingerAnim = pm.ls(side + 'Fingers_CON', type='transform')[0] if finger != 'Thumb': startFingerJnt = pm.ls(side + finger + '_00_JNT')[0] pm.setDrivenKeyframe(startFingerJnt, at='rotateY', cd=fingerAnim.name() + '.' + attr, dv=0, v=0) pm.setDrivenKeyframe(startFingerJnt, at='rotateY', cd=fingerAnim.name() + '.' + attr, dv=10, v=-10) pm.setDrivenKeyframe(startFingerJnt, at='rotateY', cd=fingerAnim.name() + '.' + attr, dv=-10, v=10)
def rigFootRoll( foot_joint, control, prefix, suffix=None, side=LEFT_SIDE, footRollMode=FOOTROLL_AUTO ): suffix = suffix or ('_l','_r')[side] exp_template = "" labels = { 'expression' : prefix + 'control' + suffix + '_EXP', 'ikToe' : prefix + 'ik_toe' + suffix, 'pivotBall' : prefix + 'pivot_ball' + suffix, 'pivotToe' : prefix + 'pivot_toe' + suffix, 'rotateToe' : prefix + 'rotate_toe' + suffix, 'pivotHeel' : prefix + 'pivot_heel' + suffix, } handles = control.getChildren(type='ikHandle') if len(handles) == 3: guide_ik, main_ik, end_ik = handles else: main_ik, end_ik = handles guide_ik = None toe_joint, heel_joint = foot_joint.getChildren( type='joint' )[:2] end_joint = toe_joint.getChildren( type='joint' )[0] toe_length = toe_joint.translate.get().length() heel_length = heel_joint.translate.get().length() pm.select( toe_joint, end_joint, r=1 ) toe_ik, toe_ee = pm.ikHandle( name=labels['ikToe'], sol='ikRPsolver', dh=1 ) # -- add pivot groups pivot_ball = createNurbsShape( labels['pivotBall'], shape='U', size=toe_length ) pivot_ball.translate.set( toe_joint.getRotatePivot(ws=1)/100 ) pivot_ball.ty.set( pivot_ball.ty.get() + toe_length/2 ) pivot_ball.rotate.set(-90,90,0) pm.makeIdentity(pivot_ball, apply=True, translate=True, rotate=True, scale=True) pivot_ball.setRotatePivot( toe_joint.getRotatePivot(ws=1), ws=1 ) if guide_ik: pm.parent( main_ik, guide_ik, pivot_ball ) else: pm.parent( main_ik, pivot_ball ) pivot_toe = createNurbsShape( labels['pivotToe'], shape='U', size=toe_length ) pivot_toe.translate.set( end_joint.getRotatePivot(ws=1)/100 ) pm.makeIdentity(pivot_toe, apply=True, translate=True, rotate=True, scale=True) pm.parent( pivot_ball, end_ik, pivot_toe ) rotate_toe = pm.group( toe_ik, n=labels['rotateToe'] ) rotate_toe.setRotatePivot( toe_joint.getRotatePivot(ws=1), ws=1 ) pivot_heel = createNurbsShape( labels['pivotHeel'], shape='U', size=heel_length ) pivot_heel.translate.set( heel_joint.getRotatePivot(ws=1)/100 ) pivot_heel.ry.set(180) pm.makeIdentity(pivot_heel, apply=True, translate=True, rotate=True, scale=True) pm.parent( pivot_toe, rotate_toe, pivot_heel ) pm.parent( pivot_heel, control ) exp_str = pm.expression( labels['expression'], query=1, s=1 ) # -- fill out the expression template exp_template += EXP_FOOT_IKFK exp_str += exp_template \ % { 'toe_ik' : toe_ik, 'end_ik' : end_ik } if footRollMode == FOOTROLL_AUTO: control.addAttr( "footRoll", sn="fr", at='double', k=1, dv=0, min=-10, max=20 ) control.addAttr( "toeRotate", sn="tr", at='double', k=1, dv=0 ) control.tr >> rotate_toe.rx # -- Set Driven Keys pm.setDrivenKeyframe( pivot_toe.rx, cd=control.fr, dv=10, v=0, ott='linear' ) pm.setDrivenKeyframe( pivot_toe.rx, cd=control.fr, dv=20, v=60, itt='linear' ) pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=0, v=0, ott='linear' ) pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=10, v=60, itt='linear' ) pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=20, v=0, itt='linear' ) pm.setDrivenKeyframe( pivot_heel.rx, cd=control.fr, dv=0, v=0, ott='linear' ) pm.setDrivenKeyframe( pivot_heel.rx, cd=control.fr, dv=-10, v=-40, itt='linear' ) elif footRollMode == FOOTROLL_CONTROLS: for obj in pm.ls( control, dag=1, type="nurbsCurve" ): addToSet( [obj.getParent()], 'controlsSet' ) exp_template += EXP_FOOT_IKFK exp_str += EXP_FOOT_IKFK_CONTROLS \ % { 'heel_pivot_shape' : pivot_heel.getShape(), 'ball_pivot_shape' : pivot_ball.getShape(), 'toe_pivot_shape' : pivot_toe.getShape(), 'end_ik' : end_ik } else: #footRollMode == FOOTROLL_ATTRIBUTES control.addAttr( "heelPivot", sn="hp", at='double', k=1, dv=0 ) control.addAttr( "ballPivot", sn="bp", at='double', k=1, dv=0 ) control.addAttr( "toePivot", sn="tp", at='double', k=1, dv=0 ) control.addAttr( "toeRotate", sn="tr", at='double', k=1, dv=0 ) control.hp >> pivot_heel.rx control.bp >> pivot_ball.rx control.tp >> pivot_toe.rx control.tr >> rotate_toe.rx for obj in pm.ls( control, dag=1, type="transform" ): shape = obj.getShape() if shape is not None: pm.reorder(shape, back=1) if obj != control: setAttrs( obj, ['t','s'], channelBox=0, keyable=0, lock=1 ) if footRollMode != FOOTROLL_CONTROLS: setAttrs( obj, ['r'], channelBox=1, keyable=0, lock=0 ) obj.visibility.set(0) obj.v.set( channelBox=0, keyable=0 ) pm.select( obj, r=1 ) pm.color( ud=(CntlColors.left, CntlColors.right)[side] ) pm.expression( labels['expression'], edit=1, s=exp_str )
def rigPage(skin, center, left, right, ctrl, pageName): '''This will do the actual page setup. takes lists of joints: skin, center, left, right the name of the ctrl and the desired attr name to add to the ctrl ''' #Variable Definitions driveName = ctrl+"."+pageName #Driven key tangent type inTangentType = 'linear' outTangentType = 'linear' #create new attr pm.addAttr(ctrl, ln=pageName, at="double", min=-10, max=10, dv=0) pm.setAttr(driveName, e=1, keyable=1) for j in range(len(skin)): #create a blend weighted node for translate x, y, z and rotate x, y, z rx = pm.createNode("blendWeighted", n=(skin[j]+"rx").replace("|", "_")) ry = pm.createNode("blendWeighted", n=(skin[j]+"ry").replace("|", "_")) rz = pm.createNode("blendWeighted", n=(skin[j]+"rz").replace("|", "_")) tx = pm.createNode("blendWeighted", n=(skin[j]+"tx").replace("|", "_")) ty = pm.createNode("blendWeighted", n=(skin[j]+"ty").replace("|", "_")) tz = pm.createNode("blendWeighted", n=(skin[j]+"tz").replace("|", "_")) '''blendWeighted is one of those nodes that don't work just yet. You need to assign a value to a certain attribute in order for the node to create it. The next section will create inputs and weights for translate x, y, z and rotate x, y, z ''' #create w[0] weight attributes rx.w[0].set(0) ry.w[0].set(0) rz.w[0].set(0) tx.w[0].set(0) ty.w[0].set(0) tz.w[0].set(0) #create w[1] weight attributes rx.w[1].set(0) ry.w[1].set(0) rz.w[1].set(0) tx.w[1].set(0) ty.w[1].set(0) tz.w[1].set(0) #create w[2] weight attributes rx.w[2].set(0) ry.w[2].set(0) rz.w[2].set(0) tx.w[2].set(0) ty.w[2].set(0) tz.w[2].set(0) #create i[0] input attributes rx.i[0].set(0) ry.i[0].set(0) rz.i[0].set(0) tx.i[0].set(0) ty.i[0].set(0) tz.i[0].set(0) #create i[1] input attributes rx.i[1].set(0) ry.i[1].set(0) rz.i[1].set(0) tx.i[1].set(0) ty.i[1].set(0) tz.i[1].set(0) #create i[2] input attributes rx.i[2].set(0) ry.i[2].set(0) rz.i[2].set(0) tx.i[2].set(0) ty.i[2].set(0) tz.i[2].set(0) #connect target joints to blendweights left[j].rx.connect(rx.i[0]) left[j].ry.connect(ry.i[0]) left[j].rz.connect(rz.i[0]) center[j].rx.connect(rx.i[1]) center[j].ry.connect(ry.i[1]) center[j].rz.connect(rz.i[1]) right[j].rx.connect(rx.i[2]) right[j].ry.connect(ry.i[2]) right[j].rz.connect(rz.i[2]) left[j].tx.connect(tx.i[0]) left[j].ty.connect(ty.i[0]) left[j].tz.connect(tz.i[0]) center[j].tx.connect(tx.i[1]) center[j].ty.connect(ty.i[1]) center[j].tz.connect(tz.i[1]) right[j].tx.connect(tx.i[2]) right[j].ty.connect(ty.i[2]) right[j].tz.connect(tz.i[2]) #connect blendweights to their respective connections rx.o.connect(skin[j].rx) ry.o.connect(skin[j].ry) rz.o.connect(skin[j].rz) tx.o.connect(skin[j].tx) ty.o.connect(skin[j].ty) tz.o.connect(skin[j].tz) #set driven keys on blendweights pm.setDrivenKeyframe(rx.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=1) pm.setDrivenKeyframe(ry.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=1) pm.setDrivenKeyframe(rz.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=1) pm.setDrivenKeyframe(rx.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(ry.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(rz.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(rx.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(ry.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(rz.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(rx.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(ry.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(rz.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(rx.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=1) pm.setDrivenKeyframe(ry.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=1) pm.setDrivenKeyframe(rz.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=1) pm.setDrivenKeyframe(rx.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(ry.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(rz.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(rx.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(ry.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(rz.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(rx.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(ry.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(rz.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(rx.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=1) pm.setDrivenKeyframe(ry.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=1) pm.setDrivenKeyframe(rz.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=1) pm.setDrivenKeyframe(tx.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=1) pm.setDrivenKeyframe(ty.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=1) pm.setDrivenKeyframe(tz.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=1) pm.setDrivenKeyframe(tx.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(ty.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(tz.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(tx.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(ty.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(tz.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=-10, v=0) pm.setDrivenKeyframe(tx.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(ty.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(tz.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(tx.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=1) pm.setDrivenKeyframe(ty.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=1) pm.setDrivenKeyframe(tz.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=1) pm.setDrivenKeyframe(tx.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(ty.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(tz.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=0, v=0) pm.setDrivenKeyframe(tx.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(ty.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(tz.w[0], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(tx.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(ty.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(tz.w[1], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=0) pm.setDrivenKeyframe(tx.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=1) pm.setDrivenKeyframe(ty.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=1) pm.setDrivenKeyframe(tz.w[2], itt=inTangentType, ott=outTangentType, cd=driveName, dv=10, v=1)
def setupFKControls(self, *args): """ Create FK controllers """ #shoulder temp = pm.PyNode(pm.circle(nr=self.normal, r=self.radius)[0]) pm.parent(temp, self.fkChain[0]) #Parent transform under fk joint pm.move(0, 0, 0, temp) #Zero it so it snaps to FK position/orientation pm.parent(temp.getShape(), self.fkChain[0], s=True, r=True) #Parent shape to joints transform pm.delete(temp) #Delete empty transform #elbow temp = pm.PyNode(pm.circle(nr=self.normal, r=self.radius)[0]) pm.parent(temp, self.fkChain[1]) #Parent transform under fk joint pm.move(0, 0, 0, temp) #Zero it so it snaps to FK position/orientation pm.parent(temp.getShape(), self.fkChain[1], s=True, r=True) #Parent shape to joints transform pm.delete(temp) #Delete empty transform #wrist temp = pm.PyNode(pm.circle(nr=self.normal, r=self.radius)[0]) pm.parent(temp, self.fkChain[2]) #Parent transform under fk joint pm.move(0, 0, 0, temp) #Zero it so it snaps to FK position/orientation pm.parent(temp.getShape(), self.fkChain[2], s=True, r=True) #Parent shape to joints transform pm.delete(temp) #Delete empty transform # # FK Length attributes setup/ Done using the translates of the child to avoid skewing that # occurs with scaling in a non-uniform manner (1,2,1) # pm.addAttr(self.fkChain[0], ln='length', min=0, dv=1, k=True) pm.addAttr(self.fkChain[1], ln='length', min=0, dv=1, k=True) #Get current translates value to set the max SDK as twice the default length val1 = pm.getAttr('%s.translate%s' % (self.fkChain[1], self.aim)) val2 = pm.getAttr('%s.translate%s' % (self.fkChain[2], self.aim)) #SDK to connect them pm.setDrivenKeyframe(self.fkChain[1], cd='%s.length' % self.fkChain[0], at='translate%s' % self.aim, dv=1) #Set default with current value in .tx pm.setDrivenKeyframe(self.fkChain[1], cd='%s.length' % self.fkChain[0], at='translate%s' % self.aim, dv=0, v=0) #Set min pm.setDrivenKeyframe(self.fkChain[1], cd='%s.length' % self.fkChain[0], at='translate%s' % self.aim, dv=2, v=(val1 * 2)) #Set max pm.setDrivenKeyframe(self.fkChain[2], cd='%s.length' % self.fkChain[1], at='translate%s' % self.aim, dv=1) #Set default with current value in .tx pm.setDrivenKeyframe(self.fkChain[2], cd='%s.length' % self.fkChain[1], at='translate%s' % self.aim, dv=0, v=0) #Set min pm.setDrivenKeyframe(self.fkChain[2], cd='%s.length' % self.fkChain[1], at='translate%s' % self.aim, dv=2, v=(val2 * 2))#Set max
def ikLimb( self, *args ): print 'ehm_leg........................ikLimb' #=============================================================================== # duplicate main leg joints and rename IK joints self.IKJnts = pm.duplicate (self.upLegJnt ) pm.select (self.IKJnts[0]) self.IKJnts = SearchReplaceNames ( "jnt", "IK_jnt", self.IKJnts[0] ) #=============================================================================== # create ik handles self.legIKStuff = pm.ikHandle( sj = self.IKJnts[0], ee = self.IKJnts[2], solver = "ikRPsolver" ) pm.rename (self.legIKStuff[0] , (self.side + "_leg_ikh") ) #=============================================================================== # distance nodes for stretching purpose self.IKLegDist = pm.distanceDimension ( sp = self.upLegPos , ep = self.anklePos ) self.IKupLegDist = pm.distanceDimension ( sp = self.upLegPos , ep = self.kneePos ) self.IKKneeDist = pm.distanceDimension ( sp = self.kneePos , ep = self.anklePos ) self.IKLegDistT = pm.listRelatives ( self.IKLegDist , p=True)[0] self.IKupLegDistT = pm.listRelatives ( self.IKupLegDist , p=True)[0] self.IKKneeDistT = pm.listRelatives ( self.IKKneeDist , p=True)[0] #=============================================================================== # find the leg locs from distance shape node self.IKlegDistLocs = pm.listConnections (self.IKLegDist , plugs=False) self.IKKneeDistLocs = pm.listConnections (self.IKKneeDist , plugs=False) pm.rename (self.IKlegDistLocs[0] , self.side + "_upLeg_dist_loc" ) pm.rename (self.IKlegDistLocs[1] , self.side + "_ankle_dist_loc" ) pm.rename (self.IKKneeDistLocs[0] , self.side + "_knee_dist_loc" ) #=============================================================================== # parent ikHandle to ankle loc pm.parent ( self.legIKStuff[0] , self.IKKneeDistLocs[1] ) #=============================================================================== # make ik joints stretchy defaultIKLegLen = pm.getAttr ( self.IKupLegDist.distance ) + pm.getAttr ( self.IKKneeDist.distance ) self.IKLeg_stretch_mdn = pm.createNode ("multiplyDivide" , n = self.side + "_IKLeg_stretch_mdn" ) pm.setAttr ( self.IKLeg_stretch_mdn.input2X, defaultIKLegLen ) self.IKLegDist.distance >> self.IKLeg_stretch_mdn.input1X pm.setAttr ( self.IKLeg_stretch_mdn.operation, 2 ) self.IKLeg_stretch_cnd = pm.createNode ("condition" , n = self.side + "_IKLeg_stretch_cnd") self.IKLegDist.distance >> self.IKLeg_stretch_cnd.firstTerm pm.setAttr ( self.IKLeg_stretch_cnd.secondTerm , defaultIKLegLen ) pm.setAttr ( self.IKLeg_stretch_cnd.operation , 2 ) self.IKLeg_stretch_mdn.outputX >> self.IKLeg_stretch_cnd.colorIfTrueR #================================================================================ # Knee Lock pm.addAttr ( self.IKKneeDistLocs[0] ,dv = 0 ,min=0 ,max=10 , keyable = True , ln = "kneeLock" , at = "double") defaultIKupLegLen = pm.getAttr ( self.IKupLegDist.distance ) self.IKupLeg_kneeLock_mdn = pm.createNode ("multiplyDivide" , n = self.side + "_IKupLeg_kneeLock_mdn" ) pm.setAttr ( self.IKupLeg_kneeLock_mdn.input2X, defaultIKupLegLen ) self.IKupLegDist.distance >> self.IKupLeg_kneeLock_mdn.input1X pm.setAttr ( self.IKupLeg_kneeLock_mdn.operation, 2 ) defaultIKKneeLen = pm.getAttr ( self.IKKneeDist.distance ) self.IKKnee_kneeLock_mdn = pm.createNode ("multiplyDivide" , n = self.side + "_IKKnee_kneeLock_mdn" ) pm.setAttr ( self.IKKnee_kneeLock_mdn.input2X, defaultIKKneeLen ) self.IKKneeDist.distance >> self.IKKnee_kneeLock_mdn.input1X pm.setAttr ( self.IKKnee_kneeLock_mdn.operation, 2 ) #================================================================================ # make kneeLock more animation friendly by dividing it by 10 self.IKLeg_kneeLockAnimFriend_mdn = pm.createNode ("multiplyDivide" , n = self.side + "_IKLeg_kneeLockAnimFriend_mdn" ) pm.setAttr ( self.IKLeg_kneeLockAnimFriend_mdn.input2X, 10 ) pm.setAttr ( self.IKLeg_kneeLockAnimFriend_mdn.operation, 2 ) self.IKKneeDistLocs[0].attr ( "kneeLock" ) >> self.IKLeg_kneeLockAnimFriend_mdn.input1X #================================================================================ # conncet result of stretch and knee lock to joint with a blend switch on the knee locator self.upLeg_stretchKneeLock_bta = pm.createNode ("blendTwoAttr" , n = self.side + "_upLeg_stretchKneeLock_bta" ) self.IKLeg_kneeLockAnimFriend_mdn.outputX >> self.upLeg_stretchKneeLock_bta.attributesBlender self.IKLeg_stretch_cnd.outColorR >> self.upLeg_stretchKneeLock_bta.input[0] self.IKupLeg_kneeLock_mdn.outputX >> self.upLeg_stretchKneeLock_bta.input[1] self.knee_stretchKneeLock_bta = pm.createNode ("blendTwoAttr" , n = self.side + "_knee_stretchKneeLock_bta" ) self.IKLeg_kneeLockAnimFriend_mdn.outputX >> self.knee_stretchKneeLock_bta.attributesBlender self.IKLeg_stretch_cnd.outColorR >> self.knee_stretchKneeLock_bta.input[0] self.IKKnee_kneeLock_mdn.outputX >> self.knee_stretchKneeLock_bta.input[1] self.upLeg_stretchKneeLock_bta.output >> self.IKJnts[0].scaleX self.knee_stretchKneeLock_bta.output >> self.IKJnts[1].scaleX #================================================================================ # force leg distance dimentions to be scalable by mainCtrl DistGlobalScale (mainCtrl=self.mainCtrl , dist=self.IKLegDist) DistGlobalScale (mainCtrl=self.mainCtrl , dist=self.IKupLegDist) DistGlobalScale (mainCtrl=self.mainCtrl , dist=self.IKKneeDist) # create IK ankle control curve with transforms of the ankle joint self.ankleIKCtrl = CubeCrv( self.legSize*1.5 , self.side + "_ankle_IK_ctrl" ) pm.select ( self.ankleIKCtrl ) self.ankleIKCtrlZero = ZeroGrp()[0] pm.parent ( self.ankleIKCtrlZero , self.IKJnts[2] ) self.ankleIKCtrlZero.translate.set( 0,0,0 ) # self.ankleIKCtrlZero.rotate.set( 0,0,0 ) pm.parent ( self.ankleIKCtrlZero , w=True ) pm.parent ( self.IKlegDistLocs[1] , self.ankleIKCtrl ) #============================================================================ # add attributes to leg_ctrl pm.addAttr ( self.ankleIKCtrl , ln = "stretch_off_on" , at = "double" , min = 0 , max = 1 , dv = 1 , k = True ) pm.addAttr ( self.ankleIKCtrl , ln = "roll" , at = "double" , min = -10 , max = 10 , dv = 0 , k = True ) pm.addAttr ( self.ankleIKCtrl , ln = "toe" , at = "double" , min = -10 , max = 10 , dv = 0 , k = True ) pm.addAttr ( self.ankleIKCtrl , ln = "side_to_side" , at = "double" , min = -10 , max = 10 , dv = 0 , k = True ) #============================================================================ # create foot ik handles self.toeIKStuff = pm.ikHandle( sj = self.IKJnts[2], ee = self.IKJnts[3], solver = "ikSCsolver" ) pm.rename(self.toeIKStuff[0], self.side + "_toe_ikh") self.toeEndIKStuff = pm.ikHandle( sj = self.IKJnts[3], ee = self.IKJnts[4], solver = "ikSCsolver" ) pm.rename(self.toeEndIKStuff[0], "_toe_end_ikh") #============================================================================ # foot ik groups and set driven keys self.heelUpSdk = pm.group ( self.toeIKStuff[0] , self.IKlegDistLocs[1] , n = self.side + "_heel_up_sdk" ) pm.xform ( os= True , piv = self.toePos ) self.toeSdk = pm.group( self.toeEndIKStuff[0] , n = self.side + "_toe_sdk" ) pm.xform ( os= True , piv = self.toePos ) self.tipSdk = pm.group ( self.heelUpSdk , self.toeSdk , n = self.side + "_tip_sdk" ) pm.xform ( os= True , piv = ( self.toeEndPos[0] , 0 , self.toeEndPos[2] ) ) self.heelSdk = pm.group ( self.tipSdk , n = self.side + "_heel_sdk" ) pm.xform ( os= True , piv = ( self.heelPos[0] , 0 , self.heelPos[2] ) ) self.inFootSdk = pm.group ( self.heelSdk, n = self.side + "_in_foot_sdk" ) pm.xform ( os= True , piv = ( self.inPivPos[0] , 0 , self.inPivPos[2] ) ) self.outFootSdk = pm.group ( self.inFootSdk , n = self.side + "_out_foot_sdk" ) pm.xform ( os= True , piv = ( self.outPivPos[0] , 0 , self.outPivPos[2] ) ) pm.parent ( self.outFootSdk , self.ankleIKCtrl ) #============================================================================ # foot set driven keys # toe set driven keys pm.setDrivenKeyframe ( self.toeSdk.rotateX , currentDriver = self.ankleIKCtrl.toe , dv = 0 , v = 0 ) pm.setDrivenKeyframe ( self.toeSdk.rotateX , currentDriver = self.ankleIKCtrl.toe , dv = 10 , v = -45 ) pm.setDrivenKeyframe ( self.toeSdk.rotateX , currentDriver = self.ankleIKCtrl.toe , dv = -10 , v = 70 ) # roll set driven keys pm.setDrivenKeyframe ( self.heelSdk.rotateX , currentDriver = self.ankleIKCtrl.roll , dv = 0 , v = 0 ) pm.setDrivenKeyframe ( self.tipSdk.rotateX , currentDriver = self.ankleIKCtrl.roll , dv = 0 , v = 0 ) pm.setDrivenKeyframe ( self.heelUpSdk.rotateX , currentDriver = self.ankleIKCtrl.roll , dv = 0 , v = 0 ) pm.setDrivenKeyframe ( self.heelSdk.rotateX , currentDriver = self.ankleIKCtrl.roll , dv = 10 , v = -30 ) pm.setDrivenKeyframe ( self.tipSdk.rotateX , currentDriver = self.ankleIKCtrl.roll , dv = -10 , v = 45 ) pm.setDrivenKeyframe ( self.heelUpSdk.rotateX , currentDriver = self.ankleIKCtrl.roll , dv = -10 , v = 0 ) pm.setDrivenKeyframe ( self.tipSdk.rotateX , currentDriver = self.ankleIKCtrl.roll , dv = -5 , v = 0 ) pm.setDrivenKeyframe ( self.heelUpSdk.rotateX , currentDriver = self.ankleIKCtrl.roll , dv = -5 , v = 30 ) #================================================================================ # create IK knee control curve self.kneeIKCtrl = SoftSpiralCrv( self.legSize , self.side + "_knee_IK_ctrl" ) if self.side == "R" : self.kneeIKCtrl.scale.scaleY.set (-1) pm.makeIdentity (self.kneeIKCtrl , apply = True , t = 1 , r = 1 , s = 1 , n = 0) pm.select ( self.kneeIKCtrl ) self.kneeIKCtrlZO = ZeroGrp() pm.parent ( self.kneeIKCtrlZO[0] , self.IKJnts[1] ) self.kneeIKCtrlZO[0].translate.set( 0,0,0 ) #self.kneeIKCtrlZO[0].rotate.set( 0,0,0 ) pm.parent ( self.kneeIKCtrlZO[0] , w=True ) pm.parent ( self.IKKneeDistLocs[0] , self.kneeIKCtrl ) # direction of the knee ctrl is defined here. ???????????????????????????????? self.kneeIKCtrlZO[1].translate.set (0,0, self.legSize*3) pm.poleVectorConstraint( self.IKKneeDistLocs[0] , self.legIKStuff[0] ) #=========== # pv guide curve self.PVGuideCrv = pm.curve ( d = 1 , p = ( (self.kneePos) , (0,0,0 ) ) , k = (1,2) , name = self.side + "_PV_guide_crv" ) self.PVGuideStartJnt =pm.joint ( p = (self.kneePos) , name = ( self.side + "_PV_guide_start_jnt" ) ) pm.select (cl=True) self.PVGuideEndJnt =pm.joint ( p = (0,0,0) , name = ( self.side + "_PV_guide_end_jnt" ) ) pm.skinCluster( self.PVGuideCrv , self.PVGuideStartJnt , self.PVGuideEndJnt , toSelectedBones = True ) pm.parent (self.PVGuideEndJnt , self.kneeIKCtrl) self.PVGuideEndJnt.translate.set(0,0,0) pm.setAttr ( self.PVGuideCrv.overrideEnabled , True) pm.setAttr ( self.PVGuideCrv.overrideDisplayType , True) pm.setAttr ( self.PVGuideCrv.inheritsTransform , False) LockHideAttr ( objs=self.PVGuideStartJnt , attrs="vv") LockHideAttr ( objs=self.PVGuideEndJnt , attrs="vv") #================================================================================ # if just ik leg is needed then delete leg joints and us ik joints as leg joints # this way we won't have extra result joint, just ik joints will remain in the scene if self.FKIKMode == "IK" : pm.delete (self.upLegJnt) self.upLegJnt = self.IKJnts[0] self.kneeJnt = self.IKJnts[1] self.ankleJnt = self.IKJnts[2] self.toeJnt = self.IKJnts[3]
""" With influences point constrained to curves setup: - Create duplicate of the curve - Name the duplicate based on prefix input by user - Crete blendshape named using prefix - SDK to multiAxis attr """ import pymel.core as pm multiAxisAttr = "rt_shoulder_jacket_inf_cnt.RtShldr_u" crv = pm.ls(sl=1)[0] name = crv.name().replace("_curve", "_back_crv") dup = pm.duplicate(crv)[0] dup.rename(name) bs = pm.blendShape(dup, crv, n="%sBS" % name)[0] # off pm.setDrivenKeyframe(bs, at="%s" % name, cd=multiAxisAttr, dv=0.5, v=0) # on pm.setDrivenKeyframe(bs, at="%s" % name, cd=multiAxisAttr, dv=1, v=1)
def rig_objectAcrossSurface(surface, global_CTRL, module, numObjs, numCtrls, uv, fk=True, customMinorCurve=None, customMajorCurve=None, obj=None, spaces=None): ''' rig_objectAcrossSurface(pm.ls(sl=True)[0], pm.PyNode("global_CTRL"), "stem", 8, 10, 1) ''' moduleGrp=pm.group(em=True,n=module+'_module_GRP') skeletonGrp=pm.group(em=True,n=module+'_skeleton_GRP',p=moduleGrp) ctrlGrp=pm.group(em=True,n=module+'_ctrl_GRP',p=moduleGrp) partsGrp=pm.group(em=True,n=module+'_parts_GRP',p=moduleGrp) folicleGrp=pm.group(em=True,n=module+'_fol_GRP',p=partsGrp) tweakJntGrp=pm.group(em=True,n=module+'_tweakSkeleton_GRP',p=skeletonGrp) bindJntGrp=pm.group(em=True,n=module+'_bindSkeleton_GRP',p=skeletonGrp) tweakCtrlGrp=pm.group(em=True,n=module+'_tweakCtrl_GRP',p=ctrlGrp) partsGrp.visibility.set(0) tweakJntGrp.visibility.set(0) global_CTRL.skeletonType.connect(skeletonGrp.overrideDisplayType) global_CTRL.controlType.connect(ctrlGrp.overrideDisplayType) ctrlGrp.overrideEnabled.set(1) skeletonGrp.overrideEnabled.set(1) moduleGrp.addAttr('controlsDisplay', k=True, at='long',min=0,max=2,dv=1) moduleGrp.addAttr('skeletonDisplay', k=True, at='long',min=0,max=1,dv=0) moduleGrp.controlsDisplay.connect(ctrlGrp.visibility) moduleGrp.skeletonDisplay.connect(skeletonGrp.visibility) pm.setDrivenKeyframe(tweakCtrlGrp, currentDriver=moduleGrp.name()+'.controlsDisplay', at='visibility', driverValue=0, value=0) pm.setDrivenKeyframe(tweakCtrlGrp, currentDriver=moduleGrp.name()+'.controlsDisplay', at='visibility', driverValue=1, value=0) pm.setDrivenKeyframe(tweakCtrlGrp, currentDriver=moduleGrp.name()+'.controlsDisplay', at='visibility', driverValue=2, value=1) #default to a joint to duplicate across tweakJointChain=[] if obj == None: tweakJnt = pm.joint(n='%s_JNT'%module) tweakJointChain.append(tweakJnt) #take an input of a nurbs surface #creates tweak controls for i in range(0,numObjs): alphabet=string.ascii_uppercase #make x follicles down the v or u (toggleable) if uv == 0: oFoll = create_follicle(surface, i/(numObjs-1.00), 0.5) if uv == 1: oFoll = create_follicle(surface, 0.5, i/(numObjs-1.00)) oFoll.getParent().rename('_'.join([surface+alphabet[i],'FOL'])) #make x joints down the surface, parent then set translate to zero (should be separate) tweakJntDup = pm.duplicate(tweakJnt, n='_'.join([tweakJnt.name()+alphabet[i],'DUP']) ) tweakJntDup[0].translate.set( oFoll.outTranslate.get() ) tweakJntDup[0].rotate.set( oFoll.outRotate.get() ) #make x controllers down surface at the same time ctrl = rig_makeCtrl( n=tweakJnt.name()+alphabet[i], curve=customMinorCurve) #drive the controller's offsets by the follicle oFoll.outTranslate.connect(ctrl[0].translate) oFoll.outRotate.connect(ctrl[0].rotate) #drive the joint's position by a parent constraint to the controller pm.parentConstraint(ctrl[2], tweakJntDup[0], mo=True) #Finalize parenting oFoll.getParent().setParent(folicleGrp) ctrl[0].setParent(tweakCtrlGrp) tweakJntDup[0].setParent(tweakJntGrp) tweakJointChain.append(tweakJntDup[0]) #creating primary controls skinJnt='' primaryControls=[] for j in range(0,numCtrls): alphabet=string.ascii_uppercase #make x follicles down the v or u (toggleable) if uv == 0: oFoll = create_follicle(surface, j/(numCtrls-1.00), 0.5) if uv == 1: oFoll = create_follicle(surface, 0.5, j/(numCtrls-1.00)) #make y joints down surface using one point on surface node over and over (should be a joint chain) jnt=pm.joint(p=oFoll.outTranslate.get(), orientation=oFoll.outRotate.get(), n=module+alphabet[j]+'_JNT') jnt.setParent(w=True) jnt.visibility.set(0) #make y controllers down surface at the same time (should be a hierarchy) ctrl = rig_makeCtrl( n=module+alphabet[j], curve=customMajorCurve ) ctrl[0].translate.set( oFoll.outTranslate.get() ) ctrl[0].rotate.set( oFoll.outRotate.get() ) pm.delete(oFoll.getParent()) if not j==0: jnt.setParent(module+alphabet[j-1]+'_JNT') ctrl[0].setParent(module+alphabet[j-1]+'Con_GRP') skinJnt = jnt else: jnt.setParent(skeletonGrp) ctrl[0].setParent(ctrlGrp) primaryControls.append(ctrl[1]) #if fk==False: # ctrl[0].inheritsTransform.set(0) #drive the y joints by the y controllers pm.parentConstraint(ctrl[2], jnt) #setup spaceSwitching if spaces: for primaryControl in primaryControls: previousControl = module+alphabet[j-1]+'Con_GRP' primaryControl.addAttr('space', at="enum", k=True, en="parent:world", dv=0) if pm.objExists(previousControl): previousControl = pm.PyNode(previousControl) else: previousControl = spaces[0] constraint = pm.parentConstraint(spaces[0], primaryControl.getParent(), mo=True) weightAttrs = constraint.getWeightAliasList() primaryControl.space.connect(weightAttrs[0]) #finally dup out the tweakJoints, parent them then drive with an ikspline created from all the tweak joint positions splineCRV = buildCurveNode(tweakJointChain[1:], module) bindJoints = jnt_buildChainFromTransforms(tweakJointChain[1:], 'skinBnd', 'JNT') ikHandle = pm.ikHandle(sol='ikSplineSolver', ccv=False, pcv=False, snc=True, ns=4, c=splineCRV, startJoint=bindJoints[0], ee=bindJoints[len(bindJoints)-1]) ikHandle[0].setParent(partsGrp) splineCRV.setParent(partsGrp) bindJoints[0].setParent(bindJntGrp) ikHandle[0].inheritsTransform.set(0) splineCRV.inheritsTransform.set(0) #skin the surface by the y joints pm.skinCluster(surface, skinJnt, dr=6) return moduleGrp
def create(self): self.nodes = [] #------------------------------ # # Create Ctrler # #------------------------------ self.root_grp = pm.group( n='TwistHelper_grp', em=True) self.constMe_to_parent = pm.group( n='constMe_to_parent', em=True) self.constMe_to_start = pm.group( n='constMe_to_start', em=True) self.constMe_to_mid = pm.group( n='constMe_to_mid', em=True ) self.constMe_to_end = pm.group( n='constMe_to_end', em=True) self.doNotTouch_grp = pm.group( n='doNotTouch_grp', em=True) pm.parent( self.constMe_to_start, self.constMe_to_mid, self.constMe_to_end, self.constMe_to_parent) pm.parent( self.constMe_to_parent, self.doNotTouch_grp, self.root_grp ) self.start_T_anim = pm.group( n='start_T_anim', em=True) self.end_T_anim = pm.group( n='end_T_anim', em=True) pm.parent( self.start_T_anim, self.constMe_to_start ) pm.parent( self.end_T_anim, self.constMe_to_end ) self.mid_T_anim = pm.group( n='mid_T_anim', em=True ) self.mid1_T_anim = pm.group( n='mid1_T_anim', em=True ) self.mid2_T_anim = pm.group( n='mid2_T_anim', em=True ) pm.parent( self.mid1_T_anim, self.mid2_T_anim, self.mid_T_anim ) pm.parent( self.mid_T_anim, self.constMe_to_mid ) self.start_R_result = pm.group( n='start_R_result', em=True) self.start_up_anim = pm.group( n='start_up_anim', em=True) pm.parent( self.start_R_result, self.start_up_anim, self.start_T_anim ) self.end_R_result = pm.group( n='end_R_result', em=True) self.end_up_anim = pm.group( n='end_up_anim', em=True) pm.parent( self.end_R_result, self.end_up_anim, self.end_T_anim ) self.doNotTouch_grp.v.set(False) # 어트리뷰트 잠금 self._lockAndHideAttr([self.start_up_anim, self.end_up_anim],['rx','ry','rz','sx','sy','sz']) self._lockAndHideAttr([self.constMe_to_start, self.constMe_to_mid, self.constMe_to_end, self.mid_T_anim, self.constMe_to_parent],['sx','sy','sz','v']) self._lockAndHideAttr([self.start_R_result, self.end_R_result],['sx','sy','sz','v']) self._lockAndHideAttr([self.start_T_anim, self.end_T_anim, self.mid1_T_anim, self.mid2_T_anim],['rx','ry','rz','sx','sy','sz','v']) self._lockAndHideAttr([self.doNotTouch_grp, self.root_grp],['tx','ty','tz','rx','ry','rz','sx','sy','sz']) self.nodes.extend([self.root_grp, self.constMe_to_parent, self.constMe_to_start, self.constMe_to_mid, self.constMe_to_end, self.doNotTouch_grp, self.start_T_anim, self.end_T_anim, self.mid_T_anim, self.mid1_T_anim, self.mid2_T_anim, self.start_R_result, self.start_up_anim]) self.nodes.extend([self.end_R_result, self.end_up_anim]) #------------------------------ # # config Attribute # #------------------------------ ctrl = self.root_grp ctrl.addAttr('aimAxis', at='enum', en='PositiveX:NegativeX:', keyable=False) # IK핸들의 Advanced Twist Controls 세팅이 -x축은 고려되어 있지 않음. 의미 없음. ctrl.addAttr('aimVector', at='double3') ctrl.addAttr('aimVectorX', at='double', p='aimVector', keyable=False) ctrl.addAttr('aimVectorY', at='double', p='aimVector', keyable=False) ctrl.addAttr('aimVectorZ', at='double', p='aimVector', keyable=False) ctrl.addAttr('upAxis', at='enum', en='PositiveY:NegativeY:ClosetY:PositiveZ:NegativeZ:ClosetZ:', keyable=True) ctrl.addAttr('upVector', at='double3') ctrl.addAttr('upVectorX', at='double', p='upVector', keyable=True) ctrl.addAttr('upVectorY', at='double', p='upVector', keyable=True) ctrl.addAttr('upVectorZ', at='double', p='upVector', keyable=True) ctrl.addAttr('startWorldUpVector', at='double3') ctrl.addAttr('startWorldUpVectorX', at='double', p='startWorldUpVector', keyable=True) ctrl.addAttr('startWorldUpVectorY', at='double', p='startWorldUpVector', keyable=True) ctrl.addAttr('startWorldUpVectorZ', at='double', p='startWorldUpVector', keyable=True) ctrl.addAttr('endWorldUpVector', at='double3') ctrl.addAttr('endworldUpVectorX', at='double', p='endWorldUpVector', keyable=True) ctrl.addAttr('endworldUpVectorY', at='double', p='endWorldUpVector', keyable=True) ctrl.addAttr('endworldUpVectorZ', at='double', p='endWorldUpVector', keyable=True) ctrl.aimVector.set(self.aimVector) ctrl.upVector.set(self.upVector) ctrl.startWorldUpVector.set(self.startWorldUpVector) ctrl.endWorldUpVector.set(self.endWorldUpVector) pm.setDrivenKeyframe( ctrl.aimVectorX, value= 1, currentDriver=ctrl.aimAxis, driverValue=0 ) # positiveX pm.setDrivenKeyframe( ctrl.aimVectorY, value= 0, currentDriver=ctrl.aimAxis, driverValue=0 ) # positiveX pm.setDrivenKeyframe( ctrl.aimVectorZ, value= 0, currentDriver=ctrl.aimAxis, driverValue=0 ) # positiveX pm.setDrivenKeyframe( ctrl.aimVectorX, value=-1, currentDriver=ctrl.aimAxis, driverValue=1 ) # negativeX pm.setDrivenKeyframe( ctrl.aimVectorY, value= 0, currentDriver=ctrl.aimAxis, driverValue=1 ) # negativeX pm.setDrivenKeyframe( ctrl.aimVectorZ, value= 0, currentDriver=ctrl.aimAxis, driverValue=1 ) # negativeX pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=0 ) # positiveY pm.setDrivenKeyframe( ctrl.upVectorY, value= 1, currentDriver=ctrl.upAxis, driverValue=0 ) # positiveY pm.setDrivenKeyframe( ctrl.upVectorZ, value= 0, currentDriver=ctrl.upAxis, driverValue=0 ) # positiveY pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=1 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorY, value=-1, currentDriver=ctrl.upAxis, driverValue=1 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorZ, value= 0, currentDriver=ctrl.upAxis, driverValue=1 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=2 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorY, value= 1, currentDriver=ctrl.upAxis, driverValue=2 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorZ, value= 0, currentDriver=ctrl.upAxis, driverValue=2 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ pm.setDrivenKeyframe( ctrl.upVectorY, value= 0, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ pm.setDrivenKeyframe( ctrl.upVectorZ, value= 1, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=4 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorY, value= 0, currentDriver=ctrl.upAxis, driverValue=4 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorZ, value=-1, currentDriver=ctrl.upAxis, driverValue=4 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=5 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorY, value= 0, currentDriver=ctrl.upAxis, driverValue=5 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorZ, value= 1, currentDriver=ctrl.upAxis, driverValue=5 ) # negativeZ ctrl.setAttr('upVectorX', keyable=False ) ctrl.setAttr('upVectorY', keyable=False ) ctrl.setAttr('upVectorZ', keyable=False ) # # # base Curve # # crv = pm.curve( n='base_crv', d=3, p=[(0,0,0),(0,0,0),(0,0,0),(0,0,0)], k=[0,0,0,1,1,1] ) pm.parent( crv, self.doNotTouch_grp ) crv.it.set(False) self.nodes.append(crv) # create curve cv clusters start_crv_clst = pm.cluster( crv.cv[0], wn=(self.start_T_anim,self.start_T_anim) )[0] mid1_crv_clst = pm.cluster( crv.cv[1], wn=(self.mid1_T_anim, self.mid1_T_anim) )[0] mid2_crv_clst = pm.cluster( crv.cv[2], wn=(self.mid2_T_anim, self.mid2_T_anim) )[0] end_crv_clst = pm.cluster( crv.cv[3], wn=(self.end_T_anim, self.end_T_anim) )[0] self.nodes.extend([start_crv_clst,mid1_crv_clst,mid2_crv_clst,end_crv_clst]) # # 초기위치 # self.start_up_anim.t.set( self.upVector * 10) self.end_up_anim .t.set( self.upVector * 10) self.constMe_to_end.t.set( self.aimVector * 10) pm.delete( pm.pointConstraint(self.start_T_anim, self.end_T_anim, self.constMe_to_mid) ) pm.delete( pm.pointConstraint(self.mid_T_anim, self.start_T_anim, self.mid1_T_anim) ) pm.delete( pm.pointConstraint(self.mid_T_anim, self.end_T_anim, self.mid2_T_anim) ) # # # rebuild curve for distribute # # # 커브 리빌드, 익스텐드 rbdCrv, rbd = pm.rebuildCurve( crv, ch=True, replaceOriginal=False, rebuildType=0, # uniform endKnots=1, # 0 - uniform end knots, 1 - multiple end knots keepRange=0, # 0 - reparameterize the resulting curve from 0 to 1, 1 - keep the original curve parameterization, 2 - reparameterize the result from 0 to number of spans keepControlPoints=False, keepEndPoints=True, keepTangents=True, spans=100, degree=3, tol=0.001 ) rdbCrv, extCrv = pm.extendCurve( rbdCrv, cos=0, ch=1, jn=True, rmk=True, rpo=True, distance = 1, start=0, # 0 - end, 1 - start, 2 - both extendMethod=0, # 0 - based on distance, 2 - to a 3D point extensionType=0, # 0 - Linear, 1 - Circular, 2 - Extrapolate ) rdbCrv.rename('rbdExtnd_crv') pm.parent( rdbCrv, self.doNotTouch_grp ) rdbCrv.it.set(False) # extend crv Locator crvEnd_loc = pm.spaceLocator(n='extCrvEnd_loc') pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=2.0, ch=True ) ) pntOnCrv.position >> crvEnd_loc.t pm.parent( crvEnd_loc, self.doNotTouch_grp ) self.nodes.extend([ rbdCrv, rbd,extCrv, crvEnd_loc]) # # Cluster & Constraint # # constraint Rig start_aimConst = pm.aimConstraint( self.end_T_anim, self.start_R_result, aim=self.aimVector, u=self.upVector, wu=self.startWorldUpVector, wut='object', wuo=self.start_up_anim) mid_pointConst = pm.pointConstraint( self.start_T_anim, self.end_T_anim, self.constMe_to_mid) mid_aimConst = pm.aimConstraint( self.end_T_anim, self.constMe_to_mid, aim=self.aimVector, u=self.upVector, wu=self.startWorldUpVector, wut='objectrotation', wuo=self.start_R_result) end_aimConst = pm.aimConstraint( crvEnd_loc, self.end_R_result, aim=self.aimVector, u=self.upVector, wu=self.startWorldUpVector, wut='object', wuo=self.end_up_anim) self.nodes.extend([ start_aimConst, mid_pointConst, mid_aimConst, end_aimConst ]) ctrl.aimVector >> start_aimConst.aimVector ctrl.aimVector >> mid_aimConst.aimVector ctrl.upVector >> start_aimConst.upVector ctrl.upVector >> mid_aimConst.upVector ctrl.startWorldUpVector >> start_aimConst.worldUpVector ctrl.startWorldUpVector >> mid_aimConst.worldUpVector # # Locators on Curve # unit = 1.0 / self.div locOnCrvs = [] for i in range(self.div+1): param = unit * i #xformOnCrv = pm.group( n='xformOnCrv#', em=True) xformOnCrv = pm.spaceLocator( n='xformOnCrv#') xformOnCrv.addAttr( 'parameter', sn='pr', dv=param, keyable=True ) xformOnCrv.addAttr( 'turnOnPercentage', sn='top', dv=False, at='bool', keyable=True ) xformOnCrv.addAttr( 'revRotation', sn='rot', keyable=True ) xformOnCrv.it.set(False) xformOnCrv.rename( 'xformOnCrv%02d'%i ) pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=param, ch=True ) ) pntOnCrv.turnOnPercentage.set(True) pntOnCrv.setAttr('parameter', keyable=True) pntOnCrv.setAttr('turnOnPercentage', keyable=True) pntOnCrv.rename( xformOnCrv+'_POC' ) xformOnCrv.parameter >> pntOnCrv.parameter xformOnCrv.turnOnPercentage >> pntOnCrv.turnOnPercentage pntOnCrv.position >> xformOnCrv.t locOnCrvs.append(xformOnCrv) pm.parent( locOnCrvs, self.doNotTouch_grp ) self.nodes.extend( locOnCrvs ) # # distance Rig # distNodes = [] for i in range(len(locOnCrvs)-1): dist = pm.createNode( 'distanceDimShape' ) locOnCrvs[i].worldPosition[0] >> dist.startPoint locOnCrvs[i+1].worldPosition[0] >> dist.endPoint distNodes.append( dist ) pm.parent( [dist.getParent() for dist in distNodes], self.doNotTouch_grp ) self.nodes.extend( [dist.getParent() for dist in distNodes] ) # # # Joint # # pm.select(cl=True) self.jnts = [] for i in range(self.div+1): self.jnts.append( pm.joint( n='bind%d'%i, p=self.aimVector*i ) ) if self.stretch: # 컨트롤러에 어트리뷰트 추가하고, 리깅까지 마침. #ctrl = pm.group( em=True) ctrl = self.root_grp ctrl.addAttr( 'initialDistance', multi=True, readable=True, indexMatters=False ) ctrl.addAttr( 'currentDistance', multi=True, readable=True, indexMatters=False ) ctrl.addAttr( 'scaleOutput', multi=True, readable=True, indexMatters=False ) for i in range(len(distNodes)): ctrl.initialDistance[i].set( distNodes[i].distance.get() ) distNodes[i].distance >> ctrl.currentDistance[i] md = pm.createNode('multiplyDivide') md.operation.set(2) # divide ctrl.currentDistance[i] >> md.input1X ctrl.initialDistance[i] >> md.input2X md.outputX >> ctrl.scaleOutput[i] for i in range(len( ctrl.scaleOutput.get() )): ctrl.scaleOutput[i] >> self.jnts[i].sx else: for dist, jnt in zip(distNodes, self.jnts[1:]): #if ctrl.aimAxis==1: # 아임축이 -일경우. md = pm.createNode('multiplyDivide') dist.distance >> md.input1X ctrl.aimVectorX >> md.input2X md.outputX >> jnt.tx #else: # dist.distance >> jnt.tx self.nodes.extend(self.jnts) # # # spline IK Handle # # ikHandle, endEff = pm.ikHandle(sol='ikSplineSolver', ccv=False, roc=True, pcv=False, ns=4, sj=self.jnts[0], ee=self.jnts[-1], curve=rdbCrv ) pm.parent(ikHandle, self.doNotTouch_grp ) # Enable Twist Controls : start, end Sample OBJ sampleObj_start = self.start_R_result sampleObj_end = self.end_R_result ikHandle.dTwistControlEnable.set(True) # Enable Twist Controls ikHandle.dWorldUpType.set(4) # 4:Object Rotation Up (Start/End) #sampleObj_start.xformMatrix.connect( foreArm_HDL.dWorldUpMatrix ) # << 요렇게 하면 좆됨 #sampleObj_end.xformMatrix.connect( foreArm_HDL.dWorldUpMatrixEnd ) # << 요렇게 하면 좆됨 sampleObj_start.worldMatrix >> ikHandle.dWorldUpMatrix # << 요렇게 해야함. sampleObj_end .worldMatrix >> ikHandle.dWorldUpMatrixEnd # << 요렇게 해야함. ikHandle.dWorldUpAxis. set(0) # 0:PositiveY, 1:Positive Z ikHandle.dWorldUpVector. set(self.upVector) ikHandle.dWorldUpVectorEnd.set(self.upVector) ctrl.aimAxis >> ikHandle.dWorldUpAxis ctrl.startWorldUpVector >> ikHandle.dWorldUpVector ctrl.endWorldUpVector >> ikHandle.dWorldUpVectorEnd self.nodes.extend([ikHandle,endEff])
import pymel.core as pm baseShape = pm.PyNode('bs_baseShape') blend50 = pm.PyNode('bs_baseShape_a_50') blend100 = pm.PyNode('bs_baseShape_a') #create 50offset shape dup = pm.duplicate(baseShape, name='temp_50offset')[0] pm.delete([x for x in dup.listRelatives() if x.name() != dup.getShape()]) bs = pm.blendShape(blend50, blend100, dup) pm.blendShape( bs, edit=True, w=[(0, 1), (1, -0.5)] ) blend50offset = pm.duplicate(dup, name = 'bs_baseShape_a_50offset')[0] pm.delete(dup) bs = pm.blendShape(blend100, blend50offset, baseShape)[0] dvr_attr = "%s.%s" %(bs.name(), blend100.name()) dvn_attr = "%s.%s" %(bs.name(), blend50offset.name()) pm.setDrivenKeyframe(dvn_attr, v=0.0, cd=dvr_attr, dv=0.0, itt='spline', ott='spline') pm.setDrivenKeyframe(dvn_attr, v=1.0, cd=dvr_attr, dv=0.5, itt='flat', ott='flat') pm.setDrivenKeyframe(dvn_attr, v=0.0, cd=dvr_attr, dv=1.0, itt='spline', ott='spline') pm.keyTangent('%s_%s'%(bs.name(), blend50offset), e=True, ow=1, index=[2], inAngle=-10) pm.keyTangent('%s_%s'%(bs.name(), blend50offset), e=True, ow=1, index=[0], outAngle=10)