Blender 4.1: Python API¶
Python 3.11¶
Python has been upgraded to version 3.11, matching the VFX platform 2024.
Enum ID Properties¶
Support for enum items has been added to integer properties. 92cf9dd2f2
There is no support yet for editing enum items through the UI (see commit message for technical reasons).
Enum items can be added to an integer property using the
id_properties_ui
python method. The as_dict method can be used to retrieve a list of
enum items of a property.
my_object["my_prop"] = 2
ui_data = my_object.id_properties_ui("my_prop")
ui_data.update(items=[
("TOMATOES", "Tomatoes", "Solanum lycopersicum"),
("CUCUMBERS", "Cucumbers", "Cucumis sativus"),
("RADISHES", "Radishes", "Raphanus raphanistrum"),
])
print(ui_data.as_dict())
The existing conveniency wrapper function supports it as well:
from rna_prop_ui import rna_idprop_ui_create
rna_idprop_ui_create(my_object, "my_prop", default=2, items=[
("TOMATOES", "Tomatoes", "Solanum lycopersicum"),
("CUCUMBERS", "Cucumbers", "Cucumis sativus"),
("RADISHES", "Radishes", "Raphanus raphanistrum"),
])
Int properties with enum items are shown as a dropdown button in the UI.
Layout Panels¶
Blender has new so called "layout panels".
These panels are defined inside of draw functions and don't require extra registration.
This significantly reduces the amount of code required to create collapsable sections in a panel.
(f824476bd5,
8896446f7e,
ddd06eeb8f)
import bpy
from bpy.props import BoolProperty
class LayoutDemoPanel(bpy.types.Panel):
bl_label = "Layout Panel Demo"
bl_idname = "SCENE_PT_layout_panel"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "scene"
def draw(self, context):
layout = self.layout
scene = context.scene
layout.label(text="Before")
header, panel = layout.panel("my_panel_id", default_closed=False)
header.label(text="Hello World")
if panel:
panel.label(text="Success")
header, panel = layout.panel_prop(scene, "show_demo_panel")
header.label(text="My Panel")
if panel:
panel.prop(scene, "frame_start")
panel.prop(scene, "frame_end")
layout.label(text="After")
bpy.utils.register_class(LayoutDemoPanel)
bpy.types.Scene.show_demo_panel = BoolProperty(default=False)
Breaking Changes¶
Foreach¶
foreach_getandforeach_sethave been optimized for cases where internal storage is 8, 16 or 64 bit. (PR#115761)foreach_setnow performs more accurate bounds checks, and raises aTypeErrorin cases where the value was previously silently written incorrectly.
Light Probes¶
- The Lightprobe type items have been renamed. It affects
bpy.types.LightProbe.type,bpy.types.BlendDataProbes.new()andbpy.ops.object.lightprobe_add().CUBEMAP->SPHEREPLANAR->PLANEGRID->VOLUME
show_datahas been deprecated. Useuse_data_displayinstead.- Each
LightProbenow has its owndata_display_sizeproperty.
Mesh¶
- Sculpt mask values are stored in a generic attribute
(f2bcd73bd2).
- The name is ".sculpt_mask", with the
FLOATtype. - Accessing, adding, and removing masks is done in a simpler way:
- The
Mesh.vertex_paint_maskproperty returns the attribute directly, rather than a collection. - The
Mesh.vertex_paint_mask_ensure()andMesh.vertex_paint_mask_remove()functions add and remove the attribute.
- The
- The name is ".sculpt_mask", with the
- The
Meshauto_smoothproperty has been replaced by a modifier node group asset (89e3ba4e25).use_auto_smoothis removed. Face corner normals are now used automatically if there are mixed smooth vs. not smooth tags. Meshes now always use custom normals if they exist.auto_smooth_angleis removed. Replaced by a modifier (or operator) controlling the"sharp_edge"attribute. This means the mesh itself (without an object) doesn't know anything about automatically smoothing by angle anymore.create_normals_split,calc_normals_split, andfree_normals_splitare removed, and are replaced by the simplerMesh.corner_normalscollection property. Since it gives access to the normals cache, it is automatically updated when relevant data changes.MeshLoop.normalis now a read-only property. Custom normals should be created bynormals_split_custom_setornormals_split_custom_set_from_vertices.
Material¶
- The
displacement_methodproperty has moved fromcycles.properties.CyclesMaterialSettingstobpy.types.Materiala001cf9f2b
Sequencer¶
- Strip transform filter type
SUBSAMPLING_3x3was renamed toBOX.
It affectsbpy.types.SequenceTransform.filter. (PR#117584)
View Layer¶
- Add
Scene.view_layers.move()method to reorder view layers. (PR#117037)
Nodes¶
- Some nodes (e.g.
Store Named Attribute) use dynamic socket types now instead of having all socket types exist at the same time. This means that doing something likenode.outputs[some_index]does not work the same for those nodes anymore. Instead usenode.outputs[some_socket_identifier]which is more reliable. (8149678d5e)
Grease Pencil Brushes¶
- The property
brush.gpencil_settings.directionhas been replaced bybrush.direction. (998514af7b)
Additions¶
- Add
Preferences.filepaths.asset_libraries.new/removemethods (0061f2f650) - Add
ID.session_uidread-only property (c68b22cfdf) - Add
NodesModifierBake.bake_idread-only property (7149424087) - Add
NodesModifierBake.noderead-only property (65b722bc30) - Add
bpy.app.handlers.translation_update_postupdate handler that runs when translations change (8564e03cdf) - Add optional "frame" & "tile_index" arguments to
Image.scale()(3d60209d3d) - Add
ShapeKey.pointsproperty (7d77caab9b) - Add access to ordering of links in multi-input socket (8f36281787)
Shape Key Locks¶
Shape Keys can now be locked by the user to prevent accidental edits in sculpt and edit mode (b350d7a4c3). Add-ons that implement operators that transform the active shape without topology changes, or invoke other built-in operators that already perform the check, may consider adding these checks to their own code.
Built-in operator examples:
mesh.vertices_smoothdoes the check, because it transforms the active shape.mesh.subdividedoesn't check, because it changes topology.object.transform_applydoesn't check, because it applies the same transformation to all shapes (the active shape key choice doesn't matter).mesh.polybuild_extrude_at_cursor_movechecks, because internally it invokes another operator that does the check.
Example of implementing the check:

