Search code examples
pythonapimaya

Finding Blendshape from Target Maya Python API


I'm trying to find a blendshape deformer from a target mesh in the python maya api. I'm pretty sure I have to iterate through the dependency graph to get the blendshape.

This is what i'm trying:

import maya.OpenMaya as OpenMaya
import maya.OpenMayaAnim as OpenMayaAnim

#Name of our targetmesh.
targetMesh = "pSphere1"

#Add selection.
mSel = OpenMaya.MSelectionList()
mSel.add(targetMesh, True)

#Get MObj
mObj = OpenMaya.MObject()
mSel.getDependNode(0, mObj)

#Make iterator.
itDG = OpenMaya.MItDependencyGraph(mObj,
                                   OpenMaya.MFn.kBlendShape, 
                                   OpenMaya.MItDependencyGraph.kUpstream)

while not itDG.isDone():
    oCurrentItem = itDG.currentItem()
    blndSkin = OpenMayaAnim.MFnBlendShapeDeformer(oCurrentItem)
    print blndSkin
    break

Unfortunately I get no blendshape deformer.

The same example with maya.cmds:

import maya.cmds as cmds

targetMesh = "pSphere1"    

history = cmds.listHistory(targetMesh, future=True)
blndshape = cmds.ls(history, type="blendShape")

print blndshape

Any help would be greatly appreciated!


Solution

  • So here's the solution I got working i believe:

    def getBlendShape(shape):
        '''
        @param Shape: Name of the shape node.
        Returns MFnBlendShapeDeformer node or None.
        '''
        # Create an MDagPath for our shape node:
        selList = OpenMaya.MSelectionList()
        selList.add(shape)
        mDagPath = OpenMaya.MDagPath()
        selList.getDagPath(0, mDagPath)
    
        #Create iterator.
        mItDependencyGraph = OpenMaya.MItDependencyGraph(
            mDagPath.node(),
            OpenMaya.MItDependencyGraph.kPlugLevel)
    
        # Start walking through our shape node's dependency graph.
        while not mItDependencyGraph.isDone():
            # Get an MObject for the current item in the graph.
            mObject = mItDependencyGraph.currentItem()
            # It has a BlendShape.
            if mObject.hasFn(OpenMaya.MFn.kBlendShape):
                # return the MFnSkinCluster object for our MObject:
                return OpenMayaAnim.MFnBlendShapeDeformer(mObject)
            mItDependencyGraph.next()
    
    if __name__ == '__main__':
        #TargetMesh
        targetMesh = "pSphereShape1"
    
        #Get Blendshape.
        blndShpNode = getBlendShape(targetMesh)
    
        if blndShpNode:
            #Get base objects.
            mObjArr = OpenMaya.MObjectArray()
            blndShpNode.getBaseObjects(mObjArr)
            mDagPath = OpenMaya.MDagPath()
            OpenMaya.MFnDagNode(mObjArr[0]).getPath(mDagPath)
            print(mDagPath.fullPathName())
    
        else:
            print("No Blendshape found.")
    

    The trick is that I needed to pass the shape node and to only use OpenMaya.MItDependencyGraph.kPlugLevel). In this example it finds the base object of the blendshape.