2

I'm controlling Blender's shapekey in the following Python script.

This still works fast enough, but is there any low layer code that works faster?

import bpy
selectList = bpy.context.selected_objects

if selectList[0].data.shape_keys: for block in selectList[0].data.shape_keys.key_blocks: block.value = 0.5

taichi
  • 398
  • 4
  • 16

1 Answers1

3

foreach_set

To avoid looping over collection and setting a property value per item can instead use collection.foreach_set(property_name, values) [Find numerous links re this']

The values list is a flat list, eg if the property uv for example is a vector then the list

values = [u0, v0, u1, v1, ...., un, vn] 

For keyblock values

import bpy

context = bpy.context

ob = context.object me = ob.data sks = me.shape_keys

if sks: vals = (0.5, ) * len(sks.key_blocks) sks.key_blocks.foreach_set("value", vals)

batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • Great! Is there a way to avoid the assignment if, for example, I don't want to assign a value to the third value of key_blocks? Is there any way to have a list of [smile_L,eyeClose_L,smile_R,,eyeClose_R] and ignore smile_R? – taichi Aug 19 '21 at 22:00
  • 1
    Can load the current values into a flat list with foreach_get eg https://blender.stackexchange.com/questions/1412/efficient-way-to-get-selected-vertices-via-python-without-iterating-over-the-en/233823#233823 – batFINGER Aug 20 '21 at 03:15