skidl.schematics.backend module¶
Tool-agnostic schematic backend interface.
This module defines the dependency surface that the tool-agnostic decision
layer (schematics/decisions.py, schematics/snap.py) needs from a
concrete schematic backend (e.g. tools/kicad9). It is deliberately
tool-agnostic: it imports nothing from any skidl.tools.* package, and the
KiCad coordinate convention / S-expression syntax never leaks across this
boundary.
The split is: the agnostic layer decides (which pins overlap, which power
pins form a bus, how labels deconflict), expressed entirely in render-mm
coordinates as returned by backend.pin_render_pos; the backend measures
(geometry queries) and writes (emission primitives).
See ARCHITECTURE-snap-backend-split.md (branch docs/snap-backend-split)
for the full design, especially sections 2, 3, 5 and 7.
- class skidl.schematics.backend.LabelPlacement(anchor_xy: Tuple[float, float], text_xy: Tuple[float, float], deconflictable: bool)[source]¶
Bases:
objectA resolved net-label / power-symbol placement (render-mm).
anchor_xyis the electrical connection point and is FIXED on the pin (in KiCad the label/power-symbolatis the connection point).text_xyis where the label text renders and may be nudged by deconfliction.deconflictableis False for power symbols, whose anchor must not move (moving it disconnects the net).
- class skidl.schematics.backend.RenderContext(backend: SchematicBackend)[source]¶
Bases:
objectMemoizes
pin_render_pos/pin_render_dirfor a backend.Per architecture doc section 7, item 6: the cache key cannot be just
(pin, sheet_tx)because snap mutatespart.txmid-pipeline. The simplest safe discipline (adopted here) is to only use the cache once snap has finalized allpart.txvalues; snap’s own pre-finalization measurements go straight to the backend and are not cached.The key folds in the part’s transform coefficients so that any
part.txmutation invalidates a stale entry automatically.
- class skidl.schematics.backend.SchematicBackend(*args, **kwargs)[source]¶
Bases:
ProtocolThe geometry + emission surface a backend exposes to the agnostic layer.
Geometry queries answer “where/which-way does the tool draw this?” in the tool’s own flip/mirror/rotate convention. Emission primitives write the tool’s native elements. See the architecture doc, section 3.
- label_bbox(text: str) Tuple[float, float][source]¶
(width, height) in mm of a rendered net-label box for
text.
- pin_render_pos(pin, sheet_tx) Tuple[float, float][source]¶
(x, y) in mm where the tool will actually DRAW this pin.
- render_xy(lx, ly, part, sheet_tx) Tuple[float, float][source]¶
Render-mm position of an arbitrary part-local point (e.g. a body bbox corner) under the tool’s transform convention. Same convention as
pin_render_posbut for non-pin points; needed by power-bus body-crossing checks.
