circuit-json-to-lbrn 0.0.8 → 0.0.10

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 (39) hide show
  1. package/README.md +39 -2
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +596 -122
  4. package/lib/ConvertContext.ts +4 -0
  5. package/lib/element-handlers/addPcbTrace/index.ts +7 -1
  6. package/lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts +38 -4
  7. package/lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts +32 -11
  8. package/lib/element-handlers/addPlatedHole/addHoleWithPolygonPad.ts +31 -9
  9. package/lib/element-handlers/addPlatedHole/addOvalPlatedHole.ts +38 -4
  10. package/lib/element-handlers/addPlatedHole/addPillHoleWithRectPad.ts +31 -9
  11. package/lib/element-handlers/addPlatedHole/addPillPlatedHole.ts +38 -4
  12. package/lib/element-handlers/addPlatedHole/addRotatedPillHoleWithRectPad.ts +31 -9
  13. package/lib/element-handlers/addSmtPad/addCircleSmtPad.ts +62 -0
  14. package/lib/element-handlers/addSmtPad/addPillSmtPad.ts +58 -0
  15. package/lib/element-handlers/addSmtPad/addPolygonSmtPad.ts +57 -0
  16. package/lib/element-handlers/addSmtPad/addRectSmtPad.ts +80 -12
  17. package/lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts +64 -0
  18. package/lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts +68 -0
  19. package/lib/element-handlers/addSmtPad/index.ts +25 -7
  20. package/lib/helpers/pathToPolygon.ts +14 -0
  21. package/lib/index.ts +39 -32
  22. package/package.json +2 -2
  23. package/tests/examples/__snapshots__/lga-interconnect.snap.svg +1 -1
  24. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-circle.snap.svg +1 -1
  25. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-oval.snap.svg +1 -1
  26. package/tests/examples/addSmtPad/__snapshots__/circleSmtPad.snap.svg +8 -0
  27. package/tests/examples/addSmtPad/__snapshots__/pillSmtPad.snap.svg +8 -0
  28. package/tests/examples/addSmtPad/__snapshots__/polygonSmtPad.snap.svg +8 -0
  29. package/tests/examples/addSmtPad/__snapshots__/rotatedPillSmtPad.snap.svg +8 -0
  30. package/tests/examples/addSmtPad/__snapshots__/rotatedRectSmtPad.snap.svg +8 -0
  31. package/tests/examples/addSmtPad/circleSmtPad.test.ts +45 -0
  32. package/tests/examples/addSmtPad/pillSmtPad.test.ts +47 -0
  33. package/tests/examples/addSmtPad/polygonSmtPad.test.ts +51 -0
  34. package/tests/examples/addSmtPad/rotatedPillSmtPad.test.ts +48 -0
  35. package/tests/examples/addSmtPad/rotatedRectSmtPad.test.ts +59 -0
  36. package/tests/examples/soldermask/__snapshots__/copper-and-soldermask.snap.svg +8 -0
  37. package/tests/examples/soldermask/__snapshots__/soldermask-only.snap.svg +8 -0
  38. package/tests/examples/soldermask/copper-and-soldermask.test.ts +96 -0
  39. package/tests/examples/soldermask/soldermask-only.test.ts +96 -0
@@ -4,23 +4,91 @@ import type { PcbSmtPadRect } from "circuit-json"
4
4
  import { ShapePath } from "lbrnts"
5
5
 
