1

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[0] #An edge, the first one

vIndex1 = edge.vertices[0] #Get the indices of the vertices of this edge vIndex2 = edge.vertices[1]

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)]

Add face

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') bpy.context.scene.collection.children.link(new_collection)

Link object to the scene collection

new_collection.objects.link(my_obj)

Create object using blender function

my_mesh.from_pydata(vert,[],face) my_mesh.update(calc_edges=True)

Davide
  • 67
  • 6

2 Answers2

1

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.

Setup script: add hooks

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}" bpy.ops.object.empty_add( 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.

batFINGER
  • 84,216
  • 10
  • 108
  • 233
0

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"]

bpy.ops.object.shape_key_add(from_mix=False) # Add a ShapeKey (Basis)
bpy.ops.object.shape_key_add(from_mix=False) # Add a ShapeKey (Key 1)

# 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)

Davide
  • 67
  • 6