Probably this has been discussed before, but I didn’t find any details. Ages ago I have pieced together a script to render all cameras in a blend to separate images. I create a lot of booths for trade shows and such stuff and it is just very convenient when I can place a few dozen cameras around an object and just hit render before going home, to find all perspectives rendered when I return. I have a script that does that quite nicely. It’s simple, it iterates through all cameras and just renders them to the output path of the file (adding the camera name to the filename).
However, there are times when I would like to see how far an image is rendered (or just check if I have made a fundamental mistake… once in the morning I found a bunch of renderings lit in bright pink because the environment map had been renamed)
So I would like to have the rendering progress displayed exactly as it is when just hitting F12. To do that I gathered that I would have to change the execution context from default “EXEC_DEFAULT” to “INVOKE_DEFAULT”. But when I do, only the first camera of the scene is rendered. For the other cameras the rendering command is just plainly skipped. I don’t see how this can be, as I see that the for loop does indeed loop through the cameras correctly.
Here is my code:
import os, bpy, bgl, blf, sys
from bpy import data, ops, props, types, context
# setup renderbutton for stills
class RenderAllCameras(bpy.types.Operator):
bl_idname = "render_cams.button"
bl_label = "All stills"
def execute(self, context):
print('')
print('Rendering stills for all cameras...')
renderStuff(False)
return{'FINISHED'}
# setup renderbutton for animations
class RenderAllAnims(bpy.types.Operator):
bl_idname = "render_anims.button"
bl_label = "All animations"
def execute(self, context):
print('')
print('Rendering animations for all cameras...')
renderStuff(True)
return{'FINISHED'}
# render scene from all cameras
def renderStuff(animToggle):
# get current scene, renderpath/filename and active camera
currentScene = bpy.data.scenes[bpy.data.scenes.keys()[0]]
renderPath = currentScene.render.filepath
previousCamera = currentScene.camera
# Loop all objects and find Cameras
for obj in currentScene.objects:
# Find cameras
if ( obj.type =='CAMERA') :
print("Rendering camera ["+obj.name+"]")
print(bpy.context.scene.render.display_mode)
# Set camera as active and create filename for image
currentScene.camera = obj
currentScene.render.filepath = renderPath+"_"+obj.name
# Render cameraview
#bpy.ops.render.render(animation=animToggle, write_still=True )#it works, but no preview, only progess in the console
bpy.ops.render.render('INVOKE_DEFAULT', write_still=True)#only renders camera 1, all others are skipped
# reset renderpath/filename and active camera
currentScene.render.filepath = renderPath
currentScene.camera = previousCamera
print('Done!')
# add section to render-panel
class RenderAllCamerasPanel(bpy.types.Panel):
bl_label = "Render all cameras"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "render"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
row = layout.row(align=True)
col = layout.column(align=True)
col.operator_context = 'INVOKE_DEFAULT'
row.operator("render_cams.button",icon = 'RENDER_STILL')
row.operator("render_anims.button",icon = 'RENDER_ANIMATION')
# register the class
def register():
bpy.utils.register_class(RenderAllCameras)
bpy.utils.register_class(RenderAllAnims)
bpy.utils.register_class(RenderAllCamerasPanel)
def unregister():
bpy.utils.unregister_class(RenderAllCameras)
bpy.utils.unregister_class(RenderAllAnims)
bpy.utils.unregister_class(RenderAllCamerasPanel)