6
6
  export const addRectSmtPad = (smtPad: PcbSmtPadRect, ctx: ConvertContext) => {
7
- const { project, copperCutSetting, connMap, netGeoms, origin } = ctx
7
+ const {
8
+ project,
9
+ copperCutSetting,
10
+ connMap,
11
+ netGeoms,
12
+ origin,
13
+ includeCopper,
14
+ includeSoldermask,
15
+ } = ctx
8
16
 
9
17
  const centerX = smtPad.x + origin.x
10
18
  const centerY = smtPad.y + origin.y
11
19
  const halfWidth = smtPad.width / 2
12
20
  const halfHeight = smtPad.height / 2
13
21
 
14
- const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id)!
15
-
16
- ctx.netGeoms
17
- .get(netId)
18
- ?.push(
19
- new Box(
20
- centerX - halfWidth,
21
- centerY - halfHeight,
22
- centerX + halfWidth,
23
- centerY + halfHeight,
24
- ),
22
+ const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id)
23
+
24
+ // Only add to netGeoms if drawing copper
25
+ if (includeCopper) {
26
+ if (netId) {
27
+ // Add to netGeoms to be merged with other elements on the same net
28
+ ctx.netGeoms
29
+ .get(netId)
30
+ ?.push(
31
+ new Box(
32
+ centerX - halfWidth,
33
+ centerY - halfHeight,
34
+ centerX + halfWidth,
35
+ centerY + halfHeight,
36
+ ),
37
+ )
38
+ } else {
39
+ // No net connection - draw directly
40
+ const verts = [
41
+ { x: centerX - halfWidth, y: centerY - halfHeight },
42
+ { x: centerX + halfWidth, y: centerY - halfHeight },
43
+ { x: centerX + halfWidth, y: centerY + halfHeight },
44
+ { x: centerX - halfWidth, y: centerY + halfHeight },
45
+ { x: centerX - halfWidth, y: centerY - halfHeight }, // Close the path
46
+ ]
47
+
48
+ const prims = [
49
+ { type: 0 },
50
+ { type: 0 },
51
+ { type: 0 },
52
+ { type: 0 },
53
+ { type: 0 },
54
+ ]
55
+
56
+ project.children.push(
57
+ new ShapePath({
58
+ cutIndex: copperCutSetting.index,
59
+ verts,
60
+ prims,
61
+ isClosed: true,
62
+ }),
63
+ )
64
+ }
65
+ }
66
+
67
+ // Add soldermask opening if drawing soldermask
68
+ if (includeSoldermask) {
69
+ const verts = [
70
+ { x: centerX - halfWidth, y: centerY - halfHeight },
71
+ { x: centerX + halfWidth, y: centerY - halfHeight },
72
+ { x: centerX + halfWidth, y: centerY + halfHeight },
73
+ { x: centerX - halfWidth, y: centerY + halfHeight },
74
+ { x: centerX - halfWidth, y: centerY - halfHeight }, // Close the path
75
+ ]
76
+
77
+ const prims = [
78
+ { type: 0 },
79
+ { type: 0 },
80
+ { type: 0 },
81
+ { type: 0 },
82
+ { type: 0 },
83
+ ]
84
+
85
+ project.children.push(
86
+ new ShapePath({
87
+ cutIndex: copperCutSetting.index,
88
+ verts,
89
+ prims,
90
+ isClosed: true,
91
+ }),
25
92
  )
93
+ }
26
94
  }
