daily pastebin goal
25%
SHARE
TWEET

proxy

snolan Oct 8th, 2016 (edited) 643 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. """
  2. Proxy Skinning Utilities
  3.    Example:
  4.  
  5.        # Select faces on a mesh
  6.        from proxy import extractFaces
  7.        newMesh = extractFaces()
  8.  
  9.        # Select Source Mesh and Destination Mesh
  10.        from proxy import skinTo
  11.        newSkinCluster = skinTo()
  12. """
  13. from maya import cmds
  14. from functools import wraps
  15.  
  16. __author__ = 'Sean.Nolan'
  17. __doc__ = 'Utility functions for Proxy skinning'
  18.  
  19.  
  20. def d_undo(func):
  21.     """
  22.    Undo Decorator
  23.    :param func: incoming function
  24.    :return:
  25.    """
  26.     @wraps(func)
  27.     def _undo_func(*args, **kwargs):
  28.         try:
  29.             cmds.undoInfo(ock=True)
  30.             return func(*args, **kwargs)
  31.         finally:
  32.             cmds.undoInfo(cck=False)
  33.             cmds.undo()
  34.  
  35.     return _undo_func
  36.  
  37.  
  38. @d_undo
  39. def extractFaces(faceList=None, newName=None, keepOriginal=False, copySkinning=False):
  40.     """
  41.    Extract faces from mesh and make a copy
  42.    :param faceList: List of faces to extract
  43.    :type : list
  44.    :param newName: New mesh name
  45.    :type: str
  46.    :param keepOriginal: Make a copy of mesh before extraction
  47.    :type: bool
  48.    :param copySkinning: Copy skin weights over to extracted mesh
  49.    :type: bool
  50.    :return: Extracted mesh name
  51.    """
  52.  
  53.     if not faceList:
  54.         selectedFaces = cmds.ls(sl=True)
  55.     else:
  56.         selectedFaces = faceList
  57.  
  58.     if not bool(cmds.filterExpand(selectedFaces, ex=True, sm=34)) or []:
  59.         raise RuntimeError("Must select one or more Faces")
  60.  
  61.     shape = cmds.listRelatives(p=1)
  62.     curMesh = cmds.listRelatives(shape, p=1)[0]
  63.  
  64.     cmds.select(curMesh + '.f[:]', tgl=1)
  65.     extractFaces = cmds.ls(sl=1)
  66.  
  67.     # Save current pose
  68.     infList = cmds.skinCluster(curMesh, q=True, wi=True)
  69.     curPose = cmds.dagPose(infList, save=True, name='extractInPose')
  70.  
  71.     # Go to bind pose before copying weights
  72.     bindPose = cmds.dagPose(infList, q=True, bindPose=True)
  73.     cmds.dagPose(bindPose, restore=True)
  74.  
  75.     newMesh = cmds.duplicate(curMesh)[0]
  76.  
  77.     # Rename mesh
  78.     if newName:
  79.         newMesh = cmds.rename(newMesh, newName)
  80.  
  81.     # Copy skin weights over to new mesh
  82.     if copySkinning:
  83.         skinTo(curMesh, newMesh)
  84.  
  85.     if not keepOriginal:
  86.         cmds.delete(selectedFaces)
  87.  
  88.     # Swap current mesh to new mesh
  89.     for i in range(len(extractFaces)):
  90.         extractFaces[i] = extractFaces[i].replace(curMesh, newMesh)
  91.  
  92.     cmds.delete(extractFaces)
  93.  
  94.     # Clean new mesh
  95.     if copySkinning:
  96.         cmds.bakePartialHistory(curMesh, prePostDeformers=True)
  97.         cmds.bakePartialHistory(newMesh, prePostDeformers=True)
  98.     else:
  99.         cmds.delete(newMesh, ch=1)
  100.  
  101.     cmds.dagPose(curPose, restore=True)
  102.     cmds.delete(curPose)
  103.     cmds.select(newMesh, r=1)
  104.     return newMesh
  105.  
  106.  
  107. def skinTo(srcMesh=None, destMesh=None):
  108.     """
  109.    Skin from source to destination mesh
  110.    :param srcMesh: Source mesh
  111.    :type : str
  112.    :param destMesh: Destination Mesh
  113.    :type: str
  114.    :return: New skinCluster name
  115.    """
  116.  
  117.     # Test for selection
  118.     if not srcMesh or not destMesh:
  119.         meshes = cmds.ls(sl=1)
  120.         if meshes:
  121.             if len(meshes) >= 2:
  122.                 srcMesh = meshes[0]
  123.                 destMesh = meshes[1]
  124.             else:
  125.                 raise RuntimeError("Two meshes need to be selected!")
  126.         else:
  127.             raise RuntimeError("Two meshes need to be selected!")
  128.  
  129.     # Get source skinCluster
  130.     srcSkin = cmds.ls(cmds.listHistory(srcMesh), type='skinCluster')
  131.     if not srcSkin:
  132.         raise RuntimeError("{} does not have a skinCluster".format(srcSkin))
  133.  
  134.     # Check destination skinCluster
  135.     dstSkin = cmds.ls(cmds.listHistory(destMesh), type='skinCluster')
  136.  
  137.     # Save current pose
  138.     infList = cmds.skinCluster(srcSkin, q=True, wi=True)
  139.     curPose = cmds.dagPose(infList, save=True, name='skinToPose')
  140.  
  141.     # Go to bind pose before copying weights
  142.     bindPose = cmds.dagPose(infList, q=True, bindPose=True)
  143.     cmds.dagPose(bindPose, restore=True)
  144.  
  145.     # Build destination skinCluster
  146.     if not dstSkin:
  147.         dstPrefix = destMesh.split(':')[-1]
  148.         srcInfList = cmds.skinCluster(srcSkin[0], q=True, inf=True)
  149.         dstSkin = cmds.skinCluster(srcInfList, destMesh,
  150.                                    toSelectedBones=True, rui=False, n=dstPrefix + '_skinCluster')
  151.  
  152.     # Copy skin weights
  153.     cmds.copySkinWeights(sourceSkin=str(srcSkin[0]),
  154.                          destinationSkin=str(dstSkin[0]),
  155.                          surfaceAssociation='closestPoint',
  156.                          influenceAssociation='name',
  157.                          noMirror=True)
  158.  
  159.     cmds.dagPose(curPose, restore=True)
  160.     cmds.delete(curPose)
  161.     cmds.select(cl=1)
  162.     # Return result
  163.     return dstSkin
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top