circuit-json-to-lbrn 0.0.20 → 0.0.22

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.
Files changed (81) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +784 -345
  3. package/lib/ConvertContext.ts +6 -2
  4. package/lib/element-handlers/addPcbCutout/addCirclePcbCutout.ts +10 -2
  5. package/lib/element-handlers/addPcbCutout/addPolygonPcbCutout.ts +10 -6
  6. package/lib/element-handlers/addPcbCutout/addRectPcbCutout.ts +12 -12
  7. package/lib/element-handlers/addPcbHole/addCirclePcbHole.ts +10 -2
  8. package/lib/element-handlers/addPcbHole/addOvalPcbHole.ts +8 -8
  9. package/lib/element-handlers/addPcbHole/addPillPcbHole.ts +8 -8
  10. package/lib/element-handlers/addPcbHole/addRectPcbHole.ts +10 -10
  11. package/lib/element-handlers/addPcbHole/addRotatedPillPcbHole.ts +8 -8
  12. package/lib/element-handlers/addPcbTrace/index.ts +145 -61
  13. package/lib/element-handlers/addPcbVia/index.ts +49 -15
  14. package/lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts +49 -15
  15. package/lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts +38 -18
  16. package/lib/element-handlers/addPlatedHole/addHoleWithPolygonPad.ts +41 -16
  17. package/lib/element-handlers/addPlatedHole/addOvalPlatedHole.ts +39 -18
  18. package/lib/element-handlers/addPlatedHole/addPillHoleWithRectPad.ts +38 -23
  19. package/lib/element-handlers/addPlatedHole/addPillPlatedHole.ts +39 -18
  20. package/lib/element-handlers/addPlatedHole/addRotatedPillHoleWithRectPad.ts +43 -28
  21. package/lib/element-handlers/addSmtPad/addCircleSmtPad.ts +31 -4
  22. package/lib/element-handlers/addSmtPad/addPillSmtPad.ts +33 -4
  23. package/lib/element-handlers/addSmtPad/addPolygonSmtPad.ts +25 -3
  24. package/lib/element-handlers/addSmtPad/addRectSmtPad.ts +20 -3
  25. package/lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts +31 -12
  26. package/lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts +31 -12
  27. package/lib/helpers/circleShape.ts +13 -6
  28. package/lib/helpers/ovalShape.ts +17 -8
  29. package/lib/helpers/pathPointUtils.ts +11 -5
  30. package/lib/helpers/pillShape.ts +24 -11
  31. package/lib/helpers/polygonShape.ts +11 -5
  32. package/lib/helpers/roundedRectShape.ts +19 -9
  33. package/lib/index.ts +92 -41
  34. package/package.json +1 -1
  35. package/tests/assets/keyboard-default60.json +92565 -0
  36. package/tests/examples/__snapshots__/board-outline-soldermask-preset.snap.svg +1 -1
  37. package/tests/examples/__snapshots__/board-outline.snap.svg +1 -1
  38. package/tests/examples/__snapshots__/lga-interconnect.snap.svg +1 -1
  39. package/tests/examples/__snapshots__/single-trace.snap.svg +1 -1
  40. package/tests/examples/addPcbCutout/__snapshots__/pcb-cutout-circle.snap.svg +1 -1
  41. package/tests/examples/addPcbCutout/__snapshots__/pcb-cutout-path.snap.svg +1 -1
  42. package/tests/examples/addPcbCutout/__snapshots__/pcb-cutout-polygon.snap.svg +1 -1
  43. package/tests/examples/addPcbCutout/__snapshots__/pcb-cutout-rect.snap.svg +1 -1
  44. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-circle.snap.svg +1 -1
  45. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-oval.snap.svg +1 -1
  46. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-pill.snap.svg +1 -1
  47. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-rect.snap.svg +1 -1
  48. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-rotated-pill.snap.svg +2 -2
  49. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-with-soldermask.snap.svg +1 -1
  50. package/tests/examples/addPcbVia/__snapshots__/pcb-via-basic.snap.svg +1 -1
  51. package/tests/examples/addPcbVia/__snapshots__/pcb-via-with-net.snap.svg +1 -1
  52. package/tests/examples/addPcbVia/__snapshots__/pcb-via-with-soldermask.snap.svg +1 -1
  53. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-circle.snap.svg +1 -1
  54. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-circular-hole-with-rect-pad.snap.svg +1 -1
  55. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-oval.snap.svg +1 -1
  56. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-pill-with-rect-pad.snap.svg +1 -1
  57. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-pill.snap.svg +1 -1
  58. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-polygon.snap.svg +1 -1
  59. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-rotated-pill-with-rect-pad.snap.svg +1 -1
  60. package/tests/examples/addSmtPad/__snapshots__/circleSmtPad.snap.svg +1 -1
  61. package/tests/examples/addSmtPad/__snapshots__/pillSmtPad.snap.svg +1 -1
  62. package/tests/examples/addSmtPad/__snapshots__/polygonSmtPad.snap.svg +1 -1
  63. package/tests/examples/addSmtPad/__snapshots__/rotatedPillSmtPad.snap.svg +1 -1
  64. package/tests/examples/addSmtPad/__snapshots__/rotatedRectSmtPad.snap.svg +1 -1
  65. package/tests/examples/keyboard-defaul60/__snapshots__/keyboard-both-layer-includeSoldermask.snap.svg +8 -0
  66. package/tests/examples/keyboard-defaul60/__snapshots__/keyboard-both-layers.snap.svg +8 -0
  67. package/tests/examples/keyboard-defaul60/__snapshots__/keyboard-bottom-layer.snap.svg +8 -0
  68. package/tests/examples/keyboard-defaul60/__snapshots__/keyboard-top-layer.snap.svg +8 -0
  69. package/tests/examples/keyboard-defaul60/keyboard-both-layer-includeSoldermask.test.ts +27 -0
  70. package/tests/examples/keyboard-defaul60/keyboard-both-layers.test.ts +26 -0
  71. package/tests/examples/keyboard-defaul60/keyboard-bottom-layer.test.ts +26 -0
  72. package/tests/examples/keyboard-defaul60/keyboard-top-layer.test.ts +26 -0
  73. package/tests/examples/lga-interconnect.test.ts +3 -2
  74. package/tests/examples/soldermask/__snapshots__/copper-and-soldermask.snap.svg +1 -1
  75. package/tests/examples/soldermask/__snapshots__/copper-only.snap.svg +1 -1
  76. package/tests/examples/soldermask/__snapshots__/soldermask-only.snap.svg +1 -1
  77. package/tests/examples/soldermask/copper-and-soldermask.test.ts +18 -10
  78. package/tests/examples/soldermask/soldermask-only.test.ts +3 -3
  79. package/tests/examples/soldermask-margin/__snapshots__/negative-soldermask-margin.snap.svg +1 -1
  80. package/tests/examples/soldermask-margin/__snapshots__/positive-soldermask-margin.snap.svg +1 -1
  81. package/tsconfig.json +2 -1
