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.
- package/README.md +39 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +596 -122
- package/lib/ConvertContext.ts +4 -0
- package/lib/element-handlers/addPcbTrace/index.ts +7 -1
- package/lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts +38 -4
- package/lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts +32 -11
- package/lib/element-handlers/addPlatedHole/addHoleWithPolygonPad.ts +31 -9
- package/lib/element-handlers/addPlatedHole/addOvalPlatedHole.ts +38 -4
- package/lib/element-handlers/addPlatedHole/addPillHoleWithRectPad.ts +31 -9
- package/lib/element-handlers/addPlatedHole/addPillPlatedHole.ts +38 -4
- package/lib/element-handlers/addPlatedHole/addRotatedPillHoleWithRectPad.ts +31 -9
- package/lib/element-handlers/addSmtPad/addCircleSmtPad.ts +62 -0
- package/lib/element-handlers/addSmtPad/addPillSmtPad.ts +58 -0
- package/lib/element-handlers/addSmtPad/addPolygonSmtPad.ts +57 -0
- package/lib/element-handlers/addSmtPad/addRectSmtPad.ts +80 -12
- package/lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts +64 -0
- package/lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts +68 -0
- package/lib/element-handlers/addSmtPad/index.ts +25 -7
- package/lib/helpers/pathToPolygon.ts +14 -0
- package/lib/index.ts +39 -32
- package/package.json +2 -2
- package/tests/examples/__snapshots__/lga-interconnect.snap.svg +1 -1
- package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-circle.snap.svg +1 -1
- package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-oval.snap.svg +1 -1
- package/tests/examples/addSmtPad/__snapshots__/circleSmtPad.snap.svg +8 -0
- package/tests/examples/addSmtPad/__snapshots__/pillSmtPad.snap.svg +8 -0
- package/tests/examples/addSmtPad/__snapshots__/polygonSmtPad.snap.svg +8 -0
- package/tests/examples/addSmtPad/__snapshots__/rotatedPillSmtPad.snap.svg +8 -0
- package/tests/examples/addSmtPad/__snapshots__/rotatedRectSmtPad.snap.svg +8 -0
- package/tests/examples/addSmtPad/circleSmtPad.test.ts +45 -0
- package/tests/examples/addSmtPad/pillSmtPad.test.ts +47 -0
- package/tests/examples/addSmtPad/polygonSmtPad.test.ts +51 -0
- package/tests/examples/addSmtPad/rotatedPillSmtPad.test.ts +48 -0
- package/tests/examples/addSmtPad/rotatedRectSmtPad.test.ts +59 -0
- package/tests/examples/soldermask/__snapshots__/copper-and-soldermask.snap.svg +8 -0
- package/tests/examples/soldermask/__snapshots__/soldermask-only.snap.svg +8 -0
- package/tests/examples/soldermask/copper-and-soldermask.test.ts +96 -0
- 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 {
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
116
|
-
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
if (netGeoms.length === 0) {
|
|
125
|
+
continue
|
|
126
|
+
}
|
|
121
127
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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.
|
|
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.
|
|
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"
|