Skip to content

Blender 4.0: Python API

Breaking changes

Asset System

  • context.asset_file_handle is removed. Use context.asset instead.
    Note that it returns a AssetRepresentation, not a FileSelectEntry, but should provide access to the same information. When not (e.g. because an asset's preview icon-ID is needed), context.active_file may be available instead. (f6a6b27ac1)
  • context.selected_asset_files is removed, use context.selected_assets instead. The same note as for context.asset_file_handle applies.
  • FileSelectEntry:
    • .id_type was removed. For assets, use AssetRepresentation.id_type instead. (d973cc7992)
    • .local_id was removed. For assets, use AssetRepresentation.local_id instead. (d973cc7992)
  • AssetHandle:
    • get_full_library_path() was removed. Use AssetRepresentation.full_library_path instead. (d973cc7992)
    • local_id was removed. Use AssetRepresentation.local_id instead. (d973cc7992)
  • Occurrences of the name asset_library_ref were replaced by asset_library_reference throughout the API (974d70918b).
  • FileAssetSelectParams.import_type was renamed to FileAssetSelectParams.import_method (ca2a8be15f).

Note: AssetHandle should now only be used to provide a collection custom property for UILayout.template_asset_view().

Window Manager

  • Operator.bl_property no longer defaults to "type" (7bc34283ea)

Mesh

  • The mesh format changes from previous versions are now included in the Blender file format, reducing overhead when saving files and decreasing file sizes (1b63a290c6).
    • Blender 3.6 can read files from 4.0, but earlier versions cannot.
    • Blender 3.6 can be used to save files from 4.0 in a format that is compatible with older versions.
  • Face Maps have been removed, with their values converted automatically to an integer attribute (46cf093270).
  • Bevel weights have been moved to generic attributes with the names bevel_weight_vert and bevel_weight_edge (2a56403cb0).
    • Existing access to bevel weights (MeshEdge.bevel_weight) has been removed in favor of the attribute API.
    • Forward compatibility is not preserved, though old versions will read the new generic attribute.
  • Vertex and edge crease have been moved to generic attributes as well, with the names crease_vert and crease_edge (e5ec04d73c).
    • The MeshEdge.crease property has been removed.
    • The mesh properties vertex_creases and edge_creases now return attributes directly.
    • New functions {vertex/edge}_creases_ensure and {vertex/edge}_creases_remove create and remove the attributes with the proper domain and type.
  • The sculpt_vertex_colors API has been removed, replaced by mesh.color_attributes (6805657a39).
  • Other mesh custom data functions redundant with the attribute API have been removed: vertex_layers_float, vertex_layers_int, vertex_layers_string, polygon_layers_float, polygon_layers_int, polygon_layers_string (d41021a7d4).
  • Mesh.calc_normals is no longer needed and has been removed (ab5fc46872).
  • bmesh_from_object and BVHTree FromObject now require an evaluated dependency graph to retrieve the final mesh (e64b3c8212).
  • A deprecated argument has been removed from the split_faces function (efbcfd8703).

Curves

  • The curves.select_end operator is now named curves.select_ends. It has a amount_start and amount_end property to select points from both the front and back.

Nodes

  • The unused width_hidden property has been removed (30a20b4def).
  • NodeItem and NodeCategory definitions have been removed for shader and compositor nodes (15f5dfd45d).
    • The add menus can be extended the standard way from the Python API, with the ID names NODE_MT_shader_node_add_all and NODE_MT_compositor_node_add_all.
  • node.inputs\[xxx\] and node.outputs\[xxx\] take socket identifiers and availability status into account (e4ad58114b).

Shader Nodes

  • The Glossy BSDF and Anisotropic BSDF nodes have been merged (8cde7d8f8a). In the Python API, the resulting node is referred to as ShaderNodeBsdfAnisotropic. When creating nodes, ShaderNodeBsdfGlossy is still accepted as an alias, but it will result in a ShaderNodeBsdfAnisotropic being created. Add-ons and scripts should replace usage of ShaderNodeBsdfGlossy with ShaderNodeBsdfAnisotropic, which will also work with previous versions all the way to pre-2.80.
  • The Principled BSDF node has been revamped and now aligns more closely to Standard Surface and OpenPBR. Various sockets were renamed:
    • Subsurface -> Subsurface Weight
    • Subsurface Color removed, use Base Color instead
    • Specular -> Specular IOR Level
    • Specular Tint changed from float to color
    • Transmission -> Transmission Weight
    • Coat -> Coat Weight
    • Sheen -> Sheen Weight
    • Emission -> Emission Color

Lights

  • Light properties for falloff, attenuation and shadow buffers were removed. These were not used by Cycles or EEVEE. (57d85b32a9)

Particle System

  • ParticleSystem.child_nbr has been renamed to child_percent e82ca9b5ff.

Blender Application (bpy.app)

  • Remove deprecated bpy.app.version_char (345fc2b1f6)

Blender Operators (bpy.ops)

  • Remove the context override argument to bpy.ops in favor of context.temp_override(..) (ac263a9bce)

Font Module (blf)

  • blf.size() dpi argument has been removed (9357f7b606).

GPU Module (gpu)

- Remove deprecated 2D_ / 3D_ prefix for built-in shader names (9a8fd2f1dd).

Animation

  • FCurve.update() now also deduplicates the F-Curve's keys (6452eccc80).
  • Action.frame_range now accurately reports zero-length frame ranges (49eab72141). Previously, it was special-cased to construct and report a 1-frame-length range if and only if the action was exactly zero length (not e.g. 0.001 length). This was confusing and easily misinterpreted as being a minimum 1-frame-length range or as being an exclusive-on-the-right range, neither of which have ever been the case. The new behavior simply reports the actual frame range as-is in all cases.

Armatures

  • Layers and bone groups have been removed with all associated properties and methods. Bone collections have been added instead. (998136f7a7 and many subsequent commits). See Bone Collections & Colors: Upgrading for an overview of how to change Python code to the new API.
  • Now edit_bones.new() behaves similar to object creation, and does not automatically add the created bone to any collections. To emulate the behavior of the add bone operator, manually assign the bone to arm.collections.active if it is not None. (ab67d410a9)
  • The deprecated use_inherit_scale bone property has been removed. (2abd026cfe)

Node Groups

# Make a socket
tree.inputs.new(name="My Input")
tree.outputs.new(name="My Output")

# Remove a socket
tree.inputs.remove(socket)
tree.outputs.remove(socket)

# Move a socket up or down
tree.inputs.move(from_index=4, to_index=2)

# Iterate over sockets
for socket in tree.inputs:
    ...
for socket in tree.outputs:
    ...
# Make a socket
# Note: socket_type accepts only base socket type names,
# e.g. `NodeSocketFloat` but not `NodeSocketFloatFactor`.
tree.interface.new_socket(name="My Input", in_out='INPUT')
tree.interface.new_socket(name="My Output", in_out='OUTPUT')
# Make node panel
tree.interface.new_panel(name="My Panel")

# Copy an existing socket or panel
tree.interface.copy(socket)

# Remove a socket or panel
tree.interface.remove(socket)
tree.interface.remove(panel)

# Move a socket up or down
tree.interface.move(socket, to_index=2)
# Move a socket into a panel
tree.interface.move_to_parent(socket, new_panel, to_index=2)

# Iterate over sockets
for item in tree.interface.items_tree:
    if item.item_type == 'SOCKET':
        if item.in_out == 'INPUT':
            ...
        elif item.in_out == 'OUTPUT':
            ...
# Iterate over panels
for item in tree.interface.items_tree:
    if item.item_type == 'PANEL':
        ...

Modifying items

The previous node group API in some cases allowed modifying inputs/outputs collections while iterating over them. This was incidental and generally should be avoided. See "Gotchas" for more details

  • Custom nodes: NodeSocket.draw_color_simple callback becomes the preferred color function for custom socket types.

    It does not take a context or node instance but that is sufficient for most use cases. The new callback is used in cases where concrete node instance exists, for example drawing node group interfaces.

class MyCustomSocket(NodeSocket):
    def draw_color(self, context, node):
        return (1, 1, 1, 1)
class MyCustomSocket(NodeSocket):
    @classmethod
    def draw_color_simple(cls):
        return (1, 1, 1, 1)

Sequencer

  • Sequence.speed_factor was replaced with more complex retiming system (86a0d0015a).

Import/Export

  • The Python based OBJ importer/exporter has now been removed. Addons using bpy.ops.import_scene.obj and bpy.ops.export_scene.obj APIs should to switch to bpy.ops.wm.obj_import and bpy.ops.wm.obj_export
  • The Python based PLY importer/exporter has now been removed. Addons using bpy.ops.import_mesh.ply and bpy.ops.import_mesh.ply APIs should to switch to bpy.ops.wm.ply_import and bpy.ops.wm.ply_export

Misc

  • Rename filename to filepath for RNA API calls (efa4179982).
    • Depsgraph.debug_relations_graphviz, Depsgraph.debug_stats_gnuplot.
    • RenderLayer.load_from_file, RenderResult.load_from_file.
    • bpy.app.icons.new_triangles_from_file
    • Some built-in color space names were renamed. Forward compatibility is preserved via do-versions, but assignment of hard-coded names could break

Hydra Render Delegates

Renderer add-ons can now be implemented as USD Hydra render delegates. We recommend add-on developers to use this, and get involved in Blender development to add any missing functionality. (04bb5f9995)

Using Hydra provides two major benefits:

  • The same Hydra render delegate works across multiple 3D apps, and therefore much of the implementation can be shared.
  • Performance with heavy scenes is much better, because Hydra is a C++ API instead of Python.

Blender shader nodes can be automatically converted to a MaterialX node graph for renderers that support it. Only a subset of shader nodes are supported currently, see the compatibility list.

The HydraRenderEngine API docs have more for details.

Additions

  • bpy.context.property, for property under the mouse cursor (6ba0346797).
  • UILayout.progress(..) widget type added to display progress from scripts (c6adafd8ef).
  • PoseBone.bbone_segment_index() for accessing the internal math mapping vertices (their positions) to B-Bone segments that deform them (36c6bcca1a)
  • Curves.add_curves(..) for adding new curves to a curves data-block (07f01b5fc2).