0

I would like to change all the normals of selected vertices in my scene to be (0,0,1). I am attempting to do this on a single mesh as a test scenario using the following code:

import bpy

mesh = bpy.context.object.data

selected_verts = [v for v in mesh.vertices if v.select]

for v in selected_verts:
print(f"Before Vertex Normal: {v.normal}") v.normal = [0,0,1] print(f"After Vertex Normal: {v.normal}")

When doing this, the value appears to change but the normal in the scene remains unchanged. Using Blender 2.83LTS

enter image description here

EDIT - subbed out the averaging routine for a Vector(0,0,1) - this works for my needs since all my Vectors are either UP or DOWN -

#Evaluate face Normals - if negative - flip
for obj in selected:
    bpy.ops.object.select_all(action='DESELECT')
    obj.select_set(True)
    bpy.context.view_layer.objects.active = obj
    bpy.ops.object.editmode_toggle()
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 ]

# Positive vector
up = Vector([0,0,1])

# Calculate the dot products between the Up vector and each face normal
dots = [ up.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 )

bpy.ops.object.editmode_toggle()

bpy.ops.object.select_all(action='DESELECT')

  • Most changes done on an object.data variable are only refreshed after the object mode is changed. I would suggest as a 1st check verifying that toggling out of edit mode does not update your scene. – Ratt Apr 20 '21 at 04:26
  • unfortunately, that doesn't seem to update the scene. i can verify they have changed with the print statement. however, after cycling through Object and Edit mode, they will eventually reset to the original position. bizarre - obviously, something with Blender happening auto-magically that I do not understand. – DP Roberts Apr 20 '21 at 14:27
  • I did find this - https://blender.stackexchange.com/questions/87106/python-find-faces-with-incorrect-normals-to-flip-and-flip-them - which is a great routine. I wonder if it could be simplified to identify negative normals. I'm essentially on flat planes and want to know UP or DOWN on the normal. And if DOWN, flip. I'm an artist with limited python ability beyond scouring the internet for solutions. – DP Roberts Apr 20 '21 at 16:54
  • Did you see brockman's answer for custom normals – Ratt Apr 20 '21 at 19:21
  • yes, but i'm trying to export these for import into Unity and wasn't sure that data would import correctly. i probably should have just phrased this as - "Is there a way to assign all my face normals to (0,0,1)?" - that's all I really need to do. I will try experimenting with modifying the bmesh routine. – DP Roberts Apr 20 '21 at 22:35
  • polygon face normals and vertex normals are the same there is a .flip() operator for polygon normals. as such you could easily find any face normal with a negative value and flip it. As such Yes I would recommend modifying your original question. – Ratt Apr 20 '21 at 22:49
  • Thank you for your assistance Ratt. I did just that and it works well. As I am no coder, there are probably simpler ways to do this but it works and is efficient enough for my needs. – DP Roberts Apr 21 '21 at 04:07

0 Answers0