I would like to animate an objects' shape keys from a data set. Imagine a default cube that will get longer (side face vertices will move in +X direction) according to a data.
The date looks like this {'2000':1, '2001':2.5, '2003':3.4, ... '2020':11.9}
As you can see, we have time versus accumulative values. In reality, the data set has 4000 data points.
In the function below, I can receive a new value, add a shape key for it and move my target face in the desired direction. Frame by frame, this works just fine. However the code execution gets really slow after about 100 keyframes insertion.
I am looking for a way to create this animation from the data set quickly. After research, I found about foreach_set
function of Blender API. However I could not find a way to use it for my case.
Could anybody please explain me how to use foreach_set
function for FAST shape key animation from a dataset?
Relevant questions I could find. However they were not helpful for my case:
Fast keyframe insertion
Editing fcurve.keyframe points in FAST mode?
Thanks in advance!
def resize_bar(obj_name, newValue = 0, active_face = 2, start_frame = 1, end_frame = 2):
# Get the active mesh
obj = bpy.data.objects[obj_name]
obj_mesh = bpy.data.objects[obj_name].data
obj_mesh_matrix = bpy.data.objects[obj_name].matrix_world
# get base shape key ready
if start_frame == 1:
basis_key = obj.shape_key_add(name="Basis", from_mix=False)
basis_key.keyframe_insert('value', frame=start_frame)
# Get a BMesh representation
bm = bmesh.new() # create an empty BMesh
bm.from_mesh(obj_mesh) # fill it in from a Mesh
# get top face of mesh
bm.faces.ensure_lookup_table()
top_face = bm.faces[active_face]
top_normal = bm.faces[active_face].normal
# add shape key and insert a key frame before transformation
new_shape_key = obj.shape_key_add(name=str(start_frame), from_mix=False)
new_shape_key.value = 1.0
new_shape_key.keyframe_insert(data_path='value', frame=start_frame)
# apply transformations
bmesh.ops.translate(bm, vec=newValue*top_normal, verts=top_face.verts)
bm.to_mesh(obj_mesh)
bm.free()
obj_mesh.update()
# insert a new key frame after transformation
new_shape_key.value = 0.0
new_shape_key.keyframe_insert(data_path='value', frame=start_frame+end_frame)