Beispiel #1
0
def addTangentMPTo(startMP, endMP, direction, default=0.5, reverse=False):
    '''
    add a "tangent" attribute to startLoc, and a tangentLoc to startLoc
    at 0, tangentLoc would be exactly on startLoc
    at 1, tangentLoc would be projected on direction vector onto endLoc's plane
    
    direction (string): 'x', 'y', or 'z'
    reverse (bool): reverse direction
    
    return tangentLoc
    '''
    # add tangentLoc
    tangentLoc = mc.spaceLocator(n=startMP+'_tangent_loc')[0]
    rt.parentSnap(tangentLoc, startMP)
    
    # add planeLoc - moves on plane of endMP, to help calculcate max distance
    planeLoc = mc.spaceLocator(n=endMP+'_plane_loc')[0]
    rt.parentSnap(planeLoc, endMP)
    
    # pointConstraint planeLoc to startMP
    # skip "direction" axis, to maintain sliding on endMP's plane
    mc.pointConstraint(startMP, planeLoc, skip=direction)
    
    # get distance between startMP and planeLoc
    # this is the maximum length for tangent
    maxDistance = cn.create_distanceBetween(startMP, planeLoc)
    
    # add "tangent" attribute to startMP
    mc.addAttr(startMP, ln='tangent', at='double', min=0, max=1, dv=default, k=True)
    
    # multiply tangent value by maxDistance
    tangentDistance = cn.create_multDoubleLinear(startMP+'.tangent', maxDistance)
    
    # reverse the direction if necessary
    if reverse:
        tangentDistance = cn.create_multDoubleLinear(tangentDistance, -1)
    
    # this will be used to drive the tangentLoc
    translatePlug = '%s.t%s' % (tangentLoc, direction)
    mc.connectAttr(tangentDistance, translatePlug, f=True)
    
    # connect locators for debug
    rt.connectVisibilityToggle((planeLoc, tangentLoc), startMP, 'debugTangentLocs', default=False)
    rt.connectVisibilityToggle(tangentLoc, startMP, 'tangentLoc', False)
    
    return tangentLoc
Beispiel #2
0
def addJntsOnSurfIntersection(surf1, surf2, jntsNum):
    '''
    Places jnts along intersection curve between surf1 and surf2
    naming convention based on surf1
    '''
    
    # intersect surfaces
    crvGrp, intNode = mc.intersect(surf1, surf2, fs=True, ch=True, o=True, cos=False)[:2]
    intNode = mc.rename(intNode, surf1+'_ints')
    crvGrp = mc.rename(crvGrp, surf1+'_ints_crv_grp')
    crv = mc.listRelatives(crvGrp, c=True)[0]
    crv = mc.rename(crv, surf1+'_ints_crv')
    
    # rebuild curve to jntNum spans
    rbdCrv, rbdNode = mc.rebuildCurve(crv, ch=True, o=True, rpo=False, spans=jntsNum, rt=0, kr=2, n=crv+'_rbd_crv')
    rbdNode = mc.rename(rbdNode, crv+'_rbd')
    
    # offset curve to control size of eye hole
    offsetCrv, offsetNode = mc.offsetCurve(rbdCrv, ch=True, distance=0, o=True, ugn=0, n=crv+'_offset_crv')
    offsetNode = mc.rename(offsetNode, crv+'_offset')
    
    locs = []
    locName = '_'.join(surf1.split('_')[:2])
    # attach locators to intersection curve
    for locId in range(jntsNum):
        loc = mc.spaceLocator(n=locName+'_loc_%d' % locId)[0]
        rt.attachToMotionPath(offsetCrv, locId, loc, fm=False)
        mc.setAttr(loc+'.localScale', 0.05, 0.05, 0.05)
        locs.append(loc)
        
    # normal constraint to surf1
    for loc in locs:
        mc.normalConstraint(surf2, loc, aim=(1,0,0))
    
    jnts = []
    # add joints under locators
    for loc in locs:
        mc.select(cl=True)
        jnt = mc.joint(n=loc.replace('_loc_','_jnt_'))
        rt.parentSnap(jnt, loc)
        mc.setAttr(jnt+'.jointOrient', 0,0,0)
        jnts.append(jnt)
        
    # groups
    grp = mc.group(crvGrp, offsetCrv, rbdCrv, locs, n=surf1+'_intersect_loc_grp')
    
    # create offset attribute
    mc.addAttr(grp, ln='collideOffset', at='double', dv=0, k=True)
    offsetPlug = cn.create_multDoubleLinear(grp+'.collideOffset', -1)
    mc.connectAttr(offsetPlug, offsetNode+'.distance', f=True)
    
    # connect debug
    rt.connectVisibilityToggle(offsetCrv, grp, 'offsetCrv', False)
    rt.connectVisibilityToggle(rbdCrv, grp, 'rebuildCrv', False)
    rt.connectVisibilityToggle(crvGrp, grp, 'intersectCrv', False)
    rt.connectVisibilityToggle(locs, grp, 'crvLocs', False)
    rt.connectVisibilityToggle(jnts, grp, 'crvJnts', False)
