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
board_bom grouping fix; framing skips body-less parts
3 files changed
+15−3
CHANGELOG.md+8@@ -3,6 +3,14 @@ All notable changes to the Adom Bridge Fusion 360 bridge, newest first. Canonical: https://wiki.adom.inc/adom/fusion-bridge ยท GitHub backup: `adom-inc/fusion-bridge` +## 1.13.36 (2026-10-30)++- `fusion_board_bom` (and fusion_bom, jlcpcb_order, assembly_check, which read it): parts without an MPN were one line per+ footprint, so a 47 nF and a 10 uF cap of the same footprint shared a line, valued "test point" and given the first+ part's LCSC number (seen live on lane-BQ25792-copy). Without an MPN a line is now footprint, value and LCSC together.+- `fusion_render_board_3d {refs}`: a part with no 3D body (an empty box at the origin) is not framed; with only such+ parts it answers unknown_parts and points at fusion_bodies' noBody.+ ## 1.13.35 (2026-10-30) - `fusion_render_board_3d` (the standard's render_board and render_board_3d): `refs` frames the named parts (the union
rust/bridge/src/docs_script.py+4−2@@ -154,12 +154,14 @@ def render_board_3d(app, args): continue for c in o.childOccurrences: r = c.name.rsplit(':', 1)[-1].upper()- if r in want and c.boundingBox:+ # a part with no 3D body has an empty box at the origin: it cannot be framed+ has_body = c.bRepBodies.count > 0 or any(x.bRepBodies.count for x in c.allOccurrences)+ if r in want and has_body and c.boundingBox: boxes.append(c.boundingBox) found.add(r) missing = sorted(want - found) if not boxes:- return {'success': False, 'errorCode': 'unknown_parts', 'error': 'No 3D part named %s on the board' % ', '.join(missing)}+ return {'success': False, 'errorCode': 'unknown_parts', 'error': 'No 3D body for %s on the board (a part with no 3D package cannot be framed: fusion_bodies lists them under noBody)' % ', '.join(missing)} lo = [min(b.minPoint.x for b in boxes), min(b.minPoint.y for b in boxes), min(b.minPoint.z for b in boxes)] hi = [max(b.maxPoint.x for b in boxes), max(b.maxPoint.y for b in boxes), max(b.maxPoint.z for b in boxes)] margin = float(args.get('marginMm', 2.0)) / 10.0
rust/bridge/src/routing_script.py+3−1@@ -701,7 +701,9 @@ def board_bom(board, args): for e in board.iter('element'): ids = part_ids(e) # MPN, LCSC... under any of the names libraries use (board_model.py) mpn = ids['mpn']- key = mpn or ('board-only:' + e.get('package', ''))+ # without an MPN, parts are one line only when footprint, value and LCSC agree: grouping by+ # footprint alone put a 47 nF and a 10 uF cap on one line, named 'test point'+ key = mpn or ('board-only:%s|%s|%s' % (e.get('package', ''), e.get('value', ''), ids['lcsc'])) r = rows.setdefault(key, {'designators': [], 'value': e.get('value', ''), 'package': e.get('package', ''), 'mpn': mpn, 'manufacturer': ids['manufacturer'], 'mouser': ids['mouser'], 'digikey': ids['digikey'], 'lcsc': ids['lcsc']})