Shape keys with python in Blender

I’ve been wanting to use Python to make shape keys. I’ve tried to use the ‘dir’ function to figure it out, but I was still not able to. I think I read on a previous thread that shape key data is read only, but I’m still interested in knowing if I can make a mesh in python and then add it to the list of shape keys. So in other words, even if I can’t use python to edit already existing shape keys, can I at least use it to make new shape keys?

I tried f=Blender.Object.Get(“Grid”) and g=f.getData() then f.insertShapeKey(). This made new shape keys, but the shape keys were identical to the basis mesh, which is redundant. I tried g.key.blocks.append( … ) for various arguments (including a separate mesh I made in 3D mode, the getData for that mesh, as well as the verts list from the getData). Nothing had any effect and nothing was added to the list of blocks.

I’ve also tried g1 = Blender.Object.Get(“Grid.001”), g1data = g1.getData() (I want to say that I realize that it would have made more sense to call the variables f1 and g1, given the variables I discussed in the previous post, but oh well). Then I tried for i in range(0,35,1): g.key.blocks[3].data[i].co = g1data.verts[i].co . I then wrote a loop to print out a truth comparison between g.key.blocks[3].data[i].co and g1data.verts[i].co for 0<=i<=35. There were four “false” values and a list of “true” values. Since each object “Grid” and “Grid.001” have exactly four vertices in different places from each other, it seems that "for i in range(0,35,1): g.key.blocks[3].data[i].co = g1data.verts[i].co " had no effect. Then I typed g.update() and Blender.Redraw() anyway, which also does not seem to have any effect.

I think this thread will help you.

Actually, I did find that thread, but there are several things about it that I don’t understand. For example one thread provides the following code with descrption:

I’m not quite sure what the author means. Is the new shape key identical to the first object? When the author says it gets pasted into the second object, does the author mean that it gets pasted into the second object as a new shape key, or does the author mean the script creates a new shape key in addition to pasting the first object into the second?

In the code:

#!BPY

import Blender
from Blender import *

myOb = Blender.Object.GetSelected()
c_copy = myOb[1].getData(mesh=1)
p_paste = myOb[0].getData(mesh=1)

I’m not sure what the “mesh=1” means. I’m used to using getData() without an argument.

v_count = 0

for vert in c_copy.verts:
v_count += 1

for vv in range(v_count):
p_paste.verts[vv].co = c_copy.verts[vv].co
p_paste.verts[vv].no = c_copy.verts[vv].no

pp_paste = myOb[0].getData()
pp_paste.update()
pp_paste.insertKey()
pp_paste.update()

I’m not clear where the for loops begin and end.

First of all, did you add a Basis key before attempting to append a new key? If you do not, your basis will be overwritten.

You get the mesh data from the object by using getData(), if you do not pass an argument of mesh=1 to getData(), you will be using the older NMesh module.

For NMesh to keep the changes you make to the mesh as a new shape key, you have first to update() your mesh, then use insertKey() and then update() again. You may change the key’s name before the last update().

I think insertShapeKey() requires to update the mesh too, at least it has worked for me like that.

There is a new insertKey() method for 2.43 in the Mesh module as well (passing mesh=1 to Object.getData()) , which might work without updating because the Mesh module has direct access to the mesh. I have not tried though.

I think you want to program shape keys. I have done this. Tomorrow i will post some examples.

Have a look at the MDD importer in blender 2.43, its a fairly simple example of using shape keys with Mesh.
MD2 importer also uses shape keys.

Sorry, but I think I forgot to mention that I want to work with relative shape keys, and not absolute shape keys. Sorry if this confused anyone.