Docs›Process›Python API

Processing from Python

Early access

The process system is new and only in the early access version of Human Generator. It replaces the process tab of version 4.0, which is deprecated. Details can still change; if something doesn't work or looks wrong, let us know.

Everything the Process tab does is available from Python, through human.process. The settings of the tab are one object, ExportSettings, and one call processes a human with them, so a build step or a render farm can export characters without anyone clicking. This page walks through the common cases; the reference is on ProcessSettings and ExportSettings, and the Python API guide covers the rest of the add-on.

Run a recipe

import bpy
from HumGen3D import ExportSettings, Human
 
human = Human.from_existing(bpy.context.object)
 
settings = ExportSettings.from_recipe("unity")   # "unity", "unreal", "godot", "mixamo", "generic", "blender"
settings.output.folder = "/path/to/MyGame/Assets/Characters"
 
result = human.process.run(settings)
print(result.files)        # ['/path/to/MyGame/Assets/Characters/Jake.fbx']
print(result.summary())    # what the popup shows, with the triangle count and warnings

run does exactly what the button does: the human is not changed, a processed copy is made per LOD level, written to the files and removed again. The ExportResult tells what was made: files, the processed humans left in the file, warnings, the triangles per level and the seconds it took.

Recipes of your own are loaded by their path inside the process_templates folder of the content folder, ExportSettings.from_recipe("MyGame/Mobile characters.json"), or by any absolute path.

Change the settings

The settings mirror the sections of the tab. Every field has the same name and values as the recipe file:

from HumGen3D import ExportSettings, QualitySettings
 
settings = ExportSettings.from_recipe("unreal")
settings.output.format = "glb"                 # see Output
settings.output.name = "Hero_{name}"
settings.lods = [QualitySettings.from_tier("high"), QualitySettings.from_tier("low")]
settings.meshes.remove_hidden_skin = False
settings.haircards.enabled = False
settings.skeleton.names = "humanoid"
settings.skeleton.rest_pose = "t_pose"
settings.shape_keys.body = "keep"
settings.textures.set_resolution_tier("1k")
settings.textures.workflow = "metallic_roughness"

Or start from the defaults with ExportSettings() and set what you need. The classes per section: OutputSettings, QualitySettings, MeshSettings, HaircardSettings, SkeletonSettings, ShapeKeySettings, TextureBakeSettings and ScriptsSettings. settings.to_dict() and ExportSettings.from_dict() turn them into plain data, settings.save_recipe("MyGame", "Hero") saves them as a recipe for the interface.

Check before running

The tab's red and grey lines come from preflight. Use it to validate settings without changing anything:

check = human.process.preflight(settings)
if not check.ok:
    print("\n".join(check.errors))     # these would make run() raise
for warning in check.warnings:
    print("warning:", warning)

run raises a HumGenException when the preflight finds an error. Without the Export pack, run, preflight, ExportSettings.from_recipe and the single steps raise ExportPackMissing, a HumGenException that says what to download. When a step fails, its own exception comes through unchanged. In both cases the copies made so far are removed.

Several humans

Every human in the scene, with the same settings:

from HumGen3D.common import find_multiple_in_list
 
rigs = find_multiple_in_list(bpy.context.scene.objects)
for human in (Human.from_existing(rig) for rig in rigs):
    result = human.process.run(settings)
    print(human.name, result.files)

Progress

run accepts a callback that gets the fraction done, for a progress bar of your own:

result = human.process.run(settings, progress=lambda fraction: print(f"{fraction:.0%}"))

For a modal operator that must keep Blender responsive, human.process.run_steps(settings) gives the same work as a generator that yields the fraction after every short chunk; that is what the Process button uses.

From the command line

Blender in background mode, for a build step or a render farm. The add-on must be enabled in the Blender preferences of the machine. Tested with Blender 5.1: the script below exports a dressed human with hair cards to glb in about a minute, textures baked included:

blender -b characters.blend --python export_characters.py
# export_characters.py
import bpy
from HumGen3D import ExportSettings, Human
from HumGen3D.common import find_multiple_in_list
 
settings = ExportSettings.from_recipe("godot")
settings.output.folder = "/builds/characters"
 
for rig in find_multiple_in_list(bpy.context.scene.objects):
    human = Human.from_existing(rig)
    result = human.process.run(settings, context=bpy.context)
    print(result.summary())
Passing context

As everywhere in the API, context is optional and bpy.context is used when you leave it out. Inside an operator or an add-on of your own, pass the context you were given. See Overview › Passing context.

Did it run in background mode?

The command, the Blender version and the console output, when it did not. Tell us.

The single steps

run is a sequence of steps, each a method of ProcessSettings that takes the matching section of the settings, or plain arguments. You can call them yourself, for example to make a game-ready copy without exporting it, or to insert something between two steps.

The steps change the human they are called on

They can't be undone, so call them on a human.duplicate(), never on the original.

from HumGen3D import QualitySettings, SkeletonSettings
 
copy = human.duplicate()
copy.process.set_shape_keys(body="keep", face="bake", age="bake")
copy.process.convert_to_haircards("medium")
copy.process.bake_textures(settings.textures, folder="/path/to/textures")
copy.process.set_quality(QualitySettings.from_tier("medium"))
copy.process.convert_to_game_rig(settings=SkeletonSettings(names="humanoid", rest_pose="t_pose"))
copy.process.apply_names()
copy.export.write("/path/to/Jake", settings.output)  # a file format; "in_file" raises
# or, to keep it in the file as a frozen result:
copy.process.mark_as_processed(human)

The order is the one run uses, and it matters:

  1. set_shape_keysFirst, so the later steps carry only the keys that stay
  2. convert_to_haircardsHair cards, game eyes and teeth before baking, as they change the materials
  3. bake_texturesBefore the meshes are reduced
  4. set_qualityAfter baking
  5. convert_to_game_rigAfter the meshes
  6. apply_namesLast

The steps with a has_* or was_* property (hair cards, baking, the game rig, the T-pose) refuse to run twice; the other steps run again. For one file with several LOD levels, make one copy per level and join them with ProcessSettings › merge_levels.

Two more steps exist for scripts: ProcessSettings › apply_modifiers applies modifiers while keeping the shape keys, which Blender itself refuses, and ProcessSettings › remove_hidden_skin deletes the body under the clothing. To write a human to a file without any processing, use ExportBuilder (human.export.to_fbx, to_glb, to_gltf_separate, to_obj, to_abc).

Reading a processed human

copy = Human.from_existing(bpy.context.object)
copy.process.is_processed        # True for a frozen result
copy.process.settings            # the ExportSettings it was made with, None otherwise
Scripts in the interface

If you want your code to run as part of a recipe that others use from the Process tab, write it as a script: a file with a main(context, human) function that runs at a stage of the process.

Something missing from the API?

A step you had to work around, or a setting the recipe cannot hold. Tell us.

Frequently asked questions

Can I export Human Generator characters without opening Blender's interface?

Yes. Run Blender in background mode with a script that loads a recipe and calls human.process.run for every human in the file. The add-on has to be enabled in the Blender preferences of that machine.

Can I process the humans the batch generator made?

Yes. Find them with find_multiple_in_list on the scene objects and run the same settings on each, or select them all in the Process tab and press the button once.