# Nonuniform Moving of Vertices of Meshes Along Local Normals

I have a 3D surface with N vetrices and M faces. I also have independent numpy arrays for face normals, n, vertices coordinates, V, and the triangulation of the vertices in F.

For each vertex, I also have a function, f(iVertex) = h_i that defines how much the vertex should move along the local normal, which can be outward (positive h_i values) or inward (negative h_i values). In other words, displacing the vertices along the local normal are not uniform and is different from vertex to vertex according to the function f(iVertex).

The closest solution I found was posted here. However, I don't want my surface to get disintegrated and I want the faces to remain connected even after displacing the vertices. How can I move the vertices based on f efficiently in Blender using Python without disassembling the faces?

I used an existing base mesh to test this, which is why the code I'm using might need some changes for you to be able to implement it. The most important thing here is lines 22-23:

d    = normal * h_i[i] # Current vertex's displacement value
v.co = V[i] + d        # Displace current vertex along normal


You calculate each vertex's new location by adding to it the displacement value, which is the h_i for that vertex X the face normal (which is a direction vector).

Here's the complete code:

import bpy, bmesh
import numpy as np

bm = bmesh.new()
bm.from_mesh( bpy.context.object.data )

worldMatrix = bpy.context.object.matrix_world

F   = bm.faces                                 # Face objects
V   = [ worldMatrix * v.co for v in bm.verts ] # Vert coordinates

# Generate a random number between -1 and 1 as a displacement value for each vertex
h_i = 2 * np.random.random( len( V ) ) - 1

# Perform displacement
# Iterate over faces (You might want to zip the face normals and triangulations here)
for f in F:
normal = f.normal # get Face normal (your n value for this face)
fVerts = f.verts  # List of face vertices (your "F" variable for this face)
# Iterate over this face's vertices (F[face_index])
for v in fVerts:
i = v.index

d    = normal * h_i[i] # Current vertex's displacement value
v.co = V[i] + d        # Displace current vertex along normal

update_existing_mesh = True
if update_existing_mesh:
bm.to_mesh( bpy.context.object.data )
else: # Generate a new mesh
m = bpy.data.meshes.new( "Displaced" )
bm.to_mesh( m )

o = bpy.data.objects.new( "Displaced", m )