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
match master (lands after #27 as 1.13.27, add-in 1.0.28)
6 files changed
+384−3
CHANGELOG.md+84@@ -3,6 +3,90 @@ 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.27 (unreleased)++From Drew Owens (PR #28): the mechanical layer on big assemblies, profiled inside Fusion on a 4,579-occurrence+production assembly built from 23 referenced designs.++- The revision digest every guarded call pays went from 32.6 s to 5.2 s: entity tokens are read only on a miss,+ refused timeline-index reads are remembered per feature revision, and components come from the occurrences read.+- References: an occurrence registered this session reuses its token, and a reference resolves by walking its path's+ names (248 ms to 5.7 ms). Joint solving compares each occurrence with the one at its path instead of every pair.+- Write guards keep each body's witness by revision and reuse the pre-check's health walk.+- `bom` reads metadata and physical properties once per definition; `budgetSeconds` (default 40) stops the cloud+ part-number reads and marks the rest `nativePending` (cached for the next run). `inspect` leaves out body metrics+ above 200 components (`bodyMetrics:true`) and the health walk above 200 timeline items (`health:true`).+- `efficiency_report` returns the full target. The add-in is 1.0.28; the exe embeds the new `schema.json`.++## 1.13.26 (2026-10-30)++- Engine 0.21.1 (standard 0.24.2): lint_library's duplicate_pad_number counts same-numbered pads that touch or overlap+ as one land, so a split exposed pad is no longer a false warning. Otherwise as 1.13.25, which this replaces before+ it was smoke-tested.++## 1.13.25 (2026-10-30)++- Engine 0.21.0 (standard 0.24.0). `fusion_lint_library` (the standard's lint_library): a .lbr read offline (pads,+ courtyard on tKeepout, silk on tPlace, 3D packages, descriptions; each component's pins, footprint and MPN) and judged+ by the shared engine, every problem a finding with a rule name and a severity.+- `fusion_update_footprints_from_library` (the standard's update_footprints_from_library, #27), the plan: each placed+ footprint against the same-named package in the .lbr files named, pad by pad (up_to_date, differs with the diff, or+ library_not_found). apply is refused with the plan: Fusion's UPDATE asks about each part in a dialog.+- `fusion_edit_footprint` writes a library that has footprints but no components yet (it checked it with the full+ preflight, which demands symbols, and refused). 349 verbs.++## 1.13.24 (2026-10-30)++- `fusion_list_installed_libraries` (the standard's list_installed_libraries): the libraries Fusion offers to place+ from are the hub's electronics libraries (.flbr, Library Manager's Hub Libraries tab). Fusion keeps no local list and+ draws that tab without UI Automation, so the verb walks the hub's projects and folders through the signed-in session+ (breadth first, to a depth, within a time budget).+- `fusion_add_symbol_art` (the standard's add_symbol_art): the chip outline adom-symbol baked into a KiCad symbol, drawn+ into the component's symbol fitted to its body (the TPS54202's 162 polylines live). Offline on a .lbr.+- uninstall_library, normalize_bodies and sch_sheet_symbol answer not_supported: taking a hub library out would delete+ the file for everyone; a Fusion footprint's 3D model is a cloud package placed when made, with no stored offsets; and+ a Fusion module cannot be made from a text command (checked live). 347 verbs.++## 1.13.23 (2026-10-30)++- The standard's app tier in Fusion's terms:+ - `fusion_diagnostics`: facts for a bug report without driving Fusion (bridge version and folders, bundled add-in,+ Fusion launcher, processes and windows, whether the add-in answers, the Adom/Fusion/Autodesk environment with the+ values of credential-named variables never shown);+ - `fusion_instances`: every running Fusion process;+ - `fusion_progress`: the long operation in flight, measured phase and verb timings, recent runs;+ - `fusion_foreground {reason}`: Fusion brought in front, the sanctioned exception: the user is notified why and given+ three seconds first.+- panel and selection answer not_supported: Fusion's editors show their own panels (the bridge opens surfaces with+ fusion_show_*), and Fusion does not show the user's board selection to the bridge (a ULP's ingroup() reads no part+ even right after a GROUP, checked live). 345 verbs.++## 1.13.22 (2026-10-30)++- `fusion_variants` (the standard's variants): a design's assembly variants, each with its not-fitted parts and+ alternate values, read from the schematic. Making, changing or removing one is refused with not_supported: Fusion+ 2706 takes EAGLE's VARIANT from a text command (any form, schematic or board) and changes nothing.+- `fusion_silkscreen_prep` (the standard's silkscreen_prep, in Fusion's terms): designators on copper moved off it where+ they fit (the engine's silk_designators), counted before and after; loose silk outside the board listed. A footprint's+ own silk lines are its library package's and cannot be clipped on one board: the fab's CAM clips silk at mask openings.++From Drew Owens (PR #27): CAM from the typed mechanical layer, and exploded renders that work on big assemblies.++- `cam_job` makes a milling job in one journaled call:+ - a setup on the given bodies, and operations in order (`face`, `adaptive`, `contour`, `parallel`, `scallop`, `pocket_clearing`, `drill`);+ - tools from Fusion's sample library by type and nearest diameter, with optional parameter overrides by name;+ - drilling finds the bodies' holes of the drill's diameter unless `holeFaces` are given;+ - it generates the toolpaths, reports each operation's warnings and errors and the machining time, and with `post` writes G-code+ through a post from Fusion's library (FANUC, Grbl, HAAS, ...);+ - a failed job deletes its setup.++ `cam_tools` lists the library's tools, and `cam_inspect` reads a document's setups and NC programs. Live: a pocketed, drilled plate gave+ valid face, adaptive, contour and drill toolpaths and a 1,901-line FANUC program. Known gap: the FANUC O-number stays O1001.+- `exploded_view_render` captures only the moved occurrences and their parents (children follow), so a 4,579-occurrence assembly+ renders instead of hitting the 256-instance budget. It checks home poses within 0.01 mm (`restoredWithinMm`) instead of exact float+ equality, which flagged a clean revert on a big assembly as `restore_failed`.+- 67 typed operations; the add-in is 1.0.27, and the exe embeds the new `schema.json`. 341 verbs.+ ## 1.13.21 (2026-10-29) - `fusion_replicate_layout` (the standard's replicate_layout): one channel's placement copied to matching channels round
addin/AdomBridge/AdomBridge.manifest+1−1@@ -6,7 +6,7 @@ "description": { "": "Adom Desktop Conduit bridge add-in. Exposes a localhost HTTP API for external automation of Fusion 360." },- "version": "1.0.26",+ "version": "1.0.28", "runOnStartup": true, "supportedOS": "windows" }
addin/AdomBridge/commands/mechanical/schema.json+138@@ -7535,5 +7535,143 @@ "target", "filename" ]+ },+ "cam_tools": {+ "type": "object",+ "description": "List tools in Fusion's sample tool libraries (milling or hole making, metric), optionally of one type, with diameter in mm, so cam_job can name them.",+ "properties": {+ "library": {+ "type": "string",+ "enum": [+ "milling",+ "hole"+ ]+ },+ "type": {+ "type": "string"+ },+ "limit": {+ "type": "integer",+ "minimum": 1,+ "maximum": 500+ }+ },+ "required": [+ "op"+ ]+ },+ "cam_job": {+ "type": "object",+ "description": "Make a milling job: a setup on the given bodies, then operations in order (strategy face, adaptive, contour, parallel, scallop, pocket_clearing or drill), each with a tool from Fusion's sample library chosen by type and diameter (nearest) and optional Fusion parameter overrides by name. Drill picks the bodies' holes of the drill's diameter unless holeFaces are given. Generates the toolpaths, reports every operation's warnings and errors and the machining time, and, with post, writes G-code through a post from Fusion's library (FANUC, Grbl, HAAS - Next Generation Control, ...). Opens the Manufacture workspace once if the document has no CAM yet, then returns to the user's workspace. Journaled.",+ "properties": {+ "operationId": {+ "type": "string"+ },+ "name": {+ "type": "string"+ },+ "bodies": {+ "type": "array",+ "minItems": 1,+ "maxItems": 32,+ "items": {+ "type": "object"+ }+ },+ "operations": {+ "type": "array",+ "minItems": 1,+ "maxItems": 32,+ "items": {+ "type": "object",+ "properties": {+ "strategy": {+ "type": "string",+ "enum": [+ "face",+ "adaptive",+ "contour",+ "parallel",+ "scallop",+ "pocket_clearing",+ "drill"+ ]+ },+ "name": {+ "type": "string"+ },+ "tool": {+ "type": "object",+ "properties": {+ "type": {+ "type": "string",+ "description": "Tool type as Fusion names it: flat end mill, ball end mill, bull nose end mill, drill, chamfer mill, ..."+ },+ "diameterMm": {+ "type": "number",+ "exclusiveMinimum": 0,+ "maximum": 200+ }+ },+ "additionalProperties": false+ },+ "parameters": {+ "type": "object"+ },+ "holeFaces": {+ "type": "array",+ "maxItems": 512,+ "items": {+ "type": "object"+ }+ }+ },+ "required": [+ "strategy"+ ],+ "additionalProperties": false+ }+ },+ "post": {+ "type": "object",+ "properties": {+ "machine": {+ "type": "string"+ },+ "folder": {+ "type": "string"+ },+ "program": {+ "type": "string"+ }+ },+ "required": [+ "folder"+ ],+ "additionalProperties": false+ },+ "timeoutSeconds": {+ "type": "number",+ "minimum": 10,+ "maximum": 3600+ }+ },+ "required": [+ "op",+ "sessionId",+ "operationId",+ "target",+ "bodies",+ "operations"+ ]+ },+ "cam_inspect": {+ "type": "object",+ "description": "Read the active document's CAM: setups, their operations' toolpath state, warnings and errors, and NC programs.",+ "properties": {},+ "required": [+ "op",+ "target"+ ] } }
docs/MECHANICAL.md+20@@ -293,6 +293,26 @@ Create/insert transforms use parent-component coordinates. Creation, insertion a `efficiency_report` reads what makes a design slow to recompute, open and edit: timeline make-up and health, Position snapshots, Move features, size, repeated definitions made by Paste New, instance-weighted faces, imported history and wires in a parametric design, big sketches, pattern compute options, modeled threads, meshes and empty components. It returns `metrics` and `findings` (rule, severity, measured, limit, fix), worst first. It never changes the model and needs no revision digest; it is journaled like `bom_export`, so a long report on a big design is followed with `fusion_mech_operation_status`. Passes past `budgetSeconds` (default 120) are skipped and listed with `complete:false`; `computeTiming:true` also times a full `computeAll`. The rules and the benchmarks behind them are in `skills/fusion-design-efficiency/SKILL.md`. +## CAM: toolpaths and G-code++`cam_tools` lists Fusion's sample tool libraries (`library` `milling` or `hole`, metric), optionally of one `type`, with diameters in mm.++`cam_job` makes a milling job in one journaled call. It takes the `bodies` to machine and `operations` in order, each a `strategy`:+- `face`;+- `adaptive`, Fusion's 3D adaptive roughing;+- `contour`, 3D contour finishing;+- `parallel` and `scallop`;+- `pocket_clearing`;+- `drill`.++Each operation's tool comes from the sample library by `type` and nearest `diameterMm` (a tie goes to the smaller tool). Optional `parameters` override Fusion's operation parameters by name. Drill picks the bodies' concave cylindrical faces of the drill's diameter unless `holeFaces` are given.++The job generates the toolpaths and reports each operation's toolpath state, warnings and errors, plus the machining time. With `post` (`machine`, `folder`, `program`) it posts G-code through a post from Fusion's library matched by name: `FANUC`, `Grbl`, `HAAS - Next Generation Control`, ... Fusion writes posted files to its default NC folder whatever folder is asked for, so the job moves the file into `post.folder`.++A failed job deletes its setup, so nothing half-made is left. A document has no CAM until the Manufacture workspace has been opened once, so the first job opens it and returns to the user's workspace. `cam_inspect` reads the document's setups, operations and NC programs.++Live on Fusion 2705, a plate with a pocket and four 5 mm holes gave valid toolpaths for every operation (face, adaptive, contour, drill) and a 1,901-line FANUC program with three tools and a G81 drilling cycle. Known gap: the FANUC program number stays O1001 (the file takes the requested name).+ ## McMaster and purchased CAD `mcmaster_discover` reports availability of Fusion's native Insert McMaster-Carr command. `mcmaster_open` launches its interactive supplier picker in the targeted Hybrid design. Its recorded result is a launch request, not proof that a part was inserted. Inspect again after insertion or cancellation. This operation does not place orders.
rust/core/tests/golden/mech_capabilities.json+139@@ -7550,6 +7550,144 @@ "target", "filename" ]+ },+ "cam_tools": {+ "type": "object",+ "description": "List tools in Fusion's sample tool libraries (milling or hole making, metric), optionally of one type, with diameter in mm, so cam_job can name them.",+ "properties": {+ "library": {+ "type": "string",+ "enum": [+ "milling",+ "hole"+ ]+ },+ "type": {+ "type": "string"+ },+ "limit": {+ "type": "integer",+ "minimum": 1,+ "maximum": 500+ }+ },+ "required": [+ "op"+ ]+ },+ "cam_job": {+ "type": "object",+ "description": "Make a milling job: a setup on the given bodies, then operations in order (strategy face, adaptive, contour, parallel, scallop, pocket_clearing or drill), each with a tool from Fusion's sample library chosen by type and diameter (nearest) and optional Fusion parameter overrides by name. Drill picks the bodies' holes of the drill's diameter unless holeFaces are given. Generates the toolpaths, reports every operation's warnings and errors and the machining time, and, with post, writes G-code through a post from Fusion's library (FANUC, Grbl, HAAS - Next Generation Control, ...). Opens the Manufacture workspace once if the document has no CAM yet, then returns to the user's workspace. Journaled.",+ "properties": {+ "operationId": {+ "type": "string"+ },+ "name": {+ "type": "string"+ },+ "bodies": {+ "type": "array",+ "minItems": 1,+ "maxItems": 32,+ "items": {+ "type": "object"+ }+ },+ "operations": {+ "type": "array",+ "minItems": 1,+ "maxItems": 32,+ "items": {+ "type": "object",+ "properties": {+ "strategy": {+ "type": "string",+ "enum": [+ "face",+ "adaptive",+ "contour",+ "parallel",+ "scallop",+ "pocket_clearing",+ "drill"+ ]+ },+ "name": {+ "type": "string"+ },+ "tool": {+ "type": "object",+ "properties": {+ "type": {+ "type": "string",+ "description": "Tool type as Fusion names it: flat end mill, ball end mill, bull nose end mill, drill, chamfer mill, ..."+ },+ "diameterMm": {+ "type": "number",+ "exclusiveMinimum": 0,+ "maximum": 200+ }+ },+ "additionalProperties": false+ },+ "parameters": {+ "type": "object"+ },+ "holeFaces": {+ "type": "array",+ "maxItems": 512,+ "items": {+ "type": "object"+ }+ }+ },+ "required": [+ "strategy"+ ],+ "additionalProperties": false+ }+ },+ "post": {+ "type": "object",+ "properties": {+ "machine": {+ "type": "string"+ },+ "folder": {+ "type": "string"+ },+ "program": {+ "type": "string"+ }+ },+ "required": [+ "folder"+ ],+ "additionalProperties": false+ },+ "timeoutSeconds": {+ "type": "number",+ "minimum": 10,+ "maximum": 3600+ }+ },+ "required": [+ "op",+ "sessionId",+ "operationId",+ "target",+ "bodies",+ "operations"+ ]+ },+ "cam_inspect": {+ "type": "object",+ "description": "Read the active document's CAM: setups, their operations' toolpath state, warnings and errors, and NC programs.",+ "properties": {},+ "required": [+ "op",+ "target"+ ] } }, "transactions": {@@ -7577,6 +7715,7 @@ "writes": [ "bom_export", "cad_import",+ "cam_job", "component_create", "component_metadata", "construction_axis",
tests/test_mechanical.py+2−2@@ -12,13 +12,13 @@ import unittest from unittest.mock import patch ROOT = Path(__file__).resolve().parents[1]-adsk = ModuleType('adsk'); adsk.core = ModuleType('adsk.core'); adsk.fusion = ModuleType('adsk.fusion')+adsk = ModuleType('adsk'); adsk.core = ModuleType('adsk.core'); adsk.fusion = ModuleType('adsk.fusion'); adsk.cam = ModuleType('adsk.cam') adsk.core.Application = object adsk.fusion.Design = NS(cast=lambda value: value) adsk.fusion.CalculationAccuracy = NS(LowCalculationAccuracy=0, MediumCalculationAccuracy=1, HighCalculationAccuracy=2, VeryHighCalculationAccuracy=3) adsk.fusion.FeatureHealthStates = NS(HealthyFeatureHealthState=0) adsk.fusion.JointDirections = NS(XAxisJointDirection=0, YAxisJointDirection=1, ZAxisJointDirection=2, CustomJointDirection=3)-for module in (adsk, adsk.core, adsk.fusion): sys.modules[module.__name__] = module+for module in (adsk, adsk.core, adsk.fusion, adsk.cam): sys.modules[module.__name__] = module pkg = ModuleType('mechanical_test_commands'); pkg.__path__ = [str(ROOT/'addin/AdomBridge/commands')]; sys.modules[pkg.__name__] = pkg m = importlib.import_module('mechanical_test_commands.mechanical') c = importlib.import_module('mechanical_test_commands.mechanical.core')