foreach_set is a convenient wrapper in the Blender Python API for quickly setting the desired value for each element of the bpy_prop_collection type. However, when using this function, script developers sometimes run into an error.
For example, let’s switch all the polygons in the mesh to smooth shading. To achieve this, the “use_smooth” property of each mesh polygon must be set to True.
With common Python syntax, we can write the following code:
1 2 |
for polygon in bpy.context.object.data.polygons: polygon.use_smooth = True |
If we want to use the foreach_set functional, it seems logical to write the following:
1 |
bpy.context.object.data.polygons.foreach_set('use_smooth', True) |
however, calling this function in this way will result in an error:
couldn’t access the py sequence
This occurs because the second parameter in the foreach_set function should not be the value itself, which we want to set for the “use_smooth” property, but a list of values for each of the polygons.
Instead of
1 |
True |
we need to use:
1 |
[True, True, ..... True] |
The length of the list must correspond to the number of elements for which the foreach_set function is called, in our case – the number of polygons.
So, to properly use the foreach_set function, first we need to create a list of values by the number of mesh polygons:
1 2 3 |
set_list = [True]*len(bpy.context.object.polygons) # [True, True, True, ....] |
and next pass it as the second parameter to the function:
1 |
bpy.context.object.data.polygons.foreach_set('use_smooth', set_list) |
Or all in one string:
1 |
bpy.context.object.data.polygons.foreach_set('use_smooth', [True]*len(bpy.context.object.polygons)) |