"""Generate a low-poly T-pose test humanoid (no rig) for the smoke test. Usage: blender -b --python bpy/smoke_mesh.py -- --out out/test_human.glb """ import argparse import math import os import sys import bpy sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from common import clean_scene, export_glb, select_only, stage_args def cube(name, center, size): bpy.ops.mesh.primitive_cube_add(location=center) o = bpy.context.active_object o.name = name o.scale = (size[0] / 2, size[1] / 2, size[2] / 2) return o def sphere(name, center, r): bpy.ops.mesh.primitive_uv_sphere_add( location=center, radius=r, segments=12, ring_count=8) o = bpy.context.active_object o.name = name return o def main(): ap = argparse.ArgumentParser() ap.add_argument("--out", required=True) args = ap.parse_args(stage_args()) clean_scene() H = 1.75 # meters, floor at z=0, facing -Y, T-pose along X parts = [] # torso: groin (0.52H) to shoulders (~0.82H) parts.append(cube("torso", (0, 0, 0.67 * H), (0.32 * H, 0.14 * H, 0.30 * H))) # head: chin 0.87H to top 1.0H parts.append(sphere("head", (0, 0, 0.93 * H), 0.075 * H)) parts.append(cube("neck", (0, 0, 0.845 * H), (0.06 * H, 0.06 * H, 0.06 * H))) # arms straight out along +/-X at shoulder height 0.82H for s in (1, -1): parts.append(cube(f"upperarm{s}", (s * 0.26 * H, 0, 0.82 * H), (0.17 * H, 0.055 * H, 0.055 * H))) parts.append(cube(f"forearm{s}", (s * 0.40 * H, 0, 0.82 * H), (0.14 * H, 0.045 * H, 0.045 * H))) parts.append(cube(f"hand{s}", (s * 0.50 * H, 0, 0.82 * H), (0.09 * H, 0.04 * H, 0.03 * H))) # legs down from groin, feet forward (-Y) for s in (1, -1): parts.append(cube(f"thigh{s}", (s * 0.09 * H, 0, 0.40 * H), (0.075 * H, 0.075 * H, 0.24 * H))) parts.append(cube(f"shin{s}", (s * 0.09 * H, 0, 0.165 * H), (0.06 * H, 0.06 * H, 0.23 * H))) parts.append(cube(f"foot{s}", (s * 0.09 * H, -0.05 * H, 0.03 * H), (0.06 * H, 0.16 * H, 0.05 * H))) select_only(parts, active=parts[0]) bpy.ops.object.join() body = bpy.context.active_object body.name = "test_human" bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) export_glb(args.out, objects=[body]) print("[mirpamo] smoke mesh OK") main()