Blender has many interlinking data types which have an auto-generated reference api which often has the information you need to write a script, but can be difficult to use.
This document is designed to help you understand how to use the reference api.
The most common case for using the reference API is to find out how to access data in the blend file.
Before going any further its best to be aware of ID Data-Blocks in Blender since you will often find properties relative to them.
ID Data-Blocks are used in Blender as top-level data containers.
From the user interface this isn’t so obvious, but when developing you need to know about ID Data-Blocks.
ID data types include Scene, Group, Object, Mesh, Screen, World, Armature, Image and Texture. for a full list see the sub-classes of bpy.types.ID
Here are some characteristics ID Data-Blocks share.
Lets start with a simple case, say you wan’t a python script to adjust the objects location.
Start by finding this setting in the interface Properties Window -> Object -> Transform -> Location
From the button you can right click and select Online Python Reference, this will link you to: bpy.types.Object.location
Being an API reference, this link often gives little more information then the tool-tip, though some of the pages include examples (normally at the top of the page).
At this point you may say Now what? - you know that you have to use .location and that its an array of 3 floats but you’re still left wondering how to access this in a script.
So the next step is to find out where to access objects, go down to the bottom of the page to the References section, for objects there are many references, but one of the most common places to access objects is via the context.
It’s easy to be overwhelmed at this point since there Object get referenced in so many places - modifiers, functions, textures and constraints.
But if you want to access any data the user has selected you typically only need to check the bpy.context references.
Even then, in this case there are quite a few though if you read over these - most are mode specific. If you happen to be writing a tool that only runs in weight paint mode, then using weight_paint_object would be appropriate. However to access an item the user last selected, look for the active members, Having access to a single active member the user selects is a convention in Blender: eg. active_bone, active_pose_bone, active_node ... and in this case we can use - active_object.
So now we have enough information to find the location of the active object.
You can type this into the python console to see the result.
The other common place to access objects in the reference is bpy.types.BlendData.objects.
With bpy.data.objects, this is a collection of objects so you need to access one of its members.
The previous example is quite straightforward because location is a property of Object which can be accessed from the context directly.
Here are some more complex examples:
# access a render layers samples bpy.context.scene.render.layers["RenderLayer"].samples # access to the current weight paint brush size bpy.context.tool_settings.weight_paint.brush.size # check if the window is fullscreen bpy.context.window.screen.show_fullscreen
As you can see there are times when you want to access data which is nested in a way that causes you to go through a few indirections.
The properties are arranged to match how data is stored internally (in blenders C code) which is often logical but not always quite what you would expect from using Blender.
So this takes some time to learn, it helps you understand how data fits together in Blender which is important to know when writing scripts.
When starting out scripting you will often run into the problem where you’re not sure how to access the data you want.
There are a few ways to do this.
Blender can compute the Python string to a property which is shown in the tool-tip, on the line below Python: ..., This saves having to use the API reference to click back up the references to find where data is accessed from.
There is a user-interface feature to copy the data-path which gives the path from an bpy.types.ID data-block, to its property.
To see how this works we’ll get the path to the Subdivision-Surface modifiers subdivision setting.
Start with the default scene and select the Modifiers tab, then add a Subdivision-Surface modifier to the cube.
Now hover your mouse over the button labeled View, The tool-tip includes bpy.types.SubsurfModifier.levels but we want the path from the object to this property.
Note that the text copied won’t include the bpy.data.collection["name"]. component since its assumed that you won’t be doing collection look-ups on every access and typically you’ll want to use the context rather then access each bpy.types.ID instance by name.
Type in the ID path into a Python console bpy.context.active_object. Include the trailing dot and don’t hit “enter”, yet.
Now right-click on the button and select Copy Data Path, then paste the result into the console.
So now you should have the answer:
Hit “enter” and you’ll get the current value of 1. Now try changing the value to 2:
bpy.context.active_object.modifiers["Subsurf"].levels = 2
You can see the value update in the Subdivision-Surface modifier’s UI as well as the cube.
For this example we’ll go over something more involved, showing the steps to access the active sculpt brushes texture.
Lets say we want to access the texture of a brush via Python, to adjust its contrast for example.
Start in the default scene and enable ‘Sculpt’ mode from the 3D-View header.
From the toolbar expand the Texture panel and add a new texture.
Notice the texture button its self doesn’t have very useful links (you can check the tool-tips).
The contrast setting isn’t exposed in the sculpt toolbar, so view the texture in the properties panel...
Right click on the contrast button and select Online Python Reference This takes you to bpy.types.Texture.contrast
Now we can see that contrast is a property of texture, so next we’ll check on how to access the texture from the brush.
Check on the References at the bottom of the page, sometimes there are many references, and it may take some guess work to find the right one, but in this case its obviously Brush.texture.
Now we know that the texture can be accessed from bpy.data.brushes["BrushName"].texture but normally you won’t want to access the brush by name, so we’ll see now to access the active brush instead.
So the next step is to check on where brushes are accessed from via the References. In this case there is simply bpy.context.brush which is all we need.
Now you can use the Python console to form the nested properties needed to access brush textures contrast, logically we now know.
Context -> Brush -> Texture -> Contrast
Since the attribute for each is given along the way we can compose the data path in the python console:
There can be multiple ways to access the same data, which you choose often depends on the task.
An alternate path to access the same setting is...
Or access the brush directly...
If you are writing a user tool normally you want to use the bpy.context since the user normally expects the tool to operate on what they have selected.
For automation you are more likely to use bpy.data since you want to be able to access specific data and manipulate it, no matter what the user currently has the view set at.
Most key-strokes and buttons in Blender call an operator which is also exposed to python via bpy.ops,
To see the Python equivalent hover your mouse over the button and see the tool-tip, eg Python: bpy.ops.render.render(), If there is no tool-tip or the Python: line is missing then this button is not using an operator and can’t be accessed from Python.
If you want to use this in a script you can press Control-C while your mouse is over the button to copy it to the clipboard.
You can also right click on the button and view the Online Python Reference, this mainly shows arguments and their defaults however operators written in Python show their file and line number which may be useful if you are interested to check on the source code.
Not all operators can be called usefully from Python, for more on this see using operators.
Blender records operators you run and displays them in the Info space. This is located above the file-menu which can be dragged down to display its contents.
Select the Script screen that comes default with Blender to see its output. You can perform some actions and see them show up - delete a vertex for example.
Each entry can be selected (Right-Mouse-Button), then copied Control-C, usually to paste in the text editor or python console.
Not all operators get registered for display, zooming the view for example isn’t so useful to repeat so its excluded from the output.
To display every operator that runs see Show All Operators