Saturday, July 23, 2011

Basic problem solving - Scripting for a monotonous task....

So, I've been working a gig for a couple of weeks now and ran into an issue that Maya's base tools seemed to provide no good solutions. When I find myself in such a predicament I invariably find myself going down a path. Before I begin, a caveat - I'm an intermediate scripter and I'm sure there's much more efficient coding methods. However, functioning inefficient tools are better than no tools:) Hope this is helpful to anyone who happens to peruse these ramblings....

  1. Identify the need - In this case I need to ensure that a skinned mesh didn't have any vert with more than two influences. The annoying thing with maya is that even if you tell the skin to only have 2 influences and to maintain it it does the job about 98% of the time and just doesn't seem to care about that other 2%. Faced with the prospect of individually checking every vertex via the component editor for more that two skins, any other option is much more attractive.

  2. See if Maya has any tools to fix the problem - Messed with skin settings and the various mirroring, hammering and skin options to see if native maya can fix it. Sometimes this work, in this case it didn't

  3. To the internets! - Google and CreativeCrash check for a script or solution. If someone else has solved it and been kind enough to post the answer no reason to reinvent the wheel.

  4. Write a tool - Think through the requirements and results you need from a specific function or functions and beg, borrow and steal (while providing credit) the pieces to make it work.
For this little conundrum,  I wanted Maya to tell me if I had any vertices that had an influence above x influences and get that information in a usable format. Here was the particular flow on this problem.

  • For this script, I started with writing a function to return any vertices over 2 influences. 
  • As a part of that, I found the functions I needed to use need to know the skin cluster name which I remembered having wrote a function for a while back so I grabbed that.
  • Then, I thought it silly to cap it at 2 influences and allowed the user to specify the number of influences the user chose
  • Finally, worked on the workflow so that the user didn't have to type commands into the script editor as I wanted to be able to give my client a buttonable script for their artists. In the end it made sense to me to have it both report the bad verts as well as select the first in that list to easily get to work. If I was in a fuller production environment it might make sense to make a gui or modify the function to be able to select through the bad vertices list rather than a one off end function here.
In the end, spending an hour or two making a simple tool both enables a montonous task prone to user error doable as well as provides a tool for other artists to be able to do the same which is always a boon in production.

import maya.cmds as mc
import maya.mel as mel

maxInfluences = 2

def returnExcessInfluenceVerts(mesh, maxInfluences):
    skinCluster = querySkinCluster(mesh)

    badVertices = []
    vertexList = ( ([mesh+'.vtx[*]'],flatten=True))
    #Find the bad verts
    for v in vertexList:
        influenceList = mc.skinPercent(skinCluster, v, query=True, transform=None) 
        if len(influenceList) > maxInfluences:
    return badVertices

def querySkinCluster(obj):
    mel.eval ('$mesh = "%s";' % (obj))
    skin = mel.eval('findRelatedSkinCluster($mesh);')
    return skin
mesh = ( (sl=True))
if len(mesh)<1:
    print ('Please select a mesh')

    badVertices = returnExcessInfluenceVerts(mesh[0],maxInfluences)
    if len(badVertices)>0:[0], replace=True)
        print ('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
        print ('%s%i%s' % ('There are ',(len(badVertices)),' verts are over the max influence:'))    
        print badVertices
        print ('No verts over max influence')


katets said...


i have a problem with max influence in maya right now.
i have rigged all my assets with max influence of 5. but now i have to set them to 4, cause of production pipeline. the problem is when i do that, my rig gets messed up.
so, do you know of any way that i can do that.

i know what kind of script would work. but i cant write any.
a script which would take the weight of the nearest point and paste it on itself. so i would duplicate the model with the bone and use it as reference on top of the other one.

i would be really grateful, if you could help me in this chaos.

Thanks a lot,

Josh Burton said...

Hey Hoss,

I don't know an automatic solution no. I wouldn't think that most of your assets would be using more than 3 influences unless they're facial stuff. Most body stuff doesn't need that much.

If I were you, I'd dup the mesh and copy the weights to have a "back to normal" and reference version. Then play with the pruning weights, changing the max influence and then doing some manual fixes. I'd use my script (the current working version I have ) and go from there.

Sorry mate.

Amy Stevens said...

Used your script and it works really well. but saving the scene while using it results in the mesh returning a noneType error - just a heads up :)

All the stuff on this site is 2000 - by Josh Burton...unless otherwise noted. All rights reserved.