@@ -0,0 +1,64 @@
1
+ import type { PcbSmtPadRotatedPill } from "circuit-json"
2
+ import type { ConvertContext } from "../../ConvertContext"
3
+ import { ShapePath } from "lbrnts"
4
+ import { createPillPath } from "../../helpers/pillShape"
5
+ import { pathToPolygon } from "../../helpers/pathToPolygon"
6
+
7
+ export const addRotatedPillSmtPad = (
8
+ smtPad: PcbSmtPadRotatedPill,
9
+ ctx: ConvertContext,
10
+ ): void => {
11
+ const {
12
+ project,
13
+ copperCutSetting,
14
+ origin,
15
+ includeCopper,
16
+ includeSoldermask,
17
+ connMap,
18
+ } = ctx
19
+ const centerX = smtPad.x + origin.x
20
+ const centerY = smtPad.y + origin.y
21
+
22
+ if (smtPad.width > 0 && smtPad.height > 0) {
23
+ const outer = createPillPath(
24
+ centerX,
25
+ centerY,
26
+ smtPad.width,
27
+ smtPad.height,
28
+ (smtPad.ccw_rotation ?? 0) * (Math.PI / 180),
29
+ )
30
+
31
+ // Add to netGeoms for copper (will be merged with traces)
32
+ if (includeCopper) {
33
+ const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id)
34
+ const polygon = pathToPolygon(outer.verts)
35
+
36
+ if (netId) {
37
+ // Add to netGeoms to be merged with other elements on the same net
38
+ ctx.netGeoms.get(netId)?.push(polygon)
39
+ } else {
40
+ // No net connection - draw directly
41
+ project.children.push(
42
+ new ShapePath({
43
+ cutIndex: copperCutSetting.index,
44
+ verts: outer.verts,
45
+ prims: outer.prims,
46
+ isClosed: true,
47
+ }),
48
+ )
49
+ }
50
+ }
51
+
52
+ // Add soldermask opening if drawing soldermask
53
+ if (includeSoldermask) {
54
+ project.children.push(
55
+ new ShapePath({
56
+ cutIndex: copperCutSetting.index,
57
+ verts: outer.verts,
58
+ prims: outer.prims,
59
+ isClosed: true,
60
+ }),
61
+ )
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,68 @@
1
+ import type { PcbSmtPadRotatedRect } from "circuit-json"
2
+ import type { ConvertContext } from "../../ConvertContext"
3
+ import { ShapePath } from "lbrnts"
4
+ import { createRoundedRectPath } from "../../helpers/roundedRectShape"
5
+ import { pathToPolygon } from "../../helpers/pathToPolygon"
6
+
7
+ export const addRotatedRectSmtPad = (
8
+ smtPad: PcbSmtPadRotatedRect,
9
+ ctx: ConvertContext,
10
+ ): void => {
11
+ const {
12
+ project,
13
+ copperCutSetting,
14
+ origin,
15
+ includeCopper,
16
+ includeSoldermask,
17
+ connMap,
18
+ } = ctx
19
+ const centerX = smtPad.x + origin.x
20
+ const centerY = smtPad.y + origin.y
21
+ const rotation = smtPad.ccw_rotation ?? 0
22
+ const borderRadius = smtPad.rect_border_radius ?? 0
23
+
24
+ if (smtPad.width > 0 && smtPad.height > 0) {
25
+ const outer = createRoundedRectPath(
26
+ centerX,
27
+ centerY,
28
+ smtPad.width,
29
+ smtPad.height,
30
+ borderRadius,
31
+ 4,
32
+ rotation,
33
+ )
34
+
35
+ // Add to netGeoms for copper (will be merged with traces)
36
+ if (includeCopper) {
37
+ const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id)
38
+ const polygon = pathToPolygon(outer.verts)
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
+ project.children.push(
46
+ new ShapePath({
47
+ cutIndex: copperCutSetting.index,
48
+ verts: outer.verts,
49
+ prims: outer.prims,
50
+ isClosed: true,
51
+ }),
52
+ )
53
+ }
54
+ }
55
+
56
+ // Add soldermask opening if drawing soldermask
57
+ if (includeSoldermask) {
58
+ project.children.push(
59
+ new ShapePath({
60
+ cutIndex: copperCutSetting.index,
61
+ verts: outer.verts,
62
+ prims: outer.prims,
63
+ isClosed: true,
64
+ }),
65
+ )
66
+ }
67
+ }
68
+ }
@@ -1,15 +1,33 @@
1
1
  import type { PcbSmtPad } from "circuit-json"
2
2
  import type { ConvertContext } from "../../ConvertContext"
3
3
  import { addRectSmtPad } from "./addRectSmtPad"
4
+ import { addCircleSmtPad } from "./addCircleSmtPad"
5
+ import { addPillSmtPad } from "./addPillSmtPad"
6
+ import { addRotatedPillSmtPad } from "./addRotatedPillSmtPad"
7
+ import { addPolygonSmtPad } from "./addPolygonSmtPad"
8
+ import { addRotatedRectSmtPad } from "./addRotatedRectSmtPad"
4
9
 
5
10
  export const addSmtPad = (smtPad: PcbSmtPad, ctx: ConvertContext) => {
6
11
  switch (smtPad.shape) {
7
- case "rect": {
8
- addRectSmtPad(smtPad, ctx)
9
- break
10
- }
11
- default: {
12
- throw new Error(`Unknown smt pad shape: ${smtPad.shape}`)
13
- }
12
+ case "rect":
13
+ return addRectSmtPad(smtPad, ctx)
14
+
15
+ case "circle":
16
+ return addCircleSmtPad(smtPad, ctx)
17
+
18
+ case "pill":
19
+ return addPillSmtPad(smtPad, ctx)
20
+
21
+ case "rotated_pill":
22
+ return addRotatedPillSmtPad(smtPad, ctx)
23
+
24
+ case "polygon":
25
+ return addPolygonSmtPad(smtPad, ctx)
26
+
27
+ case "rotated_rect":
28
+ return addRotatedRectSmtPad(smtPad, ctx)
29
+
30
+ default:
31
+ throw new Error(`Unknown smt pad shape: ${(smtPad as any).shape}`)
14
32
  }
15
33
  }
