I currently have a small Blender script that renders depth map images of OBJ files at different orthographic views. However, one thing I haven't been able to figure out so far is how to center the object in my rendered image. Right now, the object appears slightly shifted in one direction or another depending on the view, as you can see below (might be difficult with the Stack Overflow white background, but if you save it as a separate image you'll be able to see it's shifted to the right):
My question is, how can I modify my code such that I can make sure each of the rendered images are centered horizontally and vertically in output images?
This is my current code: https://pastebin.com/0Kd8JfqY
import bpy
import mathutils
import math
import os
import glob
import numpy as np
Model directory
model_dir = '/home/yuerno/Downloads/test/'
Specify OBJ files
model_files = glob.glob(os.path.join(model_dir, "*.obj"))
Rendered image directory
rendered_dir = '/home/yuerno/Downloads/rendered_images/'
Set up camera
cam_data = bpy.data.cameras.new('camera')
cam = bpy.data.objects.new('camera', cam_data)
cam_data.type = "ORTHO"
bpy.context.collection.objects.link(cam)
bpy.context.scene.camera = cam
cam.location = mathutils.Vector((0, 5, 0))
cam.rotation_euler = mathutils.Euler((math.radians(90), math.radians(0), math.radians(180)))
Set up depth map rendering configuration
bpy.context.scene.use_nodes = True
tree = bpy.context.scene.node_tree
links = tree.links
for n in tree.nodes:
tree.nodes.remove(n)
render_layer_node = tree.nodes.new('CompositorNodeRLayers')
map_value_node = tree.nodes.new(type="CompositorNodeMapValue")
file_output_node = tree.nodes.new('CompositorNodeOutputFile')
g_depth_clip_start = 0.5
g_depth_clip_end = 4
g_depth_color_mode = 'BW'
g_depth_color_depth = '8'
g_depth_file_format = 'PNG'
map_value_node.offset[0] = -g_depth_clip_start
map_value_node.size[0] = 1 / (g_depth_clip_end - g_depth_clip_start)
map_value_node.use_min = True
map_value_node.use_max = True
map_value_node.min[0] = 0.0
map_value_node.max[0] = 1.0
file_output_node.format.color_mode = g_depth_color_mode
file_output_node.format.color_depth = g_depth_color_depth
file_output_node.format.file_format = g_depth_file_format
file_output_node.base_path = rendered_dir
links.new(render_layer_node.outputs[2], map_value_node.inputs[0])
links.new(map_value_node.outputs[0], file_output_node.inputs[0])
Set up image output resolution
bpy.data.scenes["Scene"].render.resolution_x = 512
bpy.data.scenes["Scene"].render.resolution_y = 512
Process model files
for f in model_files:
print(f)
bpy.ops.import_scene.obj(filepath=f)
print("Imported")
imported = bpy.context.selected_objects[0]
print("Selected")
maxDimension = 7.5
scaleFactor = maxDimension / max(imported.dimensions)
imported.scale = (scaleFactor, scaleFactor, scaleFactor)
print("Rescaled")
imported.rotation_mode = 'XYZ'
print("Set Rotmode")
num_views = 8
views = np.array([0, np.pi/4.0, np.pi/2.0, 3*np.pi/4.0, np.pi, 5*np.pi/4.0, 3*np.pi/2.0, 7*np.pi/4.0])
phi_views = np.array([0, 0, 0, 0, 0, 0, 0, 0])
print("Views created")
sel_views = np.random.randint(0, num_views, num_views)
sel_views = range(num_views)
print("Views selected")
print()
# Render each view
for i in range(num_views):
imported.rotation_euler[2] = views[sel_views[i]]
print ("Set view")
imported.rotation_euler[1] = np.pi/2.0 - phi_views[sel_views[i]]
print ("Set phi view")
filename = f.split("/")[-1]
print (filename)
file_output_node = bpy.context.scene.node_tree.nodes[2]
file_output_node.file_slots[0].path = filename+".v"+str(i)+".png"
bpy.ops.render.render(write_still=True)
bpy.ops.object.delete()
Thanks in advance for any assistance!