@@ -10,13 +10,15 @@ export const addRotatedPillHoleWithRectPad = (
10
10
  ): void => {
11
11
  const {
12
12
  project,
13
- copperCutSetting,
13
+ topCopperCutSetting,
14
+ bottomCopperCutSetting,
14
15
  soldermaskCutSetting,
15
16
  throughBoardCutSetting,
16
17
  origin,
17
18
  includeCopper,
18
19
  includeSoldermask,
19
20
  soldermaskMargin,
21
+ includeLayers,
20
22
  } = ctx
21
23
  const centerX = platedHole.x + origin.x
22
24
  const centerY = platedHole.y + origin.y
@@ -27,41 +29,54 @@ export const addRotatedPillHoleWithRectPad = (
27
29
  const padRotation = (platedHole.rect_ccw_rotation ?? 0) * (Math.PI / 180)
28
30
 
29
31
  if (padWidth > 0 && padHeight > 0) {
30
- const padPath = createRoundedRectPath(
32
+ const padPath = createRoundedRectPath({
31
33
  centerX,
32
34
  centerY,
33
- padWidth,
34
- padHeight,
35
+ width: padWidth,
36
+ height: padHeight,
35
37
  borderRadius,
36
- 4,
37
- padRotation,
38
- )
38
+ segments: 4,
39
+ rotation: padRotation,
40
+ })
39
41
 
40
42
  // Add the rectangular pad if drawing copper
43
+ // Plated holes go through all layers, so add to both top and bottom
41
44
  if (includeCopper) {
42
- project.children.push(
43
- new ShapePath({
44
- cutIndex: copperCutSetting.index,
45
- verts: padPath.verts,
46
- prims: padPath.prims,
47
- isClosed: true,
48
- }),
49
- )
45
+ if (includeLayers.includes("top")) {
46
+ project.children.push(
47
+ new ShapePath({
48
+ cutIndex: topCopperCutSetting.index,
49
+ verts: padPath.verts,
50
+ prims: padPath.prims,
51
+ isClosed: true,
52
+ }),
53
+ )
54
+ }
55
+ if (includeLayers.includes("bottom")) {
56
+ project.children.push(
57
+ new ShapePath({
58
+ cutIndex: bottomCopperCutSetting.index,
59
+ verts: padPath.verts,
60
+ prims: padPath.prims,
61
+ isClosed: true,
62
+ }),
63
+ )
64
+ }
50
65
  }
51
66
 
52
67
  // Add soldermask opening if drawing soldermask
53
68
  if (includeSoldermask) {
54
69
  const smPadWidth = padWidth + 2 * soldermaskMargin
55
70
  const smPadHeight = padHeight + 2 * soldermaskMargin
56
- const smPadPath = createRoundedRectPath(
71
+ const smPadPath = createRoundedRectPath({
57
72
  centerX,
58
73
  centerY,
59
- smPadWidth,
60
- smPadHeight,
74
+ width: smPadWidth,
75
+ height: smPadHeight,
61
76
  borderRadius,
62
- 4,
63
- padRotation,
64
- )
77
+ segments: 4,
78
+ rotation: padRotation,
79
+ })
65
80
 
66
81
  project.children.push(
67
82
  new ShapePath({
@@ -81,13 +96,13 @@ export const addRotatedPillHoleWithRectPad = (
81
96
  if (holeWidth > 0 && holeHeight > 0 && includeCopper) {
82
97
  const holeCenterX = centerX + platedHole.hole_offset_x
83
98
  const holeCenterY = centerY + platedHole.hole_offset_y
84
- const holePath = createPillPath(
85
- holeCenterX,
86
- holeCenterY,
87
- holeWidth,
88
- holeHeight,
89
- holeRotation,
90
- )
99
+ const holePath = createPillPath({
100
+ centerX: holeCenterX,
101
+ centerY: holeCenterY,
102
+ width: holeWidth,
103
+ height: holeHeight,
104
+ rotation: holeRotation,
105
+ })
91
106
 
92
107
  project.children.push(
93
108
  new ShapePath({
@@ -11,14 +11,33 @@ export const addCircleSmtPad = (
11
11
  ): void => {
12
12
  const {
13
13
  project,
14
- copperCutSetting,
14
+ topCopperCutSetting,
15
+ bottomCopperCutSetting,
15
16
  soldermaskCutSetting,
17
+ topNetGeoms,
18
+ bottomNetGeoms,
16
19
  origin,
17
20
  includeCopper,
18
21
  includeSoldermask,
19
22
  connMap,
20
23
  soldermaskMargin,
24
+ includeLayers,
21
25
  } = ctx
26
+
27
+ // Filter by layer - only process top and bottom layers
28
+ const padLayer = smtPad.layer || "top"
29
+ if (padLayer !== "top" && padLayer !== "bottom") {
30
+ return // Skip inner layers
31
+ }
32
+ if (!includeLayers.includes(padLayer)) {
33
+ return
34
+ }
35
+
36
+ // Select the correct cut setting and net geoms based on layer
37
+ const copperCutSetting =
38
+ padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting
39
+ const netGeoms = padLayer === "top" ? topNetGeoms : bottomNetGeoms
40
+
22
41
  const centerX = smtPad.x + origin.x
23
42
  const centerY = smtPad.y + origin.y
24
43
 
@@ -33,10 +52,14 @@ export const addCircleSmtPad = (
33
52
 
34
53
  if (netId) {
35
54
  // Add to netGeoms to be merged with other elements on the same net
36
- ctx.netGeoms.get(netId)?.push(polygon)
55
+ netGeoms.get(netId)?.push(polygon)
37
56
  } else {
38
57
  // No net connection - draw directly
39
- const outer = createCirclePath(centerX, centerY, outerRadius)
58
+ const outer = createCirclePath({
59
+ centerX,
60
+ centerY,
61
+ radius: outerRadius,
62
+ })
40
63
  project.children.push(
41
64
  new ShapePath({
42
65
  cutIndex: copperCutSetting.index,
@@ -51,7 +74,11 @@ export const addCircleSmtPad = (
51
74
  // Add soldermask opening if drawing soldermask
52
75
  if (includeSoldermask) {
53
76
  const smRadius = outerRadius + soldermaskMargin
54
- const outer = createCirclePath(centerX, centerY, smRadius)
77
+ const outer = createCirclePath({
78
+ centerX,
79
+ centerY,
80
+ radius: smRadius,
81
+ })
55
82
  project.children.push(
56
83
  new ShapePath({
57
84
  cutIndex: soldermaskCutSetting.index,
@@ -10,19 +10,43 @@ export const addPillSmtPad = (
10
10
  ): void => {
11
11
  const {
12
12
  project,
13
- copperCutSetting,
13
+ topCopperCutSetting,
14
+ bottomCopperCutSetting,
14
15
  soldermaskCutSetting,
16
+ topNetGeoms,
17
+ bottomNetGeoms,
15
18
  origin,
16
19
  includeCopper,
17
20
  includeSoldermask,
18
21
  connMap,
19
22
  soldermaskMargin,
23
+ includeLayers,
20
24
  } = ctx
25
+
26
+ // Filter by layer - only process top and bottom layers
27
+ const padLayer = smtPad.layer || "top"
28
+ if (padLayer !== "top" && padLayer !== "bottom") {
29
+ return // Skip inner layers
30
+ }
31
+ if (!includeLayers.includes(padLayer)) {
32
+ return
33
+ }
34
+
35
+ // Select the correct cut setting and net geoms based on layer
36
+ const copperCutSetting =
37
+ padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting
38
+ const netGeoms = padLayer === "top" ? topNetGeoms : bottomNetGeoms
39
+
21
40
  const centerX = smtPad.x + origin.x
22
41
  const centerY = smtPad.y + origin.y
23
42
 
24
43
  if (smtPad.width > 0 && smtPad.height > 0) {
25
- const outer = createPillPath(centerX, centerY, smtPad.width, smtPad.height)
44
+ const outer = createPillPath({
45
+ centerX,
46
+ centerY,
47
+ width: smtPad.width,
48
+ height: smtPad.height,
49
+ })
26
50
 
27
51
  // Add to netGeoms for copper (will be merged with traces)
28
52
  if (includeCopper) {
@@ -31,7 +55,7 @@ export const addPillSmtPad = (
31
55
 
32
56
  if (netId) {
33
57
  // Add to netGeoms to be merged with other elements on the same net
34
- ctx.netGeoms.get(netId)?.push(polygon)
58
+ netGeoms.get(netId)?.push(polygon)
35
59
  } else {
36
60
  // No net connection - draw directly
37
61
  project.children.push(
@@ -49,7 +73,12 @@ export const addPillSmtPad = (
49
73
  if (includeSoldermask) {
50
74
  const smWidth = smtPad.width + 2 * soldermaskMargin
51
75
  const smHeight = smtPad.height + 2 * soldermaskMargin
52
- const smOuter = createPillPath(centerX, centerY, smWidth, smHeight)
76
+ const smOuter = createPillPath({
77
+ centerX,
78
+ centerY,
79
+ width: smWidth,
80
+ height: smHeight,
81
+ })
53
82
 
54
83
  project.children.push(
55
84
  new ShapePath({
@@ -11,18 +11,40 @@ export const addPolygonSmtPad = (
11
11
  ): void => {
12
12
  const {
13
13
  project,
14
- copperCutSetting,
14
+ topCopperCutSetting,
15
+ bottomCopperCutSetting,
15
16
  soldermaskCutSetting,
17
+ topNetGeoms,
18
+ bottomNetGeoms,
16
19
  origin,
17
20
  includeCopper,
18
21
  includeSoldermask,
19
22
  connMap,
20
23
  soldermaskMargin,
24
+ includeLayers,
21
25
  } = ctx
22
26
 
27
+ // Filter by layer - only process top and bottom layers
28
+ const padLayer = smtPad.layer || "top"
29
+ if (padLayer !== "top" && padLayer !== "bottom") {
30
+ return // Skip inner layers
31
+ }
32
+ if (!includeLayers.includes(padLayer)) {
33
+ return
34
+ }
35
+
36
+ // Select the correct cut setting and net geoms based on layer
37
+ const copperCutSetting =
38
+ padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting
39
+ const netGeoms = padLayer === "top" ? topNetGeoms : bottomNetGeoms
40
+
23
41
  // Create the polygon pad
24
42
  if (smtPad.points.length >= 3) {
25
- const pad = createPolygonPathFromOutline(smtPad.points, origin.x, origin.y)
43
+ const pad = createPolygonPathFromOutline({
44
+ outline: smtPad.points,
45
+ offsetX: origin.x,
46
+ offsetY: origin.y,
47
+ })
26
48
 
27
49
  // Add to netGeoms for copper (will be merged with traces)
28
50
  if (includeCopper) {
@@ -31,7 +53,7 @@ export const addPolygonSmtPad = (
31
53
 
32
54
  if (netId) {
33
55
  // Add to netGeoms to be merged with other elements on the same net
34
- ctx.netGeoms.get(netId)?.push(polygon)
56
+ netGeoms.get(netId)?.push(polygon)
35
57
  } else {
36
58
  // No net connection - draw directly
37
59
  project.children.push(
@@ -6,16 +6,28 @@ import { ShapePath } from "lbrnts"
6
6
  export const addRectSmtPad = (smtPad: PcbSmtPadRect, ctx: ConvertContext) => {
7
7
  const {
8
8
  project,
9
- copperCutSetting,
9
+ topCopperCutSetting,
10
+ bottomCopperCutSetting,
10
11
  soldermaskCutSetting,
11
12
  connMap,
12
- netGeoms,
13
+ topNetGeoms,
14
+ bottomNetGeoms,
13
15
  origin,
14
16
  includeCopper,
15
17
  includeSoldermask,
16
18
  soldermaskMargin,
19
+ includeLayers,
17
20
  } = ctx
18
21
 
22
+ // Filter by layer - only process top and bottom layers
23
+ const padLayer = smtPad.layer || "top"
24
+ if (padLayer !== "top" && padLayer !== "bottom") {
25
+ return // Skip inner layers
26
+ }
27
+ if (!includeLayers.includes(padLayer)) {
28
+ return
29
+ }
30
+
19
31
  const centerX = smtPad.x + origin.x
20
32
  const centerY = smtPad.y + origin.y
21
33
  const halfWidth = smtPad.width / 2
@@ -23,11 +35,16 @@ export const addRectSmtPad = (smtPad: PcbSmtPadRect, ctx: ConvertContext) => {
23
35
 
24
36
  const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id)
25
37
 
38
+ // Select the correct cut setting and net geoms based on layer
39
+ const copperCutSetting =
40
+ padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting
41
+ const netGeoms = padLayer === "top" ? topNetGeoms : bottomNetGeoms
42
+
26
43
  // Only add to netGeoms if drawing copper
27
44
  if (includeCopper) {
28
45
  if (netId) {
29
46
  // Add to netGeoms to be merged with other elements on the same net
30
- ctx.netGeoms
47
+ netGeoms
31
48
  .get(netId)
32
49
  ?.push(
33
50
  new Box(
@@ -10,25 +10,44 @@ export const addRotatedPillSmtPad = (
10
10
  ): void => {
11
11
  const {
12
12
  project,
13
- copperCutSetting,
13
+ topCopperCutSetting,
14
+ bottomCopperCutSetting,
14
15
  soldermaskCutSetting,
16
+ topNetGeoms,
17
+ bottomNetGeoms,
15
18
  origin,
16
19
  includeCopper,
17
20
  includeSoldermask,
18
21
  connMap,
19
22
  soldermaskMargin,
23
+ includeLayers,
20
24
  } = ctx
25
+
26
+ // Filter by layer - only process top and bottom layers
27
+ const padLayer = smtPad.layer || "top"
28
+ if (padLayer !== "top" && padLayer !== "bottom") {
29
+ return // Skip inner layers
30
+ }
31
+ if (!includeLayers.includes(padLayer)) {
32
+ return
33
+ }
34
+
35
+ // Select the correct cut setting and net geoms based on layer
36
+ const copperCutSetting =
37
+ padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting
38
+ const netGeoms = padLayer === "top" ? topNetGeoms : bottomNetGeoms
39
+
21
40
  const centerX = smtPad.x + origin.x
22
41
  const centerY = smtPad.y + origin.y
23
42
 
24
43
  if (smtPad.width > 0 && smtPad.height > 0) {
25
- const outer = createPillPath(
44
+ const outer = createPillPath({
26
45
  centerX,
27
46
  centerY,
28
- smtPad.width,
29
- smtPad.height,
30
- (smtPad.ccw_rotation ?? 0) * (Math.PI / 180),
31
- )
47
+ width: smtPad.width,
48
+ height: smtPad.height,
49
+ rotation: (smtPad.ccw_rotation ?? 0) * (Math.PI / 180),
50
+ })
32
51
 
33
52
  // Add to netGeoms for copper (will be merged with traces)
34
53
  if (includeCopper) {
@@ -37,7 +56,7 @@ export const addRotatedPillSmtPad = (
37
56
 
38
57
  if (netId) {
39
58
  // Add to netGeoms to be merged with other elements on the same net
40
- ctx.netGeoms.get(netId)?.push(polygon)
59
+ netGeoms.get(netId)?.push(polygon)
41
60
  } else {
42
61
  // No net connection - draw directly
43
62
  project.children.push(
@@ -55,13 +74,13 @@ export const addRotatedPillSmtPad = (
55
74
  if (includeSoldermask) {
56
75
  const smWidth = smtPad.width + 2 * soldermaskMargin
57
76
  const smHeight = smtPad.height + 2 * soldermaskMargin
58
- const smOuter = createPillPath(
77
+ const smOuter = createPillPath({
59
78
  centerX,
60
79
  centerY,
61
- smWidth,
62
- smHeight,
63
- (smtPad.ccw_rotation ?? 0) * (Math.PI / 180),
64
- )
80
+ width: smWidth,
81
+ height: smHeight,
82
+ rotation: (smtPad.ccw_rotation ?? 0) * (Math.PI / 180),
83
+ })
65
84
 
66
85
  project.children.push(
67
86
  new ShapePath({
@@ -10,29 +10,48 @@ export const addRotatedRectSmtPad = (
10
10
  ): void => {
11
11
  const {
12
12
  project,
13
- copperCutSetting,
13
+ topCopperCutSetting,
14
+ bottomCopperCutSetting,
14
15
  soldermaskCutSetting,
16
+ topNetGeoms,
17
+ bottomNetGeoms,
15
18
  origin,
16
19
  includeCopper,
17
20
  includeSoldermask,
18
21
  connMap,
19
22
  soldermaskMargin,
23
+ includeLayers,
20
24
  } = ctx
25
+
26
+ // Filter by layer - only process top and bottom layers
27
+ const padLayer = smtPad.layer || "top"
28
+ if (padLayer !== "top" && padLayer !== "bottom") {
29
+ return // Skip inner layers
30
+ }
31
+ if (!includeLayers.includes(padLayer)) {
32
+ return
33
+ }
34
+
35
+ // Select the correct cut setting and net geoms based on layer
36
+ const copperCutSetting =
37
+ padLayer === "top" ? topCopperCutSetting : bottomCopperCutSetting
38
+ const netGeoms = padLayer === "top" ? topNetGeoms : bottomNetGeoms
39
+
21
40
  const centerX = smtPad.x + origin.x
22
41
  const centerY = smtPad.y + origin.y
23
42
  const rotation = (smtPad.ccw_rotation ?? 0) * (Math.PI / 180)
24
43
  const borderRadius = smtPad.rect_border_radius ?? 0
25
44
 
26
45
  if (smtPad.width > 0 && smtPad.height > 0) {
27
- const outer = createRoundedRectPath(
46
+ const outer = createRoundedRectPath({
28
47
  centerX,
29
48
  centerY,
30
- smtPad.width,
31
- smtPad.height,
49
+ width: smtPad.width,
50
+ height: smtPad.height,
32
51
  borderRadius,
33
- 4,
52
+ segments: 4,
34
53
  rotation,
35
- )
54
+ })
36
55
 
37
56
  // Add to netGeoms for copper (will be merged with traces)
38
57
  if (includeCopper) {
@@ -41,7 +60,7 @@ export const addRotatedRectSmtPad = (
41
60
 
42
61
  if (netId) {
43
62
  // Add to netGeoms to be merged with other elements on the same net
44
- ctx.netGeoms.get(netId)?.push(polygon)
63
+ netGeoms.get(netId)?.push(polygon)
45
64
  } else {
46
65
  // No net connection - draw directly
47
66
  project.children.push(
@@ -59,15 +78,15 @@ export const addRotatedRectSmtPad = (
59
78
  if (includeSoldermask) {
60
79
  const smWidth = smtPad.width + 2 * soldermaskMargin
61
80
  const smHeight = smtPad.height + 2 * soldermaskMargin
62
- const smOuter = createRoundedRectPath(
81
+ const smOuter = createRoundedRectPath({
63
82
  centerX,
64
83
  centerY,
65
- smWidth,
66
- smHeight,
84
+ width: smWidth,
85
+ height: smHeight,
67
86
  borderRadius,
68
- 4,
87
+ segments: 4,
69
88
  rotation,
70
- )
89
+ })
71
90
 
72
91
  project.children.push(
73
92
  new ShapePath({
@@ -12,12 +12,19 @@ export interface CirclePath {
12
12
  prims: Prim[]
13
13
  }
14
14
 
15
- export const createCirclePath = (
16
- centerX: number,
17
- centerY: number,
18
- radius: number,
19
- segments: number = 64,
20
- ): CirclePath => {
15
+ export interface CreateCirclePathParams {
16
+ centerX: number
17
+ centerY: number
18
+ radius: number
19
+ segments?: number
20
+ }
21
+
22
+ export const createCirclePath = ({
23
+ centerX,
24
+ centerY,
25
+ radius,
26
+ segments = 64,
27
+ }: CreateCirclePathParams): CirclePath => {
21
28
  const verts: Point[] = []
22
29
  const prims: Prim[] = []
23
30
 
@@ -12,14 +12,23 @@ export interface OvalPath {
12
12
  prims: Prim[]
13
13
  }
14
14
 
15
- export const createOvalPath = (
16
- centerX: number,
17
- centerY: number,
18
- width: number,
19
- height: number,
20
- rotation: number = 0,
21
- segments: number = 64,
22
- ): OvalPath => {
15
+ export interface CreateOvalPathParams {
16
+ centerX: number
17
+ centerY: number
18
+ width: number
19
+ height: number
20
+ rotation?: number
21
+ segments?: number
22
+ }
23
+
24
+ export const createOvalPath = ({
25
+ centerX,
26
+ centerY,
27
+ width,
28
+ height,
29
+ rotation = 0,
30
+ segments = 64,
31
+ }: CreateOvalPathParams): OvalPath => {
23
32
  const verts: Point[] = []
24
33
  const prims: Prim[] = []
25
34
  const radiusX = width / 2
@@ -13,11 +13,17 @@ export interface PointAdderOptions {
13
13
  translation?: PathPoint
14
14
  }
15
15
 
16
- export const createPointAdder = (
17
- verts: PathPoint[],
18
- prims: PathPrim[],
19
- options: PointAdderOptions = {},
20
- ): ((x: number, y: number) => void) => {
16
+ export interface CreatePointAdderParams {
17
+ verts: PathPoint[]
18
+ prims: PathPrim[]
19
+ options?: PointAdderOptions
20
+ }
21
+
22
+ export const createPointAdder = ({
23
+ verts,
24
+ prims,
25
+ options = {},
26
+ }: CreatePointAdderParams): ((x: number, y: number) => void) => {
21
27
  const { rotation = 0, rotationCenter, translation } = options
22
28
  const cos = Math.cos(rotation)
23
29
  const sin = Math.sin(rotation)
@@ -14,14 +14,23 @@ export interface PillPath {
14
14
  prims: Prim[]
15
15
  }
16
16
 
17
- export const createPillPath = (
18
- centerX: number,
19
- centerY: number,
20
- width: number,
21
- height: number,
22
- rotation: number = 0,
23
- segments: number = 32,
24
- ): PillPath => {
17
+ export interface CreatePillPathParams {
18
+ centerX: number
19
+ centerY: number
20
+ width: number
21
+ height: number
22
+ rotation?: number
23
+ segments?: number
24
+ }
25
+
26
+ export const createPillPath = ({
27
+ centerX,
28
+ centerY,
29
+ width,
30
+ height,
31
+ rotation = 0,
32
+ segments = 32,
33
+ }: CreatePillPathParams): PillPath => {
25
34
  const verts: Point[] = []
26
35
  const prims: Prim[] = []
27
36
  const halfWidth = width / 2
@@ -29,9 +38,13 @@ export const createPillPath = (
29
38
  const radius = Math.min(halfWidth, halfHeight)
30
39
  const isVertical = height > width
31
40
 
32
- const addPoint = createPointAdder(verts, prims, {
33
- rotation,
34
- rotationCenter: { x: centerX, y: centerY },
41
+ const addPoint = createPointAdder({
42
+ verts,
43
+ prims,
44
+ options: {
45
+ rotation,
46
+ rotationCenter: { x: centerX, y: centerY },
47
+ },
35
48
  })
36
49
 
37
50
  if (isVertical) {
@@ -12,11 +12,17 @@ export interface PolygonPath {
12
12
  prims: Prim[]
13
13
  }
14
14
 
15
- export const createPolygonPathFromOutline = (
16
- outline: Array<{ x?: number | null; y?: number | null }>,
17
- offsetX: number,
18
- offsetY: number,
19
- ): PolygonPath => {
15
+ export interface CreatePolygonPathFromOutlineParams {
16
+ outline: Array<{ x?: number | null; y?: number | null }>
17
+ offsetX: number
18
+ offsetY: number
19
+ }
20
+
21
+ export const createPolygonPathFromOutline = ({
22
+ outline,
23
+ offsetX,
24
+ offsetY,
25
+ }: CreatePolygonPathFromOutlineParams): PolygonPath => {
20
26
  const verts: Point[] = []
21
27
 
22
28
  for (const point of outline) {