Beispiel #3
0
def addFootRoll(ctl, heelPivot, ballPivot, toePivot):
    """
    """
    #===========================================================================
    # ADD ATTRIBUTES for toe-straight, toe-lift and roll
    #===========================================================================
    mc.addAttr(ctl, ln='roll', dv=0, at='double', k=True)
    mc.addAttr(ctl, ln='toeLift', dv=30, at='double', k=True)
    mc.addAttr(ctl, ln='toeStraight', dv=60, at='double', k=True)

    #===========================================================================
    # CONNECT HEEL
    # just use negative roll values, ignore positive
    #===========================================================================
    clp = mc.createNode('clamp', n=ctl + '_roll_heel_clp')
    mc.connectAttr(ctl + '.roll', clp + '.minR', f=True)
    mc.connectAttr(ctl + '.roll', clp + '.inputR', f=True)
    mc.connectAttr(clp + '.outputR', heelPivot + '.rx', f=True)

    #===========================================================================
    # CONNECT TOE
    # linstep(lift, straight, roll) * roll
    #===========================================================================
    srg = mc.createNode('setRange', n=ctl + '_roll_srg')
    mc.connectAttr(ctl + '.toeLift', srg + '.oldMinX', f=True)
    mc.connectAttr(ctl + '.toeStraight', srg + '.oldMaxX', f=True)
    mc.connectAttr(ctl + '.roll', srg + '.valueX', f=True)
    mc.connectAttr(ctl + '.roll', srg + '.maxX', f=True)
    mc.connectAttr(srg + '.outValueX', toePivot + '.rx', f=True)

    #===========================================================================
    # CONNECT BALL
    # linstep(0, lift, roll) * (1 - linstep(lift, straight, roll)) * roll
    #===========================================================================
    # "increasing" part
    mc.connectAttr(ctl + '.toeLift', srg + '.oldMaxY', f=True)
    mc.connectAttr(ctl + '.roll', srg + '.valueY', f=True)
    mc.connectAttr(ctl + '.toeLift', srg + '.maxY', f=True)
    # "decreasing" part
    mc.connectAttr(ctl + '.toeLift', srg + '.oldMinZ', f=True)
    mc.connectAttr(ctl + '.toeStraight', srg + '.oldMaxZ', f=True)
    mc.connectAttr(ctl + '.roll', srg + '.valueZ', f=True)
    mc.setAttr(srg + '.minZ', 1)
    mc.setAttr(srg + '.maxZ', 0)  # reversed normalized range from 1-0
    # multiply the parts
    ballVal = cn.create_multDoubleLinear(srg + '.outValueY',
                                         srg + '.outValueZ')
    mc.connectAttr(ballVal, ballPivot + '.rx', f=True)
