circuit-json-to-lbrn 0.0.9 → 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 (28) hide show
  1. package/README.md +39 -2
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +517 -161
  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 +46 -10
  14. package/lib/element-handlers/addSmtPad/addPillSmtPad.ts +42 -9
  15. package/lib/element-handlers/addSmtPad/addPolygonSmtPad.ts +41 -9
  16. package/lib/element-handlers/addSmtPad/addRectSmtPad.ts +80 -12
  17. package/lib/element-handlers/addSmtPad/addRotatedPillSmtPad.ts +42 -10
  18. package/lib/element-handlers/addSmtPad/addRotatedRectSmtPad.ts +41 -9
  19. package/lib/helpers/pathToPolygon.ts +14 -0
  20. package/lib/index.ts +39 -32
  21. package/package.json +2 -2
  22. package/tests/examples/__snapshots__/lga-interconnect.snap.svg +1 -1
  23. package/tests/examples/addPlatedHole/__snapshots__/pcb-plated-hole-circle.snap.svg +1 -1
  24. package/tests/examples/addSmtPad/__snapshots__/rotatedPillSmtPad.snap.svg +1 -1
  25. package/tests/examples/soldermask/__snapshots__/copper-and-soldermask.snap.svg +8 -0
  26. package/tests/examples/soldermask/__snapshots__/soldermask-only.snap.svg +8 -0
  27. package/tests/examples/soldermask/copper-and-soldermask.test.ts +96 -0
  28. package/tests/examples/soldermask/soldermask-only.test.ts +96 -0
@@ -17,4 +17,8 @@ export interface ConvertContext {
17
17
  netGeoms: Map<ConnectivityMapKey, Array<Polygon | Box>>
18
18
 
19
19
  origin: { x: number; y: number }
20
+
21
+ // Include flags
22
+ includeCopper: boolean
23
+ includeSoldermask: boolean
20
24
  }
@@ -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,17 +2,51 @@ 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
+ throughBoardCutSetting,
16
+ origin,
17
+ includeCopper,
18
+ includeSoldermask,
19
+ connMap,
20
+ } = ctx
11
21
  const centerX = platedHole.x + origin.x
12
22
  const centerY = platedHole.y + origin.y
13
23
 
14
- // Add outer circle (copper annulus)
15
- if (platedHole.outer_diameter > 0) {
24
+ // Add outer circle (copper annulus) if drawing copper - add to netGeoms for merging
25
+ if (platedHole.outer_diameter > 0 && includeCopper) {
26
+ const netId = connMap.getNetConnectedToId(platedHole.pcb_plated_hole_id)
27
+ const outerRadius = platedHole.outer_diameter / 2
28
+ const circle = new Circle(point(centerX, centerY), outerRadius)
29
+ const polygon = circleToPolygon(circle)
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
+ const outer = createCirclePath(centerX, centerY, outerRadius)
37
+ project.children.push(
38
+ new ShapePath({
39
+ cutIndex: copperCutSetting.index,
40
+ verts: outer.verts,
41
+ prims: outer.prims,
42
+ isClosed: true,
43
+ }),
44
+ )
45
+ }
46
+ }
47
+
48
+ // Add soldermask opening if drawing soldermask
49
+ if (platedHole.outer_diameter > 0 && includeSoldermask) {
16
50
  const outerRadius = platedHole.outer_diameter / 2
17
51
  const outer = createCirclePath(centerX, centerY, outerRadius)
18
52
  project.children.push(
@@ -25,7 +59,7 @@ export const addCirclePlatedHole = (
25
59
  )
26
60
  }
27
61
 
28
- // Add inner circle (hole)
62
+ // Add inner circle (hole) - always cut through the board regardless of mode
29
63
  if (platedHole.hole_diameter > 0) {
30
64
  const innerRadius = platedHole.hole_diameter / 2
31
65
  const inner = createCirclePath(centerX, centerY, innerRadius)
@@ -8,7 +8,14 @@ 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
+ throughBoardCutSetting,
15
+ origin,
16
+ includeCopper,
17
+ includeSoldermask,
18
+ } = ctx
12
19
  const centerX = platedHole.x + origin.x
13
20
  const centerY = platedHole.y + origin.y
14
21
  const holeRadius = platedHole.hole_diameter / 2
@@ -25,17 +32,31 @@ export const addCircularHoleWithRectPad = (
25
32
  borderRadius,
26
33
  )
27
34
 
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
- )
35
+ // Add the rectangular pad if drawing copper
36
+ if (includeCopper) {
37
+ project.children.push(
38
+ new ShapePath({
39
+ cutIndex: copperCutSetting.index,
40
+ verts: padPath.verts,
41
+ prims: padPath.prims,
42
+ isClosed: true,
43
+ }),
44
+ )
45
+ }
46
+
47
+ // Add soldermask opening if drawing soldermask
48
+ if (includeSoldermask) {
49
+ project.children.push(
50
+ new ShapePath({
51
+ cutIndex: copperCutSetting.index,
52
+ verts: padPath.verts,
53
+ prims: padPath.prims,
54
+ isClosed: true,
55
+ }),
56
+ )
57
+ }
37
58
 
