def leg(self): cmds.select(cl=True) tmp = cmds.joint(n='L_template_leg', p=(1, 11, 0)) leg = setUniqueName(tmp, 'JNT') tmp = cmds.joint(n='L_template_lowLeg', p=(1, 6, 0)) lowLeg = setUniqueName(tmp, 'JNT') cmds.joint(leg, e=True, zso=True, oj='xyz', sao='yup') tmp = cmds.joint(n='L_template_foot', p=(1, 1, 0)) foot = setUniqueName(tmp, 'JNT') cmds.joint(lowLeg, e=True, zso=True, oj='xyz', sao='yup') tmp = cmds.joint(n='L_template_ball', p=(1, 0, 1)) ball = setUniqueName(tmp, 'JNT') cmds.joint(foot, e=True, zso=True, oj='xyz', sao='yup') tmp = cmds.joint(n='L_template_toe', p=(1, 0, 2)) toe = setUniqueName(tmp, 'JNT') cmds.joint(ball, e=True, zso=True, oj='xyz', sao='yup') cmds.setAttr(leg + '.rx', -10) cmds.setAttr(lowLeg + '.rx', 20) cmds.setAttr(foot + '.rx', -10) cmds.mirrorJoint(leg, mirrorYZ=True, mirrorBehavior=True, searchReplace=('L_', 'R_')) return
def rollUp(self,driven,*driver): sum= cmds.createNode ('multMatrix') dcm= cmds.createNode ('decomposeMatrix') name='' i=0 result=[] pnt= cmds.listRelatives (driven,p=True)[0] for e in driver: mmx= cmds.createNode ('multMatrix') name='' #이름 추출및 설정 if '_' in e: lst= e.split('_') for r in lst[:-1]: if len(name) !=0: name =name+'_'+r else: name=name+r name= name else: name= e #오프셋 로케이터 생성 tmp= cmds.spaceLocator (n=name+'Offset')[0] offset= setUniqueName (tmp,'LOC') tmp= cmds.spaceLocator (n=name+'Reference')[0] ref= setUniqueName (tmp,'LOC') tmp= cmds.group (offset,ref,n=name+'Space') grp= setUniqueName (tmp,'GRP') cmds.delete (cmds.parentConstraint (driven,offset,w=True)) cmds.delete (cmds.parentConstraint (driven,ref,w=True)) tmp=attachPart2 (pnt, grp,'translate','rotate','scale','shear') cmds.parent(tmp,'attach_GRP') tmp=attachPart2 (e, offset,'translate','rotate','scale','shear') cmds.parent(tmp,'attach_GRP') cmds.connectAttr (offset+'.worldMatrix[0]',mmx+'.matrixIn[0]',f=True) cmds.connectAttr (ref+'.worldInverseMatrix[0]',mmx+'.matrixIn[1]',f=True) cmds.connectAttr (mmx+'.matrixSum',sum+'.matrixIn['+str(i)+']',f=True) result.append(grp) i+=1 cmds.connectAttr (sum+'.matrixSum',dcm+'.inputMatrix',f=True) cmds.connectAttr (dcm+'.outputTranslate',driven+'.t',f=True) cmds.connectAttr (dcm+'.outputRotate',driven+'.r',f=True) return result
def setup(self, base, target, con): name = '' if '_' in con: lst = con.split('_') for e in lst[:-1]: if len(name) != 0: name = name + '_' + e else: name = name + e name = name else: name = con tmp = cmds.spaceLocator(n=name + 'Aim') aim_locator = setUniqueName(tmp[0], 'LOC') aim_nul = homeNul(aim_locator) tmp = cmds.spaceLocator(n=name + 'Target') target_locator = setUniqueName(tmp[0], 'LOC') target_nul = homeNul(target_locator) tmp = cmds.spaceLocator(n=name + 'Offset') offset_locator = setUniqueName(tmp[0], 'LOC') offset_nul = homeNul(offset_locator) tmp = cmds.group(aim_nul, target_nul, n=name + 'NoneFlip') group = setUniqueName(tmp, 'GRP') cmds.pointConstraint(base, aim_nul, w=True) cmds.pointConstraint(target, target_nul, w=True) cmds.delete(cmds.parentConstraint(con, offset_nul, w=True)) cmds.aimConstraint(target, aim_locator, w=True, aim=[1, 0, 0], u=[0, 1, 0], wut='objectrotation', wu=[1, 0, 0], wuo=base) sp = spaceBlend() sp.parentBlend(offset_locator, 'move_CON', con) cmds.parent(offset_nul, aim_locator) cmds.parent(group, 'noneFlip_GRP') return [aim_locator, target_locator, offset_locator]
def setFK(self,*jnt): copied=[] for e in jnt: name=e.split('_')[0]+'_FK_'+e.split('_')[2] dup= cmds.duplicate (e,n=name,rr=True,rc=True) tmp=setUniqueName(dup[0],'JNT') par= cmds.listRelatives (tmp,p=True,typ='joint') chi= cmds.listRelatives (tmp,c=True,typ='joint') if par is not None: if len(copied) is not 0: cmds.parent (tmp,copied[-1]) if cmds.connectionInfo (tmp+'.inverseScale',id=True) is False: cmds.connectAttr (copied[-1]+'.scale',tmp+'.inverseScale',f=True) if chi is not None: cmds.delete (chi) copied.append(tmp) cmds.parent(copied[0],'FKJoint_GRP') self.FkCon=fkControllerMaker( 'octagon', 'yellow', copied ) for s in self.FkCon[0]: sha= cmds.listRelatives (s,s=True,typ='nurbsCurve') cmds.rotate (0,0,90,sha[0]+'.cv[*]',os=1) nul= cmds.listRelatives (self.FkCon[0][0],p=True) cmds.parent (nul,'FKControl_GRP') return self.FkCon[0]
def parentBlend(self, local, world, target): name = '' if '_' in target: lst = target.split('_') for e in lst[:-1]: if len(name) != 0: name = name + '_' + e else: name = name + e name = name else: name = target tmp = cmds.group(target, n=name + 'Space') nul = setUniqueName(tmp, 'NUL') cmds.xform(nul, piv=(0, 0, 0)) cmds.addAttr(target, ln='localSpace', at='double', min=0, max=1, dv=0) cmds.setAttr(target + '.localSpace', e=True, keyable=True) locateLocal = self.createMatrixNode(local, target) locateWorld = self.createMatrixNode(world, target) blend = self.connectParent(locateLocal, locateWorld, nul) cmds.connectAttr(target + '.localSpace', blend + '.weight', f=True) return
def finger(self): #thumb cmds.select(cl=True) tmp = cmds.joint(n='L_template_thumb1', p=(0.1, 0, 0)) thumb1 = setUniqueName(tmp, 'JNT') tmp = cmds.joint(n='L_template_thumb2', p=(0.45, 0, 0)) thumb2 = setUniqueName(tmp, 'JNT') cmds.joint(thumb1, e=True, zso=True, oj='xyz', sao='yup') tmp = cmds.joint(n='L_template_thumb3', p=(0.75, 0, 0)) thumb3 = setUniqueName(tmp, 'JNT') cmds.joint(thumb2, e=True, zso=True, oj='xyz', sao='yup') tmp = cmds.joint(n='L_template_thumb4', p=(1.05, 0, 0)) thumb4 = setUniqueName(tmp, 'JNT') cmds.joint(thumb3, e=True, zso=True, oj='xyz', sao='yup') cmds.setAttr(thumb1 + '.t', 10, 10, 0.5) cmds.setAttr(thumb1 + '.jointOrient', 80, -10, -30) cmds.mirrorJoint(thumb1, mirrorYZ=True, mirrorBehavior=True, searchReplace=('L_', 'R_')) #index~pinky name = ['index', 'middle', 'ring', 'pinky'] num = ['Palm', '1', '2', '3', '4'] buffer = [] cmds.select(cl=True) for i in range(len(name)): for n in range(len(num)): tmp = cmds.joint(n='L_template_' + name[i] + num[n], p=(0.35, 0, 0), r=True) fin = setUniqueName(tmp, 'JNT') buffer.append(fin) cmds.setAttr(buffer[0] + '.t', 10, 10, i * -0.2) cmds.mirrorJoint(buffer[0], mirrorYZ=True, mirrorBehavior=True, searchReplace=('L_', 'R_')) cmds.select(cl=True) buffer = [] return
def neck(self): cmds.select(cl=True) tmp = cmds.joint(n='C_template_neck', p=(0, 15, 1)) neck = setUniqueName(tmp, 'JNT') tmp = cmds.joint(n='C_template_head', p=(0, 15.5, 1)) head = setUniqueName(tmp, 'JNT') cmds.joint(neck, e=True, zso=True, oj='xyz', sao='yup') tmp = cmds.joint(n='C_template_top', p=(0, 17, 1)) top = setUniqueName(tmp, 'JNT') cmds.joint(head, e=True, zso=True, oj='xyz', sao='yup') cmds.setAttr(neck + '.rx', 10) cmds.setAttr(head + '.rx', -10) return
def setBlend(self, chest, *jnt): buffer = [] copied = [] const = [] crv = '' tmp = cmds.listRelatives(jnt[0], c=1, ad=1) c = jnt[0] buffer.append(c) if tmp is not None: for i in range(len(tmp)): if jnt[-1] in c: break else: c = cmds.listRelatives(c, c=True) buffer.append(c[0]) #조인트 복사 및 중복된 네임 정리 for e in buffer: name = e.split('_')[0] + '_Blend_' + e.split('_')[2] dup = cmds.duplicate(e, n=name, rr=True, rc=True) tmp = setUniqueName(dup[0], 'JNT') par = cmds.listRelatives(tmp, p=True, typ='joint') chi = cmds.listRelatives(tmp, c=True, typ='joint') if par is not None: if len(copied) is not 0: cmds.parent(tmp, copied[-1]) if cmds.connectionInfo(tmp + '.inverseScale', id=True) is False: cmds.connectAttr(copied[-1] + '.scale', tmp + '.inverseScale', f=True) if chi is not None: cmds.delete(chi) copied.append(tmp) cmds.parent(copied[0], 'BlendJoint_GRP') for e in copied: if cmds.objExists(e.replace('Blend', 'FK')): const.append( cmds.parentConstraint(e.replace('Blend', 'FK'), e, w=1)[0]) if cmds.objExists(e.replace('Blend', 'IK')): const.append( cmds.parentConstraint(e.replace('Blend', 'IK'), e, w=1)[0]) #twist setup t = twistSetUp() t.blendTwist(chest, copied[0], copied[1], 3) #skin setup s = setSkinJoint() s.set() return copied
def shoulder(self): cmds.select(cl=True) tmp = cmds.joint(n='L_template_shoulder', p=(1, 13, 0)) shoulder = setUniqueName(tmp, 'JNT') cmds.mirrorJoint(shoulder, mirrorYZ=True, mirrorBehavior=True, searchReplace=('L_', 'R_')) return
def setIK(self,*jnt): buffer=[] copied=[] tmp=cmds.listRelatives (jnt[0],c=1,ad=1) c=jnt[0] buffer.append(c) for i in range(len(tmp)): if jnt[-1] in c: break else: c=cmds.listRelatives (c,c=True) buffer.append(c[0]) #조인트 복사 및 중복된 네임 정리 for e in buffer: name=e.split('_')[0]+'_IK_'+e.split('_')[2] dup= cmds.duplicate (e,n=name,rr=True,rc=True) tmp= setUniqueName(dup[0],'JNT') par= cmds.listRelatives (tmp,p=True,typ='joint') chi= cmds.listRelatives (tmp,c=True,typ='joint') if par is not None: if len(copied) is not 0: cmds.parent (tmp,copied[-1]) if cmds.connectionInfo (tmp+'.inverseScale',id=True) is False: cmds.connectAttr (copied[-1]+'.scale',tmp+'.inverseScale',f=True) if chi is not None: cmds.delete (chi) copied.append(tmp) cmds.parent(copied[0],'IKJoint_GRP') tmp= ikHandleMaker( copied[0], copied[-1], 'ikRPsolver' ) hdl= cmds.rename (tmp[0],copied[-1].replace('JNT','HDL')) cmds.setAttr (hdl+'.v',0) cmds.parent (hdl,'auxillary_GRP') self.IkCon=ikControllerMaker( copied[-1] ,hdl) #connect stretchy st=stretchyLock() if cmds.objExists (self.IkCon[0][1].replace('_CON','_LOC')) is True: st.setStretchyLock(self.IkCon[0][1],self.IkCon[0][2],self.IkCon[0][1].replace('_CON','_LOC'),copied[0],copied[1],copied[2]) else: tempString= cmds.spaceLocator (n=self.IkCon[0][1].replace('_CON','_LOC')) cmds.parent (tempString,self.IkCon[0][1].replace('_CON','Sub_CON')) st.setStretchyLock(self.IkCon[0][1],self.IkCon[0][2],self.IkCon[0][1].replace('_CON','_LOC'),copied[0],copied[1],copied[2]) return self.IkCon[0]
def arm(self): cmds.select(cl=True) tmp = cmds.joint(n='L_template_upArm', p=(2, 10, 0)) upArm = setUniqueName(tmp, 'JNT') tmp = cmds.joint(n='L_template_foreArm', p=(6, 10, 0)) cmds.joint(upArm, e=True, zso=True, oj='xyz', sao='yup') foreArm = setUniqueName(tmp, 'JNT') tmp = cmds.joint(n='L_template_hand', p=(10, 10, 0)) hand = setUniqueName(tmp, 'JNT') cmds.joint(foreArm, e=True, zso=True, oj='xyz', sao='yup') cmds.setAttr(foreArm + '.ry', -10) cmds.mirrorJoint(upArm, mirrorYZ=True, mirrorBehavior=True, searchReplace=('L_', 'R_')) return
def createMatrixNode(self, base, target): name = '' if '_' in base: lst = base.split('_') for e in lst[:-1]: if len(name) != 0: name = name + '_' + e else: name = name + e name = name + 'Space' else: name = base + 'Space' tmp = cmds.spaceLocator(n=name) loc = setUniqueName(name, 'LOC') tmp = cmds.group(loc, n=name) nul = setUniqueName(name, 'NUL') mmx = cmds.createNode('multMatrix') dcm = cmds.createNode('decomposeMatrix') cmds.connectAttr(base + '.worldMatrix', mmx + '.matrixIn[0]', f=True) cmds.connectAttr(nul + '.parentInverseMatrix', mmx + '.matrixIn[1]', f=True) cmds.connectAttr(mmx + '.matrixSum', dcm + '.inputMatrix', f=True) cmds.connectAttr(dcm + '.outputTranslate', nul + '.t', f=True) cmds.connectAttr(dcm + '.outputRotate', nul + '.r', f=True) #cmds.connectAttr (dcm+'.outputScale',nul+'.s',f=True) cmds.connectAttr(dcm + '.outputShear', nul + '.shear', f=True) cmds.delete(cmds.parentConstraint(target, loc, w=True)) cmds.parent(nul, 'space_GRP') return loc
def attachPart2( basePart, targetPart, *TRSS ): #======================= #추가된 부분 (이름 관련 하여) #======================= TargetName='' buffer= targetPart.split('_')[:-1] for i in range(len(buffer)): if i is 0: TargetName=buffer[i] else: TargetName=TargetName+'_'+buffer[i] #node create tmp1 = cmds.createNode( 'transform', n=TargetName+'Attach') attachNul=setUniqueName(tmp1,'NUL') POsnap( attachNul, basePart ) tmp2 = cmds.spaceLocator( n=TargetName+'Attach') attachLocator=setUniqueName(tmp2[0],'LOC') POsnap( attachLocator, targetPart ) cmds.parent( attachLocator,attachNul ) baseNodeMMX = cmds.createNode( 'multMatrix', n=basePart.replace( basePart.split('_')[-1], 'MMX' ) ) baseNodeDPX = cmds.createNode( 'decomposeMatrix', n=basePart.replace( basePart.split('_')[-1], 'DCM' ) ) targetNodeMMX = cmds.createNode( 'multMatrix', n=targetPart.replace( targetPart.split('_')[-1], 'MMX' ) ) targetNodeDPX = cmds.createNode( 'decomposeMatrix', n=targetPart.replace( targetPart.split('_')[-1], 'DCM' ) ) #conncet node cmds.connectAttr( '%s.worldMatrix[0]' % basePart, '%s.matrixIn[0]' % baseNodeMMX ) cmds.connectAttr( '%s.parentInverseMatrix[0]' % attachNul, '%s.matrixIn[1]' % baseNodeMMX ) cmds.connectAttr( '%s.matrixSum' % baseNodeMMX, '%s.inputMatrix' % baseNodeDPX ) cmds.connectAttr( '%s.worldMatrix[0]' % attachLocator, '%s.matrixIn[0]' % targetNodeMMX ) cmds.connectAttr( '%s.parentInverseMatrix[0]' % targetPart, '%s.matrixIn[1]' % targetNodeMMX ) #======================= #attachPart와 달라진 부분 #======================= cmds.connectAttr( '%s.matrixSum' % targetNodeMMX, '%s.inputMatrix' % targetNodeDPX ) cmds.connectAttr( '%s.outputTranslate' % baseNodeDPX, '%s.translate' % attachNul ) cmds.connectAttr( '%s.outputRotate' % baseNodeDPX, '%s.rotate' % attachNul ) cmds.connectAttr( '%s.outputScale' % baseNodeDPX, '%s.scale' % attachNul ) cmds.connectAttr( '%s.outputShear' % baseNodeDPX, '%s.shear' % attachNul ) #~여기까지 #======================= if 'translate' in TRSS: cmds.connectAttr( '%s.outputTranslate' % targetNodeDPX, '%s.translate' % targetPart ) if 'rotate' in TRSS: cmds.connectAttr( '%s.outputRotate' % targetNodeDPX, '%s.rotate' % targetPart ) if 'scale' in TRSS: cmds.connectAttr( '%s.outputScale' % targetNodeDPX, '%s.scale' % targetPart ) if 'shear' in TRSS: cmds.connectAttr( '%s.outputShear' % targetNodeDPX, '%s.shear' % targetPart ) return attachNul
def splineControllerMaker(crv,handle): list=[] #씬안에 필요한 group node생성 z=defaultGroupNode() z.createGroupNode() par= cmds.listRelatives (crv,p=True) locs= setUpCurve (crv) for e in locs: tmp= cmds.rename(e,e.replace('_LOC','Attach')) name=setUniqueName(tmp,'LOC') nul= homeNul(name) cmds.parent(nul,'attach_GRP') list.append(nul) low= controllerShape('C_IK_lowBody','cube','yellow') lowBody=setUniqueName(low,'CON') up= controllerShape( 'C_IK_upBody','cube','yellow') upBody=setUniqueName(up,'CON') lowNul= homeNul(lowBody) upNul= homeNul(upBody) cmds.parent(upNul,lowNul,'IKControl_GRP') cmds.delete(cmds.parentConstraint(list[0],lowNul,w=True)) cmds.delete(cmds.parentConstraint(list[-1],upNul,w=True)) for i in range(len(list)): chd= cmds.listRelatives(list[i],c=True) cmds.parent(chd[0],w=True) if i <= 1: mmx=cmds.createNode ('multMatrix') dcm=cmds.createNode ('decomposeMatrix') cmds.connectAttr (lowBody+'.worldMatrix',mmx+'.matrixIn[0]',f=True) cmds.connectAttr (list[i]+'.parentInverseMatrix',mmx+'.matrixIn[1]',f=True) cmds.connectAttr (mmx+'.matrixSum',dcm+'.inputMatrix',f=True) cmds.connectAttr (dcm+'.outputTranslate',list[i]+'.t',f=True) cmds.connectAttr (dcm+'.outputRotate',list[i]+'.r',f=True) cmds.parent(chd,list[i]) else: mmx=cmds.createNode ('multMatrix') dcm=cmds.createNode ('decomposeMatrix') cmds.connectAttr (upBody+'.worldMatrix',mmx+'.matrixIn[0]',f=True) cmds.connectAttr (list[i]+'.parentInverseMatrix',mmx+'.matrixIn[1]',f=True) cmds.connectAttr (mmx+'.matrixSum',dcm+'.inputMatrix',f=True) cmds.connectAttr (dcm+'.outputTranslate',list[i]+'.t',f=True) cmds.connectAttr (dcm+'.outputRotate',list[i]+'.r',f=True) cmds.parent(chd,list[i]) cmds.setAttr (handle+'.dTwistControlEnable',1) cmds.setAttr (handle+'.dWorldUpType',4) cmds.setAttr (handle+'.dWorldUpVector', 0,0,1) cmds.setAttr (handle+'.dWorldUpVectorEnd',0,0,1) cmds.connectAttr (lowBody+'.worldMatrix[0]',handle+'.dWorldUpMatrix',f=1) cmds.connectAttr (upBody+'.worldMatrix[0]',handle+'.dWorldUpMatrixEnd',f=1) #FK컨트롤러 생성및 세팅 sp1= controllerShape('C_IK_upBodyRot1','circle','yellow') spine1=setUniqueName(sp1,'CON') spNul1= homeNul(spine1) sp2= controllerShape('C_IK_upBodyRot2','circle','yellow') spine2=setUniqueName(sp2,'CON') spNul2= homeNul(spine2) cmds.delete(cmds.parentConstraint(list[1].replace('NUL','LOC'),spNul1,w=True)) cmds.delete(cmds.parentConstraint(list[2].replace('NUL','LOC'),spNul2,w=True)) cmds.parent (spNul2,spine1) cmds.parent(spNul1,'IKControl_GRP') return [lowBody,upBody]
def setIK(self, *jnt): buffer = [] copied = [] crv = '' tmp = cmds.listRelatives(jnt[0], c=1, ad=1) c = jnt[0] buffer.append(c) for i in range(len(tmp)): if jnt[-1] in c: break else: c = cmds.listRelatives(c, c=True) buffer.append(c[0]) #조인트 복사 및 중복된 네임 정리 for e in buffer: name = e.split('_')[0] + '_IK_' + e.split('_')[2] dup = cmds.duplicate(e, n=name, rr=True, rc=True) tmp = setUniqueName(dup[0], 'JNT') par = cmds.listRelatives(tmp, p=True, typ='joint') chi = cmds.listRelatives(tmp, c=True, typ='joint') if par is not None: if len(copied) is not 0: cmds.parent(tmp, copied[-1]) if cmds.connectionInfo(tmp + '.inverseScale', id=True) is False: cmds.connectAttr(copied[-1] + '.scale', tmp + '.inverseScale', f=True) if chi is not None: cmds.delete(chi) copied.append(tmp) #커브 그리기 for i in range(len(copied)): pos = cmds.xform(copied[i], q=True, ws=True, t=True) if copied[i] is copied[0]: tmp = cmds.curve(n='C_IK_spineCurve', d=1, p=pos) crv = setUniqueName(tmp, 'CRV') else: cmds.curve(crv, a=True, p=pos) cmds.parent(copied[0], 'IKJoint_GRP') tmp = ikHandleMaker(copied[0], copied[-1], 'ikSplineSolver', crv) hdl = cmds.rename(tmp[0], copied[0].replace('JNT', 'HDL')) cmds.parent(crv, hdl, 'auxillary_GRP') #컨트롤러 생성 / 스플라인 커브 컨트롤 셋 self.IkCon = neckControllerMaker(crv, hdl) cmds.delete( cmds.orientConstraint(jnt[1], self.IkCon[1].replace('_CON', '_NUL'), w=True, o=(0, -90, -90))) cmds.orientConstraint(self.IkCon[1], copied[1], mo=True) #스플라인 스트레치 연결 st = splineStretchy() st.stretchy(self.IkCon[1], crv, copied[0]) return self.IkCon
def setIK(self,*jnt): buffer=[] copied=[] tmp=cmds.listRelatives (jnt[0],c=1,ad=1) c=jnt[0] buffer.append(c) for i in range(len(tmp)): if jnt[-1] in c: break else: c=cmds.listRelatives (c,c=True) buffer.append(c[0]) #조인트 복사 및 중복된 네임 정리 for e in buffer: name=e.split('_')[0]+'_IK_'+e.split('_')[2] dup= cmds.duplicate (e,n=name,rr=True,rc=True) tmp= setUniqueName(dup[0],'JNT') par= cmds.listRelatives (tmp,p=True,typ='joint') chi= cmds.listRelatives (tmp,c=True,typ='joint') if par is not None: if len(copied) is not 0: cmds.parent (tmp,copied[-1]) if cmds.connectionInfo (tmp+'.inverseScale',id=True) is False: cmds.connectAttr (copied[-1]+'.scale',tmp+'.inverseScale',f=True) if chi is not None: cmds.delete (chi) copied.append(tmp) cmds.parent(copied[0],'IKJoint_GRP') tmp= ikHandleMaker( copied[0], copied[-2], 'ikRPsolver' ) hdl= cmds.rename (tmp[0],copied[-2].replace('JNT','HDL')) cmds.setAttr (hdl+'.v',0) cmds.parent (hdl,'auxillary_GRP') self.IkCon=ikControllerMaker( copied[-2] ,hdl) otherCon= fkControllerMaker( 'circle', 'yellow', [copied[-1]] ) cmds.delete(otherCon[2]) cmds.orientConstraint (otherCon[0],copied[-1],w=True) ballUp= controllerShape(otherCon[0][0].replace('_CON','RollUp_CON'),'hexagon', 'yellow' ) ballUp_Nul= homeNul (ballUp) cmds.delete(cmds.pointConstraint (copied[-1],ballUp_Nul,w=True)) cmds.rotate (90,0,0,ballUp+'.cv[*]',os=1) heelUp= controllerShape(self.IkCon[0][1].replace('_CON','RollUp_CON'),'hexagon', 'yellow' ) heelUp_Nul= homeNul (heelUp) cmds.delete(cmds.pointConstraint (copied[-2],heelUp_Nul,offset=(0,-1,-1),w=True)) cmds.rotate (90,0,0,heelUp+'.cv[*]',os=1) self.IkCon[0].append(str(otherCon[0][0])) self.IkCon[1].append(str(otherCon[1][0])) cmds.parent (self.IkCon[1][3],ballUp_Nul,heelUp_Nul,self.IkCon[0][0]) #rolling up roll=addRollingUp() tmp=roll.rollUp(self.IkCon[0][1].replace('_CON','_LOC'),ballUp,heelUp) cmds.parent (tmp,'roll_GRP') #attach shoulder tmp=attachPart2(heelUp ,self.IkCon[1][3] , 'translate','rotate','scale','shear') cmds.parent(tmp,'attach_GRP') #connect stretchy st=stretchyLock() if cmds.objExists (self.IkCon[0][1].replace('_CON','_LOC')) is True: st.setStretchyLock(self.IkCon[0][1],self.IkCon[0][2],self.IkCon[0][1].replace('_CON','_LOC'),copied[0],copied[1],copied[2]) else: tempString= cmds.spaceLocator (n=self.IkCon[0][1].replace('_CON','_LOC')) cmds.parent (tempString,self.IkCon[0][1].replace('_CON','Sub_CON')) st.setStretchyLock(self.IkCon[0][1],self.IkCon[0][2],self.IkCon[0][1].replace('_CON','_LOC'),copied[0],copied[1],copied[2]) n=noneFlip() n.setup(self.IkCon[0][1].replace('_CON','_LOC'),copied[0],self.IkCon[0][2]) cmds.rotate (90,0,0,self.IkCon[0][3]+'.cv[*]',os=1) return self.IkCon[0]
def setBlend(self,hip,*jnt): buffer=[] copied=[] const=[] crv='' tmp=cmds.listRelatives (jnt[0],c=1,ad=1) c=jnt[0] buffer.append(c) if tmp is not None: for i in range(len(tmp)): if jnt[-1] in c: break else: c=cmds.listRelatives (c,c=True) buffer.append(c[0]) #조인트 복사 및 중복된 네임 정리 for e in buffer: name=e.split('_')[0]+'_Blend_'+e.split('_')[2] dup= cmds.duplicate (e,n=name,rr=True,rc=True) tmp= setUniqueName(dup[0],'JNT') par= cmds.listRelatives (tmp,p=True,typ='joint') chi= cmds.listRelatives (tmp,c=True,typ='joint') if par is not None: if len(copied) is not 0: cmds.parent (tmp,copied[-1]) if cmds.connectionInfo (tmp+'.inverseScale',id=True) is False: cmds.connectAttr (copied[-1]+'.scale',tmp+'.inverseScale',f=True) if chi is not None: cmds.delete (chi) copied.append(tmp) cmds.parent(copied[0],'BlendJoint_GRP') #스위치 콘트롤러 생성 prefix= copied[0].split('_')[0] buf= controllerShape(prefix+'_legBlend','fatCross','yellow') sw= setUniqueName(buf,'CON') swNul= homeNul(sw) sha= cmds.listRelatives (sw,s=True,typ='nurbsCurve') cmds.rotate (90,0,0,sha[0]+'.cv[*]',os=1) cmds.scale (0.5,0.5,0.5,sha[0]+'.cv[*]',os=1) v= cmds.getAttr (copied[0]+'.tx') cmds.delete(cmds.pointConstraint (copied[0],swNul,w=True,offset=(v/(abs(v)),1,0))) cmds.addAttr (sw,ln ='FKIKBlend',at='double',min= 0 ,max= 1 ,dv= 0) cmds.setAttr (sw+'.FKIKBlend',e=True,keyable=True) cmds.addAttr (sw,ln ='FKConVis',at='bool') cmds.setAttr (sw+'.FKConVis',e=True,keyable=True) cmds.addAttr (sw,ln ='IKConVis',at='bool') cmds.setAttr (sw+'.IKConVis',e=True,keyable=True) cmds.parent (swNul,'otherControl_GRP') for e in copied: if cmds.objExists (e.replace('Blend','FK')) : const.append(cmds.parentConstraint (e.replace('Blend','FK'),e,w= 1)[0]) if cmds.objExists (e.replace('Blend','IK')): const.append(cmds.parentConstraint (e.replace('Blend','IK'),e,w= 1)[0]) for e in const: buf= cmds.parentConstraint (e,q=True,tl=True) if len(buf) is 2: z=connectSwitch() z.FKIKConstraint(sw,e) else: cmds.delete(swNul) break for e in self.FkCon[0]: z=connectSwitch() z.ConnectFKVisibility(sw,e.replace('_CON','_NUL')) for e in self.IkCon[0]: z=connectSwitch() z.ConnectIKVisibility(sw,e.replace('_CON','_NUL')) #twist setup t=twistSetUp() t.blendTwist(hip,copied[0],copied[1],5) t.blendTwist(copied[0],copied[1],copied[2],5) #skin setup s=setSkinJoint() s.set() return copied
def setIK(self, *jnt): buffer = [] copied = [] crv = '' tmp = cmds.listRelatives(jnt[0], c=1, ad=1) c = jnt[0] buffer.append(c) for i in range(len(tmp)): if jnt[-1] in c: break else: c = cmds.listRelatives(c, c=True) buffer.append(c[0]) #조인트 복사 및 중복된 네임 정리 for e in buffer: name = e.split('_')[0] + '_IK_' + e.split('_')[2] dup = cmds.duplicate(e, n=name, rr=True, rc=True) tmp = setUniqueName(dup[0], 'JNT') par = cmds.listRelatives(tmp, p=True, typ='joint') chi = cmds.listRelatives(tmp, c=True, typ='joint') if par is not None: if len(copied) is not 0: cmds.parent(tmp, copied[-1]) if cmds.connectionInfo(tmp + '.inverseScale', id=True) is False: cmds.connectAttr(copied[-1] + '.scale', tmp + '.inverseScale', f=True) if chi is not None: cmds.delete(chi) copied.append(tmp) #커브 그리기 for i in range(len(copied)): pos = cmds.xform(copied[i], q=True, ws=True, t=True) if i is 0: continue elif copied[i] is copied[1]: tmp = cmds.curve(n='C_IK_spineCurve', d=3, p=pos) crv = setUniqueName(tmp, 'CRV') else: cmds.curve(crv, a=True, p=pos) cmds.parent(copied[0], 'IKJoint_GRP') tmp = ikHandleMaker(copied[1], copied[-1], 'ikSplineSolver', crv) hdl = cmds.rename(tmp[0], copied[0].replace('JNT', 'HDL')) cmds.parent(crv, hdl, 'auxillary_GRP') #컨트롤러 생성 / 스플라인 커브 컨트롤 셋 cons = splineControllerMaker(crv, hdl) #스플라인 스트레치 연결 st = splineStretchy() st.stretchy(cons[1], crv, copied[1], copied[2], copied[3]) #힙 컨트롤러 생성 buf = controllerShape('C_IK_hip', 'square', 'yellow') hip = setUniqueName(buf, 'CON') hipNul = homeNul(hip) cmds.delete(cmds.parentConstraint(cons[0], hipNul, w=True)) cmds.parentConstraint(hip, copied[0], mo=True) cmds.parent(hipNul, cons[0]) cmds.orientConstraint(cons[1], copied[-1], mo=True) #루트 컨트롤러 생성 cmds.delete(cmds.parentConstraint(cons[0], 'root_NUL', w=True)) cons.append(hip) #return control curves return cons
def setUpCurve(crv): res = [] sha = cmds.listRelatives(crv, s=1) span = cmds.getAttr(sha[0] + '.spans') deg = cmds.getAttr(sha[0] + '.degree') cvs = span + deg v = 0.0 add = 1.0 / cvs for i in range(cvs): inf = cmds.createNode('pointOnCurveInfo') vpd = cmds.createNode('vectorProduct') ffm = cmds.createNode('fourByFourMatrix') dcm = cmds.createNode('decomposeMatrix') cmds.setAttr(inf + '.turnOnPercentage', 1) cmds.connectAttr(sha[0] + '.worldSpace', inf + '.inputCurve') cmds.setAttr(inf + '.parameter', v) cmds.setAttr(vpd + '.operation', 2) tr = cmds.getAttr(inf + '.result.position') pos = cmds.pointPosition(sha[0] + '.cv[' + str(i) + ']') tmp = cmds.getAttr(inf + '.result.normal') cmds.connectAttr(inf + '.tangent', vpd + '.input1', f=True) cmds.connectAttr(inf + '.normal', vpd + '.input2', f=True) cmds.connectAttr(inf + '.tangentX', ffm + '.in00', f=True) cmds.connectAttr(inf + '.tangentY', ffm + '.in01', f=True) cmds.connectAttr(inf + '.tangentZ', ffm + '.in02', f=True) cmds.connectAttr(inf + '.normalX', ffm + '.in10', f=True) cmds.connectAttr(inf + '.normalY', ffm + '.in11', f=True) cmds.connectAttr(inf + '.normalZ', ffm + '.in12', f=True) cmds.connectAttr(vpd + '.outputX', ffm + '.in20', f=True) cmds.connectAttr(vpd + '.outputY', ffm + '.in21', f=True) cmds.connectAttr(vpd + '.outputZ', ffm + '.in22', f=True) cmds.connectAttr(ffm + '.output', dcm + '.inputMatrix', f=True) rot = cmds.getAttr(dcm + '.outputRotate') if '_CRV' in crv: buffer = crv.split('_')[0] + '_' + crv.split( '_')[1] + '_' + crv.split('_')[2] else: buffer = crv tmp = cmds.spaceLocator(n=buffer) loc = setUniqueName(tmp[0], 'LOC') mmx = cmds.createNode('multMatrix') dcm = cmds.createNode('decomposeMatrix') cmds.setAttr(loc + '.t', pos[0], pos[1], pos[2]) cmds.setAttr(loc + '.r', rot[0][0], rot[0][1], rot[0][2]) cmds.connectAttr(loc + '.worldMatrix', mmx + '.matrixIn[0]', f=True) cmds.connectAttr(crv + '.parentInverseMatrix', mmx + '.matrixIn[1]', f=True) cmds.connectAttr(mmx + '.matrixSum', dcm + '.inputMatrix', f=True) cmds.connectAttr(dcm + '.outputTranslate', sha[0] + '.cv[' + str(i) + ']', f=True) aim = cmds.spaceLocator(n=crv + str(i) + 'Aim_LOC') up = cmds.spaceLocator(n=crv + str(i) + 'Up_LOC') cmds.delete(cmds.parentConstraint(loc, aim[0], w=True)) cmds.delete(cmds.parentConstraint(loc, up[0], w=True)) cmds.move(1, 0, 0, aim[0], os=True, r=True) cmds.move(1, 0, 0, up[0], ws=True, r=True) cmds.delete( cmds.aimConstraint(aim[0], loc, w=True, aim=[0, 1, 0], u=[1, 0, 0], wuo=up[0], wut='object')) cmds.delete(aim, up) v = v + add res.append(loc) return res
def setStretchyLock(self, con, polVec, guide, *jnt): msLenght = 0 #name if '_CON' in con: name = con.replace('_CON', '') elif '_LOC' in con: name = con.replace('_LOC', '') else: name = con tm = cmds.getAttr(str(jnt[-1]) + '.tx') b = tm / (abs(tm)) for i in range(len(jnt) - 1): tmp = abs(cmds.getAttr(jnt[i + 1] + ".translateX")) msLenght = tmp + msLenght dcm = cmds.createNode('decomposeMatrix') cmds.connectAttr(con + '.worldMatrix[0]', dcm + '.inputMatrix', f=True) #어트리뷰트 생성 cmds.addAttr(con, k=True, ln='stretchy', at='double', min=0, max=10, dv=0) cmds.addAttr(con, k=True, ln='antiPop', at='double', min=0, max=10, dv=0) IKSetRangeStretch = cmds.createNode('setRange', n='IKSetRangeStretch') IKSetRangeAntiPop = cmds.createNode('setRange', n='IKSetRangeAntiPop') cmds.setAttr(IKSetRangeStretch + '.maxX', 1) cmds.setAttr(IKSetRangeAntiPop + '.maxX', 1) cmds.setAttr(IKSetRangeStretch + '.oldMaxX', 10) cmds.setAttr(IKSetRangeAntiPop + '.oldMaxX', 10) cmds.connectAttr(con + '.stretchy', IKSetRangeStretch + '.valueX', f=True) cmds.connectAttr(con + '.antiPop', IKSetRangeAntiPop + '.valueX', f=True) tempString = cmds.spaceLocator() IKmessureTmp = cmds.rename(tempString[0], name + 'messureStart') IKmessureLoc1 = setUniqueName(IKmessureTmp, 'LOC') cmds.delete(cmds.pointConstraint(jnt[0], IKmessureLoc1, w=True)) cmds.pointConstraint(jnt[0], IKmessureLoc1, mo=True) tempString = cmds.spaceLocator() IKmessureTmp = cmds.rename(tempString[0], name + 'messureEnd') IKmessureLoc2 = setUniqueName(IKmessureTmp, 'LOC') cmds.pointConstraint(guide, IKmessureLoc2, w=True) #create distance IKdistance = cmds.createNode('distanceDimShape', n=name + 'distance') tempString = cmds.group(IKmessureLoc1, IKmessureLoc2, IKdistance, n=name + 'messure') IKmessureGrp = setUniqueName(tempString, 'GRP') cmds.parent(IKmessureGrp, 'stretchy_GRP') cmds.connectAttr(IKmessureLoc1 + '.translate', IKdistance + '.startPoint') cmds.connectAttr(IKmessureLoc2 + '.translate', IKdistance + '.endPoint') IKmessureDiv = cmds.createNode('multiplyDivide', n='IKmessureDiv') cmds.setAttr(IKmessureDiv + '.operation', 2) cmds.setAttr(IKmessureDiv + '.input2X', msLenght) distance = cmds.getAttr(IKdistance + '.distance') IKmessureBlendAntiPop = cmds.createNode('blendTwoAttr', n='IKmessureBlendAntiPop') cmds.connectAttr(IKSetRangeAntiPop + '.outValueX', IKmessureBlendAntiPop + '.attributesBlender') cmds.addAttr(IKdistance, ln='antiPop', at='double') IKmessureBlendReverse = cmds.createNode('multiplyDivide', n='IKmessureBlendReverse') cmds.setAttr(IKmessureBlendReverse + '.input2X', 1) cmds.connectAttr(IKmessureBlendAntiPop + '.output', IKmessureBlendReverse + '.input1X', f=True) cmds.setDrivenKeyframe(IKdistance + '.antiPop', itt='spline', ott='linear', v=msLenght, dv=msLenght, cd=IKdistance + '.distance') IKdistance_antiPop = cmds.listConnections(IKdistance + '.antiPop') cmds.setKeyframe(IKdistance_antiPop[0], itt="spline", ott="spline", v=msLenght, f=msLenght * 0.1) cmds.setKeyframe(IKdistance_antiPop[0], itt="spline", ott="spline", v=msLenght * 1.2, f=msLenght * 1.2) cmds.setKeyframe(IKdistance_antiPop[0], itt="linear", ott="spline", v=msLenght, f=msLenght * 0.70) cmds.setKeyframe(IKdistance_antiPop[0], itt="spline", ott="spline", v=msLenght * 0.9, f=msLenght * 0.85) cmds.selectKey(IKdistance_antiPop[0]) cmds.setInfinity(poi='linear') IKdistance_normal = cmds.duplicate(IKdistance_antiPop, n=IKdistance_antiPop[0].replace( 'antiPop', 'normal')) cmds.cutKey(IKdistance_normal[0], clear=True, time=(msLenght * 0.1, msLenght * 0.85), float=(msLenght * 0.1, msLenght * 0.85), option='keys', hierarchy='none') cmds.connectAttr(IKdistance + ".distance", IKdistance_normal[0] + '.input', f=True) cmds.connectAttr(IKdistance_normal[0] + '.output', IKmessureBlendAntiPop + '.input[0]', f=True) cmds.connectAttr(IKdistance_antiPop[0] + '.output', IKmessureBlendAntiPop + '.input[1]', f=True) IKdistanceClamp = cmds.createNode('clamp', n='IKdistanceClamp') cmds.setAttr(IKdistanceClamp + '.maxR', abs(msLenght)) cmds.connectAttr(IKmessureBlendReverse + '.outputX', IKdistanceClamp + '.inputR', f=True) IKmessureBlendStretch = cmds.createNode('blendTwoAttr', n='IKmessureBlendStretch') cmds.connectAttr(IKSetRangeStretch + '.outValueX', IKmessureBlendStretch + '.attributesBlender', f=True) cmds.connectAttr(IKdistanceClamp + '.outputR', IKmessureBlendStretch + '.input[0]', f=True) cmds.connectAttr(IKmessureBlendReverse + '.outputX', IKmessureBlendStretch + '.input[1]', f=True) cmds.connectAttr(IKmessureBlendStretch + '.output', IKmessureDiv + '.input1X', f=True) cmds.addAttr(polVec, k=True, ln='lock', at='double', min=0, max=10) unitConversion = cmds.createNode('unitConversion') cmds.setAttr(unitConversion + '.conversionFactor', 0.1) cmds.connectAttr(polVec + '.lock', unitConversion + '.input', f=True) #lenght average lenghtAverage = cmds.createNode('plusMinusAverage', n='lenghtAverage') cmds.setAttr(lenghtAverage + '.operation', 3) cmds.setAttr(lenghtAverage + '.input1D[0]', 1) #lenght average lenghtSum = cmds.createNode('plusMinusAverage', n='lenghtSum') cmds.setAttr(lenghtSum + '.input1D[0]', msLenght) ''' if b ==1: cmds.connectAttr (lenghtSum+'.output1D',IKdistanceClamp+'.maxR',f=True) else: cmds.connectAttr (lenghtSum+'.output1D',IKdistanceClamp+'.minR',f=True) ''' distanceDiv = cmds.createNode('multiplyDivide', n='distanceDiv') cmds.setAttr(distanceDiv + '.operation', 2) cmds.connectAttr(distanceDiv + '.outputX', IKdistance_antiPop[0] + '.input', f=True) cmds.connectAttr(distanceDiv + '.outputX', IKdistance_normal[0] + '.input', f=True) cmds.connectAttr(IKdistance + '.distance', distanceDiv + '.input1X', f=True) cmds.connectAttr(lenghtAverage + '.output1D', distanceDiv + '.input2X', f=True) for i in range(len(jnt) - 1): v = cmds.getAttr(jnt[i + 1] + ".translateX") eIKmessureDiv = cmds.createNode('multiplyDivide', n='eIKmessureDiv') cmds.setAttr(eIKmessureDiv + '.input2X', v) cmds.connectAttr(IKmessureDiv + '.output.outputX', eIKmessureDiv + '.input1X', f=True) #IkLengtControl cmds.addAttr(con, k=1, ln='lenght' + str(i + 1), at='double', min=0, max=2, dv=1) IKLenghtDiv = cmds.createNode('multiplyDivide', n='IKLenghtDiv') cmds.connectAttr(con + '.lenght' + str(i + 1), IKLenghtDiv + ".input1X", f=True) cmds.connectAttr(IKLenghtDiv + ".outputX", lenghtSum + '.input1D[' + str(i) + ']', f=True) cmds.setAttr(IKLenghtDiv + ".input2X", v) # cmds.connectAttr(con + '.lenght' + str(i + 1), lenghtAverage + '.input1D[' + str(i) + ']', f=True) cmds.connectAttr(IKLenghtDiv + '.outputX', eIKmessureDiv + '.input2X', f=True) #pole.lock PoleLockBlender = cmds.createNode('blendTwoAttr', n='PoleLockBlender') cmds.connectAttr(eIKmessureDiv + ".output.outputX", PoleLockBlender + ".input[0]", f=True) cmds.connectAttr(PoleLockBlender + ".output", jnt[i + 1] + ".translateX", f=True) cmds.connectAttr(unitConversion + ".output", PoleLockBlender + ".attributesBlender", f=True) eDistance = cmds.createNode('distanceBetween', n='eDistance') cmds.connectAttr(polVec + ".worldMatrix[0]", eDistance + '.inMatrix1', f=True) if i == 0: cmds.connectAttr(IKmessureLoc1 + ".worldMatrix[0]", eDistance + '.inMatrix2', f=True) else: cmds.connectAttr(IKmessureLoc2 + '.worldMatrix[0]', eDistance + '.inMatrix2', f=True) PoleDistanceSideReverse = cmds.createNode( 'unitConversion', n='PoleDistanceSideReverse') cmds.setAttr(PoleDistanceSideReverse + '.conversionFactor', b) #divide by Main.sy scale PoleLockMainScaler = cmds.createNode('multiplyDivide', n='PoleLockMainScaler') cmds.setAttr(PoleLockMainScaler + '.operation', 2) cmds.connectAttr(eDistance + '.distance', PoleLockMainScaler + ".input1X", f=True) cmds.connectAttr(dcm + '.outputScaleX', PoleLockMainScaler + ".input2X", f=True) cmds.connectAttr(PoleLockMainScaler + ".outputX", PoleDistanceSideReverse + ".input", f=True) cmds.connectAttr(PoleDistanceSideReverse + ".output", PoleLockBlender + ".input[1]", f=True) return
def neckControllerMaker(crv,handle): list=[] #씬안에 필요한 group node생성 z=defaultGroupNode() z.createGroupNode() par= cmds.listRelatives (crv,p=True) locs= setUpCurve (crv) for e in locs: tmp= cmds.rename(e,e.replace('_LOC','Attach')) name=setUniqueName(tmp,'LOC') nul= homeNul(name) cmds.parent(nul,'attach_GRP') list.append(nul) low= controllerShape('C_IK_neck','cube','yellow') neck=setUniqueName(low,'CON') up= controllerShape( 'C_IK_head','cube','yellow') head=setUniqueName(up,'CON') neckNul= homeNul(neck) headNul= homeNul(head) cmds.parent(headNul,neckNul,'IKControl_GRP') cmds.delete(cmds.parentConstraint(list[0],neckNul,w=True)) cmds.delete(cmds.parentConstraint(list[-1],headNul,w=True)) for i in range(len(list)): chd= cmds.listRelatives(list[i],c=True) cmds.parent(chd[0],w=True) if i == 0: mmx=cmds.createNode ('multMatrix') dcm=cmds.createNode ('decomposeMatrix') cmds.connectAttr (neck+'.worldMatrix',mmx+'.matrixIn[0]',f=True) cmds.connectAttr (list[i]+'.parentInverseMatrix',mmx+'.matrixIn[1]',f=True) cmds.connectAttr (mmx+'.matrixSum',dcm+'.inputMatrix',f=True) cmds.connectAttr (dcm+'.outputTranslate',list[i]+'.t',f=True) cmds.connectAttr (dcm+'.outputRotate',list[i]+'.r',f=True) cmds.parent(chd,list[i]) else: mmx=cmds.createNode ('multMatrix') dcm=cmds.createNode ('decomposeMatrix') cmds.connectAttr (head+'.worldMatrix',mmx+'.matrixIn[0]',f=True) cmds.connectAttr (list[i]+'.parentInverseMatrix',mmx+'.matrixIn[1]',f=True) cmds.connectAttr (mmx+'.matrixSum',dcm+'.inputMatrix',f=True) cmds.connectAttr (dcm+'.outputTranslate',list[i]+'.t',f=True) cmds.connectAttr (dcm+'.outputRotate',list[i]+'.r',f=True) cmds.parent(chd,list[i]) cmds.setAttr (handle+'.dTwistControlEnable',1) cmds.setAttr (handle+'.dWorldUpType',3) cmds.setAttr (handle+'.dWorldUpVector', 0,0,1) cmds.connectAttr (neck+'.worldMatrix[0]',handle+'.dWorldUpMatrix',f=1) return [neck,head]
def blendTwist(self, base, start, end, num): name = '' twist = [] twistNul = [] joints = [] if '_' in start: lst = start.split('_') for e in lst[:-1]: if len(name) != 0: name = name + '_' + e else: name = name + e name = name else: name = start tmp = cmds.spaceLocator(n=name + 'Up') rotUpVec = setUniqueName(tmp[0], 'LOC') rotUpNul = homeNul(rotUpVec) cmds.parentConstraint(end, rotUpNul, w=True) v = cmds.getAttr(end + '.tx') #레프트 라이트에따라서 에임되는 수치가 다르다. #레프트는 -1 0 0 #라이트는 1 0 0 이다. cmds.aimConstraint(start, rotUpVec, w=True, aim=[v / (abs(v)) * -1, 0, 0], u=[0, 1, 0], wut='none') #지정된 갯수만큼 블랜드 로케이터를 생성 한다. for i in range(num): tmp = cmds.spaceLocator(n=name + 'Twist') twist.append(setUniqueName(tmp[0], 'LOC')) twistNul.append(homeNul(twist[i])) tmp = cmds.group(twistNul, n=name + 'TwistAim') twistAim = setUniqueName(tmp, 'NUL') tmp = cmds.group(twistAim, n=name + 'TwistGroup') twistGrp = setUniqueName(tmp, 'NUL') cmds.delete(cmds.parentConstraint(start, twistGrp, w=True)) cmds.parentConstraint(base, twistGrp, mo=True) cmds.aimConstraint(end, twistAim, w=True, aim=[v / (abs(v)), 0, 0], u=[0, 1, 0], wut='none') cmds.pointConstraint(start, twistAim, w=True) #페어블랜드 노드를 이용하여 #조인트의 늘어난 거리만큼 블랜드 로케이터들을 위치 시킨다. for i in range(num): pbd = cmds.createNode('pairBlend') cmds.connectAttr(end + '.t', pbd + '.inTranslate2', f=True) cmds.connectAttr(pbd + '.outTranslateX', twistNul[i] + '.tx', f=True) if i is 0: cmds.setAttr(pbd + '.weight', 0.01) else: cmds.setAttr(pbd + '.weight', (0.99 / (num - 1)) * i) cmds.aimConstraint(start, twist[-1], w=True, aim=[v / (abs(v)) * -1, 0, 0], u=[0, 1, 0], wut='objectrotation', wuo=rotUpVec) #페어블랜드로 로케이터들의 트위스트값을 #나눈다. for i in range(num - 1): pbd = cmds.createNode('pairBlend') cmds.connectAttr(twist[-1] + '.r', pbd + '.inRotate2', f=True) cmds.connectAttr(pbd + '.outRotate', twist[i] + '.r', f=True) cmds.setAttr(pbd + '.weight', (1.0 / (num - 1)) * i) cmds.setAttr(pbd + '.rotInterpolation', 1) #트위스트 블랜드 조인트를 생성 하여 #트위스트 로케이터와 컨스트레인 한다. z = zeroOut() for e in twist: tmp = cmds.createNode('joint', n=e.replace('_LOC', '')) jnt = setUniqueName(tmp, 'JNT') cmds.delete(cmds.parentConstraint(e, jnt, w=True)) z.zeroOutJoint(jnt) cmds.parentConstraint(e, jnt, w=True) cmds.parent(jnt, 'BlendJoint_GRP') joints.append(jnt) cmds.parent(rotUpNul, twistGrp) cmds.parent(twistGrp, 'twist_GRP') return joints