Beispiel #4
0
def addFootRoll(ctl, heelPivot, ballPivot, toePivot):
    """
    """
    #===========================================================================
    # ADD ATTRIBUTES for toe-straight, toe-lift and roll
    #===========================================================================
    mc.addAttr(ctl, ln='roll', dv=0, at='double', k=True)
    mc.addAttr(ctl, ln='toeLift', dv=30, at='double', k=True)
    mc.addAttr(ctl, ln='toeStraight', dv=60, at='double', k=True)
    
    #===========================================================================
    # CONNECT HEEL
    # just use negative roll values, ignore positive
    #===========================================================================
    clp = mc.createNode('clamp', n=ctl+'_roll_heel_clp')
    mc.connectAttr(ctl+'.roll', clp+'.minR', f=True)
    mc.connectAttr(ctl+'.roll', clp+'.inputR', f=True)
    mc.connectAttr(clp+'.outputR', heelPivot+'.rx', f=True)
    
    #===========================================================================
    # CONNECT TOE
    # linstep(lift, straight, roll) * roll
    #===========================================================================
    srg = mc.createNode('setRange', n=ctl+'_roll_srg')
    mc.connectAttr(ctl+'.toeLift', srg+'.oldMinX', f=True)
    mc.connectAttr(ctl+'.toeStraight', srg+'.oldMaxX', f=True)
    mc.connectAttr(ctl+'.roll', srg+'.valueX', f=True)
    mc.connectAttr(ctl+'.roll', srg+'.maxX', f=True)
    mc.connectAttr(srg+'.outValueX', toePivot+'.rx', f=True)
    
    #===========================================================================
    # CONNECT BALL
    # linstep(0, lift, roll) * (1 - linstep(lift, straight, roll)) * roll
    #===========================================================================
    # "increasing" part
    mc.connectAttr(ctl+'.toeLift', srg+'.oldMaxY', f=True)
    mc.connectAttr(ctl+'.roll', srg+'.valueY', f=True)
    mc.connectAttr(ctl+'.toeLift', srg+'.maxY', f=True)
    # "decreasing" part
    mc.connectAttr(ctl+'.toeLift', srg+'.oldMinZ', f=True)
    mc.connectAttr(ctl+'.toeStraight', srg+'.oldMaxZ', f=True)
    mc.connectAttr(ctl+'.roll', srg+'.valueZ', f=True)
    mc.setAttr(srg+'.minZ', 1) 
    mc.setAttr(srg+'.maxZ', 0) # reversed normalized range from 1-0
    # multiply the parts
    ballVal = cn.create_multDoubleLinear(srg+'.outValueY', srg+'.outValueZ')
    mc.connectAttr(ballVal, ballPivot+'.rx', f=True)
Beispiel #5
0
def addJntsOnSurfIntersection(surf1, surf2, jntsNum):
    '''
    Places jnts along intersection curve between surf1 and surf2
    naming convention based on surf1
    '''

    # intersect surfaces
    crvGrp, intNode = mc.intersect(surf1,
                                   surf2,
                                   fs=True,
                                   ch=True,
                                   o=True,
                                   cos=False)[:2]
    intNode = mc.rename(intNode, surf1 + '_ints')
    crvGrp = mc.rename(crvGrp, surf1 + '_ints_crv_grp')
    crv = mc.listRelatives(crvGrp, c=True)[0]
    crv = mc.rename(crv, surf1 + '_ints_crv')

    # rebuild curve to jntNum spans
    rbdCrv, rbdNode = mc.rebuildCurve(crv,
                                      ch=True,
                                      o=True,
                                      rpo=False,
                                      spans=jntsNum,
                                      rt=0,
                                      kr=2,
                                      n=crv + '_rbd_crv')
    rbdNode = mc.rename(rbdNode, crv + '_rbd')

    # offset curve to control size of eye hole
    offsetCrv, offsetNode = mc.offsetCurve(rbdCrv,
                                           ch=True,
                                           distance=0,
                                           o=True,
                                           ugn=0,
                                           n=crv + '_offset_crv')
    offsetNode = mc.rename(offsetNode, crv + '_offset')

    locs = []
    locName = '_'.join(surf1.split('_')[:2])
    # attach locators to intersection curve
    for locId in range(jntsNum):
        loc = mc.spaceLocator(n=locName + '_loc_%d' % locId)[0]
        rt.attachToMotionPath(offsetCrv, locId, loc, fm=False)
        mc.setAttr(loc + '.localScale', 0.05, 0.05, 0.05)
        locs.append(loc)

    # normal constraint to surf1
    for loc in locs:
        mc.normalConstraint(surf2, loc, aim=(1, 0, 0))

    jnts = []
    # add joints under locators
    for loc in locs:
        mc.select(cl=True)
        jnt = mc.joint(n=loc.replace('_loc_', '_jnt_'))
        rt.parentSnap(jnt, loc)
        mc.setAttr(jnt + '.jointOrient', 0, 0, 0)
        jnts.append(jnt)

    # groups
    grp = mc.group(crvGrp,
                   offsetCrv,
                   rbdCrv,
                   locs,
                   n=surf1 + '_intersect_loc_grp')

    # create offset attribute
    mc.addAttr(grp, ln='collideOffset', at='double', dv=0, k=True)
    offsetPlug = cn.create_multDoubleLinear(grp + '.collideOffset', -1)
    mc.connectAttr(offsetPlug, offsetNode + '.distance', f=True)

    # connect debug
    rt.connectVisibilityToggle(offsetCrv, grp, 'offsetCrv', False)
    rt.connectVisibilityToggle(rbdCrv, grp, 'rebuildCrv', False)
    rt.connectVisibilityToggle(crvGrp, grp, 'intersectCrv', False)
    rt.connectVisibilityToggle(locs, grp, 'crvLocs', False)
    rt.connectVisibilityToggle(jnts, grp, 'crvJnts', False)