38
- // Add the circular hole (as a cutout)
59
+ // Add the circular hole (as a cutout) - always cut through the board regardless of mode
39
60
  if (holeRadius > 0) {
40
61
  const holeCenterX = centerX + platedHole.hole_offset_x
41
62
  const holeCenterY = centerY + platedHole.hole_offset_y
@@ -8,7 +8,14 @@ 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
+ throughBoardCutSetting,
15
+ origin,
16
+ includeCopper,
17
+ includeSoldermask,
18
+ } = ctx
12
19
 
13
20
  // Create the polygon pad
14
21
  if (platedHole.pad_outline.length >= 3) {
@@ -18,14 +25,29 @@ export const addHoleWithPolygonPad = (
18
25
  platedHole.y + origin.y,
19
26
  )
20
27
 
21
- project.children.push(
22
- new ShapePath({
23
- cutIndex: copperCutSetting.index,
24
- verts: pad.verts,
25
- prims: pad.prims,
26
- isClosed: true,
27
- }),
28
- )
28
+ // Add the polygon pad if drawing copper
29
+ if (includeCopper) {
30
+ project.children.push(
31
+ new ShapePath({
32
+ cutIndex: copperCutSetting.index,
33
+ verts: pad.verts,
34
+ prims: pad.prims,
35
+ isClosed: true,
36
+ }),
37
+ )
38
+ }
39
+
40
+ // Add soldermask opening if drawing soldermask
41
+ if (includeSoldermask) {
42
+ project.children.push(
43
+ new ShapePath({
44
+ cutIndex: copperCutSetting.index,
45
+ verts: pad.verts,
46
+ prims: pad.prims,
47
+ isClosed: true,
48
+ }),
49
+ )
50
+ }
29
51
  }
30
52
 
31
53
  if (platedHole.hole_shape === "circle" && platedHole.hole_diameter) {
@@ -7,7 +7,14 @@ 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
+ throughBoardCutSetting,
14
+ origin,
15
+ includeCopper,
16
+ includeSoldermask,
17
+ } = ctx
11
18
 
