@tscircuit/schematic-trace-solver 0.0.121 → 0.0.123
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 +10 -3
- package/dist/index.js +247 -31
- package/lib/solvers/RailNetLabelCornerPlacementSolver/RailNetLabelCornerPlacementSolver.ts +223 -21
- package/lib/solvers/RailNetLabelCornerPlacementSolver/types.ts +3 -3
- package/lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions.ts +50 -5
- package/lib/solvers/SameNetJunctionAlignmentSolver/pathIntersectsAnyNetLabel.ts +29 -0
- package/lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver.ts +34 -9
- package/package.json +1 -1
- package/site/bug-reports/bug-report-20260804T095800Z.page.tsx +4 -0
- package/site/bug-reports/bug-report-20260804T171919Z.page.tsx +4 -0
- package/site/bug-reports/bug-report-20260804T225912Z.page.tsx +4 -0
- package/tests/bug-reports/bug-report-20260706T213649Z/__snapshots__/bug-report-20260706T213649Z.snap.svg +4 -4
- package/tests/bug-reports/bug-report-20260706T220324Z/__snapshots__/bug-report-20260706T220324Z.snap.svg +5 -5
- package/tests/bug-reports/bug-report-20260717T042845Z/__snapshots__/bug-report-20260717T042845Z.snap.svg +12 -12
- package/tests/bug-reports/bug-report-20260721T221026Z/__snapshots__/bug-report-20260721T221026Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260728T144234Z/__snapshots__/bug-report-20260728T144234Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260804T095800Z/__snapshots__/bug-report-20260804T095800Z.snap.svg +135 -0
- package/tests/bug-reports/bug-report-20260804T095800Z/bug-report-20260804T095800Z.json +634 -0
- package/tests/bug-reports/bug-report-20260804T095800Z/bug-report-20260804T095800Z.test.ts +12 -0
- package/tests/bug-reports/bug-report-20260804T171919Z/__snapshots__/bug-report-20260804T171919Z.snap.svg +355 -0
- package/tests/bug-reports/bug-report-20260804T171919Z/bug-report-20260804T171919Z.json +1775 -0
- package/tests/bug-reports/bug-report-20260804T171919Z/bug-report-20260804T171919Z.test.ts +12 -0
- package/tests/bug-reports/bug-report-20260804T225912Z/__snapshots__/bug-report-20260804T225912Z.snap.svg +60 -0
- package/tests/bug-reports/bug-report-20260804T225912Z/bug-report-20260804T225912Z.json +148 -0
- package/tests/bug-reports/bug-report-20260804T225912Z/bug-report-20260804T225912Z.test.ts +12 -0
- package/tests/examples/__snapshots__/example12.snap.svg +2 -2
- package/tests/examples/__snapshots__/example13.snap.svg +4 -4
- package/tests/examples/__snapshots__/example14.snap.svg +36 -36
- package/tests/examples/__snapshots__/example31.snap.svg +6 -6
- package/tests/examples/__snapshots__/example43.snap.svg +2 -2
- package/tests/examples/__snapshots__/example44.snap.svg +2 -2
- package/tests/repros/__snapshots__/board-15984-same-net-junction.snap.svg +2 -2
- package/tests/repros/__snapshots__/bugreport-001-gnd-overlap.snap.svg +26 -26
- package/tests/repros/__snapshots__/netlabel-connector-through-rail-label.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-atmega328p-fault-pullup.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-atmega328p-missing-gnd-netlabel.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-bq25895-cross-net-trace-overlap.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-missing-trace-netlabel.snap.svg +18 -18
- package/tests/repros/__snapshots__/repro-netlabel-overlap-trace.snap.svg +3 -3
- package/tests/repros/__snapshots__/repro-nrf52810-clock-routing.snap.svg +82 -0
- package/tests/repros/__snapshots__/repro161-power-section-autolayout.snap.svg +112 -0
- package/tests/repros/assets/repro-nrf52810-clock-routing.input.json +234 -0
- package/tests/repros/assets/repro161-power-section-autolayout.input.json +578 -0
- package/tests/repros/repro-bq25895-cross-net-trace-overlap.test.ts +13 -0
- package/tests/repros/repro-missing-trace-netlabel.test.ts +12 -0
- package/tests/repros/repro-netlabel-overlap-trace.test.ts +38 -0
- package/tests/repros/repro-nrf52810-clock-routing.test.ts +28 -0
- package/tests/repros/repro161-power-section-autolayout.test.ts +34 -0
package/dist/index.d.ts
CHANGED
|
@@ -828,11 +828,11 @@ type TraceCornerCandidate = {
|
|
|
828
828
|
traceId: string;
|
|
829
829
|
distance: number;
|
|
830
830
|
/**
|
|
831
|
-
* True when the corner
|
|
832
|
-
*
|
|
833
|
-
* a clean stub off that pin rather than floating over a mid-trace bend.
|
|
831
|
+
* True when the corner is on a vertical rail that connects directly to one
|
|
832
|
+
* of the trace's endpoint pins, rather than on an arbitrary middle bend.
|
|
834
833
|
*/
|
|
835
834
|
pinAligned: boolean;
|
|
835
|
+
reroutedTracePath?: Point[];
|
|
836
836
|
};
|
|
837
837
|
type CornerCandidateStatus = "valid" | "chip-collision" | "text-collision" | "trace-collision" | "netlabel-collision";
|
|
838
838
|
type EvaluatedCornerCandidate = TraceCornerCandidate & {
|
|
@@ -859,6 +859,7 @@ declare class RailNetLabelCornerPlacementSolver extends BaseSolver {
|
|
|
859
859
|
getConstructorParams(): ConstructorParameters<typeof RailNetLabelCornerPlacementSolver>[0];
|
|
860
860
|
_step(): void;
|
|
861
861
|
getOutput(): {
|
|
862
|
+
traces: SolvedTracePath[];
|
|
862
863
|
netLabelPlacements: NetLabelPlacement[];
|
|
863
864
|
};
|
|
864
865
|
private getProcessableLabelIndices;
|
|
@@ -873,6 +874,12 @@ declare class RailNetLabelCornerPlacementSolver extends BaseSolver {
|
|
|
873
874
|
private intersectsAnyChip;
|
|
874
875
|
private intersectsAnyOtherNetLabel;
|
|
875
876
|
private getCornerCandidatesForLabel;
|
|
877
|
+
private isConfiguredRailLabel;
|
|
878
|
+
private pointsEqual;
|
|
879
|
+
private getVerticalSegmentPointIndices;
|
|
880
|
+
private isPinAlignedCorner;
|
|
881
|
+
private getClearanceShiftedCornerCandidates;
|
|
882
|
+
private isReroutedTraceClear;
|
|
876
883
|
private getTraceLinesForLabel;
|
|
877
884
|
private isTraceForLabel;
|
|
878
885
|
visualize(): GraphicsObject;
|
package/dist/index.js
CHANGED
|
@@ -9052,6 +9052,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9052
9052
|
}
|
|
9053
9053
|
getOutput() {
|
|
9054
9054
|
return {
|
|
9055
|
+
traces: this.traces,
|
|
9055
9056
|
netLabelPlacements: this.outputNetLabelPlacements
|
|
9056
9057
|
};
|
|
9057
9058
|
}
|
|
@@ -9104,15 +9105,25 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9104
9105
|
center,
|
|
9105
9106
|
width: label.width,
|
|
9106
9107
|
height: label.height,
|
|
9107
|
-
status: this.getCandidateStatus(bounds, labelIndex),
|
|
9108
|
+
status: this.getCandidateStatus(bounds, labelIndex, candidate),
|
|
9108
9109
|
selected: false
|
|
9109
9110
|
};
|
|
9110
9111
|
}
|
|
9111
|
-
getCandidateStatus(bounds, labelIndex) {
|
|
9112
|
+
getCandidateStatus(bounds, labelIndex, candidate) {
|
|
9112
9113
|
if (this.intersectsAnyChip(bounds)) return "chip-collision";
|
|
9113
9114
|
if (rectIntersectsAnyTextBox(bounds, this.inputProblem))
|
|
9114
9115
|
return "text-collision";
|
|
9115
|
-
|
|
9116
|
+
const candidateTraceMap = candidate.reroutedTracePath ? {
|
|
9117
|
+
...this.traceMap,
|
|
9118
|
+
[candidate.traceId]: {
|
|
9119
|
+
...this.traceMap[candidate.traceId],
|
|
9120
|
+
tracePath: candidate.reroutedTracePath
|
|
9121
|
+
}
|
|
9122
|
+
} : this.traceMap;
|
|
9123
|
+
if (traceCrossesBoundsInterior(bounds, candidateTraceMap)) {
|
|
9124
|
+
return "trace-collision";
|
|
9125
|
+
}
|
|
9126
|
+
if (candidate.reroutedTracePath && !this.isReroutedTraceClear(candidate, labelIndex)) {
|
|
9116
9127
|
return "trace-collision";
|
|
9117
9128
|
}
|
|
9118
9129
|
if (this.intersectsAnyOtherNetLabel(bounds, labelIndex)) {
|
|
@@ -9121,6 +9132,23 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9121
9132
|
return "valid";
|
|
9122
9133
|
}
|
|
9123
9134
|
applyCandidate(labelIndex, label, candidate) {
|
|
9135
|
+
if (candidate.reroutedTracePath) {
|
|
9136
|
+
const originalTrace = this.traceMap[candidate.traceId];
|
|
9137
|
+
const reroutedTrace = {
|
|
9138
|
+
...originalTrace,
|
|
9139
|
+
tracePath: candidate.reroutedTracePath
|
|
9140
|
+
};
|
|
9141
|
+
this.traces = this.traces.map(
|
|
9142
|
+
(trace) => trace.mspPairId === candidate.traceId ? reroutedTrace : trace
|
|
9143
|
+
);
|
|
9144
|
+
this.traceMap[candidate.traceId] = reroutedTrace;
|
|
9145
|
+
this.outputNetLabelPlacements = moveAttachedLabelsToReroutedTrace({
|
|
9146
|
+
trace: originalTrace,
|
|
9147
|
+
originalTracePath: originalTrace.tracePath,
|
|
9148
|
+
reroutedTracePath: candidate.reroutedTracePath,
|
|
9149
|
+
netLabelPlacements: this.outputNetLabelPlacements
|
|
9150
|
+
});
|
|
9151
|
+
}
|
|
9124
9152
|
this.outputNetLabelPlacements[labelIndex] = {
|
|
9125
9153
|
...label,
|
|
9126
9154
|
anchorPoint: candidate.anchorPoint,
|
|
@@ -9146,30 +9174,152 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
9146
9174
|
});
|
|
9147
9175
|
}
|
|
9148
9176
|
getCornerCandidatesForLabel(label) {
|
|
9149
|
-
const
|
|
9150
|
-
const
|
|
9151
|
-
const
|
|
9152
|
-
|
|
9177
|
+
const anchorAlignedCandidates = [];
|
|
9178
|
+
const railAlignedCandidates = [];
|
|
9179
|
+
const labelTraces = this.getTraceLinesForLabel(label);
|
|
9180
|
+
const allowRailAlignedFallback = this.isConfiguredRailLabel(label) && !labelTraces.some(
|
|
9181
|
+
(trace) => getTraceCorners(trace.tracePath).some(
|
|
9182
|
+
(corner) => this.pointsEqual(corner, label.anchorPoint)
|
|
9183
|
+
)
|
|
9184
|
+
);
|
|
9185
|
+
for (const trace of labelTraces) {
|
|
9153
9186
|
const path = trace.tracePath;
|
|
9154
9187
|
const pins = [path[0], path[path.length - 1]];
|
|
9155
9188
|
for (const anchorPoint of getTraceCorners(path)) {
|
|
9156
|
-
const
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
return Math.abs(pin.y - anchorPoint.y) < EPS6;
|
|
9162
|
-
});
|
|
9189
|
+
const cornerIndex = path.indexOf(anchorPoint);
|
|
9190
|
+
const anchorAlignedToPin = pins.some(
|
|
9191
|
+
(pin) => Math.abs(pin.x - anchorPoint.x) <= EPS6
|
|
9192
|
+
);
|
|
9193
|
+
const pinAligned = anchorAlignedToPin || allowRailAlignedFallback && this.isPinAlignedCorner(path, cornerIndex);
|
|
9163
9194
|
if (!pinAligned) continue;
|
|
9164
|
-
candidates
|
|
9195
|
+
const candidates = anchorAlignedToPin ? anchorAlignedCandidates : railAlignedCandidates;
|
|
9196
|
+
candidates.push(
|
|
9197
|
+
{
|
|
9198
|
+
anchorPoint,
|
|
9199
|
+
traceId: trace.mspPairId,
|
|
9200
|
+
distance: getDistance(anchorPoint, label.anchorPoint),
|
|
9201
|
+
pinAligned
|
|
9202
|
+
},
|
|
9203
|
+
...this.getClearanceShiftedCornerCandidates({
|
|
9204
|
+
label,
|
|
9205
|
+
trace,
|
|
9206
|
+
cornerIndex,
|
|
9207
|
+
pinAligned
|
|
9208
|
+
})
|
|
9209
|
+
);
|
|
9210
|
+
}
|
|
9211
|
+
}
|
|
9212
|
+
return [
|
|
9213
|
+
...anchorAlignedCandidates.sort((a, b) => a.distance - b.distance),
|
|
9214
|
+
...railAlignedCandidates.sort((a, b) => a.distance - b.distance)
|
|
9215
|
+
];
|
|
9216
|
+
}
|
|
9217
|
+
isConfiguredRailLabel(label) {
|
|
9218
|
+
if (!label.netId) return false;
|
|
9219
|
+
return this.inputProblem.availableNetLabelOrientations[label.netId]?.some(
|
|
9220
|
+
(orientation) => orientation === "y+" || orientation === "y-"
|
|
9221
|
+
);
|
|
9222
|
+
}
|
|
9223
|
+
pointsEqual(a, b) {
|
|
9224
|
+
return Math.abs(a.x - b.x) <= EPS6 && Math.abs(a.y - b.y) <= EPS6;
|
|
9225
|
+
}
|
|
9226
|
+
getVerticalSegmentPointIndices(path, cornerIndex) {
|
|
9227
|
+
const corner = path[cornerIndex];
|
|
9228
|
+
const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <= EPS6;
|
|
9229
|
+
const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <= EPS6;
|
|
9230
|
+
if (previousIsVertical === nextIsVertical) return null;
|
|
9231
|
+
const indices = previousIsVertical ? [cornerIndex - 1, cornerIndex] : [cornerIndex, cornerIndex + 1];
|
|
9232
|
+
return indices;
|
|
9233
|
+
}
|
|
9234
|
+
isPinAlignedCorner(path, cornerIndex) {
|
|
9235
|
+
const verticalPointIndices = this.getVerticalSegmentPointIndices(
|
|
9236
|
+
path,
|
|
9237
|
+
cornerIndex
|
|
9238
|
+
);
|
|
9239
|
+
if (!verticalPointIndices) return false;
|
|
9240
|
+
const [startIndex, endIndex] = verticalPointIndices;
|
|
9241
|
+
return startIndex <= 1 || endIndex >= path.length - 2;
|
|
9242
|
+
}
|
|
9243
|
+
getClearanceShiftedCornerCandidates({
|
|
9244
|
+
label,
|
|
9245
|
+
trace,
|
|
9246
|
+
cornerIndex,
|
|
9247
|
+
pinAligned
|
|
9248
|
+
}) {
|
|
9249
|
+
if (label.orientation !== "y+" && label.orientation !== "y-") return [];
|
|
9250
|
+
const path = trace.tracePath;
|
|
9251
|
+
const corner = path[cornerIndex];
|
|
9252
|
+
const verticalPointIndices = this.getVerticalSegmentPointIndices(
|
|
9253
|
+
path,
|
|
9254
|
+
cornerIndex
|
|
9255
|
+
);
|
|
9256
|
+
if (!verticalPointIndices || verticalPointIndices.includes(0) || verticalPointIndices.includes(path.length - 1)) {
|
|
9257
|
+
return [];
|
|
9258
|
+
}
|
|
9259
|
+
const center = getCenterFromAnchor(
|
|
9260
|
+
corner,
|
|
9261
|
+
label.orientation,
|
|
9262
|
+
label.width,
|
|
9263
|
+
label.height
|
|
9264
|
+
);
|
|
9265
|
+
const labelBounds = getRectBounds(center, label.width, label.height);
|
|
9266
|
+
const collidingChipBounds = this.inputProblem.chips.map((chip) => getRectBounds(chip.center, chip.width, chip.height)).filter((chipBounds) => rectsOverlap(labelBounds, chipBounds));
|
|
9267
|
+
const shiftedCoordinates = /* @__PURE__ */ new Set();
|
|
9268
|
+
for (const chipBounds of collidingChipBounds) {
|
|
9269
|
+
shiftedCoordinates.add(chipBounds.minX - label.width / 2);
|
|
9270
|
+
shiftedCoordinates.add(chipBounds.maxX + label.width / 2);
|
|
9271
|
+
}
|
|
9272
|
+
return [...shiftedCoordinates].flatMap((x) => {
|
|
9273
|
+
if (Math.abs(x - corner.x) <= EPS6) return [];
|
|
9274
|
+
const reroutedTracePath = simplifyPath(
|
|
9275
|
+
path.map(
|
|
9276
|
+
(point, pointIndex) => verticalPointIndices.includes(pointIndex) ? { ...point, x } : point
|
|
9277
|
+
)
|
|
9278
|
+
);
|
|
9279
|
+
const anchorPoint = { x, y: corner.y };
|
|
9280
|
+
const remainsCorner = getTraceCorners(reroutedTracePath).some(
|
|
9281
|
+
(point) => this.pointsEqual(point, anchorPoint)
|
|
9282
|
+
);
|
|
9283
|
+
if (!remainsCorner) return [];
|
|
9284
|
+
return [
|
|
9285
|
+
{
|
|
9165
9286
|
anchorPoint,
|
|
9166
9287
|
traceId: trace.mspPairId,
|
|
9167
9288
|
distance: getDistance(anchorPoint, label.anchorPoint),
|
|
9168
|
-
pinAligned
|
|
9169
|
-
|
|
9170
|
-
|
|
9289
|
+
pinAligned,
|
|
9290
|
+
reroutedTracePath
|
|
9291
|
+
}
|
|
9292
|
+
];
|
|
9293
|
+
});
|
|
9294
|
+
}
|
|
9295
|
+
isReroutedTraceClear(candidate, labelIndex) {
|
|
9296
|
+
const reroutedTracePath = candidate.reroutedTracePath;
|
|
9297
|
+
if (isPathCollidingWithObstacles(
|
|
9298
|
+
reroutedTracePath,
|
|
9299
|
+
getObstacleRects(this.inputProblem)
|
|
9300
|
+
)) {
|
|
9301
|
+
return false;
|
|
9302
|
+
}
|
|
9303
|
+
const candidateTrace = this.traceMap[candidate.traceId];
|
|
9304
|
+
const otherNetTraces = this.traces.filter(
|
|
9305
|
+
(trace) => trace.mspPairId !== candidate.traceId && trace.globalConnNetId !== candidateTrace.globalConnNetId
|
|
9306
|
+
);
|
|
9307
|
+
if (doesPathOverlapTraceStrokes(reroutedTracePath, otherNetTraces)) {
|
|
9308
|
+
return false;
|
|
9171
9309
|
}
|
|
9172
|
-
|
|
9310
|
+
const reroutedTraceMap = {
|
|
9311
|
+
[candidate.traceId]: {
|
|
9312
|
+
...candidateTrace,
|
|
9313
|
+
tracePath: reroutedTracePath
|
|
9314
|
+
}
|
|
9315
|
+
};
|
|
9316
|
+
return this.outputNetLabelPlacements.every((label, index) => {
|
|
9317
|
+
if (index === labelIndex) return true;
|
|
9318
|
+
return !traceCrossesBoundsInterior(
|
|
9319
|
+
getRectBounds(label.center, label.width, label.height),
|
|
9320
|
+
reroutedTraceMap
|
|
9321
|
+
);
|
|
9322
|
+
});
|
|
9173
9323
|
}
|
|
9174
9324
|
getTraceLinesForLabel(label) {
|
|
9175
9325
|
return this.traces.filter(
|
|
@@ -11031,6 +11181,7 @@ var UnroutedTraceRecoverySolver = class extends BaseSolver {
|
|
|
11031
11181
|
};
|
|
11032
11182
|
|
|
11033
11183
|
// lib/solvers/SameNetJunctionAlignmentSolver/pathIntersectsAnyNetLabel.ts
|
|
11184
|
+
var NET_LABEL_INTERIOR_INSET = 1e-6;
|
|
11034
11185
|
var pathIntersectsAnyNetLabel = ({
|
|
11035
11186
|
path,
|
|
11036
11187
|
netLabelPlacements
|
|
@@ -11045,9 +11196,30 @@ var pathIntersectsAnyNetLabel = ({
|
|
|
11045
11196
|
}
|
|
11046
11197
|
return false;
|
|
11047
11198
|
};
|
|
11199
|
+
var pathEntersAnyNetLabel = ({
|
|
11200
|
+
path,
|
|
11201
|
+
netLabelPlacements
|
|
11202
|
+
}) => {
|
|
11203
|
+
for (const label of netLabelPlacements) {
|
|
11204
|
+
const labelBounds = getRectBounds(label.center, label.width, label.height);
|
|
11205
|
+
const labelInteriorBounds = {
|
|
11206
|
+
minX: labelBounds.minX + NET_LABEL_INTERIOR_INSET,
|
|
11207
|
+
minY: labelBounds.minY + NET_LABEL_INTERIOR_INSET,
|
|
11208
|
+
maxX: labelBounds.maxX - NET_LABEL_INTERIOR_INSET,
|
|
11209
|
+
maxY: labelBounds.maxY - NET_LABEL_INTERIOR_INSET
|
|
11210
|
+
};
|
|
11211
|
+
for (let index = 0; index < path.length - 1; index++) {
|
|
11212
|
+
if (segmentIntersectsRect2(path[index], path[index + 1], labelInteriorBounds)) {
|
|
11213
|
+
return true;
|
|
11214
|
+
}
|
|
11215
|
+
}
|
|
11216
|
+
}
|
|
11217
|
+
return false;
|
|
11218
|
+
};
|
|
11048
11219
|
|
|
11049
11220
|
// lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions.ts
|
|
11050
11221
|
var MAX_ALIGNED_LOAD_PIN_OFFSET = 0.2;
|
|
11222
|
+
var MAX_SAME_NET_LABEL_BOUNDARY_RAIL_OFFSET = 0.2;
|
|
11051
11223
|
var getSharedPin = ({
|
|
11052
11224
|
donorTrace,
|
|
11053
11225
|
branchTrace
|
|
@@ -11124,6 +11296,7 @@ var getAlignedBranchPath = ({
|
|
|
11124
11296
|
};
|
|
11125
11297
|
var candidateIsClear = ({
|
|
11126
11298
|
candidateTrace,
|
|
11299
|
+
originalTrace,
|
|
11127
11300
|
traces,
|
|
11128
11301
|
inputProblem,
|
|
11129
11302
|
netLabelPlacements
|
|
@@ -11138,10 +11311,34 @@ var candidateIsClear = ({
|
|
|
11138
11311
|
if (doesPathCoincideWithTraces(candidateTrace.tracePath, otherNetTraces)) {
|
|
11139
11312
|
return false;
|
|
11140
11313
|
}
|
|
11141
|
-
|
|
11314
|
+
const otherNetLabelPlacements = netLabelPlacements.filter(
|
|
11315
|
+
(label) => label.globalConnNetId !== candidateTrace.globalConnNetId
|
|
11316
|
+
);
|
|
11317
|
+
if (pathIntersectsAnyNetLabel({
|
|
11318
|
+
path: candidateTrace.tracePath,
|
|
11319
|
+
netLabelPlacements: otherNetLabelPlacements
|
|
11320
|
+
})) {
|
|
11321
|
+
return false;
|
|
11322
|
+
}
|
|
11323
|
+
const sameNetLabelPlacements = netLabelPlacements.filter(
|
|
11324
|
+
(label) => label.globalConnNetId === candidateTrace.globalConnNetId
|
|
11325
|
+
);
|
|
11326
|
+
if (!pathIntersectsAnyNetLabel({
|
|
11142
11327
|
path: candidateTrace.tracePath,
|
|
11143
|
-
netLabelPlacements
|
|
11144
|
-
})
|
|
11328
|
+
netLabelPlacements: sameNetLabelPlacements
|
|
11329
|
+
})) {
|
|
11330
|
+
return true;
|
|
11331
|
+
}
|
|
11332
|
+
if (pathEntersAnyNetLabel({
|
|
11333
|
+
path: candidateTrace.tracePath,
|
|
11334
|
+
netLabelPlacements: sameNetLabelPlacements
|
|
11335
|
+
})) {
|
|
11336
|
+
return false;
|
|
11337
|
+
}
|
|
11338
|
+
const originalRail = getLongestHorizontalSegment(originalTrace);
|
|
11339
|
+
const candidateRail = getLongestHorizontalSegment(candidateTrace);
|
|
11340
|
+
if (!originalRail || !candidateRail) return false;
|
|
11341
|
+
return Math.abs(originalRail.start.y - candidateRail.start.y) <= MAX_SAME_NET_LABEL_BOUNDARY_RAIL_OFFSET;
|
|
11145
11342
|
};
|
|
11146
11343
|
var alignSameNetJunctions = ({
|
|
11147
11344
|
inputProblem,
|
|
@@ -11174,6 +11371,7 @@ var alignSameNetJunctions = ({
|
|
|
11174
11371
|
}
|
|
11175
11372
|
if (!candidateIsClear({
|
|
11176
11373
|
candidateTrace,
|
|
11374
|
+
originalTrace: branchTrace,
|
|
11177
11375
|
traces: outputTraces,
|
|
11178
11376
|
inputProblem,
|
|
11179
11377
|
netLabelPlacements
|
|
@@ -11484,9 +11682,7 @@ var SchematicTracePipelineSolver = class extends BaseSolver {
|
|
|
11484
11682
|
(instance) => [
|
|
11485
11683
|
{
|
|
11486
11684
|
inputProblem: instance.inputProblem,
|
|
11487
|
-
traces:
|
|
11488
|
-
instance.postLabelTraceOverlapShiftSolver.correctedTraceMap
|
|
11489
|
-
),
|
|
11685
|
+
traces: instance.railNetLabelCornerPlacementSolver.getOutput().traces,
|
|
11490
11686
|
netLabelPlacements: instance.railNetLabelCornerPlacementSolver.outputNetLabelPlacements
|
|
11491
11687
|
}
|
|
11492
11688
|
]
|
|
@@ -11497,9 +11693,7 @@ var SchematicTracePipelineSolver = class extends BaseSolver {
|
|
|
11497
11693
|
(instance) => [
|
|
11498
11694
|
{
|
|
11499
11695
|
inputProblem: instance.inputProblem,
|
|
11500
|
-
traces:
|
|
11501
|
-
instance.postLabelTraceOverlapShiftSolver.correctedTraceMap
|
|
11502
|
-
),
|
|
11696
|
+
traces: instance.railNetLabelCornerPlacementSolver.getOutput().traces,
|
|
11503
11697
|
netLabelPlacements: instance.traceAnchoredNetLabelOverlapSolver.outputNetLabelPlacements
|
|
11504
11698
|
}
|
|
11505
11699
|
]
|
|
@@ -11529,12 +11723,34 @@ var SchematicTracePipelineSolver = class extends BaseSolver {
|
|
|
11529
11723
|
"netLabelTraceCollisionSolver",
|
|
11530
11724
|
NetLabelTraceCollisionSolver,
|
|
11531
11725
|
(instance) => {
|
|
11532
|
-
const
|
|
11726
|
+
const previousOutput = instance.preAlignmentNetLabelTraceCollisionSolver.getOutput();
|
|
11727
|
+
const alignmentOutput = instance.traceCleanupSolver2.getOutput();
|
|
11728
|
+
const previousTraceMap = new Map(
|
|
11729
|
+
previousOutput.traces.map((trace) => [trace.mspPairId, trace])
|
|
11730
|
+
);
|
|
11731
|
+
let netLabelPlacements = previousOutput.netLabelPlacements;
|
|
11732
|
+
for (const trace of alignmentOutput.traces) {
|
|
11733
|
+
const previousTrace = previousTraceMap.get(trace.mspPairId);
|
|
11734
|
+
if (!previousTrace || previousTrace.tracePath === trace.tracePath) {
|
|
11735
|
+
continue;
|
|
11736
|
+
}
|
|
11737
|
+
const currentLabels = netLabelPlacements;
|
|
11738
|
+
const movedLabels = moveAttachedLabelsToReroutedTrace({
|
|
11739
|
+
trace: previousTrace,
|
|
11740
|
+
originalTracePath: previousTrace.tracePath,
|
|
11741
|
+
reroutedTracePath: trace.tracePath,
|
|
11742
|
+
netLabelPlacements: currentLabels
|
|
11743
|
+
});
|
|
11744
|
+
netLabelPlacements = movedLabels.map((movedLabel, labelIndex) => {
|
|
11745
|
+
const label = currentLabels[labelIndex];
|
|
11746
|
+
return label.orientation === "y+" || label.orientation === "y-" ? movedLabel : label;
|
|
11747
|
+
});
|
|
11748
|
+
}
|
|
11533
11749
|
return [
|
|
11534
11750
|
{
|
|
11535
11751
|
inputProblem: instance.inputProblem,
|
|
11536
|
-
traces:
|
|
11537
|
-
netLabelPlacements
|
|
11752
|
+
traces: alignmentOutput.traces,
|
|
11753
|
+
netLabelPlacements
|
|
11538
11754
|
}
|
|
11539
11755
|
];
|
|
11540
11756
|
}
|