I want to animate a landscapes that "grows" up, using a grid. The landscape sits in a numpy matrix. After I update the Z values in the grid, the shape keys don't capture this.
Below is my current code. At line 49, just below the text "### Below here', the data can be set. If you fill in "False", the grid values get replaced by a random vertex transform, and this works fine, creating a changing grid between frame 1 and 100.
If "True" is filled in, the numpy matrix data is used (here a funny sine wave for testing) and this sets the Z coordinates directly, to adjust the mesh. The problem is: the shape-keys/keyframes don't capture this, just showing the landscape that I set for the entire animation.
What am I doing wrong?
import bpy, bmesh
from math import pi
import numpy as np
O = bpy.data.objects
--- Cleaning previous iterations --------------------------------------
for o in O:
if o.name[0:4]=='Land':
O.remove(o)
--- Function setting the mesh -----------------------------------------
def SetMesh(me, V):
# Get a BMesh representation
bm = bmesh.new() # create an empty BMesh
bm.from_mesh(me) # fill it in from a Mesh
bm.verts.ensure_lookup_table()
# Modify the BMesh, can do anything here...
for i in range(len(bm.verts)):
bm.verts[i].co.z =V[i]
# Finish up, write the bmesh back to the mesh
bm.to_mesh(me)
bm.free()
me.update()
--- Generating data (wavy landscape) ---------------------------------
GridDim = 20
R=np.linspace(0,pi,GridDim)
X,Y=np.meshgrid(R,R)
D=np.sin(XY)
D=D.flatten()0.1
bpy.context.scene.frame_current = 1
bpy.ops.mesh.primitive_grid_add(
x_subdivisions=GridDim, y_subdivisions=GridDim,
size=2, location=(0, 0, 0))
bpy.context.object.name = "Landscape"
bpy.ops.object.shape_key_add(from_mix=False) # The basis shape_key
bpy.ops.object.shape_key_add(from_mix=False) # The "Key 1" shape_key
Below here, the data can be set
if True:
SetMesh(Landscape.data, D)
else:
bpy.ops.object.editmode_toggle()
bpy.ops.transform.vertex_random(offset=0.2)
bpy.ops.object.editmode_toggle()
bpy.context.object.data.shape_keys.key_blocks["Key 1"].value = 1
bpy.context.object.data.shape_keys.key_blocks["Key 1"].keyframe_insert(data_path='value', frame=1)
Setting keyframes for animation
sk1 = bpy.context.object.data.shape_keys.key_blocks["Key 1"]
sk1.value = 0.0
sk1.keyframe_insert(data_path='value', frame=1)
sk1.value = 1.0
sk1.keyframe_insert(data_path='value', frame=100)
meshinstead ofbpy.context.object.data– batFINGER Aug 19 '20 at 11:35sk1above, (possibly three lines prior.) Reading full addresses to variables feels like hearing somebody's title, full name, address, everytime they are addressed. Edit ability. Portability. eg using a variable namedcontextin test scripts can then be pasted into (eg) operator method code where it is an argument. – batFINGER Aug 19 '20 at 13:41