app
Adom Library
Public Made by Adomby adom
adom-lbr — the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad ⇄ Altium ⇄ EAGLE/Fusion) through one canonical adom-lbr JSON — symbol + footprint + 3D + pin↔pad 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.
← 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)
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![]);