Rendering multiple files / scenes via python API

Hello,

I’ve been looking for a way to automate rendering of several scenes in Blender, either from the same file or from different files, and I can’t seem to get it working.

There are two ways to do this, as far as I can see. Option 1 is to save many different scenes to the same .blend file, and cycle through each scene, rendering it as I go. That code would look something like this:

for Scn in bpy.data.scenes:
# Set active scene
bpy.context.screen.scene = Scn
# Set rendering options
Scn.render.file_format = ‘PNG’
Scn.render.filepath = ‘/some/unique/file/path.png’ # (I of course vary this with each loop iteration)
# Render
bpy.ops.render.render(write_still=True,scene=Scn.name)

… However, this doesn’t work - the render command at the end of the loop will repeatedly render whichever scene is active as the script is called. Basically, the “scene=” argument in the render() command seems not to work.

The second way I could do this is to store all my scenes in different .blend files, open each one and render it in sequence. However, it seems that once a .blend file is opened via

bpy.ops.wm.open_mainfile(filepath=‘FileName.blend’,load_ui=False)

… then the script stops dead in its tracks and no further commands are executed. That is:

bpy.ops.wm.open_mainfile(filepath=‘FileName.blend’,load_ui=False)

This never executes.

Scn = bpy.context.scene
print(Scn.name)

Anyone have any idea how I might proceed? Is there some other option I haven’t considered? Also, even if it’s not the best way, I’m particularly interested in whether the python API can handle opening and closing multiple files within the same script…

Thanks!

A third option, btw, is to import each scene into an empty .blend file, but if you do that you run into the same problem as before - namely, that you can’t switch to the new scene and then render it.

Again - any help would be much appreciated. Cheers.

Solved this problem eventually by using compositor nodes (thanks to a suggestion from Atom). I now have files with many scenes in them, and in the first scene, I add a compositor “File Output” node and connect it to the render layer node.

I then change the input of the render layer node via a python script, and repeatedly render the first scene. This is an OK work-around, but it would be nice if the bpy.data.scenes[n].update() command took effect before any subsequent render commands.

The original poster already found a solution for his problem, but I came upon this thread while searching for a solution to a similar problem.
On IRC I was pointed to the following code (part of addons/io_mesh_uv_layout/export_uv_png.py):

data_context = {"blend_data": bpy.context.blend_data, "scene": scene}
bpy.ops.render.render(data_context)

I’m posting it here, because other people who come upon this thread by searching, might find it useful.

Hmm… I’m surprised at the problem - is the 2.5x API really that unfinished? In 2.49 this works perfectly:

for tScene in bpy.data.scenes:
  tScene.makeCurrent()
  print "Rendering " + tScene.getName()
  tRenderData = tScene.getRenderingContext()
  tRenderData.render()

(I went through about ten edits to get this post to display correctly…)

So the complete code to render all scenes in your blend file using their original settings would be as follows:

import bpy
for scene in bpy.data.scenes:
    data_context = {"blend_data": bpy.context.blend_data, "scene": scene}
    bpy.ops.render.render(data_context, animation=True)

note, you can do this…


import bpy
data_context = bpy.context.copy()

for scene in bpy.data.scenes:
    data_context["scene"] = some_scene
    bpy.ops.render.render(data_context, animation=True)

After a bit of tinkering, I found a oneliner to render a specific scene (single image).

bpy.ops.render.render({'scene': bpy.data.scenes['SpecificScene']}, write_still=True)

(for future searches, like the one I made to find this thread)