@tscircuit/schematic-trace-solver 0.0.142 → 0.0.143
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 +1 -0
- package/dist/index.js +68 -16
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +92 -16
- package/package.json +1 -1
- package/tests/bug-reports/bug-report-20260721T221026Z/__snapshots__/bug-report-20260721T221026Z.snap.svg +3 -3
- package/tests/repros/__snapshots__/repro-tida010076-page02.snap.svg +3 -3
- package/tests/repros/repro-tida010076-page02.test.ts +19 -0
- package/tests/repros/repro-usb-power-vbus-label-detour.test.ts +23 -1
package/dist/index.d.ts
CHANGED
|
@@ -825,6 +825,7 @@ declare class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
825
825
|
private findValidTraceAnchorCandidate;
|
|
826
826
|
private findValidOutwardTraceAnchorCandidate;
|
|
827
827
|
private getTraceAnchorCandidatePoints;
|
|
828
|
+
private sharesVerticalRailWithAny;
|
|
828
829
|
private getAvailableOrientations;
|
|
829
830
|
private findValidShiftedCandidate;
|
|
830
831
|
/**
|
package/dist/index.js
CHANGED
|
@@ -8842,13 +8842,14 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8842
8842
|
}
|
|
8843
8843
|
findValidTraceAnchorCandidate(label, orientation, labelIndex) {
|
|
8844
8844
|
const direction = dir(orientation);
|
|
8845
|
-
const candidatePoints = this.getTraceAnchorCandidatePoints(
|
|
8846
|
-
|
|
8847
|
-
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8845
|
+
const candidatePoints = this.getTraceAnchorCandidatePoints(
|
|
8846
|
+
label,
|
|
8847
|
+
orientation
|
|
8848
|
+
).sort((a, b) => {
|
|
8849
|
+
const aAlongDirection = a.x * direction.x + a.y * direction.y;
|
|
8850
|
+
const bAlongDirection = b.x * direction.x + b.y * direction.y;
|
|
8851
|
+
return bAlongDirection - aAlongDirection;
|
|
8852
|
+
});
|
|
8852
8853
|
for (const anchorPoint of candidatePoints) {
|
|
8853
8854
|
const candidate = this.createCandidate(label, anchorPoint, orientation);
|
|
8854
8855
|
const result = this.evaluateCandidate(
|
|
@@ -8867,13 +8868,14 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8867
8868
|
}
|
|
8868
8869
|
findValidOutwardTraceAnchorCandidate(label, orientation, labelIndex) {
|
|
8869
8870
|
const direction = dir(orientation);
|
|
8870
|
-
const candidatePoints = this.getTraceAnchorCandidatePoints(
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8871
|
+
const candidatePoints = this.getTraceAnchorCandidatePoints(
|
|
8872
|
+
label,
|
|
8873
|
+
orientation
|
|
8874
|
+
).sort((a, b) => {
|
|
8875
|
+
const aAlongDirection = a.x * direction.x + a.y * direction.y;
|
|
8876
|
+
const bAlongDirection = b.x * direction.x + b.y * direction.y;
|
|
8877
|
+
return bAlongDirection - aAlongDirection;
|
|
8878
|
+
});
|
|
8877
8879
|
for (const connectorSource of candidatePoints) {
|
|
8878
8880
|
const preservedColumnAnchor = this.getSearchStartAnchor(
|
|
8879
8881
|
label,
|
|
@@ -8931,10 +8933,40 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8931
8933
|
}
|
|
8932
8934
|
return null;
|
|
8933
8935
|
}
|
|
8934
|
-
getTraceAnchorCandidatePoints(label) {
|
|
8936
|
+
getTraceAnchorCandidatePoints(label, orientation) {
|
|
8935
8937
|
const seen = /* @__PURE__ */ new Set();
|
|
8936
8938
|
const points = [];
|
|
8937
|
-
|
|
8939
|
+
const connectedTraceIds = new Set(label.mspConnectionPairIds ?? []);
|
|
8940
|
+
if (isYOrientation(orientation)) {
|
|
8941
|
+
const connectedPinIds = /* @__PURE__ */ new Set();
|
|
8942
|
+
for (const traceId of connectedTraceIds) {
|
|
8943
|
+
for (const pinId of this.traceMap[traceId]?.pinIds ?? []) {
|
|
8944
|
+
connectedPinIds.add(pinId);
|
|
8945
|
+
}
|
|
8946
|
+
}
|
|
8947
|
+
let foundConnectedTrace = true;
|
|
8948
|
+
while (foundConnectedTrace) {
|
|
8949
|
+
foundConnectedTrace = false;
|
|
8950
|
+
for (const trace of Object.values(this.traceMap)) {
|
|
8951
|
+
if (connectedTraceIds.has(trace.mspPairId)) continue;
|
|
8952
|
+
if (trace.mspPairId.startsWith("available-net-orientation-")) continue;
|
|
8953
|
+
if (trace.globalConnNetId !== label.globalConnNetId) continue;
|
|
8954
|
+
if (!trace.pinIds.some((pinId) => connectedPinIds.has(pinId)))
|
|
8955
|
+
continue;
|
|
8956
|
+
const connectedTraces = [...connectedTraceIds].flatMap((traceId) => {
|
|
8957
|
+
const connectedTrace = this.traceMap[traceId];
|
|
8958
|
+
return connectedTrace ? [connectedTrace] : [];
|
|
8959
|
+
});
|
|
8960
|
+
if (!this.sharesVerticalRailWithAny(trace, connectedTraces)) {
|
|
8961
|
+
continue;
|
|
8962
|
+
}
|
|
8963
|
+
connectedTraceIds.add(trace.mspPairId);
|
|
8964
|
+
for (const pinId of trace.pinIds) connectedPinIds.add(pinId);
|
|
8965
|
+
foundConnectedTrace = true;
|
|
8966
|
+
}
|
|
8967
|
+
}
|
|
8968
|
+
}
|
|
8969
|
+
for (const traceId of connectedTraceIds) {
|
|
8938
8970
|
const trace = this.traceMap[traceId];
|
|
8939
8971
|
if (!trace) continue;
|
|
8940
8972
|
for (const point of trace.tracePath) {
|
|
@@ -8946,6 +8978,26 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8946
8978
|
}
|
|
8947
8979
|
return points;
|
|
8948
8980
|
}
|
|
8981
|
+
sharesVerticalRailWithAny(trace, otherTraces) {
|
|
8982
|
+
const verticalRailXs = /* @__PURE__ */ new Set();
|
|
8983
|
+
for (const otherTrace of otherTraces) {
|
|
8984
|
+
for (let i = 0; i < otherTrace.tracePath.length - 1; i++) {
|
|
8985
|
+
const start = otherTrace.tracePath[i];
|
|
8986
|
+
const end = otherTrace.tracePath[i + 1];
|
|
8987
|
+
if (Math.abs(start.x - end.x) <= EPS12 && Math.abs(start.y - end.y) > EPS12) {
|
|
8988
|
+
verticalRailXs.add(start.x);
|
|
8989
|
+
}
|
|
8990
|
+
}
|
|
8991
|
+
}
|
|
8992
|
+
for (let i = 0; i < trace.tracePath.length - 1; i++) {
|
|
8993
|
+
const start = trace.tracePath[i];
|
|
8994
|
+
const end = trace.tracePath[i + 1];
|
|
8995
|
+
if (Math.abs(start.x - end.x) <= EPS12 && Math.abs(start.y - end.y) > EPS12 && [...verticalRailXs].some((x) => Math.abs(x - start.x) <= EPS12)) {
|
|
8996
|
+
return true;
|
|
8997
|
+
}
|
|
8998
|
+
}
|
|
8999
|
+
return false;
|
|
9000
|
+
}
|
|
8949
9001
|
getAvailableOrientations(label) {
|
|
8950
9002
|
const effectiveNetId = label.netId ?? label.globalConnNetId;
|
|
8951
9003
|
return this.inputProblem.availableNetLabelOrientations[effectiveNetId] ?? [];
|
|
@@ -635,13 +635,14 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
635
635
|
labelIndex: number,
|
|
636
636
|
) {
|
|
637
637
|
const direction = dir(orientation)
|
|
638
|
-
const candidatePoints = this.getTraceAnchorCandidatePoints(
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
638
|
+
const candidatePoints = this.getTraceAnchorCandidatePoints(
|
|
639
|
+
label,
|
|
640
|
+
orientation,
|
|
641
|
+
).sort((a, b) => {
|
|
642
|
+
const aAlongDirection = a.x * direction.x + a.y * direction.y
|
|
643
|
+
const bAlongDirection = b.x * direction.x + b.y * direction.y
|
|
644
|
+
return bAlongDirection - aAlongDirection
|
|
645
|
+
})
|
|
645
646
|
|
|
646
647
|
for (const anchorPoint of candidatePoints) {
|
|
647
648
|
const candidate = this.createCandidate(label, anchorPoint, orientation)
|
|
@@ -668,13 +669,14 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
668
669
|
labelIndex: number,
|
|
669
670
|
) {
|
|
670
671
|
const direction = dir(orientation)
|
|
671
|
-
const candidatePoints = this.getTraceAnchorCandidatePoints(
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
672
|
+
const candidatePoints = this.getTraceAnchorCandidatePoints(
|
|
673
|
+
label,
|
|
674
|
+
orientation,
|
|
675
|
+
).sort((a, b) => {
|
|
676
|
+
const aAlongDirection = a.x * direction.x + a.y * direction.y
|
|
677
|
+
const bAlongDirection = b.x * direction.x + b.y * direction.y
|
|
678
|
+
return bAlongDirection - aAlongDirection
|
|
679
|
+
})
|
|
678
680
|
|
|
679
681
|
for (const connectorSource of candidatePoints) {
|
|
680
682
|
const preservedColumnAnchor = this.getSearchStartAnchor(
|
|
@@ -742,11 +744,52 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
742
744
|
return null
|
|
743
745
|
}
|
|
744
746
|
|
|
745
|
-
private getTraceAnchorCandidatePoints(
|
|
747
|
+
private getTraceAnchorCandidatePoints(
|
|
748
|
+
label: NetLabelPlacement,
|
|
749
|
+
orientation: FacingDirection,
|
|
750
|
+
) {
|
|
746
751
|
const seen = new Set<string>()
|
|
747
752
|
const points: Point[] = []
|
|
753
|
+
const connectedTraceIds = new Set(label.mspConnectionPairIds ?? [])
|
|
754
|
+
|
|
755
|
+
if (isYOrientation(orientation)) {
|
|
756
|
+
const connectedPinIds = new Set<string>()
|
|
757
|
+
for (const traceId of connectedTraceIds) {
|
|
758
|
+
for (const pinId of this.traceMap[traceId]?.pinIds ?? []) {
|
|
759
|
+
connectedPinIds.add(pinId)
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// Multi-pin rails are routed as a chain of pairwise traces. Follow the
|
|
764
|
+
// pairs only when they share both a pin and an aligned vertical rail,
|
|
765
|
+
// which identifies one continuous rail. A shared pin alone can join
|
|
766
|
+
// unrelated branches whose rail offsets are far apart; walking those
|
|
767
|
+
// branches would extend the label connector across the schematic.
|
|
768
|
+
let foundConnectedTrace = true
|
|
769
|
+
while (foundConnectedTrace) {
|
|
770
|
+
foundConnectedTrace = false
|
|
771
|
+
for (const trace of Object.values(this.traceMap)) {
|
|
772
|
+
if (connectedTraceIds.has(trace.mspPairId)) continue
|
|
773
|
+
if (trace.mspPairId.startsWith("available-net-orientation-")) continue
|
|
774
|
+
if (trace.globalConnNetId !== label.globalConnNetId) continue
|
|
775
|
+
if (!trace.pinIds.some((pinId) => connectedPinIds.has(pinId)))
|
|
776
|
+
continue
|
|
777
|
+
const connectedTraces = [...connectedTraceIds].flatMap((traceId) => {
|
|
778
|
+
const connectedTrace = this.traceMap[traceId]
|
|
779
|
+
return connectedTrace ? [connectedTrace] : []
|
|
780
|
+
})
|
|
781
|
+
if (!this.sharesVerticalRailWithAny(trace, connectedTraces)) {
|
|
782
|
+
continue
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
connectedTraceIds.add(trace.mspPairId)
|
|
786
|
+
for (const pinId of trace.pinIds) connectedPinIds.add(pinId)
|
|
787
|
+
foundConnectedTrace = true
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
748
791
|
|
|
749
|
-
for (const traceId of
|
|
792
|
+
for (const traceId of connectedTraceIds) {
|
|
750
793
|
const trace = this.traceMap[traceId]
|
|
751
794
|
if (!trace) continue
|
|
752
795
|
for (const point of trace.tracePath) {
|
|
@@ -760,6 +803,39 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
760
803
|
return points
|
|
761
804
|
}
|
|
762
805
|
|
|
806
|
+
private sharesVerticalRailWithAny(
|
|
807
|
+
trace: SolvedTracePath,
|
|
808
|
+
otherTraces: SolvedTracePath[],
|
|
809
|
+
) {
|
|
810
|
+
const verticalRailXs = new Set<number>()
|
|
811
|
+
for (const otherTrace of otherTraces) {
|
|
812
|
+
for (let i = 0; i < otherTrace.tracePath.length - 1; i++) {
|
|
813
|
+
const start = otherTrace.tracePath[i]!
|
|
814
|
+
const end = otherTrace.tracePath[i + 1]!
|
|
815
|
+
if (
|
|
816
|
+
Math.abs(start.x - end.x) <= EPS &&
|
|
817
|
+
Math.abs(start.y - end.y) > EPS
|
|
818
|
+
) {
|
|
819
|
+
verticalRailXs.add(start.x)
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
for (let i = 0; i < trace.tracePath.length - 1; i++) {
|
|
825
|
+
const start = trace.tracePath[i]!
|
|
826
|
+
const end = trace.tracePath[i + 1]!
|
|
827
|
+
if (
|
|
828
|
+
Math.abs(start.x - end.x) <= EPS &&
|
|
829
|
+
Math.abs(start.y - end.y) > EPS &&
|
|
830
|
+
[...verticalRailXs].some((x) => Math.abs(x - start.x) <= EPS)
|
|
831
|
+
) {
|
|
832
|
+
return true
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
return false
|
|
837
|
+
}
|
|
838
|
+
|
|
763
839
|
private getAvailableOrientations(label: NetLabelPlacement) {
|
|
764
840
|
const effectiveNetId = label.netId ?? label.globalConnNetId
|
|
765
841
|
return this.inputProblem.availableNetLabelOrientations[effectiveNetId] ?? []
|