circuit-json-to-lbrn 0.0.14 → 0.0.16
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 +1 -0
- package/dist/index.js +218 -90
- package/lib/ConvertContext.ts +3 -0
- package/lib/element-handlers/addPcbVia/index.ts +84 -0
- package/lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts +3 -2
- package/lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts +13 -2
- package/lib/element-handlers/addPlatedHole/addHoleWithPolygonPad.ts +3 -0
- package/lib/element-handlers/addPlatedHole/addOvalPlatedHole.ts +4 -7
- package/lib/element-handlers/addPlatedHole/addPillHoleWithRectPad.ts +13 -2
- package/lib/element-handlers/addPlatedHole/addPillPlatedHole.ts +4 -7
- package/lib/element-handlers/addPlatedHole/addRotatedPillHoleWithRectPad.ts +15 -2
- package/lib/element-handlers/addSmtPad/addCircleSmtPad.ts +3 -1
- package/lib/element-handlers/addSmtPad/addPillSmtPad.ts +7 -2
- package/lib/element-handlers/addSmtPad/addPolygonSmtPad.ts +6 -0
- package/lib/element-handlers/addSmtPad/addRectSmtPad.ts +9 -5
- package/lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts +13 -2
- package/lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts +15 -2
- package/lib/index.ts +7 -0
- package/package.json +1 -1
- 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/tests/examples/soldermask-margin/__snapshots__/negative-soldermask-margin.snap.svg +8 -0
- package/tests/examples/soldermask-margin/__snapshots__/positive-soldermask-margin.snap.svg +8 -0
- package/tests/examples/soldermask-margin/negative-soldermask-margin.test.ts +85 -0
- package/tests/examples/soldermask-margin/positive-soldermask-margin.test.ts +85 -0
package/dist/index.d.ts
CHANGED
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 ShapePath16 } from "lbrnts";
|
|
3
3
|
import { cju as cju2 } from "@tscircuit/circuit-json-util";
|
|
4
4
|
|
|
5
5
|
// lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts
|
|
@@ -52,7 +52,8 @@ var addCirclePlatedHole = (platedHole, ctx) => {
|
|
|
52
52
|
origin,
|
|
53
53
|
includeCopper,
|
|
54
54
|
includeSoldermask,
|
|
55
|
-
connMap
|
|
55
|
+
connMap,
|
|
56
|
+
soldermaskMargin
|
|
56
57
|
} = ctx;
|
|
57
58
|
const centerX = platedHole.x + origin.x;
|
|
58
59
|
const centerY = platedHole.y + origin.y;
|
|
@@ -76,8 +77,8 @@ var addCirclePlatedHole = (platedHole, ctx) => {
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
if (platedHole.outer_diameter > 0 && includeSoldermask) {
|
|
79
|
-
const
|
|
80
|
-
const outer = createCirclePath(centerX, centerY,
|
|
80
|
+
const smRadius = platedHole.outer_diameter / 2 + soldermaskMargin;
|
|
81
|
+
const outer = createCirclePath(centerX, centerY, smRadius);
|
|
81
82
|
project.children.push(
|
|
82
83
|
new ShapePath({
|
|
83
84
|
cutIndex: soldermaskCutSetting.index,
|
|
@@ -140,7 +141,8 @@ var addOvalPlatedHole = (platedHole, ctx) => {
|
|
|
140
141
|
throughBoardCutSetting,
|
|
141
142
|
origin,
|
|
142
143
|
includeCopper,
|
|
143
|
-
includeSoldermask
|
|
144
|
+
includeSoldermask,
|
|
145
|
+
soldermaskMargin
|
|
144
146
|
} = ctx;
|
|
145
147
|
if (platedHole.outer_width <= 0 || platedHole.outer_height <= 0) {
|
|
146
148
|
return;
|
|
@@ -166,13 +168,9 @@ var addOvalPlatedHole = (platedHole, ctx) => {
|
|
|
166
168
|
);
|
|
167
169
|
}
|
|
168
170
|
if (platedHole.outer_width > 0 && platedHole.outer_height > 0 && includeSoldermask) {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
platedHole.outer_width,
|
|
173
|
-
platedHole.outer_height,
|
|
174
|
-
rotation
|
|
175
|
-
);
|
|
171
|
+
const smWidth = platedHole.outer_width + 2 * soldermaskMargin;
|
|
172
|
+
const smHeight = platedHole.outer_height + 2 * soldermaskMargin;
|
|
173
|
+
const outer = createOvalPath(centerX, centerY, smWidth, smHeight, rotation);
|
|
176
174
|
project.children.push(
|
|
177
175
|
new ShapePath2({
|
|
178
176
|
cutIndex: soldermaskCutSetting.index,
|
|
@@ -294,7 +292,8 @@ var addCircularHoleWithRectPad = (platedHole, ctx) => {
|
|
|
294
292
|
throughBoardCutSetting,
|
|
295
293
|
origin,
|
|
296
294
|
includeCopper,
|
|
297
|
-
includeSoldermask
|
|
295
|
+
includeSoldermask,
|
|
296
|
+
soldermaskMargin
|
|
298
297
|
} = ctx;
|
|
299
298
|
const centerX = platedHole.x + origin.x;
|
|
300
299
|
const centerY = platedHole.y + origin.y;
|
|
@@ -320,11 +319,20 @@ var addCircularHoleWithRectPad = (platedHole, ctx) => {
|
|
|
320
319
|
);
|
|
321
320
|
}
|
|
322
321
|
if (includeSoldermask) {
|
|
322
|
+
const smPadWidth = padWidth + 2 * soldermaskMargin;
|
|
323
|
+
const smPadHeight = padHeight + 2 * soldermaskMargin;
|
|
324
|
+
const smPadPath = createRoundedRectPath(
|
|
325
|
+
centerX,
|
|
326
|
+
centerY,
|
|
327
|
+
smPadWidth,
|
|
328
|
+
smPadHeight,
|
|
329
|
+
borderRadius
|
|
330
|
+
);
|
|
323
331
|
project.children.push(
|
|
324
332
|
new ShapePath3({
|
|
325
333
|
cutIndex: soldermaskCutSetting.index,
|
|
326
|
-
verts:
|
|
327
|
-
prims:
|
|
334
|
+
verts: smPadPath.verts,
|
|
335
|
+
prims: smPadPath.prims,
|
|
328
336
|
isClosed: true
|
|
329
337
|
})
|
|
330
338
|
);
|
|
@@ -435,7 +443,8 @@ var addPillHoleWithRectPad = (platedHole, ctx) => {
|
|
|
435
443
|
throughBoardCutSetting,
|
|
436
444
|
origin,
|
|
437
445
|
includeCopper,
|
|
438
|
-
includeSoldermask
|
|
446
|
+
includeSoldermask,
|
|
447
|
+
soldermaskMargin
|
|
439
448
|
} = ctx;
|
|
440
449
|
const centerX = platedHole.x + origin.x;
|
|
441
450
|
const centerY = platedHole.y + origin.y;
|
|
@@ -461,11 +470,20 @@ var addPillHoleWithRectPad = (platedHole, ctx) => {
|
|
|
461
470
|
);
|
|
462
471
|
}
|
|
463
472
|
if (includeSoldermask) {
|
|
473
|
+
const smPadWidth = padWidth + 2 * soldermaskMargin;
|
|
474
|
+
const smPadHeight = padHeight + 2 * soldermaskMargin;
|
|
475
|
+
const smPadPath = createRoundedRectPath(
|
|
476
|
+
centerX,
|
|
477
|
+
centerY,
|
|
478
|
+
smPadWidth,
|
|
479
|
+
smPadHeight,
|
|
480
|
+
borderRadius
|
|
481
|
+
);
|
|
464
482
|
project.children.push(
|
|
465
483
|
new ShapePath4({
|
|
466
484
|
cutIndex: soldermaskCutSetting.index,
|
|
467
|
-
verts:
|
|
468
|
-
prims:
|
|
485
|
+
verts: smPadPath.verts,
|
|
486
|
+
prims: smPadPath.prims,
|
|
469
487
|
isClosed: true
|
|
470
488
|
})
|
|
471
489
|
);
|
|
@@ -503,7 +521,8 @@ var addRotatedPillHoleWithRectPad = (platedHole, ctx) => {
|
|
|
503
521
|
throughBoardCutSetting,
|
|
504
522
|
origin,
|
|
505
523
|
includeCopper,
|
|
506
|
-
includeSoldermask
|
|
524
|
+
includeSoldermask,
|
|
525
|
+
soldermaskMargin
|
|
507
526
|
} = ctx;
|
|
508
527
|
const centerX = platedHole.x + origin.x;
|
|
509
528
|
const centerY = platedHole.y + origin.y;
|
|
@@ -532,11 +551,22 @@ var addRotatedPillHoleWithRectPad = (platedHole, ctx) => {
|
|
|
532
551
|
);
|
|
533
552
|
}
|
|
534
553
|
if (includeSoldermask) {
|
|
554
|
+
const smPadWidth = padWidth + 2 * soldermaskMargin;
|
|
555
|
+
const smPadHeight = padHeight + 2 * soldermaskMargin;
|
|
556
|
+
const smPadPath = createRoundedRectPath(
|
|
557
|
+
centerX,
|
|
558
|
+
centerY,
|
|
559
|
+
smPadWidth,
|
|
560
|
+
smPadHeight,
|
|
561
|
+
borderRadius,
|
|
562
|
+
4,
|
|
563
|
+
padRotation
|
|
564
|
+
);
|
|
535
565
|
project.children.push(
|
|
536
566
|
new ShapePath5({
|
|
537
567
|
cutIndex: soldermaskCutSetting.index,
|
|
538
|
-
verts:
|
|
539
|
-
prims:
|
|
568
|
+
verts: smPadPath.verts,
|
|
569
|
+
prims: smPadPath.prims,
|
|
540
570
|
isClosed: true
|
|
541
571
|
})
|
|
542
572
|
);
|
|
@@ -572,9 +602,9 @@ import { ShapePath as ShapePath6 } from "lbrnts";
|
|
|
572
602
|
// lib/helpers/polygonShape.ts
|
|
573
603
|
var createPolygonPathFromOutline = (outline, offsetX, offsetY) => {
|
|
574
604
|
const verts = [];
|
|
575
|
-
for (const
|
|
576
|
-
const x = (
|
|
577
|
-
const y = (
|
|
605
|
+
for (const point6 of outline) {
|
|
606
|
+
const x = (point6.x ?? 0) + offsetX;
|
|
607
|
+
const y = (point6.y ?? 0) + offsetY;
|
|
578
608
|
verts.push({ x, y });
|
|
579
609
|
}
|
|
580
610
|
if (verts.length === 0) {
|
|
@@ -595,7 +625,8 @@ var addHoleWithPolygonPad = (platedHole, ctx) => {
|
|
|
595
625
|
throughBoardCutSetting,
|
|
596
626
|
origin,
|
|
597
627
|
includeCopper,
|
|
598
|
-
includeSoldermask
|
|
628
|
+
includeSoldermask,
|
|
629
|
+
soldermaskMargin
|
|
599
630
|
} = ctx;
|
|
600
631
|
if (platedHole.pad_outline.length >= 3) {
|
|
601
632
|
const pad = createPolygonPathFromOutline(
|
|
@@ -664,7 +695,8 @@ var addPcbPlatedHolePill = (platedHole, ctx) => {
|
|
|
664
695
|
throughBoardCutSetting,
|
|
665
696
|
origin,
|
|
666
697
|
includeCopper,
|
|
667
|
-
includeSoldermask
|
|
698
|
+
includeSoldermask,
|
|
699
|
+
soldermaskMargin
|
|
668
700
|
} = ctx;
|
|
669
701
|
const centerX = platedHole.x + origin.x;
|
|
670
702
|
const centerY = platedHole.y + origin.y;
|
|
@@ -687,13 +719,9 @@ var addPcbPlatedHolePill = (platedHole, ctx) => {
|
|
|
687
719
|
);
|
|
688
720
|
}
|
|
689
721
|
if (platedHole.outer_width > 0 && platedHole.outer_height > 0 && includeSoldermask) {
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
platedHole.outer_width,
|
|
694
|
-
platedHole.outer_height,
|
|
695
|
-
rotation
|
|
696
|
-
);
|
|
722
|
+
const smWidth = platedHole.outer_width + 2 * soldermaskMargin;
|
|
723
|
+
const smHeight = platedHole.outer_height + 2 * soldermaskMargin;
|
|
724
|
+
const outer = createPillPath(centerX, centerY, smWidth, smHeight, rotation);
|
|
697
725
|
project.children.push(
|
|
698
726
|
new ShapePath7({
|
|
699
727
|
cutIndex: soldermaskCutSetting.index,
|
|
@@ -757,7 +785,8 @@ var addRectSmtPad = (smtPad, ctx) => {
|
|
|
757
785
|
netGeoms,
|
|
758
786
|
origin,
|
|
759
787
|
includeCopper,
|
|
760
|
-
includeSoldermask
|
|
788
|
+
includeSoldermask,
|
|
789
|
+
soldermaskMargin
|
|
761
790
|
} = ctx;
|
|
762
791
|
const centerX = smtPad.x + origin.x;
|
|
763
792
|
const centerY = smtPad.y + origin.y;
|
|
@@ -801,12 +830,14 @@ var addRectSmtPad = (smtPad, ctx) => {
|
|
|
801
830
|
}
|
|
802
831
|
}
|
|
803
832
|
if (includeSoldermask) {
|
|
833
|
+
const smHalfWidth = halfWidth + soldermaskMargin;
|
|
834
|
+
const smHalfHeight = halfHeight + soldermaskMargin;
|
|
804
835
|
const verts = [
|
|
805
|
-
{ x: centerX -
|
|
806
|
-
{ x: centerX +
|
|
807
|
-
{ x: centerX +
|
|
808
|
-
{ x: centerX -
|
|
809
|
-
{ x: centerX -
|
|
836
|
+
{ x: centerX - smHalfWidth, y: centerY - smHalfHeight },
|
|
837
|
+
{ x: centerX + smHalfWidth, y: centerY - smHalfHeight },
|
|
838
|
+
{ x: centerX + smHalfWidth, y: centerY + smHalfHeight },
|
|
839
|
+
{ x: centerX - smHalfWidth, y: centerY + smHalfHeight },
|
|
840
|
+
{ x: centerX - smHalfWidth, y: centerY - smHalfHeight }
|
|
810
841
|
// Close the path
|
|
811
842
|
];
|
|
812
843
|
const prims = [
|
|
@@ -838,7 +869,8 @@ var addCircleSmtPad = (smtPad, ctx) => {
|
|
|
838
869
|
origin,
|
|
839
870
|
includeCopper,
|
|
840
871
|
includeSoldermask,
|
|
841
|
-
connMap
|
|
872
|
+
connMap,
|
|
873
|
+
soldermaskMargin
|
|
842
874
|
} = ctx;
|
|
843
875
|
const centerX = smtPad.x + origin.x;
|
|
844
876
|
const centerY = smtPad.y + origin.y;
|
|
@@ -863,7 +895,8 @@ var addCircleSmtPad = (smtPad, ctx) => {
|
|
|
863
895
|
}
|
|
864
896
|
}
|
|
865
897
|
if (includeSoldermask) {
|
|
866
|
-
const
|
|
898
|
+
const smRadius = outerRadius + soldermaskMargin;
|
|
899
|
+
const outer = createCirclePath(centerX, centerY, smRadius);
|
|
867
900
|
project.children.push(
|
|
868
901
|
new ShapePath9({
|
|
869
902
|
cutIndex: soldermaskCutSetting.index,
|
|
@@ -895,7 +928,8 @@ var addPillSmtPad = (smtPad, ctx) => {
|
|
|
895
928
|
origin,
|
|
896
929
|
includeCopper,
|
|
897
930
|
includeSoldermask,
|
|
898
|
-
connMap
|
|
931
|
+
connMap,
|
|
932
|
+
soldermaskMargin
|
|
899
933
|
} = ctx;
|
|
900
934
|
const centerX = smtPad.x + origin.x;
|
|
901
935
|
const centerY = smtPad.y + origin.y;
|
|
@@ -918,11 +952,14 @@ var addPillSmtPad = (smtPad, ctx) => {
|
|
|
918
952
|
}
|
|
919
953
|
}
|
|
920
954
|
if (includeSoldermask) {
|
|
955
|
+
const smWidth = smtPad.width + 2 * soldermaskMargin;
|
|
956
|
+
const smHeight = smtPad.height + 2 * soldermaskMargin;
|
|
957
|
+
const smOuter = createPillPath(centerX, centerY, smWidth, smHeight);
|
|
921
958
|
project.children.push(
|
|
922
959
|
new ShapePath10({
|
|
923
960
|
cutIndex: soldermaskCutSetting.index,
|
|
924
|
-
verts:
|
|
925
|
-
prims:
|
|
961
|
+
verts: smOuter.verts,
|
|
962
|
+
prims: smOuter.prims,
|
|
926
963
|
isClosed: true
|
|
927
964
|
})
|
|
928
965
|
);
|
|
@@ -940,7 +977,8 @@ var addRotatedPillSmtPad = (smtPad, ctx) => {
|
|
|
940
977
|
origin,
|
|
941
978
|
includeCopper,
|
|
942
979
|
includeSoldermask,
|
|
943
|
-
connMap
|
|
980
|
+
connMap,
|
|
981
|
+
soldermaskMargin
|
|
944
982
|
} = ctx;
|
|
945
983
|
const centerX = smtPad.x + origin.x;
|
|
946
984
|
const centerY = smtPad.y + origin.y;
|
|
@@ -969,11 +1007,20 @@ var addRotatedPillSmtPad = (smtPad, ctx) => {
|
|
|
969
1007
|
}
|
|
970
1008
|
}
|
|
971
1009
|
if (includeSoldermask) {
|
|
1010
|
+
const smWidth = smtPad.width + 2 * soldermaskMargin;
|
|
1011
|
+
const smHeight = smtPad.height + 2 * soldermaskMargin;
|
|
1012
|
+
const smOuter = createPillPath(
|
|
1013
|
+
centerX,
|
|
1014
|
+
centerY,
|
|
1015
|
+
smWidth,
|
|
1016
|
+
smHeight,
|
|
1017
|
+
(smtPad.ccw_rotation ?? 0) * (Math.PI / 180)
|
|
1018
|
+
);
|
|
972
1019
|
project.children.push(
|
|
973
1020
|
new ShapePath11({
|
|
974
1021
|
cutIndex: soldermaskCutSetting.index,
|
|
975
|
-
verts:
|
|
976
|
-
prims:
|
|
1022
|
+
verts: smOuter.verts,
|
|
1023
|
+
prims: smOuter.prims,
|
|
977
1024
|
isClosed: true
|
|
978
1025
|
})
|
|
979
1026
|
);
|
|
@@ -983,6 +1030,35 @@ var addRotatedPillSmtPad = (smtPad, ctx) => {
|
|
|
983
1030
|
|
|
984
1031
|
// lib/element-handlers/addSmtPad/addPolygonSmtPad.ts
|
|
985
1032
|
import { ShapePath as ShapePath12 } from "lbrnts";
|
|
1033
|
+
|
|
1034
|
+
// lib/polygon-to-shape-path.ts
|
|
1035
|
+
function polygonToShapePathData(polygon) {
|
|
1036
|
+
const verts = [];
|
|
1037
|
+
const prims = [];
|
|
1038
|
+
const svgString = polygon.svg();
|
|
1039
|
+
const dAttributeMatch = svgString.match(/\bd="([^"]+)"/);
|
|
1040
|
+
if (!dAttributeMatch || !dAttributeMatch[1]) {
|
|
1041
|
+
return { verts, prims };
|
|
1042
|
+
}
|
|
1043
|
+
const pathData = dAttributeMatch[1].trim();
|
|
1044
|
+
const commands = pathData.match(/[MLz][^MLz]*/g) || [];
|
|
1045
|
+
for (const command of commands) {
|
|
1046
|
+
const type = command[0];
|
|
1047
|
+
const coords = command.slice(1).trim();
|
|
1048
|
+
if (type === "M" || type === "L") {
|
|
1049
|
+
const parts = coords.split(",");
|
|
1050
|
+
const x = Number(parts[0]);
|
|
1051
|
+
const y = Number(parts[1]);
|
|
1052
|
+
if (!Number.isNaN(x) && !Number.isNaN(y)) {
|
|
1053
|
+
verts.push({ x, y });
|
|
1054
|
+
prims.push({ type: 0 });
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
return { verts, prims };
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
// lib/element-handlers/addSmtPad/addPolygonSmtPad.ts
|
|
986
1062
|
var addPolygonSmtPad = (smtPad, ctx) => {
|
|
987
1063
|
const {
|
|
988
1064
|
project,
|
|
@@ -991,7 +1067,8 @@ var addPolygonSmtPad = (smtPad, ctx) => {
|
|
|
991
1067
|
origin,
|
|
992
1068
|
includeCopper,
|
|
993
1069
|
includeSoldermask,
|
|
994
|
-
connMap
|
|
1070
|
+
connMap,
|
|
1071
|
+
soldermaskMargin
|
|
995
1072
|
} = ctx;
|
|
996
1073
|
if (smtPad.points.length >= 3) {
|
|
997
1074
|
const pad = createPolygonPathFromOutline(smtPad.points, origin.x, origin.y);
|
|
@@ -1034,7 +1111,8 @@ var addRotatedRectSmtPad = (smtPad, ctx) => {
|
|
|
1034
1111
|
origin,
|
|
1035
1112
|
includeCopper,
|
|
1036
1113
|
includeSoldermask,
|
|
1037
|
-
connMap
|
|
1114
|
+
connMap,
|
|
1115
|
+
soldermaskMargin
|
|
1038
1116
|
} = ctx;
|
|
1039
1117
|
const centerX = smtPad.x + origin.x;
|
|
1040
1118
|
const centerY = smtPad.y + origin.y;
|
|
@@ -1067,11 +1145,22 @@ var addRotatedRectSmtPad = (smtPad, ctx) => {
|
|
|
1067
1145
|
}
|
|
1068
1146
|
}
|
|
1069
1147
|
if (includeSoldermask) {
|
|
1148
|
+
const smWidth = smtPad.width + 2 * soldermaskMargin;
|
|
1149
|
+
const smHeight = smtPad.height + 2 * soldermaskMargin;
|
|
1150
|
+
const smOuter = createRoundedRectPath(
|
|
1151
|
+
centerX,
|
|
1152
|
+
centerY,
|
|
1153
|
+
smWidth,
|
|
1154
|
+
smHeight,
|
|
1155
|
+
borderRadius,
|
|
1156
|
+
4,
|
|
1157
|
+
rotation
|
|
1158
|
+
);
|
|
1070
1159
|
project.children.push(
|
|
1071
1160
|
new ShapePath13({
|
|
1072
1161
|
cutIndex: soldermaskCutSetting.index,
|
|
1073
|
-
verts:
|
|
1074
|
-
prims:
|
|
1162
|
+
verts: smOuter.verts,
|
|
1163
|
+
prims: smOuter.prims,
|
|
1075
1164
|
isClosed: true
|
|
1076
1165
|
})
|
|
1077
1166
|
);
|
|
@@ -1118,7 +1207,7 @@ var addPcbTrace = (trace, ctx) => {
|
|
|
1118
1207
|
return;
|
|
1119
1208
|
}
|
|
1120
1209
|
const { route } = trace;
|
|
1121
|
-
const traceWidth = route.find((
|
|
1210
|
+
const traceWidth = route.find((point6) => point6.route_type === "wire")?.width ?? 0.15;
|
|
1122
1211
|
const polygons = [];
|
|
1123
1212
|
for (const routePoint of route) {
|
|
1124
1213
|
const circle = new Flatten2.Circle(
|
|
@@ -1169,35 +1258,6 @@ var addPcbTrace = (trace, ctx) => {
|
|
|
1169
1258
|
// lib/element-handlers/addPcbBoard/index.ts
|
|
1170
1259
|
import { Polygon as Polygon3, point as point4 } from "@flatten-js/core";
|
|
1171
1260
|
import { ShapePath as ShapePath14 } from "lbrnts";
|
|
1172
|
-
|
|
1173
|
-
// lib/polygon-to-shape-path.ts
|
|
1174
|
-
function polygonToShapePathData(polygon) {
|
|
1175
|
-
const verts = [];
|
|
1176
|
-
const prims = [];
|
|
1177
|
-
const svgString = polygon.svg();
|
|
1178
|
-
const dAttributeMatch = svgString.match(/\bd="([^"]+)"/);
|
|
1179
|
-
if (!dAttributeMatch || !dAttributeMatch[1]) {
|
|
1180
|
-
return { verts, prims };
|
|
1181
|
-
}
|
|
1182
|
-
const pathData = dAttributeMatch[1].trim();
|
|
1183
|
-
const commands = pathData.match(/[MLz][^MLz]*/g) || [];
|
|
1184
|
-
for (const command of commands) {
|
|
1185
|
-
const type = command[0];
|
|
1186
|
-
const coords = command.slice(1).trim();
|
|
1187
|
-
if (type === "M" || type === "L") {
|
|
1188
|
-
const parts = coords.split(",");
|
|
1189
|
-
const x = Number(parts[0]);
|
|
1190
|
-
const y = Number(parts[1]);
|
|
1191
|
-
if (!Number.isNaN(x) && !Number.isNaN(y)) {
|
|
1192
|
-
verts.push({ x, y });
|
|
1193
|
-
prims.push({ type: 0 });
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
return { verts, prims };
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
// lib/element-handlers/addPcbBoard/index.ts
|
|
1201
1261
|
var addPcbBoard = (board, ctx) => {
|
|
1202
1262
|
const {
|
|
1203
1263
|
origin,
|
|
@@ -1281,14 +1341,14 @@ var calculateCircuitBounds = (circuitJson) => {
|
|
|
1281
1341
|
}
|
|
1282
1342
|
}
|
|
1283
1343
|
for (const trace of db.pcb_trace.list()) {
|
|
1284
|
-
const isWidthPoint = (
|
|
1344
|
+
const isWidthPoint = (point6) => "width" in point6 && typeof point6.width === "number";
|
|
1285
1345
|
const halfWidth = trace.route_thickness_mode === "interpolated" ? 0 : (trace.route.find(isWidthPoint)?.width ?? 0) / 2;
|
|
1286
|
-
for (const
|
|
1287
|
-
const pointWidth = trace.route_thickness_mode === "interpolated" ? isWidthPoint(
|
|
1288
|
-
minX = Math.min(minX,
|
|
1289
|
-
minY = Math.min(minY,
|
|
1290
|
-
maxX = Math.max(maxX,
|
|
1291
|
-
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);
|
|
1292
1352
|
}
|
|
1293
1353
|
}
|
|
1294
1354
|
for (const hole of db.pcb_plated_hole.list()) {
|
|
@@ -1312,6 +1372,70 @@ var calculateOriginFromBounds = (bounds, margin) => {
|
|
|
1312
1372
|
return { x: originX, y: originY };
|
|
1313
1373
|
};
|
|
1314
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
|
+
|
|
1315
1439
|
// lib/index.ts
|
|
1316
1440
|
var convertCircuitJsonToLbrn = (circuitJson, options = {}) => {
|
|
1317
1441
|
const db = cju2(circuitJson);
|
|
@@ -1365,7 +1489,8 @@ var convertCircuitJsonToLbrn = (circuitJson, options = {}) => {
|
|
|
1365
1489
|
netGeoms: /* @__PURE__ */ new Map(),
|
|
1366
1490
|
origin,
|
|
1367
1491
|
includeCopper: options.includeCopper ?? true,
|
|
1368
|
-
includeSoldermask: options.includeSoldermask ?? false
|
|
1492
|
+
includeSoldermask: options.includeSoldermask ?? false,
|
|
1493
|
+
soldermaskMargin: options.soldermaskMargin ?? 0
|
|
1369
1494
|
};
|
|
1370
1495
|
for (const net of Object.keys(connMap.netMap)) {
|
|
1371
1496
|
ctx.netGeoms.set(net, []);
|
|
@@ -1382,6 +1507,9 @@ var convertCircuitJsonToLbrn = (circuitJson, options = {}) => {
|
|
|
1382
1507
|
for (const board of db.pcb_board.list()) {
|
|
1383
1508
|
addPcbBoard(board, ctx);
|
|
1384
1509
|
}
|
|
1510
|
+
for (const via of db.pcb_via.list()) {
|
|
1511
|
+
addPcbVia(via, ctx);
|
|
1512
|
+
}
|
|
1385
1513
|
if (ctx.includeCopper) {
|
|
1386
1514
|
for (const net of Object.keys(connMap.netMap)) {
|
|
1387
1515
|
const netGeoms = ctx.netGeoms.get(net);
|
|
@@ -1402,7 +1530,7 @@ var convertCircuitJsonToLbrn = (circuitJson, options = {}) => {
|
|
|
1402
1530
|
for (const island of union.splitToIslands()) {
|
|
1403
1531
|
const { verts, prims } = polygonToShapePathData(island);
|
|
1404
1532
|
project.children.push(
|
|
1405
|
-
new
|
|
1533
|
+
new ShapePath16({
|
|
1406
1534
|
cutIndex: copperCutSetting.index,
|
|
1407
1535
|
verts,
|
|
1408
1536
|
prims,
|
package/lib/ConvertContext.ts
CHANGED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { PcbVia } from "circuit-json"
|
|
2
|
+
import type { ConvertContext } from "../../ConvertContext"
|
|
3
|
+
import { ShapePath } from "lbrnts"
|
|
4
|
+
import { createCirclePath } from "../../helpers/circleShape"
|
|
5
|
+
import { Circle, point } from "@flatten-js/core"
|
|
6
|
+
import { circleToPolygon } from "../addPcbTrace/circle-to-polygon"
|
|
7
|
+
|
|
8
|
+
export const addPcbVia = (via: PcbVia, ctx: ConvertContext): void => {
|
|
9
|
+
const {
|
|
10
|
+
db,
|
|
11
|
+
project,
|
|
12
|
+
copperCutSetting,
|
|
13
|
+
soldermaskCutSetting,
|
|
14
|
+
throughBoardCutSetting,
|
|
15
|
+
origin,
|
|
16
|
+
includeCopper,
|
|
17
|
+
includeSoldermask,
|
|
18
|
+
connMap,
|
|
19
|
+
soldermaskMargin,
|
|
20
|
+
} = ctx
|
|
21
|
+
const centerX = via.x + origin.x
|
|
22
|
+
const centerY = via.y + origin.y
|
|
23
|
+
|
|
24
|
+
// Add outer circle (copper annulus) if drawing copper - add to netGeoms for merging
|
|
25
|
+
if (via.outer_diameter > 0 && includeCopper) {
|
|
26
|
+
// Find the pcb_port associated with this via (vias don't have pcb_port_id property)
|
|
27
|
+
// We need to find a port at the same location as the via
|
|
28
|
+
const viaPort = db.pcb_port
|
|
29
|
+
.list()
|
|
30
|
+
.find((port) => port.x === via.x && port.y === via.y)
|
|
31
|
+
|
|
32
|
+
const netId = viaPort
|
|
33
|
+
? connMap.getNetConnectedToId(viaPort.pcb_port_id)
|
|
34
|
+
: undefined
|
|
35
|
+
|
|
36
|
+
const outerRadius = via.outer_diameter / 2
|
|
37
|
+
const circle = new Circle(point(centerX, centerY), outerRadius)
|
|
38
|
+
const polygon = circleToPolygon(circle)
|
|
39
|
+
|
|
40
|
+
if (netId) {
|
|
41
|
+
// Add to netGeoms to be merged with other elements on the same net
|
|
42
|
+
ctx.netGeoms.get(netId)?.push(polygon)
|
|
43
|
+
} else {
|
|
44
|
+
// No net connection - draw directly
|
|
45
|
+
const outer = createCirclePath(centerX, centerY, outerRadius)
|
|
46
|
+
project.children.push(
|
|
47
|
+
new ShapePath({
|
|
48
|
+
cutIndex: copperCutSetting.index,
|
|
49
|
+
verts: outer.verts,
|
|
50
|
+
prims: outer.prims,
|
|
51
|
+
isClosed: true,
|
|
52
|
+
}),
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Add soldermask opening if drawing soldermask
|
|
58
|
+
if (via.outer_diameter > 0 && includeSoldermask) {
|
|
59
|
+
const smRadius = via.outer_diameter / 2 + soldermaskMargin
|
|
60
|
+
const outer = createCirclePath(centerX, centerY, smRadius)
|
|
61
|
+
project.children.push(
|
|
62
|
+
new ShapePath({
|
|
63
|
+
cutIndex: soldermaskCutSetting.index,
|
|
64
|
+
verts: outer.verts,
|
|
65
|
+
prims: outer.prims,
|
|
66
|
+
isClosed: true,
|
|
67
|
+
}),
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Add inner circle (hole) - always cut through the board regardless of mode
|
|
72
|
+
if (via.hole_diameter > 0) {
|
|
73
|
+
const innerRadius = via.hole_diameter / 2
|
|
74
|
+
const inner = createCirclePath(centerX, centerY, innerRadius)
|
|
75
|
+
project.children.push(
|
|
76
|
+
new ShapePath({
|
|
77
|
+
cutIndex: throughBoardCutSetting.index,
|
|
78
|
+
verts: inner.verts,
|
|
79
|
+
prims: inner.prims,
|
|
80
|
+
isClosed: true,
|
|
81
|
+
}),
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -18,6 +18,7 @@ export const addCirclePlatedHole = (
|
|
|
18
18
|
includeCopper,
|
|
19
19
|
includeSoldermask,
|
|
20
20
|
connMap,
|
|
21
|
+
soldermaskMargin,
|
|
21
22
|
} = ctx
|
|
22
23
|
const centerX = platedHole.x + origin.x
|
|
23
24
|
const centerY = platedHole.y + origin.y
|
|
@@ -48,8 +49,8 @@ export const addCirclePlatedHole = (
|
|
|
48
49
|
|
|
49
50
|
// Add soldermask opening if drawing soldermask
|
|
50
51
|
if (platedHole.outer_diameter > 0 && includeSoldermask) {
|
|
51
|
-
const
|
|
52
|
-
const outer = createCirclePath(centerX, centerY,
|
|
52
|
+
const smRadius = platedHole.outer_diameter / 2 + soldermaskMargin
|
|
53
|
+
const outer = createCirclePath(centerX, centerY, smRadius)
|
|
53
54
|
project.children.push(
|
|
54
55
|
new ShapePath({
|
|
55
56
|
cutIndex: soldermaskCutSetting.index,
|