circuit-json-to-lbrn 0.0.15 → 0.0.17
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 +337 -13
- package/lib/element-handlers/addPcbHole/addCirclePcbHole.ts +51 -0
- package/lib/element-handlers/addPcbHole/addOvalPcbHole.ts +59 -0
- package/lib/element-handlers/addPcbHole/addPillPcbHole.ts +59 -0
- package/lib/element-handlers/addPcbHole/addRectPcbHole.ts +61 -0
- package/lib/element-handlers/addPcbHole/addRotatedPillPcbHole.ts +62 -0
- package/lib/element-handlers/addPcbHole/index.ts +36 -0
- package/lib/element-handlers/addPcbVia/index.ts +84 -0
- package/lib/index.ts +10 -0
- package/package.json +1 -1
- package/tests/examples/addPcbHole/__snapshots__/pcb-hole-circle.snap.svg +8 -0
- package/tests/examples/addPcbHole/__snapshots__/pcb-hole-oval.snap.svg +8 -0
- package/tests/examples/addPcbHole/__snapshots__/pcb-hole-pill.snap.svg +8 -0
- package/tests/examples/addPcbHole/__snapshots__/pcb-hole-rect.snap.svg +8 -0
- package/tests/examples/addPcbHole/__snapshots__/pcb-hole-rotated-pill.snap.svg +8 -0
- package/tests/examples/addPcbHole/__snapshots__/pcb-hole-with-soldermask.snap.svg +8 -0
- package/tests/examples/addPcbHole/pcb-hole-circle.test.ts +47 -0
- package/tests/examples/addPcbHole/pcb-hole-oval.test.ts +49 -0
- package/tests/examples/addPcbHole/pcb-hole-pill.test.ts +49 -0
- package/tests/examples/addPcbHole/pcb-hole-rect.test.ts +49 -0
- package/tests/examples/addPcbHole/pcb-hole-rotated-pill.test.ts +61 -0
- package/tests/examples/addPcbHole/pcb-hole-with-soldermask.test.ts +60 -0
- package/tests/examples/addPcbVia/__snapshots__/pcb-via-basic.snap.svg +8 -0
- package/tests/examples/addPcbVia/__snapshots__/pcb-via-with-net.snap.svg +8 -0
- package/tests/examples/addPcbVia/__snapshots__/pcb-via-with-soldermask.snap.svg +8 -0
- package/tests/examples/addPcbVia/pcb-via-basic.test.ts +49 -0
- package/tests/examples/addPcbVia/pcb-via-with-net.test.ts +126 -0
- package/tests/examples/addPcbVia/pcb-via-with-soldermask.test.ts +53 -0
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// lib/index.ts
|
|
2
|
-
import { LightBurnProject, CutSetting, ShapePath as
|
|
2
|
+
import { LightBurnProject, CutSetting, ShapePath as ShapePath21 } from "lbrnts";
|
|
3
3
|
import { cju as cju2 } from "@tscircuit/circuit-json-util";
|
|
4
4
|
|
|
5
5
|
// lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts
|
|
@@ -602,9 +602,9 @@ import { ShapePath as ShapePath6 } from "lbrnts";
|
|
|
602
602
|
// lib/helpers/polygonShape.ts
|
|
603
603
|
var createPolygonPathFromOutline = (outline, offsetX, offsetY) => {
|
|
604
604
|
const verts = [];
|
|
605
|
-
for (const
|
|
606
|
-
const x = (
|
|
607
|
-
const y = (
|
|
605
|
+
for (const point6 of outline) {
|
|
606
|
+
const x = (point6.x ?? 0) + offsetX;
|
|
607
|
+
const y = (point6.y ?? 0) + offsetY;
|
|
608
608
|
verts.push({ x, y });
|
|
609
609
|
}
|
|
610
610
|
if (verts.length === 0) {
|
|
@@ -1207,7 +1207,7 @@ var addPcbTrace = (trace, ctx) => {
|
|
|
1207
1207
|
return;
|
|
1208
1208
|
}
|
|
1209
1209
|
const { route } = trace;
|
|
1210
|
-
const traceWidth = route.find((
|
|
1210
|
+
const traceWidth = route.find((point6) => point6.route_type === "wire")?.width ?? 0.15;
|
|
1211
1211
|
const polygons = [];
|
|
1212
1212
|
for (const routePoint of route) {
|
|
1213
1213
|
const circle = new Flatten2.Circle(
|
|
@@ -1341,14 +1341,14 @@ var calculateCircuitBounds = (circuitJson) => {
|
|
|
1341
1341
|
}
|
|
1342
1342
|
}
|
|
1343
1343
|
for (const trace of db.pcb_trace.list()) {
|
|
1344
|
-
const isWidthPoint = (
|
|
1344
|
+
const isWidthPoint = (point6) => "width" in point6 && typeof point6.width === "number";
|
|
1345
1345
|
const halfWidth = trace.route_thickness_mode === "interpolated" ? 0 : (trace.route.find(isWidthPoint)?.width ?? 0) / 2;
|
|
1346
|
-
for (const
|
|
1347
|
-
const pointWidth = trace.route_thickness_mode === "interpolated" ? isWidthPoint(
|
|
1348
|
-
minX = Math.min(minX,
|
|
1349
|
-
minY = Math.min(minY,
|
|
1350
|
-
maxX = Math.max(maxX,
|
|
1351
|
-
maxY = Math.max(maxY,
|
|
1346
|
+
for (const point6 of trace.route) {
|
|
1347
|
+
const pointWidth = trace.route_thickness_mode === "interpolated" ? isWidthPoint(point6) ? point6.width / 2 : 0 : halfWidth;
|
|
1348
|
+
minX = Math.min(minX, point6.x - pointWidth);
|
|
1349
|
+
minY = Math.min(minY, point6.y - pointWidth);
|
|
1350
|
+
maxX = Math.max(maxX, point6.x + pointWidth);
|
|
1351
|
+
maxY = Math.max(maxY, point6.y + pointWidth);
|
|
1352
1352
|
}
|
|
1353
1353
|
}
|
|
1354
1354
|
for (const hole of db.pcb_plated_hole.list()) {
|
|
@@ -1372,6 +1372,324 @@ var calculateOriginFromBounds = (bounds, margin) => {
|
|
|
1372
1372
|
return { x: originX, y: originY };
|
|
1373
1373
|
};
|
|
1374
1374
|
|
|
1375
|
+
// lib/element-handlers/addPcbVia/index.ts
|
|
1376
|
+
import { ShapePath as ShapePath15 } from "lbrnts";
|
|
1377
|
+
import { Circle as Circle3, point as point5 } from "@flatten-js/core";
|
|
1378
|
+
var addPcbVia = (via, ctx) => {
|
|
1379
|
+
const {
|
|
1380
|
+
db,
|
|
1381
|
+
project,
|
|
1382
|
+
copperCutSetting,
|
|
1383
|
+
soldermaskCutSetting,
|
|
1384
|
+
throughBoardCutSetting,
|
|
1385
|
+
origin,
|
|
1386
|
+
includeCopper,
|
|
1387
|
+
includeSoldermask,
|
|
1388
|
+
connMap,
|
|
1389
|
+
soldermaskMargin
|
|
1390
|
+
} = ctx;
|
|
1391
|
+
const centerX = via.x + origin.x;
|
|
1392
|
+
const centerY = via.y + origin.y;
|
|
1393
|
+
if (via.outer_diameter > 0 && includeCopper) {
|
|
1394
|
+
const viaPort = db.pcb_port.list().find((port) => port.x === via.x && port.y === via.y);
|
|
1395
|
+
const netId = viaPort ? connMap.getNetConnectedToId(viaPort.pcb_port_id) : void 0;
|
|
1396
|
+
const outerRadius = via.outer_diameter / 2;
|
|
1397
|
+
const circle = new Circle3(point5(centerX, centerY), outerRadius);
|
|
1398
|
+
const polygon = circleToPolygon(circle);
|
|
1399
|
+
if (netId) {
|
|
1400
|
+
ctx.netGeoms.get(netId)?.push(polygon);
|
|
1401
|
+
} else {
|
|
1402
|
+
const outer = createCirclePath(centerX, centerY, outerRadius);
|
|
1403
|
+
project.children.push(
|
|
1404
|
+
new ShapePath15({
|
|
1405
|
+
cutIndex: copperCutSetting.index,
|
|
1406
|
+
verts: outer.verts,
|
|
1407
|
+
prims: outer.prims,
|
|
1408
|
+
isClosed: true
|
|
1409
|
+
})
|
|
1410
|
+
);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
if (via.outer_diameter > 0 && includeSoldermask) {
|
|
1414
|
+
const smRadius = via.outer_diameter / 2 + soldermaskMargin;
|
|
1415
|
+
const outer = createCirclePath(centerX, centerY, smRadius);
|
|
1416
|
+
project.children.push(
|
|
1417
|
+
new ShapePath15({
|
|
1418
|
+
cutIndex: soldermaskCutSetting.index,
|
|
1419
|
+
verts: outer.verts,
|
|
1420
|
+
prims: outer.prims,
|
|
1421
|
+
isClosed: true
|
|
1422
|
+
})
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
if (via.hole_diameter > 0) {
|
|
1426
|
+
const innerRadius = via.hole_diameter / 2;
|
|
1427
|
+
const inner = createCirclePath(centerX, centerY, innerRadius);
|
|
1428
|
+
project.children.push(
|
|
1429
|
+
new ShapePath15({
|
|
1430
|
+
cutIndex: throughBoardCutSetting.index,
|
|
1431
|
+
verts: inner.verts,
|
|
1432
|
+
prims: inner.prims,
|
|
1433
|
+
isClosed: true
|
|
1434
|
+
})
|
|
1435
|
+
);
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
|
|
1439
|
+
// lib/element-handlers/addPcbHole/addCirclePcbHole.ts
|
|
1440
|
+
import { ShapePath as ShapePath16 } from "lbrnts";
|
|
1441
|
+
var addCirclePcbHole = (hole, ctx) => {
|
|
1442
|
+
const {
|
|
1443
|
+
project,
|
|
1444
|
+
throughBoardCutSetting,
|
|
1445
|
+
soldermaskCutSetting,
|
|
1446
|
+
origin,
|
|
1447
|
+
includeSoldermask,
|
|
1448
|
+
soldermaskMargin
|
|
1449
|
+
} = ctx;
|
|
1450
|
+
const centerX = hole.x + origin.x;
|
|
1451
|
+
const centerY = hole.y + origin.y;
|
|
1452
|
+
if (hole.hole_diameter > 0 && includeSoldermask) {
|
|
1453
|
+
const smRadius = hole.hole_diameter / 2 + soldermaskMargin;
|
|
1454
|
+
const soldermaskPath = createCirclePath(centerX, centerY, smRadius);
|
|
1455
|
+
project.children.push(
|
|
1456
|
+
new ShapePath16({
|
|
1457
|
+
cutIndex: soldermaskCutSetting.index,
|
|
1458
|
+
verts: soldermaskPath.verts,
|
|
1459
|
+
prims: soldermaskPath.prims,
|
|
1460
|
+
isClosed: true
|
|
1461
|
+
})
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1464
|
+
if (hole.hole_diameter > 0) {
|
|
1465
|
+
const radius = hole.hole_diameter / 2;
|
|
1466
|
+
const circlePath = createCirclePath(centerX, centerY, radius);
|
|
1467
|
+
project.children.push(
|
|
1468
|
+
new ShapePath16({
|
|
1469
|
+
cutIndex: throughBoardCutSetting.index,
|
|
1470
|
+
verts: circlePath.verts,
|
|
1471
|
+
prims: circlePath.prims,
|
|
1472
|
+
isClosed: true
|
|
1473
|
+
})
|
|
1474
|
+
);
|
|
1475
|
+
}
|
|
1476
|
+
};
|
|
1477
|
+
|
|
1478
|
+
// lib/element-handlers/addPcbHole/addRectPcbHole.ts
|
|
1479
|
+
import { ShapePath as ShapePath17 } from "lbrnts";
|
|
1480
|
+
var addRectPcbHole = (hole, ctx) => {
|
|
1481
|
+
const {
|
|
1482
|
+
project,
|
|
1483
|
+
throughBoardCutSetting,
|
|
1484
|
+
soldermaskCutSetting,
|
|
1485
|
+
origin,
|
|
1486
|
+
includeSoldermask,
|
|
1487
|
+
soldermaskMargin
|
|
1488
|
+
} = ctx;
|
|
1489
|
+
const centerX = hole.x + origin.x;
|
|
1490
|
+
const centerY = hole.y + origin.y;
|
|
1491
|
+
if (hole.hole_width > 0 && hole.hole_height > 0 && includeSoldermask) {
|
|
1492
|
+
const soldermaskPath = createRoundedRectPath(
|
|
1493
|
+
centerX,
|
|
1494
|
+
centerY,
|
|
1495
|
+
hole.hole_width + soldermaskMargin * 2,
|
|
1496
|
+
hole.hole_height + soldermaskMargin * 2,
|
|
1497
|
+
0
|
|
1498
|
+
// no border radius for rect holes
|
|
1499
|
+
);
|
|
1500
|
+
project.children.push(
|
|
1501
|
+
new ShapePath17({
|
|
1502
|
+
cutIndex: soldermaskCutSetting.index,
|
|
1503
|
+
verts: soldermaskPath.verts,
|
|
1504
|
+
prims: soldermaskPath.prims,
|
|
1505
|
+
isClosed: true
|
|
1506
|
+
})
|
|
1507
|
+
);
|
|
1508
|
+
}
|
|
1509
|
+
if (hole.hole_width > 0 && hole.hole_height > 0) {
|
|
1510
|
+
const rectPath = createRoundedRectPath(
|
|
1511
|
+
centerX,
|
|
1512
|
+
centerY,
|
|
1513
|
+
hole.hole_width,
|
|
1514
|
+
hole.hole_height,
|
|
1515
|
+
0
|
|
1516
|
+
// no border radius for rect holes
|
|
1517
|
+
);
|
|
1518
|
+
project.children.push(
|
|
1519
|
+
new ShapePath17({
|
|
1520
|
+
cutIndex: throughBoardCutSetting.index,
|
|
1521
|
+
verts: rectPath.verts,
|
|
1522
|
+
prims: rectPath.prims,
|
|
1523
|
+
isClosed: true
|
|
1524
|
+
})
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
};
|
|
1528
|
+
|
|
1529
|
+
// lib/element-handlers/addPcbHole/addOvalPcbHole.ts
|
|
1530
|
+
import { ShapePath as ShapePath18 } from "lbrnts";
|
|
1531
|
+
var addOvalPcbHole = (hole, ctx) => {
|
|
1532
|
+
const {
|
|
1533
|
+
project,
|
|
1534
|
+
throughBoardCutSetting,
|
|
1535
|
+
soldermaskCutSetting,
|
|
1536
|
+
origin,
|
|
1537
|
+
includeSoldermask,
|
|
1538
|
+
soldermaskMargin
|
|
1539
|
+
} = ctx;
|
|
1540
|
+
const centerX = hole.x + origin.x;
|
|
1541
|
+
const centerY = hole.y + origin.y;
|
|
1542
|
+
if (hole.hole_width > 0 && hole.hole_height > 0 && includeSoldermask) {
|
|
1543
|
+
const soldermaskPath = createOvalPath(
|
|
1544
|
+
centerX,
|
|
1545
|
+
centerY,
|
|
1546
|
+
hole.hole_width + soldermaskMargin * 2,
|
|
1547
|
+
hole.hole_height + soldermaskMargin * 2
|
|
1548
|
+
);
|
|
1549
|
+
project.children.push(
|
|
1550
|
+
new ShapePath18({
|
|
1551
|
+
cutIndex: soldermaskCutSetting.index,
|
|
1552
|
+
verts: soldermaskPath.verts,
|
|
1553
|
+
prims: soldermaskPath.prims,
|
|
1554
|
+
isClosed: true
|
|
1555
|
+
})
|
|
1556
|
+
);
|
|
1557
|
+
}
|
|
1558
|
+
if (hole.hole_width > 0 && hole.hole_height > 0) {
|
|
1559
|
+
const ovalPath = createOvalPath(
|
|
1560
|
+
centerX,
|
|
1561
|
+
centerY,
|
|
1562
|
+
hole.hole_width,
|
|
1563
|
+
hole.hole_height
|
|
1564
|
+
);
|
|
1565
|
+
project.children.push(
|
|
1566
|
+
new ShapePath18({
|
|
1567
|
+
cutIndex: throughBoardCutSetting.index,
|
|
1568
|
+
verts: ovalPath.verts,
|
|
1569
|
+
prims: ovalPath.prims,
|
|
1570
|
+
isClosed: true
|
|
1571
|
+
})
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
};
|
|
1575
|
+
|
|
1576
|
+
// lib/element-handlers/addPcbHole/addPillPcbHole.ts
|
|
1577
|
+
import { ShapePath as ShapePath19 } from "lbrnts";
|
|
1578
|
+
var addPillPcbHole = (hole, ctx) => {
|
|
1579
|
+
const {
|
|
1580
|
+
project,
|
|
1581
|
+
throughBoardCutSetting,
|
|
1582
|
+
soldermaskCutSetting,
|
|
1583
|
+
origin,
|
|
1584
|
+
includeSoldermask,
|
|
1585
|
+
soldermaskMargin
|
|
1586
|
+
} = ctx;
|
|
1587
|
+
const centerX = hole.x + origin.x;
|
|
1588
|
+
const centerY = hole.y + origin.y;
|
|
1589
|
+
if (hole.hole_width > 0 && hole.hole_height > 0 && includeSoldermask) {
|
|
1590
|
+
const soldermaskPath = createPillPath(
|
|
1591
|
+
centerX,
|
|
1592
|
+
centerY,
|
|
1593
|
+
hole.hole_width + soldermaskMargin * 2,
|
|
1594
|
+
hole.hole_height + soldermaskMargin * 2
|
|
1595
|
+
);
|
|
1596
|
+
project.children.push(
|
|
1597
|
+
new ShapePath19({
|
|
1598
|
+
cutIndex: soldermaskCutSetting.index,
|
|
1599
|
+
verts: soldermaskPath.verts,
|
|
1600
|
+
prims: soldermaskPath.prims,
|
|
1601
|
+
isClosed: true
|
|
1602
|
+
})
|
|
1603
|
+
);
|
|
1604
|
+
}
|
|
1605
|
+
if (hole.hole_width > 0 && hole.hole_height > 0) {
|
|
1606
|
+
const pillPath = createPillPath(
|
|
1607
|
+
centerX,
|
|
1608
|
+
centerY,
|
|
1609
|
+
hole.hole_width,
|
|
1610
|
+
hole.hole_height
|
|
1611
|
+
);
|
|
1612
|
+
project.children.push(
|
|
1613
|
+
new ShapePath19({
|
|
1614
|
+
cutIndex: throughBoardCutSetting.index,
|
|
1615
|
+
verts: pillPath.verts,
|
|
1616
|
+
prims: pillPath.prims,
|
|
1617
|
+
isClosed: true
|
|
1618
|
+
})
|
|
1619
|
+
);
|
|
1620
|
+
}
|
|
1621
|
+
};
|
|
1622
|
+
|
|
1623
|
+
// lib/element-handlers/addPcbHole/addRotatedPillPcbHole.ts
|
|
1624
|
+
import { ShapePath as ShapePath20 } from "lbrnts";
|
|
1625
|
+
var addRotatedPillPcbHole = (hole, ctx) => {
|
|
1626
|
+
const {
|
|
1627
|
+
project,
|
|
1628
|
+
throughBoardCutSetting,
|
|
1629
|
+
soldermaskCutSetting,
|
|
1630
|
+
origin,
|
|
1631
|
+
includeSoldermask,
|
|
1632
|
+
soldermaskMargin
|
|
1633
|
+
} = ctx;
|
|
1634
|
+
const centerX = hole.x + origin.x;
|
|
1635
|
+
const centerY = hole.y + origin.y;
|
|
1636
|
+
const rotation = (hole.ccw_rotation || 0) * (Math.PI / 180);
|
|
1637
|
+
if (hole.hole_width > 0 && hole.hole_height > 0 && includeSoldermask) {
|
|
1638
|
+
const soldermaskPath = createPillPath(
|
|
1639
|
+
centerX,
|
|
1640
|
+
centerY,
|
|
1641
|
+
hole.hole_width + soldermaskMargin * 2,
|
|
1642
|
+
hole.hole_height + soldermaskMargin * 2,
|
|
1643
|
+
rotation
|
|
1644
|
+
);
|
|
1645
|
+
project.children.push(
|
|
1646
|
+
new ShapePath20({
|
|
1647
|
+
cutIndex: soldermaskCutSetting.index,
|
|
1648
|
+
verts: soldermaskPath.verts,
|
|
1649
|
+
prims: soldermaskPath.prims,
|
|
1650
|
+
isClosed: true
|
|
1651
|
+
})
|
|
1652
|
+
);
|
|
1653
|
+
}
|
|
1654
|
+
if (hole.hole_width > 0 && hole.hole_height > 0) {
|
|
1655
|
+
const pillPath = createPillPath(
|
|
1656
|
+
centerX,
|
|
1657
|
+
centerY,
|
|
1658
|
+
hole.hole_width,
|
|
1659
|
+
hole.hole_height,
|
|
1660
|
+
rotation
|
|
1661
|
+
);
|
|
1662
|
+
project.children.push(
|
|
1663
|
+
new ShapePath20({
|
|
1664
|
+
cutIndex: throughBoardCutSetting.index,
|
|
1665
|
+
verts: pillPath.verts,
|
|
1666
|
+
prims: pillPath.prims,
|
|
1667
|
+
isClosed: true
|
|
1668
|
+
})
|
|
1669
|
+
);
|
|
1670
|
+
}
|
|
1671
|
+
};
|
|
1672
|
+
|
|
1673
|
+
// lib/element-handlers/addPcbHole/index.ts
|
|
1674
|
+
var addPcbHole = (hole, ctx) => {
|
|
1675
|
+
switch (hole.hole_shape) {
|
|
1676
|
+
case "circle":
|
|
1677
|
+
case "square":
|
|
1678
|
+
return addCirclePcbHole(hole, ctx);
|
|
1679
|
+
case "rect":
|
|
1680
|
+
return addRectPcbHole(hole, ctx);
|
|
1681
|
+
case "oval":
|
|
1682
|
+
return addOvalPcbHole(hole, ctx);
|
|
1683
|
+
case "pill":
|
|
1684
|
+
return addPillPcbHole(hole, ctx);
|
|
1685
|
+
case "rotated_pill":
|
|
1686
|
+
return addRotatedPillPcbHole(hole, ctx);
|
|
1687
|
+
default:
|
|
1688
|
+
const _exhaustive = hole;
|
|
1689
|
+
console.warn(`Unknown hole shape: ${hole.hole_shape}`);
|
|
1690
|
+
}
|
|
1691
|
+
};
|
|
1692
|
+
|
|
1375
1693
|
// lib/index.ts
|
|
1376
1694
|
var convertCircuitJsonToLbrn = (circuitJson, options = {}) => {
|
|
1377
1695
|
const db = cju2(circuitJson);
|
|
@@ -1443,6 +1761,12 @@ var convertCircuitJsonToLbrn = (circuitJson, options = {}) => {
|
|
|
1443
1761
|
for (const board of db.pcb_board.list()) {
|
|
1444
1762
|
addPcbBoard(board, ctx);
|
|
1445
1763
|
}
|
|
1764
|
+
for (const via of db.pcb_via.list()) {
|
|
1765
|
+
addPcbVia(via, ctx);
|
|
1766
|
+
}
|
|
1767
|
+
for (const hole of db.pcb_hole.list()) {
|
|
1768
|
+
addPcbHole(hole, ctx);
|
|
1769
|
+
}
|
|
1446
1770
|
if (ctx.includeCopper) {
|
|
1447
1771
|
for (const net of Object.keys(connMap.netMap)) {
|
|
1448
1772
|
const netGeoms = ctx.netGeoms.get(net);
|
|
@@ -1463,7 +1787,7 @@ var convertCircuitJsonToLbrn = (circuitJson, options = {}) => {
|
|
|
1463
1787
|
for (const island of union.splitToIslands()) {
|
|
1464
1788
|
const { verts, prims } = polygonToShapePathData(island);
|
|
1465
1789
|
project.children.push(
|
|
1466
|
-
new
|
|
1790
|
+
new ShapePath21({
|
|
1467
1791
|
cutIndex: copperCutSetting.index,
|
|
1468
1792
|
verts,
|
|
1469
1793
|
prims,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { PcbHoleCircle, PcbHoleCircleOrSquare } from "circuit-json"
|
|
2
|
+
import type { ConvertContext } from "../../ConvertContext"
|
|
3
|
+
import { ShapePath } from "lbrnts"
|
|
4
|
+
import { createCirclePath } from "../../helpers/circleShape"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Adds a circular PCB hole (non-plated) to the project
|
|
8
|
+
*/
|
|
9
|
+
export const addCirclePcbHole = (
|
|
10
|
+
hole: PcbHoleCircle | PcbHoleCircleOrSquare,
|
|
11
|
+
ctx: ConvertContext,
|
|
12
|
+
): void => {
|
|
13
|
+
const {
|
|
14
|
+
project,
|
|
15
|
+
throughBoardCutSetting,
|
|
16
|
+
soldermaskCutSetting,
|
|
17
|
+
origin,
|
|
18
|
+
includeSoldermask,
|
|
19
|
+
soldermaskMargin,
|
|
20
|
+
} = ctx
|
|
21
|
+
const centerX = hole.x + origin.x
|
|
22
|
+
const centerY = hole.y + origin.y
|
|
23
|
+
|
|
24
|
+
// Add soldermask opening if drawing soldermask
|
|
25
|
+
if (hole.hole_diameter > 0 && includeSoldermask) {
|
|
26
|
+
const smRadius = hole.hole_diameter / 2 + soldermaskMargin
|
|
27
|
+
const soldermaskPath = createCirclePath(centerX, centerY, smRadius)
|
|
28
|
+
project.children.push(
|
|
29
|
+
new ShapePath({
|
|
30
|
+
cutIndex: soldermaskCutSetting.index,
|
|
31
|
+
verts: soldermaskPath.verts,
|
|
32
|
+
prims: soldermaskPath.prims,
|
|
33
|
+
isClosed: true,
|
|
34
|
+
}),
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Add the hole - cut through the board
|
|
39
|
+
if (hole.hole_diameter > 0) {
|
|
40
|
+
const radius = hole.hole_diameter / 2
|
|
41
|
+
const circlePath = createCirclePath(centerX, centerY, radius)
|
|
42
|
+
project.children.push(
|
|
43
|
+
new ShapePath({
|
|
44
|
+
cutIndex: throughBoardCutSetting.index,
|
|
45
|
+
verts: circlePath.verts,
|
|
46
|
+
prims: circlePath.prims,
|
|
47
|
+
isClosed: true,
|
|
48
|
+
}),
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { PcbHoleOval } from "circuit-json"
|
|
2
|
+
import type { ConvertContext } from "../../ConvertContext"
|
|
3
|
+
import { ShapePath } from "lbrnts"
|
|
4
|
+
import { createOvalPath } from "../../helpers/ovalShape"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Adds an oval PCB hole (non-plated) to the project
|
|
8
|
+
*/
|
|
9
|
+
export const addOvalPcbHole = (
|
|
10
|
+
hole: PcbHoleOval,
|
|
11
|
+
ctx: ConvertContext,
|
|
12
|
+
): void => {
|
|
13
|
+
const {
|
|
14
|
+
project,
|
|
15
|
+
throughBoardCutSetting,
|
|
16
|
+
soldermaskCutSetting,
|
|
17
|
+
origin,
|
|
18
|
+
includeSoldermask,
|
|
19
|
+
soldermaskMargin,
|
|
20
|
+
} = ctx
|
|
21
|
+
const centerX = hole.x + origin.x
|
|
22
|
+
const centerY = hole.y + origin.y
|
|
23
|
+
|
|
24
|
+
// Add soldermask opening if drawing soldermask
|
|
25
|
+
if (hole.hole_width > 0 && hole.hole_height > 0 && includeSoldermask) {
|
|
26
|
+
const soldermaskPath = createOvalPath(
|
|
27
|
+
centerX,
|
|
28
|
+
centerY,
|
|
29
|
+
hole.hole_width + soldermaskMargin * 2,
|
|
30
|
+
hole.hole_height + soldermaskMargin * 2,
|
|
31
|
+
)
|
|
32
|
+
project.children.push(
|
|
33
|
+
new ShapePath({
|
|
34
|
+
cutIndex: soldermaskCutSetting.index,
|
|
35
|
+
verts: soldermaskPath.verts,
|
|
36
|
+
prims: soldermaskPath.prims,
|
|
37
|
+
isClosed: true,
|
|
38
|
+
}),
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Add the hole - cut through the board
|
|
43
|
+
if (hole.hole_width > 0 && hole.hole_height > 0) {
|
|
44
|
+
const ovalPath = createOvalPath(
|
|
45
|
+
centerX,
|
|
46
|
+
centerY,
|
|
47
|
+
hole.hole_width,
|
|
48
|
+
hole.hole_height,
|
|
49
|
+
)
|
|
50
|
+
project.children.push(
|
|
51
|
+
new ShapePath({
|
|
52
|
+
cutIndex: throughBoardCutSetting.index,
|
|
53
|
+
verts: ovalPath.verts,
|
|
54
|
+
prims: ovalPath.prims,
|
|
55
|
+
isClosed: true,
|
|
56
|
+
}),
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { PcbHolePill } from "circuit-json"
|
|
2
|
+
import type { ConvertContext } from "../../ConvertContext"
|
|
3
|
+
import { ShapePath } from "lbrnts"
|
|
4
|
+
import { createPillPath } from "../../helpers/pillShape"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Adds a pill-shaped PCB hole (non-plated) to the project
|
|
8
|
+
*/
|
|
9
|
+
export const addPillPcbHole = (
|
|
10
|
+
hole: PcbHolePill,
|
|
11
|
+
ctx: ConvertContext,
|
|
12
|
+
): void => {
|
|
13
|
+
const {
|
|
14
|
+
project,
|
|
15
|
+
throughBoardCutSetting,
|
|
16
|
+
soldermaskCutSetting,
|
|
17
|
+
origin,
|
|
18
|
+
includeSoldermask,
|
|
19
|
+
soldermaskMargin,
|
|
20
|
+
} = ctx
|
|
21
|
+
const centerX = hole.x + origin.x
|
|
22
|
+
const centerY = hole.y + origin.y
|
|
23
|
+
|
|
24
|
+
// Add soldermask opening if drawing soldermask
|
|
25
|
+
if (hole.hole_width > 0 && hole.hole_height > 0 && includeSoldermask) {
|
|
26
|
+
const soldermaskPath = createPillPath(
|
|
27
|
+
centerX,
|
|
28
|
+
centerY,
|
|
29
|
+
hole.hole_width + soldermaskMargin * 2,
|
|
30
|
+
hole.hole_height + soldermaskMargin * 2,
|
|
31
|
+
)
|
|
32
|
+
project.children.push(
|
|
33
|
+
new ShapePath({
|
|
34
|
+
cutIndex: soldermaskCutSetting.index,
|
|
35
|
+
verts: soldermaskPath.verts,
|
|
36
|
+
prims: soldermaskPath.prims,
|
|
37
|
+
isClosed: true,
|
|
38
|
+
}),
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Add the hole - cut through the board
|
|
43
|
+
if (hole.hole_width > 0 && hole.hole_height > 0) {
|
|
44
|
+
const pillPath = createPillPath(
|
|
45
|
+
centerX,
|
|
46
|
+
centerY,
|
|
47
|
+
hole.hole_width,
|
|
48
|
+
hole.hole_height,
|
|
49
|
+
)
|
|
50
|
+
project.children.push(
|
|
51
|
+
new ShapePath({
|
|
52
|
+
cutIndex: throughBoardCutSetting.index,
|
|
53
|
+
verts: pillPath.verts,
|
|
54
|
+
prims: pillPath.prims,
|
|
55
|
+
isClosed: true,
|
|
56
|
+
}),
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { PcbHoleRect } from "circuit-json"
|
|
2
|
+
import type { ConvertContext } from "../../ConvertContext"
|
|
3
|
+
import { ShapePath } from "lbrnts"
|
|
4
|
+
import { createRoundedRectPath } from "../../helpers/roundedRectShape"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Adds a rectangular PCB hole (non-plated) to the project
|
|
8
|
+
*/
|
|
9
|
+
export const addRectPcbHole = (
|
|
10
|
+
hole: PcbHoleRect,
|
|
11
|
+
ctx: ConvertContext,
|
|
12
|
+
): void => {
|
|
13
|
+
const {
|
|
14
|
+
project,
|
|
15
|
+
throughBoardCutSetting,
|
|
16
|
+
soldermaskCutSetting,
|
|
17
|
+
origin,
|
|
18
|
+
includeSoldermask,
|
|
19
|
+
soldermaskMargin,
|
|
20
|
+
} = ctx
|
|
21
|
+
const centerX = hole.x + origin.x
|
|
22
|
+
const centerY = hole.y + origin.y
|
|
23
|
+
|
|
24
|
+
// Add soldermask opening if drawing soldermask
|
|
25
|
+
if (hole.hole_width > 0 && hole.hole_height > 0 && includeSoldermask) {
|
|
26
|
+
const soldermaskPath = createRoundedRectPath(
|
|
27
|
+
centerX,
|
|
28
|
+
centerY,
|
|
29
|
+
hole.hole_width + soldermaskMargin * 2,
|
|
30
|
+
hole.hole_height + soldermaskMargin * 2,
|
|
31
|
+
0, // no border radius for rect holes
|
|
32
|
+
)
|
|
33
|
+
project.children.push(
|
|
34
|
+
new ShapePath({
|
|
35
|
+
cutIndex: soldermaskCutSetting.index,
|
|
36
|
+
verts: soldermaskPath.verts,
|
|
37
|
+
prims: soldermaskPath.prims,
|
|
38
|
+
isClosed: true,
|
|
39
|
+
}),
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Add the hole - cut through the board
|
|
44
|
+
if (hole.hole_width > 0 && hole.hole_height > 0) {
|
|
45
|
+
const rectPath = createRoundedRectPath(
|
|
46
|
+
centerX,
|
|
47
|
+
centerY,
|
|
48
|
+
hole.hole_width,
|
|
49
|
+
hole.hole_height,
|
|
50
|
+
0, // no border radius for rect holes
|
|
51
|
+
)
|
|
52
|
+
project.children.push(
|
|
53
|
+
new ShapePath({
|
|
54
|
+
cutIndex: throughBoardCutSetting.index,
|
|
55
|
+
verts: rectPath.verts,
|
|
56
|
+
prims: rectPath.prims,
|
|
57
|
+
isClosed: true,
|
|
58
|
+
}),
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { PcbHoleRotatedPill } from "circuit-json"
|
|
2
|
+
import type { ConvertContext } from "../../ConvertContext"
|
|
3
|
+
import { ShapePath } from "lbrnts"
|
|
4
|
+
import { createPillPath } from "../../helpers/pillShape"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Adds a rotated pill-shaped PCB hole (non-plated) to the project
|
|
8
|
+
*/
|
|
9
|
+
export const addRotatedPillPcbHole = (
|
|
10
|
+
hole: PcbHoleRotatedPill,
|
|
11
|
+
ctx: ConvertContext,
|
|
12
|
+
): void => {
|
|
13
|
+
const {
|
|
14
|
+
project,
|
|
15
|
+
throughBoardCutSetting,
|
|
16
|
+
soldermaskCutSetting,
|
|
17
|
+
origin,
|
|
18
|
+
includeSoldermask,
|
|
19
|
+
soldermaskMargin,
|
|
20
|
+
} = ctx
|
|
21
|
+
const centerX = hole.x + origin.x
|
|
22
|
+
const centerY = hole.y + origin.y
|
|
23
|
+
const rotation = (hole.ccw_rotation || 0) * (Math.PI / 180) // Convert degrees to radians
|
|
24
|
+
|
|
25
|
+
// Add soldermask opening if drawing soldermask
|
|
26
|
+
if (hole.hole_width > 0 && hole.hole_height > 0 && includeSoldermask) {
|
|
27
|
+
const soldermaskPath = createPillPath(
|
|
28
|
+
centerX,
|
|
29
|
+
centerY,
|
|
30
|
+
hole.hole_width + soldermaskMargin * 2,
|
|
31
|
+
hole.hole_height + soldermaskMargin * 2,
|
|
32
|
+
rotation,
|
|
33
|
+
)
|
|
34
|
+
project.children.push(
|
|
35
|
+
new ShapePath({
|
|
36
|
+
cutIndex: soldermaskCutSetting.index,
|
|
37
|
+
verts: soldermaskPath.verts,
|
|
38
|
+
prims: soldermaskPath.prims,
|
|
39
|
+
isClosed: true,
|
|
40
|
+
}),
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Add the hole - cut through the board
|
|
45
|
+
if (hole.hole_width > 0 && hole.hole_height > 0) {
|
|
46
|
+
const pillPath = createPillPath(
|
|
47
|
+
centerX,
|
|
48
|
+
centerY,
|
|
49
|
+
hole.hole_width,
|
|
50
|
+
hole.hole_height,
|
|
51
|
+
rotation,
|
|
52
|
+
)
|
|
53
|
+
project.children.push(
|
|
54
|
+
new ShapePath({
|
|
55
|
+
cutIndex: throughBoardCutSetting.index,
|
|
56
|
+
verts: pillPath.verts,
|
|
57
|
+
prims: pillPath.prims,
|
|
58
|
+
isClosed: true,
|
|
59
|
+
}),
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
}
|