# Batch rendering of 10,000 images from 10,000 obj files

I have around 10,000 wavefront (obj) files with a volume.

I would like to load a predefined scene with a camera position, light, etc. Then load an obj file, render a snapshot from that camera (no animation), save that as a png file and then pass to the next one and repeat the operation.

I know bash and python, but I am not sure how to do this "load & render" from the command line or using python.

Cheers.

• How do you know which files to import? Do you have the filenames of the OBJ files in a file somewhere? Or are they all in the same directory? – dr. Sybren Jun 7 '17 at 9:19
• File, directory, etc... That is not really important. I can either do: for fileName in \$dir/*.obj ; do BLA ; done or while read line ; do BLA ; done < list_of_names.txt – Phai Jun 7 '17 at 13:10
• One tactic that might be useful is to load all the objects into a .blend file, but only make each object renderable for a single frame. That way when you render the 10000 frames of animation, each frame will have a different object in it. This might have scaling problems, so you might end up doing 10 .blend files with 1000 frames each, or 100 .blend files with 100 frames each. – Mutant Bob Jun 7 '17 at 14:36
• Not feasible. Objects are complex (More than 40 MB each), so memory requirements for that would be crazy. – Phai Jun 7 '17 at 15:18

This script will take all OBJ files in a certain directory, and one by one load them, render them, and remove them from the scene again. This way you can render 10000 OBJ files without having to load them all into memory at the same time. The OBJ files do not need to be named in any special way (except ending in .obj).

import bpy
import pathlib

# Adjust this for where you have the OBJ files.
obj_root = pathlib.Path('c:/temp/obj')

# Before we start, make sure nothing is selected. The importer will select
# imported objects, which allows us to delete them after rendering.
bpy.ops.object.select_all(action='DESELECT')
render = bpy.context.scene.render

for obj_fname in obj_root.glob('*.obj'):
bpy.ops.import_scene.obj(filepath=str(obj_fname))

render.filepath = '//obj-%s' % obj_fname.stem
bpy.ops.render.render(write_still=True)

# Remember which meshes were just imported
meshes_to_remove = []
for ob in bpy.context.selected_objects:
meshes_to_remove.append(ob.data)

bpy.ops.object.delete()

# Remove the meshes from memory too
for mesh in meshes_to_remove:
bpy.data.meshes.remove(mesh)


The rendered image files will have the OBJ filename in their name, so if you have cube.obj, the output file will be obj-cube.jpg (assuming you're rendering to JPEG files).

The camera and lighting is use as-is in the scene, so you can set it up beforehand and render everything with the same settings.

NOTE: since this is a synchronous script, Blender's UI will block while it's running. You may want to start Blender from a terminal (or choose Window > Toggle System Console on Windows) before you start it, to keep an eye on its progress.