0
$\begingroup$

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.

$\endgroup$
7
  • $\begingroup$ 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 blender.stackexchange.com/a/93180/15543 $\endgroup$
    – batFINGER
    Commented Aug 22, 2021 at 14:46
  • 1
    $\begingroup$ Hard to tell, but I think you want something lik blender.stackexchange.com/questions/116633/… 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. $\endgroup$
    – batFINGER
    Commented Aug 22, 2021 at 15:30
  • $\begingroup$ 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. $\endgroup$
    – taichi
    Commented Aug 22, 2021 at 22:14
  • 1
    $\begingroup$ 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. $\endgroup$
    – batFINGER
    Commented Aug 23, 2021 at 6:54
  • 1
    $\begingroup$ 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. $\endgroup$
    – batFINGER
    Commented Aug 23, 2021 at 8:40

0

You must log in to answer this question.

Browse other questions tagged .