How to find out which Shape Keys are visible to iterate through...

Hi again;

I have a set of shape keys on an object. Since you can’t actively mark shape keys to operate on, I’m aiming to work on the visible ones. Amongst all the shape keys, how can I retrieve the visible ones to iterate through only them?

Thank you;

Cheers;

AJ

No one?..

obj.data.shape_keys.key_blocks[‘Key 1’].mute will return whether or not a shape key is muted. Don’t know what you mean about you can’t actively mark shape keys.

I find that it is not possible to select x number of shape keys in the shape keys list to tell Blender that those are the ones you want to work on… I wanna be able to select, say 4 shape keys and execute a routine on them. The only way that occurred to me that would enable the user to do so would be to mute the visibility on all keys and enable it only on the ones he/she wants treated… Hope I could make myself clear enough, but I’m open to suggestions though…

Oh, I didn’t know you meant for the user. Yeah, that would probably be the easiest way. This will return a list of the visible shape keys for an object:


myList = [sk for sk in obj.data.shape_keys.key_blocks if not sk.mute]

Absolutely awesome… Thanx a lot man, I really appreciate it.

Cheers;

AJ

Aarrrghhhh!!! :frowning: Another road block… Everything works fine, except that when I iterate through the filtered list, Blender does the iteration using the shape keys’ ID numbers, although the narrowed down list be iterated according to the suffix at the end. So, I’ll need to get the user to add suffixes to the end of the name of each shape key in order to let Blender know the iteration order. But even if that’s done, how do I resort the list? I found this online, but just couldn’t adapt it to Blender Python:

Any help from the pros would again be wildly appreciated… I’m coming from XSI and used to code in VB, just started Pyhton with Blender, so I’m begging you guys to bear with me :slight_smile:

Cheers;

AJ

Sorry, I don’t understand exactly what you need. What is the basis of the iteration order?

Ok, I’ll be more specific, I know it’s a bit of a haywire…

1- The user has some shape keys in his list.
2- He mutes all of them except the ones he wants treated.
3- He renames those with a suffix (like key_1, key_2, key_3 etc.) so that Blender can understand the treatment order.
4- Then the script goes through each of those keys and does what it does.

Your snippet did the trick cmomoney, but when I iterated through the filtered list, they were iterated in the wrong order, not the order that I wanted, probably due to their ID’s being considered by Blender during iteration. What I want to do is to be able to filter them like I did, but after that tell blender to iterate through them beginning with the smallest suffix and move on to the next that has a larger suffix and etc…

Hope that makes sense…

Cheers;

AJ

If you want, you could iterate through them and get a list of them by name:


myList = [sk.name for sk in obj.data.shape_keys.key_blocks if not sk.mute]
myList.sort()  #sorts the list

Thanx once again cmomoney, but I’m getting this error in the console although the shapes are named Key 1, Key 2, Key 3:

typeError: unorderable types: ShapeKey() < ShapeKey()

Maybe I took it too literally…

The above error I got using myList.sort()

Then I tried:

unmutedShapes.sort(unmutedShapes, key = lambda x: int(x.split(’_’)[1]))

But this gives the following error:

TypeError: Argument given by name (‘Key’) and position (1)

Aaarghhh… (sigh) :-p

Did you use the code I posted? sk.name gets the name.

My bad… I overlooked that. But now, I have another problem (ayyaaa :frowning: ) Now, the names are sorted out just fine, yet they aren’t recognized when I try to add drivers to their values because the sorted list yields a list of strings… :frowning:


import bpy

ob = bpy.context.active_object

bpy.types.Object.Inbetweener = bpy.props.FloatProperty(min=0,max=1)
ob.Inbetweener = 0

shape_key = ob.data.shape_keys
kbloks = shape_key.key_blocks
#NoOfShps = len(kbloks)
unmutedShapes = [sk.name for sk in ob.data.shape_keys.key_blocks if not sk.mute]
unmutedShapes.sort()
NoOfShps = len(unmutedShapes)

i=0
while (i &lt; NoOfShps):   
    mydriver = unmutedShapes[i-1].driver_add('value')#This is where I run into problems and get an error
.......

Awww maaan… Please excuse my stupes cmomoney, I just altered the line where I add the driver to:

mydriver = ob.data.shape_keys.key_blocks[unmutedShapes[i]].driver_add("value")

I really appreciate all your help cmomoney, you’ve been so patient and helpful.

I’ll share this one with the community as soon as I can get it polished up.

Cheers; :slight_smile:

AJ


for shape in unmutedShapes:
    mydriver = kbloks[shape].driver_add('value')

EDIT- Oh, never mind, you got it. :slight_smile:

Thanx once again, you’re definitely da man, and as patient as Buddha himself :)…

Cheers;

AJ