← Commit history

v1.6.73: relay-safe wait defaults (15s) + fusion_export_optimized_glb/fusion_fetch_optimized_glb docs in skill

John Lauer ·9e75576a5f ·3mo ago ·parent 5a19638
6 files changed +47−10
BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.6.72\ No newline at end of file+1.6.73\ No newline at end of file
adom-bridge-fusion-manifest.json+4−4
@@ -1,10 +1,10 @@ {   "manifest_version": 1,   "name": "fusion360",-  "version": "1.6.72",-  "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.72/adom-bridge-fusion-v1.6.72.zip",-  "sha256": "617db8fc2cc62b99d9d9d03e14f4adb21bc28d1d68d66d7a40ad7d25ca13459b",-  "size": 371999,+  "version": "1.6.73",+  "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.73/adom-bridge-fusion-v1.6.73.zip",+  "sha256": "720325557ad11533caf7b618588255533b37fcff50924051be229d6d9862a4a2",+  "size": 373207,   "verbPrefixes": [     "fusion_"   ],
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "fusion360",   "displayName": "Autodesk Fusion 360",-  "version": "1.6.72",+  "version": "1.6.73",   "description": "Drive Autodesk Fusion 360 from the cloud: launch Fusion, electronics board layout, design rules, exports (STEP/IGES/STL/3MF/USDZ/OBJ/DXF/DWG/Gerbers/BOM/CPL), fast APS server-indexed cloud search plus browse/recent/file-info/versions, cloud file download/upload and folder creation, and in-app parametric modeling (fusion_run_modeling_script). Never-charge: APS calls are capped to the free tier.",   "homepage": "https://wiki.adom.inc/adom/adom-desktop-fusion-bridge",   "author": "Adom Inc.",
describe.py+2−2
@@ -132,8 +132,8 @@ _T = [     ("fusion_export_stl", "Export to STL mesh.", {"outputPath": "required str"}, {"format": "str"}, 300, None, True, {"outputPath": "C:/out/part.stl"}),     ("fusion_export_3mf", "Export to 3MF mesh.", {"outputPath": "required str"}, {"format": "str"}, 300, None, True, {"outputPath": "C:/out/part.3mf"}),     ("fusion_export_usdz", "Export to USDZ (AR / Hydrogen 3D).", {"outputPath": "required str"}, {"format": "str"}, 300, None, True, {"outputPath": "C:/out/part.usdz"}),-    ("fusion_export_optimized_glb", "Fusion board -> wiki-grade optimized GLB. Exports STEP (+ optional silkscreen) and submits it to service-step2glb molecule mode (anchor to MP pins + silk bake + gold pins + join/weld/prune + Draco): ~465KB/~31 draw calls vs a raw ~16MB/~25000 that halts the viewer. Bounded-waits `wait`s (default 90); small boards return complete, big boards return {pending, jobId} - finish with fusion_fetch_optimized_glb. Use for a component page's component.parts.model_3d.", {"outputPath": "required str (.glb)", "silkscreen": "bool default true", "pin": "str medium|large default medium", "wait": "int seconds default 90"}, {"glbPath": "str", "jobId": "str", "pending": "bool", "meshesAfter": "int", "sizeBytes": "int", "moleculeAnchored": "bool", "silkscreenApplied": "bool"}, 200, None, True, {"outputPath": "C:/out/board.glb"}),-    ("fusion_fetch_optimized_glb", "Finish a fusion_export_optimized_glb job: bounded-poll the optimizer by jobId and write the GLB to outputPath when complete. Re-call until status=complete (big boards tessellate a few minutes). No Fusion needed.", {"jobId": "required str", "outputPath": "str (.glb)", "wait": "int seconds default 90"}, {"glbPath": "str", "status": "str", "pending": "bool", "sizeBytes": "int"}, 150, None, False, {"jobId": "abc123", "outputPath": "C:/out/board.glb"}),+    ("fusion_export_optimized_glb", "Fusion board -> wiki-grade optimized GLB. Exports STEP (+ optional silkscreen) and submits it to service-step2glb molecule mode (anchor to MP pins + silk bake + gold pins + join/weld/prune + Draco): ~465KB/~31 draw calls vs a raw ~16MB/~25000 that halts the viewer. Bounded-waits `wait`s (default 90); small boards return complete, big boards return {pending, jobId} - finish with fusion_fetch_optimized_glb. Use for a component page's component.parts.model_3d.", {"outputPath": "required str (.glb)", "silkscreen": "bool default true", "pin": "str medium|large default medium", "wait": "int seconds default 15 (keep under the ~60s relay timeout; re-call fetch until complete)"}, {"glbPath": "str", "jobId": "str", "pending": "bool", "meshesAfter": "int", "sizeBytes": "int", "moleculeAnchored": "bool", "silkscreenApplied": "bool"}, 200, None, True, {"outputPath": "C:/out/board.glb"}),+    ("fusion_fetch_optimized_glb", "Finish a fusion_export_optimized_glb job: bounded-poll the optimizer by jobId and write the GLB to outputPath when complete. Re-call until status=complete (big boards tessellate a few minutes). No Fusion needed.", {"jobId": "required str", "outputPath": "str (.glb)", "wait": "int seconds default 15 (keep under the ~60s relay timeout; re-call fetch until complete)"}, {"glbPath": "str", "status": "str", "pending": "bool", "sizeBytes": "int"}, 150, None, False, {"jobId": "abc123", "outputPath": "C:/out/board.glb"}),     ("fusion_export_obj", "Export to OBJ mesh.", {"outputPath": "required str"}, {"format": "str"}, 300, None, True, {"outputPath": "C:/out/part.obj"}),     ("fusion_export_dxf", "Export 2D DXF.", {"outputPath": "required str"}, {"format": "str"}, 120, None, True, {"outputPath": "C:/out/sketch.dxf"}),     ("fusion_export_dwg", "Export 2D DWG.", {"outputPath": "required str"}, {"format": "str"}, 120, None, True, {"outputPath": "C:/out/sketch.dwg"}),
server.py+2−2
@@ -3417,7 +3417,7 @@ def _orchestrate_export_optimized_glb(args: dict) -> dict:         return {"success": False, "error": sub.get("error"), "_hint": sub.get("_hint"),                 "stepPath": step_path, "note": "STEP exported OK; optimize submit failed."}     job_id = sub["jobId"]-    wait_s = int(args.get("wait", 90))+    wait_s = int(args.get("wait", 15))  # keep total (STEP export + wait) under the ~60s relay timeout     fetched = _service_glb_fetch(job_id, out_path=output_path, poll_s=wait_s) if wait_s > 0 else {"ok": True, "status": "processing"}     status_url = "%s/jobs/%s" % (STEP2GLB_URL, job_id)     result_url = "%s/jobs/%s/result" % (STEP2GLB_URL, job_id)@@ -3464,7 +3464,7 @@ def _orchestrate_fetch_optimized_glb(args: dict) -> dict:     out_path = args.get("outputPath") or args.get("output_path")     if out_path and not out_path.lower().endswith(".glb"):         out_path = out_path + ".glb"-    wait_s = int(args.get("wait", 90))+    wait_s = int(args.get("wait", 15))  # keep total (STEP export + wait) under the ~60s relay timeout     res = _service_glb_fetch(job_id, out_path=out_path, poll_s=wait_s)     status_url = "%s/jobs/%s" % (STEP2GLB_URL, job_id)     result_url = "%s/jobs/%s/result" % (STEP2GLB_URL, job_id)
skills/fusion-molecule-export/SKILL.md+37
@@ -77,6 +77,43 @@ Field-name gotchas (these are the exact multipart names the server parses; guess The page then lives at `https://hydrogen.adom.inc/{username}/molecules/{Name}` (login-gated) and the USDZ->GLB optimization is queued automatically (ready in a few minutes). +## The pretty 3D: `fusion_export_optimized_glb` (do NOT ship a raw STEP dump)++A raw `fusion_export_step` + a plain `adom-step2glb convert` leaves EVERY solid/pad/via+as its own draw call: a real board comes out ~16 MB / ~25,000 primitives that HALTS the+viewer's GPU on rotation (John hit this live). The bridge verb runs the board through+**service-step2glb molecule mode** instead (the OCCT replacement for Colby's Blender+pipeline: anchor to MP pins -> optional silk bake -> gold pins -> dedup/flatten/JOIN/weld/+prune -> Draco), so the same board comes out **~465 KB / ~31 draw calls, auto-anchored**.+ALWAYS use this for a component page's `component.parts.model_3d` - never a raw STEP->GLB.++Two verbs, because a big board tessellates for minutes (longer than the AD relay's ~60s+request timeout), so it is submit-then-poll, never one long blocking call:++```+# 1) export STEP + submit to the optimizer (returns fast with a jobId; small boards may+#    already come back complete within `wait` seconds)+fusion_export_optimized_glb {"outputPath":"C:/tmp/board.glb", "silkscreen":true, "pin":"medium", "wait":15}+#    -> { pending:true, jobId:"...", stepPath, resultUrl }   (big board)+#    -> { status:"complete", glbPath, sizeBytes, meshesAfter, moleculeAnchored }  (small board)++# 2) finish it: re-call until status=complete (each call polls ~15s, well under the relay+#    timeout, and writes the GLB on the box when ready). No Fusion needed for this verb.+fusion_fetch_optimized_glb {"jobId":"...", "outputPath":"C:/tmp/board.glb", "wait":15}+#    -> { status:"complete", glbPath, sizeBytes }   then pull_file it.+```++Gotchas baked in from the live bring-up (2026-07-14):+- **The *.adom.cloud edge WAF 403s the default `Python-urllib` User-Agent.** The bridge sets+  a UA on every service call; if you ever call the service yourself from Python, set one too.+- **`/jobs/{id}/result` is ONE-SHOT** - it returns the GLB once, then empty. So fetch exactly+  once per job when complete; do not race multiple overlapping fetches at the same outputPath+  (they truncate each other to 0 bytes).+- Keep `wait` small (<=~25s). A `wait` big enough to exceed the relay timeout loses the response+  even though the box finished - and with a one-shot result, the re-call then gets nothing.+- Silkscreen bake needs the silk PNGs registered to the board XY bbox (Drew's contract); the+  verb captures them best-effort and still returns a great (un-silked) GLB if capture is off.+ ## A parallel, PUBLIC option: an adom-wiki `component` page  If you also want a browsable PUBLIC page with a live 3D viewer (no molecule login), scaffold an