← Commit history

2.44.0: generate carries the KiCad polyline stroke into the .lbr; <= 0.2 mm art strokes become 0.0254 mm hairline wires so the chip outline renders crisp in Fusion (John, 2026-09-19)

John Lauer ·efe995d0bc ·1mo ago ·parent c8c6607
5 files changed +34−9
Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "adom-lbr"-version = "2.43.0"+version = "2.44.0" edition = "2021" description = "adom-lbr generator / EDA translator: the canonical adom-lbr JSON is the hub, with native converters to Altium (.SchLib/.PcbLib/.IntLib), EAGLE/Fusion (.lbr), and KiCad. Altium output is written natively — no Altium needed at conversion time." 
SKILL.md+8
@@ -54,6 +54,14 @@ keeps one footprint PER PART even when land patterns match, so each part carries own STEP body and its symbol links its own footprint name (the ToF trio VL53L5CX / L7CX / L8CX share a pattern but not a body). +**Fusion/EAGLE symbols, same rule (2.44.0).** `generate` carries each `.kicad_sym` polyline's+stroke width into the `.lbr`: a stroke at or under 0.2 mm (the chip-thumbnailer outline is+0.167 mm) becomes a 0.0254 mm hairline wire, which Fusion draws one pixel wide at any zoom;+wider hand-drawn strokes keep their width. Before 2.44.0 every symbol wire was a flat+0.1524 mm and the outline read as a fat smeared stroke in Fusion (John, 2026-09-19).+`--part-metadata page.json` (the wiki component page) adds the MPN / MANUFACTURER /+distributor attributes a BOM needs; pass it every time, the ToF pages shipped without them once.+ **What carries across (both ways):** symbol pins + body graphics; footprint pads; **footprint silk / courtyard / fab graphics with their layers**; the pin↔pad map; the footprint link. Value/Manufacturer/MPN/Package become Altium component
VERSION+1−1
@@ -1 +1 @@-2.43.0+2.44.0
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-lbr",-  "version": "2.43.0",+  "version": "2.44.0",   "type": "app",   "description": "adom-lbr \u2014 the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad \u21c4 Altium \u21c4 EAGLE/Fusion) through one canonical adom-lbr JSON \u2014 symbol + footprint + 3D + pin\u2194pad map. Altium is written natively (no Altium needed). Includes the adom-lbr Manager: browse wiki components and view symbol/footprint/3D + the per-EDA layer stackup.",   "dependencies": {},
src/main.rs+23−6
@@ -500,11 +500,13 @@ pub(crate) fn parse_kicad_sym(content: &str, name_override: Option<&str>) -> Res         });     }     let xy_re = regex_lite::Regex::new(r#"\(xy\s+(-?[\d.]+)\s+(-?[\d.]+)\)"#).unwrap();+    let stroke_re = regex_lite::Regex::new(r#"\(stroke\s*\(width\s+(-?[\d.]+)\)"#).unwrap();     for b in sexpr_blocks(content, "polyline") {         let pts: Vec<(f64, f64)> = xy_re.captures_iter(b)             .map(|c| (c[1].parse().unwrap_or(0.0), c[2].parse().unwrap_or(0.0)))             .collect();-        if pts.len() >= 2 { graphics.push(SymGraphic::Poly(pts)); }+        let w = stroke_re.captures(b).and_then(|c| c[1].parse::<f64>().ok()).unwrap_or(0.0);+        if pts.len() >= 2 { graphics.push(SymGraphic::Poly(pts, w)); }     }     let arc_re = regex_lite::Regex::new(         r#"(?s)\(start\s+(-?[\d.]+)\s+(-?[\d.]+)\).*?\(mid\s+(-?[\d.]+)\s+(-?[\d.]+)\).*?\(end\s+(-?[\d.]+)\s+(-?[\d.]+)\)"#@@ -1095,13 +1097,27 @@ fn synth_symbol_from_mod(km: &str, name: &str) -> ParsedSymbol { /// Y-up — same as the pins, so it carries through to EAGLE without a Y-flip). #[derive(Debug, Serialize, Deserialize)] enum SymGraphic {-    Poly(Vec<(f64, f64)>),+    /// Polyline points plus the source stroke width in mm (0 when the symbol did not say).+    Poly(Vec<(f64, f64)>, f64),     Arc { start: (f64, f64), mid: (f64, f64), end: (f64, f64) },     /// A `(rectangle …)` that is NOT the body box (the first one is the body).     Rect { x1: f64, y1: f64, x2: f64, y2: f64 },     Circle { cx: f64, cy: f64, r: f64 }, } +/// EAGLE/Fusion wire width for a symbol polyline from its KiCad stroke (mm). Fusion draws+/// a wire at its true width, so the chip-thumbnailer outline (0.167 mm in the .kicad_sym,+/// written as a flat 0.1524 before 2.44.0) came out as a fat smeared stroke on a symbol a+/// few mm across. John, 2026-09-19, after the same fix on the Altium lane: "make the stroke+/// on the chip-thumbnail outlines really thin as well". Anything at or under 0.2 mm is+/// art and becomes a 0.0254 mm (1 mil) line, which every renderer clamps to one pixel;+/// wider strokes (hand-drawn symbol graphics) keep their width; 0 (unspecified) keeps the+/// old 0.1524.+fn eagle_symbol_wire_width(src_mm: f64) -> f64 {+    if src_mm <= 0.0 { 0.1524 } else if src_mm <= 0.2 { 0.0254 } else { src_mm }+}++ /// One SMD/thru-hole pad parsed from a `.kicad_mod`, in KiCad coordinates /// (millimetres, Y-down). `drill` is `Some` only for thru-hole pads. struct ModPad {@@ -1971,9 +1987,10 @@ fn emit_symbol_block(xml: &mut String, sym: &ParsedSymbol, symbol_art: Option<&S     } else {         for g in &sym.graphics {             match g {-                SymGraphic::Poly(pts) => {+                SymGraphic::Poly(pts, src_w) => {+                    let ww = eagle_symbol_wire_width(*src_w);                     for w in pts.windows(2) {-                        xml.push_str(&format!("  <wire x1=\"{:.4}\" y1=\"{:.4}\" x2=\"{:.4}\" y2=\"{:.4}\" width=\"0.1524\" layer=\"94\"/>\n", w[0].0, w[0].1, w[1].0, w[1].1));+                        xml.push_str(&format!("  <wire x1=\"{:.4}\" y1=\"{:.4}\" x2=\"{:.4}\" y2=\"{:.4}\" width=\"{:.4}\" layer=\"94\"/>\n", w[0].0, w[0].1, w[1].0, w[1].1, ww));                     }                 }                 SymGraphic::Arc { start, mid, end } => {@@ -4585,11 +4602,11 @@ mod lint_tests {             ref_pos: None, val_pos: None,         };         // with its own drawing (the capacitor's two plates) it must be LEFT ALONE-        let mut drawn = mk(vec![SymGraphic::Poly(vec![(-2.032, 0.762), (2.032, 0.762)])]);+        let mut drawn = mk(vec![SymGraphic::Poly(vec![(-2.032, 0.762), (2.032, 0.762)], 0.0)]);         assert!(!relayout_two_columns(&mut drawn, false));         assert_eq!(drawn.pins[0].y, 3.81, "pins must not move");         // ...but forcing it is still allowed for a caller who means it-        let mut forced = mk(vec![SymGraphic::Poly(vec![(-2.032, 0.762), (2.032, 0.762)])]);+        let mut forced = mk(vec![SymGraphic::Poly(vec![(-2.032, 0.762), (2.032, 0.762)], 0.0)]);         assert!(relayout_two_columns(&mut forced, true));         // and a symbol with NO artwork of its own still gets the EE-convention relayout         let mut plain = mk(vec![]);