# How can I animate a vertex translation of a triangular mesh?

I have a triangular mesh in my viewport and I used this Python script to move a single vertex of the mesh (Do You know better methods? I am new to Blender and Python).

import bpy

obj = bpy.context.object

edge = obj.data.edges #An edge, the first one

vIndex1 = edge.vertices #Get the indices of the vertices of this edge
vIndex2 = edge.vertices

v1 = obj.data.vertices[vIndex1] #Get the corresponding vertices
v2 = obj.data.vertices[vIndex2]

vCoord1 = v1.co #Get their coordinates
vCoord2 = v2.co

edgeVector = vCoord2 - vCoord1 #The vector formed by these two vertices

edgeVector.normalize() #So that it has 1 unit length

distance = 0.5 #Say we want to move v2 of this distance of 0.5 units

v2.co += edgeVector * distance #Translate the vertex


My doubt is: how can I create the animation of this translation using scripts? This is the code to create a triangular mesh:

# Create a triangle mesh
import bpy

# Initialize our vertices
vert=[(0,0,0),(10,0,0),(5,10,0)]

face=[(0,1,2)]

# Create mesh and related object
my_mesh=bpy.data.meshes.new("Triangle")
my_obj=bpy.data.objects.new("Triangle",my_mesh)

# Set object location in 3D space
my_obj.location = bpy.context.scene.cursor.location

# make collection
new_collection = bpy.data.collections.new('new_collection')

# Link object to the scene collection

# Create object using blender function
my_mesh.from_pydata(vert,[],face)
my_mesh.update(calc_edges=True)


Scripting blenders animation system.

Back in the old days one of the common methods to animate a mesh was via a hook.

Similarly to How to transform a mesh with many objects? here is code to add and assign a hook empty to each vertex of the object named "Triangle" in the scene.

import bpy

context = bpy.context
scene = context.scene
tri = scene.objects.get("Triangle")
if tri:
me = tri.data
for v in me.vertices:
name = f"Vert_{v.index}"
location=tri.matrix_world @ v.co
)
mt = context.object
mt.name = name
hm = tri.modifiers.new(
name=name,
type='HOOK',
)
hm.object = mt
hm.vertex_indices_set([v.index])


To move any vert simply animate the associated hook.

To animate.

Each hook is a proxy for its associated vert in global space.

Demo script, at each 50 frame interval keyframe the location of vertex 2's hook such that it is 25% further from vertex 2 moving along the direction of edge (v1, v2).

import bpy
context = bpy.context

ob = context.object # Hooked object

v1, v2, v3 = [m.object for m in ob.modifiers
if m.type == 'HOOK' and m.object]
context.scene.frame_set(1)
for frame in range(1, 250, 58):
v2.keyframe_insert("location", frame=frame)
v2.location += 0.25 * (v2.location - v1.location)


removing the hooks and / or the hook modifiers returns the triangle back to its original geometry.

After a lot of research and tests, I found the solution (You must select a vertex in Edit Mode and after return in Object Mode):

 import bpy

# The object Triangle
obj = bpy.data.objects["Triangle"]

# First keyframe for the start position
bpy.data.shape_keys["Key"].key_blocks["Key 1"].value = 0
bpy.data.shape_keys["Key"].key_blocks['Key 1'].keyframe_insert("value",frame=0)

# Move a single vertex (if the vertex is active)

# Activate Edit Mode
bpy.ops.object.editmode_toggle()

# Translation
bpy.ops.transform.translate(value=(10, 0, 0),
orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)),
orient_matrix_type='GLOBAL', mirror=True, use_proportional_edit=False,
proportional_edit_falloff='SMOOTH', proportional_size=1,
use_proportional_connected=False,
use_proportional_projected=False)

# Deactivate Edit Mode
bpy.ops.object.editmode_toggle()

# Second keyframe for the end position
bpy.data.shape_keys["Key"].key_blocks["Key 1"].value = 1
bpy.data.shape_keys["Key"].key_blocks['Key 1'].keyframe_insert("value",frame=20)