import sys
import os
import errno
import json
import re

import maya.cmds as cmd
import maya.mel as mel

def addBlendshape(controlName='',seperate=False):
    '''
    Blendshapes two objects or two groups with geometry and adds a transform to control the blendshape nodes. The blends start from the top down so be sure to keep the geometries matching.
    Add a name to the control using controlName argument.
    Deside whether to keep blendshape attributes sepereated or driven by one attribute using the seperate argument.
    '''
    prefix = ""
    sel = cmd.ls(sl=True)
    if len(sel)>1:
        driver = []
        driven = []
        if len(sel) > 2:
            drivenShape = cmd.listRelatives(sel[-1], type="mesh", f=True)
            for drt in sel:
                driverShape = cmd.listRelatives(drt, type="mesh", f=True)
                if driverShape:
                    if drivenShape:
                        driven.append(sel[-1])
                    if drt not in driven:
                        driver.append(drt)
        else:
            if cmd.listRelatives(sel[0], ad=True, type="transform"):
                driverTransform = cmd.listRelatives(sel[0], ad=True, type="transform", f=True)
                if driverTransform:
                    for drt in driverTransform:
                        driverShape = cmd.listRelatives(drt, type="mesh", f=True)
                        if driverShape:
                            driver.append(drt)
            else:
                driver.append(sel[0])
            if cmd.listRelatives(sel[1], ad=True, type="transform"):
                drivenTransform = cmd.listRelatives(sel[1], ad=True, type="transform", f=True)
                if drivenTransform:
                    for dnt in drivenTransform:
                        drivenShape = cmd.listRelatives(dnt, type="mesh", f=True)
                        if drivenShape:
                            driven.append(dnt)
            else:
                driven.append(sel[1])
        
        if driver and driven:
            control = cmd.createNode('transform', n='{0}_CONTROLS'.format(controlName))
            cmd.setAttr('{0}.tx'.format(control), l=True, k=False)
            cmd.setAttr('{0}.ty'.format(control), l=True, k=False)
            cmd.setAttr('{0}.tz'.format(control), l=True, k=False)
            cmd.setAttr('{0}.rx'.format(control), l=True, k=False)
            cmd.setAttr('{0}.ry'.format(control), l=True, k=False)
            cmd.setAttr('{0}.rz'.format(control), l=True, k=False)
            cmd.setAttr('{0}.sx'.format(control), l=True, k=False)
            cmd.setAttr('{0}.sy'.format(control), l=True, k=False)
            cmd.setAttr('{0}.sz'.format(control), l=True, k=False)
            cmd.setAttr('{0}.v'.format(control), l=True, k=False)
            if not seperate:
                cmd.addAttr(control, longName='{0}_Blend'.format(controlName), defaultValue=0.00, minValue=0.00, maxValue=1.0)
                cmd.setAttr('{0}.{1}_Blend'.format(control,controlName), l=False, k=True)
            
            for i in range(len(driver)):
                driverName = driver[i].split('|')[-1]
                if ':' in driverName:
                    driverName = driverName.split(':')[-1]
                drivenName = driven[i].split('|')[-1]
                if ':' in drivenName:
                    drivenName = drivenName.split(':')[-1]
                
                blendshape = cmd.blendShape(driver[i], driven[i], n='{0}_BLEND'.format(drivenName))
                cmd.setAttr((blendshape[0]+'.'+driverName), 1)
                if seperate:
                    blendName = '{0}_Blend{1}'.format(drivenName,str(i))
                    cmd.addAttr(control, longName=blendName, defaultValue=0.00, minValue=0.00, maxValue=1.0)
                    cmd.setAttr('{0}.{1}'.format(control,blendName), l=False, k=True)
                    cmd.connectAttr('{0}.{1}'.format(control,blendName), '{0}.envelope'.format(blendshape[0]), f=True)
                elif control:
                    cmd.connectAttr('{0}.{1}_Blend'.format(control,controlName), '{0}.envelope'.format(blendshape[0]), f=True)
    else:
        print "Either there is nothing selected or there is not enough selected."

Tags:

Comments are closed