How to run Blender headless (from the command line, without the GUI)

Today I decided to roll up my sleeves and figure out how to run Blender headless. I’ve been telling people that it’s possible (based on documentation), but haven’t tried it out myself.

Until now!

It’s actually pretty simple. Here are some steps. I’m on a Mac, so the paths might be slightly different if you’re on another operating system (check out these instructions for for Windows).

1. Figure out the path of the Blender executable. If you’ve ran the Blender console window before, it’s the same executable.

To find it via GUI, open up where the downloaded Blender zip was extracted.

Blender package

On a Mac, show package contents and navigate to the blender executable.

Blender executable

Actual path:

/Users/Jenny/Desktop/Blender/blender.app/Contents/MacOS

(I currently have the extracted Blender 2.74 package on the Desktop for simplicity so my path reflects that.)

2. Run the executable with the -b argument to run Blender without the GUI. You can add the path to your PATH or run ./blender.

With path added:

blender -b

Run locally:

./blender -b

3. You can pass scripts into Blender while running Blender headless.

blender -b -P /Users/Jenny/Desktop/my_script.py

4. Passing arguments into your script is a little bizarre. The documentation specifies the -- (double dash) syntax to signal to Blender to stop reading those arguments and have them processed by your script. However, inside your script, if you’re trying to parse out the arguments, you get all the arguments, not just the ones after the --. You must parse them out yourself. Here’s an example below. I’m using argparse instead of sys.args because argparse is very powerful and handles a lot of edge cases (plus it’s just darn good practice).

blender -b -P /Users/Jenny/Desktop/my_script.py -- --number 5 --save '/Users/Jenny/Desktop/cube.obj'

The example script creates a number of cubes and exports them.

import argparse
import bpy

def get_args():
  parser = argparse.ArgumentParser()

  # get all script args
  _, all_arguments = parser.parse_known_args()
  double_dash_index = all_arguments.index('--')
  script_args = all_arguments[double_dash_index + 1: ]

  # add parser rules
  parser.add_argument('-n', '--number', help="number of cubes")
  parser.add_argument('-m', '--save', help="output file")
  parsed_script_args, _ = parser.parse_known_args(script_args)
  return parsed_script_args

args = get_args()
number_of_cubes = int(args.number)

# create cubes
if number_of_cubes > 1:
  for x in range(0, number_of_cubes):
    bpy.ops.mesh.primitive_cube_add(location=(x, 0, 0))

# export scene
bpy.ops.export_scene.obj(filepath=args.save)

Running the script will give you an exported OBJ with the cubes.

There you have it: how to run headless Blender. Most people use headless Blender to farm out rendering jobs and increase render speeds, but you can do all sorts of neat stuffs by providing a script. Have fun!

5 comments
  1. Alex said:

    Is it possible to add an addon for headless Blender?

    • Jenny said:

      I’m not sure if there’s a way to activate addons from the API (I haven’t checked) but I know that if you activate an addon, you can save that as your default Blender profile so that next time you open it, it’s automatically loaded.

  2. Hi, is it possible to have an API that calls a python script which does randomizations and generates 2D images of 3D objects? I am curious as I would like to trigger such a rendering from a frontend and also display the rendered 2D images back to a browser.
    Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: