You have found the right command bpy.ops.view3d.camera_to_view()
but it can't be run as is from the Python console. The error message means that the op can only be run from a 3D Viewport context. There are (at least) two solutions:
- Create an operator class that performs the operation and make sure you invoke it from a 3D Viewport context. Here's a class I use for adding a new camera to a scene.
class TOOL_OT_add_camera(Operator):
bl_idname = "camera.add"
bl_label = "add camera"
bl_description = "add a camera in the viewport"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
""" Add a new camera to the scene, make it the active camera,
and match it to the current view.
"""
camera_data = bpy.data.cameras.new(name="Camera")
if camera_data is None:
return {"CANCELLED"}
my_camera = bpy.data.objects.new("Camera", camera_data)
if my_camera is None:
return {"CANCELLED"}
bpy.context.scene.collection.objects.link(my_camera)
context.scene.camera = my_camera
bpy.ops.view3d.camera_to_view()
return {"FINISHED"}
- Override the context. Here's sample code that will do that:
win = bpy.context.window
scr = win.screen
areas3d = [area for area in scr.areas if area.type == 'VIEW_3D']
region = [region for region in areas3d[0].regions if region.type == 'WINDOW']
override = {
'window': win,
'screen': scr,
'area' : areas3d[0],
'region': region[0],
'scene' : bpy.context.scene,
}
bpy.ops.view3d.camera_to_view(override)
Note that this code makes a couple of assumptions; mainly that the interesting 3D viewport will be the first one on the list of 3D viewport areas. Since mostly we operate with only one 3D viewport this is usually true.
In this case, the example override is overkill and can be simplified to
areas3d = [area for area in bpy.context.window.screen.areas if area.type == 'VIEW_3D']
bpy.ops.view3d.camera_to_view({'area':areas3d[0]})
You can read more about operator overrides in the bpy ops introduction. The above code was adapted from this answer to "python - How do I override context for bpy.ops.mesh.loopcut?"
Note that this will only work if you have an active camera.
3.2 Update
Context overrides are deprecated in Blender 3.2 and are scheduled to be removed in Blender 3.3 The replacement is temp_override
. The manual has examples of how to use the new function.