circuit-json-to-lbrn 0.0.9 → 0.0.11

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 (33) hide show
  1. package/README.md +39 -2
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +567 -171
  4. package/lib/ConvertContext.ts +6 -1
  5. package/lib/element-handlers/addPcbBoard/index.ts +28 -9
  6. package/lib/element-handlers/addPcbTrace/index.ts +7 -1
  7. package/lib/element-handlers/addPlatedHole/addCirclePlatedHole.ts +40 -5
  8. package/lib/element-handlers/addPlatedHole/addCircularHoleWithRectPad.ts +33 -11
  9. package/lib/element-handlers/addPlatedHole/addHoleWithPolygonPad.ts +32 -9
  10. package/lib/element-handlers/addPlatedHole/addOvalPlatedHole.ts +39 -4
  11. package/lib/element-handlers/addPlatedHole/addPillHoleWithRectPad.ts +32 -9
  12. package/lib/element-handlers/addPlatedHole/addPillPlatedHole.ts +38 -3
  13. package/lib/element-handlers/addPlatedHole/addRotatedPillHoleWithRectPad.ts +32 -9
  14. package/lib/element-handlers/addSmtPad/addCircleSmtPad.ts +47 -10
  15. package/lib/element-handlers/addSmtPad/addPillSmtPad.ts +43 -9
  16. package/lib/element-handlers/addSmtPad/addPolygonSmtPad.ts +42 -9
  17. package/lib/element-handlers/addSmtPad/addRectSmtPad.ts +81 -12
  18. package/lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts +43 -10
  19. package/lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts +42 -9
  20. package/lib/helpers/pathToPolygon.ts +14 -0
  21. package/lib/index.ts +48 -32
  22. package/package.json +2 -2
  23. package/tests/examples/__snapshots__/board-outline-soldermask-preset.snap.svg +8 -0
  24. package/tests/examples/__snapshots__/lga-interconnect.snap.svg +1 -1
  25. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-circle.snap.svg +1 -1
  26. package/tests/examples/addSmtPad/__snapshots__/rotatedPillSmtPad.snap.svg +1 -1
  27. package/tests/examples/board-outline-soldermask-preset.test.ts +44 -0
  28. package/tests/examples/soldermask/__snapshots__/copper-and-soldermask.snap.svg +8 -0
  29. package/tests/examples/soldermask/__snapshots__/copper-only.snap.svg +8 -0
  30. package/tests/examples/soldermask/__snapshots__/soldermask-only.snap.svg +8 -0
  31. package/tests/examples/soldermask/copper-and-soldermask.test.ts +117 -0
  32. package/tests/examples/soldermask/copper-only.test.ts +106 -0
  33. package/tests/examples/soldermask/soldermask-only.test.ts +109 -0
@@ -1,6 +1,6 @@
1
1
  import type { CircuitJsonUtilObjects } from "@tscircuit/circuit-json-util"
2
2
  import type { CutSetting, LightBurnProject } from "lbrnts"
3
- import type { AnyShape, Box, Polygon } from "@flatten-js/core"
3
+ import type { Box, Polygon } from "@flatten-js/core"
4
4
  import type { ConnectivityMap } from "circuit-json-to-connectivity-map"
5
5
 
6
6
  export type ConnectivityMapKey = string
@@ -11,10 +11,15 @@ export interface ConvertContext {
11
11
 
12
12
  copperCutSetting: CutSetting
13
13
  throughBoardCutSetting: CutSetting
14
+ soldermaskCutSetting: CutSetting
14
15
 
15
16
  connMap: ConnectivityMap
16
17
 
17
18
  netGeoms: Map<ConnectivityMapKey, Array<Polygon | Box>>
18
19
 
19
20
  origin: { x: number; y: number }
21
+
22
+ // Include flags
23
+ includeCopper: boolean
24
+ includeSoldermask: boolean
20
25
  }