Beispiel #6
0
def addOns():
    '''
    Add ons to Advanced Skeleton fitV027, buildV001
    '''
    # START WITH RIGHT SIDE

    #===========================================================================
    # ADD REVERSE ROLL
    #===========================================================================
    bendPivot, leftPivot, rightPivot = ms.placePivotsForReverseRoll(
        'Wrist_R', (0.715, -0.011, 0.038), (0, -0.194, -0.687),
        (0, -0.194, 0.631))

    jnts = [
        'Wrist_R', ['FKOffsetPinkyFinger1_R', 'FKXPinkyFinger3_R'],
        ['FKOffsetMiddleFinger1_R', 'FKXMiddleFinger3_R'],
        ['FKOffsetIndexFinger1_R', 'FKXIndexFinger3_R'],
        ['FKOffsetThumbFinger1_R', 'FKXThumbFinger3_R']
    ]

    rollGrp, baseJnt = ms.addReverseRoll(jnts, bendPivot, leftPivot,
                                         rightPivot)

    # drive rollGrp via FKIK switching
    FKDriver = 'FKWrist_R'
    IKDriver = 'IKArm_R_IKFKOffsetBlend_grp'
    FKIKSwitch = 'FKIKArm_R'

    pCons = mc.parentConstraint(FKDriver, IKDriver, rollGrp, mo=True)[0]
    wal = mc.parentConstraint(pCons, q=True, wal=True)

    FKIKValue = cn.create_multDoubleLinear(FKIKSwitch + '.FKIKBlend', 0.1)

    #===========================================================================
    # SET DRIVERS AND DRIVENS
    #===========================================================================
    # drive blend in constraint
    rollGrp = rollGrp.split('|')[1]
    rev = mc.createNode('reverse', n=rollGrp + '_FKIKSwitch_rev')
    mc.connectAttr(FKIKValue, rev + '.inputX', f=True)
    mc.connectAttr(rev + '.outputX', pCons + '.' + wal[0], f=True)
    mc.connectAttr(FKIKValue, pCons + '.' + wal[1], f=True)

    # baseJnt to drive ikHandle & IKFKOffsetBlend
    IKHandle = 'IKXArmHandle_R'
    IKFKMix = 'FKIKMixWrist_R'

    mc.parentConstraint(baseJnt, IKHandle, mo=True)
    mc.delete(IKFKMix + '_parentConstraint1')
    mc.parentConstraint(baseJnt, IKFKMix, mo=True)

    #===========================================================================
    # FIX LENGTH MEASUREMENT
    #===========================================================================
    endLoc = 'IKmessureConstrainToArm_R'
    mc.parentConstraint(baseJnt, endLoc)

    # DO SAME FOR LEFT SIDE

    #===========================================================================
    # ADD REVERSE ROLL
    #===========================================================================
    bendPivot, leftPivot, rightPivot = ms.placePivotsForReverseRoll(
        'Wrist_L', (-0.715, -0.011, 0.038), (0, 0.194, -0.687),
        (0, 0.194, 0.631))

    jnts = [
        'Wrist_L', ['FKOffsetPinkyFinger1_L', 'FKXPinkyFinger3_L'],
        ['FKOffsetMiddleFinger1_L', 'FKXMiddleFinger3_L'],
        ['FKOffsetIndexFinger1_L', 'FKXIndexFinger3_L'],
        ['FKOffsetThumbFinger1_L', 'FKXThumbFinger3_L']
    ]

    rollGrp, baseJnt = ms.addReverseRoll(jnts, bendPivot, rightPivot,
                                         leftPivot)

    # drive rollGrp via FKIK switching
    FKDriver = 'FKWrist_L'
    IKDriver = 'IKArm_L_IKFKOffsetBlend_grp'
    FKIKSwitch = 'FKIKArm_L'

    pCons = mc.parentConstraint(FKDriver, IKDriver, rollGrp, mo=True)[0]
    wal = mc.parentConstraint(pCons, q=True, wal=True)

    FKIKValue = cn.create_multDoubleLinear(FKIKSwitch + '.FKIKBlend', 0.1)

    #===========================================================================
    # SET DRIVERS AND DRIVENS
    #===========================================================================
    # drive blend in constraint
    rollGrp = rollGrp.split('|')[1]
    rev = mc.createNode('reverse', n=rollGrp + '_FKIKSwitch_rev')
    mc.connectAttr(FKIKValue, rev + '.inputX', f=True)
    mc.connectAttr(rev + '.outputX', pCons + '.' + wal[0], f=True)
    mc.connectAttr(FKIKValue, pCons + '.' + wal[1], f=True)

    # baseJnt to drive ikHandle & IKFKOffsetBlend
    IKHandle = 'IKXArmHandle_L'
    IKFKMix = 'FKIKMixWrist_L'

    mc.parentConstraint(baseJnt, IKHandle, mo=True)
    mc.delete(IKFKMix + '_parentConstraint1')
    mc.parentConstraint(baseJnt, IKFKMix, mo=True)

    #===========================================================================
    # FIX LENGTH MEASUREMENT
    #===========================================================================
    endLoc = 'IKmessureConstrainToArm_L'
    mc.parentConstraint(baseJnt, endLoc)
