# bpy.ops.render.render does not find camera

I'm trying to run the following smallscript. The preview with 12 does render, but the last line of the script fails with this error:

Traceback (most recent call last):
File "<blender_console>", line 1, in <module>
File "D:\Programme\Blender\2.78\scripts\modules\bpy\ops.py", line 189, in __call__
ret = op_call(self.idname_py(), None, kw)
RuntimeError: Error: Cannot render, no camera


But there is a camera

import bpy

def reset_scene():
for item in bpy.data.objects:
item.select = True

bpy.ops.object.delete()

for material in bpy.data.materials:
if not material.users:
bpy.data.materials.remove(material)

for texture in bpy.data.textures:
if not texture.users:
bpy.data.textures.remove(texture)

reset_scene()

bpy.context.object.scale[1] = 0.1
bpy.context.object.scale[0] = 10
bpy.context.object.scale[2] = 10

bpy.ops.object.camera_add(location=(0, 4, 4), rotation=(-0.7853, 0, 0))

bpy.data.scenes["Scene"].render.filepath = 'c:\test.jpg'
bpy.ops.render.render( write_still=True )


When I set the camera explicitly with this script:

bpy.context.scene.camera = bpy.data.objects['Camera']


it seems to work.

Why can't it find the camera automatically like when you press F12?

Simply set the scene.camera after you add the camera.

from bpy import context
scene = context.scene

...

rotation=(-0.7853, 0, 0))
scene.camera = context.object
...


Hitting F12 invokes the operator, which when scene.camera is None , throws a message if no cam, or uses a camera from the scene and sets it to scene.camera. Test by adding a few cameras, setting scene.camera to None, and pressing F12.

To invoke the operator from code,

bpy.ops.render.render('INVOKE_DEFAULT', write_still=True)


Note: bpy.data contains all the objects in the blend file. context.scene.objects contains all the objects in the context scene. The context scene may not necessarily be bpy.data.scenes["Scene"]. render.render renders the context scene, unless another scene is specified.

A tip, set up a context variable, either context = bpy.context or from bpy import context at the beginning of your test code, then later cut and paste into, for instance, operator execute(self, context) methods. Setting vars like scene = context.scene, obj = context.object, obj.scale = (0.1, 1, 10) makes code far more readable IMO rather than always addressing from bpy.

• Dear batFINGER, just a big thank you from someone who has been learning Blender (and 3D graphics) without formal training, but with the help of Google, which so so so often has led me (and my friends) to your contributions! – legel Aug 27 '19 at 3:53