circuit-json-to-lbrn 0.0.21 → 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 (67) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +489 -182
  3. package/lib/ConvertContext.ts +6 -2
  4. package/lib/element-handlers/addPcbTrace/index.ts +145 -61
  5. package/lib/element-handlers/addPcbVia/index.ts +34 -12
  6. package/lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts +34 -12
  7. package/lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts +24 -9
  8. package/lib/element-handlers/addPlatedHole/addHoleWithPolygonPad.ts +24 -9
  9. package/lib/element-handlers/addPlatedHole/addOvalPlatedHole.ts +24 -9
  10. package/lib/element-handlers/addPlatedHole/addPillHoleWithRectPad.ts +24 -9
  11. package/lib/element-handlers/addPlatedHole/addPillPlatedHole.ts +24 -9
  12. package/lib/element-handlers/addPlatedHole/addRotatedPillHoleWithRectPad.ts +24 -9
  13. package/lib/element-handlers/addSmtPad/addCircleSmtPad.ts +21 -2
  14. package/lib/element-handlers/addSmtPad/addPillSmtPad.ts +21 -2
  15. package/lib/element-handlers/addSmtPad/addPolygonSmtPad.ts +20 -2
  16. package/lib/element-handlers/addSmtPad/addRectSmtPad.ts +20 -3
  17. package/lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts +21 -2
  18. package/lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts +21 -2
  19. package/lib/index.ts +92 -41
  20. package/package.json +1 -1
  21. package/tests/assets/keyboard-default60.json +92565 -0
  22. package/tests/examples/__snapshots__/board-outline-soldermask-preset.snap.svg +1 -1
  23. package/tests/examples/__snapshots__/board-outline.snap.svg +1 -1
  24. package/tests/examples/__snapshots__/lga-interconnect.snap.svg +1 -1
  25. package/tests/examples/__snapshots__/single-trace.snap.svg +1 -1
  26. package/tests/examples/addPcbCutout/__snapshots__/pcb-cutout-circle.snap.svg +1 -1
  27. package/tests/examples/addPcbCutout/__snapshots__/pcb-cutout-path.snap.svg +1 -1
  28. package/tests/examples/addPcbCutout/__snapshots__/pcb-cutout-polygon.snap.svg +1 -1
  29. package/tests/examples/addPcbCutout/__snapshots__/pcb-cutout-rect.snap.svg +1 -1
  30. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-circle.snap.svg +1 -1
  31. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-oval.snap.svg +1 -1
  32. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-pill.snap.svg +1 -1
  33. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-rect.snap.svg +1 -1
  34. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-rotated-pill.snap.svg +2 -2
  35. package/tests/examples/addPcbHole/__snapshots__/pcb-hole-with-soldermask.snap.svg +1 -1
  36. package/tests/examples/addPcbVia/__snapshots__/pcb-via-basic.snap.svg +1 -1
  37. package/tests/examples/addPcbVia/__snapshots__/pcb-via-with-net.snap.svg +1 -1
  38. package/tests/examples/addPcbVia/__snapshots__/pcb-via-with-soldermask.snap.svg +1 -1
  39. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-circle.snap.svg +1 -1
  40. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-circular-hole-with-rect-pad.snap.svg +1 -1
  41. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-oval.snap.svg +1 -1
  42. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-pill-with-rect-pad.snap.svg +1 -1
  43. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-pill.snap.svg +1 -1
  44. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-polygon.snap.svg +1 -1
  45. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-rotated-pill-with-rect-pad.snap.svg +1 -1
  46. package/tests/examples/addSmtPad/__snapshots__/circleSmtPad.snap.svg +1 -1
  47. package/tests/examples/addSmtPad/__snapshots__/pillSmtPad.snap.svg +1 -1
  48. package/tests/examples/addSmtPad/__snapshots__/polygonSmtPad.snap.svg +1 -1
  49. package/tests/examples/addSmtPad/__snapshots__/rotatedPillSmtPad.snap.svg +1 -1
  50. package/tests/examples/addSmtPad/__snapshots__/rotatedRectSmtPad.snap.svg +1 -1
  51. package/tests/examples/keyboard-defaul60/__snapshots__/keyboard-both-layer-includeSoldermask.snap.svg +8 -0
  52. package/tests/examples/keyboard-defaul60/__snapshots__/keyboard-both-layers.snap.svg +8 -0
  53. package/tests/examples/keyboard-defaul60/__snapshots__/keyboard-bottom-layer.snap.svg +8 -0
  54. package/tests/examples/keyboard-defaul60/__snapshots__/keyboard-top-layer.snap.svg +8 -0
  55. package/tests/examples/keyboard-defaul60/keyboard-both-layer-includeSoldermask.test.ts +27 -0
  56. package/tests/examples/keyboard-defaul60/keyboard-both-layers.test.ts +26 -0
  57. package/tests/examples/keyboard-defaul60/keyboard-bottom-layer.test.ts +26 -0
  58. package/tests/examples/keyboard-defaul60/keyboard-top-layer.test.ts +26 -0
  59. package/tests/examples/lga-interconnect.test.ts +3 -2
  60. package/tests/examples/soldermask/__snapshots__/copper-and-soldermask.snap.svg +1 -1
  61. package/tests/examples/soldermask/__snapshots__/copper-only.snap.svg +1 -1
  62. package/tests/examples/soldermask/__snapshots__/soldermask-only.snap.svg +1 -1
  63. package/tests/examples/soldermask/copper-and-soldermask.test.ts +18 -10
  64. package/tests/examples/soldermask/soldermask-only.test.ts +3 -3
  65. package/tests/examples/soldermask-margin/__snapshots__/negative-soldermask-margin.snap.svg +1 -1
  66. package/tests/examples/soldermask-margin/__snapshots__/positive-soldermask-margin.snap.svg +1 -1
  67. package/tsconfig.json +2 -1