Beispiel #7
0
def reverseAttr(obj, attr):
    outPlugs = mc.listConnections(obj+'.'+attr, s=False, p=True)    
    revPlug = cn.create_multDoubleLinear(obj+'.'+attr, -1)
    for eachPlug in outPlugs:
        mc.connectAttr(revPlug, eachPlug, f=True)
Beispiel #8
0
def reverseAttr(obj, attr):
    outPlugs = mc.listConnections(obj + '.' + attr, s=False, p=True)
    revPlug = cn.create_multDoubleLinear(obj + '.' + attr, -1)
    for eachPlug in outPlugs:
        mc.connectAttr(revPlug, eachPlug, f=True)
Beispiel #9
0
def addOns():
    '''
    Add ons to Advanced Skeleton fitV027, buildV001
    '''
    # START WITH RIGHT SIDE
    
    #===========================================================================
    # ADD REVERSE ROLL
    #===========================================================================
    bendPivot, leftPivot, rightPivot = ms.placePivotsForReverseRoll('Wrist_R', (0.715, -0.011, 0.038), (0,-0.194,-0.687), (0,-0.194,0.631))
    
    jnts = ['Wrist_R',
    ['FKOffsetPinkyFinger1_R', 'FKXPinkyFinger3_R'],
    ['FKOffsetMiddleFinger1_R', 'FKXMiddleFinger3_R'],
    ['FKOffsetIndexFinger1_R', 'FKXIndexFinger3_R'],
    ['FKOffsetThumbFinger1_R', 'FKXThumbFinger3_R']
    ]
    
    rollGrp, baseJnt = ms.addReverseRoll(jnts, bendPivot, leftPivot, rightPivot)

    # drive rollGrp via FKIK switching
    FKDriver = 'FKWrist_R'
    IKDriver = 'IKArm_R_IKFKOffsetBlend_grp'
    FKIKSwitch = 'FKIKArm_R'

    pCons = mc.parentConstraint(FKDriver, IKDriver, rollGrp, mo=True)[0]
    wal = mc.parentConstraint(pCons, q=True, wal=True)

    FKIKValue = cn.create_multDoubleLinear(FKIKSwitch+'.FKIKBlend', 0.1)
    
    #===========================================================================
    # SET DRIVERS AND DRIVENS
    #===========================================================================
    # drive blend in constraint
    rollGrp = rollGrp.split('|')[1]
    rev = mc.createNode('reverse', n=rollGrp+'_FKIKSwitch_rev')
    mc.connectAttr(FKIKValue, rev+'.inputX', f=True)
    mc.connectAttr(rev+'.outputX', pCons+'.'+wal[0], f=True)
    mc.connectAttr(FKIKValue, pCons+'.'+wal[1], f=True)
    
    # baseJnt to drive ikHandle & IKFKOffsetBlend
    IKHandle = 'IKXArmHandle_R'
    IKFKMix = 'FKIKMixWrist_R'
    
    mc.parentConstraint(baseJnt, IKHandle, mo=True)
    mc.delete(IKFKMix+'_parentConstraint1')
    mc.parentConstraint(baseJnt, IKFKMix, mo=True)
    
    #===========================================================================
    # FIX LENGTH MEASUREMENT
    #===========================================================================
    endLoc = 'IKmessureConstrainToArm_R'
    mc.parentConstraint(baseJnt, endLoc)
    
    # DO SAME FOR LEFT SIDE
    
    #===========================================================================
    # ADD REVERSE ROLL
    #===========================================================================
    bendPivot, leftPivot, rightPivot = ms.placePivotsForReverseRoll('Wrist_L', (-0.715, -0.011, 0.038), (0,0.194,-0.687), (0,0.194,0.631))
    
    jnts = ['Wrist_L',
    ['FKOffsetPinkyFinger1_L', 'FKXPinkyFinger3_L'],
    ['FKOffsetMiddleFinger1_L', 'FKXMiddleFinger3_L'],
    ['FKOffsetIndexFinger1_L', 'FKXIndexFinger3_L'],
    ['FKOffsetThumbFinger1_L', 'FKXThumbFinger3_L']
    ]
    
    rollGrp, baseJnt = ms.addReverseRoll(jnts, bendPivot, rightPivot, leftPivot)

    # drive rollGrp via FKIK switching
    FKDriver = 'FKWrist_L'
    IKDriver = 'IKArm_L_IKFKOffsetBlend_grp'
    FKIKSwitch = 'FKIKArm_L'

    pCons = mc.parentConstraint(FKDriver, IKDriver, rollGrp, mo=True)[0]
    wal = mc.parentConstraint(pCons, q=True, wal=True)

    FKIKValue = cn.create_multDoubleLinear(FKIKSwitch+'.FKIKBlend', 0.1)
    
    #===========================================================================
    # SET DRIVERS AND DRIVENS
    #===========================================================================
    # drive blend in constraint
    rollGrp = rollGrp.split('|')[1]
    rev = mc.createNode('reverse', n=rollGrp+'_FKIKSwitch_rev')
    mc.connectAttr(FKIKValue, rev+'.inputX', f=True)
    mc.connectAttr(rev+'.outputX', pCons+'.'+wal[0], f=True)
    mc.connectAttr(FKIKValue, pCons+'.'+wal[1], f=True)
    
    # baseJnt to drive ikHandle & IKFKOffsetBlend
    IKHandle = 'IKXArmHandle_L'
    IKFKMix = 'FKIKMixWrist_L'
    
    mc.parentConstraint(baseJnt, IKHandle, mo=True)
    mc.delete(IKFKMix+'_parentConstraint1')
    mc.parentConstraint(baseJnt, IKFKMix, mo=True)
    
    #===========================================================================
    # FIX LENGTH MEASUREMENT
    #===========================================================================
    endLoc = 'IKmessureConstrainToArm_L'
    mc.parentConstraint(baseJnt, endLoc)