Any blender python reference for idiots?

I’m a novice trying to work out how to create a minimal Blender animation scene using a driver entirely in Python. Basically I have created an empty and a sphere, and I want the sphere’s Z-location to be driven by the empty’s Z-rotation, eg. Sphere’s z location = cos(empty’s z-rotation).

I expected it to be trivial, but…

I have hunted around for hours and I’m still a bit lost. I’ve found lots of posts and examples but they all start in the middle of the process and assume a lot of prior knowledge of Blender. The Blender API is not much use because it doesn’t really explain much and I don’t know how to combine the information into a working script. The Python error messages in the linux terminal don’t help much either. I’m not looking for someone to just tell me the solution, I want to understand how to do this, but just searching on the internet hoping to stumble across a relevant page seems like an absurdly scattershot approach. I’ve done prior programming with C, C++, javascript, PHP, etc, but they all have excellent references available so learning them didn’t seem anywhere near as difficult as I’m finding Blender Python.

Is there any comprehensive reference for Blender Python for thickheads like me, preferably with fully worked examples?:spin:

This is what I’ve got so far. The initial position of the sphere is correct but I don’t know how to make the sphere’s location change when the empty rotates. Presumably keyframes are involved but I haven’t found any example that details that part. (It’s probably obvious to you, but hey like I said: ‘thickhead’)


import bpy
from math import pi

scn = bpy.context.scene

# Create an Empty
empty = bpy.data.objects.new('Empty', None)
empty.location = (0, 0, 0)
empty.rotation_euler = (0, 0, pi)
empty.empty_draw_size = 0.5
empty.empty_draw_type = 'PLAIN_AXES'
empty.show_name = True
scn.objects.link(empty)
scn.update()

# Create sphere
bpy.ops.mesh.primitive_uv_sphere_add(segments=32, size=0.3, location=(1, 1, 0))
bpy.ops.object.shade_smooth()
ob = bpy.context.active_object
ob.name = "sphere"
ob.show_name = True
print(ob.name)

# Create a driver for the sphere's Z-axis position
fcurve = ob.driver_add("location", 2)

fvar = fcurve.driver.variables.new()
fvar.name = 'rotation'
fvar.targets[0].id = empty
fvar.targets[0].data_path = 'rotation.z'

fcurve.driver.expression = 'cos(rotation)'

Ok, in mucking about with the Blender UI I’ve realised the problem isn’t with keyframes. Clearly there’s something wrong with the script because I can get the driver working via the GUI. Now if there was only some way of exporting a Blender scene to a working python script so I could work out how it’s supposed to be coded …

Ok, I finally got it working by sheer trial and error - so far, anyway.

Having developed this script by the internet’s equivalent of Brownian motion, I assume there are potential issues in this code somewhere.

I would still like to be pointed in the direction of any good books for doing this Blender Python stuff. Learning anything this random searching way sucks bigtime.


import bpy
from math import pi

# Get the current scene
scn = bpy.context.scene

# Set a name for the empty object to be created
empty_name = 'Empty'

# Define a function to return the empty's z-rotation
def get_empty_z_rotation():
    obj = bpy.data.objects[empty_name]
    return obj.rotation_euler[2]

# Add the name of the function to the scene's driver namespace for future reference
bpy.app.driver_namespace['get_empty_z_rotation'] = get_empty_z_rotation

# Create an Empty
empty = bpy.data.objects.new(empty_name, None)
empty.location = (0, 0, 0)
empty.rotation_euler = (0, 0, pi)
empty.empty_draw_size = 0.5
empty.empty_draw_type = 'PLAIN_AXES'
empty.show_name = True
scn.objects.link(empty)
scn.update()

# Create sphere
bpy.ops.mesh.primitive_uv_sphere_add(segments=32, size=0.3, location=(1, 1, 0))
bpy.ops.object.shade_smooth()
sphere = bpy.context.active_object
sphere.name = "sphere"
sphere.show_name = True
print(sphere.name)

# Create a driver for the sphere's Z-axis location
fcurve = sphere.driver_add("location", 2)

# Create a driver variable - this is required, but why? 
# To tell Blender which properties to track? Or something else?
fvar = fcurve.driver.variables.new()
fvar.name = 'rotation'
fvar.targets[0].id = empty
fvar.targets[0].data_path = 'rotation_euler[2]'

# The python expression used to calculate the sphere's z-location
fcurve.driver.expression = 'cos(get_empty_z_rotation())'

Well, you have the reference (https://www.blender.org/api/blender_python_api_2_77_1/) but you still need a functional knowledge of python.

Thanks for the reply. It’s not Python that I find difficult, it’s Blender’s internals, and how to understand them so I can program what I want in Python. For example, I discovered that I had to create a driver variable to get the script to work, but I don’t really know why a driver variable is required. I would have thought the driver expression using a function was sufficient.
Ideally I would like to find a book that teaches how to write functional Blender Python scripts, from beginner to advanced, like the books that are available for so many other programming tasks.

I find the “Autocomplete” button at the bottom of the python console very helpful in understanding syntax etc. The Info window is also helpful in that it echoes the functions you use by clicking in the graphical interface.

The cookbook and gotchas are good to check out, can also checkout this blog and these code snippets or those that come with blender in the text editor, there is also blender stack exchange for questions you may have and this forum of course, ultimately nothing beats looking through other scripts.

Driver variables are required internally for blender’s driver system if you want to do any type of real time updating with a few exceptions, they are not to be confused with python variables, you can have 0 or more driver variables all of which references their own channels of influence, such as the location of an object, furthermore it is possible to combine these variables via the driver expression to desired effect.

Note - Documentation easily becomes out dated at the rate that blender is developed.

Thanks for the responses, they are very helpful.

There is obviously a lot of information about Blender Python available within Blender itself and in the linked sites (duly bookmarked :)), the trick is knowing where to find it. Strangely, countless internet searches for hours didn’t lead me to any of proxe’s linked suggestions. They are exactly the type of site I was looking for.

I take your point about documentation becoming out of date. It’s the price we pay for rapidly evolving software.

My next step was to (reluctantly) start searching through Blender’s source code, but I think I can put that off for now.

[Is blender stack exchange better than the standard programming stack exchange? I used to be a member of stack overflow for programming but the only answers I got were immediate responses from people that didn’t address my question, apparently something to do with earning points for stack exchange’s absurd ‘game-style’ approach.]