Last active
November 15, 2023 14:13
-
-
Save aobond2/f9c9ed202050c165b48acd1fc4d72e51 to your computer and use it in GitHub Desktop.
Transfer blendshape between mesh with different topology. In this case from head to additional meshes (eyebrows, moustache, etc)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import maya.cmds as cmds | |
blendshapeList = [] | |
# TODO: Change this, hard code for now | |
objectAffected = "eyebrow" | |
mainHead = None | |
blendshapeCopies = [] | |
meshDeformer = None | |
renamedBlendshapesArray = [] | |
# Get blendshapes of head | |
def GetHeadBlendshapes(): | |
global blendshapeList | |
global mainHead | |
global meshDeformer | |
selectedObjects = cmds.ls(selection=True) | |
# List all deformers applied to the selected object | |
for selectedObject in selectedObjects: | |
# TODO: Add better check on this. Set selected object as baseMesh | |
mainHead = selectedObject | |
meshName = mainHead.split('|')[-1] | |
meshDeformer = cmds.listHistory(mainHead) | |
for deformer in meshDeformer: | |
if cmds.nodeType(deformer) == "blendShape": | |
blendShape = cmds.blendShape(deformer, q=True, target=True) | |
blendshapeTargets = cmds.listAttr(deformer + '.weight', multi=True) | |
for b in blendshapeTargets: | |
print(b) | |
if b not in blendshapeList: | |
blendshapeList.append(b) | |
# Create copies of original eyebrow, based on number of blendshapes | |
def MakeCopiesFacialObject(): | |
global blendshapeCopies | |
# TODO: Change this later, currently selecting by name | |
facialObject = cmds.ls(objectAffected) | |
for b in blendshapeList: | |
blendshapeDuplicate = cmds.duplicate(facialObject, returnRootsOnly=True) | |
blendshapeCopies.append(blendshapeDuplicate) | |
# Wrap modifier on each eyebrow copies | |
def WrapEyebrowCopy(): | |
for bc in blendshapeCopies: | |
AddWrapDeformer(bc, mainHead) | |
''' | |
wrapDeformer = cmds.deformer(bc, type='wrap')[0] | |
# Set source mesh, in this case the head | |
cmds.setAttr(wrapDeformer + '.maxDistance', 1.0) | |
cmds.setAttr(wrapDeformer + '.autoWeightThreshold', 1.0) | |
#cmds.setAttr(wrapDeformer + '.weightThreshold', 1.0) | |
# Connect this deformer | |
cmds.connectAttr(str(mainHead) + '.worldMesh[0]', wrapDeformer + '.driverPoints[0]') | |
#AddWrapDeformer(bc, mainHead) | |
''' | |
def AddWrapDeformer(targetMesh, driverMesh): | |
''' | |
wrapNode = cmds.deformer(targetMesh, type='wrap')[0] | |
cmds.setAttr(wrapNode + '.driver[0]', driverMesh, type='string') | |
''' | |
cmds.select(targetMesh) | |
cmds.select(driverMesh, add=True) | |
cmds.CreateWrap() | |
cmds.select(clear=True) | |
def RenameBlendshapeCopies(): | |
# Name the copies to be the same with blendshape name | |
for i, copy in enumerate(blendshapeCopies): | |
newBS = cmds.rename(copy, blendshapeList[i]) | |
renamedBlendshapesArray.append(newBS) | |
# For loop on each blendshape, set it to 1 on each | |
# Freeze transform on each eyebrow deformed by each blendshape | |
def UpdateBlendshapeCopy(): | |
for i, copy in enumerate(blendshapeCopies): | |
print("THISISTHECOPY") | |
print(copy) | |
for md in meshDeformer: | |
if cmds.nodeType(md) == "blendShape": | |
print(md) | |
blendShape = cmds.listAttr(md + '.weight', multi=True) | |
for b in blendShape: | |
bShape = cmds.listRelatives(b, shapes=True) | |
# TODO: Somehow there's Shape appended to the name of these blendshape, need to remove them. This is also not great | |
bShape = str(bShape[0])[:-5] | |
if blendshapeList[i] == bShape: | |
cmds.setAttr((str(md) + "." + str(bShape)), 1) | |
print ("PROCESSINGNOW") | |
print(blendshapeList[i]) | |
print(bShape) | |
print(renamedBlendshapesArray[i]) | |
# Set all other blendshapes to 0 | |
else: | |
cmds.setAttr((str(md) + "." + str(bShape)), 0) | |
cmds.select(clear=True) | |
cmds.select(renamedBlendshapesArray[i]) | |
cmds.delete(renamedBlendshapesArray[i], constructionHistory=True) | |
cmds.select(clear=True) | |
# TODO: Create blendshapes on original eyebrow, picking the deformed eyebrow | |
def MakeBlendshapes(): | |
print("Making blendshapes") | |
def RunThis(): | |
GetHeadBlendshapes() | |
MakeCopiesFacialObject() | |
WrapEyebrowCopy() | |
RenameBlendshapeCopies() | |
UpdateBlendshapeCopy() | |
RunThis() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment