Spaces:
Runtime error
Runtime error
| """ | |
| Forge-Anim Brick | |
| """ | |
| import gradio as gr | |
| import spaces | |
| # Robust import for local workspace + HF Space deployment (common is vendored on push) | |
| import sys | |
| from pathlib import Path | |
| HERE = Path(__file__).resolve().parent | |
| for candidate in (HERE.parent, HERE): | |
| if (candidate / "common" / "manifest.py").exists(): | |
| sys.path.insert(0, str(candidate)) | |
| break | |
| try: | |
| from common.manifest import create_manifest | |
| except ImportError as e: | |
| raise ImportError( | |
| "Failed to import shared 'common' package (manifest.py).\n" | |
| "For local development: run ./install.sh from the forge-bricks/ root.\n" | |
| "For HF Spaces: re-run scripts/push_to_hf.py so it vendors common/." | |
| ) from e | |
| import os | |
| from pathlib import Path | |
| from datetime import datetime | |
| def generate_anim(rig_data: str, motion_desc: str) -> dict: | |
| out = Path(os.environ.get("FORGE_BRICKS_OUTPUT", "./outputs/forge_anim")) | |
| out.mkdir(parents=True, exist_ok=True) | |
| ts = int(datetime.now().timestamp()) | |
| # Use VLM or simple logic + structured output for animation data | |
| # In production, could call a motion model Space or LLM for keyframe data | |
| anim = { | |
| "clips": ["idle", "walk", "attack"], | |
| "motion_desc": motion_desc, | |
| "rig_ref": rig_data[:100] if rig_data else "", | |
| "keyframe_suggestions": { | |
| "idle": "loop 0-30 frames, subtle breathing", | |
| "walk": "cycle 0-24 frames, foot plant at 0/12", | |
| "attack": "windup 0-10, impact 10-15, recover 15-30" | |
| }, | |
| "note": "Structured animation metadata. Apply in Godot/Blender using the rig_data." | |
| } | |
| man = create_manifest( | |
| name="anim", | |
| type="animation", | |
| source_brick="forge-anim", | |
| prompt_or_desc=motion_desc, | |
| files={"anim_data": str(out / f"anim_{ts}.json")}, | |
| metadata=anim, | |
| commercial_ok=True | |
| ) | |
| (out / f"anim_{ts}.json").write_text(str(anim)) | |
| man.save(out / f"manifest_{ts}.json") | |
| return {"anim_data": anim, "manifest": man.to_dict()} | |
| def build_ui(): | |
| with gr.Blocks() as d: | |
| gr.Markdown("# Forge-Anim") | |
| rig = gr.Textbox("rig json or description") | |
| motion = gr.Textbox("heroic walk cycle") | |
| btn = gr.Button("Generate Anim") | |
| out = gr.JSON() | |
| btn.click(generate_anim, [rig, motion], out) | |
| return d | |
| # Build at module level so that `demo` (and `gradio_app`) exist when the module is imported | |
| # (required for Hugging Face Spaces and for agent/MCP discovery). | |
| demo = build_ui() | |
| gradio_app = demo # alias for compatibility with tools/skills that expect `gradio_app` | |
| if __name__ == "__main__": | |
| demo.launch(server_name="0.0.0.0", server_port=7867, mcp_server=True) |