@@ -0,0 +1,14 @@
1
+ import { Polygon, point } from "@flatten-js/core"
2
+
3
+ export interface Point {
4
+ x: number
5
+ y: number
6
+ }
7
+
8
+ /**
9
+ * Convert an array of points to a Polygon
10
+ */
11
+ export const pathToPolygon = (verts: Point[]): Polygon => {
12
+ const points = verts.map((v) => point(v.x, v.y))
13
+ return new Polygon(points)
14
+ }
package/lib/index.ts CHANGED
@@ -21,6 +21,8 @@ export const convertCircuitJsonToLbrn = (
21
21
  includeSilkscreen?: boolean
22
22
  origin?: { x: number; y: number }
23
23
  margin?: number
24
+ includeCopper?: boolean
25
+ includeSoldermask?: boolean
24
26
  } = {},
25
27
  ): LightBurnProject => {
26
28
  const db = cju(circuitJson)
@@ -62,6 +64,8 @@ export const convertCircuitJsonToLbrn = (
62
64
  connMap,
63
65
  netGeoms: new Map(),
64
66
  origin,
67
+ includeCopper: options.includeCopper ?? true,
68
+ includeSoldermask: options.includeSoldermask ?? false,
65
69
  }
66
70
 
67
71
  for (const net of Object.keys(connMap.netMap)) {
@@ -112,42 +116,45 @@ export const convertCircuitJsonToLbrn = (
112
116
  // }
113
117
 
114
118
  // Create a union of all the net geoms, and add to project
115
- for (const net of Object.keys(connMap.netMap)) {
116
- const netGeoms = ctx.netGeoms.get(net)!
119
+ // Only do this when including copper
120
+ if (ctx.includeCopper) {
121
+ for (const net of Object.keys(connMap.netMap)) {
122
+ const netGeoms = ctx.netGeoms.get(net)!
117
123
 
118
- if (netGeoms.length === 0) {
119
- continue
120
- }
124
+ if (netGeoms.length === 0) {
125
+ continue
126
+ }
121
127
 
122
- let union = netGeoms[0]!
123
- if (union instanceof Box) {
124
- union = new Polygon(union)
125
- }
126
- for (const geom of netGeoms.slice(1)) {
127
- if (geom instanceof Polygon) {
128
- union = BooleanOperations.unify(union, geom)
129
- } else if (geom instanceof Box) {
130
- union = BooleanOperations.unify(union, new Polygon(geom))
128
+ let union = netGeoms[0]!
129
+ if (union instanceof Box) {
130
+ union = new Polygon(union)
131
+ }
132
+ for (const geom of netGeoms.slice(1)) {
133
+ if (geom instanceof Polygon) {
134
+ union = BooleanOperations.unify(union, geom)
135
+ } else if (geom instanceof Box) {
136
+ union = BooleanOperations.unify(union, new Polygon(geom))
137
+ }
131
138
  }
132
- }
133
139
 
134
- // DEBUGGING ONLY!!!
135
- // if (netGeoms.length > 1) {
136
- // writeDebugSvg(net, union)
137
- // }
138
-
139
- for (const island of union.splitToIslands()) {
140
- // Convert the polygon to verts and prims
141
- const { verts, prims } = polygonToShapePathData(island)
142
-
143
- project.children.push(
144
- new ShapePath({
145
- cutIndex: copperCutSetting.index,
146
- verts,
147
- prims,
148
- isClosed: false,
149
- }),
150
- )
140
+ // DEBUGGING ONLY!!!
141
+ // if (netGeoms.length > 1) {
142
+ // writeDebugSvg(net, union)
143
+ // }
144
+
145
+ for (const island of union.splitToIslands()) {
146
+ // Convert the polygon to verts and prims
147
+ const { verts, prims } = polygonToShapePathData(island)
148
+
149
+ project.children.push(
150
+ new ShapePath({
151
+ cutIndex: copperCutSetting.index,
152
+ verts,
153
+ prims,
154
+ isClosed: false,
155
+ }),
156
+ )
157
+ }
151
158
  }
152
159
  }
153
160
  return project
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.8",
4
+ "version": "0.0.10",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "bun run site/index.html",
@@ -19,7 +19,7 @@
19
19
  "bun-match-svg": "^0.0.14",
20
20
  "circuit-json": "^0.0.316",
21
21
  "circuit-json-to-connectivity-map": "^0.0.22",
22
- "circuit-to-svg": "^0.0.271",
22
+ "circuit-to-svg": "^0.0.283",
23
23
  "schematic-symbols": "^0.0.202",
24
24
  "stack-svgs": "^0.0.1",
25
25
  "tsup": "^8.5.1"