12
19
  if (platedHole.outer_width <= 0 || platedHole.outer_height <= 0) {
13
20
  return
@@ -17,8 +24,12 @@ export const addOvalPlatedHole = (
17
24
  const centerY = platedHole.y + origin.y
18
25
  const rotation = (platedHole.ccw_rotation ?? 0) * (Math.PI / 180)
19
26
 
20
- // Add outer oval (copper)
21
- if (platedHole.outer_width > 0 && platedHole.outer_height > 0) {
27
+ // Add outer oval (copper) if drawing copper
28
+ if (
29
+ platedHole.outer_width > 0 &&
30
+ platedHole.outer_height > 0 &&
31
+ includeCopper
32
+ ) {
22
33
  const outer = createOvalPath(
23
34
  centerX,
24
35
  centerY,
@@ -36,7 +47,30 @@ export const addOvalPlatedHole = (
36
47
  )
37
48
  }
38
49
 
39
- // Add inner oval (hole)
50
+ // Add soldermask opening if drawing soldermask
51
+ if (
52
+ platedHole.outer_width > 0 &&
53
+ platedHole.outer_height > 0 &&
54
+ includeSoldermask
55
+ ) {
56
+ const outer = createOvalPath(
57
+ centerX,
58
+ centerY,
59
+ platedHole.outer_width,
60
+ platedHole.outer_height,
61
+ rotation,
62
+ )
63
+ project.children.push(
64
+ new ShapePath({
65
+ cutIndex: copperCutSetting.index,
66
+ verts: outer.verts,
67
+ prims: outer.prims,
68
+ isClosed: true,
69
+ }),
70
+ )
71
+ }
72
+
73
+ // Add inner oval (hole) - always cut through the board regardless of mode
40
74
  if (platedHole.hole_width > 0 && platedHole.hole_height > 0) {
41
75
  const inner = createOvalPath(
42
76
  centerX,
@@ -8,7 +8,14 @@ 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
+ throughBoardCutSetting,
15
+ origin,
16
+ includeCopper,
17
+ includeSoldermask,
18
+ } = ctx
12
19
  const centerX = platedHole.x + origin.x
13
20
  const centerY = platedHole.y + origin.y
14
21
 
@@ -25,14 +32,29 @@ export const addPillHoleWithRectPad = (
25
32
  borderRadius,
26
33
  )
27
34
 
28
- project.children.push(
29
- new ShapePath({
30
- cutIndex: copperCutSetting.index,
31
- verts: padPath.verts,
32
- prims: padPath.prims,
33
- isClosed: true,
34
- }),
35
- )
35
+ // Add the rectangular pad if drawing copper
36
+ if (includeCopper) {
37
+ project.children.push(
38
+ new ShapePath({
39
+ cutIndex: copperCutSetting.index,
40
+ verts: padPath.verts,
41
+ prims: padPath.prims,
42
+ isClosed: true,
43
+ }),
44
+ )
45
+ }
46
+
47
+ // Add soldermask opening if drawing soldermask
48
+ if (includeSoldermask) {
49
+ project.children.push(
50
+ new ShapePath({
51
+ cutIndex: copperCutSetting.index,
52
+ verts: padPath.verts,
53
+ prims: padPath.prims,
54
+ isClosed: true,
55
+ }),
56
+ )
57
+ }
36
58
  }
37
59
 
38
60
  const holeWidth = platedHole.hole_width
@@ -7,13 +7,24 @@ 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
+ throughBoardCutSetting,
14
+ origin,
15
+ includeCopper,
16
+ includeSoldermask,
17
+ } = ctx
11
18
  const centerX = platedHole.x + origin.x
12
19
  const centerY = platedHole.y + origin.y
13
20
  const rotation = (platedHole.ccw_rotation || 0) * (Math.PI / 180) // Convert degrees to radians
14
21
 
15
- // Add outer pill shape (copper)
16
- if (platedHole.outer_width > 0 && platedHole.outer_height > 0) {
22
+ // Add outer pill shape (copper) if drawing copper
23
+ if (
24
+ platedHole.outer_width > 0 &&
25
+ platedHole.outer_height > 0 &&
26
+ includeCopper
27
+ ) {
17
28
  const outer = createPillPath(
18
29
  centerX,
19
30
  centerY,
@@ -31,7 +42,30 @@ export const addPcbPlatedHolePill = (
31
42
  )
32
43
  }
33
44
 
34
- // Add inner pill shape (hole)
45
+ // Add soldermask opening if drawing soldermask
46
+ if (
47
+ platedHole.outer_width > 0 &&
48
+ platedHole.outer_height > 0 &&
49
+ includeSoldermask
50
+ ) {
51
+ const outer = createPillPath(
52
+ centerX,
53
+ centerY,
54
+ platedHole.outer_width,
55
+ platedHole.outer_height,
56
+ rotation,
57
+ )
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
+ // Add inner pill shape (hole) - always cut through the board regardless of mode
35
69
  if (platedHole.hole_width > 0 && platedHole.hole_height > 0) {
36
70
  const inner = createPillPath(
37
71
  centerX,
@@ -8,7 +8,14 @@ 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
+ throughBoardCutSetting,
15
+ origin,
16
+ includeCopper,
17
+ includeSoldermask,
18
+ } = ctx
12
19
  const centerX = platedHole.x + origin.x
13
20
  const centerY = platedHole.y + origin.y
14
21
 
@@ -28,14 +35,29 @@ export const addRotatedPillHoleWithRectPad = (
28
35
  padRotation,
29
36
  )
30
37
 
31
- project.children.push(
32
- new ShapePath({
33
- cutIndex: copperCutSetting.index,
34
- verts: padPath.verts,
35
- prims: padPath.prims,
36
- isClosed: true,
37
- }),
38
- )
38
+ // Add the rectangular pad if drawing copper
39
+ if (includeCopper) {
40
+ project.children.push(
41
+ new ShapePath({
42
+ cutIndex: copperCutSetting.index,
43
+ verts: padPath.verts,
44
+ prims: padPath.prims,
45
+ isClosed: true,
46
+ }),
47
+ )
48
+ }
49
+
50
+ // Add soldermask opening if drawing soldermask
51
+ if (includeSoldermask) {
52
+ project.children.push(
53
+ new ShapePath({
54
+ cutIndex: copperCutSetting.index,
55
+ verts: padPath.verts,
56
+ prims: padPath.prims,
57
+ isClosed: true,
58
+ }),
59
+ )
60
+ }
39
61
  }
40
62
 
41
63
  const holeWidth = platedHole.hole_width
@@ -2,25 +2,61 @@ 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
+ 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.radius > 0) {
15
24
  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
- )
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 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 (includeSoldermask) {
51
+ const outer = createCirclePath(centerX, centerY, outerRadius)
52
+ project.children.push(
53
+ new ShapePath({
54
+ cutIndex: copperCutSetting.index,
55
+ verts: outer.verts,
56
+ prims: outer.prims,
57
+ isClosed: true,
58
+ }),
59
+ )
60
+ }
25
61
  }
26
62
  }
@@ -2,24 +2,57 @@ 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
+ origin,
15
+ includeCopper,
16
+ includeSoldermask,
17
+ connMap,
18
+ } = ctx
11
19
  const centerX = smtPad.x + origin.x
12
20
  const centerY = smtPad.y + origin.y
13
21
 
14
22
  if (smtPad.width > 0 && smtPad.height > 0) {
15
23
  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
- )
24
+
25
+ // Add to netGeoms for copper (will be merged with traces)
26
+ if (includeCopper) {
27
+ const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id)
28
+ const polygon = pathToPolygon(outer.verts)
29
+
30
+ if (netId) {
31
+ // Add to netGeoms to be merged with other elements on the same net
32
+ ctx.netGeoms.get(netId)?.push(polygon)
33
+ } else {
34
+ // No net connection - draw directly
35
+ project.children.push(
36
+ new ShapePath({
37
+ cutIndex: copperCutSetting.index,
38
+ verts: outer.verts,
39
+ prims: outer.prims,
40
+ isClosed: true,
41
+ }),
42
+ )
43
+ }
44
+ }
45
+
46
+ // Add soldermask opening if drawing soldermask
47
+ if (includeSoldermask) {
48
+ project.children.push(
49
+ new ShapePath({
50
+ cutIndex: copperCutSetting.index,
51
+ verts: outer.verts,
52
+ prims: outer.prims,
53
+ isClosed: true,
54
+ }),
55
+ )
56
+ }
24
57
  }