@@ -5,7 +5,14 @@ import type { ConvertContext } from "../../ConvertContext"
5
5
  import { polygonToShapePathData } from "../../polygon-to-shape-path"
6
6
 
7
7
  export const addPcbBoard = (board: PcbBoard, ctx: ConvertContext) => {
8
- const { origin, project, throughBoardCutSetting } = ctx
8
+ const {
9
+ origin,
10
+ project,
11
+ throughBoardCutSetting,
12
+ soldermaskCutSetting,
13
+ includeCopper,
14
+ includeSoldermask,
15
+ } = ctx
9
16
 
10
17
  let polygon: Polygon | null = null
11
18
 
@@ -39,12 +46,24 @@ export const addPcbBoard = (board: PcbBoard, ctx: ConvertContext) => {
39
46
 
40
47
  const { verts, prims } = polygonToShapePathData(polygon)
41
48
 
42
- project.children.push(
43
- new ShapePath({
44
- cutIndex: throughBoardCutSetting.index,
45
- verts,
46
- prims,
47
- isClosed: true,
48
- }),
49
- )
49
+ if (includeCopper) {
50
+ project.children.push(
51
+ new ShapePath({
52
+ cutIndex: throughBoardCutSetting.index,
53
+ verts,
54
+ prims,
55
+ isClosed: true,
56
+ }),
57
+ )
58
+ }
59
+ if (includeSoldermask) {
60
+ project.children.push(
61
+ new ShapePath({
62
+ cutIndex: soldermaskCutSetting.index,
63
+ verts,
64
+ prims,
65
+ isClosed: true,
66
+ }),
67
+ )
68
+ }
50
69
  }
@@ -4,7 +4,13 @@ import Flatten, { BooleanOperations } from "@flatten-js/core"
4
4
  import { circleToPolygon } from "./circle-to-polygon"
5
5
 
6
6
  export const addPcbTrace = (trace: PcbTrace, ctx: ConvertContext) => {
7
- const { netGeoms, connMap, origin } = ctx
7
+ const { netGeoms, connMap, origin, includeCopper, includeSoldermask } = ctx
8
+
9
+ // Only include traces when including copper
10
+ // Traces are NOT included in soldermask-only mode to prevent accidental bridging
11
+ if (!includeCopper) {
12
+ return
13
+ }
8
14
 
9
15
  const netId = connMap.getNetConnectedToId(
10
16
  trace.source_trace_id ?? trace.pcb_trace_id,
@@ -2,22 +2,57 @@ import type { PcbPlatedHoleCircle } from "circuit-json"
2
2
  import type { ConvertContext } from "../../ConvertContext"
3
3
  import { ShapePath } from "lbrnts"
4
4
  import { createCirclePath } from "../../helpers/circleShape"
5
+ import { Circle, point } from "@flatten-js/core"
6
+ import { circleToPolygon } from "../addPcbTrace/circle-to-polygon"
5
7
 
6
8
  export const addCirclePlatedHole = (
7
9
  platedHole: PcbPlatedHoleCircle,
8
10
  ctx: ConvertContext,
9
11
  ): void => {
10
- const { project, copperCutSetting, throughBoardCutSetting, origin } = ctx
12
+ const {
13
+ project,
14
+ copperCutSetting,
15
+ soldermaskCutSetting,
16
+ throughBoardCutSetting,
17
+ origin,
18
+ includeCopper,
19
+ includeSoldermask,
20
+ connMap,
21
+ } = ctx
11
22
  const centerX = platedHole.x + origin.x
12
23
  const centerY = platedHole.y + origin.y
13
24
 
14
- // Add outer circle (copper annulus)
15
- if (platedHole.outer_diameter > 0) {
25
+ // Add outer circle (copper annulus) if drawing copper - add to netGeoms for merging
26
+ if (platedHole.outer_diameter > 0 && includeCopper) {
27
+ const netId = connMap.getNetConnectedToId(platedHole.pcb_plated_hole_id)
28
+ const outerRadius = platedHole.outer_diameter / 2
29
+ const circle = new Circle(point(centerX, centerY), outerRadius)
30
+ const polygon = circleToPolygon(circle)
31
+
32
+ if (netId) {
33
+ // Add to netGeoms to be merged with other elements on the same net
34
+ ctx.netGeoms.get(netId)?.push(polygon)
35
+ } else {
36
+ // No net connection - draw directly
37
+ const outer = createCirclePath(centerX, centerY, outerRadius)
38
+ project.children.push(
39
+ new ShapePath({
40
+ cutIndex: copperCutSetting.index,
41
+ verts: outer.verts,
42
+ prims: outer.prims,
43
+ isClosed: true,
44
+ }),
45
+ )
46
+ }
47
+ }
48
+
49
+ // Add soldermask opening if drawing soldermask
50
+ if (platedHole.outer_diameter > 0 && includeSoldermask) {
16
51
  const outerRadius = platedHole.outer_diameter / 2
17
52
  const outer = createCirclePath(centerX, centerY, outerRadius)
18
53
  project.children.push(
19
54
  new ShapePath({
20
- cutIndex: copperCutSetting.index,
55
+ cutIndex: soldermaskCutSetting.index,
21
56
  verts: outer.verts,
22
57
  prims: outer.prims,
23
58
  isClosed: true,
@@ -25,7 +60,7 @@ export const addCirclePlatedHole = (
25
60
  )
26
61
  }
27
62
 
28
- // Add inner circle (hole)
63
+ // Add inner circle (hole) - always cut through the board regardless of mode
29
64
  if (platedHole.hole_diameter > 0) {
30
65
  const innerRadius = platedHole.hole_diameter / 2
31
66
  const inner = createCirclePath(centerX, centerY, innerRadius)
@@ -8,7 +8,15 @@ export const addCircularHoleWithRectPad = (
8
8
  platedHole: PcbHoleCircularWithRectPad,
9
9
  ctx: ConvertContext,
10
10
  ): void => {
11
- const { project, copperCutSetting, throughBoardCutSetting, origin } = ctx
11
+ const {
12
+ project,
13
+ copperCutSetting,
14
+ soldermaskCutSetting,
15
+ throughBoardCutSetting,
16
+ origin,
17
+ includeCopper,
18
+ includeSoldermask,
19
+ } = ctx
12
20
  const centerX = platedHole.x + origin.x
13
21
  const centerY = platedHole.y + origin.y
14
22
  const holeRadius = platedHole.hole_diameter / 2
@@ -25,17 +33,31 @@ export const addCircularHoleWithRectPad = (
25
33
  borderRadius,
26
34
  )
27
35
 
28
- // Add the rectangular pad
29
- project.children.push(
30
- new ShapePath({
31
- cutIndex: copperCutSetting.index,
32
- verts: padPath.verts,
33
- prims: padPath.prims,
34
- isClosed: true,
35
- }),
36
- )
36
+ // Add the rectangular pad if drawing copper
37
+ if (includeCopper) {
38
+ project.children.push(
39
+ new ShapePath({
40
+ cutIndex: copperCutSetting.index,
41
+ verts: padPath.verts,
42
+ prims: padPath.prims,
43
+ isClosed: true,
44
+ }),
45
+ )
46
+ }
47
+
48
+ // Add soldermask opening if drawing soldermask
49
+ if (includeSoldermask) {
50
+ project.children.push(
51
+ new ShapePath({
52
+ cutIndex: soldermaskCutSetting.index,
53
+ verts: padPath.verts,
54
+ prims: padPath.prims,
55
+ isClosed: true,
56
+ }),
57
+ )
58
+ }
37
59
 
38
- // Add the circular hole (as a cutout)
60
+ // Add the circular hole (as a cutout) - always cut through the board regardless of mode
39
61
  if (holeRadius > 0) {
40
62
  const holeCenterX = centerX + platedHole.hole_offset_x
41
63
  const holeCenterY = centerY + platedHole.hole_offset_y
@@ -8,7 +8,15 @@ export const addHoleWithPolygonPad = (
8
8
  platedHole: PcbHoleWithPolygonPad,
9
9
  ctx: ConvertContext,
10
10
  ): void => {
11
- const { project, copperCutSetting, throughBoardCutSetting, origin } = ctx
11
+ const {
12
+ project,
13
+ copperCutSetting,
14
+ soldermaskCutSetting,
15
+ throughBoardCutSetting,
16
+ origin,
17
+ includeCopper,
18
+ includeSoldermask,
19
+ } = ctx
12
20
 
13
21
  // Create the polygon pad
14
22
  if (platedHole.pad_outline.length >= 3) {
@@ -18,14 +26,29 @@ export const addHoleWithPolygonPad = (
18
26
  platedHole.y + origin.y,
19
27
  )
20
28
 
21
- project.children.push(
22
- new ShapePath({
23
- cutIndex: copperCutSetting.index,
24
- verts: pad.verts,
25
- prims: pad.prims,
26
- isClosed: true,
27
- }),
28
- )
29
+ // Add the polygon pad if drawing copper
30
+ if (includeCopper) {
31
+ project.children.push(
32
+ new ShapePath({
33
+ cutIndex: copperCutSetting.index,
34
+ verts: pad.verts,
35
+ prims: pad.prims,
36
+ isClosed: true,
37
+ }),
38
+ )
39
+ }
40
+
41
+ // Add soldermask opening if drawing soldermask
42
+ if (includeSoldermask) {
43
+ project.children.push(
44
+ new ShapePath({
45
+ cutIndex: soldermaskCutSetting.index,
46
+ verts: pad.verts,
47
+ prims: pad.prims,
48
+ isClosed: true,
49
+ }),
50
+ )
51
+ }
29
52
  }
30
53
 
31
54
  if (platedHole.hole_shape === "circle" && platedHole.hole_diameter) {
@@ -7,7 +7,15 @@ export const addOvalPlatedHole = (
7
7
  platedHole: PcbPlatedHoleOval,
8
8
  ctx: ConvertContext,
9
9
  ): void => {
10
- const { project, copperCutSetting, throughBoardCutSetting, origin } = ctx
10
+ const {
11
+ project,
12
+ copperCutSetting,
13
+ soldermaskCutSetting,
14
+ throughBoardCutSetting,
15
+ origin,
16
+ includeCopper,
17
+ includeSoldermask,
18
+ } = ctx
11
19
 
12
20
  if (platedHole.outer_width <= 0 || platedHole.outer_height <= 0) {
13
21
  return
@@ -17,8 +25,12 @@ export const addOvalPlatedHole = (
17
25
  const centerY = platedHole.y + origin.y
18
26
  const rotation = (platedHole.ccw_rotation ?? 0) * (Math.PI / 180)
19
27
 
20
- // Add outer oval (copper)
21
- if (platedHole.outer_width > 0 && platedHole.outer_height > 0) {
28
+ // Add outer oval (copper) if drawing copper
29
+ if (
30
+ platedHole.outer_width > 0 &&
31
+ platedHole.outer_height > 0 &&
32
+ includeCopper
33
+ ) {
22
34
  const outer = createOvalPath(
23
35
  centerX,
24
36
  centerY,
@@ -36,7 +48,30 @@ export const addOvalPlatedHole = (
36
48
  )
37
49
  }
38
50
 
39
- // Add inner oval (hole)
51
+ // Add soldermask opening if drawing soldermask
52
+ if (
53
+ platedHole.outer_width > 0 &&
54
+ platedHole.outer_height > 0 &&
55
+ includeSoldermask
56
+ ) {
57
+ const outer = createOvalPath(
58
+ centerX,
59
+ centerY,
60
+ platedHole.outer_width,
61
+ platedHole.outer_height,
62
+ rotation,
63
+ )
64
+ project.children.push(
65
+ new ShapePath({
66
+ cutIndex: soldermaskCutSetting.index,
67
+ verts: outer.verts,
68
+ prims: outer.prims,
69
+ isClosed: true,
70
+ }),
71
+ )
72
+ }
73
+
74
+ // Add inner oval (hole) - always cut through the board regardless of mode
40
75
  if (platedHole.hole_width > 0 && platedHole.hole_height > 0) {
41
76
  const inner = createOvalPath(
42
77
  centerX,
@@ -8,7 +8,15 @@ export const addPillHoleWithRectPad = (
8
8
  platedHole: PcbHolePillWithRectPad,
9
9
  ctx: ConvertContext,
10
10
  ): void => {
11
- const { project, copperCutSetting, throughBoardCutSetting, origin } = ctx
11
+ const {
12
+ project,
13
+ copperCutSetting,
14
+ soldermaskCutSetting,
15
+ throughBoardCutSetting,
16
+ origin,
17
+ includeCopper,
18
+ includeSoldermask,
19
+ } = ctx
12
20
  const centerX = platedHole.x + origin.x
13
21
  const centerY = platedHole.y + origin.y
14
22
 
@@ -25,14 +33,29 @@ export const addPillHoleWithRectPad = (
25
33
  borderRadius,
26
34
  )
27
35
 
28
- project.children.push(
29
- new ShapePath({
30
- cutIndex: copperCutSetting.index,
31
- verts: padPath.verts,
32
- prims: padPath.prims,
33
- isClosed: true,
34
- }),
35
- )
36
+ // Add the rectangular pad if drawing copper
37
+ if (includeCopper) {
38
+ project.children.push(
39
+ new ShapePath({
40
+ cutIndex: copperCutSetting.index,
41
+ verts: padPath.verts,
42
+ prims: padPath.prims,
43
+ isClosed: true,
44
+ }),
45
+ )
46
+ }
47
+
48
+ // Add soldermask opening if drawing soldermask
49
+ if (includeSoldermask) {
50
+ project.children.push(
51
+ new ShapePath({
52
+ cutIndex: soldermaskCutSetting.index,
53
+ verts: padPath.verts,
54
+ prims: padPath.prims,
55
+ isClosed: true,
56
+ }),
57
+ )
58
+ }
36
59
  }
37
60
 
38
61
  const holeWidth = platedHole.hole_width
@@ -7,13 +7,25 @@ export const addPcbPlatedHolePill = (
7
7
  platedHole: PcbPlatedHoleOval,
8
8
  ctx: ConvertContext,
9
9
  ): void => {
10
- const { project, copperCutSetting, throughBoardCutSetting, origin } = ctx
10
+ const {
11
+ project,
12
+ copperCutSetting,
13
+ soldermaskCutSetting,
14
+ throughBoardCutSetting,
15
+ origin,
16
+ includeCopper,
17
+ includeSoldermask,
18
+ } = ctx
11
19
  const centerX = platedHole.x + origin.x
12
20
  const centerY = platedHole.y + origin.y
13
21
  const rotation = (platedHole.ccw_rotation || 0) * (Math.PI / 180) // Convert degrees to radians
14
22
 
15
- // Add outer pill shape (copper)
16
- if (platedHole.outer_width > 0 && platedHole.outer_height > 0) {
23
+ // Add outer pill shape (copper) if drawing copper
24
+ if (
25
+ platedHole.outer_width > 0 &&
26
+ platedHole.outer_height > 0 &&
27
+ includeCopper
28
+ ) {
17
29
  const outer = createPillPath(
18
30
  centerX,
19
31
  centerY,
@@ -31,6 +43,29 @@ export const addPcbPlatedHolePill = (
31
43
  )
32
44
  }
33
45
 
46
+ // Add soldermask opening if drawing soldermask
47
+ if (
48
+ platedHole.outer_width > 0 &&
49
+ platedHole.outer_height > 0 &&
50
+ includeSoldermask
51
+ ) {
52
+ const outer = createPillPath(
53
+ centerX,
54
+ centerY,
55
+ platedHole.outer_width,
56
+ platedHole.outer_height,
57
+ rotation,
58
+ )
59
+ project.children.push(
60
+ new ShapePath({
61
+ cutIndex: soldermaskCutSetting.index,
62
+ verts: outer.verts,
63
+ prims: outer.prims,
64
+ isClosed: true,
65
+ }),
66
+ )
67
+ }
68
+
34
69
  // Add inner pill shape (hole)
35
70
  if (platedHole.hole_width > 0 && platedHole.hole_height > 0) {
36
71
  const inner = createPillPath(
@@ -8,7 +8,15 @@ export const addRotatedPillHoleWithRectPad = (
8
8
  platedHole: PcbHoleRotatedPillWithRectPad,
9
9
  ctx: ConvertContext,
10
10
  ): void => {
11
- const { project, copperCutSetting, throughBoardCutSetting, origin } = ctx
11
+ const {
12
+ project,
13
+ copperCutSetting,
14
+ soldermaskCutSetting,
15
+ throughBoardCutSetting,
16
+ origin,
17
+ includeCopper,
18
+ includeSoldermask,
19
+ } = ctx
12
20
  const centerX = platedHole.x + origin.x
13
21
  const centerY = platedHole.y + origin.y
14
22
 
@@ -28,14 +36,29 @@ export const addRotatedPillHoleWithRectPad = (
28
36
  padRotation,
29
37
  )
30
38
 
31
- project.children.push(
32
- new ShapePath({
33
- cutIndex: copperCutSetting.index,
34
- verts: padPath.verts,
35
- prims: padPath.prims,
36
- isClosed: true,
37
- }),
38
- )
39
+ // Add the rectangular pad if drawing copper
40
+ if (includeCopper) {
41
+ project.children.push(
42
+ new ShapePath({
43
+ cutIndex: copperCutSetting.index,
44
+ verts: padPath.verts,
45
+ prims: padPath.prims,
46
+ isClosed: true,
47
+ }),
48
+ )
49
+ }
50
+
51
+ // Add soldermask opening if drawing soldermask
52
+ if (includeSoldermask) {
53
+ project.children.push(
54
+ new ShapePath({
55
+ cutIndex: soldermaskCutSetting.index,
56
+ verts: padPath.verts,
57
+ prims: padPath.prims,
58
+ isClosed: true,
59
+ }),
60
+ )
61
+ }
39
62
  }
40
63
 
41
64
  const holeWidth = platedHole.hole_width
@@ -2,25 +2,62 @@ import type { PcbSmtPadCircle } from "circuit-json"
2
2
  import type { ConvertContext } from "../../ConvertContext"
3
3
  import { ShapePath } from "lbrnts"
4
4
  import { createCirclePath } from "../../helpers/circleShape"
5
+ import { Circle, Polygon, point } from "@flatten-js/core"
6
+ import { circleToPolygon } from "../addPcbTrace/circle-to-polygon"
5
7
 
6
8
  export const addCircleSmtPad = (
7
9
  smtPad: PcbSmtPadCircle,
8
10
  ctx: ConvertContext,
9
11
  ): void => {
10
- const { project, copperCutSetting, origin } = ctx
12
+ const {
13
+ project,
14
+ copperCutSetting,
15
+ soldermaskCutSetting,
16
+ origin,
17
+ includeCopper,
18
+ includeSoldermask,
19
+ connMap,
20
+ } = ctx
11
21
  const centerX = smtPad.x + origin.x
12
22
  const centerY = smtPad.y + origin.y
13
23
 
14
24
  if (smtPad.radius > 0) {
15
25
  const outerRadius = smtPad.radius
16
- const outer = createCirclePath(centerX, centerY, outerRadius)
17
- project.children.push(
18
- new ShapePath({
19
- cutIndex: copperCutSetting.index,
20
- verts: outer.verts,
21
- prims: outer.prims,
22
- isClosed: true,
23
- }),
24
- )
26
+
27
+ // Add to netGeoms for copper (will be merged with traces)
28
+ if (includeCopper) {
29
+ const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id)
30
+ const circle = new Circle(point(centerX, centerY), outerRadius)
31
+ const polygon = circleToPolygon(circle)
32
+
33
+ if (netId) {
34
+ // Add to netGeoms to be merged with other elements on the same net
35
+ ctx.netGeoms.get(netId)?.push(polygon)
36
+ } else {
37
+ // No net connection - draw directly
38
+ const outer = createCirclePath(centerX, centerY, outerRadius)
39
+ project.children.push(
40
+ new ShapePath({
41
+ cutIndex: copperCutSetting.index,
42
+ verts: outer.verts,
43
+ prims: outer.prims,
44
+ isClosed: true,
45
+ }),
46
+ )
47
+ }
48
+ }
49
+
50
+ // Add soldermask opening if drawing soldermask
51
+ if (includeSoldermask) {
52
+ const outer = createCirclePath(centerX, centerY, outerRadius)
53
+ project.children.push(
54
+ new ShapePath({
55
+ cutIndex: soldermaskCutSetting.index,
56
+ verts: outer.verts,
57
+ prims: outer.prims,
58
+ isClosed: true,
59
+ }),
60
+ )
61
+ }
25
62
  }
26
63
  }
@@ -2,24 +2,58 @@ import type { PcbSmtPadPill } from "circuit-json"
2
2
  import type { ConvertContext } from "../../ConvertContext"
3
3
  import { ShapePath } from "lbrnts"
4
4
  import { createPillPath } from "../../helpers/pillShape"
5
+ import { pathToPolygon } from "../../helpers/pathToPolygon"
5
6
 
6
7
  export const addPillSmtPad = (
7
8
  smtPad: PcbSmtPadPill,
8
9
  ctx: ConvertContext,
9
10
  ): void => {
10
- const { project, copperCutSetting, origin } = ctx
11
+ const {
12
+ project,
13
+ copperCutSetting,
14
+ soldermaskCutSetting,
15
+ origin,
16
+ includeCopper,
17
+ includeSoldermask,
18
+ connMap,
19
+ } = ctx
11
20
  const centerX = smtPad.x + origin.x
12
21
  const centerY = smtPad.y + origin.y
13
22
 
14
23
  if (smtPad.width > 0 && smtPad.height > 0) {
15
24
  const outer = createPillPath(centerX, centerY, smtPad.width, smtPad.height)
16
- project.children.push(
17
- new ShapePath({
18
- cutIndex: copperCutSetting.index,
19
- verts: outer.verts,
20
- prims: outer.prims,
21
- isClosed: true,
22
- }),
23
- )
25
+
26
+ // Add to netGeoms for copper (will be merged with traces)
27
+ if (includeCopper) {
28
+ const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id)
29
+ const polygon = pathToPolygon(outer.verts)
30
+
31
+ if (netId) {
32
+ // Add to netGeoms to be merged with other elements on the same net
33
+ ctx.netGeoms.get(netId)?.push(polygon)
34
+ } else {
35
+ // No net connection - draw directly
36
+ project.children.push(
37
+ new ShapePath({
38
+ cutIndex: copperCutSetting.index,
39
+ verts: outer.verts,
40
+ prims: outer.prims,
41
+ isClosed: true,
42
+ }),
43
+ )
44
+ }
45
+ }
46
+
47
+ // Add soldermask opening if drawing soldermask
48
+ if (includeSoldermask) {
49
+ project.children.push(
50
+ new ShapePath({
51
+ cutIndex: soldermaskCutSetting.index,
52
+ verts: outer.verts,
53
+ prims: outer.prims,
54
+ isClosed: true,
55
+ }),
56
+ )
57
+ }
24
58
  }
25
59
  }