circuit-json-to-kicad 0.0.23 → 0.0.25
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.js +123 -41
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -399,14 +399,14 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
|
|
|
399
399
|
*/
|
|
400
400
|
createPolylineFromPoints({
|
|
401
401
|
points,
|
|
402
|
-
scale:
|
|
402
|
+
scale: scale4,
|
|
403
403
|
center,
|
|
404
404
|
fillType
|
|
405
405
|
}) {
|
|
406
406
|
const polyline = new SymbolPolyline();
|
|
407
407
|
const cx = center?.x ?? 0;
|
|
408
408
|
const cy = center?.y ?? 0;
|
|
409
|
-
const scaleMatrix = createScaleMatrix(
|
|
409
|
+
const scaleMatrix = createScaleMatrix(scale4, scale4);
|
|
410
410
|
const xyPoints = points.map((p) => {
|
|
411
411
|
const translated = applyToPoint(scaleMatrix, { x: p.x - cx, y: p.y - cy });
|
|
412
412
|
return new Xy(translated.x, translated.y);
|
|
@@ -1277,7 +1277,7 @@ var CircuitJsonToKicadSchConverter = class {
|
|
|
1277
1277
|
// lib/pcb/CircuitJsonToKicadPcbConverter.ts
|
|
1278
1278
|
import { KicadPcb } from "kicadts";
|
|
1279
1279
|
import { cju as cju2 } from "@tscircuit/circuit-json-util";
|
|
1280
|
-
import { compose as
|
|
1280
|
+
import { compose as compose3, translate as translate3, scale as scale3 } from "transformation-matrix";
|
|
1281
1281
|
|
|
1282
1282
|
// lib/pcb/stages/InitializePcbStage.ts
|
|
1283
1283
|
import {
|
|
@@ -1380,38 +1380,93 @@ import { Footprint } from "kicadts";
|
|
|
1380
1380
|
import { applyToPoint as applyToPoint9 } from "transformation-matrix";
|
|
1381
1381
|
|
|
1382
1382
|
// lib/pcb/stages/utils/CreateSmdPadFromCircuitJson.ts
|
|
1383
|
-
import {
|
|
1384
|
-
|
|
1383
|
+
import {
|
|
1384
|
+
FootprintPad,
|
|
1385
|
+
PadPrimitives,
|
|
1386
|
+
PadPrimitiveGrPoly,
|
|
1387
|
+
Pts as Pts3,
|
|
1388
|
+
Xy as Xy3,
|
|
1389
|
+
PadOptions
|
|
1390
|
+
} from "kicadts";
|
|
1391
|
+
import {
|
|
1392
|
+
applyToPoint as applyToPoint5,
|
|
1393
|
+
compose as compose2,
|
|
1394
|
+
translate as translate2,
|
|
1395
|
+
scale as scale2,
|
|
1396
|
+
rotate
|
|
1397
|
+
} from "transformation-matrix";
|
|
1385
1398
|
function createSmdPadFromCircuitJson({
|
|
1386
1399
|
pcbPad,
|
|
1387
1400
|
componentCenter,
|
|
1388
1401
|
padNumber,
|
|
1389
1402
|
componentRotation = 0
|
|
1390
1403
|
}) {
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
x
|
|
1399
|
-
y
|
|
1404
|
+
let padX;
|
|
1405
|
+
let padY;
|
|
1406
|
+
if ("x" in pcbPad && "y" in pcbPad) {
|
|
1407
|
+
padX = pcbPad.x;
|
|
1408
|
+
padY = pcbPad.y;
|
|
1409
|
+
} else if ("points" in pcbPad && Array.isArray(pcbPad.points)) {
|
|
1410
|
+
const points = pcbPad.points;
|
|
1411
|
+
padX = points.reduce((sum, p) => sum + p.x, 0) / points.length;
|
|
1412
|
+
padY = points.reduce((sum, p) => sum + p.y, 0) / points.length;
|
|
1413
|
+
} else {
|
|
1414
|
+
throw new Error("Pad must have either x/y coordinates or points array");
|
|
1415
|
+
}
|
|
1416
|
+
const cj2kicadMatrix = compose2(
|
|
1417
|
+
componentRotation !== 0 ? rotate(componentRotation * Math.PI / 180) : { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 },
|
|
1418
|
+
scale2(1, -1),
|
|
1419
|
+
// Flip Y-axis
|
|
1420
|
+
translate2(-componentCenter.x, -componentCenter.y)
|
|
1421
|
+
);
|
|
1422
|
+
const rotatedPos = applyToPoint5(cj2kicadMatrix, {
|
|
1423
|
+
x: padX,
|
|
1424
|
+
y: padY
|
|
1400
1425
|
});
|
|
1401
1426
|
const layerMap = {
|
|
1402
1427
|
top: "F.Cu",
|
|
1403
1428
|
bottom: "B.Cu"
|
|
1404
1429
|
};
|
|
1405
1430
|
const padLayer = layerMap[pcbPad.layer] || "F.Cu";
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
"
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1431
|
+
let padShape;
|
|
1432
|
+
let padSize;
|
|
1433
|
+
let padOptions;
|
|
1434
|
+
let padPrimitives;
|
|
1435
|
+
if (pcbPad.shape === "circle") {
|
|
1436
|
+
padShape = "circle";
|
|
1437
|
+
padSize = [
|
|
1438
|
+
"radius" in pcbPad ? pcbPad.radius * 2 : 0.5,
|
|
1439
|
+
"radius" in pcbPad ? pcbPad.radius * 2 : 0.5
|
|
1440
|
+
];
|
|
1441
|
+
} else if (pcbPad.shape === "polygon" && "points" in pcbPad) {
|
|
1442
|
+
const points = pcbPad.points;
|
|
1443
|
+
const pointTransformMatrix = compose2(
|
|
1444
|
+
scale2(1, -1),
|
|
1445
|
+
// Flip Y-axis
|
|
1446
|
+
translate2(-padX, -padY)
|
|
1447
|
+
);
|
|
1448
|
+
const relativePoints = points.map((p) => {
|
|
1449
|
+
const transformed = applyToPoint5(pointTransformMatrix, { x: p.x, y: p.y });
|
|
1450
|
+
return new Xy3(transformed.x, transformed.y);
|
|
1451
|
+
});
|
|
1452
|
+
const grPoly = new PadPrimitiveGrPoly();
|
|
1453
|
+
grPoly.contours = [new Pts3(relativePoints)];
|
|
1454
|
+
grPoly.width = 0;
|
|
1455
|
+
grPoly.filled = true;
|
|
1456
|
+
padPrimitives = new PadPrimitives();
|
|
1457
|
+
padPrimitives.addGraphic(grPoly);
|
|
1458
|
+
padShape = "custom";
|
|
1459
|
+
padOptions = new PadOptions();
|
|
1460
|
+
padOptions.anchor = "circle";
|
|
1461
|
+
padSize = [0.2, 0.2];
|
|
1462
|
+
} else {
|
|
1463
|
+
padShape = "rect";
|
|
1464
|
+
padSize = [
|
|
1465
|
+
"width" in pcbPad ? pcbPad.width : 0.5,
|
|
1466
|
+
"height" in pcbPad ? pcbPad.height : 0.5
|
|
1467
|
+
];
|
|
1468
|
+
}
|
|
1469
|
+
const pad = new FootprintPad({
|
|
1415
1470
|
number: String(padNumber),
|
|
1416
1471
|
padType: "smd",
|
|
1417
1472
|
shape: padShape,
|
|
@@ -1424,11 +1479,18 @@ function createSmdPadFromCircuitJson({
|
|
|
1424
1479
|
],
|
|
1425
1480
|
uuid: crypto.randomUUID()
|
|
1426
1481
|
});
|
|
1482
|
+
if (padOptions) {
|
|
1483
|
+
pad.options = padOptions;
|
|
1484
|
+
}
|
|
1485
|
+
if (padPrimitives) {
|
|
1486
|
+
pad.primitives = padPrimitives;
|
|
1487
|
+
}
|
|
1488
|
+
return pad;
|
|
1427
1489
|
}
|
|
1428
1490
|
|
|
1429
1491
|
// lib/pcb/stages/utils/CreateThruHolePadFromCircuitJson.ts
|
|
1430
1492
|
import { FootprintPad as FootprintPad2, PadDrill } from "kicadts";
|
|
1431
|
-
import { applyToPoint as applyToPoint6, rotate as rotate2, identity
|
|
1493
|
+
import { applyToPoint as applyToPoint6, rotate as rotate2, identity } from "transformation-matrix";
|
|
1432
1494
|
function createThruHolePadFromCircuitJson({
|
|
1433
1495
|
platedHole,
|
|
1434
1496
|
componentCenter,
|
|
@@ -1440,7 +1502,7 @@ function createThruHolePadFromCircuitJson({
|
|
|
1440
1502
|
}
|
|
1441
1503
|
const relativeX = platedHole.x - componentCenter.x;
|
|
1442
1504
|
const relativeY = -(platedHole.y - componentCenter.y);
|
|
1443
|
-
const rotationMatrix = componentRotation !== 0 ? rotate2(componentRotation * Math.PI / 180) :
|
|
1505
|
+
const rotationMatrix = componentRotation !== 0 ? rotate2(componentRotation * Math.PI / 180) : identity();
|
|
1444
1506
|
const rotatedPos = applyToPoint6(rotationMatrix, {
|
|
1445
1507
|
x: relativeX,
|
|
1446
1508
|
y: relativeY
|
|
@@ -1449,11 +1511,27 @@ function createThruHolePadFromCircuitJson({
|
|
|
1449
1511
|
let padSize;
|
|
1450
1512
|
let drill;
|
|
1451
1513
|
let rotation = 0;
|
|
1514
|
+
const hasHoleOffset = "hole_offset_x" in platedHole || "hole_offset_y" in platedHole;
|
|
1515
|
+
let drillOffset;
|
|
1516
|
+
if (hasHoleOffset) {
|
|
1517
|
+
const rawOffset = {
|
|
1518
|
+
x: platedHole.hole_offset_x ?? 0,
|
|
1519
|
+
y: platedHole.hole_offset_y ?? 0
|
|
1520
|
+
};
|
|
1521
|
+
if (rawOffset.x !== 0 || rawOffset.y !== 0) {
|
|
1522
|
+
const rotatedOffset = applyToPoint6(rotationMatrix, {
|
|
1523
|
+
x: -rawOffset.x,
|
|
1524
|
+
y: rawOffset.y
|
|
1525
|
+
});
|
|
1526
|
+
drillOffset = rotatedOffset;
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1452
1529
|
if (platedHole.shape === "circle") {
|
|
1453
1530
|
padShape = "circle";
|
|
1454
1531
|
padSize = [platedHole.outer_diameter, platedHole.outer_diameter];
|
|
1455
1532
|
drill = new PadDrill({
|
|
1456
|
-
diameter: platedHole.hole_diameter
|
|
1533
|
+
diameter: platedHole.hole_diameter,
|
|
1534
|
+
offset: drillOffset
|
|
1457
1535
|
});
|
|
1458
1536
|
} else if (platedHole.shape === "pill" || platedHole.shape === "oval") {
|
|
1459
1537
|
padShape = "oval";
|
|
@@ -1464,7 +1542,8 @@ function createThruHolePadFromCircuitJson({
|
|
|
1464
1542
|
drill = new PadDrill({
|
|
1465
1543
|
oval: true,
|
|
1466
1544
|
diameter: platedHole.hole_width,
|
|
1467
|
-
width: platedHole.hole_height
|
|
1545
|
+
width: platedHole.hole_height,
|
|
1546
|
+
offset: drillOffset
|
|
1468
1547
|
});
|
|
1469
1548
|
} else if (platedHole.shape === "pill_hole_with_rect_pad") {
|
|
1470
1549
|
padShape = "rect";
|
|
@@ -1475,7 +1554,8 @@ function createThruHolePadFromCircuitJson({
|
|
|
1475
1554
|
drill = new PadDrill({
|
|
1476
1555
|
oval: true,
|
|
1477
1556
|
diameter: platedHole.hole_width,
|
|
1478
|
-
width: platedHole.hole_height
|
|
1557
|
+
width: platedHole.hole_height,
|
|
1558
|
+
offset: drillOffset
|
|
1479
1559
|
});
|
|
1480
1560
|
} else if (platedHole.shape === "circular_hole_with_rect_pad") {
|
|
1481
1561
|
padShape = "rect";
|
|
@@ -1484,7 +1564,8 @@ function createThruHolePadFromCircuitJson({
|
|
|
1484
1564
|
platedHole.rect_pad_height
|
|
1485
1565
|
];
|
|
1486
1566
|
drill = new PadDrill({
|
|
1487
|
-
diameter: platedHole.hole_diameter
|
|
1567
|
+
diameter: platedHole.hole_diameter,
|
|
1568
|
+
offset: drillOffset
|
|
1488
1569
|
});
|
|
1489
1570
|
} else if (platedHole.shape === "rotated_pill_hole_with_rect_pad") {
|
|
1490
1571
|
padShape = "rect";
|
|
@@ -1495,13 +1576,14 @@ function createThruHolePadFromCircuitJson({
|
|
|
1495
1576
|
drill = new PadDrill({
|
|
1496
1577
|
oval: true,
|
|
1497
1578
|
diameter: platedHole.hole_width,
|
|
1498
|
-
width: platedHole.hole_height
|
|
1579
|
+
width: platedHole.hole_height,
|
|
1580
|
+
offset: drillOffset
|
|
1499
1581
|
});
|
|
1500
1582
|
rotation = platedHole.rect_ccw_rotation || 0;
|
|
1501
1583
|
} else {
|
|
1502
1584
|
padShape = "circle";
|
|
1503
1585
|
padSize = [1.6, 1.6];
|
|
1504
|
-
drill = new PadDrill({ diameter: 0.8 });
|
|
1586
|
+
drill = new PadDrill({ diameter: 0.8, offset: drillOffset });
|
|
1505
1587
|
}
|
|
1506
1588
|
return new FootprintPad2({
|
|
1507
1589
|
number: String(padNumber),
|
|
@@ -1518,7 +1600,7 @@ function createThruHolePadFromCircuitJson({
|
|
|
1518
1600
|
|
|
1519
1601
|
// lib/pcb/stages/utils/CreateNpthPadFromCircuitJson.ts
|
|
1520
1602
|
import { FootprintPad as FootprintPad3, PadDrill as PadDrill2 } from "kicadts";
|
|
1521
|
-
import { applyToPoint as applyToPoint7, rotate as rotate3, identity as
|
|
1603
|
+
import { applyToPoint as applyToPoint7, rotate as rotate3, identity as identity2 } from "transformation-matrix";
|
|
1522
1604
|
function createNpthPadFromCircuitJson({
|
|
1523
1605
|
pcbHole,
|
|
1524
1606
|
componentCenter,
|
|
@@ -1529,7 +1611,7 @@ function createNpthPadFromCircuitJson({
|
|
|
1529
1611
|
}
|
|
1530
1612
|
const relativeX = pcbHole.x - componentCenter.x;
|
|
1531
1613
|
const relativeY = -(pcbHole.y - componentCenter.y);
|
|
1532
|
-
const rotationMatrix = componentRotation !== 0 ? rotate3(componentRotation * Math.PI / 180) :
|
|
1614
|
+
const rotationMatrix = componentRotation !== 0 ? rotate3(componentRotation * Math.PI / 180) : identity2();
|
|
1533
1615
|
const rotatedPos = applyToPoint7(rotationMatrix, {
|
|
1534
1616
|
x: relativeX,
|
|
1535
1617
|
y: relativeY
|
|
@@ -1556,7 +1638,7 @@ function createNpthPadFromCircuitJson({
|
|
|
1556
1638
|
});
|
|
1557
1639
|
} else {
|
|
1558
1640
|
padShape = "circle";
|
|
1559
|
-
const diameter = pcbHole.hole_diameter
|
|
1641
|
+
const diameter = "hole_diameter" in pcbHole ? pcbHole.hole_diameter : 1;
|
|
1560
1642
|
padSize = [diameter, diameter];
|
|
1561
1643
|
drill = new PadDrill2({ diameter });
|
|
1562
1644
|
}
|
|
@@ -1576,7 +1658,7 @@ function createNpthPadFromCircuitJson({
|
|
|
1576
1658
|
|
|
1577
1659
|
// lib/pcb/stages/utils/CreateFpTextFromCircuitJson.ts
|
|
1578
1660
|
import { FpText, TextEffects as TextEffects4, TextEffectsFont as TextEffectsFont4 } from "kicadts";
|
|
1579
|
-
import { applyToPoint as applyToPoint8, rotate as rotate4, identity as
|
|
1661
|
+
import { applyToPoint as applyToPoint8, rotate as rotate4, identity as identity3 } from "transformation-matrix";
|
|
1580
1662
|
function createFpTextFromCircuitJson({
|
|
1581
1663
|
textElement,
|
|
1582
1664
|
componentCenter,
|
|
@@ -1587,7 +1669,7 @@ function createFpTextFromCircuitJson({
|
|
|
1587
1669
|
}
|
|
1588
1670
|
const relativeX = textElement.anchor_position.x - componentCenter.x;
|
|
1589
1671
|
const relativeY = -(textElement.anchor_position.y - componentCenter.y);
|
|
1590
|
-
const rotationMatrix = componentRotation !== 0 ? rotate4(componentRotation * Math.PI / 180) :
|
|
1672
|
+
const rotationMatrix = componentRotation !== 0 ? rotate4(componentRotation * Math.PI / 180) : identity3();
|
|
1591
1673
|
const rotatedPos = applyToPoint8(rotationMatrix, {
|
|
1592
1674
|
x: relativeX,
|
|
1593
1675
|
y: relativeY
|
|
@@ -1972,8 +2054,8 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
1972
2054
|
if (board.outline && board.outline.length > 0) {
|
|
1973
2055
|
corners = board.outline;
|
|
1974
2056
|
} else {
|
|
1975
|
-
const halfWidth = board.width / 2;
|
|
1976
|
-
const halfHeight = board.height / 2;
|
|
2057
|
+
const halfWidth = board.width ? board.width / 2 : 0;
|
|
2058
|
+
const halfHeight = board.height ? board.height / 2 : 0;
|
|
1977
2059
|
corners = [
|
|
1978
2060
|
{ x: board.center.x - halfWidth, y: board.center.y - halfHeight },
|
|
1979
2061
|
{ x: board.center.x + halfWidth, y: board.center.y - halfHeight },
|
|
@@ -2026,9 +2108,9 @@ var CircuitJsonToKicadPcbConverter = class {
|
|
|
2026
2108
|
generator: "circuit-json-to-kicad",
|
|
2027
2109
|
generatorVersion: "0.0.1"
|
|
2028
2110
|
}),
|
|
2029
|
-
c2kMatPcb:
|
|
2030
|
-
|
|
2031
|
-
|
|
2111
|
+
c2kMatPcb: compose3(
|
|
2112
|
+
translate3(KICAD_PCB_CENTER_X, KICAD_PCB_CENTER_Y),
|
|
2113
|
+
scale3(CIRCUIT_JSON_TO_MM_SCALE, -CIRCUIT_JSON_TO_MM_SCALE)
|
|
2032
2114
|
)
|
|
2033
2115
|
};
|
|
2034
2116
|
this.pipeline = [
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circuit-json-to-kicad",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.25",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
"@tscircuit/circuit-json-util": "^0.0.72",
|
|
19
19
|
"@tscircuit/common": "^0.0.5",
|
|
20
20
|
"@types/bun": "latest",
|
|
21
|
-
"circuit-json": "^0.0.
|
|
21
|
+
"circuit-json": "^0.0.302",
|
|
22
22
|
"circuit-to-svg": "^0.0.208",
|
|
23
|
-
"kicadts": "^0.0.
|
|
23
|
+
"kicadts": "^0.0.22",
|
|
24
24
|
"schematic-symbols": "^0.0.202",
|
|
25
25
|
"sharp": "^0.34.4",
|
|
26
26
|
"transformation-matrix": "^3.1.0",
|
|
27
|
-
"tscircuit": "^0.0.
|
|
27
|
+
"tscircuit": "^0.0.866",
|
|
28
28
|
"tsup": "^8.5.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|