25
58
  }
@@ -2,24 +2,56 @@ import type { PcbSmtPadPolygon } from "circuit-json"
2
2
  import type { ConvertContext } from "../../ConvertContext"
3
3
  import { ShapePath } from "lbrnts"
4
4
  import { createPolygonPathFromOutline } from "../../helpers/polygonShape"
5
+ import { pathToPolygon } from "../../helpers/pathToPolygon"
5
6
 
6
7
  export const addPolygonSmtPad = (
7
8
  smtPad: PcbSmtPadPolygon,
8
9
  ctx: ConvertContext,
9
10
  ): void => {
10
- const { project, copperCutSetting, origin } = ctx
11
+ const {
12
+ project,
13
+ copperCutSetting,
14
+ origin,
15
+ includeCopper,
16
+ includeSoldermask,
17
+ connMap,
18
+ } = ctx
11
19
 
12
20
  // Create the polygon pad
13
21
  if (smtPad.points.length >= 3) {
14
22
  const pad = createPolygonPathFromOutline(smtPad.points, origin.x, origin.y)
15
23
 
16
- project.children.push(
17
- new ShapePath({
18
- cutIndex: copperCutSetting.index,
19
- verts: pad.verts,
20
- prims: pad.prims,
21
- isClosed: true,
22
- }),
23
- )
24
+ // Add to netGeoms for copper (will be merged with traces)
25
+ if (includeCopper) {
26
+ const netId = connMap.getNetConnectedToId(smtPad.pcb_smtpad_id)
27
+ const polygon = pathToPolygon(pad.verts)
28
+
29
+ if (netId) {
30
+ // Add to netGeoms to be merged with other elements on the same net
31
+ ctx.netGeoms.get(netId)?.push(polygon)
32
+ } else {
33
+ // No net connection - draw directly
34
+ project.children.push(
35
+ new ShapePath({
36
+ cutIndex: copperCutSetting.index,
37
+ verts: pad.verts,
38
+ prims: pad.prims,
39
+ isClosed: true,
40
+ }),
41
+ )
42
+ }
43
+ }
44
+
45
+ // Add soldermask opening if drawing soldermask
46
+ if (includeSoldermask) {
47
+ project.children.push(
48
+ new ShapePath({
49
+ cutIndex: copperCutSetting.index,
50
+ verts: pad.verts,
51
+ prims: pad.prims,
52
+ isClosed: true,
53
+ }),
54
+ )
55
+ }
24
56
  }
25
57
  }