circuit-json-to-kicad 0.0.24 → 0.0.26
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 +5 -1
- package/dist/index.js +169 -38
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ interface PaperDimensions {
|
|
|
13
13
|
type SchematicPortId = string;
|
|
14
14
|
type SchematicTraceId = string;
|
|
15
15
|
type PcbPortId = string;
|
|
16
|
+
interface PcbNetInfo {
|
|
17
|
+
id: number;
|
|
18
|
+
name: string;
|
|
19
|
+
}
|
|
16
20
|
interface ConverterContext {
|
|
17
21
|
db: CircuitJsonUtilObjects;
|
|
18
22
|
circuitJson: CircuitJson;
|
|
@@ -33,7 +37,7 @@ interface ConverterContext {
|
|
|
33
37
|
x: number;
|
|
34
38
|
y: number;
|
|
35
39
|
}>;
|
|
36
|
-
pcbNetMap?: Map<string,
|
|
40
|
+
pcbNetMap?: Map<string, PcbNetInfo>;
|
|
37
41
|
}
|
|
38
42
|
declare abstract class ConverterStage<Input, Output> {
|
|
39
43
|
MAX_ITERATIONS: number;
|
package/dist/index.js
CHANGED
|
@@ -1347,27 +1347,49 @@ var AddNetsStage = class extends ConverterStage {
|
|
|
1347
1347
|
if (!kicadPcb) {
|
|
1348
1348
|
throw new Error("KicadPcb instance not initialized in context");
|
|
1349
1349
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1350
|
+
this.ctx.pcbNetMap = /* @__PURE__ */ new Map();
|
|
1351
|
+
const netNameByKey = /* @__PURE__ */ new Map();
|
|
1352
|
+
const sourceNets = this.ctx.db.source_net?.list() ?? [];
|
|
1353
|
+
for (const sourceNet of sourceNets) {
|
|
1354
|
+
const connectivityKey = sourceNet.subcircuit_connectivity_map_key || sourceNet.source_net_id;
|
|
1355
|
+
if (!connectivityKey) continue;
|
|
1356
|
+
const candidateName = sourceNet.name || sourceNet.source_net_id || "";
|
|
1357
|
+
const netName = candidateName && candidateName.trim().length > 0 ? candidateName : connectivityKey;
|
|
1358
|
+
netNameByKey.set(connectivityKey, netName);
|
|
1359
|
+
}
|
|
1360
|
+
const sourceTraces = this.ctx.db.source_trace?.list() ?? [];
|
|
1361
|
+
for (const sourceTrace of sourceTraces) {
|
|
1362
|
+
let connectivityKey = sourceTrace.subcircuit_connectivity_map_key;
|
|
1363
|
+
if (!connectivityKey && sourceTrace.connected_source_net_ids?.length) {
|
|
1364
|
+
for (const sourceNetId of sourceTrace.connected_source_net_ids) {
|
|
1365
|
+
const connectedNet = this.ctx.db.source_net?.get(sourceNetId);
|
|
1366
|
+
if (connectedNet?.subcircuit_connectivity_map_key && connectedNet.subcircuit_connectivity_map_key.length > 0) {
|
|
1367
|
+
connectivityKey = connectedNet.subcircuit_connectivity_map_key;
|
|
1368
|
+
break;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
if (!connectivityKey) continue;
|
|
1373
|
+
if (!netNameByKey.has(connectivityKey)) {
|
|
1374
|
+
const candidateName = sourceTrace.display_name || sourceTrace.source_trace_id || "";
|
|
1375
|
+
const netName = candidateName && candidateName.trim().length > 0 ? candidateName : connectivityKey;
|
|
1376
|
+
netNameByKey.set(connectivityKey, netName);
|
|
1360
1377
|
}
|
|
1361
1378
|
}
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1379
|
+
const sortedEntries = Array.from(netNameByKey.entries()).sort(
|
|
1380
|
+
(a, b) => a[0].localeCompare(b[0])
|
|
1381
|
+
);
|
|
1382
|
+
const nets = [];
|
|
1383
|
+
nets.push(new PcbNet(0, ""));
|
|
1384
|
+
let netNumber = 1;
|
|
1385
|
+
for (const [connectivityKey, netName] of sortedEntries) {
|
|
1386
|
+
const pcbNet = new PcbNet(netNumber, netName);
|
|
1387
|
+
nets.push(pcbNet);
|
|
1388
|
+
const netInfo = { id: netNumber, name: netName };
|
|
1389
|
+
this.ctx.pcbNetMap.set(connectivityKey, netInfo);
|
|
1369
1390
|
netNumber++;
|
|
1370
1391
|
}
|
|
1392
|
+
kicadPcb.nets = nets;
|
|
1371
1393
|
this.finished = true;
|
|
1372
1394
|
}
|
|
1373
1395
|
getOutput() {
|
|
@@ -1386,7 +1408,8 @@ import {
|
|
|
1386
1408
|
PadPrimitiveGrPoly,
|
|
1387
1409
|
Pts as Pts3,
|
|
1388
1410
|
Xy as Xy3,
|
|
1389
|
-
PadOptions
|
|
1411
|
+
PadOptions,
|
|
1412
|
+
PadNet
|
|
1390
1413
|
} from "kicadts";
|
|
1391
1414
|
import {
|
|
1392
1415
|
applyToPoint as applyToPoint5,
|
|
@@ -1399,7 +1422,8 @@ function createSmdPadFromCircuitJson({
|
|
|
1399
1422
|
pcbPad,
|
|
1400
1423
|
componentCenter,
|
|
1401
1424
|
padNumber,
|
|
1402
|
-
componentRotation = 0
|
|
1425
|
+
componentRotation = 0,
|
|
1426
|
+
netInfo
|
|
1403
1427
|
}) {
|
|
1404
1428
|
let padX;
|
|
1405
1429
|
let padY;
|
|
@@ -1485,17 +1509,21 @@ function createSmdPadFromCircuitJson({
|
|
|
1485
1509
|
if (padPrimitives) {
|
|
1486
1510
|
pad.primitives = padPrimitives;
|
|
1487
1511
|
}
|
|
1512
|
+
if (netInfo) {
|
|
1513
|
+
pad.net = new PadNet(netInfo.id, netInfo.name);
|
|
1514
|
+
}
|
|
1488
1515
|
return pad;
|
|
1489
1516
|
}
|
|
1490
1517
|
|
|
1491
1518
|
// lib/pcb/stages/utils/CreateThruHolePadFromCircuitJson.ts
|
|
1492
|
-
import { FootprintPad as FootprintPad2, PadDrill } from "kicadts";
|
|
1519
|
+
import { FootprintPad as FootprintPad2, PadDrill, PadNet as PadNet2 } from "kicadts";
|
|
1493
1520
|
import { applyToPoint as applyToPoint6, rotate as rotate2, identity } from "transformation-matrix";
|
|
1494
1521
|
function createThruHolePadFromCircuitJson({
|
|
1495
1522
|
platedHole,
|
|
1496
1523
|
componentCenter,
|
|
1497
1524
|
padNumber,
|
|
1498
|
-
componentRotation = 0
|
|
1525
|
+
componentRotation = 0,
|
|
1526
|
+
netInfo
|
|
1499
1527
|
}) {
|
|
1500
1528
|
if (!("x" in platedHole && "y" in platedHole)) {
|
|
1501
1529
|
return null;
|
|
@@ -1511,11 +1539,27 @@ function createThruHolePadFromCircuitJson({
|
|
|
1511
1539
|
let padSize;
|
|
1512
1540
|
let drill;
|
|
1513
1541
|
let rotation = 0;
|
|
1542
|
+
const hasHoleOffset = "hole_offset_x" in platedHole || "hole_offset_y" in platedHole;
|
|
1543
|
+
let drillOffset;
|
|
1544
|
+
if (hasHoleOffset) {
|
|
1545
|
+
const rawOffset = {
|
|
1546
|
+
x: platedHole.hole_offset_x ?? 0,
|
|
1547
|
+
y: platedHole.hole_offset_y ?? 0
|
|
1548
|
+
};
|
|
1549
|
+
if (rawOffset.x !== 0 || rawOffset.y !== 0) {
|
|
1550
|
+
const rotatedOffset = applyToPoint6(rotationMatrix, {
|
|
1551
|
+
x: -rawOffset.x,
|
|
1552
|
+
y: rawOffset.y
|
|
1553
|
+
});
|
|
1554
|
+
drillOffset = rotatedOffset;
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1514
1557
|
if (platedHole.shape === "circle") {
|
|
1515
1558
|
padShape = "circle";
|
|
1516
1559
|
padSize = [platedHole.outer_diameter, platedHole.outer_diameter];
|
|
1517
1560
|
drill = new PadDrill({
|
|
1518
|
-
diameter: platedHole.hole_diameter
|
|
1561
|
+
diameter: platedHole.hole_diameter,
|
|
1562
|
+
offset: drillOffset
|
|
1519
1563
|
});
|
|
1520
1564
|
} else if (platedHole.shape === "pill" || platedHole.shape === "oval") {
|
|
1521
1565
|
padShape = "oval";
|
|
@@ -1526,7 +1570,8 @@ function createThruHolePadFromCircuitJson({
|
|
|
1526
1570
|
drill = new PadDrill({
|
|
1527
1571
|
oval: true,
|
|
1528
1572
|
diameter: platedHole.hole_width,
|
|
1529
|
-
width: platedHole.hole_height
|
|
1573
|
+
width: platedHole.hole_height,
|
|
1574
|
+
offset: drillOffset
|
|
1530
1575
|
});
|
|
1531
1576
|
} else if (platedHole.shape === "pill_hole_with_rect_pad") {
|
|
1532
1577
|
padShape = "rect";
|
|
@@ -1537,7 +1582,8 @@ function createThruHolePadFromCircuitJson({
|
|
|
1537
1582
|
drill = new PadDrill({
|
|
1538
1583
|
oval: true,
|
|
1539
1584
|
diameter: platedHole.hole_width,
|
|
1540
|
-
width: platedHole.hole_height
|
|
1585
|
+
width: platedHole.hole_height,
|
|
1586
|
+
offset: drillOffset
|
|
1541
1587
|
});
|
|
1542
1588
|
} else if (platedHole.shape === "circular_hole_with_rect_pad") {
|
|
1543
1589
|
padShape = "rect";
|
|
@@ -1546,7 +1592,8 @@ function createThruHolePadFromCircuitJson({
|
|
|
1546
1592
|
platedHole.rect_pad_height
|
|
1547
1593
|
];
|
|
1548
1594
|
drill = new PadDrill({
|
|
1549
|
-
diameter: platedHole.hole_diameter
|
|
1595
|
+
diameter: platedHole.hole_diameter,
|
|
1596
|
+
offset: drillOffset
|
|
1550
1597
|
});
|
|
1551
1598
|
} else if (platedHole.shape === "rotated_pill_hole_with_rect_pad") {
|
|
1552
1599
|
padShape = "rect";
|
|
@@ -1557,15 +1604,16 @@ function createThruHolePadFromCircuitJson({
|
|
|
1557
1604
|
drill = new PadDrill({
|
|
1558
1605
|
oval: true,
|
|
1559
1606
|
diameter: platedHole.hole_width,
|
|
1560
|
-
width: platedHole.hole_height
|
|
1607
|
+
width: platedHole.hole_height,
|
|
1608
|
+
offset: drillOffset
|
|
1561
1609
|
});
|
|
1562
1610
|
rotation = platedHole.rect_ccw_rotation || 0;
|
|
1563
1611
|
} else {
|
|
1564
1612
|
padShape = "circle";
|
|
1565
1613
|
padSize = [1.6, 1.6];
|
|
1566
|
-
drill = new PadDrill({ diameter: 0.8 });
|
|
1614
|
+
drill = new PadDrill({ diameter: 0.8, offset: drillOffset });
|
|
1567
1615
|
}
|
|
1568
|
-
|
|
1616
|
+
const pad = new FootprintPad2({
|
|
1569
1617
|
number: String(padNumber),
|
|
1570
1618
|
padType: "thru_hole",
|
|
1571
1619
|
shape: padShape,
|
|
@@ -1576,6 +1624,10 @@ function createThruHolePadFromCircuitJson({
|
|
|
1576
1624
|
removeUnusedLayers: false,
|
|
1577
1625
|
uuid: crypto.randomUUID()
|
|
1578
1626
|
});
|
|
1627
|
+
if (netInfo) {
|
|
1628
|
+
pad.net = new PadNet2(netInfo.id, netInfo.name);
|
|
1629
|
+
}
|
|
1630
|
+
return pad;
|
|
1579
1631
|
}
|
|
1580
1632
|
|
|
1581
1633
|
// lib/pcb/stages/utils/CreateNpthPadFromCircuitJson.ts
|
|
@@ -1687,6 +1739,18 @@ function createFpTextFromCircuitJson({
|
|
|
1687
1739
|
var AddFootprintsStage = class extends ConverterStage {
|
|
1688
1740
|
componentsProcessed = 0;
|
|
1689
1741
|
pcbComponents = [];
|
|
1742
|
+
getNetInfoForPcbPort(pcbPortId) {
|
|
1743
|
+
if (!pcbPortId) return void 0;
|
|
1744
|
+
const pcbPort = this.ctx.db.pcb_port?.get(pcbPortId);
|
|
1745
|
+
if (!pcbPort) return void 0;
|
|
1746
|
+
const sourcePortId = pcbPort.source_port_id;
|
|
1747
|
+
if (!sourcePortId) return void 0;
|
|
1748
|
+
const sourcePort = this.ctx.db.source_port?.get(sourcePortId);
|
|
1749
|
+
if (!sourcePort) return void 0;
|
|
1750
|
+
const connectivityKey = sourcePort.subcircuit_connectivity_map_key;
|
|
1751
|
+
if (!connectivityKey) return void 0;
|
|
1752
|
+
return this.ctx.pcbNetMap?.get(connectivityKey);
|
|
1753
|
+
}
|
|
1690
1754
|
constructor(input, ctx) {
|
|
1691
1755
|
super(input, ctx);
|
|
1692
1756
|
this.pcbComponents = this.ctx.db.pcb_component.list();
|
|
@@ -1737,11 +1801,13 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
1737
1801
|
const fpPads = footprint.fpPads;
|
|
1738
1802
|
let padNumber = 1;
|
|
1739
1803
|
for (const pcbPad of pcbPads) {
|
|
1804
|
+
const netInfo = this.getNetInfoForPcbPort(pcbPad.pcb_port_id);
|
|
1740
1805
|
const pad = createSmdPadFromCircuitJson({
|
|
1741
1806
|
pcbPad,
|
|
1742
1807
|
componentCenter: component.center,
|
|
1743
1808
|
padNumber,
|
|
1744
|
-
componentRotation: component.rotation || 0
|
|
1809
|
+
componentRotation: component.rotation || 0,
|
|
1810
|
+
netInfo
|
|
1745
1811
|
});
|
|
1746
1812
|
fpPads.push(pad);
|
|
1747
1813
|
padNumber++;
|
|
@@ -1750,11 +1816,13 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
1750
1816
|
(hole) => hole.pcb_component_id === component.pcb_component_id
|
|
1751
1817
|
) || [];
|
|
1752
1818
|
for (const platedHole of pcbPlatedHoles) {
|
|
1819
|
+
const netInfo = this.getNetInfoForPcbPort(platedHole.pcb_port_id);
|
|
1753
1820
|
const pad = createThruHolePadFromCircuitJson({
|
|
1754
1821
|
platedHole,
|
|
1755
1822
|
componentCenter: component.center,
|
|
1756
1823
|
padNumber,
|
|
1757
|
-
componentRotation: component.rotation || 0
|
|
1824
|
+
componentRotation: component.rotation || 0,
|
|
1825
|
+
netInfo
|
|
1758
1826
|
});
|
|
1759
1827
|
if (pad) {
|
|
1760
1828
|
fpPads.push(pad);
|
|
@@ -1823,10 +1891,35 @@ var AddTracesStage = class extends ConverterStage {
|
|
|
1823
1891
|
x: endPoint.x,
|
|
1824
1892
|
y: endPoint.y
|
|
1825
1893
|
});
|
|
1826
|
-
let
|
|
1894
|
+
let netInfo;
|
|
1827
1895
|
if (pcbNetMap) {
|
|
1828
|
-
|
|
1829
|
-
|
|
1896
|
+
let connectivityKey = trace.subcircuit_connectivity_map_key;
|
|
1897
|
+
if (!connectivityKey && trace.source_trace_id) {
|
|
1898
|
+
const sourceTrace = this.ctx.db.source_trace?.get(
|
|
1899
|
+
trace.source_trace_id
|
|
1900
|
+
);
|
|
1901
|
+
if (sourceTrace) {
|
|
1902
|
+
connectivityKey = sourceTrace.subcircuit_connectivity_map_key;
|
|
1903
|
+
if (!connectivityKey && sourceTrace.connected_source_net_ids?.length) {
|
|
1904
|
+
for (const sourceNetId of sourceTrace.connected_source_net_ids) {
|
|
1905
|
+
const sourceNet = this.ctx.db.source_net?.get(sourceNetId);
|
|
1906
|
+
if (sourceNet?.subcircuit_connectivity_map_key) {
|
|
1907
|
+
connectivityKey = sourceNet.subcircuit_connectivity_map_key;
|
|
1908
|
+
break;
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
if (!connectivityKey && typeof trace.connection_name === "string") {
|
|
1915
|
+
const sourceNet = this.ctx.db.source_net?.get(trace.connection_name);
|
|
1916
|
+
if (sourceNet?.subcircuit_connectivity_map_key) {
|
|
1917
|
+
connectivityKey = sourceNet.subcircuit_connectivity_map_key;
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
if (connectivityKey) {
|
|
1921
|
+
netInfo = pcbNetMap.get(connectivityKey);
|
|
1922
|
+
}
|
|
1830
1923
|
}
|
|
1831
1924
|
const layerMap = {
|
|
1832
1925
|
top: "F.Cu",
|
|
@@ -1838,7 +1931,8 @@ var AddTracesStage = class extends ConverterStage {
|
|
|
1838
1931
|
end: { x: transformedEnd.x, y: transformedEnd.y },
|
|
1839
1932
|
layer: kicadLayer,
|
|
1840
1933
|
width: trace.width || 0.25,
|
|
1841
|
-
net: new SegmentNet(
|
|
1934
|
+
net: new SegmentNet(netInfo?.id ?? 0),
|
|
1935
|
+
uuid: crypto.randomUUID()
|
|
1842
1936
|
});
|
|
1843
1937
|
const segments = kicadPcb.segments;
|
|
1844
1938
|
segments.push(segment);
|
|
@@ -1878,16 +1972,53 @@ var AddViasStage = class extends ConverterStage {
|
|
|
1878
1972
|
x: via.x,
|
|
1879
1973
|
y: via.y
|
|
1880
1974
|
});
|
|
1881
|
-
let
|
|
1882
|
-
if (pcbNetMap
|
|
1883
|
-
|
|
1975
|
+
let netInfo;
|
|
1976
|
+
if (pcbNetMap) {
|
|
1977
|
+
let connectivityKey = via.subcircuit_connectivity_map_key;
|
|
1978
|
+
if (!connectivityKey && via.pcb_trace_id) {
|
|
1979
|
+
const pcbTrace = this.ctx.db.pcb_trace?.get(via.pcb_trace_id);
|
|
1980
|
+
if (pcbTrace) {
|
|
1981
|
+
if ("subcircuit_connectivity_map_key" in pcbTrace) {
|
|
1982
|
+
connectivityKey = pcbTrace.subcircuit_connectivity_map_key;
|
|
1983
|
+
}
|
|
1984
|
+
if (!connectivityKey && pcbTrace.source_trace_id) {
|
|
1985
|
+
const sourceTrace = this.ctx.db.source_trace?.get(
|
|
1986
|
+
pcbTrace.source_trace_id
|
|
1987
|
+
);
|
|
1988
|
+
if (sourceTrace) {
|
|
1989
|
+
if ("subcircuit_connectivity_map_key" in sourceTrace) {
|
|
1990
|
+
connectivityKey = sourceTrace.subcircuit_connectivity_map_key;
|
|
1991
|
+
}
|
|
1992
|
+
if (!connectivityKey && sourceTrace.connected_source_net_ids?.length) {
|
|
1993
|
+
for (const sourceNetId of sourceTrace.connected_source_net_ids) {
|
|
1994
|
+
const sourceNet = this.ctx.db.source_net?.get(sourceNetId);
|
|
1995
|
+
if (sourceNet?.subcircuit_connectivity_map_key) {
|
|
1996
|
+
connectivityKey = sourceNet.subcircuit_connectivity_map_key;
|
|
1997
|
+
break;
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
if (!connectivityKey && via.connection_name) {
|
|
2006
|
+
const sourceNet = this.ctx.db.source_net?.get(via.connection_name);
|
|
2007
|
+
if (sourceNet?.subcircuit_connectivity_map_key) {
|
|
2008
|
+
connectivityKey = sourceNet.subcircuit_connectivity_map_key;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
if (connectivityKey) {
|
|
2012
|
+
netInfo = pcbNetMap.get(connectivityKey);
|
|
2013
|
+
}
|
|
1884
2014
|
}
|
|
1885
2015
|
const kicadVia = new Via({
|
|
1886
2016
|
at: [transformedPos.x, transformedPos.y],
|
|
1887
2017
|
size: via.outer_diameter || 0.8,
|
|
1888
2018
|
drill: via.hole_diameter || 0.4,
|
|
1889
2019
|
layers: ["F.Cu", "B.Cu"],
|
|
1890
|
-
net: new ViaNet(
|
|
2020
|
+
net: new ViaNet(netInfo?.id ?? 0),
|
|
2021
|
+
uuid: crypto.randomUUID()
|
|
1891
2022
|
});
|
|
1892
2023
|
const vias = kicadPcb.vias;
|
|
1893
2024
|
vias.push(kicadVia);
|