@@ -9,19 +9,22 @@ export const addPcbPlatedHolePill = (
9
9
  ): void => {
10
10
  const {
11
11
  project,
12
- copperCutSetting,
12
+ topCopperCutSetting,
13
+ bottomCopperCutSetting,
13
14
  soldermaskCutSetting,
14
15
  throughBoardCutSetting,
15
16
  origin,
16
17
  includeCopper,
17
18
  includeSoldermask,
18
19
  soldermaskMargin,
20
+ includeLayers,
19
21
  } = ctx
20
22
  const centerX = platedHole.x + origin.x
21
23
  const centerY = platedHole.y + origin.y
22
24
  const rotation = (platedHole.ccw_rotation || 0) * (Math.PI / 180) // Convert degrees to radians
23
25
 
24
26
  // Add outer pill shape (copper) if drawing copper
27
+ // Plated holes go through all layers, so add to both top and bottom
25
28
  if (
26
29
  platedHole.outer_width > 0 &&
27
30
  platedHole.outer_height > 0 &&
@@ -34,14 +37,26 @@ export const addPcbPlatedHolePill = (
34
37
  height: platedHole.outer_height,
35
38
  rotation,
36
39
  })
37
- project.children.push(
38
- new ShapePath({
39
- cutIndex: copperCutSetting.index,
40
- verts: outer.verts,
41
- prims: outer.prims,
42
- isClosed: true,
43
- }),
44
- )
40
+ if (includeLayers.includes("top")) {
41
+ project.children.push(
42
+ new ShapePath({
43
+ cutIndex: topCopperCutSetting.index,
44
+ verts: outer.verts,
45
+ prims: outer.prims,
46
+ isClosed: true,
47
+ }),
48
+ )
49
+ }
50
+ if (includeLayers.includes("bottom")) {
51
+ project.children.push(
52
+ new ShapePath({
53
+ cutIndex: bottomCopperCutSetting.index,
54
+ verts: outer.verts,
55
+ prims: outer.prims,
56
+ isClosed: true,
57
+ }),
58
+ )
59
+ }
45
60
  }
46
61
 
47
62
  // Add soldermask opening if drawing soldermask
