app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Drive your own KiCad from an AI, in the background: open every editor, read the whole board as data (the EDA Bridge Standard board model), stack-up, part heights, netlists, place, route, pour, DRC and exports.
master
Colby Knox
Fix #133 (outline box from arcs and circles; ring courtyards: 2-degree sampling, interior probes), #130 (KICAD10_3RD_PA…
f7d1e2b
15d ago
//! Wiki #133: concentric ring courtyards (two F.CrtYd circles each, an annulus) do not overlap, and a
//! board edge drawn as one large arc bounds the outline by its real extent.
use kicad_core::{pcb, placement};
fn ring(reference: &str, d_in: f64, d_out: f64) -> String {
format!("(footprint \"x:{reference}\" (layer \"F.Cu\") (at 100 100) (property \"Reference\" \"{reference}\")\
(fp_circle (center 0 0) (end {} 0) (layer \"F.CrtYd\") (stroke (width 0.05)))\
(fp_circle (center 0 0) (end {} 0) (layer \"F.CrtYd\") (stroke (width 0.05))))", d_in / 2.0, d_out / 2.0)
}
#[test]
fn nested_ring_courtyards_do_not_overlap() {
// the sensor from the report: electrodes and guards, all on one centre
let fps = [ring("E2", 23.0, 31.95), ring("G2", 43.8, 47.7), ring("E4", 48.0, 56.95), ring("G3", 57.25, 59.25)].concat();
let text = format!("(kicad_pcb (version 20241229) (layers (0 \"F.Cu\" signal)) {fps})");
let board = pcb::parse_pcb_text(&text, "t.kicad_pcb").unwrap();
let o = placement::overlaps(&placement::placements(&board));
assert!(o.is_empty(), "{o:?}");
}
#[test]
fn a_large_edge_arc_bounds_the_outline_by_its_bulge() {
// a 146 mm ring edge drawn as one arc of about 340 degrees: start and end low, mid at the top
let r = 73.0_f64;
let (cx, cy) = (100.0, 110.0);
let a = |deg: f64| (cx + r * deg.to_radians().cos(), cy + r * deg.to_radians().sin());
let (s, e, m) = (a(100.0), a(80.0), a(270.0));
let text = format!("(kicad_pcb (version 20241229) (layers (0 \"F.Cu\" signal) (25 \"Edge.Cuts\" user))\
(gr_arc (start {} {}) (mid {} {}) (end {} {}) (layer \"Edge.Cuts\") (stroke (width 0.1)))\
(gr_line (start {} {}) (end {} {}) (layer \"Edge.Cuts\") (stroke (width 0.1)))\
(gr_circle (center {cx} {cy}) (end {} {cy}) (layer \"Edge.Cuts\") (stroke (width 0.1))))",
s.0, s.1, m.0, m.1, e.0, e.1, e.0, e.1, s.0, s.1, cx + 22.5);
let board = pcb::parse_pcb_text(&text, "t.kicad_pcb").unwrap();
let o = placement::outline(&board).unwrap();
assert!((o.min_x - (cx - r)).abs() < 0.01 && (o.max_x - (cx + r)).abs() < 0.01, "{o:?}");
assert!((o.min_y - (cy - r)).abs() < 0.01, "{o:?}");
}