@tscircuit/schematic-trace-solver 0.0.198 → 0.0.200
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 +57 -4
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +10 -1
- package/lib/solvers/UnroutedTraceRecoverySolver/UnroutedTraceRecoverySolver.ts +69 -0
- package/package.json +1 -1
- package/site/bug-reports/bug-report-20260916T054012Z.page.tsx +4 -0
- package/tests/bug-reports/bug-report-20260916T054012Z/__snapshots__/bug-report-20260916T054012Z.snap.svg +504 -0
- package/tests/bug-reports/bug-report-20260916T054012Z/bug-report-20260916T054012Z.json +1847 -0
- package/tests/bug-reports/bug-report-20260916T054012Z/bug-report-20260916T054012Z.test.ts +28 -0
- package/tests/repros/__snapshots__/repro-acoustic-tuner-parallel-vref-traces.snap.svg +585 -0
- package/tests/repros/assets/repro-acoustic-tuner-parallel-vref-traces.input.json +1484 -0
- package/tests/repros/repro-acoustic-tuner-parallel-vref-traces.test.ts +50 -0
- package/tests/solvers/UnroutedTraceRecoverySolver/skip-connected-pair.test.ts +80 -0
package/dist/index.js
CHANGED
|
@@ -10274,7 +10274,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10274
10274
|
result.selected = true;
|
|
10275
10275
|
return result;
|
|
10276
10276
|
}
|
|
10277
|
-
if (stopOnTraceCollision && result.status === "trace-collision")
|
|
10277
|
+
if (stopOnTraceCollision && result.status === "trace-collision" && (!projectedConnectorSource || orientation !== "y-" || !this.isGroundLabel(label)))
|
|
10278
|
+
break;
|
|
10278
10279
|
}
|
|
10279
10280
|
return null;
|
|
10280
10281
|
}
|
|
@@ -13242,6 +13243,52 @@ var getUnconnectedPins = ({
|
|
|
13242
13243
|
);
|
|
13243
13244
|
return connectionPair.pins.filter((pin) => !connectedPinIds.has(pin.pinId));
|
|
13244
13245
|
};
|
|
13246
|
+
var pathsIntersect = (firstPath, secondPath) => {
|
|
13247
|
+
for (let firstIndex = 0; firstIndex < firstPath.length - 1; firstIndex++) {
|
|
13248
|
+
for (let secondIndex = 0; secondIndex < secondPath.length - 1; secondIndex++) {
|
|
13249
|
+
if (doSegmentsIntersect3(
|
|
13250
|
+
firstPath[firstIndex],
|
|
13251
|
+
firstPath[firstIndex + 1],
|
|
13252
|
+
secondPath[secondIndex],
|
|
13253
|
+
secondPath[secondIndex + 1]
|
|
13254
|
+
)) {
|
|
13255
|
+
return true;
|
|
13256
|
+
}
|
|
13257
|
+
}
|
|
13258
|
+
}
|
|
13259
|
+
return false;
|
|
13260
|
+
};
|
|
13261
|
+
var connectionPairPinsAreAlreadyConnected = ({
|
|
13262
|
+
connectionPair,
|
|
13263
|
+
sameNetTraces
|
|
13264
|
+
}) => {
|
|
13265
|
+
const [firstPin, secondPin] = connectionPair.pins;
|
|
13266
|
+
const connectedTraceIndexes = new Set(
|
|
13267
|
+
sameNetTraces.flatMap(
|
|
13268
|
+
(trace, index) => trace.pinIds.includes(firstPin.pinId) ? [index] : []
|
|
13269
|
+
)
|
|
13270
|
+
);
|
|
13271
|
+
let previousSize = -1;
|
|
13272
|
+
while (connectedTraceIndexes.size !== previousSize) {
|
|
13273
|
+
previousSize = connectedTraceIndexes.size;
|
|
13274
|
+
for (let traceIndex = 0; traceIndex < sameNetTraces.length; traceIndex++) {
|
|
13275
|
+
if (connectedTraceIndexes.has(traceIndex)) continue;
|
|
13276
|
+
const trace = sameNetTraces[traceIndex];
|
|
13277
|
+
const connectsToComponent = [...connectedTraceIndexes].some(
|
|
13278
|
+
(connectedTraceIndex) => {
|
|
13279
|
+
const connectedTrace = sameNetTraces[connectedTraceIndex];
|
|
13280
|
+
return trace.pinIds.some(
|
|
13281
|
+
(pinId) => connectedTrace.pinIds.includes(pinId)
|
|
13282
|
+
) || pathsIntersect(trace.tracePath, connectedTrace.tracePath);
|
|
13283
|
+
}
|
|
13284
|
+
);
|
|
13285
|
+
if (connectsToComponent) connectedTraceIndexes.add(traceIndex);
|
|
13286
|
+
}
|
|
13287
|
+
}
|
|
13288
|
+
return [...connectedTraceIndexes].some(
|
|
13289
|
+
(traceIndex) => sameNetTraces[traceIndex].pinIds.includes(secondPin.pinId)
|
|
13290
|
+
);
|
|
13291
|
+
};
|
|
13245
13292
|
var getJunctionCandidates = ({
|
|
13246
13293
|
connectionPair,
|
|
13247
13294
|
sameNetTraces,
|
|
@@ -13506,6 +13553,12 @@ var UnroutedTraceRecoverySolver = class extends BaseSolver {
|
|
|
13506
13553
|
const sameNetTraces = existingTraces.filter(
|
|
13507
13554
|
(trace) => trace.globalConnNetId === connectionPair.globalConnNetId
|
|
13508
13555
|
);
|
|
13556
|
+
if (connectionPairPinsAreAlreadyConnected({
|
|
13557
|
+
connectionPair,
|
|
13558
|
+
sameNetTraces
|
|
13559
|
+
})) {
|
|
13560
|
+
return;
|
|
13561
|
+
}
|
|
13509
13562
|
const junctionCandidates = getJunctionCandidates({
|
|
13510
13563
|
connectionPair,
|
|
13511
13564
|
sameNetTraces,
|
|
@@ -14518,7 +14571,7 @@ var getAlignedAttachedLabelConnectorPath = ({
|
|
|
14518
14571
|
const reverseCandidate = findCandidate([...forwardPath].reverse());
|
|
14519
14572
|
return reverseCandidate ? reverseCandidate.reverse() : null;
|
|
14520
14573
|
};
|
|
14521
|
-
var
|
|
14574
|
+
var pathsIntersect2 = (firstPath, secondPath) => {
|
|
14522
14575
|
if (firstPath.some((point) => tracePathContainsPoint(secondPath, point)) || secondPath.some((point) => tracePathContainsPoint(firstPath, point))) {
|
|
14523
14576
|
return true;
|
|
14524
14577
|
}
|
|
@@ -14545,7 +14598,7 @@ var preserveAttachedTraceJunctions = ({
|
|
|
14545
14598
|
(trace) => trace.mspPairId === originalTrace.mspPairId ? candidateTrace : trace
|
|
14546
14599
|
);
|
|
14547
14600
|
for (const connector of traces) {
|
|
14548
|
-
if (connector.mspPairId === originalTrace.mspPairId || connector.globalConnNetId !== originalTrace.globalConnNetId || !
|
|
14601
|
+
if (connector.mspPairId === originalTrace.mspPairId || connector.globalConnNetId !== originalTrace.globalConnNetId || !pathsIntersect2(originalTrace.tracePath, connector.tracePath) || pathsIntersect2(candidateTrace.tracePath, connector.tracePath)) {
|
|
14549
14602
|
continue;
|
|
14550
14603
|
}
|
|
14551
14604
|
const endpointIndex = [0, connector.tracePath.length - 1].find(
|
|
@@ -14578,7 +14631,7 @@ var preserveAttachedTraceJunctions = ({
|
|
|
14578
14631
|
(point, index) => index === endpointIndex ? movedJunction : point
|
|
14579
14632
|
)
|
|
14580
14633
|
};
|
|
14581
|
-
if (!
|
|
14634
|
+
if (!pathsIntersect2(candidateTrace.tracePath, movedConnector.tracePath)) {
|
|
14582
14635
|
return null;
|
|
14583
14636
|
}
|
|
14584
14637
|
outputTraces = outputTraces.map(
|
|
@@ -1172,7 +1172,16 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
1172
1172
|
result.selected = true
|
|
1173
1173
|
return result
|
|
1174
1174
|
}
|
|
1175
|
-
|
|
1175
|
+
// A downward ground branch projected onto its existing trace can reach a
|
|
1176
|
+
// clear position below a crossing trace.
|
|
1177
|
+
if (
|
|
1178
|
+
stopOnTraceCollision &&
|
|
1179
|
+
result.status === "trace-collision" &&
|
|
1180
|
+
(!projectedConnectorSource ||
|
|
1181
|
+
orientation !== "y-" ||
|
|
1182
|
+
!this.isGroundLabel(label))
|
|
1183
|
+
)
|
|
1184
|
+
break
|
|
1176
1185
|
}
|
|
1177
1186
|
|
|
1178
1187
|
return null
|
|
@@ -204,6 +204,67 @@ const getUnconnectedPins = ({
|
|
|
204
204
|
return connectionPair.pins.filter((pin) => !connectedPinIds.has(pin.pinId))
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
const pathsIntersect = (firstPath: Point[], secondPath: Point[]): boolean => {
|
|
208
|
+
for (let firstIndex = 0; firstIndex < firstPath.length - 1; firstIndex++) {
|
|
209
|
+
for (
|
|
210
|
+
let secondIndex = 0;
|
|
211
|
+
secondIndex < secondPath.length - 1;
|
|
212
|
+
secondIndex++
|
|
213
|
+
) {
|
|
214
|
+
if (
|
|
215
|
+
doSegmentsIntersect(
|
|
216
|
+
firstPath[firstIndex]!,
|
|
217
|
+
firstPath[firstIndex + 1]!,
|
|
218
|
+
secondPath[secondIndex]!,
|
|
219
|
+
secondPath[secondIndex + 1]!,
|
|
220
|
+
)
|
|
221
|
+
) {
|
|
222
|
+
return true
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return false
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const connectionPairPinsAreAlreadyConnected = ({
|
|
230
|
+
connectionPair,
|
|
231
|
+
sameNetTraces,
|
|
232
|
+
}: {
|
|
233
|
+
connectionPair: MspConnectionPair
|
|
234
|
+
sameNetTraces: SolvedTracePath[]
|
|
235
|
+
}): boolean => {
|
|
236
|
+
const [firstPin, secondPin] = connectionPair.pins
|
|
237
|
+
const connectedTraceIndexes = new Set(
|
|
238
|
+
sameNetTraces.flatMap((trace, index) =>
|
|
239
|
+
trace.pinIds.includes(firstPin.pinId) ? [index] : [],
|
|
240
|
+
),
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
let previousSize = -1
|
|
244
|
+
while (connectedTraceIndexes.size !== previousSize) {
|
|
245
|
+
previousSize = connectedTraceIndexes.size
|
|
246
|
+
for (let traceIndex = 0; traceIndex < sameNetTraces.length; traceIndex++) {
|
|
247
|
+
if (connectedTraceIndexes.has(traceIndex)) continue
|
|
248
|
+
const trace = sameNetTraces[traceIndex]!
|
|
249
|
+
const connectsToComponent = [...connectedTraceIndexes].some(
|
|
250
|
+
(connectedTraceIndex) => {
|
|
251
|
+
const connectedTrace = sameNetTraces[connectedTraceIndex]!
|
|
252
|
+
return (
|
|
253
|
+
trace.pinIds.some((pinId) =>
|
|
254
|
+
connectedTrace.pinIds.includes(pinId),
|
|
255
|
+
) || pathsIntersect(trace.tracePath, connectedTrace.tracePath)
|
|
256
|
+
)
|
|
257
|
+
},
|
|
258
|
+
)
|
|
259
|
+
if (connectsToComponent) connectedTraceIndexes.add(traceIndex)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return [...connectedTraceIndexes].some((traceIndex) =>
|
|
264
|
+
sameNetTraces[traceIndex]!.pinIds.includes(secondPin.pinId),
|
|
265
|
+
)
|
|
266
|
+
}
|
|
267
|
+
|
|
207
268
|
const getJunctionCandidates = ({
|
|
208
269
|
connectionPair,
|
|
209
270
|
sameNetTraces,
|
|
@@ -552,6 +613,14 @@ export class UnroutedTraceRecoverySolver extends BaseSolver {
|
|
|
552
613
|
const sameNetTraces = existingTraces.filter(
|
|
553
614
|
(trace) => trace.globalConnNetId === connectionPair.globalConnNetId,
|
|
554
615
|
)
|
|
616
|
+
if (
|
|
617
|
+
connectionPairPinsAreAlreadyConnected({
|
|
618
|
+
connectionPair,
|
|
619
|
+
sameNetTraces,
|
|
620
|
+
})
|
|
621
|
+
) {
|
|
622
|
+
return
|
|
623
|
+
}
|
|
555
624
|
const junctionCandidates = getJunctionCandidates({
|
|
556
625
|
connectionPair,
|
|
557
626
|
sameNetTraces,
|
package/package.json
CHANGED