0
$\begingroup$

I've been trying to set the selected vertex normals of my model to have a common average direction. After some research I came up with this

    import bpy
    import bmesh
    import gpu
    from gpu_extras.batch import batch_for_shader
    from mathutils import Matrix, Vector, Euler
        
    class ButtonAverageNormals(bpy.types.Operator):
            bl_idname = "button.average_normals"
            bl_label = "Average Normals"
        
            def execute(self, context):
                
                context = bpy.context
                ob = context.object
                me = ob.data
        
                me.use_auto_smooth = True
               
                averageNormals = Vector((0,0,0))
                selectedCount = 0
                newNormals = []
                for v in me.vertices:
                    if v.select:
                        averageNormals = averageNormals + v.normal
                        selectedCount = selectedCount + 1
                averageNormals = averageNormals / selectedCount
                
                for v in me.vertices:
                    if v.select:
                        newNormals.append(averageNormals)
                    else:
                        newNormals.append(v.normal)
        
                me.normals_split_custom_set_from_vertices(newNormals)
                me.update()
                print(averageNormals)
                return{'FINISHED'}

Everything works ok. I'm executing the operation with an UI button called "Calculate Normals", and the average normals are calculated and printed correctly, but they're never applied to the vertex. This: "me.normals_split_custom_set_from_vertices(newNormals)" doesn't seem to be working. enter image description here

$\endgroup$

1 Answer 1

0
$\begingroup$

The mesh data is accessed in object mode and intended for compact storage, for more flexible mesh editing from python see bmesh. Insert bpy.ops.object.mode_set(mode='OBJECT') in your operator and try again.

def execute(self, context):
    context = bpy.context

    bpy.ops.object.mode_set(mode='OBJECT') #
                     
    ob = context.object
    me = ob.data
    ...
$\endgroup$
1
  • $\begingroup$ Thanks! This worked like a charm. I'm getting some unexpected results, but that's something I think I can handle. $\endgroup$
    – JuanSalice
    Commented Dec 21, 2021 at 17:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .