#!/usr/bin/env python3 # create_glb.py — Blender headless STL -> GLB # # Example: # blender-bin-5.0.0 --background --python create_glb.py -- input.stl [output.glb] import bpy import sys import os from mathutils import Vector def die(msg, rc=2): print(f"ERROR: {msg}") raise SystemExit(rc) # args after "--" argv = sys.argv argv = argv[argv.index("--") + 1:] if "--" in argv else [] if len(argv) == 1: inp = argv[0] base, _ = os.path.splitext(inp) outp = base + ".glb" elif len(argv) >= 2: inp, outp = argv[0], argv[1] else: die("USAGE: blender --background --python create_glb.py -- input.stl [output.glb]") if not os.path.exists(inp): die(f"Input not found: {inp}") # Empty scene bpy.ops.wm.read_factory_settings(use_empty=True) # Import STL (Blender 4/5 operator) res = bpy.ops.wm.stl_import(filepath=inp) if 'FINISHED' not in res: die(f"STL import failed for: {inp}") # Gather imported mesh objects objs = [o for o in bpy.context.scene.objects if o.type == 'MESH'] if not objs: die("No mesh objects after import (unexpected)") # Compute combined bounding box center in world space min_v = Vector(( 1e30, 1e30, 1e30)) max_v = Vector((-1e30, -1e30, -1e30)) for o in objs: # object bound_box is in local coords; transform to world for corner in o.bound_box: v = o.matrix_world @ Vector(corner) min_v.x = min(min_v.x, v.x); min_v.y = min(min_v.y, v.y); min_v.z = min(min_v.z, v.z) max_v.x = max(max_v.x, v.x); max_v.y = max(max_v.y, v.y); max_v.z = max(max_v.z, v.z) center = (min_v + max_v) * 0.5 # Translate all meshes so center is at origin for o in objs: o.location -= center # Export GLB res = bpy.ops.export_scene.gltf( filepath=outp, export_format='GLB', export_apply=True, ) if 'FINISHED' not in res: die(f"GLB export failed: {outp}") print(f"Wrote: {outp}")