@@ -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
@@ -38,15 +40,28 @@ export const addRotatedPillHoleWithRectPad = (
38
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
@@ -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,7 +52,7 @@ 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
58
  const outer = createCirclePath({
@@ -10,14 +10,33 @@ 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
 
@@ -36,7 +55,7 @@ export const addPillSmtPad = (
36
55
 
37
56
  if (netId) {
38
57
  // Add to netGeoms to be merged with other elements on the same net
39
- ctx.netGeoms.get(netId)?.push(polygon)
58
+ netGeoms.get(netId)?.push(polygon)
40
59
  } else {
41
60
  // No net connection - draw directly
42
61
  project.children.push(
@@ -11,15 +11,33 @@ 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
43
  const pad = createPolygonPathFromOutline({
@@ -35,7 +53,7 @@ export const addPolygonSmtPad = (
35
53
 
36
54
  if (netId) {
37
55
  // Add to netGeoms to be merged with other elements on the same net
38
- ctx.netGeoms.get(netId)?.push(polygon)
56
+ netGeoms.get(netId)?.push(polygon)
39
57
  } else {
40
58
  // No net connection - draw directly
41
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,14 +10,33 @@ 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
 
@@ -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(
@@ -10,14 +10,33 @@ 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)
@@ -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(
package/lib/index.ts CHANGED
@@ -27,6 +27,7 @@ export const convertCircuitJsonToLbrn = (
27
27
  includeCopper?: boolean
28
28
  includeSoldermask?: boolean
29
29
  soldermaskMargin?: number
30
+ includeLayers?: Array<"top" | "bottom">
30
31
  } = {},
31
32
  ): LightBurnProject => {
32
33
  const db = cju(circuitJson)
@@ -35,16 +36,27 @@ export const convertCircuitJsonToLbrn = (
35
36
  formatVersion: "1",
36
37
  })
37
38
 
38
- const copperCutSetting = new CutSetting({
39
+ // Default to all layers if not specified
40
+ const includeLayers = options.includeLayers ?? ["top", "bottom"]
41
+
42
+ const topCopperCutSetting = new CutSetting({
39
43
  index: 0,
40
- name: "Cut Copper",
44
+ name: "Cut Top Copper",
41
45
  numPasses: 12,
42
46
  speed: 100,
43
47
  })
44
- project.children.push(copperCutSetting)
48
+ project.children.push(topCopperCutSetting)
45
49
 
46
- const throughBoardCutSetting = new CutSetting({
50
+ const bottomCopperCutSetting = new CutSetting({
47
51
  index: 1,
52
+ name: "Cut Bottom Copper",
53
+ numPasses: 12,
54
+ speed: 100,
55
+ })
56
+ project.children.push(bottomCopperCutSetting)
57
+
58
+ const throughBoardCutSetting = new CutSetting({
59
+ index: 2,
48
60
  name: "Cut Through Board",
49
61
  numPasses: 3,
50
62
  speed: 50,
@@ -52,14 +64,14 @@ export const convertCircuitJsonToLbrn = (
52
64
  project.children.push(throughBoardCutSetting)
53
65
 
54
66
  const soldermaskCutSetting = new CutSetting({
55
- type: "Scan", // Use Scan mode to fill the pad shapes for Kapton tape cutting
56
- index: 2,
67
+ type: "Scan", // Use Scan mode to fill pad shapes for Kapton tape cutting
68
+ index: 3,
57
69
  name: "Cut Soldermask",
58
70
  numPasses: 1,
59
71
  speed: 150,
60
72
  scanOpt: "individual", // Scan each shape individually
61
73
  interval: 0.18, // Distance between cross-hatch lines
62
- angle: 45, // Angle of the cross-hatch lines
74
+ angle: 45, // Angle of cross-hatch lines
63
75
  crossHatch: true,
64
76
  })
65
77
  project.children.push(soldermaskCutSetting)
@@ -76,19 +88,23 @@ export const convertCircuitJsonToLbrn = (
76
88
  const ctx: ConvertContext = {
77
89
  db,
78
90
  project,
79
- copperCutSetting,
91
+ topCopperCutSetting,
92
+ bottomCopperCutSetting,
80
93
  throughBoardCutSetting,
81
94
  soldermaskCutSetting,
82
95
  connMap,
83
- netGeoms: new Map(),
96
+ topNetGeoms: new Map(),
97
+ bottomNetGeoms: new Map(),
84
98
  origin,
85
99
  includeCopper: options.includeCopper ?? true,
86
100
  includeSoldermask: options.includeSoldermask ?? false,
87
101
  soldermaskMargin: options.soldermaskMargin ?? 0,
102
+ includeLayers,
88
103
  }
89
104
 
90
105
  for (const net of Object.keys(connMap.netMap)) {
91
- ctx.netGeoms.set(net, [])
106
+ ctx.topNetGeoms.set(net, [])
107
+ ctx.bottomNetGeoms.set(net, [])
92
108
  }
93
109
 
94
110
  for (const smtpad of db.pcb_smtpad.list()) {
@@ -149,42 +165,77 @@ export const convertCircuitJsonToLbrn = (
149
165
  // Create a union of all the net geoms, and add to project
150
166
  // Only do this when including copper
151
167
  if (ctx.includeCopper) {
152
- for (const net of Object.keys(connMap.netMap)) {
153
- const netGeoms = ctx.netGeoms.get(net)!
168
+ // Process top layer
169
+ if (includeLayers.includes("top")) {
170
+ for (const net of Object.keys(connMap.netMap)) {
171
+ const netGeoms = ctx.topNetGeoms.get(net)!
154
172
 
155
- if (netGeoms.length === 0) {
156
- continue
157
- }
173
+ if (netGeoms.length === 0) {
174
+ continue
175
+ }
158
176
 
159
- let union = netGeoms[0]!
160
- if (union instanceof Box) {
161
- union = new Polygon(union)
162
- }
163
- for (const geom of netGeoms.slice(1)) {
164
- if (geom instanceof Polygon) {
165
- union = BooleanOperations.unify(union, geom)
166
- } else if (geom instanceof Box) {
167
- union = BooleanOperations.unify(union, new Polygon(geom))
177
+ let union = netGeoms[0]!
178
+ if (union instanceof Box) {
179
+ union = new Polygon(union)
180
+ }
181
+ for (const geom of netGeoms.slice(1)) {
182
+ if (geom instanceof Polygon) {
183
+ union = BooleanOperations.unify(union, geom)
184
+ } else if (geom instanceof Box) {
185
+ union = BooleanOperations.unify(union, new Polygon(geom))
186
+ }
187
+ }
188
+
189
+ for (const island of union.splitToIslands()) {
190
+ // Convert the polygon to verts and prims
191
+ const { verts, prims } = polygonToShapePathData(island)
192
+
193
+ project.children.push(
194
+ new ShapePath({
195
+ cutIndex: topCopperCutSetting.index,
196
+ verts,
197
+ prims,
198
+ isClosed: false,
199
+ }),
200
+ )
168
201
  }
169
202
  }
203
+ }
204
+
205
+ // Process bottom layer
206
+ if (includeLayers.includes("bottom")) {
207
+ for (const net of Object.keys(connMap.netMap)) {
208
+ const netGeoms = ctx.bottomNetGeoms.get(net)!
170
209
 
171
- // DEBUGGING ONLY!!!
172
- // if (netGeoms.length > 1) {
173
- // writeDebugSvg(net, union)
174
- // }
175
-
176
- for (const island of union.splitToIslands()) {
177
- // Convert the polygon to verts and prims
178
- const { verts, prims } = polygonToShapePathData(island)
179
-
180
- project.children.push(
181
- new ShapePath({
182
- cutIndex: copperCutSetting.index,
183
- verts,
184
- prims,
185
- isClosed: false,
186
- }),
187
- )
210
+ if (netGeoms.length === 0) {
211
+ continue
212
+ }
213
+
214
+ let union = netGeoms[0]!
215
+ if (union instanceof Box) {
216
+ union = new Polygon(union)
217
+ }
218
+ for (const geom of netGeoms.slice(1)) {
219
+ if (geom instanceof Polygon) {
220
+ union = BooleanOperations.unify(union, geom)
221
+ } else if (geom instanceof Box) {
222
+ union = BooleanOperations.unify(union, new Polygon(geom))
223
+ }
224
+ }
225
+
226
+ for (const island of union.splitToIslands()) {
227
+ // Convert the polygon to verts and prims
228
+ const { verts, prims } = polygonToShapePathData(island)
229
+
230
+ project.children.push(
231
+ new ShapePath({
232
+ cutIndex: bottomCopperCutSetting.index,
233
+ verts,
234
+ prims,
235
+ isClosed: false,
236
+ }),
237
+ )
238
+ }
188
239
  }
189
240
  }
190
241
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "circuit-json-to-lbrn",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.21",
4
+ "version": "0.0.22",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "bun run site/index.html",