1
$\begingroup$

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)
$\endgroup$

2 Answers 2

1
$\begingroup$

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.

$\endgroup$
0
$\begingroup$

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)
$\endgroup$

You must log in to answer this question.

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