"""批量图生 3D — batch image to model. tripocli batch -i a.png,b.png,c.png --wait -o ./out Verified against the live API: the batch endpoint takes ``image`` as an *array* (the field is singular, not ``images``) and answers with an array of ``{project_id, operator_id}`` — one entry per submitted image. """ import os from . import _common NAME = "batch" HELP = "批量图生 3D(多张图片一次提交,返回多个任务)" def add_arguments(parser): parser.add_argument("-i", "--images", required=True, help="逗号分隔的本地图片路径") _common.add_generation_options(parser) _common.add_wait_options(parser, "输出目录(每个结果保存为 .glb)") def run(ctx): args = ctx.args paths = [p.strip() for p in args.images.split(",") if p.strip()] if not paths: raise ValueError("--images 至少需要一张图片") images = [] for path in paths: ctx.out.line(f"📤 上传并审核图片: {path}") images.append(ctx.client.upload_image(path)) body = _common.generation_body(args) results = ctx.client.get_data( "POST", "/v2/studio/operation/batch_image_to_model", body={ "image": images, "model_version": body["model_version"], "face_limit": body["face_limit"], "quad": body["quad"], "texture": body["texture"], "visibility": body["visibility"], }, ) results = results or [] if not args.wait: ctx.out.data( results, human=lambda: ( ctx.out.line(f"✅ 已提交 {len(results)} 个任务"), *[ctx.out.line(f" project {r.get('project_id')} operator {r.get('operator_id')}") for r in results], ), ) return results out_dir = args.output or "." payload = [] for item in results: project_id = item.get("project_id") wait_task = _common.wait_and_report(ctx, item.get("operator_id")) model_url, _detail = _common.fetch_model_url(ctx, project_id) target = None if model_url: target = os.path.abspath(os.path.join(out_dir, f"{project_id}.glb")) ctx.client.download(model_url, target) payload.append({"task": wait_task, "project_id": project_id, "model_url": model_url, "output_file": target}) ctx.out.data( payload, human=lambda: [ctx.out.line(f"✨ {p['output_file'] or p['project_id']}") for p in payload], ) return payload