Python and Shape Keys

Hello Everyone,

I am using Blender 2.49b.

I have made a object in blender that has several shape keys. I would like to export the “delta” function that each shape key makes as it moves from 0 to 1.

To access a shape key’s data I am doing the following:
ob=Blender.Object.GetSelected()[0]
mesh=ob.data
key=mesh.key
ipo=mesh.ipo
To access the IPO Curve data I can do:
ipo.getCurveCurval(g) (where g is an integer which selects which IPO curve.

I can also access the Mesh data for the key shapes by doing the following:
key.blocks[0].data #the first one is ALWAYS the basis shape

What I NEED to find in python is a way to access what each shape key is using as a “basis”. Typically it goes “Key 1” uses “Basis” as its basis function, and then “Key 2” uses “Key 1” as its basis function. But I cannot find that information anywhere in the API.
My goal is to work out the delta function (Key1 Verts - Basis Verts…etc) for each key shape. But Blender can store these out of order (Basis, Key2, Key1 is how they are ordered in this file) Is there a way to explicitly get the “Basis” function that each key shape uses?

Also I have found that when the key shapes are out of order, the IPO curves are also out of order. Does anyone know how to query the name of an IPO curve so that I can match it to its keyshape?

I am sure this is NOT normal usage of Blender, but I know all this data must be stored somewhere!

Thanks for all your help
Ben

Hi there!

I agree that there is a very tiny line connecting the items related to shapes in Blender (2.49). Coping with this by using Python is a difficult exercise in 2.4x but it is quite a fun in the same time… Soooo getting control over these gives amazing results :spin:

Any way… In some versions of my Bubbles animation (see more about it here) I had several objects each having several keys. Here is a code for obtaining info about this:

def Get_obj_key_IPOs(objects):
    d_obj_key_IPOs = {}
    for ob in objects:
        try:
            me = ob.getData(mesh=True)
            key = me.key
            ipo = key.getIpo()
            d_obj_key_IPOs[ob.name] = ipo.name
        except: pass
    return d_obj_key_IPOs
            
d_obj_key_IPOs = Get_obj_key_IPOs(Object.Get())
print d_obj_key_IPOs
print

keys = d_obj_key_IPOs.keys()
values = d_obj_key_IPOs.values()
print keys
print values
print keys[3]
print values[3]
print

k_object_name = keys[2]
k_object = Object.Get(k_object_name)
k_mesh = k_object.getData(mesh=True)
print k_mesh.name
print k_mesh.key
print

key = k_mesh.key
print key.getIpo()
print key.getBlocks()
print key.blocks
print key.ipo
print key.relative
print key.type
print key.value
print

keyblocks = key.blocks
k_block = keyblocks[0]
#print k_block.getData()
print k_block.curval
#print k_block.data
print k_block.name
print k_block.pos
print k_block.slidermax
print k_block.slidermin
print k_block.vgroup
print

k_block = keyblocks[1]
#print k_block.getData()
print k_block.curval
#print k_block.data
print k_block.name
print k_block.pos
print k_block.slidermax
print k_block.slidermin
print k_block.vgroup
print
print "========================="


In my case it gives the following output:

{'Bubble_2': 'KeyIpo.001', 'Bubble.001': 'KeyIpo.002', 'Bubble': 'KeyIpo.004', 'Sphere': 'KeyIpo'}

['Bubble_2', 'Bubble.001', 'Bubble', 'Sphere']
['KeyIpo.001', 'KeyIpo.002', 'KeyIpo.004', 'KeyIpo']
Sphere
KeyIpo

Bubble
[Key "Key.003"]

[Ipo "KeyIpo.004" (Key)]
[[KeyBlock "Basis"], [KeyBlock "Key 1"], [KeyBlock "Key 2"], [KeyBlock "Key 3"], [KeyBlock "Key 4"], [KeyBlock "Key 5"]]
[[KeyBlock "Basis"], [KeyBlock "Key 1"], [KeyBlock "Key 2"], [KeyBlock "Key 3"], [KeyBlock "Key 4"], [KeyBlock "Key 5"]]
[Ipo "KeyIpo.004" (Key)]
True
0
0.0

0.0
Basis
-1.49011614159e-009
0.0
0.0


1.0
Key 1
0.10000000149
1.0
0.0

=========================

Obviously, the getBlocks() and blocks of key are the same. Similarly, the getData() and data of keyblock are the same and gives you the data assigned (a list of vectors for each vertex included in the key). In the above code I excluded the keyblock’s getData() and data due the large output that is NOT needed for the purposes we are discussing here, ok?

Hope the above helps! :slight_smile:

Regards,

Thanks Abidos. I appreciate the advice. I think I am still missing something here though. I am looking to get the “basis name” information for each key. So Key1 might have “Basis” as its basis, and Key2 might have “key 1” as its basis, but that makes an assumption that everything is progressing in a linear fashion. What if I name the Keys “start” “middle” and “end”? I need to know the name of the Key block that is being used as the basis for the Key I am looking at. Does that make sense?

In blender 2.5 (which has really great documentation)
ob.data.shape_keys.keys[1].name
gives me Key1
ob.data.shape_keys.keys[1].relative_key.name
would give me the name “Basis” when looking at Key1
As far as I can tell there is no way to do get this info in Blender 2.49b.

The reason this can become an issue is that if I create a shape key, (which gives me “basis”) and then create another shape key to get Key1. But if I am making changes to the “Basis” key and then choose to add another shape key, then the order ends up at Basis Key2 Key1. Even though Key1 uses Basis as its starting point and Key2 uses Key1.

Thanks
Ben

Well, I think Key2 using Key1 and Key1 using Basis-key means your keys are relative. In my Bubbles animation used relative keys and I had some problems to properly imagine what should be the next key cause it should only show the vertices displacement of those verts that needs to move from Key1 to Key2, for example. I think that NOT using relative keys would mean more work though… Any how… Blender uses some strange algorithm to adding newly touched keys in the key-list for some weird sorting reasons, perhaps… :wink:

Regards,