import os, sys import maya.cmds as cmds import maya.OpenMaya as OpenMaya import math """ MetaHuman Body Control """ def mgBuildMetaHumansRigCntrls(): metahuman_skeleton = [ 'root', 'pelvis', 'spine_01', 'spine_02', 'spine_03', 'spine_04', 'spine_05', 'neck_01', 'neck_02', 'head', 'clavicle_l', 'clavicle_r', 'bigtoe_01_l', 'bigtoe_02_l', 'indextoe_01_l', 'indextoe_02_l', 'middletoe_01_l', 'middletoe_02_l', 'ringtoe_01_l', 'ringtoe_02_l', 'littletoe_01_l', 'littletoe_02_l', 'bigtoe_01_r', 'bigtoe_02_r', 'indextoe_01_r', 'indextoe_02_r', 'middletoe_01_r', 'middletoe_02_r', 'ringtoe_01_r', 'ringtoe_02_r', 'littletoe_01_r', 'littletoe_02_r', 'pinky_metacarpal_r', 'pinky_01_r', 'pinky_02_r', 'pinky_03_r', 'ring_metacarpal_r', 'ring_01_r', 'ring_02_r', 'ring_03_r', 'middle_metacarpal_r', 'middle_01_r', 'middle_02_r', 'middle_03_r', 'index_metacarpal_r', 'index_01_r', 'index_02_r', 'index_03_r', 'thumb_01_r', 'thumb_02_r', 'thumb_03_r', 'pinky_metacarpal_l', 'pinky_01_l', 'pinky_02_l', 'pinky_03_l', 'ring_metacarpal_l', 'ring_01_l', 'ring_02_l', 'ring_03_l', 'middle_metacarpal_l', 'middle_01_l', 'middle_02_l', 'middle_03_l', 'index_metacarpal_l', 'index_01_l', 'index_02_l', 'index_03_l', 'thumb_01_l', 'thumb_02_l', 'thumb_03_l', ] metahuman_ctrl_radius = [ 20, 30, 20, 20, 20, 20, 20, 8, 8, 15, 15, 15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, ] dir_str_list = ['l', 'r'] type_str_list = ['fk', 'ik'] part_list = ['upperarm', 'lowerarm', 'hand', 'thigh', 'calf', 'foot', 'ball'] digits_part_list = [['pinky_metacarpal', 'pinky_01', 'pinky_02', 'pinky_03'], ['ring_metacarpal', 'ring_01', 'ring_02', 'ring_03'], ['middle_metacarpal', 'middle_01', 'middle_02', 'middle_03'], ['index_metacarpal', 'index_01', 'index_02', 'index_03'], ['thumb_01', 'thumb_02', 'thumb_03']] constrain_parts = ['root', 'pelvis', 'spine', 'neck', 'head', 'clavicle', 'toe', 'metacarpal', 'thumb', 'index', 'middle', 'ring', 'pinky', '_ik_'] run_script = 1 user_decision = None axisUp = cmds.upAxis( q=True, axis=True ) if axisUp == 'y': cmds.setAttr("root_drv.rotateX", 90) if cmds.objExists('root_motion') or cmds.objExists('rig_setup') or cmds.objExists('rig_ctrls'): user_decision = cmds.confirmDialog( title='Confirm', message='Metahuman Body Ctrls found in scene. Delete and rebuild?', button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' ) if user_decision == 'Yes': if cmds.objExists('root_motion'): cmds.delete('root_motion') if cmds.objExists('rig_setup'): cmds.delete('rig_setup') if cmds.objExists('rig_ctrls'): cmds.delete('rig_ctrls') if cmds.objExists('face_gui_custom_labels_sceneConfigurationScriptNode'): cmds.delete('face_gui_custom_labels_sceneConfigurationScriptNode') if cmds.objExists('face_gui_custom_labels_uiConfigurationScriptNode'): cmds.delete('face_gui_custom_labels_uiConfigurationScriptNode') if user_decision == 'No': run_script = 0 if run_script == 1: # create motion skeleton (duplicate of driver skeleton to drive drv) cmds.duplicate('root_drv', n='root_motion', rc=1) cmds.select(cl=1) cmds.select('root_motion') cmds.select(hi=1) objLs = cmds.ls(sl=1) for num in range(0, len(objLs)): obj = objLs[num] if not '_motion' in obj: cmds.rename(obj, obj.replace(obj.split('_')[-1], 'motion')) # delete skinning helper bones from mocap skeleton delSkel() cmds.select(cl=1) cmds.select('root_motion') cmds.select(hi=1) objLs = cmds.ls(sl=1) # connect skeletons motion and drv for obj in objLs: #if not 'arm' in obj and not 'thigh' in obj: cmds.connectAttr(obj + '.translate', obj.replace('_motion', '_drv') + '.translate', f=1) cmds.connectAttr(obj + '.rotate', obj.replace('_motion', '_drv') + '.rotate', f=1) #else: #cmds.parentConstraint(obj, obj.replace('_motion', '_drv'), n = obj + '_parentCon') # rig setup group if not cmds.objExists('rig_setup'): cmds.group(n = 'rig_setup', em = 1) rig_setup_group = 'rig_setup' # rig ctrls group if not cmds.objExists('rig_ctrls'): cmds.group(n='rig_ctrls', em=1) else: cmds.delete('rig_ctrls') cmds.group(n='rig_ctrls', em=1) ############################### # create ik and fk limb joints for dir_str in dir_str_list: for type_str in type_str_list: for num in range(0, len(part_list)): part = part_list[num] cmds.duplicate(part + '_' + dir_str + '_motion', n=part + '_' + dir_str + '_' + type_str + '_motion', po = 1) if num > 0 and not num == 3: if not cmds.listRelatives(part + '_' + dir_str + '_' + type_str + '_motion', p=1)[0] == part_list[num-1] + '_' + dir_str + '_' + type_str + '_motion': cmds.parent(part + '_' + dir_str + '_' + type_str + '_motion', part_list[num-1] + '_' + dir_str + '_' + type_str + '_motion') else: cmds.parent(part + '_' + dir_str + '_' + type_str + '_motion', rig_setup_group) for part in part_list: cur_str = part + '_' + dir_str + '_' + type_str + '_motion' if part == 'upperarm' or part == 'thigh': cmds.parent(cur_str, cmds.listRelatives(part + '_' + dir_str + '_motion', p=1)[0]) for part in part_list: # create constraints constraint_name = part + '_' + dir_str + '_ikfk_motion' + '_orient_con' cmds.orientConstraint(part + '_' + dir_str + '_ik_motion', part + '_' + dir_str + '_fk_motion', part + '_' + dir_str + '_motion', n = constraint_name , mo = 1) cmds.setAttr(constraint_name + '.' + part + '_' + dir_str + '_ik_motionW0', 0) cmds.setAttr(constraint_name + '.' + part + '_' + dir_str + '_fk_motionW1', 1) # create ik handles cmds.ikHandle( sj='upperarm_' + dir_str + '_ik_motion', ee='hand_' + dir_str + '_ik_motion', s = 'sticky', n = 'hand_' + dir_str + '_ikHandle') cmds.parent('hand_' + dir_str + '_ikHandle', rig_setup_group) cmds.ikHandle( sj='thigh_' + dir_str + '_ik_motion', ee='foot_' + dir_str + '_ik_motion', s = 'sticky', n = 'foot_' + dir_str + '_ikHandle') cmds.parent('foot_' + dir_str + '_ikHandle', rig_setup_group) # create ctrl objects for num in range(0, len(metahuman_skeleton)): current_joint = metahuman_skeleton[num] current_motion_joint = current_joint + '_motion' current_ctrl = current_joint + '_ctrl' if 'pelvis' in current_ctrl: current_ctrl = current_ctrl.replace('pelvis', 'hips') if cmds.objExists(current_motion_joint): cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = metahuman_ctrl_radius[num], tol = 0, n = current_ctrl) cmds.setAttr(current_ctrl+"Shape.lineWidth", 2) cmds.parent(current_ctrl, 'rig_ctrls') #rotate 90 degrees if not 'root' in current_ctrl: cmds.setAttr(current_ctrl + '.ry', 90) #reset xform cmds.makeIdentity(current_ctrl, apply=True, t=1, r=1, s=1, n=0, pn=1) #parent con to get into position cmds.parentConstraint(current_motion_joint, current_ctrl, n = 'delete_con' ) cmds.delete('delete_con') metahuman_offset = create_offset(source_object = current_ctrl, offset_name = current_ctrl.replace('_ctrl', '_offset')) # collapses rig constrain_joint = 0 for constrain_string in constrain_parts: if constrain_string in current_joint: constrain_joint = 1 if constrain_joint == 1: cmds.pointConstraint(current_ctrl, current_motion_joint, n = current_ctrl + '_point_con' , mo = 1) cmds.orientConstraint(current_ctrl, current_motion_joint, n = current_ctrl + '_orient_con' , mo = 1) else: cmds.connectAttr(current_ctrl + '.translate', current_motion_joint + '.translate') cmds.connectAttr(current_ctrl + '.rotate', current_motion_joint + '.rotate') #parent ctrl for num in range(0, len(metahuman_skeleton)): current_joint = metahuman_skeleton[num] current_motion_joint = current_joint + '_motion' current_ctrl = current_joint + '_ctrl' current_offset = current_joint + '_offset' if 'pelvis' in current_ctrl: current_ctrl = current_ctrl.replace('pelvis', 'hips') if cmds.objExists(current_offset): if cmds.listRelatives(current_motion_joint, p=1): parent_ctrl = (cmds.listRelatives(current_motion_joint, p=1)[0]).replace('_motion', '_ctrl') if 'pelvis' in parent_ctrl: parent_ctrl = parent_ctrl.replace('pelvis', 'hips') if cmds.objExists(parent_ctrl): cmds.parent(current_offset, parent_ctrl) else: if 'metacarpal' in current_ctrl or 'thumb_01_' in current_ctrl: if '_r_' in current_ctrl: cmds.parentConstraint('hand_r_motion', current_ctrl.replace('_ctrl', '_offset'), mo=1) if '_l_' in current_ctrl: cmds.parentConstraint('hand_l_motion', current_ctrl.replace('_ctrl', '_offset'), mo=1) if 'toe' in current_ctrl: if '_r_' in current_ctrl: cmds.parentConstraint('ball_r_motion', current_ctrl.replace('_ctrl', '_offset'), mo=1) if '_l_' in current_ctrl: cmds.parentConstraint('ball_l_motion', current_ctrl.replace('_ctrl', '_offset'), mo=1) if 'head' in current_ctrl or 'spine' in current_ctrl or 'clavicle' in current_ctrl: makeNode = str(findMakeNode(current_ctrl, 'makeNurbCircle')) if makeNode!='None': cmds.setAttr (makeNode + '.degree', 1) cmds.setAttr (makeNode + '.sections', 6) # color ctrl objects if '_r_' in current_ctrl: cmds.setAttr(current_ctrl + 'Shape.overrideEnabled', 1) cmds.setAttr(current_ctrl + 'Shape.overrideRGBColors', 1) cmds.setAttr(current_ctrl + 'Shape.overrideColorRGB', 0.5, 0.0, 0.0) if '_l_' in current_ctrl: cmds.setAttr(current_ctrl + 'Shape.overrideEnabled', 1) cmds.setAttr(current_ctrl + 'Shape.overrideRGBColors', 1) cmds.setAttr(current_ctrl + 'Shape.overrideColorRGB', 0.0, 0.0, 0.5) if not '_l_' in current_ctrl and not '_r_' in current_ctrl: cmds.setAttr(current_ctrl + 'Shape.overrideEnabled', 1) cmds.setAttr(current_ctrl + 'Shape.overrideRGBColors', 1) cmds.setAttr(current_ctrl + 'Shape.overrideColorRGB', 1.0, 0.25, 0.0) attribute_cleanup(object=current_ctrl, translate_key = 0, translate_visible = 0, translate_lock = 1, rotation_key = 1, rotation_visible = 1, rotation_lock = 0, scale_key = 0, scale_visible = 0 , scale_lock = 1) ######################### # create additional ctrls attr_list = ['tx', 'ty', 'tz', 'sx', 'sy', 'sz'] ############# # global ctrl str_val = 'global' cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 50, tol = 0, n = str_val + '_ctrl') cmds.setAttr(str_val + '_ctrl' + "Shape.lineWidth", 2) makeNode = str(findMakeNode(str_val + '_ctrl', 'makeNurbCircle')) if makeNode!='None': cmds.setAttr (makeNode + '.degree', 1) cmds.setAttr (makeNode + '.sections', 6) cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideEnabled', 1) cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideRGBColors', 1) cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideColorRGB', 0.75, 0.75, 0.0) cmds.parent(str_val + '_ctrl', 'rig_ctrls') metahuman_offset = create_offset(source_object = str_val + '_ctrl', offset_name = str_val + '_ctrl'.replace('_ctrl', '_offset')) attribute_cleanup(object=str_val+'_ctrl', translate_key = 1, translate_visible = 0, translate_lock = 0, rotation_key = 1, rotation_visible = 0, rotation_lock = 0, scale_key = 1, scale_visible = 1 , scale_lock = 1) ################## # body offset ctrl cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 30, tol = 0, n = 'body_offset_ctrl') cmds.setAttr('body_offset_ctrl'+"Shape.lineWidth", 2) makeNode = str(findMakeNode('body_offset_ctrl', 'makeNurbCircle')) if makeNode!='None': cmds.setAttr (makeNode + '.degree', 1) cmds.setAttr (makeNode + '.sections', 6) cmds.setAttr('body_offset_ctrl' + 'Shape.overrideEnabled', 1) cmds.setAttr('body_offset_ctrl' + 'Shape.overrideRGBColors', 1) cmds.setAttr('body_offset_ctrl' + 'Shape.overrideColorRGB', 0.75, 0.75, 0.0) # 1 = 255 metahuman_offset = create_offset(source_object = 'body_offset_ctrl', offset_name = 'body_offset_ctrl'.replace('_ctrl', '_offset')) cmds.parent('body_offset_offset', 'global_ctrl') cmds.parent('root_offset', 'body_offset_ctrl') attribute_cleanup(object='body_offset_ctrl', translate_key = 1, translate_visible = 0, translate_lock = 0, rotation_key = 1, rotation_visible = 0, rotation_lock = 0, scale_key = 1, scale_visible = 1 , scale_lock = 1) ########### # body ctrl cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 35, tol = 0, n = 'body_ctrl') cmds.setAttr('body_ctrl'+"Shape.lineWidth", 2) makeNode = str(findMakeNode('body_ctrl', 'makeNurbCircle')) if makeNode!='None': cmds.setAttr (makeNode + '.degree', 1) cmds.setAttr (makeNode + '.sections', 6) cmds.setAttr ('body_ctrl' + '.degree', 1) cmds.setAttr('body_ctrl' + 'Shape.overrideEnabled', 1) cmds.setAttr('body_ctrl' + 'Shape.overrideRGBColors', 1) cmds.setAttr('body_ctrl' + 'Shape.overrideColorRGB', 0.75, 0.5, 0.0) # 1 = 255 cmds.setAttr('body_ctrl' + '.ry', 90) #reset xform cmds.makeIdentity('body_ctrl', apply=True, t=1, r=1, s=1, n=0, pn=1) #parent con to get into position cmds.parentConstraint( 'hips_ctrl', 'body_ctrl', n = 'delete_con' ) cmds.delete('delete_con') metahuman_offset = create_offset(source_object = 'body_ctrl', offset_name = 'body_ctrl'.replace('_ctrl', '_offset')) cmds.parent('body_offset', 'root_ctrl') cmds.parent('hips_offset', 'body_ctrl') cmds.parent('spine_01_offset', 'body_ctrl') attribute_cleanup(object='body_ctrl', translate_key = 1, translate_visible = 0, translate_lock = 0, rotation_key = 1, rotation_visible = 0, rotation_lock = 0, scale_key = 1, scale_visible = 1 , scale_lock = 1) # fk limbs controls for dir_str in dir_str_list: # create fk limb ctrls str_list = ['upperarm_'+ dir_str + '_fk', 'lowerarm_'+ dir_str + '_fk', 'hand_'+ dir_str + '_fk', 'thigh_'+ dir_str + '_fk', 'calf_'+ dir_str + '_fk', 'foot_'+ dir_str + '_fk', 'ball_'+ dir_str + '_fk', 'hand_'+ dir_str + '_ik', 'foot_'+ dir_str + '_ik'] for str_val in str_list: if 'thigh' in str_val: cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 15, tol = 0, n = str_val + '_ctrl') if 'ik' in str_val: cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 15, tol = 0, n = str_val + '_ctrl') if not 'thigh' in str_val and not 'ik' in str_val: cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 10, tol = 0, n = str_val + '_ctrl') cmds.setAttr(str_val + '_ctrl' + "Shape.lineWidth", 2) cmds.setAttr(str_val + '_ctrl' + '.ry', 90) if 'ball' in str_val + '_ctrl': cmds.setAttr(str_val + '_ctrl' + '.sx', .55) cmds.setAttr(str_val + '_ctrl' + '.sy', .55) cmds.setAttr(str_val + '_ctrl' + '.sz', .55) #reset xform cmds.makeIdentity(str_val + '_ctrl', apply=True, t=1, r=1, s=1, n=0, pn=1) #parent con to get into position cmds.parentConstraint(str_val + '_motion', str_val + '_ctrl', n = 'delete_con' ) cmds.delete('delete_con') if '_ik' in str_val: makeNode = str(findMakeNode(str_val + '_ctrl', 'makeNurbCircle')) if makeNode!='None': cmds.setAttr (makeNode + '.degree', 1) cmds.setAttr (makeNode + '.sections', 6) cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideEnabled', 1) cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideRGBColors', 1) if dir_str == 'l': cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideColorRGB', 0.0, 0.0, 0.75) if dir_str == 'r': cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideColorRGB', 0.75, 0.0, 0.0) metahuman_offset = str_val + '_ctrl'.replace('_ctrl', '_offset') create_offset(source_object = str_val + '_ctrl', offset_name = metahuman_offset) cmds.parent(str_val + '_offset', 'rig_ctrls') if not '_ik_' in (str_val + '_ctrl'): for attr in attr_list: cmds.setAttr(str_val + '_ctrl' + '.' + attr, lock = 1, k = 0) for num in range(0, len(part_list)): part = part_list[num] if part == 'hand' or part == 'foot': cmds.parentConstraint(part + '_'+ dir_str + '_ik_ctrl', part + '_' + dir_str + '_ikHandle', n = part + '_'+ dir_str + '_ik_ctrl_parent_con', mo=1 ) if part == 'upperarm': cmds.parent(part + '_' + dir_str + '_fk_offset', 'clavicle_' + dir_str + '_ctrl') if part == 'thigh': cmds.parent('thigh_' + dir_str + '_fk_offset', 'hips_ctrl') if not part == 'upperarm' and not part == 'thigh': cmds.parent(part + '_' + dir_str + '_fk_offset', part_list[num-1] + '_' + dir_str + '_fk_ctrl') # direct connection caused limbs orientation issue when root rotated cmds.orientConstraint(part + '_' + dir_str + '_fk_ctrl', part +'_' + dir_str + '_fk_motion', mo = 0, n = part + '_' + dir_str + '_fk_ctrl_parent_con') # create switch objects switch_object = 'hand_fkik_' + dir_str + '_switch' if not cmds.objExists(switch_object): cmds.group(n = switch_object, em = 1) cmds.textCurves( f='Arial', t='+', n = switch_object) shape_list = cmds.listRelatives(switch_object+'Shape', ad=1, typ='nurbsCurve') for current_shape in shape_list: cmds.parent(current_shape, switch_object, s=1, r=1) cmds.delete(switch_object+'Shape') #rotate 90 degrees cmds.setAttr(switch_object + '.rx', 90) #reset xform cmds.makeIdentity(switch_object, apply=True, t=1, r=1, s=1, n=0, pn=1) #parent con to get into position cmds.parentConstraint('upperarm_' + dir_str + '_fk_motion', switch_object, n = 'delete_con' ) cmds.delete('delete_con') #cmds.setAttr(switch_object + '.rx', 90) cmds.setAttr(switch_object + '.sx', 10) cmds.setAttr(switch_object + '.sy', 10) cmds.setAttr(switch_object + '.sz', 10) if dir_str == 'l': cmds.setAttr(switch_object + '.tx', 30) if dir_str == 'r': cmds.setAttr(switch_object + '.tx', -40) #reset xform cmds.makeIdentity(switch_object, apply=True, t=1, r=1, s=1, n=0, pn=1) cmds.parent(switch_object, 'rig_ctrls') cmds.parentConstraint('spine_01_motion', switch_object, n = 'spine_01_motion_parent_con', mo=1 ) # add attribute fk/ik cmds.addAttr(switch_object, longName='limb_fkik_switch', shortName='limb_fk_ik', attributeType='float', keyable=True, defaultValue=0.0, minValue=0.0, maxValue=1.0) cmds.setAttr(switch_object+'.limb_fk_ik', cb=1, c=1, keyable=True) attribute_cleanup(object=switch_object, translate_key = 0, translate_visible = 0, translate_lock = 0, rotation_key = 0, rotation_visible = 0, rotation_lock = 0, scale_key = 0, scale_visible = 0 , scale_lock = 0) switch_object = 'foot_fkik_' + dir_str + '_switch' if not cmds.objExists(switch_object): cmds.group(n = switch_object, em = 1) cmds.textCurves( f='Arial', t='+', n = switch_object) shape_list = cmds.listRelatives(switch_object+'Shape', ad=1, typ='nurbsCurve') for current_shape in shape_list: cmds.parent(current_shape, switch_object, s=1, r=1) cmds.delete(switch_object+'Shape') #parent con to get into position cmds.parentConstraint('thigh_' + dir_str + '_fk_motion', switch_object, n = 'delete_con' ) cmds.delete('delete_con') cmds.setAttr(switch_object + '.rx', 90) cmds.setAttr(switch_object + '.sx', 10) cmds.setAttr(switch_object + '.sy', 10) cmds.setAttr(switch_object + '.sz', 10) if dir_str == 'l': cmds.setAttr(switch_object + '.tx', 30) if dir_str == 'r': cmds.setAttr(switch_object + '.tx', -40) #reset xform cmds.makeIdentity(switch_object, apply=True, t=1, r=1, s=1, n=0, pn=1) cmds.parent(switch_object, 'rig_ctrls') cmds.parentConstraint('spine_05_motion', switch_object, n = 'spine_05_motion_parent_con' , mo=1) # add attribute fk/ik cmds.addAttr(switch_object, longName='limb_fkik_switch', shortName='limb_fk_ik', attributeType='float', keyable=True, defaultValue=0.0, minValue=0.0, maxValue=1.0) cmds.setAttr(switch_object+'.limb_fk_ik', cb=1, c=1) attribute_cleanup(object=switch_object, translate_key = 0, translate_visible = 0, translate_lock = 1, rotation_key = 0, rotation_visible = 0, rotation_lock = 1, scale_key = 0, scale_visible = 0 , scale_lock = 1) # position pole vector pole_vector_location_ref = create_pole_vector_object(boneA='upperarm_' + dir_str + '_ik_motion', boneB='lowerarm_' + dir_str + '_ik_motion', boneC='hand_' + dir_str + '_ik_motion') # arm pole vectors str_val = 'arm_pole_vector_' + dir_str cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 5, tol = 0, n = str_val + '_ctrl') cmds.setAttr(str_val + '_ctrl' + "Shape.lineWidth", 2) #parent con to get into position cmds.parentConstraint(pole_vector_location_ref, str_val + '_ctrl', n = 'delete_con' ) cmds.delete('delete_con') cmds.delete(pole_vector_location_ref) makeNode = str(findMakeNode(str_val + '_ctrl', 'makeNurbCircle')) if makeNode!='None': cmds.setAttr (makeNode + '.degree', 1) cmds.setAttr (makeNode + '.sections', 6) cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideEnabled', 1) cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideRGBColors', 1) if dir_str == 'l': cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideColorRGB', 0.0, 0.0, 0.75) if dir_str == 'r': cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideColorRGB', 0.75, 0.0, 0.0) cmds.setAttr(str_val + '_ctrl' + '.ty', 50) cmds.setAttr(str_val + '_ctrl' + '.ry', 90) cur_offset = str_val + '_offset' cur_str = str_val + '_ctrl' # creates offset for pole vectors if not cmds.objExists(str_val + '_offset'): cmds.group(n = str_val + '_offset', em = 1) # parent con to get into position cmds.parentConstraint(cur_str, cur_offset, n = 'delete_con' ) cmds.delete('delete_con') cmds.parent(cur_str, cur_offset) cmds.parent(cur_offset, 'rig_ctrls') cmds.poleVectorConstraint(str_val + '_ctrl', 'hand_' + dir_str + '_ikHandle' ) cur_match = str_val+'_match' cur_offset = str_val + '_match_offset' cmds.duplicate(str_val + '_ctrl', n=cur_match) cmds.scale( .3, .3, .3, cur_match, relative=True) #reset xform cmds.makeIdentity(cur_match, apply=True, t=1, r=1, s=1, n=0, pn=1) # creates offset for pole vectors if not cmds.objExists(cur_offset): cmds.group(n = cur_offset, em = 1) # parent con to get into position cmds.parentConstraint(cur_match, cur_offset, n = 'delete_con' ) cmds.delete('delete_con') if cmds.listRelatives(cur_match, p=1): if not cmds.listRelatives(cur_match, p=1)[0] == cur_offset: cmds.parent(cur_match, cur_offset) else: cmds.parent(cur_match, cur_offset) cmds.parent(cur_offset, 'rig_ctrls') cmds.parentConstraint('lowerarm_' + dir_str + '_fk_motion', cur_offset, mo=1) # position pole vector pole_vector_location_ref = create_pole_vector_object(boneA='thigh_' + dir_str + '_ik_motion', boneB='calf_' + dir_str + '_ik_motion', boneC='foot_' + dir_str + '_ik_motion') # leg pole vector str_val = 'leg_pole_vector_' + dir_str cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 5, tol = 0, n = str_val + '_ctrl') cmds.setAttr(str_val + '_ctrl' + "Shape.lineWidth", 2) #parent con to get into position cmds.parentConstraint(pole_vector_location_ref, str_val + '_ctrl', n = 'delete_con' ) cmds.delete('delete_con') cmds.delete(pole_vector_location_ref) makeNode = str(findMakeNode(str_val + '_ctrl', 'makeNurbCircle')) if makeNode!='None': cmds.setAttr (makeNode + '.degree', 1) cmds.setAttr (makeNode + '.sections', 6) cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideEnabled', 1) cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideRGBColors', 1) if dir_str == 'l': cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideColorRGB', 0.0, 0.0, 0.75) if dir_str == 'r': cmds.setAttr(str_val + '_ctrl' + 'Shape.overrideColorRGB', 0.75, 0.0, 0.0) cmds.setAttr(str_val + '_ctrl' + '.ty', -50) cmds.setAttr(str_val + '_ctrl' + '.ry', 90) cur_offset = str_val + '_offset' cur_str = str_val + '_ctrl' # creates offset for pole vectors if not cmds.objExists(str_val + '_offset'): cmds.group(n = str_val + '_offset', em = 1) # parent con to get into position cmds.parentConstraint(cur_str, cur_offset, n = 'delete_con' ) cmds.delete('delete_con') cmds.parent(cur_str, cur_offset) cmds.parent(cur_offset, 'rig_ctrls') #reset xform cmds.makeIdentity(str_val + '_ctrl', apply=True, t=1, r=1, s=1, n=0, pn=1) cmds.poleVectorConstraint(str_val + '_ctrl', 'foot_' + dir_str + '_ikHandle', n='foot_' + dir_str + '_poleVector_con') cur_match = str_val+'_match' cur_offset = str_val + '_match_offset' cmds.duplicate(str_val + '_ctrl', n=cur_match) cmds.scale( .3, .3, .3, cur_match, relative=True) #reset xform cmds.makeIdentity(cur_match, apply=True, t=1, r=1, s=1, n=0, pn=1) # creates offset for pole vectors if not cmds.objExists(cur_offset): cmds.group(n = cur_offset, em = 1) # parent con to get into position cmds.parentConstraint(cur_match, cur_offset, n = 'delete_con' ) cmds.delete('delete_con') if cmds.listRelatives(cur_match, p=1): if not cmds.listRelatives(cur_match, p=1)[0] == cur_offset: cmds.parent(cur_match, cur_offset) else: cmds.parent(cur_match, cur_offset) cmds.parent(cur_offset, 'rig_ctrls') cmds.parentConstraint('calf_' + dir_str + '_fk_motion', cur_offset, mo=1) cmds.orientConstraint('hand_' + dir_str + '_ik_ctrl', 'hand_' + dir_str + '_ik_motion', mo=0) cmds.orientConstraint('foot_' + dir_str + '_ik_ctrl', 'foot_' + dir_str + '_ik_motion', mo=0) attribute_cleanup(object='hand_' + dir_str + '_ik_ctrl', translate_key = 1, translate_visible = 1, translate_lock = 0, rotation_key = 1, rotation_visible = 1, rotation_lock = 0, scale_key = 0, scale_visible = 0 , scale_lock = 1) attribute_cleanup(object='foot_' + dir_str + '_ik_ctrl', translate_key = 1, translate_visible = 1, translate_lock = 0, rotation_key = 1, rotation_visible = 1, rotation_lock = 0, scale_key = 0, scale_visible = 0 , scale_lock = 1) # parent con ik ctrls and pole vector ctrls cmds.parentConstraint('root_ctrl', 'hand_' + dir_str + '_ik_offset', mo=1) cmds.parentConstraint('root_ctrl', 'foot_' + dir_str + '_ik_offset', mo=1) cmds.parentConstraint('root_ctrl', 'arm_pole_vector_' + dir_str + '_offset', mo=1) cmds.parentConstraint('root_ctrl', 'leg_pole_vector_' + dir_str + '_offset', mo=1) attribute_cleanup(object='arm_pole_vector_' + dir_str + '_ctrl', translate_key = 1, translate_visible = 1, translate_lock = 0, rotation_key = 0, rotation_visible = 0, rotation_lock = 1, scale_key = 0, scale_visible = 0 , scale_lock = 1) attribute_cleanup(object='leg_pole_vector_' + dir_str + '_ctrl', translate_key = 1, translate_visible = 1, translate_lock = 0, rotation_key = 0, rotation_visible = 0, rotation_lock = 1, scale_key = 0, scale_visible = 0 , scale_lock = 1) # fk ik connections partA_list = ('upperarm', 'lowerarm', 'hand', 'thigh', 'calf', 'foot', 'ball') partB_list = ('hand', 'hand', 'hand', 'foot', 'foot', 'foot', 'foot') for num in range(0,len(partA_list)): partStrA = partA_list[num] partStrB = partB_list[num] if cmds.objExists('plusMinusAverage_' + partStrA + '_' + dir_str): cmds.delete('plusMinusAverage_' + partStrA + '_' + dir_str) pmavg = cmds.shadingNode('plusMinusAverage', au=1, n = 'plusMinusAverage_' + partStrA + '_' + dir_str) cmds.setAttr(pmavg+'.operation', 2) if cmds.objExists('floatConstant_' + partStrA + '_' + dir_str): cmds.delete('floatConstant_' + partStrA + '_' + dir_str) floatConst = cmds.shadingNode('floatConstant', au=1, n = 'floatConstant_' + partStrA + '_' + dir_str) cmds.connectAttr(floatConst + '.outFloat', pmavg + '.input1D[0]', f=1) cmds.connectAttr(partStrB + '_fkik_' + dir_str + '_switch' + '.limb_fkik_switch', partStrA + '_' + dir_str + '_ikfk_motion_orient_con' + '.' + partStrA + '_' + dir_str + '_ik_motionW0', f=1) cmds.connectAttr(pmavg + '.output1D', partStrA + '_' + dir_str + '_ikfk_motion_orient_con' + '.' + partStrA + '_' + dir_str + '_fk_motionW1', f=1) cmds.connectAttr(partStrB + '_fkik_' + dir_str + '_switch' + '.limb_fkik_switch', pmavg + '.input1D[1]', f=1) if cmds.objExists(partStrA + '_' + dir_str + '_fk_ctrl'): cmds.connectAttr(pmavg + '.output1D', partStrA + '_' + dir_str + '_fk_ctrl.visibility', f=1) if cmds.objExists(partStrA + '_' + dir_str + '_ik_ctrl'): cmds.connectAttr(partStrB + '_fkik_' + dir_str + '_switch.limb_fkik_switch', partStrA + '_' + dir_str + '_ik_ctrl.visibility', f=1) cmds.setAttr('arm_pole_vector_' + dir_str + '_match.visibility',0) cmds.setAttr('leg_pole_vector_' + dir_str + '_match.visibility',0) cmds.setAttr('foot_fkik_' + dir_str +'_switch.limb_fkik_switch', c=1) if cmds.objExists('arm_pole_vector_' + dir_str + '_ctrl'): cmds.connectAttr('hand_fkik_' + dir_str + '_switch.limb_fkik_switch', 'arm_pole_vector_' + dir_str + '_ctrl.visibility', f=1) if cmds.objExists('leg_pole_vector_' + dir_str + '_ctrl'): cmds.connectAttr('foot_fkik_' + dir_str + '_switch.limb_fkik_switch', 'leg_pole_vector_' + dir_str + '_ctrl.visibility', f=1) #################### # reverse foot setup foot_roll_list = ['foot', 'ball', 'toe'] for foot_roll_str in foot_roll_list: foot_loc = foot_roll_str + '_' + dir_str + '_loc' cmds.spaceLocator(n=foot_loc) if not foot_roll_str == 'toe': cmds.parentConstraint(foot_roll_str + '_' + dir_str + '_ik_motion', foot_loc, mo=0, n = 'delete_con') else: cmds.parentConstraint('ball_' + dir_str + '_ik_motion', foot_loc, mo=0, n = 'delete_con') cmds.delete('delete_con') if foot_roll_str == 'foot': cmds.parent(foot_loc, 'rig_setup') else: cmds.parent(foot_loc, 'foot_' + dir_str + '_loc') if foot_roll_str == 'ball': cmds.makeIdentity(foot_loc, apply=True, t=1, r=1, s=1, n=0, pn=1) # position toe at front of foot if foot_roll_str == 'toe': val = cmds.getAttr(foot_loc + '.translateY') cmds.setAttr(foot_loc + '.translateY', val - 7) cmds.setAttr(foot_loc + '.translateZ', 0) #reset xform cmds.makeIdentity(foot_loc, apply=True, t=1, r=1, s=1, n=0, pn=1) # position foot at heel lcoation if foot_roll_str == 'foot': val = cmds.getAttr(foot_loc + '.translateY') cmds.setAttr(foot_loc + '.translateY', val + 5) cmds.setAttr(foot_loc + '.translateZ', 0) #reset xform cmds.makeIdentity(foot_loc, apply=True, t=1, r=1, s=1, n=0, pn=1) cmds.group(foot_loc, n=foot_loc.replace('_loc', '_offset')) cmds.parentConstraint('foot_' + dir_str + '_ik_ctrl', foot_loc.replace('_loc', '_offset'), mo=1) else: cmds.group(foot_loc, n=foot_loc.replace('_loc', '_offset')) if foot_roll_str == 'toe': current_joint = foot_roll_str + '_' + dir_str + '_ik_motion' cmds.joint(n = current_joint, p=(0, 0, 0) ) cmds.parentConstraint(foot_roll_str + '_' + dir_str + '_offset', current_joint, mo=0, n='delete_con') cmds.delete('delete_con') cmds.parent(current_joint, 'ball_' + dir_str + '_ik_motion') if cmds.objExists('foot_' + dir_str + '_ik_ctrl_parent_con'): cmds.delete('foot_' + dir_str + '_ik_ctrl_parent_con') cmds.ikHandle( sj='foot_' + dir_str + '_ik_motion', ee='ball_' + dir_str + '_ik_motion', p=2, w=.5, s = 'sticky', n = 'ball_rev_' + dir_str + '_ikHandle' ) cmds.parent('ball_rev_' + dir_str + '_ikHandle', 'ball_'+dir_str+'_loc') cmds.ikHandle( sj='ball_' + dir_str + '_ik_motion', ee='toe_' + dir_str + '_ik_motion', p=2, w=.5, s = 'sticky', n = 'toe_rev_' + dir_str + '_ikHandle' ) cmds.parent('toe_rev_' + dir_str + '_ikHandle', 'foot_'+dir_str+'_loc') cmds.parentConstraint('ball_'+dir_str+'_loc', 'foot_' + dir_str + '_ikHandle', mo=1, n='foot_' + dir_str + '_ikHandle_Con') cmds.parent('ball_' + dir_str + '_offset', 'toe_'+dir_str+'_loc') # create custom attributes ctrl_name = 'foot_' + dir_str + '_ik_ctrl' cmds.addAttr(ctrl_name, longName = 'Roll', shortName = 'Roll', attributeType='float', keyable=True, defaultValue=0.0, minValue=-30.0, maxValue=70.0) cmds.setAttr(ctrl_name+'.Roll', cb=1, c=1) cmds.addAttr(ctrl_name, longName = 'Bend_Limit_Angle', shortName = 'BendLimitAngle', attributeType='float', defaultValue=45.0, minValue=-180.0, maxValue=180.0) cmds.setAttr(ctrl_name+'.Bend_Limit_Angle', cb=1, c=1, l=1) cmds.addAttr(ctrl_name, longName = 'Toe_Straight', shortName = 'ToeStraight', attributeType='float', defaultValue=75.0, minValue=-180.0, maxValue=180.0) cmds.setAttr(ctrl_name+'.Toe_Straight', cb=1, c=1, l=1) nodeStr = 'foot_rot_clamp_' + dir_str if cmds.objExists(nodeStr): cmds.delete(nodeStr) cmds.shadingNode('clamp', au=1, n= nodeStr) cmds.connectAttr('foot_' + dir_str + '_ik_ctrl.Roll', nodeStr + '.inputR', f=1) cmds.setAttr(nodeStr + '.minR', -90) cmds.setAttr(nodeStr + '.maxR', 0) cmds.connectAttr(nodeStr + '.outputR', 'foot_' + dir_str + '_loc.rotateX', f=1) nodeStr = 'ball_zeroToBlend_clamp_' + dir_str if cmds.objExists(nodeStr): cmds.delete(nodeStr) cmds.shadingNode('clamp', au=1, n= nodeStr) cmds.connectAttr('foot_' + dir_str + '_ik_ctrl.Roll', nodeStr + '.inputR', f=1) cmds.setAttr(nodeStr + '.minR', 0) cmds.connectAttr(ctrl_name+'.Bend_Limit_Angle', nodeStr + '.maxR', f=1) nodeStrAB = 'toe_setRange_zeroToBendPercent' + dir_str if cmds.objExists(nodeStrAB): cmds.delete(nodeStrAB) cmds.shadingNode('setRange', au=1, n= nodeStrAB) cmds.connectAttr(nodeStr + '.minR', nodeStrAB + '.oldMinX', f=1) cmds.connectAttr(nodeStr + '.maxR', nodeStrAB + '.oldMaxX', f=1) cmds.setAttr(nodeStrAB + '.maxX', 1) cmds.setAttr(nodeStrAB + '.minX', 0) cmds.connectAttr(nodeStr + '.inputR', nodeStrAB + '.valueX', f=1) nodeStr = 'toe_rot_clamp_' + dir_str if cmds.objExists(nodeStr): cmds.delete(nodeStr) cmds.shadingNode('clamp', au=1, n= nodeStr) cmds.connectAttr('foot_' + dir_str + '_ik_ctrl.Bend_Limit_Angle', nodeStr + '.minR', f=1) cmds.connectAttr('foot_' + dir_str + '_ik_ctrl.Toe_Straight', nodeStr + '.maxR', f=1) cmds.connectAttr('foot_' + dir_str + '_ik_ctrl.Roll', nodeStr + '.inputR', f=1) nodeStrB = 'toe_setRange_bendToStraightPercent_' + dir_str if cmds.objExists(nodeStrB): cmds.delete(nodeStrB) cmds.shadingNode('setRange', au=1, n= nodeStrB) cmds.connectAttr(nodeStr + '.minR', nodeStrB + '.oldMinX', f=1) cmds.connectAttr(nodeStr + '.maxR', nodeStrB + '.oldMaxX', f=1) cmds.setAttr(nodeStrB + '.maxX', 1) cmds.setAttr(nodeStrB + '.minX', 0) cmds.connectAttr(nodeStr + '.inputR', nodeStrB + '.valueX', f=1) nodeStrAC = 'toe_invertPercentage_' + dir_str if cmds.objExists(nodeStrAC): cmds.delete(nodeStrAC) cmds.shadingNode('plusMinusAverage', au=1, n= nodeStrAC) cmds.setAttr(nodeStrAC+'.input1D[0]', 1) cmds.setAttr(nodeStrAC+'.input1D[1]', 1) cmds.connectAttr(nodeStrB + '.outValueX', nodeStrAC + '.input1D[1]', f=1) cmds.setAttr(nodeStrAC + '.operation', 2) nodeStrBC = 'ball_percentMult_multiplydivide_' + dir_str if cmds.objExists(nodeStrBC): cmds.delete(nodeStrBC) cmds.shadingNode('multiplyDivide', au=1, n= nodeStrBC) cmds.connectAttr(nodeStrAB + '.outValueX', nodeStrBC + '.input1X', f=1) cmds.connectAttr(nodeStrAC + '.output1D', nodeStrBC + '.input2X', f=1) nodeStrCC = 'ball_rollMult_multiplydivide_' + dir_str if cmds.objExists(nodeStrCC): cmds.delete(nodeStrCC) cmds.shadingNode('multiplyDivide', au=1, n= nodeStrCC) cmds.connectAttr(nodeStrBC + '.outputX', nodeStrCC + '.input1X', f=1) cmds.connectAttr('foot_' + dir_str + '_ik_ctrl.Roll', nodeStrCC + '.input2X', f=1) cmds.connectAttr(nodeStrCC + '.outputX', 'ball_' + dir_str + '_loc.rotateX', f=1) nodeStrC = 'toe_rot_multiplydivide_' + dir_str if cmds.objExists(nodeStrC): cmds.delete(nodeStrC) cmds.shadingNode('multiplyDivide', au=1, n= nodeStrC) cmds.connectAttr(nodeStrB + '.outValueX', nodeStrC + '.input1X', f=1) cmds.connectAttr(nodeStr + '.inputR', nodeStrC + '.input2X', f=1) cmds.connectAttr(nodeStrC + '.outputX', 'toe_' + dir_str + '_loc' + '.rotateX', f=1) ############################# # additional ik toe controls # Toe Twist Ctrl ctrl_name = 'toe_twist' + '_' + dir_str + '_ik_ctrl' cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 3, tol = 0, n = ctrl_name) cmds.setAttr(ctrl_name + "Shape.lineWidth", 2) makeNode = str(findMakeNode(ctrl_name, 'makeNurbCircle')) if makeNode!='None': cmds.setAttr (makeNode + '.degree', 1) cmds.setAttr (makeNode + '.sections', 6) cmds.setAttr(ctrl_name + 'Shape.overrideEnabled', 1) cmds.setAttr(ctrl_name + 'Shape.overrideRGBColors', 1) if dir_str == 'l': cmds.setAttr(ctrl_name + 'Shape.overrideColorRGB', 0.0, 0.0, 0.75) if dir_str == 'r': cmds.setAttr(ctrl_name + 'Shape.overrideColorRGB', 0.75, 0.0, 0.0) #parent con to get into position cmds.parentConstraint('toe_' + dir_str + '_loc', ctrl_name, n = 'delete_con' ) cmds.delete('delete_con') current_offset = create_offset(source_object = ctrl_name, offset_name = ctrl_name.replace('_ctrl', '_offset')) cmds.parentConstraint('toe_' + dir_str + '_loc', current_offset, n = current_offset + '_con', mo = 1 ) cmds.parent(current_offset, 'rig_ctrls') cmds.connectAttr('toe_twist_' + dir_str + '_ik_ctrl.rotateZ', 'toe_' + dir_str + '_loc.rotateZ', f=1) attribute_cleanup(object=ctrl_name, translate_key = 0, translate_visible = 0, translate_lock = 0, rotation_key = 1, rotation_visible = 1, rotation_lock = 0, scale_key = 0, scale_visible = 0, scale_lock = 0) cmds.setAttr(ctrl_name + '.translate'+'X', keyable=0) cmds.setAttr(ctrl_name + '.rotate'+'X', k=0, cb=0, l=1) cmds.setAttr(ctrl_name + '.translate'+'Y', keyable=0) cmds.setAttr(ctrl_name + '.rotate'+'Y', k=0, cb=0, l=1) if cmds.objExists('leg_pole_vector_' + dir_str + '_ctrl'): cmds.connectAttr('foot_fkik_' + dir_str + '_switch.limb_fkik_switch', 'toe_twist_' + dir_str + '_ik_ctrl.visibility', f=1) # toe IK rotate ctrl ball_lift_joint = 'ball_lift_' + dir_str + '_ik_motion' cmds.duplicate('ball_' + dir_str + '_ik_motion', n=ball_lift_joint, rc=1) duplicates_list = cmds.listRelatives('ball_lift_' + dir_str + '_ik_motion') for duplicate in duplicates_list: if 'effector' in duplicate: cmds.delete(duplicate) cmds.rename(cmds.listRelatives(ball_lift_joint, c=1)[0], ball_lift_joint.replace('ball_', 'toe_')) ball_lift_joint = 'ball_lift_' + dir_str + '_ik_motion' cmds.parent(ball_lift_joint, 'rig_setup') current_offset = create_offset(source_object = ball_lift_joint, offset_name = ball_lift_joint.replace('_motion', '_motion_offset')) cmds.parentConstraint('ball_' + dir_str + '_ik_motion', current_offset, n =current_offset + '_con', mo=1) # create control ctrl_name = 'ball_lift' + '_' + dir_str + '_ik_ctrl' cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 5, tol = 0, n = ctrl_name) cmds.setAttr(ctrl_name + "Shape.lineWidth", 2) makeNode = str(findMakeNode(ctrl_name, 'makeNurbCircle')) if makeNode!='None': cmds.setAttr (makeNode + '.degree', 1) cmds.setAttr (makeNode + '.sections', 6) #rotate 90 degrees cmds.setAttr(ctrl_name + '.ry', 90) #reset xform cmds.makeIdentity(ctrl_name, apply=True, t=1, r=1, s=1, n=0, pn=1) cmds.setAttr(ctrl_name + 'Shape.overrideEnabled', 1) cmds.setAttr(ctrl_name + 'Shape.overrideRGBColors', 1) if dir_str == 'l': cmds.setAttr(ctrl_name + 'Shape.overrideColorRGB', 0.0, 0.0, 0.75) if dir_str == 'r': cmds.setAttr(ctrl_name + 'Shape.overrideColorRGB', 0.75, 0.0, 0.0) # parent con to get into position cmds.parentConstraint('ball_' + dir_str + '_fk_ctrl', ctrl_name, n = 'delete_con' ) cmds.delete('delete_con') cmds.parent(ctrl_name, 'rig_ctrls') current_offset = create_offset(source_object = ctrl_name, offset_name = ctrl_name.replace('_ctrl', '_offset')) if cmds.objExists(current_offset + '_parent_con'): print('deleteing old constraint') cmds.delete(current_offset + '_parent_con') cmds.parentConstraint('ball_' + dir_str + '_ik_motion', current_offset, n=current_offset + '_parent_con', mo=1) cmds.orientConstraint(ctrl_name, ball_lift_joint, n = ctrl_name + '_orient_con', mo=1) orient_con = 'ball' + '_' + dir_str + '_ikfk_motion_orient_con' if dir_str: if cmds.objExists(orient_con): cmds.delete(orient_con) # create constraints cmds.orientConstraint(ball_lift_joint, 'ball' + '_' + dir_str + '_fk_motion', 'ball' + '_' + dir_str + '_motion', n = orient_con, mo = 1) # fk ik connections partStrA = 'ball_lift' #partA_list[num] partStrB = 'foot' #partB_list[num] if cmds.objExists('plusMinusAverage_' + partStrA + '_' + dir_str): cmds.delete('plusMinusAverage_' + partStrA + '_' + dir_str) pmavg = cmds.shadingNode('plusMinusAverage', au=1, n = 'plusMinusAverage_' + partStrA + '_' + dir_str) cmds.setAttr(pmavg+'.operation', 2) if cmds.objExists('floatConstant_' + partStrA + '_' + dir_str): cmds.delete('floatConstant_' + partStrA + '_' + dir_str) floatConst = cmds.shadingNode('floatConstant', au=1, n = 'floatConstant_' + partStrA + '_' + dir_str) cmds.connectAttr(floatConst + '.outFloat', pmavg + '.input1D[0]', f=1) cmds.connectAttr(partStrB + '_fkik_' + dir_str + '_switch' + '.limb_fkik_switch', orient_con + '.' + partStrA + '_' + dir_str + '_ik_motionW0', f=1) cmds.connectAttr(pmavg + '.output1D', orient_con + '.' + partStrA.replace('_lift', '') + '_' + dir_str + '_fk_motionW1', f=1) cmds.connectAttr(partStrB + '_fkik_' + dir_str + '_switch' + '.limb_fkik_switch', pmavg + '.input1D[1]', f=1) if cmds.objExists(partStrA + '_' + dir_str + '_fk_ctrl'): cmds.connectAttr(pmavg + '.output1D', partStrA + '_' + dir_str + '_fk_ctrl.visibility', f=1) if cmds.objExists(partStrA + '_' + dir_str + '_ik_ctrl'): cmds.connectAttr(partStrB + '_fkik_' + dir_str + '_switch.limb_fkik_switch', partStrA + '_' + dir_str + '_ik_ctrl.visibility', f=1) cmds.setAttr(ctrl_name + '.translate'+'X', keyable=0) cmds.setAttr(ctrl_name + '.rotate'+'X', k=0, cb=0, l=1) cmds.setAttr(ctrl_name + '.translate'+'Y', keyable=0) cmds.setAttr(ctrl_name + '.rotate'+'Y', k=0, cb=0, l=1) ctrl_name = ctrl_name.replace('_lift', '').replace('_ik_', '_fk_') cmds.setAttr(ctrl_name + '.translate'+'X', keyable=0) cmds.setAttr(ctrl_name + '.rotate'+'X', k=0, cb=0, l=1) cmds.setAttr(ctrl_name + '.translate'+'Y', keyable=0) cmds.setAttr(ctrl_name + '.rotate'+'Y', k=0, cb=0, l=1) ################# # finger custom attr controls ctrl_name = 'fingers' + '_' + dir_str + '_ctrl' cmds.circle( nr=(0, 0, 1), c=(0, 0, 0), r = 10, tol = 0, n = ctrl_name) cmds.setAttr(ctrl_name + "Shape.lineWidth", 2) #parent con to get into position cmds.parentConstraint('hand_' + dir_str + '_motion', ctrl_name, n = 'delete_con' ) cmds.delete('delete_con') cmds.parentConstraint('middle_03_' + dir_str + '_ctrl', ctrl_name, n = 'delete_con' ) cmds.delete('delete_con') cmds.setAttr(ctrl_name + '.rx', -105) cmds.setAttr(ctrl_name + '.sx', .25) # direct connection puts it in the wrong place cmds.parentConstraint('hand_' + dir_str + '_motion', ctrl_name, n = ctrl_name + '_con', mo = 1 ) cmds.parent(ctrl_name, 'rig_ctrls') cmds.setAttr(ctrl_name + 'Shape.overrideEnabled', 1) cmds.setAttr(ctrl_name + 'Shape.overrideRGBColors', 1) if dir_str == 'l': cmds.setAttr(ctrl_name + 'Shape.overrideColorRGB', 0.0, 0.0, 0.75) if dir_str == 'r': cmds.setAttr(ctrl_name + 'Shape.overrideColorRGB', 0.75, 0.0, 0.0) finger_list = ('thumb', 'index', 'middle', 'ring', 'pinky', 'spread') for finger_str in finger_list: # add attributes if not finger_str == 'spread': cmds.addAttr(ctrl_name, longName = finger_str + '_curl', shortName = finger_str, attributeType='float', keyable=True, defaultValue=0.0, minValue=-30.0, maxValue=90.0 ) cmds.setAttr(ctrl_name + '.' + finger_str, cb=1, c=1) else: if finger_str == 'index' or finger_str == 'middle': cmds.addAttr(ctrl_name, longName = 'spread_fingers', shortName = 'spread', attributeType='float', keyable=True, defaultValue=0.0, minValue=-10.0, maxValue=10.0) else: cmds.addAttr(ctrl_name, longName = 'spread_fingers', shortName = 'spread', attributeType='float', keyable=True, defaultValue=0.0, minValue=-10.0, maxValue=10.0) cmds.setAttr(ctrl_name + '.' + 'spread', cb=1, c=1) for finger_str in finger_list: if not finger_str == 'spread': for num in range(1,3): cur_str = finger_str + '_0' + str(num) + '_' + dir_str + '_motion' cur_offset = cur_str.replace('_motion', '_offsetA') cur_ctrl = cur_str.replace('_motion', '_ctrl') if not cmds.objExists(cur_offset): cmds.group(n=cur_offset, em=1) #parent con to get into position cmds.parentConstraint(cur_str, cur_offset, n = 'delete_con' ) cmds.delete('delete_con') if num == 1: if not finger_str == 'thumb': cmds.parent(cur_offset, 'rig_ctrls') cmds.parentConstraint(finger_str + '_metacarpal_' + dir_str +'_motion',cur_offset, mo=1) else: cmds.parentConstraint('hand_' + dir_str +'_motion',cur_offset, mo=1) cmds.parent(cur_offset, 'rig_ctrls') else: cmds.parent(cur_offset, finger_str + '_0' + str(num-1) + '_' + dir_str + '_ctrl') cur_offsetB = cur_offset.replace('_offsetA', '_offsetB') cmds.duplicate(cur_offset, n = cur_offsetB, po=1 ) cmds.parent(cur_offsetB, cur_offset) attribute_cleanup(object=cur_ctrl, translate_key = 1, translate_visible = 0, translate_lock = 0, rotation_key = 1, rotation_visible = 1, rotation_lock = 0, scale_key = 1, scale_visible = 0 , scale_lock = 0) if not cmds.listRelatives(cur_ctrl, p=1)[0] == cur_offsetB: cmds.parent(cur_ctrl, cur_offsetB) attribute_cleanup(object=cur_ctrl, translate_key = 0, translate_visible = 0, translate_lock = 0, rotation_key = 1, rotation_visible = 1, rotation_lock = 0, scale_key = 0, scale_visible = 1 , scale_lock = 0) cmds.connectAttr('fingers_' + dir_str + '_ctrl.' + finger_str, finger_str + '_0' + str(num) + '_' + dir_str + '_offsetB.rotateZ', f=1) for finger_str in finger_list: if not finger_str == 'spread' and not finger_str == 'thumb': if finger_str == 'index' or finger_str == 'middle': if finger_str == 'middle': cmds.connectAttr('fingers_' + dir_str + '_ctrl.spread', finger_str + '_01_' + dir_str + '_offsetB.rotateY', f=1) else: nodeStr = finger_str + '_01_' + dir_str + '_multiplyDivide' cmds.shadingNode('multiplyDivide', au=1, n= nodeStr) cmds.setAttr(nodeStr + '.input2X', 2) cmds.connectAttr('fingers_' + dir_str + '_ctrl.spread', nodeStr + '.input1X', f=1) cmds.connectAttr(nodeStr + '.outputX', finger_str + '_01_' + dir_str + '_offsetB.rotateY', f=1) else: mult = -1 if finger_str == 'pinky': mult = -2 nodeStr = finger_str + '_01_' + dir_str + '_multiplyDivide' cmds.shadingNode('multiplyDivide', au=1, n= nodeStr) cmds.setAttr(nodeStr + '.input2X', mult) cmds.connectAttr('fingers_' + dir_str + '_ctrl.spread', nodeStr + '.input1X', f=1) cmds.connectAttr(nodeStr + '.outputX', finger_str + '_01_' + dir_str + '_offsetB.rotateY', f=1) attribute_cleanup(object='fingers_' + dir_str + '_ctrl', translate_key = 0, translate_visible = 0, translate_lock = 1, rotation_key = 0, rotation_visible = 0, rotation_lock = 1, scale_key = 0, scale_visible = 0 , scale_lock = 1) cmds.setAttr('fingers_' + dir_str + '_ctrl.v', k=0, cb=0) for dir_str in dir_str_list: cmds.parent('ball_lift_' + dir_str + '_ik_motion_offset', 'rig_ctrls') str_list = ['upperarm_'+ dir_str + '_fk', 'lowerarm_'+ dir_str + '_fk', 'hand_'+ dir_str + '_fk', 'thigh_'+ dir_str + '_fk', 'calf_'+ dir_str + '_fk', 'foot_'+ dir_str + '_fk', 'ball_'+ dir_str + '_fk', 'hand_'+ dir_str + '_ik', 'foot_'+ dir_str + '_ik'] #, 'ball_'+ dir_str + '_ik' for str_val in str_list: # lock axis if not '_ik_' in current_ctrl and not 'root' in current_ctrl: attr_list = ['tx', 'ty', 'tz', 'sx', 'sy', 'sz'] for attr in attr_list: cmds.setAttr(current_ctrl + '.' + attr, lock = 1, k = 0) # make custom attr keyable for dir_str in dir_str_list: cmds.setAttr('hand_fkik_' + dir_str + '_switch.limb_fk_ik', keyable = True) cmds.setAttr('foot_fkik_' + dir_str + '_switch.limb_fk_ik', keyable = True) cmds.setAttr('fingers_' + dir_str + '_ctrl.thumb', keyable = True) cmds.setAttr('fingers_' + dir_str + '_ctrl.index', keyable = True) cmds.setAttr('fingers_' + dir_str + '_ctrl.middle', keyable = True) cmds.setAttr('fingers_' + dir_str + '_ctrl.ring', keyable = True) cmds.setAttr('fingers_' + dir_str + '_ctrl.pinky', keyable = True) cmds.setAttr('fingers_' + dir_str + '_ctrl.spread', keyable = True) cmds.setAttr('foot_' + dir_str + '_ik_ctrl.Roll', keyable = True) cmds.setAttr('foot_' + dir_str + '_ik_ctrl.Bend_Limit_Angle', keyable = True) cmds.setAttr('foot_' + dir_str + '_ik_ctrl.Toe_Straight', keyable = True) # face gui labels script_path = os.path.dirname(__file__) face_gui_file = script_path + '/' + 'face_gui_custom_labels.ma' if not cmds.objExists('facial_gui_custom_labels_offset'): if os.path.exists(face_gui_file): cmds.file(face_gui_file, i=True) if cmds.objExists('facial_gui_custom_labels_offset') and cmds.objExists('CTRL_faceGUI'): cmds.parent('facial_gui_custom_labels_offset', 'rig_setup') cmds.parentConstraint('CTRL_faceGUI', 'facial_gui_custom_labels_offset', mo=0, n='facial_gui_custom_labels_parentCon') cmds.select(cl=1) print('Metahuman Body Ctrls created.') else: print('User canceled Metahuman Body Ctrls creation.') if axisUp == 'y': cmds.setAttr("global_offset.rotateX", -90) def delSkel(): metahuman_skeleton = [ 'root', 'pelvis', 'spine_01', 'spine_02', 'spine_03', 'spine_04', 'spine_05', 'neck_01', 'neck_02', 'head', 'clavicle_l', 'upperarm_l', 'lowerarm_l', 'hand_l', 'middle_metacarpal_l', 'middle_01_l', 'middle_02_l', 'middle_03_l', 'pinky_metacarpal_l', 'pinky_01_l', 'pinky_02_l', 'pinky_03_l', 'ring_metacarpal_l', 'ring_01_l', 'ring_02_l', 'ring_03_l', 'thumb_01_l', 'thumb_02_l', 'thumb_03_l', 'index_metacarpal_l', 'index_01_l', 'index_02_l', 'index_03_l', 'clavicle_r', 'upperarm_r', 'lowerarm_r', 'hand_r', 'middle_metacarpal_r', 'middle_01_r', 'middle_02_r', 'middle_03_r', 'pinky_metacarpal_r', 'pinky_01_r', 'pinky_02_r', 'pinky_03_r', 'ring_metacarpal_r', 'ring_01_r', 'ring_02_r', 'ring_03_r', 'thumb_01_r', 'thumb_02_r', 'thumb_03_r', 'index_metacarpal_r', 'index_01_r', 'index_02_r', 'index_03_r', 'thigh_l', 'calf_l', 'foot_l', 'ball_l', 'thigh_r', 'calf_r', 'foot_r', 'ball_r', 'bigtoe_01_l', 'bigtoe_02_l', 'indextoe_01_l', 'indextoe_02_l', 'middletoe_01_l', 'middletoe_02_l', 'ringtoe_01_l', 'ringtoe_02_l', 'littletoe_01_l', 'littletoe_02_l', 'bigtoe_01_r', 'bigtoe_02_r', 'indextoe_01_r', 'indextoe_02_r', 'middletoe_01_r', 'middletoe_02_r', 'ringtoe_01_r', 'ringtoe_02_r', 'littletoe_01_r', 'littletoe_02_r' ] cmds.select(hi=1) objLs = cmds.ls(sl=1) current_namespace = str(objLs[0].split(':')[:-1])+':' for obj in objLs: checkObj = obj.replace('_' + obj.split('_')[-1], '') if not checkObj in metahuman_skeleton: if cmds.objExists(obj): cmds.delete(obj) def findMakeNode(srcNode, findStr): #makeNode = '' for inputNode in cmds.listHistory(srcNode): if findStr in str(inputNode): makeNode = str(inputNode) return makeNode def create_offset(source_object = '', offset_name = ''): cmds.select(cl=1) if not cmds.objectType(source_object)=='joint': cmds.duplicate(source_object, n = offset_name) if cmds.listRelatives(offset_name, s=1): cmds.delete(cmds.listRelatives(offset_name, s=1)[0]) cmds.parent(source_object, offset_name) else: offset_name = cmds.group(n=offset_name, em=1) cmds.parentConstraint(source_object, offset_name, n='delete_con') cmds.delete('delete_con') if cmds.listRelatives(source_object, p=1): cmds.parent(offset_name, cmds.listRelatives(source_object, p=1)[0]) cmds.parent(source_object, offset_name) return offset_name def attribute_cleanup(object='', translate_key = 1, translate_visible = 1, translate_lock = 0, rotation_key = 1, rotation_visible = 1, rotation_lock = 0, scale_key = 1, scale_visible = 1 , scale_lock = 0): axis_list = ['X','Y','Z'] if cmds.objExists(object): for axis_letter in axis_list: cmds.setAttr(object + '.translate'+axis_letter, keyable=True) cmds.setAttr(object + '.translate'+axis_letter, k=translate_key, cb=translate_visible, l=translate_lock) cmds.setAttr(object + '.rotate'+axis_letter, keyable=True) cmds.setAttr(object + '.rotate'+axis_letter, k=rotation_key, cb=rotation_visible, l=rotation_lock) cmds.setAttr(object + '.scale'+axis_letter, keyable=True) cmds.setAttr(object + '.scale'+axis_letter, k=scale_key, cb=scale_visible, l=scale_lock) set_keyable(object = object) def set_keyable(object = ''): axis_list = ['X','Y','Z'] if cmds.objExists(object): for axis_letter in axis_list: if cmds.getAttr(object + '.translate'+axis_letter, cb=True) and not cmds.getAttr(object + '.translate'+axis_letter, keyable=True): cmds.setAttr(object + '.translate'+axis_letter, keyable=True) if cmds.getAttr(object + '.rotate'+axis_letter, cb=True) and not cmds.getAttr(object + '.rotate'+axis_letter, keyable=True): cmds.setAttr(object + '.rotate'+axis_letter, keyable=True) if cmds.getAttr(object + '.scale'+axis_letter, cb=True) and not cmds.getAttr(object + '.scale'+axis_letter, keyable=True): cmds.setAttr(object + '.scale'+axis_letter, keyable=True) #from Craig Miller https://vimeo.com/66262994 def create_pole_vector_object(boneA='', boneB='', boneC=''): #sel = cmds.ls(sl = 1) start = cmds.xform(boneA ,q= 1 ,ws = 1,t =1 ) mid = cmds.xform(boneB ,q= 1 ,ws = 1,t =1 ) end = cmds.xform(boneC ,q= 1 ,ws = 1,t =1 ) startV = OpenMaya.MVector(start[0] ,start[1],start[2]) midV = OpenMaya.MVector(mid[0] ,mid[1],mid[2]) endV = OpenMaya.MVector(end[0] ,end[1],end[2]) startEnd = endV - startV startMid = midV - startV dotP = startMid * startEnd proj = float(dotP) / float(startEnd.length()) startEndN = startEnd.normal() projV = startEndN * proj arrowV = startMid - projV arrowV*= 0.5 finalV = arrowV + midV cross1 = startEnd ^ startMid cross1.normalize() cross2 = cross1 ^ arrowV cross2.normalize() arrowV.normalize() matrixV = [arrowV.x , arrowV.y , arrowV.z , 0 , cross1.x ,cross1.y , cross1.z , 0 , cross2.x , cross2.y , cross2.z , 0, 0,0,0,1] matrixM = OpenMaya.MMatrix() OpenMaya.MScriptUtil.createMatrixFromList(matrixV , matrixM) matrixFn = OpenMaya.MTransformationMatrix(matrixM) rot = matrixFn.eulerRotation() loc = cmds.spaceLocator(n=boneB + 'space_locator_delete')[0] cmds.xform(loc , ws =1 , t= (finalV.x , finalV.y ,finalV.z)) cmds.xform ( loc , ws = 1 , rotation = ((rot.x/math.pi*180.0), (rot.y/math.pi*180.0), (rot.z/math.pi*180.0))) return boneB + 'space_locator_delete' mgBuildMetaHumansRigCntrls()