Python: find faces with incorrect normals to flip and flip them

Loading...

Python: find faces with incorrect normals to flip and flip them

.
Hi all,
Here is the issue. I've a mesh with some faces that need to be flipped in other to have something consistent:

These faces are selected:

So I would like to find the faces that must be flipped and flip them using a Python script. I tried making faces constistent by it didn't work.
My idea was the following:

Loop on the bmesh vertices  (I can do it)
Check that the vertice is selected (I can do it)
Check that the normal has to be flipped (I can't do it. Should I check the normal??
Flip normal (I can do it)

I hope I explained the issue clearly.
Thanks,
Maxime
PS: here is my blend file enter link description here

Solutions/Answers:

Answer 1:

enter image description here

This script finds the average normal from the selected faces, then finds normals that are very different by calculating the dot product between the average and each face normal.

Any face that has a negative dot product will be flipped. This fixes the normals on the faces in your blendfile, although your selection doesn’t include all the flipped faces (if selected, they will be fixed).

The script assumes you are in edit mode with all the faces of interest selected.

import bpy, bmesh
from mathutils import Vector

bm = bmesh.from_edit_mesh( bpy.context.object.data )

# Reference selected face indices
bm.faces.ensure_lookup_table()
selFaces = [ f.index for f in bm.faces if f.select ]

# Calculate the average normal vector
avgNormal = Vector()
for i in selFaces: avgNormal += bm.faces[i].normal
avgNormal = avgNormal / len( selFaces )

# Calculate the dot products between the average an each face normal
dots = [ avgNormal.dot( bm.faces[i].normal ) for i in selFaces ]

# Reversed faces have a negative dot product value
reversedFaces = [ i for i, dot in zip( selFaces, dots ) if dot < 0 ]

# Deselect all faces and (later) only select flipped faces as indication of change
for f in bm.faces: f.select = False
bm.select_flush( False )

for i in reversedFaces:
    bm.faces[i].select = True
    bm.faces[i].normal_flip()  # Flip normal

bm.select_flush( True )

Answer 2:

Did you try to go to edit mode, select all faces then recalculate normals? (Ctrl+N)

Answer 3:

.
well i had same as your issue, i was trying to resolve it, i get in your question to see the answers to resolve mine!
,
i found the solution, is Make Normals Consistent the shortcut Ctrl + N while you are still in the edit mode 🙂

thanks

References

Loading...