How to keyframe mesh vertices in Python I'm updating all the vertex coordinates of a mesh frame-by-frame in python and need to animate but can not figure out how. Here is a small abstracted script - the python isn't pretty, but it makes an icosphere gaussian hiccup (a little like this coarse GIF):



import bpy
import bmesh
import numpy as np

pi = np.pi
make_ico = bpy.ops.mesh.primitive_ico_sphere_add
ok = make_ico(subdivisions=3, size = 2.0, location = (0,0,3))

ao = bpy.context.active_object
oo = bpy.ops.object
ok = oo.mode_set(mode='EDIT')
me = bmesh.from_edit_mesh(ao.data)
ico0 = np.array([vert.co for vert in me.verts]) # get ico vertices
ok = oo.mode_set(mode='OBJECT')

n_frames = 101
bpy.context.scene.frame_end = n_frames

zmin, zmax = ico0[:,2].min(), ico0[:,2].max()
zc = np.linspace(zmin, zmaz, n_frames)

sig = 0.3
ico = np.zeros_like(ico0)
data = []
for i in range(n_frames):
    ico[:,:2] = (1.0 + np.exp(-(ico0[:,2] - zc[i])**2/(2.*sig**2)))[:,None] * ico0[:,:2]
    ico[:,2] = ico0[:,2]
    data.append(ico.copy())

for i_frame in range(n_frames):
    ok = oo.mode_set(mode='EDIT')
    me = bmesh.from_edit_mesh(ao.data)  #DO THIS EVERY TIME?
    for (vert, co) in zip(me.verts, data[i_frame]):
        vert.co = co
    bmesh.update_edit_mesh(ao.data)  # update
    ok = oo.mode_set(mode='OBJECT')
    bpy.context.scene.frame_current = i_frame + 1
    # something about keyframes HERE?
It is also possible to directly keyframe the positions of the mesh vertices
Edit updated for 2.8.
import bpy
from mathutils import Vector

def insert_keyframe(fcurves, frame, values):
    for fcu, val in zip(fcurves, values):
        fcu.keyframe_points.insert(frame, val, options={'FAST'})

obj = bpy.context.active_object
mesh = obj.data
action = bpy.data.actions.new(&quot;MeshAnimation&quot;)

mesh.animation_data_create()
mesh.animation_data.action = action

data_path = &quot;vertices[%d].co&quot;
vec_z = Vector((0.0, 0.0, 1.0))

frames = 0, 25, 50, 75, 100
values = 0.0, 3.0, 5.0, 3.0, 0.0

for v in mesh.vertices:
    fcurves = [action.fcurves.new(data_path % v.index, index =  i) for i in range(3)]
    co_rest = v.co

    for t, value in zip(frames, values):
        co_kf = co_rest + value * vec_z
        insert_keyframe(fcurves, t, co_kf)