circuit-json-to-kicad 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +9 -0
- package/dist/index.js +116 -8
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,13 @@ import { CircuitJsonUtilObjects, cju } from '@tscircuit/circuit-json-util';
|
|
|
3
3
|
import { KicadSch, KicadPcb } from 'kicadts';
|
|
4
4
|
import { Matrix } from 'transformation-matrix';
|
|
5
5
|
|
|
6
|
+
type PaperSize = "A0" | "A1" | "A2" | "A3" | "A4" | "A5";
|
|
7
|
+
interface PaperDimensions {
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
name: PaperSize;
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
type SchematicPortId = string;
|
|
7
14
|
type SchematicTraceId = string;
|
|
8
15
|
type PcbPortId = string;
|
|
@@ -15,6 +22,8 @@ interface ConverterContext {
|
|
|
15
22
|
c2kMatSch?: Matrix;
|
|
16
23
|
/** Circuit JSON to KiCad PCB transformation matrix */
|
|
17
24
|
c2kMatPcb?: Matrix;
|
|
25
|
+
/** Selected paper size for schematic */
|
|
26
|
+
schematicPaperSize?: PaperDimensions;
|
|
18
27
|
pinPositions?: Map<SchematicPortId, {
|
|
19
28
|
x: number;
|
|
20
29
|
y: number;
|
package/dist/index.js
CHANGED
|
@@ -38,13 +38,13 @@ import { compose, translate, scale } from "transformation-matrix";
|
|
|
38
38
|
import { Paper, Uuid } from "kicadts";
|
|
39
39
|
var InitializeSchematicStage = class extends ConverterStage {
|
|
40
40
|
_step() {
|
|
41
|
-
const { kicadSch } = this.ctx;
|
|
41
|
+
const { kicadSch, schematicPaperSize } = this.ctx;
|
|
42
42
|
if (!kicadSch) {
|
|
43
43
|
throw new Error("KicadSch instance not initialized in context");
|
|
44
44
|
}
|
|
45
45
|
kicadSch.version = 20250114;
|
|
46
46
|
const paper = new Paper();
|
|
47
|
-
paper.size = "A4";
|
|
47
|
+
paper.size = schematicPaperSize?.name ?? "A4";
|
|
48
48
|
kicadSch.paper = paper;
|
|
49
49
|
kicadSch.uuid = new Uuid(crypto.randomUUID());
|
|
50
50
|
this.finished = true;
|
|
@@ -1184,6 +1184,26 @@ function getSchematicBoundsAndCenter(db) {
|
|
|
1184
1184
|
};
|
|
1185
1185
|
}
|
|
1186
1186
|
|
|
1187
|
+
// lib/schematic/selectSchematicPaperSize.ts
|
|
1188
|
+
var PAPER_SIZES = [
|
|
1189
|
+
{ name: "A4", width: 297, height: 210 },
|
|
1190
|
+
{ name: "A3", width: 420, height: 297 },
|
|
1191
|
+
{ name: "A2", width: 594, height: 420 },
|
|
1192
|
+
{ name: "A1", width: 841, height: 594 },
|
|
1193
|
+
{ name: "A0", width: 1189, height: 841 }
|
|
1194
|
+
];
|
|
1195
|
+
function selectSchematicPaperSize(contentWidth, contentHeight, paddingMm = 20) {
|
|
1196
|
+
const requiredWidth = contentWidth + 2 * paddingMm;
|
|
1197
|
+
const requiredHeight = contentHeight + 2 * paddingMm;
|
|
1198
|
+
for (let i = 0; i < PAPER_SIZES.length; i++) {
|
|
1199
|
+
const paperSize = PAPER_SIZES[i];
|
|
1200
|
+
if (requiredWidth <= paperSize.width && requiredHeight <= paperSize.height) {
|
|
1201
|
+
return paperSize;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
return PAPER_SIZES[PAPER_SIZES.length - 1];
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1187
1207
|
// lib/schematic/CircuitJsonToKicadSchConverter.ts
|
|
1188
1208
|
var CircuitJsonToKicadSchConverter = class {
|
|
1189
1209
|
ctx;
|
|
@@ -1195,10 +1215,16 @@ var CircuitJsonToKicadSchConverter = class {
|
|
|
1195
1215
|
}
|
|
1196
1216
|
constructor(circuitJson) {
|
|
1197
1217
|
const CIRCUIT_JSON_SCALE_FACTOR = 15;
|
|
1198
|
-
const KICAD_CENTER_Y = 105;
|
|
1199
|
-
const KICAD_CENTER_X = 148.5;
|
|
1200
1218
|
const db = cju(circuitJson);
|
|
1201
|
-
const { center } = getSchematicBoundsAndCenter(db);
|
|
1219
|
+
const { center, bounds } = getSchematicBoundsAndCenter(db);
|
|
1220
|
+
const schematicWidthMm = (bounds.maxX - bounds.minX) * CIRCUIT_JSON_SCALE_FACTOR;
|
|
1221
|
+
const schematicHeightMm = (bounds.maxY - bounds.minY) * CIRCUIT_JSON_SCALE_FACTOR;
|
|
1222
|
+
const paperSize = selectSchematicPaperSize(
|
|
1223
|
+
schematicWidthMm,
|
|
1224
|
+
schematicHeightMm
|
|
1225
|
+
);
|
|
1226
|
+
const KICAD_CENTER_X = paperSize.width / 2;
|
|
1227
|
+
const KICAD_CENTER_Y = paperSize.height / 2;
|
|
1202
1228
|
this.ctx = {
|
|
1203
1229
|
db,
|
|
1204
1230
|
circuitJson,
|
|
@@ -1206,6 +1232,7 @@ var CircuitJsonToKicadSchConverter = class {
|
|
|
1206
1232
|
generator: "circuit-json-to-kicad",
|
|
1207
1233
|
generatorVersion: "0.0.1"
|
|
1208
1234
|
}),
|
|
1235
|
+
schematicPaperSize: paperSize,
|
|
1209
1236
|
c2kMatSch: compose(
|
|
1210
1237
|
translate(KICAD_CENTER_X, KICAD_CENTER_Y),
|
|
1211
1238
|
scale(CIRCUIT_JSON_SCALE_FACTOR, -CIRCUIT_JSON_SCALE_FACTOR),
|
|
@@ -1812,7 +1839,76 @@ var AddViasStage = class extends ConverterStage {
|
|
|
1812
1839
|
|
|
1813
1840
|
// lib/pcb/stages/AddGraphicsStage.ts
|
|
1814
1841
|
import { GrLine } from "kicadts";
|
|
1842
|
+
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
1843
|
+
|
|
1844
|
+
// lib/pcb/stages/utils/CreateGrTextFromCircuitJson.ts
|
|
1845
|
+
import {
|
|
1846
|
+
GrText,
|
|
1847
|
+
TextEffects as TextEffects5,
|
|
1848
|
+
TextEffectsFont as TextEffectsFont5,
|
|
1849
|
+
TextEffectsJustify as TextEffectsJustify3,
|
|
1850
|
+
At
|
|
1851
|
+
} from "kicadts";
|
|
1815
1852
|
import { applyToPoint as applyToPoint12 } from "transformation-matrix";
|
|
1853
|
+
function createGrTextFromCircuitJson({
|
|
1854
|
+
textElement,
|
|
1855
|
+
c2kMatPcb
|
|
1856
|
+
}) {
|
|
1857
|
+
if (!textElement.text || !textElement.anchor_position) {
|
|
1858
|
+
return null;
|
|
1859
|
+
}
|
|
1860
|
+
const transformedPos = applyToPoint12(c2kMatPcb, {
|
|
1861
|
+
x: textElement.anchor_position.x,
|
|
1862
|
+
y: textElement.anchor_position.y
|
|
1863
|
+
});
|
|
1864
|
+
const layerMap = {
|
|
1865
|
+
top: "F.SilkS",
|
|
1866
|
+
bottom: "B.SilkS"
|
|
1867
|
+
};
|
|
1868
|
+
const kicadLayer = layerMap[textElement.layer] || textElement.layer || "F.SilkS";
|
|
1869
|
+
const fontSize = (textElement.font_size || 1) / 1.5;
|
|
1870
|
+
const font = new TextEffectsFont5();
|
|
1871
|
+
font.size = { width: fontSize, height: fontSize };
|
|
1872
|
+
const justify = new TextEffectsJustify3();
|
|
1873
|
+
const anchorAlignment = textElement.anchor_alignment || "center";
|
|
1874
|
+
switch (anchorAlignment) {
|
|
1875
|
+
case "top_left":
|
|
1876
|
+
justify.horizontal = "left";
|
|
1877
|
+
justify.vertical = "top";
|
|
1878
|
+
break;
|
|
1879
|
+
case "top_right":
|
|
1880
|
+
justify.horizontal = "right";
|
|
1881
|
+
justify.vertical = "top";
|
|
1882
|
+
break;
|
|
1883
|
+
case "bottom_left":
|
|
1884
|
+
justify.horizontal = "left";
|
|
1885
|
+
justify.vertical = "bottom";
|
|
1886
|
+
break;
|
|
1887
|
+
case "bottom_right":
|
|
1888
|
+
justify.horizontal = "right";
|
|
1889
|
+
justify.vertical = "bottom";
|
|
1890
|
+
break;
|
|
1891
|
+
case "center":
|
|
1892
|
+
break;
|
|
1893
|
+
}
|
|
1894
|
+
const textEffects = new TextEffects5({
|
|
1895
|
+
font
|
|
1896
|
+
});
|
|
1897
|
+
if (anchorAlignment !== "center") {
|
|
1898
|
+
textEffects.justify = justify;
|
|
1899
|
+
}
|
|
1900
|
+
const rotation = textElement.ccw_rotation || 0;
|
|
1901
|
+
const position = new At([transformedPos.x, transformedPos.y, rotation]);
|
|
1902
|
+
const grText = new GrText({
|
|
1903
|
+
text: textElement.text,
|
|
1904
|
+
layer: kicadLayer,
|
|
1905
|
+
effects: textEffects
|
|
1906
|
+
});
|
|
1907
|
+
grText.position = position;
|
|
1908
|
+
return grText;
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
// lib/pcb/stages/AddGraphicsStage.ts
|
|
1816
1912
|
var AddGraphicsStage = class extends ConverterStage {
|
|
1817
1913
|
_step() {
|
|
1818
1914
|
const { kicadPcb, c2kMatPcb } = this.ctx;
|
|
@@ -1829,11 +1925,11 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
1829
1925
|
const startPoint = path.route[i];
|
|
1830
1926
|
const endPoint = path.route[i + 1];
|
|
1831
1927
|
if (!startPoint || !endPoint) continue;
|
|
1832
|
-
const transformedStart =
|
|
1928
|
+
const transformedStart = applyToPoint13(c2kMatPcb, {
|
|
1833
1929
|
x: startPoint.x,
|
|
1834
1930
|
y: startPoint.y
|
|
1835
1931
|
});
|
|
1836
|
-
const transformedEnd =
|
|
1932
|
+
const transformedEnd = applyToPoint13(c2kMatPcb, {
|
|
1837
1933
|
x: endPoint.x,
|
|
1838
1934
|
y: endPoint.y
|
|
1839
1935
|
});
|
|
@@ -1853,6 +1949,18 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
1853
1949
|
kicadPcb.graphicLines = graphicLines;
|
|
1854
1950
|
}
|
|
1855
1951
|
}
|
|
1952
|
+
const standaloneSilkscreenTexts = this.ctx.db.pcb_silkscreen_text?.list().filter((text) => !text.pcb_component_id) || [];
|
|
1953
|
+
for (const textElement of standaloneSilkscreenTexts) {
|
|
1954
|
+
const grText = createGrTextFromCircuitJson({
|
|
1955
|
+
textElement,
|
|
1956
|
+
c2kMatPcb
|
|
1957
|
+
});
|
|
1958
|
+
if (grText) {
|
|
1959
|
+
const graphicTexts = kicadPcb.graphicTexts;
|
|
1960
|
+
graphicTexts.push(grText);
|
|
1961
|
+
kicadPcb.graphicTexts = graphicTexts;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1856
1964
|
const pcbBoards = this.ctx.db.pcb_board?.list() || [];
|
|
1857
1965
|
if (pcbBoards.length > 0) {
|
|
1858
1966
|
const board = pcbBoards[0];
|
|
@@ -1874,7 +1982,7 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
1874
1982
|
];
|
|
1875
1983
|
}
|
|
1876
1984
|
const transformedCorners = corners.map(
|
|
1877
|
-
(corner) =>
|
|
1985
|
+
(corner) => applyToPoint13(c2kMatPcb, corner)
|
|
1878
1986
|
);
|
|
1879
1987
|
for (let i = 0; i < transformedCorners.length; i++) {
|
|
1880
1988
|
const start = transformedCorners[i];
|