@tscircuit/schematic-trace-solver 0.0.136 → 0.0.140
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/.github/workflows/bun-pver-release.yml +7 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.js +333 -45
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationObstacleIndex.ts +182 -0
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +67 -25
- package/lib/solvers/AvailableNetOrientationSolver/constants.ts +2 -0
- package/lib/solvers/Example28Solver/labelMovement.ts +71 -0
- package/lib/solvers/SameNetJunctionAlignmentSolver/SameNetJunctionAlignmentSolver.ts +5 -2
- package/lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions.ts +93 -14
- package/lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver.ts +12 -4
- package/package.json +5 -1
- package/tests/bug-reports/bug-report-20260721T221026Z/__snapshots__/bug-report-20260721T221026Z.snap.svg +4 -4
- package/tests/bug-reports/bug-report-20260721T221026Z/bug-report-20260721T221026Z.test.ts +11 -0
- package/tests/bug-reports/bug-report-20260815T073240Z/__snapshots__/bug-report-20260815T073240Z.snap.svg +3 -3
- package/tests/bug-reports/bug-report-20260815T073240Z/bug-report-20260815T073240Z.test.ts +39 -0
- package/tests/bug-reports/bug-report-20260819T091818Z/__snapshots__/bug-report-20260819T091818Z.snap.svg +237 -0
- package/tests/bug-reports/bug-report-20260819T091818Z/bug-report-20260819T091818Z.json +1052 -0
- package/tests/bug-reports/bug-report-20260819T091818Z/bug-report-20260819T091818Z.test.ts +33 -0
- package/tests/repros/__snapshots__/repro-board-589-regulator-section.snap.svg +4 -4
- package/tests/repros/__snapshots__/repro-board-648-esp12f-section.snap.svg +124 -0
- package/tests/repros/assets/repro-board-648-esp12f-section.input.json +537 -0
- package/tests/repros/repro-board-589-regulator-section.test.ts +23 -1
- package/tests/repros/repro-board-648-esp12f-section.test.ts +13 -0
- package/tests/repros/repro161-power-section-autolayout.test.ts +7 -0
- package/tests/solvers/AvailableNetOrientationSolver/AvailableNetOrientationObstacleIndex.test.ts +122 -0
|
@@ -3,8 +3,9 @@ import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetL
|
|
|
3
3
|
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
4
4
|
import { isPathCollidingWithObstacles } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/collisions"
|
|
5
5
|
import { getObstacleRects } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect"
|
|
6
|
+
import { moveAttachedLabelsToReroutedTrace } from "lib/solvers/Example28Solver/labelMovement"
|
|
7
|
+
import { tracePathContainsPoint } from "lib/solvers/RailNetLabelCornerPlacementSolver/geometry"
|
|
6
8
|
import { simplifyPath } from "lib/solvers/TraceCleanupSolver/simplifyPath"
|
|
7
|
-
import { preservesLabelAnchors } from "lib/solvers/TraceCleanupSolver/sameNetRailAlignment/preservesLabelAnchors"
|
|
8
9
|
import {
|
|
9
10
|
getVisibleTraceLength,
|
|
10
11
|
getVisibleTraceSegmentCount,
|
|
@@ -95,6 +96,52 @@ const railIsOnFacingSide = ({
|
|
|
95
96
|
return false
|
|
96
97
|
}
|
|
97
98
|
|
|
99
|
+
const getAttachedLabelIndexes = (
|
|
100
|
+
trace: SolvedTracePath,
|
|
101
|
+
netLabelPlacements: NetLabelPlacement[],
|
|
102
|
+
) =>
|
|
103
|
+
netLabelPlacements.flatMap((label, index) => {
|
|
104
|
+
const labelOwnsTrace =
|
|
105
|
+
label.mspConnectionPairIds.includes(trace.mspPairId) ||
|
|
106
|
+
(label.mspConnectionPairIds.length === 0 &&
|
|
107
|
+
label.globalConnNetId === trace.globalConnNetId)
|
|
108
|
+
return labelOwnsTrace &&
|
|
109
|
+
tracePathContainsPoint(trace.tracePath, label.anchorPoint)
|
|
110
|
+
? [index]
|
|
111
|
+
: []
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
const moveAttachedLabels = ({
|
|
115
|
+
trace,
|
|
116
|
+
reroutedTracePath,
|
|
117
|
+
netLabelPlacements,
|
|
118
|
+
attachedLabelIndexes,
|
|
119
|
+
}: {
|
|
120
|
+
trace: SolvedTracePath
|
|
121
|
+
reroutedTracePath: Point[]
|
|
122
|
+
netLabelPlacements: NetLabelPlacement[]
|
|
123
|
+
attachedLabelIndexes: number[]
|
|
124
|
+
}) => {
|
|
125
|
+
const attachedLabels = attachedLabelIndexes.map(
|
|
126
|
+
(index) => netLabelPlacements[index]!,
|
|
127
|
+
)
|
|
128
|
+
const movedAttachedLabels = moveAttachedLabelsToReroutedTrace({
|
|
129
|
+
trace,
|
|
130
|
+
originalTracePath: trace.tracePath,
|
|
131
|
+
reroutedTracePath,
|
|
132
|
+
netLabelPlacements: attachedLabels,
|
|
133
|
+
})
|
|
134
|
+
const movedLabelByIndex = new Map(
|
|
135
|
+
attachedLabelIndexes.map((labelIndex, index) => [
|
|
136
|
+
labelIndex,
|
|
137
|
+
movedAttachedLabels[index]!,
|
|
138
|
+
]),
|
|
139
|
+
)
|
|
140
|
+
return netLabelPlacements.map(
|
|
141
|
+
(label, index) => movedLabelByIndex.get(index) ?? label,
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
98
145
|
const getAlignedBranchPath = ({
|
|
99
146
|
donorTrace,
|
|
100
147
|
branchTrace,
|
|
@@ -145,13 +192,15 @@ const candidateIsClear = ({
|
|
|
145
192
|
originalTrace,
|
|
146
193
|
traces,
|
|
147
194
|
inputProblem,
|
|
148
|
-
|
|
195
|
+
candidateNetLabelPlacements,
|
|
196
|
+
attachedLabelIndexes,
|
|
149
197
|
}: {
|
|
150
198
|
candidateTrace: SolvedTracePath
|
|
151
199
|
originalTrace: SolvedTracePath
|
|
152
200
|
traces: SolvedTracePath[]
|
|
153
201
|
inputProblem: InputProblem
|
|
154
|
-
|
|
202
|
+
candidateNetLabelPlacements: NetLabelPlacement[]
|
|
203
|
+
attachedLabelIndexes: number[]
|
|
155
204
|
}) => {
|
|
156
205
|
const obstacles = getObstacleRects(inputProblem)
|
|
157
206
|
if (isPathCollidingWithObstacles(candidateTrace.tracePath, obstacles)) {
|
|
@@ -165,15 +214,18 @@ const candidateIsClear = ({
|
|
|
165
214
|
return false
|
|
166
215
|
}
|
|
167
216
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
217
|
+
if (
|
|
218
|
+
!attachedLabelIndexes.every((index) =>
|
|
219
|
+
tracePathContainsPoint(
|
|
220
|
+
candidateTrace.tracePath,
|
|
221
|
+
candidateNetLabelPlacements[index]!.anchorPoint,
|
|
222
|
+
),
|
|
223
|
+
)
|
|
224
|
+
) {
|
|
173
225
|
return false
|
|
174
226
|
}
|
|
175
227
|
|
|
176
|
-
const otherNetLabelPlacements =
|
|
228
|
+
const otherNetLabelPlacements = candidateNetLabelPlacements.filter(
|
|
177
229
|
(label) => label.globalConnNetId !== candidateTrace.globalConnNetId,
|
|
178
230
|
)
|
|
179
231
|
if (
|
|
@@ -185,7 +237,7 @@ const candidateIsClear = ({
|
|
|
185
237
|
return false
|
|
186
238
|
}
|
|
187
239
|
|
|
188
|
-
const sameNetLabelPlacements =
|
|
240
|
+
const sameNetLabelPlacements = candidateNetLabelPlacements.filter(
|
|
189
241
|
(label) => label.globalConnNetId === candidateTrace.globalConnNetId,
|
|
190
242
|
)
|
|
191
243
|
// A same-net rail may follow its label edge, but never enter the label body.
|
|
@@ -221,11 +273,18 @@ export const alignSameNetJunctions = ({
|
|
|
221
273
|
netLabelPlacements,
|
|
222
274
|
}: AlignSameNetJunctionsInput) => {
|
|
223
275
|
let outputTraces = [...traces]
|
|
276
|
+
let outputNetLabelPlacements = [...netLabelPlacements]
|
|
224
277
|
const alignedBranchTraceIds = new Set<string>()
|
|
225
278
|
let alignedJunctionCount = 0
|
|
226
279
|
|
|
227
|
-
// Reuse each aligned branch as the rail for the next load in the chain.
|
|
228
|
-
|
|
280
|
+
// Reuse each aligned branch as the rail for the next load in the chain. An
|
|
281
|
+
// aligned branch may already have had its donor turn, so queue it again when
|
|
282
|
+
// its geometry changes.
|
|
283
|
+
const donorTraceIds = traces.map((trace) => trace.mspPairId)
|
|
284
|
+
const pendingDonorTraceIds = new Set(donorTraceIds)
|
|
285
|
+
for (let donorIndex = 0; donorIndex < donorTraceIds.length; donorIndex++) {
|
|
286
|
+
const donorTraceId = donorTraceIds[donorIndex]!
|
|
287
|
+
pendingDonorTraceIds.delete(donorTraceId)
|
|
229
288
|
const donorTrace = outputTraces.find(
|
|
230
289
|
(trace) => trace.mspPairId === donorTraceId,
|
|
231
290
|
)!
|
|
@@ -252,13 +311,24 @@ export const alignSameNetJunctions = ({
|
|
|
252
311
|
if (!removesVisibleSegment && !shortensVisibleTrace) {
|
|
253
312
|
continue
|
|
254
313
|
}
|
|
314
|
+
const attachedLabelIndexes = getAttachedLabelIndexes(
|
|
315
|
+
branchTrace,
|
|
316
|
+
outputNetLabelPlacements,
|
|
317
|
+
)
|
|
318
|
+
const candidateNetLabelPlacements = moveAttachedLabels({
|
|
319
|
+
trace: branchTrace,
|
|
320
|
+
reroutedTracePath: candidatePath,
|
|
321
|
+
netLabelPlacements: outputNetLabelPlacements,
|
|
322
|
+
attachedLabelIndexes,
|
|
323
|
+
})
|
|
255
324
|
if (
|
|
256
325
|
!candidateIsClear({
|
|
257
326
|
candidateTrace,
|
|
258
327
|
originalTrace: branchTrace,
|
|
259
328
|
traces: outputTraces,
|
|
260
329
|
inputProblem,
|
|
261
|
-
|
|
330
|
+
candidateNetLabelPlacements,
|
|
331
|
+
attachedLabelIndexes,
|
|
262
332
|
})
|
|
263
333
|
) {
|
|
264
334
|
continue
|
|
@@ -268,10 +338,19 @@ export const alignSameNetJunctions = ({
|
|
|
268
338
|
if (trace.mspPairId === branchTrace.mspPairId) return candidateTrace
|
|
269
339
|
return trace
|
|
270
340
|
})
|
|
341
|
+
outputNetLabelPlacements = candidateNetLabelPlacements
|
|
271
342
|
alignedBranchTraceIds.add(branchTrace.mspPairId)
|
|
272
343
|
alignedJunctionCount++
|
|
344
|
+
if (!pendingDonorTraceIds.has(branchTrace.mspPairId)) {
|
|
345
|
+
donorTraceIds.push(branchTrace.mspPairId)
|
|
346
|
+
pendingDonorTraceIds.add(branchTrace.mspPairId)
|
|
347
|
+
}
|
|
273
348
|
}
|
|
274
349
|
}
|
|
275
350
|
|
|
276
|
-
return {
|
|
351
|
+
return {
|
|
352
|
+
traces: outputTraces,
|
|
353
|
+
netLabelPlacements: outputNetLabelPlacements,
|
|
354
|
+
alignedJunctionCount,
|
|
355
|
+
}
|
|
277
356
|
}
|
|
@@ -22,7 +22,10 @@ import { LongDistancePairSolver } from "../LongDistancePairSolver/LongDistancePa
|
|
|
22
22
|
import { MergedNetLabelObstacleSolver } from "../TraceLabelOverlapAvoidanceSolver/sub-solvers/LabelMergingSolver/LabelMergingSolver"
|
|
23
23
|
import { TraceCleanupSolver } from "../TraceCleanupSolver/TraceCleanupSolver"
|
|
24
24
|
import { Example28Solver } from "../Example28Solver/Example28Solver"
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
moveAttachedLabelsToReroutedTrace,
|
|
27
|
+
moveNetLabelConnectorsToReroutedTraces,
|
|
28
|
+
} from "../Example28Solver/labelMovement"
|
|
26
29
|
import { AvailableNetOrientationSolver } from "../AvailableNetOrientationSolver/AvailableNetOrientationSolver"
|
|
27
30
|
import { RailNetLabelCornerPlacementSolver } from "../RailNetLabelCornerPlacementSolver/RailNetLabelCornerPlacementSolver"
|
|
28
31
|
import { TraceAnchoredNetLabelOverlapSolver } from "../TraceAnchoredNetLabelOverlapSolver/TraceAnchoredNetLabelOverlapSolver"
|
|
@@ -426,12 +429,17 @@ export class SchematicTracePipelineSolver extends BaseSolver {
|
|
|
426
429
|
const previousOutput =
|
|
427
430
|
instance.preAlignmentNetLabelTraceCollisionSolver!.getOutput()
|
|
428
431
|
const alignmentOutput = instance.traceCleanupSolver2!.getOutput()
|
|
432
|
+
const connectorMovement = moveNetLabelConnectorsToReroutedTraces({
|
|
433
|
+
originalTraces: previousOutput.traces,
|
|
434
|
+
reroutedTraces: alignmentOutput.traces,
|
|
435
|
+
netLabelPlacements: previousOutput.netLabelPlacements,
|
|
436
|
+
})
|
|
429
437
|
const previousTraceMap = new Map(
|
|
430
438
|
previousOutput.traces.map((trace) => [trace.mspPairId, trace]),
|
|
431
439
|
)
|
|
432
|
-
let netLabelPlacements =
|
|
440
|
+
let netLabelPlacements = connectorMovement.netLabelPlacements
|
|
433
441
|
|
|
434
|
-
for (const trace of
|
|
442
|
+
for (const trace of connectorMovement.traces) {
|
|
435
443
|
const previousTrace = previousTraceMap.get(trace.mspPairId)
|
|
436
444
|
if (!previousTrace || previousTrace.tracePath === trace.tracePath) {
|
|
437
445
|
continue
|
|
@@ -455,7 +463,7 @@ export class SchematicTracePipelineSolver extends BaseSolver {
|
|
|
455
463
|
return [
|
|
456
464
|
{
|
|
457
465
|
inputProblem: instance.inputProblem,
|
|
458
|
-
traces:
|
|
466
|
+
traces: connectorMovement.traces,
|
|
459
467
|
netLabelPlacements,
|
|
460
468
|
},
|
|
461
469
|
]
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/schematic-trace-solver",
|
|
3
|
+
"repository": {
|
|
4
|
+
"type": "git",
|
|
5
|
+
"url": "https://github.com/tscircuit/schematic-trace-solver.git"
|
|
6
|
+
},
|
|
3
7
|
"main": "dist/index.js",
|
|
4
|
-
"version": "0.0.
|
|
8
|
+
"version": "0.0.140",
|
|
5
9
|
"type": "module",
|
|
6
10
|
"scripts": {
|
|
7
11
|
"start": "cosmos",
|