app
Fusion - the Fusion 360 Bridge
Public Made by Adomby adom
Drive Autodesk Fusion 360 from the cloud via Adom Bridge: component libraries, IPC package generation, board layout, exports (STEP/Gerbers/BOM/CPL), fast APS cloud search, and parametric modeling.
← Commit history
v1.6.2: capture_library_views settle fix + shared-footprint pattern in skill
7 files changed
+56−10
BRIDGE_VERSION+1−1@@ -1 +1 @@-1.6.1+1.6.2
CHANGELOG.md+12@@ -3,6 +3,18 @@ All notable changes to the Adom Desktop Fusion 360 bridge, newest first. Canonical: https://wiki.adom.inc/adom/adom-desktop-fusion-bridge · GitHub backup: `adom-inc/adom-desktop-fusion-bridge` +## 1.6.2 - 2026-06-29++- **`fusion_capture_library_views` settle fix.** It fired the screenshot ~0.4s after `EDIT`, before+ the editor actually switched - so a shot could capture the PREVIOUS part (a mislabeled view). Now it+ waits a tunable **`settle`** (default 1.5s) after each `EDIT` before framing + capturing, so the shot+ matches its label.+- **Skill: the SHARED-FOOTPRINT pattern for whole-catalog libraries.** `fusion-multipart-libraries`+ now documents how a 138-part library is really 10 footprints + 138 devicesets: collapse the catalog+ to its unique `(type, package)` combos, `fusion_build_library_3d` the ~10 bases (10 uploads, not+ 138), then clone each base deviceset per value (sharing its symbol + package + 3D binding). Proven+ by building the entire Adom basic parts library (138 parts, all Mapped + rendering).+ ## 1.6.1 - 2026-06-29 - **NEW `fusion_capture_library_views` - the views EEs actually trust.** Given a list of packages
adom-bridge-fusion-manifest.json+5−5@@ -1,13 +1,13 @@ { "manifest_version": 1, "name": "fusion360",- "version": "1.6.1",- "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.1/adom-bridge-fusion-v1.6.1.zip",- "sha256": "602dd8aa07e5d3e0b376a2f0d0d87743189634b735d0a957894923cd84692e2e",- "size": 282802,+ "version": "1.6.2",+ "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.2/adom-bridge-fusion-v1.6.2.zip",+ "sha256": "a3f9922f29273ca0b24eab7a0cd744fd3aa5b84a7c3439f2223b4b7066e97657",+ "size": 285138, "verbPrefixes": [ "fusion_" ], "healthEndpoint": "/status",- "released_at": "2026-06-29T17:30:00Z"+ "released_at": "2026-06-29T19:30:00Z" }
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "fusion360", "displayName": "Autodesk Fusion 360",- "version": "1.6.1",+ "version": "1.6.2", "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://github.com/adom-inc/adom-desktop-fusion-bridge", "author": "Adom Inc.",
describe.py+1−1@@ -84,7 +84,7 @@ _T = [ {"lbrPath": "required str (combined .lbr WINDOWS path to bind + open)", "parts": "required [{package, lbrPath (per-part footprint .lbr), modelPath (.step)}]", "outLbrPath": "optional str (default: overwrite lbrPath)", "capture": "optional bool (default true)", "projectId": "optional str", "folderId": "optional str", "openWhenDone": "optional bool (default true)"}, {"success": "bool", "boundLbr": "str", "partsBound": "int", "partsTotal": "int", "parts": "[{package,success,wip_urn,dims_mm,error}]", "screenshots": "[{package,stage,path}]", "opened": "bool"}, 1800, _STATUS, True, {"lbrPath": "C:/tmp/newlib/AdomBasicParts2.lbr", "parts": [{"package": "R_4k7", "lbrPath": "C:/tmp/newlib/R_4k7.lbr", "modelPath": "C:/tmp/newlib/R_4k7.step"}]}), ("fusion_capture_library_views", "Capture the LIBRARY-EDITOR views EEs trust: the schematic SYMBOL (full pinout), the FOOTPRINT (pads + layer stack), and the COMPONENT/device view (Content Manager: symbol + the package table with the footprint<->package Mapped check + pin/pad counts). The 3D before/after shots don't show these. Requires the .lbr OPEN in the Electronics Library workspace (fusion_open_lbr first). Runs EDIT <pkg>.sym/.pac/.dev + WINDOW FIT + a background hwnd screenshot per view; returns the PNG paths on the box (C:/tmp/conduit-screenshots - pull with desktop_pull_file). EDIT uses the DEVICESET name (e.g. ESP32-S3FN8).",- {"packages": "required [<deviceset name>] (or 'package': single name)", "views": "optional subset of ['component','symbol','footprint'] (default all)"},+ {"packages": "required [<deviceset name>] (or 'package': single name)", "views": "optional subset of ['component','symbol','footprint'] (default all)", "settle": "optional float secs after each EDIT before capture (default 1.5; raise if a shot shows the PREVIOUS part)"}, {"success": "bool", "captured": "[{package,view,path,ok}]"}, 300, _STATUS, True, {"packages": ["ESP32-S3FN8", "ATSAMD51J20A-AUT"]}), ("fusion_run_modeling_script", "Run an adsk.fusion modeling script in the live session (sketches/extrudes/params). Free programmatic CAD.", {"script": "required str (Python using adsk; globals: adsk, app, ui, design)"},
server.py+10−2@@ -1554,7 +1554,11 @@ def _orchestrate_capture_library_views(args: dict) -> dict: (C:/tmp/conduit-screenshots - pull them with desktop_pull_file). args: {packages: [<deviceset name>, ...] (or a single 'package'),- views?: subset of ['component','symbol','footprint'] (default all three)}+ views?: subset of ['component','symbol','footprint'] (default all three),+ settle?: seconds to wait after each EDIT before framing/capturing (default 1.5 - raise it+ if a shot shows the PREVIOUS part, lower it to go faster on a snappy machine)}+ NOTE: ~2s per view * parts * views can exceed the ~60s relay request timeout - the captures still+ complete server-side; verify the PNGs landed in C:/tmp/conduit-screenshots and pull them. """ import time as _t pkgs = args.get("packages") or ([args["package"]] if args.get("package") else [])@@ -1566,13 +1570,17 @@ def _orchestrate_capture_library_views(args: dict) -> dict: "dev": "dev", "sym": "sym", "pac": "pac"} label_of = {"dev": "component", "sym": "symbol", "pac": "footprint"} views = args.get("views") or ["component", "symbol", "footprint"]+ # EDIT is async - the editor takes a beat to actually SWITCH the view. Capturing too soon grabs+ # the PREVIOUS view (a mislabeled shot). Settle AFTER the EDIT (before fit/capture); tunable.+ settle = float(args.get("settle", 1.5)) out = [] for pkg in pkgs: for v in views: ext = view_ext.get(v, v) er = _proxy_to_addin("electron_run", {"command": f"EDIT {pkg}.{ext}"}, timeout=30)+ _t.sleep(settle) # let the editor LOAD the new view before framing/capturing it _proxy_to_addin("electron_run", {"command": "WINDOW FIT"}, timeout=20)- _t.sleep(0.4)+ _t.sleep(0.6) shot = _capture_labeled(f"{pkg}_{label_of.get(ext, ext)}") out.append({"package": pkg, "view": label_of.get(ext, ext), "path": shot, "ok": bool(er.get("success", True)) and bool(shot)})
skills/fusion-multipart-libraries/SKILL.md+26@@ -77,6 +77,32 @@ pinout), the **FOOTPRINT** (pad array + the Copper/Silkscreen/Mask layer stack), **Mapped ✓** check + pin/pad counts). Put these in the demo video alongside the 3D - they are the warm -and-fuzzy shots. (Manual equivalent: `fusion_open_lbr` then `fusion_electron_run "EDIT X.sym"` etc.) +### 🏭 Scaling to a WHOLE catalog - SHARE footprints (do NOT build 3D per value)++Building a big library (e.g. the entire **138-part Adom basic parts library**) does NOT mean 138 3D+builds. A real EAGLE/Fusion library SHARES footprints: ONE `R-0402` package is used by all 41 of the+0402 resistor *values*; ONE `C-0603` by all 14 of those caps. The 3D model is per *package*, not per+value. So:++1. **Collapse the catalog to its unique `(type, package)` combos.** The whole Adom basic parts catalog+ (138 values) is just **10 footprints**: R-0402, R-0603, C-0402, C-0603, C-0805, L, LED-0402,+ LED-0603, LED-2020, FB-0402.+2. **Build ONE base part per combo** (`adom-lbr generate` → a `.lbr` with that footprint + symbol),+ then `fusion_build_library_3d` over the ~10 bases → ~10 f3d `package3d` bindings. (10 builds, not 138.)+3. **Clone the base deviceset per value.** Take each bound base `<deviceset>` (it already carries the+ shared `<gate symbol=…>`, `<device package=…>`, and `<package3dinstances>` 3D binding) and emit one+ copy per catalog value, changing only the `<deviceset name=…>` (EAGLE-style, e.g. `R-0402-4K7`,+ `C-0603-100N`) and the `<technology>` attributes (`VALUE`/`MPN`/`MF`/`MOUSER`). All clones reference+ the SAME symbol + package + 3D urn.+4. Result: **N packages + N symbols + N package3d + M devicesets** (M ≫ N). The 138-part library =+ 10 packages + 138 devicesets, every one Mapped ✓ and rendering, built from 10 uploads.++**Sourcing the ~10 footprints + 3D:** passive land patterns are standard per package (IPC-7351), so a+0603 cap shares the 0603 *resistor* land, an 0805 cap shares the 0805 land, etc. Pull real CAD from the+per-MPN wiki pages (`/api/v1/pages/<mpn-lowercased>/files/<MPN>.kicad_mod`/`.step` - chip-fetcher's+output), the wiki **static footprints library** (`static/footprints/<pkg>/`), or generic KiCad models+(`C_0603_1608Metric.step`, etc.). One representative MPN per combo is enough.+ Everything below is the MANUAL equivalent (what the verb does internally) - read it to understand or debug, but reach for `fusion_build_library_3d` first.