@tscircuit/copper-pour-solver 0.0.13 → 0.0.15
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/dist/index.js +12 -70
- package/lib/circuit-json/convert-circuit-json-to-input-problem.ts +18 -89
- package/package.json +3 -2
- package/tests/repro01-business-via-card/__snapshots__/repro01-business-via-card.snap.svg +1 -0
- package/tests/repro01-business-via-card/repro01-business-via-card.json +10307 -0
- package/tests/repro01-business-via-card/repro01-business-via-card.test.ts +18 -0
- package/tests/utils/run-solver-and-render-to-svg.ts +14 -3
package/dist/index.js
CHANGED
|
@@ -339,75 +339,20 @@ var CopperPourPipelineSolver = class extends BasePipelineSolver {
|
|
|
339
339
|
};
|
|
340
340
|
|
|
341
341
|
// lib/circuit-json/convert-circuit-json-to-input-problem.ts
|
|
342
|
+
import { getFullConnectivityMapFromCircuitJson } from "circuit-json-to-connectivity-map";
|
|
342
343
|
var convertCircuitJsonToInputProblem = (circuitJson, options) => {
|
|
343
|
-
const source_ports = circuitJson.filter(
|
|
344
|
-
(e) => e.type === "source_port"
|
|
345
|
-
);
|
|
346
|
-
const pcb_ports = circuitJson.filter(
|
|
347
|
-
(e) => e.type === "pcb_port"
|
|
348
|
-
);
|
|
349
|
-
const source_traces = circuitJson.filter(
|
|
350
|
-
(e) => e.type === "source_trace"
|
|
351
|
-
);
|
|
352
|
-
const pcb_traces = circuitJson.filter(
|
|
353
|
-
(e) => e.type === "pcb_trace"
|
|
354
|
-
);
|
|
355
|
-
const source_nets = circuitJson.filter(
|
|
356
|
-
(e) => e.type === "source_net"
|
|
357
|
-
);
|
|
358
344
|
const pcb_board = circuitJson.find((e) => e.type === "pcb_board");
|
|
359
345
|
if (!pcb_board) throw new Error("No pcb_board found in circuit json");
|
|
360
|
-
const
|
|
361
|
-
source_ports.map((sp) => [
|
|
362
|
-
sp.source_port_id,
|
|
363
|
-
sp.subcircuit_connectivity_map_key
|
|
364
|
-
])
|
|
365
|
-
);
|
|
366
|
-
const pcbPortIdToConnectivityKey = Object.fromEntries(
|
|
367
|
-
pcb_ports.map((pp) => [
|
|
368
|
-
pp.pcb_port_id,
|
|
369
|
-
sourcePortIdToConnectivityKey[pp.source_port_id]
|
|
370
|
-
])
|
|
371
|
-
);
|
|
372
|
-
const pcbPlatedHoleIdToConnectivityKey = {};
|
|
373
|
-
for (const pcb_port of pcb_ports) {
|
|
374
|
-
if (pcb_port.pcb_port_id) {
|
|
375
|
-
pcbPlatedHoleIdToConnectivityKey[pcb_port.pcb_port_id] = pcbPortIdToConnectivityKey[pcb_port.pcb_port_id];
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
const sourceTraceIdToConnectivityKey = Object.fromEntries(
|
|
379
|
-
source_traces.map((st) => [
|
|
380
|
-
st.source_trace_id,
|
|
381
|
-
st.subcircuit_connectivity_map_key
|
|
382
|
-
])
|
|
383
|
-
);
|
|
384
|
-
const sourceNetIdToConnectivityKey = Object.fromEntries(
|
|
385
|
-
source_nets.map((sn) => [
|
|
386
|
-
sn.source_net_id,
|
|
387
|
-
sn.subcircuit_connectivity_map_key
|
|
388
|
-
])
|
|
389
|
-
);
|
|
390
|
-
const idToConnectivityKey = {
|
|
391
|
-
...sourceTraceIdToConnectivityKey,
|
|
392
|
-
...sourceNetIdToConnectivityKey
|
|
393
|
-
};
|
|
394
|
-
const pcbTraceIdToConnectivityKey = Object.fromEntries(
|
|
395
|
-
pcb_traces.map(
|
|
396
|
-
(trace) => [
|
|
397
|
-
trace.pcb_trace_id,
|
|
398
|
-
trace.source_trace_id ? idToConnectivityKey[trace.source_trace_id] : void 0
|
|
399
|
-
]
|
|
400
|
-
).filter((entry) => Boolean(entry[1]))
|
|
401
|
-
);
|
|
346
|
+
const connectivityMap = getFullConnectivityMapFromCircuitJson(circuitJson);
|
|
402
347
|
const pads = [];
|
|
403
348
|
for (const elm of circuitJson) {
|
|
404
349
|
if (elm.type === "pcb_smtpad") {
|
|
405
350
|
const smtpad = elm;
|
|
406
351
|
if (smtpad.layer !== options.layer) continue;
|
|
407
352
|
let connectivityKey;
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
353
|
+
connectivityKey = connectivityMap.getNetConnectedToId(
|
|
354
|
+
smtpad.pcb_smtpad_id
|
|
355
|
+
);
|
|
411
356
|
if (!connectivityKey) {
|
|
412
357
|
connectivityKey = `unconnected:${smtpad.pcb_smtpad_id}`;
|
|
413
358
|
}
|
|
@@ -439,7 +384,9 @@ var convertCircuitJsonToInputProblem = (circuitJson, options) => {
|
|
|
439
384
|
const platedHole = elm;
|
|
440
385
|
if (platedHole.shape !== "circle") continue;
|
|
441
386
|
if (!platedHole.layers.includes(options.layer)) continue;
|
|
442
|
-
let connectivityKey =
|
|
387
|
+
let connectivityKey = connectivityMap.getNetConnectedToId(
|
|
388
|
+
platedHole.pcb_plated_hole_id
|
|
389
|
+
);
|
|
443
390
|
if (!connectivityKey) {
|
|
444
391
|
connectivityKey = `unconnected-plated-hole:${platedHole.pcb_plated_hole_id}`;
|
|
445
392
|
}
|
|
@@ -505,13 +452,7 @@ var convertCircuitJsonToInputProblem = (circuitJson, options) => {
|
|
|
505
452
|
} else if (elm.type === "pcb_via") {
|
|
506
453
|
const via = elm;
|
|
507
454
|
if (!via.layers.includes(options.layer)) continue;
|
|
508
|
-
|
|
509
|
-
if (via.pcb_trace_id) {
|
|
510
|
-
connectivityKey = pcbTraceIdToConnectivityKey[via.pcb_trace_id];
|
|
511
|
-
}
|
|
512
|
-
if (!connectivityKey) {
|
|
513
|
-
connectivityKey = `unconnected-via:${via.pcb_via_id}`;
|
|
514
|
-
}
|
|
455
|
+
const connectivityKey = connectivityMap.getNetConnectedToId(via.pcb_via_id) ?? `unconnected-via:${via.pcb_via_id}`;
|
|
515
456
|
pads.push({
|
|
516
457
|
shape: "circle",
|
|
517
458
|
padId: via.pcb_via_id,
|
|
@@ -523,8 +464,9 @@ var convertCircuitJsonToInputProblem = (circuitJson, options) => {
|
|
|
523
464
|
});
|
|
524
465
|
} else if (elm.type === "pcb_trace") {
|
|
525
466
|
const trace = elm;
|
|
526
|
-
|
|
527
|
-
|
|
467
|
+
const connectivityKey = connectivityMap.getNetConnectedToId(
|
|
468
|
+
trace.pcb_trace_id
|
|
469
|
+
);
|
|
528
470
|
if (!connectivityKey) continue;
|
|
529
471
|
let currentSegmentGroup = [];
|
|
530
472
|
let currentWidth = null;
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
SourcePort,
|
|
14
14
|
SourceTrace,
|
|
15
15
|
} from "circuit-json"
|
|
16
|
+
import { getFullConnectivityMapFromCircuitJson } from "circuit-json-to-connectivity-map"
|
|
16
17
|
import type {
|
|
17
18
|
InputCircularPad,
|
|
18
19
|
InputPad,
|
|
@@ -33,81 +34,13 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
33
34
|
cutout_margin?: number
|
|
34
35
|
},
|
|
35
36
|
): InputProblem => {
|
|
36
|
-
const source_ports = circuitJson.filter(
|
|
37
|
-
(e) => e.type === "source_port",
|
|
38
|
-
) as SourcePort[]
|
|
39
|
-
const pcb_ports = circuitJson.filter(
|
|
40
|
-
(e) => e.type === "pcb_port",
|
|
41
|
-
) as PcbPort[]
|
|
42
|
-
const source_traces = circuitJson.filter(
|
|
43
|
-
(e) => e.type === "source_trace",
|
|
44
|
-
) as SourceTrace[]
|
|
45
|
-
const pcb_traces = circuitJson.filter(
|
|
46
|
-
(e) => e.type === "pcb_trace",
|
|
47
|
-
) as PcbTrace[]
|
|
48
|
-
const source_nets = circuitJson.filter(
|
|
49
|
-
(e) => e.type === "source_net",
|
|
50
|
-
) as SourceNet[]
|
|
51
37
|
const pcb_board = circuitJson.find((e) => e.type === "pcb_board") as
|
|
52
38
|
| PcbBoard
|
|
53
39
|
| undefined
|
|
54
40
|
|
|
55
41
|
if (!pcb_board) throw new Error("No pcb_board found in circuit json")
|
|
56
42
|
|
|
57
|
-
const
|
|
58
|
-
source_ports.map((sp) => [
|
|
59
|
-
sp.source_port_id,
|
|
60
|
-
sp.subcircuit_connectivity_map_key,
|
|
61
|
-
]),
|
|
62
|
-
)
|
|
63
|
-
const pcbPortIdToConnectivityKey: Record<string, string | undefined> =
|
|
64
|
-
Object.fromEntries(
|
|
65
|
-
pcb_ports.map((pp) => [
|
|
66
|
-
pp.pcb_port_id,
|
|
67
|
-
sourcePortIdToConnectivityKey[pp.source_port_id],
|
|
68
|
-
]),
|
|
69
|
-
)
|
|
70
|
-
const pcbPlatedHoleIdToConnectivityKey: Record<string, string | undefined> =
|
|
71
|
-
{}
|
|
72
|
-
for (const pcb_port of pcb_ports) {
|
|
73
|
-
if (pcb_port.pcb_port_id) {
|
|
74
|
-
pcbPlatedHoleIdToConnectivityKey[pcb_port.pcb_port_id] =
|
|
75
|
-
pcbPortIdToConnectivityKey[pcb_port.pcb_port_id]
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const sourceTraceIdToConnectivityKey = Object.fromEntries(
|
|
80
|
-
source_traces.map((st) => [
|
|
81
|
-
st.source_trace_id,
|
|
82
|
-
st.subcircuit_connectivity_map_key,
|
|
83
|
-
]),
|
|
84
|
-
)
|
|
85
|
-
const sourceNetIdToConnectivityKey = Object.fromEntries(
|
|
86
|
-
source_nets.map((sn) => [
|
|
87
|
-
sn.source_net_id,
|
|
88
|
-
sn.subcircuit_connectivity_map_key,
|
|
89
|
-
]),
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
const idToConnectivityKey = {
|
|
93
|
-
...sourceTraceIdToConnectivityKey,
|
|
94
|
-
...sourceNetIdToConnectivityKey,
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const pcbTraceIdToConnectivityKey: Record<string, string> =
|
|
98
|
-
Object.fromEntries(
|
|
99
|
-
pcb_traces
|
|
100
|
-
.map(
|
|
101
|
-
(trace) =>
|
|
102
|
-
[
|
|
103
|
-
trace.pcb_trace_id,
|
|
104
|
-
trace.source_trace_id
|
|
105
|
-
? idToConnectivityKey[trace.source_trace_id]
|
|
106
|
-
: undefined,
|
|
107
|
-
] as const,
|
|
108
|
-
)
|
|
109
|
-
.filter((entry): entry is [string, string] => Boolean(entry[1])),
|
|
110
|
-
)
|
|
43
|
+
const connectivityMap = getFullConnectivityMapFromCircuitJson(circuitJson)
|
|
111
44
|
|
|
112
45
|
const pads: InputPad[] = []
|
|
113
46
|
|
|
@@ -117,9 +50,9 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
117
50
|
if (smtpad.layer !== options.layer) continue
|
|
118
51
|
|
|
119
52
|
let connectivityKey: string | undefined
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
53
|
+
connectivityKey = connectivityMap.getNetConnectedToId(
|
|
54
|
+
smtpad.pcb_smtpad_id,
|
|
55
|
+
)
|
|
123
56
|
if (!connectivityKey) {
|
|
124
57
|
connectivityKey = `unconnected:${smtpad.pcb_smtpad_id}`
|
|
125
58
|
}
|
|
@@ -153,9 +86,9 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
153
86
|
if (platedHole.shape !== "circle") continue
|
|
154
87
|
if (!platedHole.layers.includes(options.layer)) continue
|
|
155
88
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
89
|
+
let connectivityKey = connectivityMap.getNetConnectedToId(
|
|
90
|
+
platedHole.pcb_plated_hole_id,
|
|
91
|
+
)
|
|
159
92
|
if (!connectivityKey) {
|
|
160
93
|
connectivityKey = `unconnected-plated-hole:${platedHole.pcb_plated_hole_id}`
|
|
161
94
|
}
|
|
@@ -220,14 +153,9 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
220
153
|
const via = elm as PcbVia
|
|
221
154
|
if (!via.layers.includes(options.layer)) continue
|
|
222
155
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if (!connectivityKey) {
|
|
229
|
-
connectivityKey = `unconnected-via:${via.pcb_via_id}`
|
|
230
|
-
}
|
|
156
|
+
const connectivityKey: string =
|
|
157
|
+
connectivityMap.getNetConnectedToId(via.pcb_via_id) ??
|
|
158
|
+
`unconnected-via:${via.pcb_via_id}`
|
|
231
159
|
|
|
232
160
|
pads.push({
|
|
233
161
|
shape: "circle",
|
|
@@ -240,8 +168,9 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
240
168
|
} as InputCircularPad)
|
|
241
169
|
} else if (elm.type === "pcb_trace") {
|
|
242
170
|
const trace = elm as PcbTrace
|
|
243
|
-
|
|
244
|
-
|
|
171
|
+
const connectivityKey = connectivityMap.getNetConnectedToId(
|
|
172
|
+
trace.pcb_trace_id,
|
|
173
|
+
)
|
|
245
174
|
if (!connectivityKey) continue
|
|
246
175
|
|
|
247
176
|
let currentSegmentGroup: Point[] = []
|
|
@@ -283,10 +212,10 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
283
212
|
shape: "rect" as const,
|
|
284
213
|
layer: options.layer,
|
|
285
214
|
bounds: {
|
|
286
|
-
minX: -width / 2,
|
|
287
|
-
minY: -height / 2,
|
|
288
|
-
maxX: width / 2,
|
|
289
|
-
maxY: height / 2,
|
|
215
|
+
minX: -width! / 2,
|
|
216
|
+
minY: -height! / 2,
|
|
217
|
+
maxX: width! / 2,
|
|
218
|
+
maxY: height! / 2,
|
|
290
219
|
},
|
|
291
220
|
outline: pcb_board.outline,
|
|
292
221
|
connectivityKey: options.pour_connectivity_key,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/copper-pour-solver",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.15",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"format": "biome format . --write",
|
|
7
7
|
"format:check": "biome format .",
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"@flatten-js/core": "^1.6.2",
|
|
14
14
|
"@tscircuit/math-utils": "^0.0.25",
|
|
15
15
|
"@tscircuit/solver-utils": "^0.0.3",
|
|
16
|
+
"circuit-json-to-connectivity-map": "^0.0.23",
|
|
16
17
|
"@types/bun": "latest",
|
|
17
18
|
"bun-match-svg": "^0.0.13",
|
|
18
|
-
"circuit-json": "^0.0.
|
|
19
|
+
"circuit-json": "^0.0.306",
|
|
19
20
|
"circuit-to-svg": "^0.0.262",
|
|
20
21
|
"react-cosmos": "^7.0.0",
|
|
21
22
|
"react-cosmos-plugin-vite": "^7.0.0",
|