Paint Blend Shape Weights Tool via Python/MEL?

Paint Blend Shape Weights Tool via Python/MEL?

jmalaska
Advocate Advocate
2,455 Views
3 Replies
Message 1 of 4

Paint Blend Shape Weights Tool via Python/MEL?

jmalaska
Advocate
Advocate

Trying to do some very targeted blendshape painting. What I'd like to be able to do is select a series of vertices with soft selection, and have that selection be my "painted weights". I don't really want to have to go through manually painting weights.

 

Are there Python commands to help with this?

 

I can't dig to find out what the Paint Blendshape Weights tool is doing. The Node Graph doesn't show any intermediary that would hold this data.

 

https://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2020/ENU/Maya-Cha...

Accepted solutions (1)
2,456 Views
3 Replies
Replies (3)
Message 2 of 4

lee.dunham
Collaborator
Collaborator
Accepted solution

So its certainly possible, although it will depend on how comfortable you are with python.

 

First off, you need to get the components and "weighting" from the soft selection;

https://github.com/ldunham1/maya_utilities/blob/master/ld_soft_cluster.py

def _get_soft_selection():
    """
    Return the current soft selection components and normalised influence weights.
    :return: List of components and matching weights.
    :rtype: list(str), list(float)
    """
    # Grab the soft selection
    selection = om.MSelectionList()
    soft_sel = om.MRichSelection()
    om.MGlobal.getRichSelection(soft_sel)
    soft_sel.getSelection(selection)
    dag_path = om.MDagPath()
    component = om.MObject()

    # Filter Defeats the purpose of the else statement
    iter_sel = om.MItSelectionList(selection, om.MFn.kMeshVertComponent)
    elements, weights = [], []
    while not iter_sel.isDone():
        iter_sel.getDagPath(dag_path, component)

        # Grab the parent of the shape node
        dag_path.pop()
        node = dag_path.fullPathName()
        fn_comp = om.MFnSingleIndexedComponent(component)
        vtx_str = node + '.vtx[{}]'

        for i in range(fn_comp.elementCount()):
            elements.append(vtx_str.format(fn_comp.element(i)))
            weights.append(fn_comp.weight(i).influence() if fn_comp.hasWeights() else 1.0)

        iter_sel.next()

    return elements, weights

 

 

Then, modify the blendshape weights using the component index and soft selection weight - these two posts should help you out there.

https://yantor3d.wordpress.com/2017/09/16/inside-the-node-blendshape/ 

https://soup-dev.websitetoolbox.com/post/setting-blendshape-weights-through-maya-api-7116714?pid=128...

 

Hint: You're modify this to affect the blendshape base weights, although you can also access target specific weights too;

blendshape.inputTarget[0].baseWeights

 

Hope this helps!

Message 3 of 4

jmalaska
Advocate
Advocate

Lee, this is wicked awesome. Thank you for dropping your knowledge! Exactly what I was looking for. Cheers!

0 Likes
Message 4 of 4

lee.dunham
Collaborator
Collaborator

Not a problem, glad it's helpful 🙂

0 Likes