app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Reference implementation of the KiCad bridge: multi-instance Python server, forward path via kicad-cli, reverse path via in-process plugin. Most complex of the three bundled bridges.
← Commit history
1.0.55: 1.0.55 REVERTS the 1.0.54 pad change for wiki #119, which was wrong. KiCad's own DRC on KiCad 10.0.2 and 10.0.5 shows that a footprint on B.Cu whose SMD pads are on F.Cu keeps those pads on the FRONT copper at their stored positions (its connectivity report names them 'on F.Cu'; back-layer tracks reach them neither at the stored nor at the mirrored spot). The bridge's literal reading, as in 1.0.53, matches KiCad; 1.0.54 moved such pads to the back and mirrored them, disagreeing with KiCad. New instead: kicad_board_pads and kicad_routing_state list backFootprintsWithFrontPads with a hint, because such a footprint is a part placed on the back without being flipped the way KiCad flips it (KiCad's flip moves the pads to B.*). 1.0.54's other changes stay: the product name out of hints, examples and docs (wiki #118), and the silk hints (wiki #104).
4 files changed
+20−8
rust/Cargo.lock+3−3@@ -244,7 +244,7 @@ dependencies = [ [[package]] name = "kicad-bridge"-version = "1.0.54"+version = "1.0.55" dependencies = [ "kicad-core", "kicad-platform",@@ -255,7 +255,7 @@ dependencies = [ [[package]] name = "kicad-core"-version = "1.0.54"+version = "1.0.55" dependencies = [ "kicad-ipc-rs", "kicad-platform",@@ -281,7 +281,7 @@ dependencies = [ [[package]] name = "kicad-platform"-version = "1.0.54"+version = "1.0.55" dependencies = [ "serde", "serde_json",
rust/Cargo.toml+1−1@@ -3,7 +3,7 @@ resolver = "2" members = ["crates/*"] [workspace.package]-version = "1.0.54"+version = "1.0.55" edition = "2021" license = "MIT" publish = false
rust/crates/kicad-bridge/src/verbs_routing.rs+8−2@@ -338,6 +338,7 @@ fn board_pads(args: &Value) -> Value { }; let board = &loaded.board; let all = pcb::pads(board);+ let front_pads = pcb::back_footprints_with_front_pads(board); let mut pads = all.clone(); if let Some(net_filter) = args.get("net").filter(|v| !v.is_null() && *v != &json!("")) { let net = match pcb::resolve_net(board, Some(net_filter)) {@@ -383,7 +384,7 @@ fn board_pads(args: &Value) -> Value { let mut needs_copper: Vec<String> = nets.iter().filter(|n| n["pads"].as_u64().unwrap_or(0) > 1 && n["hasCopper"] == json!(false)).map(|n| n["name"].as_str().unwrap_or("").to_string()).collect(); needs_copper.sort(); let copper = pcb::copper_layers(board);- json!({+ let mut out = json!({ "success": true, "boardPath": loaded.path.to_string_lossy(), "pads": pads,@@ -399,7 +400,12 @@ fn board_pads(args: &Value) -> Value { "source": "file", "connectivityChecked": false, "output": format!("{} pads, {} nets, {} tracks on {} copper layers", pads.len(), nets.len(), board.segments.len(), copper.len()), "_hint": "Pad x/y are BOARD millimetres (+y is DOWN) with footprint rotation applied: feed them straight to kicad_route or kicad_add_track. Route a net by name and pick your own waypoints. hasCopper means a track exists, not that the net is connected. Use kicad_routing_state for live connectivity. kicad_run_drc is the authority on clearance.",- })+ });+ if !front_pads.is_empty() {+ out["backFootprintsWithFrontPads"] = json!(front_pads);+ out["_frontPadsHint"] = json!(pcb::FRONT_PADS_HINT);+ }+ out } fn add_track(args: &Value) -> Value {
rust/crates/kicad-core/src/ipc.rs+8−2@@ -628,6 +628,7 @@ pub fn routing_state(ctx: &Ctx, args: &Value) -> RResult<Value> { let s = connect(ctx, args)?; let (_text, data, revision) = s.snapshot()?; let pads = pcb::pads(&data);+ let front_pads = pcb::back_footprints_with_front_pads(&data); let live_pads: Vec<(String, String)> = s .items_of(&[PcbObjectTypeCode::new_pad()])? .into_iter()@@ -670,13 +671,18 @@ pub fn routing_state(ctx: &Ctx, args: &Value) -> RResult<Value> { return Err(RoutingError::new("stale_board", "Board changed during connectivity inspection; read again").with("currentRevision", json!(current))); } let remaining: Vec<Value> = nets.iter().filter(|n| n["connected"] == json!(false)).map(|n| n["name"].clone()).collect();- Ok(json!({+ let mut out = json!({ "success": true, "boardPath": s.file_path, "revision": revision, "source": "live-editor", "kicadVersion": s.version.full_version, "socket": s.socket, "pads": pads, "nets": nets, "netsRemaining": remaining, "segments": data.segments, "vias": data.vias, "copperLayers": pcb::copper_layers(&data), "_hint": "Use this revision as expectedRevision in kicad_route_net. Coordinates are mm, +y down. Connectivity is measured by KiCad; kicad_routing_validate checks clearance and unconnected items.",- }))+ });+ if !front_pads.is_empty() {+ out["backFootprintsWithFrontPads"] = json!(front_pads);+ out["_frontPadsHint"] = json!(pcb::FRONT_PADS_HINT);+ }+ Ok(out) } /// `kicad_route_net`: DRC preflight on a snapshot, then one commit of the planned copper.