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$
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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.