0

In a past question, I learned that using foreach_set for a collection in shapekey can speed up the process.

However, I don't know how to create a collection with shapekey.

I have tried the following code.

import bpy

context = bpy.context

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

key_blockList = [] shapeKeyValueList = [0.0,0.1,0.2]

if sks: for block in sks.key_blocks: key_blockList.append(block)

key_blockList = sorted(key_blockList, key=lambda key_block: (key_block.name))

key_blockList.foreach_set("value", shapeKeyValueList)

Then I got the following error.

AttributeError: 'list' object has no attribute 'foreach_set'

The error message says that list objects and collections are different things.

I also tried to see if I could add shapekey to the collection.

import bpy

context = bpy.context

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

key_blockList = bpy.data.collections.new("test") shapeKeyValueList = [0.0,0.1,0.2]

if sks: for block in sks.key_blocks: key_blockList.link(block)

key_blockList = sorted(key_blockList, key=lambda key_block: (key_block.name))

key_blockList.foreach_set("value", shapeKeyValueList)

But,I got a following error.

AttributeError: 'Collection' object has no attribute 'ShapeKey'

I would like to know how to add shapekey to a collection, remove it, or initialize a collection.

Python's List allows us to reorder, remove and add elements. sks.key_blocks is inconvenient for me because it doesn't allow me to reorder, remove and add elements. I don't want to reorder them in a way that is visible to the user, I just want to reorder and remove elements as variables.

When I add key_blocks in the list, foreach_set is no longer available. But if I keep the collection, I can't figure out how to reorder or remove elements. I don't want the user to see the change in the order.

taichi
  • 398
  • 4
  • 16
  • The foreach_set method is not creating the objects, it is setting a property value to all objects in a collection, from a list of values. Use ob.shape_key_add(...) to add a new key block. Example https://blender.stackexchange.com/a/93180/15543 – batFINGER Aug 22 '21 at 14:46
  • 1
    Hard to tell, but I think you want something lik https://blender.stackexchange.com/questions/116633/adding-multiple-shape-keys-with-python-and-bmesh-while-creating-a-mesh to add shapekeys Actually, reading again Not a Blender Collection (like in outliner) used as a term for a collection of shapekeys eg sks.key_blocks where an object in that collection is a shape key. – batFINGER Aug 22 '21 at 15:30
  • The shape_key_add command adds keyblocks to a shapekey that does not have any keyblocks. However, I don't want to add keyblocks to the shapekey. What I want to do is to extract keyblocks from a shapekey that already has keyblocks. Then I want to treat the extracted keyblocks like a list. – taichi Aug 22 '21 at 22:14
  • 1
    sks.key_blocks[:] is a list. A blender object collection ie a bpy_prop_collection like bpy.data.objects or sks.key_blocks has a foreach_set method, a python list does not. Hard to get a read on what you are trying to achieve here. – batFINGER Aug 23 '21 at 06:54
  • I already have a list of shapekey values like [0.1, 0.2, 0.3, 0.4, 0.5 ....]. I want to assign this values to [keyblock_a, keyblock_b, keyblock_c, keyblock_d, keyblock_e ....] with foreach_set. However, depending on the user's environment, the order of keyblocks may be different, such as [keyblock_c, keyblock_b, keyblock_a, keyblock_e, keyblock_d ....]. Therefore, it is difficult to use foreach_set. – taichi Aug 23 '21 at 07:31
  • 1
    Consider then making queston that. Remove , what are IMO unnecessary references to bpy.data.collections, and list not having a foreach_set, The sks.key_blocks is in the order seen in UI, in general with "Basis" at zero index (on top). If your list of values is in name order, then to set with foreach_set sort your list to match the order of the key blocks. – batFINGER Aug 23 '21 at 08:40
  • OK,Thank you for the reply! – taichi Aug 23 '21 at 09:30

0 Answers0