Tool to help select faces on a mesh for FWN work


I have written a FWN (Face Weighted Normal) tool in Python for Maya and it works pretty well. However my artists are asking me to write some sort of tool to select all of the faces in a mesh that you would want to run this on. IE: most flat faces but no fillets. I’m not trying to perfectly solve this but get a good selection for my artists and then let them select and deselect any faces they want before running the FWN tool. I’ve been playing around with polySelectConstraint but have not yet figured out any patterns that actually work. I’m wondering if anyone has any code ideas for what I need to consider here.


Morris Olmsted
Army Game Studios


polySelectConstraint can help you find all faces that point in a single, specific direction, within a specified tolerance. But it sounds like you want something that can find large swaths of mostly flat surfaces pointing in any direction.

I wrote something to help with auto-projecting UVs that didn’t rely on pre-determined projection planes. I gathered up all the normals from all the faces and sorted them into buckets based on a tolerance. This gave me buckets of faces that more or less pointed in the same direction. Then i would use these direction to apply planar UV projections.

A similar approach could help you find the faces in your model that need FWN.


The only issues with this is that this would also give me all of the fillets in the mesh. But basically that is what I am running into with my own tests too.


you would probably need to run a second pass to filter out faces that have very short edges adjacent to very long edges.


So I found a good cheap solution to help the artist get close enough to useful that then allows them to add or remove selection once they run this little helper selection tool. It grabs all of the faces larger than a tollerance but puts itself into a mode for selecting faces for the user.
selected = pm.selected()
if selected:
print selected
cmds.polySelectConstraint(mode=0, geometricarea=False)
cmds.polySelectConstraint(m=3, type=8, geometricarea=True, geometricareabound=(55, 1000000))
selectionGrp = pm.selected()
cmds.polySelectConstraint(mode=0, geometricarea=False)
if selectionGrp:
print selectionGrp, r=True)
pm.hilite(selected, tgl=True)

Once they are happy with the selection they then use the Face Weighted Normal button I referred to earlier to run that command.