@tscircuit/schematic-trace-solver 0.0.171 → 0.0.172
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 +49 -13
- package/lib/solvers/NetLabelToTraceSolver/NetLabelToTraceSolver.ts +68 -14
- package/package.json +1 -1
- package/tests/repros/__snapshots__/repro-battery-management-bq24073.snap.svg +191 -0
- package/tests/repros/__snapshots__/repro-powerbank-3v-system-power.snap.svg +11 -29
- package/tests/repros/__snapshots__/repro-tida-01389-hbridge.snap.svg +216 -0
- package/tests/repros/__snapshots__/repro-tmp1075-ground-label-overlap.snap.svg +166 -0
- package/tests/repros/assets/repro-battery-management-bq24073.input.json +721 -0
- package/tests/repros/assets/repro-tida-01389-hbridge.input.json +780 -0
- package/tests/repros/assets/repro-tmp1075-ground-label-overlap.input.json +305 -0
- package/tests/repros/repro-battery-management-bq24073.test.ts +62 -0
- package/tests/repros/repro-tida-01389-hbridge.test.ts +23 -0
- package/tests/repros/repro-tmp1075-ground-label-overlap.test.ts +18 -0
package/dist/index.js
CHANGED
|
@@ -15625,24 +15625,42 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
15625
15625
|
}
|
|
15626
15626
|
}
|
|
15627
15627
|
}
|
|
15628
|
-
candidates.push(
|
|
15628
|
+
candidates.push(
|
|
15629
|
+
...this.buildRoutedComponentCandidates(groundGlobalConnNetIds)
|
|
15630
|
+
);
|
|
15629
15631
|
candidates.sort(
|
|
15630
15632
|
(first, second) => first.perpendicularOffset - second.perpendicularOffset || first.routeDistance - second.routeDistance || first.key.localeCompare(second.key)
|
|
15631
15633
|
);
|
|
15632
15634
|
return candidates;
|
|
15633
15635
|
}
|
|
15634
|
-
buildRoutedComponentCandidates() {
|
|
15636
|
+
buildRoutedComponentCandidates(groundGlobalConnNetIds) {
|
|
15635
15637
|
const { netConnMap } = getConnectivityMapsFromInputProblem(
|
|
15636
15638
|
this.inputProblem
|
|
15637
15639
|
);
|
|
15638
15640
|
const candidates = [];
|
|
15639
|
-
|
|
15640
|
-
|
|
15641
|
+
const directConnections = new Set(
|
|
15642
|
+
this.inputProblem.directConnections
|
|
15643
|
+
);
|
|
15644
|
+
for (const connection of [
|
|
15645
|
+
...this.inputProblem.netConnections.filter(
|
|
15646
|
+
(connection2) => connection2.pinIds.length > 2 && connection2.isGround === false
|
|
15647
|
+
),
|
|
15648
|
+
...this.inputProblem.directConnections
|
|
15649
|
+
]) {
|
|
15650
|
+
const isDirectConnection = directConnections.has(connection);
|
|
15651
|
+
const globalConnNetId = netConnMap.getNetConnectedToId(
|
|
15652
|
+
connection.pinIds[0]
|
|
15653
|
+
);
|
|
15654
|
+
if (!globalConnNetId || isDirectConnection && groundGlobalConnNetIds.has(globalConnNetId))
|
|
15641
15655
|
continue;
|
|
15642
|
-
|
|
15643
|
-
if (
|
|
15656
|
+
let connectionPinIds = connection.pinIds;
|
|
15657
|
+
if (isDirectConnection) {
|
|
15658
|
+
connectionPinIds = [...this.pinMap.keys()].filter(
|
|
15659
|
+
(pinId) => netConnMap.getNetConnectedToId(pinId) === globalConnNetId
|
|
15660
|
+
);
|
|
15661
|
+
}
|
|
15644
15662
|
const traceConnectedPinComponents = getTraceConnectedPinComponents({
|
|
15645
|
-
pinIds:
|
|
15663
|
+
pinIds: connectionPinIds,
|
|
15646
15664
|
traces: this.outputTraces.filter(
|
|
15647
15665
|
(trace) => trace.globalConnNetId === globalConnNetId
|
|
15648
15666
|
)
|
|
@@ -15651,6 +15669,8 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
15651
15669
|
for (let secondIndex = firstIndex + 1; secondIndex < traceConnectedPinComponents.length; secondIndex++) {
|
|
15652
15670
|
const firstComponent = traceConnectedPinComponents[firstIndex];
|
|
15653
15671
|
const secondComponent = traceConnectedPinComponents[secondIndex];
|
|
15672
|
+
if (isDirectConnection && !(firstComponent.pinIds.includes(connection.pinIds[0]) && secondComponent.pinIds.includes(connection.pinIds[1]) || firstComponent.pinIds.includes(connection.pinIds[1]) && secondComponent.pinIds.includes(connection.pinIds[0])))
|
|
15673
|
+
continue;
|
|
15654
15674
|
const firstLabel = this.input.netLabelPlacements.find(
|
|
15655
15675
|
(label) => label.globalConnNetId === globalConnNetId && label.mspConnectionPairIds.length > 0 && label.pinIds.some(
|
|
15656
15676
|
(pinId) => firstComponent.pinIds.includes(pinId)
|
|
@@ -15670,11 +15690,23 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
15670
15690
|
continue;
|
|
15671
15691
|
}
|
|
15672
15692
|
let bestCandidate;
|
|
15673
|
-
|
|
15674
|
-
|
|
15693
|
+
let firstPinIds = firstComponent.pinIds;
|
|
15694
|
+
let secondPinIds = secondComponent.pinIds;
|
|
15695
|
+
if (isDirectConnection) {
|
|
15696
|
+
firstPinIds = connection.pinIds.filter(
|
|
15697
|
+
(pinId) => firstComponent.pinIds.includes(pinId)
|
|
15698
|
+
);
|
|
15699
|
+
secondPinIds = connection.pinIds.filter(
|
|
15700
|
+
(pinId) => secondComponent.pinIds.includes(pinId)
|
|
15701
|
+
);
|
|
15702
|
+
}
|
|
15703
|
+
for (const firstPinId of firstPinIds) {
|
|
15704
|
+
for (const secondPinId of secondPinIds) {
|
|
15675
15705
|
const firstPin = this.pinMap.get(firstPinId);
|
|
15676
15706
|
const secondPin = this.pinMap.get(secondPinId);
|
|
15677
15707
|
if (!firstPin || !secondPin) continue;
|
|
15708
|
+
if (isDirectConnection && firstPin.chipId === secondPin.chipId)
|
|
15709
|
+
continue;
|
|
15678
15710
|
const perpendicularOffset = getPerpendicularOffset(
|
|
15679
15711
|
firstPin,
|
|
15680
15712
|
secondPin
|
|
@@ -15693,6 +15725,10 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
15693
15725
|
continue;
|
|
15694
15726
|
}
|
|
15695
15727
|
const routeDistance = Math.abs(firstPin.x - secondPin.x) + Math.abs(firstPin.y - secondPin.y);
|
|
15728
|
+
let recoveryMode = "routed_components";
|
|
15729
|
+
if (isDirectConnection) {
|
|
15730
|
+
recoveryMode = "routed_direct_connection";
|
|
15731
|
+
}
|
|
15696
15732
|
const candidate = {
|
|
15697
15733
|
firstLabel,
|
|
15698
15734
|
secondLabel,
|
|
@@ -15700,8 +15736,8 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
15700
15736
|
perpendicularOffset,
|
|
15701
15737
|
routeDistance,
|
|
15702
15738
|
key: getCanonicalPairKey(firstPin.pinId, secondPin.pinId),
|
|
15703
|
-
recoveryMode
|
|
15704
|
-
netConnectionPinIds:
|
|
15739
|
+
recoveryMode,
|
|
15740
|
+
netConnectionPinIds: connectionPinIds
|
|
15705
15741
|
};
|
|
15706
15742
|
if (!bestCandidate || candidate.routeDistance < bestCandidate.routeDistance || candidate.routeDistance === bestCandidate.routeDistance && (candidate.perpendicularOffset < bestCandidate.perpendicularOffset || candidate.perpendicularOffset === bestCandidate.perpendicularOffset && candidate.key.localeCompare(bestCandidate.key) < 0)) {
|
|
15707
15743
|
bestCandidate = candidate;
|
|
@@ -15740,7 +15776,7 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
15740
15776
|
(trace) => !this.isSupersededConnectorTrace(trace, candidate)
|
|
15741
15777
|
);
|
|
15742
15778
|
let collisionTraces = retainedTraces;
|
|
15743
|
-
if (candidate.recoveryMode
|
|
15779
|
+
if (candidate.recoveryMode !== "fallback_labels") {
|
|
15744
15780
|
collisionTraces = retainedTraces.filter(
|
|
15745
15781
|
(trace) => trace.globalConnNetId !== candidate.firstLabel.globalConnNetId
|
|
15746
15782
|
);
|
|
@@ -15766,7 +15802,7 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
15766
15802
|
pinIds: [firstPin.pinId, secondPin.pinId]
|
|
15767
15803
|
};
|
|
15768
15804
|
this.outputTraces = [...retainedTraces, recoveredTrace];
|
|
15769
|
-
if (candidate.recoveryMode
|
|
15805
|
+
if (candidate.recoveryMode !== "routed_components") {
|
|
15770
15806
|
this.outputNetLabelPlacements = this.outputNetLabelPlacements.filter(
|
|
15771
15807
|
(label) => label !== candidate.firstLabel && label !== candidate.secondLabel
|
|
15772
15808
|
);
|
|
@@ -40,7 +40,10 @@ interface CandidatePair {
|
|
|
40
40
|
perpendicularOffset: number
|
|
41
41
|
routeDistance: number
|
|
42
42
|
key: string
|
|
43
|
-
recoveryMode:
|
|
43
|
+
recoveryMode:
|
|
44
|
+
| "fallback_labels"
|
|
45
|
+
| "routed_components"
|
|
46
|
+
| "routed_direct_connection"
|
|
44
47
|
netConnectionPinIds?: PinId[]
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -260,7 +263,9 @@ export class NetLabelToTraceSolver extends BaseSolver {
|
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
265
|
|
|
263
|
-
candidates.push(
|
|
266
|
+
candidates.push(
|
|
267
|
+
...this.buildRoutedComponentCandidates(groundGlobalConnNetIds),
|
|
268
|
+
)
|
|
264
269
|
|
|
265
270
|
candidates.sort(
|
|
266
271
|
(first, second) =>
|
|
@@ -271,20 +276,42 @@ export class NetLabelToTraceSolver extends BaseSolver {
|
|
|
271
276
|
return candidates
|
|
272
277
|
}
|
|
273
278
|
|
|
274
|
-
private buildRoutedComponentCandidates(
|
|
279
|
+
private buildRoutedComponentCandidates(
|
|
280
|
+
groundGlobalConnNetIds: Set<GlobalConnNetId>,
|
|
281
|
+
) {
|
|
275
282
|
const { netConnMap } = getConnectivityMapsFromInputProblem(
|
|
276
283
|
this.inputProblem,
|
|
277
284
|
)
|
|
278
285
|
const candidates: CandidatePair[] = []
|
|
286
|
+
const directConnections = new Set<object>(
|
|
287
|
+
this.inputProblem.directConnections,
|
|
288
|
+
)
|
|
279
289
|
|
|
280
|
-
for (const connection of
|
|
281
|
-
|
|
290
|
+
for (const connection of [
|
|
291
|
+
...this.inputProblem.netConnections.filter(
|
|
292
|
+
(connection) =>
|
|
293
|
+
connection.pinIds.length > 2 && connection.isGround === false,
|
|
294
|
+
),
|
|
295
|
+
...this.inputProblem.directConnections,
|
|
296
|
+
]) {
|
|
297
|
+
const isDirectConnection = directConnections.has(connection)
|
|
298
|
+
const globalConnNetId = netConnMap.getNetConnectedToId(
|
|
299
|
+
connection.pinIds[0],
|
|
300
|
+
)
|
|
301
|
+
if (
|
|
302
|
+
!globalConnNetId ||
|
|
303
|
+
(isDirectConnection && groundGlobalConnNetIds.has(globalConnNetId))
|
|
304
|
+
)
|
|
282
305
|
continue
|
|
283
|
-
|
|
284
|
-
if (
|
|
306
|
+
let connectionPinIds: PinId[] = connection.pinIds
|
|
307
|
+
if (isDirectConnection) {
|
|
308
|
+
connectionPinIds = [...this.pinMap.keys()].filter(
|
|
309
|
+
(pinId) => netConnMap.getNetConnectedToId(pinId) === globalConnNetId,
|
|
310
|
+
)
|
|
311
|
+
}
|
|
285
312
|
|
|
286
313
|
const traceConnectedPinComponents = getTraceConnectedPinComponents({
|
|
287
|
-
pinIds:
|
|
314
|
+
pinIds: connectionPinIds,
|
|
288
315
|
traces: this.outputTraces.filter(
|
|
289
316
|
(trace) => trace.globalConnNetId === globalConnNetId,
|
|
290
317
|
),
|
|
@@ -302,6 +329,16 @@ export class NetLabelToTraceSolver extends BaseSolver {
|
|
|
302
329
|
) {
|
|
303
330
|
const firstComponent = traceConnectedPinComponents[firstIndex]!
|
|
304
331
|
const secondComponent = traceConnectedPinComponents[secondIndex]!
|
|
332
|
+
if (
|
|
333
|
+
isDirectConnection &&
|
|
334
|
+
!(
|
|
335
|
+
(firstComponent.pinIds.includes(connection.pinIds[0]) &&
|
|
336
|
+
secondComponent.pinIds.includes(connection.pinIds[1])) ||
|
|
337
|
+
(firstComponent.pinIds.includes(connection.pinIds[1]) &&
|
|
338
|
+
secondComponent.pinIds.includes(connection.pinIds[0]))
|
|
339
|
+
)
|
|
340
|
+
)
|
|
341
|
+
continue
|
|
305
342
|
const firstLabel = this.input.netLabelPlacements.find(
|
|
306
343
|
(label) =>
|
|
307
344
|
label.globalConnNetId === globalConnNetId &&
|
|
@@ -330,11 +367,23 @@ export class NetLabelToTraceSolver extends BaseSolver {
|
|
|
330
367
|
}
|
|
331
368
|
|
|
332
369
|
let bestCandidate: CandidatePair | undefined
|
|
333
|
-
|
|
334
|
-
|
|
370
|
+
let firstPinIds = firstComponent.pinIds
|
|
371
|
+
let secondPinIds = secondComponent.pinIds
|
|
372
|
+
if (isDirectConnection) {
|
|
373
|
+
firstPinIds = connection.pinIds.filter((pinId) =>
|
|
374
|
+
firstComponent.pinIds.includes(pinId),
|
|
375
|
+
)
|
|
376
|
+
secondPinIds = connection.pinIds.filter((pinId) =>
|
|
377
|
+
secondComponent.pinIds.includes(pinId),
|
|
378
|
+
)
|
|
379
|
+
}
|
|
380
|
+
for (const firstPinId of firstPinIds) {
|
|
381
|
+
for (const secondPinId of secondPinIds) {
|
|
335
382
|
const firstPin = this.pinMap.get(firstPinId)
|
|
336
383
|
const secondPin = this.pinMap.get(secondPinId)
|
|
337
384
|
if (!firstPin || !secondPin) continue
|
|
385
|
+
if (isDirectConnection && firstPin.chipId === secondPin.chipId)
|
|
386
|
+
continue
|
|
338
387
|
const perpendicularOffset = getPerpendicularOffset(
|
|
339
388
|
firstPin,
|
|
340
389
|
secondPin,
|
|
@@ -362,6 +411,11 @@ export class NetLabelToTraceSolver extends BaseSolver {
|
|
|
362
411
|
const routeDistance =
|
|
363
412
|
Math.abs(firstPin.x - secondPin.x) +
|
|
364
413
|
Math.abs(firstPin.y - secondPin.y)
|
|
414
|
+
let recoveryMode: CandidatePair["recoveryMode"] =
|
|
415
|
+
"routed_components"
|
|
416
|
+
if (isDirectConnection) {
|
|
417
|
+
recoveryMode = "routed_direct_connection"
|
|
418
|
+
}
|
|
365
419
|
const candidate: CandidatePair = {
|
|
366
420
|
firstLabel,
|
|
367
421
|
secondLabel,
|
|
@@ -369,8 +423,8 @@ export class NetLabelToTraceSolver extends BaseSolver {
|
|
|
369
423
|
perpendicularOffset,
|
|
370
424
|
routeDistance,
|
|
371
425
|
key: getCanonicalPairKey(firstPin.pinId, secondPin.pinId),
|
|
372
|
-
recoveryMode
|
|
373
|
-
netConnectionPinIds:
|
|
426
|
+
recoveryMode,
|
|
427
|
+
netConnectionPinIds: connectionPinIds,
|
|
374
428
|
}
|
|
375
429
|
if (
|
|
376
430
|
!bestCandidate ||
|
|
@@ -429,7 +483,7 @@ export class NetLabelToTraceSolver extends BaseSolver {
|
|
|
429
483
|
(trace) => !this.isSupersededConnectorTrace(trace, candidate),
|
|
430
484
|
)
|
|
431
485
|
let collisionTraces = retainedTraces
|
|
432
|
-
if (candidate.recoveryMode
|
|
486
|
+
if (candidate.recoveryMode !== "fallback_labels") {
|
|
433
487
|
collisionTraces = retainedTraces.filter(
|
|
434
488
|
(trace) =>
|
|
435
489
|
trace.globalConnNetId !== candidate.firstLabel.globalConnNetId,
|
|
@@ -466,7 +520,7 @@ export class NetLabelToTraceSolver extends BaseSolver {
|
|
|
466
520
|
}
|
|
467
521
|
|
|
468
522
|
this.outputTraces = [...retainedTraces, recoveredTrace]
|
|
469
|
-
if (candidate.recoveryMode
|
|
523
|
+
if (candidate.recoveryMode !== "routed_components") {
|
|
470
524
|
this.outputNetLabelPlacements = this.outputNetLabelPlacements.filter(
|
|
471
525
|
(label) =>
|
|
472
526
|
label !== candidate.firstLabel && label !== candidate.secondLabel,
|