2
$\begingroup$

I want to position the camera around an object using Blender's Python API. Assuming that an object is centered at (0, 0, 0), I want to move the camera around it given a set of known (x, y, z) coordinate values while keeping its focus on the point (0, 0, 0) and its distance to middle of the object to be dist, a constant. I wonder how I can do that in Python?

$\endgroup$
2
  • $\begingroup$ That should be really easy if you know the distance $\endgroup$ Commented Feb 8, 2018 at 21:55
  • $\begingroup$ As a matter of fact that should be easy even if you don't, we can calculate distance from to known points (Camera & Origin). Give me a few, I'll post an answer to this. $\endgroup$ Commented Feb 8, 2018 at 21:56

2 Answers 2

4
$\begingroup$

The next function will rotate the camera towards the focus point. And then place the camera at a certain distance. The location of camera will only change along the direct line with the focus point.

import bpy import mathutils def update_camera(camera, focus_point=mathutils.Vector((0.0, 0.0, 0.0)), distance=10.0): """ Focus the camera to a focus point and place the camera at a specific distance from that focus point. The camera stays in a direct line with the focus point. :param camera: the camera object :type camera: bpy.types.object :param focus_point: the point to focus on (default=``mathutils.Vector((0.0, 0.0, 0.0))``) :type focus_point: mathutils.Vector :param distance: the distance to keep to the focus point (default=``10.0``) :type distance: float """ looking_direction = camera.location - focus_point rot_quat = looking_direction.to_track_quat('Z', 'Y') camera.rotation_euler = rot_quat.to_euler() # Use * instead of @ for Blender <2.8 camera.location = rot_quat @ mathutils.Vector((0.0, 0.0, distance)) update_camera(bpy.data.objects['Camera']) 
$\endgroup$
1
  • $\begingroup$ I just wanted to point out that this answer is also useful for (re-)orienting lights as well!!! It's just a matter of passing a light object in the camera variable. Thanks to J Bakker!!! $\endgroup$ Commented Feb 7, 2021 at 15:12
1
$\begingroup$

Shift + A >> E >> P enter image description here

Set X Location to 1.00000 enter image description here

Add another Empty (it will automatically be named 'Empty.001')

Shift + A >> E >> P enter image description here

Now add a Camera

Shift + A >> E >> P enter image description here

Position the Camera as follows:

[1.00000, 0.00000, 0.00000]

Rotate the Angles as follows:

90°, 0°, 90° enter image description here

With the Camera still selected...

Shift + Select the First Empty >> Ctrl + P >> K (Object (Keep Transform)) enter image description here

Next select only the first Empty and add a Track To Modifier enter image description here

Then set the Target to: Empty.001

Then set To to: -X enter image description here


Here's the Python Code to do basically all of the same steps as above


import bpy import math bpy.ops.object.empty_add(type='PLAIN_AXES', view_align=False, location=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)) bpy.ops.object.empty_add(type='PLAIN_AXES', view_align=False, location=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)) newEmpties = [] for objName in bpy.data.objects.keys(): if(len(objName.split("mpty")) > 1): newEmpties.append(objName) # print("-----") print(len(newEmpties)) print("-----") for i in newEmpties: print(i) cnt = len(newEmpties) myEmpties = [] myEmpties.append(newEmpties[cnt - 2]) myEmpties.append(newEmpties[cnt - 1]) e1 = bpy.data.objects[myEmpties[0]] e2 = bpy.data.objects[myEmpties[1]] e1.location.x = 1.0 bpy.ops.object.camera_add(view_align=True, enter_editmode=False, location=(0, 0, 0), rotation=(0.961699, 0.0122912, -0.897371), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)) newCams = [] for objName in bpy.data.objects.keys(): if(len(objName.split("amera")) > 1): newCams.append(objName) # myCam = bpy.data.objects[newCams[len(newCams) - 1]] myCam.location.x = 1.0 myCam.rotation_euler.x = math.pi * 0.5 myCam.rotation_euler.z = math.pi * 0.5 bpy.ops.object.select_all(action='DESELECT') myCam.select = True e1.select = True bpy.context.scene.objects.active = e1 bpy.ops.object.parent_set(type='OBJECT', keep_transform=True) bpy.ops.object.constraint_add(type='TRACK_TO') e1.constraints['Track To'].target = e2 e1.constraints['Track To'].track_axis = 'TRACK_NEGATIVE_X' bpy.context.scene.objects.active = myCam scene = bpy.data.scenes['Scene'] scene.camera = myCam 

For Blender >2.8 (new python api)


import bpy import math def pointACamTo(toPoint, fromPoint): bpy.ops.object.empty_add(type='PLAIN_AXES', location=fromPoint) bpy.ops.object.empty_add(type='PLAIN_AXES', location=toPoint) newEmpties = [] for objName in bpy.data.objects.keys(): if(len(objName.split("mpty")) > 1): newEmpties.append(objName) # print("-----") print(len(newEmpties)) print("-----") for i in newEmpties: print(i) cnt = len(newEmpties) myEmpties = [] myEmpties.append(newEmpties[cnt - 2]) myEmpties.append(newEmpties[cnt - 1]) e1 = bpy.data.objects[myEmpties[0]] e2 = bpy.data.objects[myEmpties[1]] e1.location.x = fromPoint[0] e1.location.y = fromPoint[1] e1.location.z = fromPoint[2] bpy.ops.object.camera_add(align='VIEW', enter_editmode=False, location=(0, 0, 0), rotation=(0.961699, 0.0122912, -0.897371)) newCams = [] for objName in bpy.data.objects.keys(): if(len(objName.split("amera")) > 1): newCams.append(objName) # myCam = bpy.data.objects[newCams[len(newCams) - 1]] #myCam.location.x = fromPoint[0] myCam.location.x = fromPoint[0] myCam.location.y = fromPoint[1] myCam.location.z = fromPoint[2] myCam.rotation_euler.x = math.pi * 0.5 myCam.rotation_euler.z = math.pi * 0.5 bpy.ops.object.select_all(action='DESELECT') myCam.select = True e1.select = True #bpy.context.scene.objects.active = e1 # wrong, read-only bpy.context.active_object = e1 # select: eventually remove # wrong, for multiple selection eventually: e1.select_set(True) bpy.context.view_layer.objects.active = e1 bpy.ops.object.parent_set(type='OBJECT', keep_transform=True) bpy.ops.object.constraint_add(type='TRACK_TO') e1.constraints['Track To'].target = e2 e1.constraints['Track To'].track_axis = 'TRACK_NEGATIVE_X' # as safety measure: ##deselectAllObjectsInScene() # eventually remove #bpy.context.scene.objects.active = myCam bpy.context.view_layer.objects.active = myCam scene = bpy.data.scenes['Scene'] scene.camera = myCam #and run pointACamTo([0,0,0], [2,2,2]) 

Now in a separate python script you can use a function like follows to position the camera to a point. enter image description here

Here's an example of the result

enter image description here

$\endgroup$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.