@tscircuit/schematic-trace-solver 0.0.40 → 0.0.42
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 +155 -9
- package/dist/index.js +998 -479
- package/lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts +238 -0
- package/lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver.ts +61 -26
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/TraceLabelOverlapAvoidanceSolver.ts +94 -192
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/rerouteCollidingTrace.ts +13 -24
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/LabelMergingSolver/LabelMergingSolver.ts +205 -0
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/OverlapAvoidanceStepSolver/OverlapAvoidanceStepSolver.ts +144 -0
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/SingleOverlapSolver/SingleOverlapSolver.ts +117 -0
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/TraceCleanupSolver/TraceCleanupSolver.ts +132 -0
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{balanceLShapes.ts → sub-solvers/TraceCleanupSolver/balanceLShapes.ts} +12 -10
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{hasCollisions.ts → sub-solvers/TraceCleanupSolver/hasCollisions.ts} +1 -1
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{hasCollisionsWithLabels.ts → sub-solvers/TraceCleanupSolver/hasCollisionsWithLabels.ts} +1 -1
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{minimizeTurnsWithFilteredLabels.ts → sub-solvers/TraceCleanupSolver/minimizeTurnsWithFilteredLabels.ts} +6 -6
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{simplifyPath.ts → sub-solvers/TraceCleanupSolver/simplifyPath.ts} +1 -1
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{turnMinimization.ts → sub-solvers/TraceCleanupSolver/turnMinimization.ts} +0 -2
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/tryFourPointDetour.ts +104 -0
- package/lib/solvers/TraceLabelOverlapAvoidanceSolver/trySnipAndReconnect.ts +24 -154
- package/lib/utils/does-trace-overlap-with-existing-traces.ts +33 -0
- package/package.json +1 -1
- package/site/examples/example25.page.tsx +4 -0
- package/tests/assets/1.input.json +379 -0
- package/tests/assets/2.input.json +330 -0
- package/tests/assets/3.input.json +388 -0
- package/tests/assets/MergedNetLabelObstacles.test.input.json +154 -0
- package/tests/assets/OverlapAvoidanceStepSolver.test.input.json +682 -0
- package/tests/assets/SingleOverlapSolver.test.input.json +170 -0
- package/tests/assets/TraceCleanupSolver.test.input.json +216 -0
- package/tests/assets/TraceLabelOverlapAvoidanceSolver.test.input.json +424 -0
- package/tests/assets/example25.json +96 -0
- package/tests/examples/__snapshots__/example03.snap.svg +67 -76
- package/tests/examples/__snapshots__/example10.snap.svg +24 -30
- package/tests/examples/__snapshots__/example13.snap.svg +81 -84
- package/tests/examples/__snapshots__/example15.snap.svg +5 -8
- package/tests/examples/__snapshots__/example21.snap.svg +68 -74
- package/tests/examples/__snapshots__/example25.snap.svg +3 -3
- package/tests/examples/__snapshots__/example26.snap.svg +3 -3
- package/tests/examples/__snapshots__/example28.snap.svg +273 -0
- package/tests/examples/example28.test.ts +13 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/TraceLabelOverlapAvoidanceSolver.test.ts +18 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/__snapshots__/TraceLabelOverlapAvoidanceSolver.snap.svg +243 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/__snapshots__/renderComparisonView01.snap.svg +223 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/__snapshots__/renderComparisonView02.snap.svg +205 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/__snapshots__/renderComparisonView03.snap.svg +184 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/renderComparisonView01.test.ts +29 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/renderComparisonView02.test.ts +27 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/renderComparisonView03.test.ts +39 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/MergedNetLabelObstacles.test.ts +14 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/OverlapAvoidanceStepSolver.test.ts +20 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/SingleOverlapSolver.test.ts +10 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/TraceCleanupSolver.test.ts +19 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/MergedNetLabelObstacles.snap.svg +140 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/OverlapAvoidanceStepSolver.snap.svg +216 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/SingleOverlapSolver.snap.svg +125 -0
- package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/TraceCleanupSolver.snap.svg +119 -0
- /package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{countTurns.ts → sub-solvers/TraceCleanupSolver/countTurns.ts} +0 -0
- /package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{tryConnectPoints.ts → sub-solvers/TraceCleanupSolver/tryConnectPoints.ts} +0 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { getConnectivityMapsFromInputProblem } from "lib/solvers/MspConnectionPairSolver/getConnectivityMapFromInputProblem"
|
|
2
|
+
import type { MspConnectionPair } from "lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver"
|
|
3
|
+
import type {
|
|
4
|
+
InputProblem,
|
|
5
|
+
InputPin,
|
|
6
|
+
PinId,
|
|
7
|
+
InputChip,
|
|
8
|
+
} from "lib/types/InputProblem"
|
|
9
|
+
import { BaseSolver } from "../BaseSolver/BaseSolver"
|
|
10
|
+
import { SchematicTraceSingleLineSolver2 } from "../SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/SchematicTraceSingleLineSolver2"
|
|
11
|
+
import { doesTraceOverlapWithExistingTraces } from "lib/utils/does-trace-overlap-with-existing-traces"
|
|
12
|
+
import { visualizeInputProblem } from "../SchematicTracePipelineSolver/visualizeInputProblem"
|
|
13
|
+
import type { SolvedTracePath } from "../SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
14
|
+
import type { ConnectivityMap } from "connectivity-map"
|
|
15
|
+
|
|
16
|
+
const NEAREST_NEIGHBOR_COUNT = 3
|
|
17
|
+
|
|
18
|
+
const distance = (p1: InputPin, p2: InputPin) => {
|
|
19
|
+
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class LongDistancePairSolver extends BaseSolver {
|
|
23
|
+
public solvedLongDistanceTraces: SolvedTracePath[] = []
|
|
24
|
+
private queuedCandidatePairs: Array<
|
|
25
|
+
[InputPin & { chipId: string }, InputPin & { chipId: string }]
|
|
26
|
+
> = []
|
|
27
|
+
private currentCandidatePair:
|
|
28
|
+
| [InputPin & { chipId: string }, InputPin & { chipId: string }]
|
|
29
|
+
| null = null
|
|
30
|
+
private subSolver: SchematicTraceSingleLineSolver2 | null = null
|
|
31
|
+
private chipMap: Record<string, InputChip> = {}
|
|
32
|
+
private inputProblem: InputProblem
|
|
33
|
+
private netConnMap: ConnectivityMap
|
|
34
|
+
private newlyConnectedPinIds = new Set<PinId>()
|
|
35
|
+
private allSolvedTraces: SolvedTracePath[] = []
|
|
36
|
+
|
|
37
|
+
constructor(
|
|
38
|
+
private params: {
|
|
39
|
+
inputProblem: InputProblem
|
|
40
|
+
alreadySolvedTraces: SolvedTracePath[]
|
|
41
|
+
primaryMspConnectionPairs: MspConnectionPair[]
|
|
42
|
+
},
|
|
43
|
+
) {
|
|
44
|
+
super()
|
|
45
|
+
|
|
46
|
+
const { inputProblem, primaryMspConnectionPairs, alreadySolvedTraces } =
|
|
47
|
+
this.params
|
|
48
|
+
|
|
49
|
+
this.inputProblem = inputProblem
|
|
50
|
+
this.allSolvedTraces = [...alreadySolvedTraces]
|
|
51
|
+
|
|
52
|
+
// 1. Create initial maps and sets for efficient lookup
|
|
53
|
+
const primaryConnectedPinIds = new Set<PinId>()
|
|
54
|
+
for (const pair of primaryMspConnectionPairs) {
|
|
55
|
+
primaryConnectedPinIds.add(pair.pins[0].pinId)
|
|
56
|
+
primaryConnectedPinIds.add(pair.pins[1].pinId)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem)
|
|
60
|
+
this.netConnMap = netConnMap
|
|
61
|
+
const pinMap = new Map<PinId, InputPin & { chipId: string }>()
|
|
62
|
+
for (const chip of inputProblem.chips) {
|
|
63
|
+
this.chipMap[chip.chipId] = chip
|
|
64
|
+
for (const pin of chip.pins) {
|
|
65
|
+
pinMap.set(pin.pinId, { ...pin, chipId: chip.chipId })
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 2. Generate candidate pairs using N-Nearest-Neighbors approach
|
|
70
|
+
const candidatePairs: Array<
|
|
71
|
+
[InputPin & { chipId: string }, InputPin & { chipId: string }]
|
|
72
|
+
> = []
|
|
73
|
+
const addedPairKeys = new Set<string>()
|
|
74
|
+
|
|
75
|
+
for (const netId of Object.keys(netConnMap.netMap)) {
|
|
76
|
+
const allPinIdsInNet = netConnMap.getIdsConnectedToNet(netId)
|
|
77
|
+
if (allPinIdsInNet.length < 2) continue
|
|
78
|
+
|
|
79
|
+
const unconnectedPinIds = allPinIdsInNet.filter(
|
|
80
|
+
(pinId) => !primaryConnectedPinIds.has(pinId),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
for (const unconnectedPinId of unconnectedPinIds) {
|
|
84
|
+
const sourcePin = pinMap.get(unconnectedPinId)
|
|
85
|
+
if (!sourcePin) continue
|
|
86
|
+
|
|
87
|
+
const neighbors = allPinIdsInNet
|
|
88
|
+
.filter((otherPinId) => otherPinId !== unconnectedPinId)
|
|
89
|
+
.flatMap((otherPinId) => {
|
|
90
|
+
const targetPin = pinMap.get(otherPinId)
|
|
91
|
+
if (!targetPin) return [] // Gracefully handle missing pins
|
|
92
|
+
return [
|
|
93
|
+
{
|
|
94
|
+
pin: targetPin,
|
|
95
|
+
distance: distance(sourcePin, targetPin),
|
|
96
|
+
},
|
|
97
|
+
]
|
|
98
|
+
})
|
|
99
|
+
.sort((a, b) => a.distance - b.distance)
|
|
100
|
+
.slice(0, NEAREST_NEIGHBOR_COUNT)
|
|
101
|
+
|
|
102
|
+
for (const neighbor of neighbors) {
|
|
103
|
+
const pair: [
|
|
104
|
+
InputPin & { chipId: string },
|
|
105
|
+
InputPin & { chipId: string },
|
|
106
|
+
] = [sourcePin, neighbor.pin]
|
|
107
|
+
const pairKey = pair
|
|
108
|
+
.map((p) => p.pinId)
|
|
109
|
+
.sort()
|
|
110
|
+
.join("--")
|
|
111
|
+
|
|
112
|
+
if (!addedPairKeys.has(pairKey)) {
|
|
113
|
+
candidatePairs.push(pair)
|
|
114
|
+
addedPairKeys.add(pairKey)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
this.queuedCandidatePairs = candidatePairs
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
override getConstructorParams() {
|
|
123
|
+
return this.params
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
override _step() {
|
|
127
|
+
// 1. Check if a sub-solver has finished and process its result
|
|
128
|
+
if (this.subSolver?.solved) {
|
|
129
|
+
const newTracePath = this.subSolver.solvedTracePath
|
|
130
|
+
if (newTracePath && this.currentCandidatePair) {
|
|
131
|
+
const isTraceClear = !doesTraceOverlapWithExistingTraces(
|
|
132
|
+
newTracePath,
|
|
133
|
+
this.allSolvedTraces,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
if (isTraceClear) {
|
|
137
|
+
const [p1, p2] = this.currentCandidatePair
|
|
138
|
+
const globalConnNetId = this.netConnMap.getNetConnectedToId(p1.pinId)!
|
|
139
|
+
const mspPairId = `${p1.pinId}-${p2.pinId}`
|
|
140
|
+
|
|
141
|
+
const newSolvedTrace: SolvedTracePath = {
|
|
142
|
+
mspPairId,
|
|
143
|
+
dcConnNetId: globalConnNetId,
|
|
144
|
+
globalConnNetId,
|
|
145
|
+
pins: [p1, p2],
|
|
146
|
+
tracePath: newTracePath,
|
|
147
|
+
mspConnectionPairIds: [mspPairId],
|
|
148
|
+
pinIds: [p1.pinId, p2.pinId],
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
this.solvedLongDistanceTraces.push(newSolvedTrace)
|
|
152
|
+
this.allSolvedTraces.push(newSolvedTrace)
|
|
153
|
+
|
|
154
|
+
this.newlyConnectedPinIds.add(p1.pinId)
|
|
155
|
+
this.newlyConnectedPinIds.add(p2.pinId)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
this.subSolver = null
|
|
159
|
+
this.currentCandidatePair = null
|
|
160
|
+
} else if (this.subSolver?.failed) {
|
|
161
|
+
this.subSolver = null
|
|
162
|
+
this.currentCandidatePair = null
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 2. If a sub-solver is already running, let it continue
|
|
166
|
+
if (this.subSolver) {
|
|
167
|
+
this.subSolver.step()
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 3. Find the next valid candidate pair and start a new sub-solver
|
|
172
|
+
while (this.queuedCandidatePairs.length > 0) {
|
|
173
|
+
const nextPair = this.queuedCandidatePairs.shift()!
|
|
174
|
+
const [p1, p2] = nextPair
|
|
175
|
+
|
|
176
|
+
if (
|
|
177
|
+
this.newlyConnectedPinIds.has(p1.pinId) ||
|
|
178
|
+
this.newlyConnectedPinIds.has(p2.pinId)
|
|
179
|
+
) {
|
|
180
|
+
continue
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this.currentCandidatePair = nextPair
|
|
184
|
+
this.subSolver = new SchematicTraceSingleLineSolver2({
|
|
185
|
+
inputProblem: this.params.inputProblem,
|
|
186
|
+
pins: this.currentCandidatePair,
|
|
187
|
+
chipMap: this.chipMap,
|
|
188
|
+
})
|
|
189
|
+
return
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 4. If we've exited the loop, there are no more valid pairs to process
|
|
193
|
+
this.solved = true
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
override visualize() {
|
|
197
|
+
if (this.subSolver) {
|
|
198
|
+
return this.subSolver.visualize()
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const graphics = visualizeInputProblem(this.inputProblem)
|
|
202
|
+
|
|
203
|
+
// Draw solved long-distance traces
|
|
204
|
+
for (const trace of this.solvedLongDistanceTraces) {
|
|
205
|
+
graphics.lines!.push({
|
|
206
|
+
points: trace.tracePath,
|
|
207
|
+
strokeColor: "purple",
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Draw queued candidate pairs
|
|
212
|
+
for (const [p1, p2] of this.queuedCandidatePairs) {
|
|
213
|
+
graphics.lines!.push({
|
|
214
|
+
points: [p1, p2],
|
|
215
|
+
strokeColor: "gray",
|
|
216
|
+
strokeDash: "4 4",
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return graphics
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
public getOutput(): {
|
|
224
|
+
newTraces: SolvedTracePath[]
|
|
225
|
+
allTracesMerged: SolvedTracePath[]
|
|
226
|
+
} {
|
|
227
|
+
if (!this.solved) {
|
|
228
|
+
return { newTraces: [], allTracesMerged: this.params.alreadySolvedTraces }
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
newTraces: this.solvedLongDistanceTraces,
|
|
232
|
+
allTracesMerged: [
|
|
233
|
+
...this.params.alreadySolvedTraces,
|
|
234
|
+
...this.solvedLongDistanceTraces,
|
|
235
|
+
],
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -7,15 +7,19 @@ import type { GraphicsObject } from "graphics-debug"
|
|
|
7
7
|
import { BaseSolver } from "lib/solvers/BaseSolver/BaseSolver"
|
|
8
8
|
import type { InputProblem } from "lib/types/InputProblem"
|
|
9
9
|
import { MspConnectionPairSolver } from "../MspConnectionPairSolver/MspConnectionPairSolver"
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
SchematicTraceLinesSolver,
|
|
12
|
+
type SolvedTracePath,
|
|
13
|
+
} from "../SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
11
14
|
import { TraceOverlapShiftSolver } from "../TraceOverlapShiftSolver/TraceOverlapShiftSolver"
|
|
12
15
|
import { NetLabelPlacementSolver } from "../NetLabelPlacementSolver/NetLabelPlacementSolver"
|
|
13
16
|
import { visualizeInputProblem } from "./visualizeInputProblem"
|
|
14
|
-
import { GuidelinesSolver } from "../GuidelinesSolver/GuidelinesSolver"
|
|
15
17
|
import { TraceLabelOverlapAvoidanceSolver } from "../TraceLabelOverlapAvoidanceSolver/TraceLabelOverlapAvoidanceSolver"
|
|
16
|
-
import { getInputChipBounds } from "../GuidelinesSolver/getInputChipBounds"
|
|
17
18
|
import { correctPinsInsideChips } from "./correctPinsInsideChip"
|
|
18
19
|
import { expandChipsToFitPins } from "./expandChipsToFitPins"
|
|
20
|
+
import { LongDistancePairSolver } from "../LongDistancePairSolver/LongDistancePairSolver"
|
|
21
|
+
import { MergedNetLabelObstacleSolver } from "../TraceLabelOverlapAvoidanceSolver/sub-solvers/LabelMergingSolver/LabelMergingSolver"
|
|
22
|
+
import { TraceCleanupSolver } from "../TraceLabelOverlapAvoidanceSolver/sub-solvers/TraceCleanupSolver/TraceCleanupSolver"
|
|
19
23
|
|
|
20
24
|
type PipelineStep<T extends new (...args: any[]) => BaseSolver> = {
|
|
21
25
|
solverName: string
|
|
@@ -24,6 +28,7 @@ type PipelineStep<T extends new (...args: any[]) => BaseSolver> = {
|
|
|
24
28
|
instance: SchematicTracePipelineSolver,
|
|
25
29
|
) => ConstructorParameters<T>
|
|
26
30
|
onSolved?: (instance: SchematicTracePipelineSolver) => void
|
|
31
|
+
shouldSkip?: (instance: SchematicTracePipelineSolver) => boolean
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
function definePipelineStep<
|
|
@@ -37,6 +42,7 @@ function definePipelineStep<
|
|
|
37
42
|
getConstructorParams: (instance: SchematicTracePipelineSolver) => P,
|
|
38
43
|
opts: {
|
|
39
44
|
onSolved?: (instance: SchematicTracePipelineSolver) => void
|
|
45
|
+
shouldSkip?: (instance: SchematicTracePipelineSolver) => boolean
|
|
40
46
|
} = {},
|
|
41
47
|
): PipelineStep<T> {
|
|
42
48
|
return {
|
|
@@ -44,16 +50,25 @@ function definePipelineStep<
|
|
|
44
50
|
solverClass,
|
|
45
51
|
getConstructorParams,
|
|
46
52
|
onSolved: opts.onSolved,
|
|
53
|
+
shouldSkip: opts.shouldSkip,
|
|
47
54
|
}
|
|
48
55
|
}
|
|
49
56
|
|
|
57
|
+
export interface SchematicTracePipelineSolverParams {
|
|
58
|
+
inputProblem: InputProblem
|
|
59
|
+
allowLongDistanceTraces?: boolean
|
|
60
|
+
}
|
|
61
|
+
|
|
50
62
|
export class SchematicTracePipelineSolver extends BaseSolver {
|
|
51
63
|
mspConnectionPairSolver?: MspConnectionPairSolver
|
|
52
64
|
// guidelinesSolver?: GuidelinesSolver
|
|
53
65
|
schematicTraceLinesSolver?: SchematicTraceLinesSolver
|
|
66
|
+
longDistancePairSolver?: LongDistancePairSolver
|
|
54
67
|
traceOverlapShiftSolver?: TraceOverlapShiftSolver
|
|
55
68
|
netLabelPlacementSolver?: NetLabelPlacementSolver
|
|
69
|
+
labelMergingSolver?: MergedNetLabelObstacleSolver
|
|
56
70
|
traceLabelOverlapAvoidanceSolver?: TraceLabelOverlapAvoidanceSolver
|
|
71
|
+
traceCleanupSolver?: TraceCleanupSolver
|
|
57
72
|
|
|
58
73
|
startTimeOfPhase: Record<string, number>
|
|
59
74
|
endTimeOfPhase: Record<string, number>
|
|
@@ -96,6 +111,19 @@ export class SchematicTracePipelineSolver extends BaseSolver {
|
|
|
96
111
|
chipMap: this.mspConnectionPairSolver!.chipMap,
|
|
97
112
|
},
|
|
98
113
|
],
|
|
114
|
+
),
|
|
115
|
+
definePipelineStep(
|
|
116
|
+
"longDistancePairSolver",
|
|
117
|
+
LongDistancePairSolver,
|
|
118
|
+
(instance) => [
|
|
119
|
+
{
|
|
120
|
+
inputProblem: instance.inputProblem,
|
|
121
|
+
primaryMspConnectionPairs:
|
|
122
|
+
instance.mspConnectionPairSolver!.mspConnectionPairs,
|
|
123
|
+
alreadySolvedTraces:
|
|
124
|
+
instance.schematicTraceLinesSolver!.solvedTracePaths,
|
|
125
|
+
},
|
|
126
|
+
],
|
|
99
127
|
{
|
|
100
128
|
onSolved: (schematicTraceLinesSolver) => {},
|
|
101
129
|
},
|
|
@@ -106,7 +134,8 @@ export class SchematicTracePipelineSolver extends BaseSolver {
|
|
|
106
134
|
() => [
|
|
107
135
|
{
|
|
108
136
|
inputProblem: this.inputProblem,
|
|
109
|
-
inputTracePaths:
|
|
137
|
+
inputTracePaths:
|
|
138
|
+
this.longDistancePairSolver?.getOutput().allTracesMerged!,
|
|
110
139
|
globalConnMap: this.mspConnectionPairSolver!.globalConnMap,
|
|
111
140
|
},
|
|
112
141
|
],
|
|
@@ -123,10 +152,9 @@ export class SchematicTracePipelineSolver extends BaseSolver {
|
|
|
123
152
|
inputTraceMap:
|
|
124
153
|
this.traceOverlapShiftSolver?.correctedTraceMap ??
|
|
125
154
|
Object.fromEntries(
|
|
126
|
-
this.
|
|
127
|
-
p.mspPairId,
|
|
128
|
-
|
|
129
|
-
]),
|
|
155
|
+
this.longDistancePairSolver!.getOutput().allTracesMerged.map(
|
|
156
|
+
(p) => [p.mspPairId, p],
|
|
157
|
+
),
|
|
130
158
|
),
|
|
131
159
|
},
|
|
132
160
|
],
|
|
@@ -143,10 +171,9 @@ export class SchematicTracePipelineSolver extends BaseSolver {
|
|
|
143
171
|
const traceMap =
|
|
144
172
|
instance.traceOverlapShiftSolver?.correctedTraceMap ??
|
|
145
173
|
Object.fromEntries(
|
|
146
|
-
instance
|
|
147
|
-
|
|
148
|
-
p,
|
|
149
|
-
]),
|
|
174
|
+
instance
|
|
175
|
+
.longDistancePairSolver!.getOutput()
|
|
176
|
+
.allTracesMerged.map((p) => [p.mspPairId, p]),
|
|
150
177
|
)
|
|
151
178
|
const traces = Object.values(traceMap)
|
|
152
179
|
const netLabelPlacements =
|
|
@@ -160,18 +187,23 @@ export class SchematicTracePipelineSolver extends BaseSolver {
|
|
|
160
187
|
},
|
|
161
188
|
]
|
|
162
189
|
},
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
190
|
+
),
|
|
191
|
+
definePipelineStep(
|
|
192
|
+
"netLabelPlacementSolver",
|
|
193
|
+
NetLabelPlacementSolver,
|
|
194
|
+
(instance) => {
|
|
195
|
+
const traces =
|
|
196
|
+
instance.traceCleanupSolver?.getOutput().traces ??
|
|
197
|
+
instance.traceLabelOverlapAvoidanceSolver!.getOutput().traces
|
|
198
|
+
|
|
199
|
+
return [
|
|
200
|
+
{
|
|
201
|
+
inputProblem: instance.inputProblem,
|
|
202
|
+
inputTraceMap: Object.fromEntries(
|
|
203
|
+
traces.map((trace: SolvedTracePath) => [trace.mspPairId, trace]),
|
|
204
|
+
),
|
|
205
|
+
},
|
|
206
|
+
]
|
|
175
207
|
},
|
|
176
208
|
),
|
|
177
209
|
]
|
|
@@ -281,16 +313,19 @@ export class SchematicTracePipelineSolver extends BaseSolver {
|
|
|
281
313
|
}) as GraphicsObject[]),
|
|
282
314
|
]
|
|
283
315
|
|
|
284
|
-
if (visualizations.length === 1)
|
|
316
|
+
if (visualizations.length === 1) {
|
|
317
|
+
return visualizations[0]!
|
|
318
|
+
}
|
|
285
319
|
|
|
286
320
|
// Simple combination of visualizations
|
|
287
|
-
|
|
321
|
+
const finalGraphics = {
|
|
288
322
|
points: visualizations.flatMap((v) => v.points || []),
|
|
289
323
|
rects: visualizations.flatMap((v) => v.rects || []),
|
|
290
324
|
lines: visualizations.flatMap((v) => v.lines || []),
|
|
291
325
|
circles: visualizations.flatMap((v) => v.circles || []),
|
|
292
326
|
texts: visualizations.flatMap((v) => v.texts || []),
|
|
293
327
|
}
|
|
328
|
+
return finalGraphics
|
|
294
329
|
}
|
|
295
330
|
|
|
296
331
|
/**
|