Jump to content
Sign in to follow this  
Pomperi

Vertex normal script for Maya

Recommended Posts

Hi everyone!

I just wanted to share a script I've done for Maya to quickly be able to set the vertex normals based on the face normals. I know there are a few ways to do this within native maya, as well as a few scripts, but I haven't been able to find one which averages the normals for verts shared by multiple selected faces. This can be quite annoying when setting up curved or round surfaces.

oBTdSYt.jpg

For 3ds max there's a great script called GetVertNormalFromFace which does this. What mine does is essentially the same but in Maya. Just make a face selection of the faces you want to set the vert normals for and run the script.

98uBPfL.jpg

To run the script, just paste into the script editor as python and drag it to a shelf, or set it up as a hotkey

Here's the script:

# ---------------------------------------------------------------------------------------

# - pompVertNormFaceAvg

#

# - Sets the vertex normals of a face selection,

#   averaging normals shared by multiple selected faces.

#

#

# - by Pontus Karlsson 2013 (www.pomperi.com)

# ---------------------------------------------------------------------------------------


import maya.cmds as cmds


faces = cmds.filterExpand(sm=34, ex=True)

verts = cmds.ls((cmds.polyListComponentConversion(faces, ff=True, tv=True)), flatten=True)

normals = [[], [], []]


for v in verts:

    conFaces = cmds.ls(cmds.polyListComponentConversion(v, fv=True, tf=True), flatten=True)

    shaFaces = list(set(conFaces).intersection(set(faces)))

    faceNorm = cmds.polyInfo(shaFaces, fn=True)


    for normal in faceNorm:

	    label, vertex, x, y, z = normal.split()

	    normals[0].append(float(x))

	    normals[1].append(float(y))

	    normals[2].append(float(z))


    x_avg = (sum(normals[0]) / len(shaFaces))

    y_avg = (sum(normals[1]) / len(shaFaces))

    z_avg = (sum(normals[2]) / len(shaFaces))


    cmds.select(v)

    cmds.polyNormalPerVertex(xyz = (x_avg, y_avg, z_avg))


    normals[:] = [[], [], []]


cmds.select(cl=True)

I hope someone finds it useful :)

Edited by Pomperi

Share this post


Link to post
Share on other sites

Oh oh ! Smells good ! Going to test right now dude. Thanks =)

EDIT :

Works great. Amazing job dude !

Edited by kikette

Share this post


Link to post
Share on other sites

Good boy Pontus. Look at you with all your fancy technical know-how.

I use this script all the time in 3ds max. If ever I make the dirty leap to Maya, I'll be sure to give this an install!

Share this post


Link to post
Share on other sites

Hehe, thanks guys :)

 

kikette: Glad you like it!

 

I'm currently trying to re-write the script in OpenMaya to make it a bit faster. Also trying to come up with a good way to maintain hard edges, as it's quite cumbersome whenever you want to keep hard edges intact when setting up the vertex normals for a mesh. I think the best way workflow-wise is to set up hard and soft edges before manipulating the vert normals (meaning you would simply soften the whole mesh if you don't want any hard edges) then run the script and wherever there's a split, the vert normal will be set for each face individually.

 

If anyone have any suggestions, that would be awesome!

Share this post


Link to post
Share on other sites

beautiful!! I have a script like this at work I use all the time :).

Maintaining hard edges is a problem, I always end up having to cut up my model into separate objects. There must be a better way..

 

damn, now I'm inspired to make my own version of this 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

×