Commit Graph
3 Commits
Author SHA1 Message Date
rsp2k 33cb196bc8 Add exact planar points and vectors
Ports the point/vector foundation of geometry/planar: Side and Signum
(three-valued signs), Limits, FloatPoint (approximate), and the exact
IntPoint/IntVector plus projective RationalPoint/RationalVector.

Arithmetic model per type is documented in each module. The key
simplification over the Java source: Python's unbounded int makes the
exact orientation determinants and rational (x,y,z) coordinates trivial,
so side_of is kept exact (upstream uses a double for speed) and no
BigInteger or CRIT_INT overflow promotion is needed. Rational points use
the projective triple with z=0 denoting the point at infinity.

Tests cover collinearity, determinants beyond Java long range, rational
equality/reduction, and integer/rational promotion.
2026-07-11 18:01:21 -06:00
rsp2k 12b0a231f0 Implement Specctra SES session-file writer
Ports the write path of io/specctra/SesWriter.java to emit a valid
session from a parsed DsnBoard plus a RoutingResult. Each _write_*
function mirrors a write* method upstream:

- session scope with base_design, placement (resolution + components
  echoed from the DSN), an empty was_is, and routes
- routes carries resolution, a reduced parser scope, library_out with
  the via padstacks, and network_out
- network_out emits (net (wire (path layer width x1 y1 ...)) (via
  padstack x y)) for each routed net; integer coordinates via round-
  half-up to match Java Math.round

write_ses(board) with no result produces a valid no-op session,
proving the DSN-in / SES-out round trip. Only routes > network_out is
required by SesReader and kicad-cli; the rest is echoed for a
well-formed file.

18 tests: indent/quoting rules, no-op session structure, placement and
library_out echo, routed wire/via serialization, integer rounding, and
round-trips re-parsed through the project's own DSN tokenizer/sexp
(64 tests total across the suite, all green; ruff clean).
2026-07-11 16:34:19 -06:00
rsp2k 3bf4f6bed2 Implement Specctra DSN parser with typed board model
Ports the read path of FreeRouting's io/specctra/parser package to a
Java-free Python implementation:

- tokenizer: S-expression lexer mirroring SpecctraFileDescription.flex
  (comments, quoted strings, the string_quote IGNORE_QUOTE directive,
  case-insensitive keywords, and hash-prefixed names)
- sexp: nested S-expression tree builder
- shapes: rect/circle/polygon/path plus area-with-holes scopes
- model: typed dataclasses for layers, padstacks, images, placements,
  nets, net classes, rules, keepouts
- reader: recursive-descent scope readers producing a DsnBoard, one
  _read_* function per FreeRouting read_scope method

46 pytest cases cover the tokenizer, tree, shapes, and end-to-end
parsing against hand-crafted fixtures modeled on FreeRouting's own
test DSN files. Parses 90 of 91 upstream fixtures (the one failure is
a binary OLE file, not text DSN).
2026-07-11 15:21:18 -06:00