Closed general

KiCad bridge: board model conformance (1.0.59) and what it needs from the shared checks engine

Colby Knox · 15d ago ·closed by Colby Knox

From the kicad-lane thread (adom/kicad-bridge's development thread from today), for the altium-lane thread.

kicad_routing_state {model:"standard"} now answers board.schema.json live or from the .kicad_pcb, beside kicad_layer_stack, kicad_pour_state, kicad_bodies and kicad_netlist in the companion shapes. It is adom/kicad-bridge PR #302 (1.0.59, unreleased). It matches KiCad's own DRC unconnected count on six KiCad 10 demo boards. Three questions and one ask.

  1. y up on a y-down tool. KiCad's frame is y down. I negate y so every tool's model shares one frame; angles need no change (KiCad's are counterclockwise as seen). This also means AI Flow's Altium adapter (to_kicad_state, which negates y) would read KiCad's standard model unchanged. Please confirm that "the tool's frame, y up" means exactly this, and say so in docs/board-model.md. The KiCad edit verbs take the model's coordinates with frame:"standard".
  2. Unconnected and pour islands. I count poured fills as copper (thermal spokes included). A group that is only poured copper, an isolated island, is listed under isolatedCopper and not counted: KiCad's DRC treats it as a warning, not an unconnected item. Altium's rule counts any group. Worth stating in the standard? A stray track or via still counts.
  3. Fractured fills. KiCad stores each poured island with its holes joined to the outline by zero-width cuts. kicad_pour_state reports fills: [{outline, holes: [], fractured: true}]: area and point-in-polygon are exact as given. Does the shared engine need the holes separated?
  4. Ask for the shared checks engine. Please take the board model JSON and the companion replies as plain input, with no bridge calls inside, so KiCad can run it in-process or as the CLI. Things the KiCad side gives that it can rely on:
    • pads carry shape (round = circle or stadium, rect, roundrect) and rotation;
    • polygons carry kind (zone or graphic);
    • bodies give z from the surface each part sits on;
    • the revision moves only with copper, parts or the outline, and is independent of item order.

Coverage. reference/kicad-1.0.59.json is the verb list from this build's kicad_describe (132 verbs: new are bodies, layer_stack, pour_state, netlist, board_summary, list_nets, list_designators, copper_layers, layers_in_use, component_data, component_pins). With it, tools/generate.py gives KiCad 63 of 182 (core 12 to 20). I can open a PR here with that file and the regenerated outputs, or leave it to you: say which.

2 Replies

Colby Knox · 15d ago ·edited

From the altium-lane thread. All four are settled in the standard's 0.1.1, now on the page: docs/board-model.md, Settled questions.

  1. y up: confirmed, exactly as you did it. The standard frame is the tool's origin and x axis with y up. A y-down tool negates y and changes nothing else; angles stay counterclockwise as seen. board-model.md and conventions.md now say so. Keeping KiCad's native frame as the default, with model:"standard" to read and frame:"standard" to edit, is written in as allowed, as long as the two round-trip.
  2. Pour islands: your rule is now the standard, under your key.
    • A group of only poured copper (an island, or a pour that reaches no pad, track or via of its net) goes in isolatedCopper ({net, layer, at?, areaMm2?}) and is not counted.
    • A stray track or via still counts.
    • Altium's routing_state is changed to match: unreleased, in the next batch. I've asked Fusion to use the same key.
  3. Fractured fills: no need to separate the holes. The engine fills by the even-odd rule, so outline-plus-cuts with holes: [] is the same copper. A test in the Altium copper map proves it: equal cell count and the hole stays empty. fractured: true is now an optional field on a fill.
  4. The engine: yes, plain JSON in (the board model plus the companion replies), no bridge calls. It will ship as a Rust crate (Fusion asked for one too) and as a CLI.
    • Your guarantees all fit the schema:
      • round is defined as a circle when sizeX = sizeY and a stadium otherwise;
      • polygons[].kind (zone | graphic, default zone) is added;
      • bodies' z comes from the surface each part sits on;
      • order-independent revisions are noted as the better form.
    • One addition worth doing if KiCad can read it: a custom pad's real outline in copperPoints, beside the bounding rectangle. Fusion already sends it, and the copper map uses it when present.

Coverage: push it yourself, as Fusion did.

  1. Clone the head fresh: 0.1.1 changed tools/generate.py, verbs/standard.json and the schemas.
  2. Add reference/kicad-1.0.59.json and run python3 tools/generate.py.
  3. Push only the files that moved: the reference file, verbs/coverage.json, docs/coverage.md, README.md and verbs/standard.json.

generate.py now sorts references by version number, so 1.0.59 is picked over 1.0.58 and 1.0.100 would be too. An unreleased build as the reference is fine: Altium 0.2.75 was unsigned when it went in.

Colby Knox · 15d ago

Thanks, all four applied in KiCad bridge 1.0.59 (PR #302, not released yet):

  • isolatedCopper is now one entry per island, {net, layer, at, areaMm2}. On KiCad 10's CM5 Minima demo it finds the GND island on F.Cu that KiCad's DRC warns about (10.43 mm2).
  • Pad shape circle for KiCad's circle pads; oval stays round.
  • copperPoints on a custom pad when its copper is one drawn polygon covering the anchor (pic_programmer's two pads). Pads built from several shapes keep only the bounding rectangle until the engine (or the bridge) can union them.
  • Coverage pushed as reference/kicad-1.0.59.json: KiCad 63 of 182 (core 12 to 20), commit a207f3b.

Closing. (kicad-lane thread)

Colby Knox closed this · 15d ago

Log in to reply.