@tscircuit/schematic-trace-solver 0.0.145 → 0.0.147
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.d.ts +9 -2
- package/dist/index.js +482 -86
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +38 -30
- package/lib/solvers/InlineNetLabelSolver/InlineNetLabelSolver.ts +30 -8
- package/lib/solvers/InlineNetLabelSolver/pushAnchoredNetLabelsAwayFromInlineLabels.ts +530 -0
- package/lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver.ts +6 -21
- package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/SchematicTraceSingleLineSolver2.ts +7 -23
- package/lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts +7 -14
- package/lib/types/InputProblem.ts +8 -0
- package/lib/utils/getNetLabelWidthForConnection.ts +63 -0
- package/package.json +1 -1
- package/tests/assets/inline-net-label-anchored-label-clearance.json +56 -0
- package/tests/repros/__snapshots__/repro-ti-power-output-section.snap.svg +80 -0
- package/tests/repros/repro-ti-power-output-section.input.ts +341 -0
- package/tests/repros/repro-ti-power-output-section.test.ts +13 -0
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/fallback-net-label-width.snap.svg +69 -0
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label-anchored-label-clearance.snap.svg +54 -0
- package/tests/solvers/InlineNetLabelSolver/fallback-net-label-width.test.ts +152 -0
- package/tests/solvers/InlineNetLabelSolver/inline-net-label-anchored-label-clearance.test.ts +28 -0
- package/tests/solvers/InlineNetLabelSolver/push-anchored-net-labels-away.test.ts +227 -0
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
InputProblem,
|
|
17
17
|
} from "lib/types/InputProblem"
|
|
18
18
|
import { dir, type FacingDirection } from "lib/utils/dir"
|
|
19
|
+
import { getNetLabelWidthForConnection } from "lib/utils/getNetLabelWidthForConnection"
|
|
19
20
|
import { rectIntersectsAnyTextBox } from "lib/utils/textBoxBounds"
|
|
20
21
|
import {
|
|
21
22
|
EPS,
|
|
@@ -180,13 +181,23 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
180
181
|
const bY = this.outputNetLabelPlacements[b]!.anchorPoint.y
|
|
181
182
|
return requiredOrientation === "y+" ? bY - aY : aY - bY
|
|
182
183
|
})
|
|
183
|
-
const blockedLabelWidth =
|
|
184
|
+
const blockedLabelWidth = getNetLabelWidthForConnection({
|
|
185
|
+
inputProblem: this.inputProblem,
|
|
186
|
+
netId: blockedLabel.netId,
|
|
187
|
+
pinIds: blockedLabel.pinIds,
|
|
188
|
+
})
|
|
184
189
|
let columnLabelIndex: number | undefined
|
|
185
190
|
if (blockedLabelWidth !== undefined) {
|
|
186
191
|
columnLabelIndex = labelsToOrder.find((index) => {
|
|
187
192
|
if (index === blockedStandaloneLabelIndex) return false
|
|
188
193
|
const label = this.outputNetLabelPlacements[index]!
|
|
189
|
-
return
|
|
194
|
+
return (
|
|
195
|
+
getNetLabelWidthForConnection({
|
|
196
|
+
inputProblem: this.inputProblem,
|
|
197
|
+
netId: label.netId,
|
|
198
|
+
pinIds: label.pinIds,
|
|
199
|
+
}) === blockedLabelWidth
|
|
200
|
+
)
|
|
190
201
|
})
|
|
191
202
|
}
|
|
192
203
|
if (columnLabelIndex !== undefined) {
|
|
@@ -481,7 +492,11 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
481
492
|
|
|
482
493
|
const { width, height } = getDimsForOrientation({
|
|
483
494
|
orientation,
|
|
484
|
-
netLabelWidth:
|
|
495
|
+
netLabelWidth: getNetLabelWidthForConnection({
|
|
496
|
+
inputProblem: this.inputProblem,
|
|
497
|
+
netId: label.netId,
|
|
498
|
+
pinIds: label.pinIds,
|
|
499
|
+
}),
|
|
485
500
|
netLabelHeight: this.getNetLabelHeight(label),
|
|
486
501
|
})
|
|
487
502
|
|
|
@@ -1094,7 +1109,11 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
1094
1109
|
private labelIntersectsDifferentNetTrace(label: NetLabelPlacement) {
|
|
1095
1110
|
const { width, height } = getDimsForOrientation({
|
|
1096
1111
|
orientation: label.orientation,
|
|
1097
|
-
netLabelWidth:
|
|
1112
|
+
netLabelWidth: getNetLabelWidthForConnection({
|
|
1113
|
+
inputProblem: this.inputProblem,
|
|
1114
|
+
netId: label.netId,
|
|
1115
|
+
pinIds: label.pinIds,
|
|
1116
|
+
}),
|
|
1098
1117
|
netLabelHeight: this.getNetLabelHeight(label),
|
|
1099
1118
|
})
|
|
1100
1119
|
const center = getCenterFromAnchor(
|
|
@@ -1118,7 +1137,11 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
1118
1137
|
const anchorPoint = this.getWickOffsetAnchor(label.anchorPoint, orientation)
|
|
1119
1138
|
const { width, height } = getDimsForOrientation({
|
|
1120
1139
|
orientation,
|
|
1121
|
-
netLabelWidth:
|
|
1140
|
+
netLabelWidth: getNetLabelWidthForConnection({
|
|
1141
|
+
inputProblem: this.inputProblem,
|
|
1142
|
+
netId: label.netId,
|
|
1143
|
+
pinIds: label.pinIds,
|
|
1144
|
+
}),
|
|
1122
1145
|
netLabelHeight: this.getNetLabelHeight(label),
|
|
1123
1146
|
})
|
|
1124
1147
|
|
|
@@ -1197,7 +1220,11 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
1197
1220
|
) {
|
|
1198
1221
|
const { width, height } = getDimsForOrientation({
|
|
1199
1222
|
orientation,
|
|
1200
|
-
netLabelWidth:
|
|
1223
|
+
netLabelWidth: getNetLabelWidthForConnection({
|
|
1224
|
+
inputProblem: this.inputProblem,
|
|
1225
|
+
netId: label.netId,
|
|
1226
|
+
pinIds: label.pinIds,
|
|
1227
|
+
}),
|
|
1201
1228
|
netLabelHeight: this.getNetLabelHeight(label),
|
|
1202
1229
|
})
|
|
1203
1230
|
const labelLength =
|
|
@@ -1278,7 +1305,11 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
1278
1305
|
): CandidateLabel {
|
|
1279
1306
|
const { width, height } = getDimsForOrientation({
|
|
1280
1307
|
orientation,
|
|
1281
|
-
netLabelWidth:
|
|
1308
|
+
netLabelWidth: getNetLabelWidthForConnection({
|
|
1309
|
+
inputProblem: this.inputProblem,
|
|
1310
|
+
netId: label.netId,
|
|
1311
|
+
pinIds: label.pinIds,
|
|
1312
|
+
}),
|
|
1282
1313
|
netLabelHeight: this.getNetLabelHeight(label),
|
|
1283
1314
|
})
|
|
1284
1315
|
return {
|
|
@@ -1291,29 +1322,6 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
1291
1322
|
}
|
|
1292
1323
|
}
|
|
1293
1324
|
|
|
1294
|
-
private getNetLabelWidth(label: NetLabelPlacement) {
|
|
1295
|
-
if (label.netId) {
|
|
1296
|
-
const ncWidth = this.inputProblem.netConnections.find(
|
|
1297
|
-
(connection) => connection.netId === label.netId,
|
|
1298
|
-
)?.netLabelWidth
|
|
1299
|
-
if (ncWidth !== undefined) return ncWidth
|
|
1300
|
-
|
|
1301
|
-
const dcWidthByNetId = this.inputProblem.directConnections.find(
|
|
1302
|
-
(dc) => dc.netId === label.netId,
|
|
1303
|
-
)?.netLabelWidth
|
|
1304
|
-
if (dcWidthByNetId !== undefined) return dcWidthByNetId
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
const dcWidthByPinId = this.inputProblem.directConnections.find((dc) =>
|
|
1308
|
-
dc.pinIds.some((pid) => label.pinIds.includes(pid)),
|
|
1309
|
-
)?.netLabelWidth
|
|
1310
|
-
if (dcWidthByPinId !== undefined) return dcWidthByPinId
|
|
1311
|
-
|
|
1312
|
-
return this.inputProblem.netConnections.find((nc) =>
|
|
1313
|
-
nc.pinIds.some((pid) => label.pinIds.includes(pid)),
|
|
1314
|
-
)?.netLabelWidth
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
1325
|
private getNetLabelHeight(label: NetLabelPlacement) {
|
|
1318
1326
|
if (label.netId) {
|
|
1319
1327
|
const ncHeight = this.inputProblem.netConnections.find(
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
getAxisAlignedSegments,
|
|
19
19
|
} from "./getAxisAlignedSegments"
|
|
20
20
|
import { alignPortOnlyInlineNetLabelStubs } from "./alignPortOnlyInlineNetLabelStubs"
|
|
21
|
+
import { pushAnchoredNetLabelsAwayFromInlineLabels } from "./pushAnchoredNetLabelsAwayFromInlineLabels"
|
|
21
22
|
|
|
22
23
|
export const DEFAULT_INLINE_NET_LABEL_HEIGHT = 0.18
|
|
23
24
|
|
|
@@ -111,6 +112,11 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
111
112
|
|
|
112
113
|
private tracesByPinPairKey: Map<string, SolvedTracePath[]>
|
|
113
114
|
private hasAlignedPortOnlyStubs = false
|
|
115
|
+
private postProcessedOutput?: {
|
|
116
|
+
traces: SolvedTracePath[]
|
|
117
|
+
netLabelPlacements: NetLabelPlacement[]
|
|
118
|
+
inlineNetLabelPlacements: InlineNetLabelPlacement[]
|
|
119
|
+
}
|
|
114
120
|
|
|
115
121
|
constructor(input: InlineNetLabelSolverInput) {
|
|
116
122
|
super()
|
|
@@ -191,6 +197,11 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
191
197
|
return
|
|
192
198
|
}
|
|
193
199
|
|
|
200
|
+
if (!this.postProcessedOutput) {
|
|
201
|
+
this.postProcessedOutput = this.buildPostProcessedOutput()
|
|
202
|
+
return
|
|
203
|
+
}
|
|
204
|
+
|
|
194
205
|
this.solved = true
|
|
195
206
|
this.stats.inlineNetLabelCount = this.inlineNetLabelPlacements.length
|
|
196
207
|
}
|
|
@@ -584,20 +595,31 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
584
595
|
)
|
|
585
596
|
}
|
|
586
597
|
|
|
587
|
-
|
|
598
|
+
private buildPostProcessedOutput() {
|
|
588
599
|
const superseded = this.getSupersededNetLabelKeys()
|
|
600
|
+
const retainedNetLabelPlacements = this.inputNetLabelPlacements.filter(
|
|
601
|
+
(placement) => !superseded.has(placement.globalConnNetId),
|
|
602
|
+
)
|
|
603
|
+
const outputTraces = this.getOutputTraces(superseded)
|
|
604
|
+
const pushed = pushAnchoredNetLabelsAwayFromInlineLabels({
|
|
605
|
+
inputProblem: this.inputProblem,
|
|
606
|
+
traces: outputTraces,
|
|
607
|
+
netLabelPlacements: retainedNetLabelPlacements,
|
|
608
|
+
inlineNetLabelPlacements: this.inlineNetLabelPlacements,
|
|
609
|
+
})
|
|
610
|
+
this.stats.pushedAnchoredNetLabelCount = pushed.movedLabelCount
|
|
589
611
|
return {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
// actual net trace, but discard that now-orphaned label connector.
|
|
593
|
-
traces: this.getOutputTraces(superseded),
|
|
594
|
-
netLabelPlacements: this.inputNetLabelPlacements.filter(
|
|
595
|
-
(placement) => !superseded.has(placement.globalConnNetId),
|
|
596
|
-
),
|
|
612
|
+
traces: pushed.traces,
|
|
613
|
+
netLabelPlacements: pushed.netLabelPlacements,
|
|
597
614
|
inlineNetLabelPlacements: this.inlineNetLabelPlacements,
|
|
598
615
|
}
|
|
599
616
|
}
|
|
600
617
|
|
|
618
|
+
getOutput() {
|
|
619
|
+
if (this.postProcessedOutput) return this.postProcessedOutput
|
|
620
|
+
return this.buildPostProcessedOutput()
|
|
621
|
+
}
|
|
622
|
+
|
|
601
623
|
override visualize(): GraphicsObject {
|
|
602
624
|
// Mirrors the previous pipeline stage's visualization so that a problem
|
|
603
625
|
// with no inline labels renders identically, then layers the inline labels
|