0

I am currently using blender version 2.92 and am trying to change the camera position using a python script. I am passing the coordinates for the camera using a JSON file and the snippet for the same is as :

"camera_locations":[
    [
      2.576395273208618,
      -4.465750694274902,
      1.094475507736206
    ],
    [
     100.87639527320862,
      -9.465750694274902,
      400.094475507736206
    ]

I am creating a function and passing the camera object and the camera locations (that I have read from the JSON file ) as parameters. Further, I am then trying to change the camera location and render. Following is the code snippet:

def render(camera_locations,object):
camera_location=object.location
print("the current camera position is as: ", camera_location)
for locations in camera_locations:
    count=0
    for location in locations:
        object.location[count]=location
        count+=1
        if(count==3):
           count=0
    bpy.context.scene.render.filepath=output_path+str(i)
    bpy.ops.render.render(use_viewport=True,write_still=True)

However, when I render I do not see any changes in the images with respect to the camera location. The images look identical. I have tried printing the above variables and those do show the updated values. I am not sure what I am missing here. Can someone guide me with this or suggest a better way to tackle the problem?

batFINGER
  • 84,216
  • 10
  • 108
  • 233
Sourabh
  • 43
  • 5
  • @brockmann The indentation is actually a copying mistake from my end. I have edited the question now. I am getting two output images currently and they look identical. Sorry for the confusion.But I will try the below approach – Sourabh Oct 23 '21 at 09:55

1 Answers1

3

Make the render operator and the output path assignment part of the actual for-loop. Demo code using a regular dictionary for the camera locations based on this answer.

import bpy
import os.path

camera_locations = { 0: (2.576395273208618, -4.465750694274902, 1.094475507736206), 1: (-0.573695343202619, -1.863753624223357, 1.094235453632562) }

Scene variables

scn = bpy.context.scene cam = scn.camera output_path = scn.render.filepath

Iterate through the dict, set the locations and render

for k, v in camera_locations.items(): # Set the locations cam.location = v # Assemble the path (.jpg is a placeholder) scn.render.filepath = os.path.join(output_path, "cam_{}.jpg".format(k)) # Call the render operator bpy.ops.render.render(write_still=True)

Reset the output path to "/tmp/"

bpy.context.scene.render.filepath = output_path

Render output (default scene), output file type set to OpenEXR:

/tmp/
├── cam_0.exr
├── cam_1.exr
...

Render output of our famous classroom scene (make sure to remove the location keyframes of the scene camera before running the script):

enter image description here cam_0.png (left), cam_1.png (right)


In case there is no way around a two-dimensional list as provided, I'd suggest use python's build-in enumerate() as mentioned in the comments, makes the code nearly identical:

import bpy
import os.path

camera_locations = [ [2.576395273208618, -4.465750694274902, 1.094475507736206], [100.87639527320862, -9.465750694274902, 400.094475507736206] ]

Scene variables

scn = bpy.context.scene cam = scn.camera output_path = scn.render.filepath

Iterate through the list, set the locations and render

for c, v in enumerate(camera_locations): # Set the locations cam.location = v # Assemble the path (.jpg is a placeholder) scn.render.filepath = os.path.join(output_path, "cam_{}.jpg".format(c)) # Call the render operator bpy.ops.render.render(write_still=True)

Reset the output path to "/tmp/"

bpy.context.scene.render.filepath = output_path

Note: object is an identifier in python hence the different syntax highlighting, I'd suggest use obj as variable name and I'd also recommend against string addition for paths, either use os.path.join() as above or have a look into the pathlib module.

brockmann
  • 12,613
  • 4
  • 50
  • 93