@tscircuit/schematic-trace-solver 0.0.190 → 0.0.192
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 +2 -0
- package/dist/index.js +437 -211
- package/lib/solvers/InlineNetLabelSolver/getLocalTraceLabelShifts.ts +29 -0
- package/lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts +7 -0
- package/lib/solvers/LongDistancePairSolver/getParallelNetLabelPolicy.ts +98 -0
- package/lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver.ts +24 -2
- package/lib/solvers/MspConnectionPairSolver/getParallelRailPairs.ts +178 -0
- package/lib/solvers/NetLabelToTraceSolver/NetLabelToTraceSolver.ts +13 -0
- package/lib/solvers/SameNetJunctionAlignmentSolver/collapseRedundantSharedEndpointStubs.ts +12 -6
- package/package.json +1 -1
- package/tests/bug-reports/bug-report-20260706T213649Z/__snapshots__/bug-report-20260706T213649Z.snap.svg +837 -799
- package/tests/bug-reports/bug-report-20260706T220324Z/__snapshots__/bug-report-20260706T220324Z.snap.svg +904 -866
- package/tests/bug-reports/bug-report-20260707T092615Z/__snapshots__/bug-report-20260707T092615Z.snap.svg +533 -524
- package/tests/bug-reports/bug-report-20260721T221026Z/__snapshots__/bug-report-20260721T221026Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260724T175257Z/__snapshots__/bug-report-20260724T175257Z.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-20260804T171919Z/__snapshots__/bug-report-20260804T171919Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260806T093501Z/__snapshots__/bug-report-20260806T093501Z.snap.svg +94 -94
- package/tests/bug-reports/bug-report-20260815T073240Z/__snapshots__/bug-report-20260815T073240Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260901T055358Z/__snapshots__/bug-report-20260901T055358Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260901T064117Z/bug-report-20260901T064117Z.test.ts +13 -2
- package/tests/bug-reports/bug-report-20260902T092425Z/__snapshots__/bug-report-20260902T092425Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260902T092425Z/bug-report-20260902T092425Z.test.ts +16 -2
- package/tests/bug-reports/bug-report-20260905T041712Z/__snapshots__/bug-report-20260905T041712Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260907T083336Z/__snapshots__/bug-report-20260907T083336Z.snap.svg +2 -2
- package/tests/bug-reports/bug-report-20260907T110144Z/__snapshots__/bug-report-20260907T110144Z.snap.svg +19 -58
- package/tests/bug-reports/bug-report-20260907T110144Z/bug-report-20260907T110144Z.test.ts +2 -2
- package/tests/bug-reports/bug-report-20260907T145640Z/__snapshots__/bug-report-20260907T145640Z.snap.svg +917 -933
- package/tests/examples/__snapshots__/example13.snap.svg +2 -2
- package/tests/examples/__snapshots__/example15.snap.svg +2 -2
- package/tests/examples/__snapshots__/example51.snap.svg +2 -2
- package/tests/repros/__snapshots__/board-1273-trace-overlap-cycle.snap.svg +2 -2
- package/tests/repros/__snapshots__/board-15984-same-net-junction.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-bq25895-cross-net-trace-overlap.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-cc2340r5.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-esp12f-section.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-example35-minimize-trace-crossing.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-hub-usb-sheet.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-isolated-rs485-isow7841.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-pga300-redundant-ground-traces.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-pmp11282-isolated-dcdc.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-powerbank-3v-system-power.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-repeated-power-rail-junctions.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-rp2040-gamepad-trace-alignment.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-smartwatch-power-sheet.snap.svg +111 -75
- package/tests/repros/__snapshots__/repro-tida00553-j4-cell-divider.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-tida010076-page02.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-type-c-vbus-led-ground-label.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-usb-power-vbus-label-detour.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro130-bq27441-fuel-gauge-trace-through-c1.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro161-power-section-autolayout.snap.svg +2 -2
- package/tests/repros/repro-trellis-core-decoupling-snake-traces.test.ts +66 -0
- package/tests/solvers/InlineNetLabelSolver/local-trace-label-shifts.test.ts +62 -0
- package/tests/solvers/LongDistancePairSolver/__snapshots__/decoupling-mixed-supplies.snap.svg +112 -0
- package/tests/solvers/LongDistancePairSolver/__snapshots__/horizontal-rails.snap.svg +79 -0
- package/tests/solvers/LongDistancePairSolver/__snapshots__/vertical-rails.snap.svg +86 -0
- package/tests/solvers/LongDistancePairSolver/parallel-decoupling-labels.test.ts +505 -0
- package/tests/solvers/SameNetJunctionAlignmentSolver/collapse-redundant-shared-endpoint-stubs.test.ts +45 -0
package/dist/index.js
CHANGED
|
@@ -342,19 +342,19 @@ var doesPairCrossRestrictedCenterLines = (params) => {
|
|
|
342
342
|
chipMap
|
|
343
343
|
});
|
|
344
344
|
if (restrictedCenterLines.size === 0) return false;
|
|
345
|
-
const
|
|
345
|
+
const EPS19 = 1e-9;
|
|
346
346
|
const crossesSegment = (a, b) => {
|
|
347
347
|
for (const [, rcl] of restrictedCenterLines) {
|
|
348
348
|
if (rcl.axes.has("x") && typeof rcl.x === "number") {
|
|
349
|
-
if ((a.x - rcl.x) * (b.x - rcl.x) < -
|
|
349
|
+
if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS19) return true;
|
|
350
350
|
}
|
|
351
351
|
if (rcl.axes.has("y") && typeof rcl.y === "number") {
|
|
352
|
-
if ((a.y - rcl.y) * (b.y - rcl.y) < -
|
|
352
|
+
if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS19) return true;
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
355
|
return false;
|
|
356
356
|
};
|
|
357
|
-
if (Math.abs(p1.x - p2.x) <
|
|
357
|
+
if (Math.abs(p1.x - p2.x) < EPS19 || Math.abs(p1.y - p2.y) < EPS19) {
|
|
358
358
|
return crossesSegment({ x: p1.x, y: p1.y }, { x: p2.x, y: p2.y });
|
|
359
359
|
}
|
|
360
360
|
const elbowHV = { x: p2.x, y: p1.y };
|
|
@@ -608,6 +608,126 @@ function shouldSeparateGroundNetRows({
|
|
|
608
608
|
return isGroupedHorizontalRail({ pin: pin1, netPins }) && isGroupedHorizontalRail({ pin: pin2, netPins });
|
|
609
609
|
}
|
|
610
610
|
|
|
611
|
+
// lib/solvers/MspConnectionPairSolver/getParallelRailPairs.ts
|
|
612
|
+
var EPS = 1e-6;
|
|
613
|
+
var MAX_RAIL_SPACING_IN_TERMINAL_SPANS = 4;
|
|
614
|
+
var MAX_RAIL_SPACING_MULTIPLIER = 2;
|
|
615
|
+
var getRailPairKey = (first, second) => JSON.stringify([first, second].sort());
|
|
616
|
+
var getParallelRailPairs = (inputProblem, netConnMap, maxMspPairDistance) => {
|
|
617
|
+
const groundNetIds = /* @__PURE__ */ new Set();
|
|
618
|
+
const namedPinIds = /* @__PURE__ */ new Set();
|
|
619
|
+
const wiredPinIds = /* @__PURE__ */ new Set();
|
|
620
|
+
for (const connection of inputProblem.netConnections) {
|
|
621
|
+
for (const pinId of connection.pinIds) namedPinIds.add(pinId);
|
|
622
|
+
const netId = netConnMap.getNetConnectedToId(connection.netId);
|
|
623
|
+
if (netId && connection.isGround) {
|
|
624
|
+
groundNetIds.add(netId);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
for (const connection of inputProblem.directConnections) {
|
|
628
|
+
const pinIds = connection.netLabelWidth === void 0 ? wiredPinIds : namedPinIds;
|
|
629
|
+
for (const pinId of connection.pinIds) pinIds.add(pinId);
|
|
630
|
+
}
|
|
631
|
+
const rows = [];
|
|
632
|
+
for (const chip of inputProblem.chips) {
|
|
633
|
+
if (chip.pins.length !== 2 || chip.symbolName && !chip.symbolName.startsWith("capacitor") || !chip.pins.every((pin) => namedPinIds.has(pin.pinId)) || chip.pins.some((pin) => wiredPinIds.has(pin.pinId)))
|
|
634
|
+
continue;
|
|
635
|
+
const nets = chip.pins.map(
|
|
636
|
+
(pin) => netConnMap.getNetConnectedToId(pin.pinId)
|
|
637
|
+
);
|
|
638
|
+
if (!nets[0] || !nets[1] || nets[0] === nets[1] || groundNetIds.has(nets[0]) === groundNetIds.has(nets[1]))
|
|
639
|
+
continue;
|
|
640
|
+
const directions = chip.pins.map(
|
|
641
|
+
(pin) => pin._facingDirection ?? getPinDirection(pin, chip)
|
|
642
|
+
);
|
|
643
|
+
if (directions[0][0] !== directions[1][0] || directions[0] === directions[1])
|
|
644
|
+
continue;
|
|
645
|
+
const axis = directions[0][0];
|
|
646
|
+
const along = axis === "x" ? "y" : "x";
|
|
647
|
+
if (Math.abs(chip.pins[0][along] - chip.pins[1][along]) > EPS) continue;
|
|
648
|
+
for (const [index, pin] of chip.pins.entries()) {
|
|
649
|
+
const direction = directions[index];
|
|
650
|
+
let row = rows.find(
|
|
651
|
+
(candidate) => candidate.sectionId === chip.sectionId && candidate.direction === direction && Math.abs(candidate.coordinate - pin[axis]) <= EPS
|
|
652
|
+
);
|
|
653
|
+
if (!row) {
|
|
654
|
+
row = {
|
|
655
|
+
sectionId: chip.sectionId,
|
|
656
|
+
direction,
|
|
657
|
+
coordinate: pin[axis],
|
|
658
|
+
axis,
|
|
659
|
+
pins: []
|
|
660
|
+
};
|
|
661
|
+
rows.push(row);
|
|
662
|
+
}
|
|
663
|
+
row.pins.push({
|
|
664
|
+
...pin,
|
|
665
|
+
chipId: chip.chipId,
|
|
666
|
+
oppositeCoordinate: chip.pins[1 - index][axis]
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
const pairKeys = /* @__PURE__ */ new Set();
|
|
671
|
+
const extendedRailPinIds = /* @__PURE__ */ new Set();
|
|
672
|
+
const separatedRailPinIds = /* @__PURE__ */ new Set();
|
|
673
|
+
for (const row of rows) {
|
|
674
|
+
const along = row.axis === "x" ? "y" : "x";
|
|
675
|
+
row.pins.sort(
|
|
676
|
+
(a, b) => a[along] - b[along] || a.pinId.localeCompare(b.pinId)
|
|
677
|
+
);
|
|
678
|
+
for (let index = 1; index < row.pins.length; index++) {
|
|
679
|
+
const first = row.pins[index - 1];
|
|
680
|
+
const second = row.pins[index];
|
|
681
|
+
const spacing = second[along] - first[along];
|
|
682
|
+
const neighboringSpacings = [
|
|
683
|
+
first[along] - (row.pins[index - 2]?.[along] ?? first[along]),
|
|
684
|
+
(row.pins[index + 1]?.[along] ?? second[along]) - second[along]
|
|
685
|
+
].filter((gap) => gap > EPS);
|
|
686
|
+
const maxRailSpacing = Math.max(
|
|
687
|
+
MAX_RAIL_SPACING_MULTIPLIER * maxMspPairDistance,
|
|
688
|
+
MAX_RAIL_SPACING_MULTIPLIER * (neighboringSpacings.length ? Math.min(...neighboringSpacings) : 0),
|
|
689
|
+
MAX_RAIL_SPACING_IN_TERMINAL_SPANS * Math.max(
|
|
690
|
+
Math.abs(first[row.axis] - first.oppositeCoordinate),
|
|
691
|
+
Math.abs(second[row.axis] - second.oppositeCoordinate)
|
|
692
|
+
)
|
|
693
|
+
);
|
|
694
|
+
if (spacing <= EPS || netConnMap.getNetConnectedToId(first.pinId) !== netConnMap.getNetConnectedToId(second.pinId))
|
|
695
|
+
continue;
|
|
696
|
+
if (spacing > maxRailSpacing + EPS) {
|
|
697
|
+
separatedRailPinIds.add(first.pinId);
|
|
698
|
+
separatedRailPinIds.add(second.pinId);
|
|
699
|
+
continue;
|
|
700
|
+
}
|
|
701
|
+
const minAcross = Math.min(
|
|
702
|
+
first[row.axis],
|
|
703
|
+
second[row.axis],
|
|
704
|
+
first.oppositeCoordinate,
|
|
705
|
+
second.oppositeCoordinate
|
|
706
|
+
);
|
|
707
|
+
const maxAcross = Math.max(
|
|
708
|
+
first[row.axis],
|
|
709
|
+
second[row.axis],
|
|
710
|
+
first.oppositeCoordinate,
|
|
711
|
+
second.oppositeCoordinate
|
|
712
|
+
);
|
|
713
|
+
if (inputProblem.chips.some((chip) => {
|
|
714
|
+
if (chip.chipId === first.chipId || chip.chipId === second.chipId)
|
|
715
|
+
return false;
|
|
716
|
+
const acrossSize = row.axis === "x" ? chip.width : chip.height;
|
|
717
|
+
const alongSize = along === "x" ? chip.width : chip.height;
|
|
718
|
+
return chip.center[row.axis] + acrossSize / 2 >= minAcross - EPS && chip.center[row.axis] - acrossSize / 2 <= maxAcross + EPS && chip.center[along] + alongSize / 2 > first[along] + EPS && chip.center[along] - alongSize / 2 < second[along] - EPS;
|
|
719
|
+
}))
|
|
720
|
+
continue;
|
|
721
|
+
pairKeys.add(getRailPairKey(first.pinId, second.pinId));
|
|
722
|
+
if (spacing > maxMspPairDistance) {
|
|
723
|
+
extendedRailPinIds.add(first.pinId);
|
|
724
|
+
extendedRailPinIds.add(second.pinId);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
return { pairKeys, extendedRailPinIds, separatedRailPinIds };
|
|
729
|
+
};
|
|
730
|
+
|
|
611
731
|
// lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver.ts
|
|
612
732
|
var DEFAULT_MAX_MSP_PAIR_DISTANCE = 1;
|
|
613
733
|
var getPinPairKey = (pinIds) => [...pinIds].sort().join("::");
|
|
@@ -624,6 +744,7 @@ var MspConnectionPairSolver = class extends BaseSolver {
|
|
|
624
744
|
userNetIdByPinId;
|
|
625
745
|
directConnectionPinPairKeys;
|
|
626
746
|
canRouteGroundPair;
|
|
747
|
+
parallelRailPairKeys;
|
|
627
748
|
constructor({ inputProblem }) {
|
|
628
749
|
super();
|
|
629
750
|
this.inputProblem = inputProblem;
|
|
@@ -632,6 +753,11 @@ var MspConnectionPairSolver = class extends BaseSolver {
|
|
|
632
753
|
const { directConnMap, netConnMap } = getConnectivityMapsFromInputProblem(inputProblem);
|
|
633
754
|
this.dcConnMap = directConnMap;
|
|
634
755
|
this.globalConnMap = netConnMap;
|
|
756
|
+
this.parallelRailPairKeys = getParallelRailPairs(
|
|
757
|
+
inputProblem,
|
|
758
|
+
netConnMap,
|
|
759
|
+
this.maxMspPairDistance
|
|
760
|
+
).pairKeys;
|
|
635
761
|
this.pinMap = {};
|
|
636
762
|
for (const chip of inputProblem.chips) {
|
|
637
763
|
for (const pin of chip.pins) {
|
|
@@ -695,7 +821,7 @@ var MspConnectionPairSolver = class extends BaseSolver {
|
|
|
695
821
|
chipMap: this.chipMap,
|
|
696
822
|
pins: [p1, p2]
|
|
697
823
|
});
|
|
698
|
-
if (pairDistance > this.maxMspPairDistance && !labeledConnectionRouteReason) {
|
|
824
|
+
if (pairDistance > this.maxMspPairDistance && !this.parallelRailPairKeys.has(getRailPairKey(pin1, pin2)) && !labeledConnectionRouteReason) {
|
|
699
825
|
return;
|
|
700
826
|
}
|
|
701
827
|
if (arePinsInDifferentSchematicSections(this.inputProblem, p1, p2)) {
|
|
@@ -733,8 +859,7 @@ var MspConnectionPairSolver = class extends BaseSolver {
|
|
|
733
859
|
(pinId) => this.pinMap[pinId]
|
|
734
860
|
);
|
|
735
861
|
const msp = getOrthogonalMinimumSpanningTree(directlyConnectedPinObjects, {
|
|
736
|
-
|
|
737
|
-
forbidEdge: (a, b) => !this.canRouteGroundPair(a.pinId, b.pinId) || shouldSeparateGroundNetRows({
|
|
862
|
+
forbidEdge: (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y) > this.maxMspPairDistance && !this.parallelRailPairKeys.has(getRailPairKey(a.pinId, b.pinId)) || !this.canRouteGroundPair(a.pinId, b.pinId) || shouldSeparateGroundNetRows({
|
|
738
863
|
netConnection,
|
|
739
864
|
netPins: directlyConnectedPinObjects,
|
|
740
865
|
pin1: a,
|
|
@@ -747,7 +872,11 @@ var MspConnectionPairSolver = class extends BaseSolver {
|
|
|
747
872
|
p2: b
|
|
748
873
|
})
|
|
749
874
|
});
|
|
750
|
-
for (
|
|
875
|
+
for (let [pin1, pin2] of msp) {
|
|
876
|
+
if (this.parallelRailPairKeys.has(getRailPairKey(pin1, pin2)) && Math.abs(this.pinMap[pin1].x - this.pinMap[pin2].x) + Math.abs(this.pinMap[pin1].y - this.pinMap[pin2].y) > this.maxMspPairDistance && directlyConnectedPins.indexOf(pin1) > directlyConnectedPins.indexOf(pin2)) {
|
|
877
|
+
;
|
|
878
|
+
[pin1, pin2] = [pin2, pin1];
|
|
879
|
+
}
|
|
751
880
|
const p1Obj = this.pinMap[pin1];
|
|
752
881
|
const p2Obj = this.pinMap[pin2];
|
|
753
882
|
if (arePinsInDifferentSchematicSections(this.inputProblem, p1Obj, p2Obj)) {
|
|
@@ -971,10 +1100,10 @@ function calculateDirectShortPath(pin1, pin2) {
|
|
|
971
1100
|
}
|
|
972
1101
|
|
|
973
1102
|
// lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/collisions.ts
|
|
974
|
-
var
|
|
975
|
-
var isVertical = (a, b, eps =
|
|
976
|
-
var isHorizontal = (a, b, eps =
|
|
977
|
-
var segmentIntersectsRect = (a, b, r, eps =
|
|
1103
|
+
var EPS2 = 1e-9;
|
|
1104
|
+
var isVertical = (a, b, eps = EPS2) => Math.abs(a.x - b.x) < eps;
|
|
1105
|
+
var isHorizontal = (a, b, eps = EPS2) => Math.abs(a.y - b.y) < eps;
|
|
1106
|
+
var segmentIntersectsRect = (a, b, r, eps = EPS2) => {
|
|
978
1107
|
const vert = isVertical(a, b, eps);
|
|
979
1108
|
const horz = isHorizontal(a, b, eps);
|
|
980
1109
|
if (!vert && !horz) return false;
|
|
@@ -994,7 +1123,7 @@ var segmentIntersectsRect = (a, b, r, eps = EPS) => {
|
|
|
994
1123
|
return overlap > eps;
|
|
995
1124
|
}
|
|
996
1125
|
};
|
|
997
|
-
var segmentOverlapsRectBoundary = (a, b, r, eps =
|
|
1126
|
+
var segmentOverlapsRectBoundary = (a, b, r, eps = EPS2) => {
|
|
998
1127
|
if (isVertical(a, b, eps)) {
|
|
999
1128
|
const onVerticalBoundary = Math.abs(a.x - r.minX) <= eps || Math.abs(a.x - r.maxX) <= eps;
|
|
1000
1129
|
if (!onVerticalBoundary) return false;
|
|
@@ -1035,7 +1164,7 @@ var isPathCollidingWithObstacles = (path, obstacles) => {
|
|
|
1035
1164
|
};
|
|
1036
1165
|
|
|
1037
1166
|
// lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/mid.ts
|
|
1038
|
-
var
|
|
1167
|
+
var EPS3 = 1e-9;
|
|
1039
1168
|
var OBSTACLE_CLEARANCE = 0.2;
|
|
1040
1169
|
var aabbFromPoints = (a, b) => ({
|
|
1041
1170
|
minX: Math.min(a.x, b.x),
|
|
@@ -1043,7 +1172,7 @@ var aabbFromPoints = (a, b) => ({
|
|
|
1043
1172
|
minY: Math.min(a.y, b.y),
|
|
1044
1173
|
maxY: Math.max(a.y, b.y)
|
|
1045
1174
|
});
|
|
1046
|
-
var midBetweenPointAndRect = (axis, p, r, eps =
|
|
1175
|
+
var midBetweenPointAndRect = (axis, p, r, eps = EPS3) => {
|
|
1047
1176
|
if (axis === "x") {
|
|
1048
1177
|
if (p.x < r.minX - eps) {
|
|
1049
1178
|
return [(p.x + r.minX) / 2];
|
|
@@ -1063,7 +1192,7 @@ var midBetweenPointAndRect = (axis, p, r, eps = EPS2) => {
|
|
|
1063
1192
|
}
|
|
1064
1193
|
};
|
|
1065
1194
|
var candidateMidsFromSet = (axis, colliding, collisionRects, aabb, opts = {}) => {
|
|
1066
|
-
const { allowOpenSideCandidates = false, eps =
|
|
1195
|
+
const { allowOpenSideCandidates = false, eps = EPS3 } = opts;
|
|
1067
1196
|
const setRects = [...collisionRects];
|
|
1068
1197
|
if (axis === "x") {
|
|
1069
1198
|
const leftBoundaries = [aabb.minX, ...setRects.map((r) => r.maxX)].filter(
|
|
@@ -1111,7 +1240,7 @@ var candidateMidsFromSet = (axis, colliding, collisionRects, aabb, opts = {}) =>
|
|
|
1111
1240
|
};
|
|
1112
1241
|
|
|
1113
1242
|
// lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/pathOps.ts
|
|
1114
|
-
var
|
|
1243
|
+
var EPS4 = 1e-9;
|
|
1115
1244
|
var hasOnlyNonzeroOrthogonalSegments = (path) => path.every((point, index) => {
|
|
1116
1245
|
const nextPoint = path[index + 1];
|
|
1117
1246
|
if (!nextPoint) return true;
|
|
@@ -1120,7 +1249,7 @@ var hasOnlyNonzeroOrthogonalSegments = (path) => path.every((point, index) => {
|
|
|
1120
1249
|
}
|
|
1121
1250
|
return Math.abs(point.x - nextPoint.x) + Math.abs(point.y - nextPoint.y) > 0;
|
|
1122
1251
|
});
|
|
1123
|
-
var shiftSegmentOrth = (pts, segIndex, axis, newCoord, eps =
|
|
1252
|
+
var shiftSegmentOrth = (pts, segIndex, axis, newCoord, eps = EPS4) => {
|
|
1124
1253
|
if (segIndex < 0 || segIndex >= pts.length - 1) {
|
|
1125
1254
|
return null;
|
|
1126
1255
|
}
|
|
@@ -1237,9 +1366,9 @@ var generateEndpointCollisionDetours = ({
|
|
|
1237
1366
|
};
|
|
1238
1367
|
|
|
1239
1368
|
// lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/generateInternalSegmentCollisionDetours.ts
|
|
1240
|
-
var
|
|
1369
|
+
var EPS5 = 1e-9;
|
|
1241
1370
|
var DEFAULT_CLEARANCE = 0.2;
|
|
1242
|
-
var isStrictlyBetween = (value, a, b) => value > Math.min(a, b) +
|
|
1371
|
+
var isStrictlyBetween = (value, a, b) => value > Math.min(a, b) + EPS5 && value < Math.max(a, b) - EPS5;
|
|
1243
1372
|
var generateInternalSegmentCollisionDetours = ({
|
|
1244
1373
|
path,
|
|
1245
1374
|
collidingSegmentIndex,
|
|
@@ -1657,8 +1786,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
1657
1786
|
if (!collision) {
|
|
1658
1787
|
const first = path[0];
|
|
1659
1788
|
const last = path[path.length - 1];
|
|
1660
|
-
const
|
|
1661
|
-
const samePoint = (p, q) => Math.abs(p.x - q.x) <
|
|
1789
|
+
const EPS19 = 1e-9;
|
|
1790
|
+
const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS19 && Math.abs(p.y - q.y) < EPS19;
|
|
1662
1791
|
if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y }) && (!this.hasAmbiguousPinDirections || pathMatchesPinDirections({
|
|
1663
1792
|
path,
|
|
1664
1793
|
pin1: { ...PA, _facingDirection: directions[0] },
|
|
@@ -2013,13 +2142,13 @@ var applyJogToTerminalSegment = ({
|
|
|
2013
2142
|
segmentIndex: si,
|
|
2014
2143
|
offset,
|
|
2015
2144
|
JOG_SIZE,
|
|
2016
|
-
EPS:
|
|
2145
|
+
EPS: EPS19 = 1e-6
|
|
2017
2146
|
}) => {
|
|
2018
2147
|
if (si !== 0 && si !== pts.length - 2) return;
|
|
2019
2148
|
const start = pts[si];
|
|
2020
2149
|
const end = pts[si + 1];
|
|
2021
|
-
const isVertical6 = Math.abs(start.x - end.x) <
|
|
2022
|
-
const isHorizontal5 = Math.abs(start.y - end.y) <
|
|
2150
|
+
const isVertical6 = Math.abs(start.x - end.x) < EPS19;
|
|
2151
|
+
const isHorizontal5 = Math.abs(start.y - end.y) < EPS19;
|
|
2023
2152
|
if (!isVertical6 && !isHorizontal5) return;
|
|
2024
2153
|
const segDir = isVertical6 ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
|
|
2025
2154
|
if (pts.length === 2) {
|
|
@@ -2092,7 +2221,7 @@ var applyJogToTerminalSegment = ({
|
|
|
2092
2221
|
};
|
|
2093
2222
|
|
|
2094
2223
|
// lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/TraceOverlapIssueSolver.ts
|
|
2095
|
-
var
|
|
2224
|
+
var EPS6 = 1e-6;
|
|
2096
2225
|
var TraceOverlapIssueSolver = class extends BaseSolver {
|
|
2097
2226
|
overlappingTraceSegments;
|
|
2098
2227
|
interactionKind;
|
|
@@ -2189,7 +2318,7 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
|
|
|
2189
2318
|
}
|
|
2190
2319
|
applyOffsets(offsets) {
|
|
2191
2320
|
const correctedTraceMap = { ...this.correctedTraceMap };
|
|
2192
|
-
const eq = (a, b) => Math.abs(a - b) <
|
|
2321
|
+
const eq = (a, b) => Math.abs(a - b) < EPS6;
|
|
2193
2322
|
const samePoint = (p, q) => !!p && !!q && eq(p.x, q.x) && eq(p.y, q.y);
|
|
2194
2323
|
this.overlappingTraceSegments.forEach((group, groupIndex) => {
|
|
2195
2324
|
const offset = offsets[groupIndex];
|
|
@@ -2211,9 +2340,9 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
|
|
|
2211
2340
|
const start = pts[si];
|
|
2212
2341
|
const end = pts[si + 1];
|
|
2213
2342
|
if (!start || !end) continue;
|
|
2214
|
-
if (Math.abs(start.x - end.x) <
|
|
2343
|
+
if (Math.abs(start.x - end.x) < EPS6) {
|
|
2215
2344
|
segmentAxes.set(si, "vertical");
|
|
2216
|
-
} else if (Math.abs(start.y - end.y) <
|
|
2345
|
+
} else if (Math.abs(start.y - end.y) < EPS6) {
|
|
2217
2346
|
segmentAxes.set(si, "horizontal");
|
|
2218
2347
|
}
|
|
2219
2348
|
}
|
|
@@ -2228,7 +2357,7 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
|
|
|
2228
2357
|
segmentIndex: si,
|
|
2229
2358
|
offset,
|
|
2230
2359
|
JOG_SIZE,
|
|
2231
|
-
EPS:
|
|
2360
|
+
EPS: EPS6
|
|
2232
2361
|
});
|
|
2233
2362
|
} else {
|
|
2234
2363
|
const start = pts[si];
|
|
@@ -2315,7 +2444,7 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
|
|
|
2315
2444
|
max = obstacle.maxY;
|
|
2316
2445
|
}
|
|
2317
2446
|
const next = orig + candidateOffset;
|
|
2318
|
-
return orig <= min +
|
|
2447
|
+
return orig <= min + EPS6 && next >= max - EPS6 || orig >= max - EPS6 && next <= min + EPS6;
|
|
2319
2448
|
});
|
|
2320
2449
|
const edges = blockingCollisions.map(({ start, isVertical: isVertical6, obstacle }) => {
|
|
2321
2450
|
if (isVertical6) {
|
|
@@ -2352,8 +2481,8 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
|
|
|
2352
2481
|
const start = trace.tracePath[traceSegmentIndex];
|
|
2353
2482
|
const end = trace.tracePath[traceSegmentIndex + 1];
|
|
2354
2483
|
if (!start || !end) continue;
|
|
2355
|
-
const isVertical6 = Math.abs(start.x - end.x) <
|
|
2356
|
-
const isHorizontal5 = Math.abs(start.y - end.y) <
|
|
2484
|
+
const isVertical6 = Math.abs(start.x - end.x) < EPS6;
|
|
2485
|
+
const isHorizontal5 = Math.abs(start.y - end.y) < EPS6;
|
|
2357
2486
|
if (!isVertical6 && !isHorizontal5) continue;
|
|
2358
2487
|
const shiftedSegment = isVertical6 ? [
|
|
2359
2488
|
{ ...start, x: start.x + offset },
|
|
@@ -2453,7 +2582,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2453
2582
|
return islands;
|
|
2454
2583
|
}
|
|
2455
2584
|
findNextOverlapIssue() {
|
|
2456
|
-
const
|
|
2585
|
+
const EPS19 = 2e-3;
|
|
2457
2586
|
const netIds = Object.keys(this.traceNetIslands);
|
|
2458
2587
|
for (let i = 0; i < netIds.length; i++) {
|
|
2459
2588
|
for (let j = i + 1; j < netIds.length; j++) {
|
|
@@ -2480,7 +2609,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2480
2609
|
segmentBIndex,
|
|
2481
2610
|
rangeOverlap
|
|
2482
2611
|
}) => {
|
|
2483
|
-
if (rangeOverlap >
|
|
2612
|
+
if (rangeOverlap > EPS19) {
|
|
2484
2613
|
const keyA = `${pathAIndex}:${segmentAIndex}`;
|
|
2485
2614
|
const keyB = `${pathBIndex}:${segmentBIndex}`;
|
|
2486
2615
|
if (!seenA.has(keyA)) {
|
|
@@ -2499,7 +2628,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2499
2628
|
}
|
|
2500
2629
|
return;
|
|
2501
2630
|
}
|
|
2502
|
-
if (rangeOverlap < -
|
|
2631
|
+
if (rangeOverlap < -EPS19) return;
|
|
2503
2632
|
const pathA = pathsA[pathAIndex].tracePath;
|
|
2504
2633
|
const pathB = pathsB[pathBIndex].tracePath;
|
|
2505
2634
|
const segmentAStart = pathA[segmentAIndex];
|
|
@@ -2522,8 +2651,8 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2522
2651
|
for (let sa = 0; sa < ptsA.length - 1; sa++) {
|
|
2523
2652
|
const a1 = ptsA[sa];
|
|
2524
2653
|
const a2 = ptsA[sa + 1];
|
|
2525
|
-
const aVert = Math.abs(a1.x - a2.x) <
|
|
2526
|
-
const aHorz = Math.abs(a1.y - a2.y) <
|
|
2654
|
+
const aVert = Math.abs(a1.x - a2.x) < EPS19;
|
|
2655
|
+
const aHorz = Math.abs(a1.y - a2.y) < EPS19;
|
|
2527
2656
|
if (!aVert && !aHorz) continue;
|
|
2528
2657
|
for (let pb = 0; pb < pathsB.length; pb++) {
|
|
2529
2658
|
const pathB = pathsB[pb];
|
|
@@ -2534,11 +2663,11 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2534
2663
|
for (let sb = 0; sb < ptsB.length - 1; sb++) {
|
|
2535
2664
|
const b1 = ptsB[sb];
|
|
2536
2665
|
const b2 = ptsB[sb + 1];
|
|
2537
|
-
const bVert = Math.abs(b1.x - b2.x) <
|
|
2538
|
-
const bHorz = Math.abs(b1.y - b2.y) <
|
|
2666
|
+
const bVert = Math.abs(b1.x - b2.x) < EPS19;
|
|
2667
|
+
const bHorz = Math.abs(b1.y - b2.y) < EPS19;
|
|
2539
2668
|
if (!bVert && !bHorz) continue;
|
|
2540
2669
|
if (aVert && bVert) {
|
|
2541
|
-
if (Math.abs(a1.x - b1.x) <
|
|
2670
|
+
if (Math.abs(a1.x - b1.x) < EPS19) {
|
|
2542
2671
|
recordCollinearInteraction({
|
|
2543
2672
|
pathAIndex: pa,
|
|
2544
2673
|
segmentAIndex: sa,
|
|
@@ -2548,7 +2677,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2548
2677
|
});
|
|
2549
2678
|
}
|
|
2550
2679
|
} else if (aHorz && bHorz) {
|
|
2551
|
-
if (Math.abs(a1.y - b1.y) <
|
|
2680
|
+
if (Math.abs(a1.y - b1.y) < EPS19) {
|
|
2552
2681
|
recordCollinearInteraction({
|
|
2553
2682
|
pathAIndex: pa,
|
|
2554
2683
|
segmentAIndex: sa,
|
|
@@ -2604,14 +2733,14 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2604
2733
|
return null;
|
|
2605
2734
|
}
|
|
2606
2735
|
findNextDiagonalSegment() {
|
|
2607
|
-
const
|
|
2736
|
+
const EPS19 = 2e-3;
|
|
2608
2737
|
for (const mspPairId in this.correctedTraceMap) {
|
|
2609
2738
|
const tracePath = this.correctedTraceMap[mspPairId].tracePath;
|
|
2610
2739
|
for (let i = 0; i < tracePath.length - 1; i++) {
|
|
2611
2740
|
const p1 = tracePath[i];
|
|
2612
2741
|
const p2 = tracePath[i + 1];
|
|
2613
|
-
const isHorizontal5 = Math.abs(p1.y - p2.y) <
|
|
2614
|
-
const isVertical6 = Math.abs(p1.x - p2.x) <
|
|
2742
|
+
const isHorizontal5 = Math.abs(p1.y - p2.y) < EPS19;
|
|
2743
|
+
const isVertical6 = Math.abs(p1.x - p2.x) < EPS19;
|
|
2615
2744
|
if (!isHorizontal5 && !isVertical6) {
|
|
2616
2745
|
return { mspPairId, tracePath, i, p1, p2 };
|
|
2617
2746
|
}
|
|
@@ -2625,13 +2754,13 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2625
2754
|
return false;
|
|
2626
2755
|
}
|
|
2627
2756
|
const { mspPairId, tracePath, i, p1, p2 } = diagonalInfo;
|
|
2628
|
-
const
|
|
2757
|
+
const EPS19 = 2e-3;
|
|
2629
2758
|
const p0 = i > 0 ? tracePath[i - 1] : null;
|
|
2630
2759
|
const p3 = i + 2 < tracePath.length ? tracePath[i + 2] : null;
|
|
2631
|
-
const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) <
|
|
2632
|
-
const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) <
|
|
2633
|
-
const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) <
|
|
2634
|
-
const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) <
|
|
2760
|
+
const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS19 : false;
|
|
2761
|
+
const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS19 : false;
|
|
2762
|
+
const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS19 : false;
|
|
2763
|
+
const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS19 : false;
|
|
2635
2764
|
const elbow1 = { x: p1.x, y: p2.y };
|
|
2636
2765
|
const elbow2 = { x: p2.x, y: p1.y };
|
|
2637
2766
|
let score1 = 0;
|
|
@@ -2793,24 +2922,24 @@ var ChipObstacleSpatialIndex = class {
|
|
|
2793
2922
|
};
|
|
2794
2923
|
|
|
2795
2924
|
// lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions.ts
|
|
2796
|
-
function segmentIntersectsRect2(p1, p2, rect,
|
|
2797
|
-
const isVert = Math.abs(p1.x - p2.x) <
|
|
2798
|
-
const isHorz = Math.abs(p1.y - p2.y) <
|
|
2925
|
+
function segmentIntersectsRect2(p1, p2, rect, EPS19 = 1e-9) {
|
|
2926
|
+
const isVert = Math.abs(p1.x - p2.x) < EPS19;
|
|
2927
|
+
const isHorz = Math.abs(p1.y - p2.y) < EPS19;
|
|
2799
2928
|
if (!isVert && !isHorz) return false;
|
|
2800
2929
|
if (isVert) {
|
|
2801
2930
|
const x = p1.x;
|
|
2802
|
-
if (x < rect.minX -
|
|
2931
|
+
if (x < rect.minX - EPS19 || x > rect.maxX + EPS19) return false;
|
|
2803
2932
|
const segMinY = Math.min(p1.y, p2.y);
|
|
2804
2933
|
const segMaxY = Math.max(p1.y, p2.y);
|
|
2805
2934
|
const overlap = Math.min(segMaxY, rect.maxY) - Math.max(segMinY, rect.minY);
|
|
2806
|
-
return overlap >
|
|
2935
|
+
return overlap > EPS19;
|
|
2807
2936
|
} else {
|
|
2808
2937
|
const y = p1.y;
|
|
2809
|
-
if (y < rect.minY -
|
|
2938
|
+
if (y < rect.minY - EPS19 || y > rect.maxY + EPS19) return false;
|
|
2810
2939
|
const segMinX = Math.min(p1.x, p2.x);
|
|
2811
2940
|
const segMaxX = Math.max(p1.x, p2.x);
|
|
2812
2941
|
const overlap = Math.min(segMaxX, rect.maxX) - Math.max(segMinX, rect.minX);
|
|
2813
|
-
return overlap >
|
|
2942
|
+
return overlap > EPS19;
|
|
2814
2943
|
}
|
|
2815
2944
|
}
|
|
2816
2945
|
function rectIntersectsAnyTrace(bounds, inputTraceMap, hostPathId, hostSegIndex) {
|
|
@@ -3209,14 +3338,14 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
|
|
|
3209
3338
|
};
|
|
3210
3339
|
let bestCandidate = null;
|
|
3211
3340
|
let bestScore = -Infinity;
|
|
3212
|
-
const
|
|
3341
|
+
const EPS19 = 1e-6;
|
|
3213
3342
|
for (const curr of tracesToScan) {
|
|
3214
3343
|
const pts = curr.tracePath.slice();
|
|
3215
3344
|
for (let si = 0; si < pts.length - 1; si++) {
|
|
3216
3345
|
const a = pts[si];
|
|
3217
3346
|
const b = pts[si + 1];
|
|
3218
|
-
const isH = Math.abs(a.y - b.y) <
|
|
3219
|
-
const isV = Math.abs(a.x - b.x) <
|
|
3347
|
+
const isH = Math.abs(a.y - b.y) < EPS19;
|
|
3348
|
+
const isV = Math.abs(a.x - b.x) < EPS19;
|
|
3220
3349
|
if (!isH && !isV) continue;
|
|
3221
3350
|
const segmentAllowed = isH ? ["y+", "y-"] : ["x+", "x-"];
|
|
3222
3351
|
const candidateOrients = orientations.filter(
|
|
@@ -4992,19 +5121,81 @@ function doesTraceOverlapWithExistingTraces(newTracePath, existingTraces) {
|
|
|
4992
5121
|
return false;
|
|
4993
5122
|
}
|
|
4994
5123
|
|
|
5124
|
+
// lib/solvers/LongDistancePairSolver/getParallelNetLabelPolicy.ts
|
|
5125
|
+
import { ConnectivityMap as ConnectivityMap3 } from "connectivity-map";
|
|
5126
|
+
var getParallelNetLabelPolicy = (inputProblem, netConnMap, connectedPinIds) => {
|
|
5127
|
+
const maxDistance = inputProblem.maxMspPairDistance ?? DEFAULT_MAX_MSP_PAIR_DISTANCE;
|
|
5128
|
+
const { extendedRailPinIds, separatedRailPinIds } = getParallelRailPairs(
|
|
5129
|
+
inputProblem,
|
|
5130
|
+
netConnMap,
|
|
5131
|
+
maxDistance
|
|
5132
|
+
);
|
|
5133
|
+
const groundNetIds = /* @__PURE__ */ new Set();
|
|
5134
|
+
const namedPinIds = /* @__PURE__ */ new Set();
|
|
5135
|
+
for (const connection of inputProblem.netConnections) {
|
|
5136
|
+
const netId = netConnMap.getNetConnectedToId(connection.netId);
|
|
5137
|
+
if (!netId) continue;
|
|
5138
|
+
for (const pinId of connection.pinIds) namedPinIds.add(pinId);
|
|
5139
|
+
if (connection.isGround) {
|
|
5140
|
+
groundNetIds.add(netId);
|
|
5141
|
+
}
|
|
5142
|
+
}
|
|
5143
|
+
const banks = /* @__PURE__ */ new Map();
|
|
5144
|
+
for (const chip of inputProblem.chips) {
|
|
5145
|
+
if (chip.pins.length !== 2 || !chip.pins.every((pin) => namedPinIds.has(pin.pinId)) || chip.pins.some(
|
|
5146
|
+
(pin) => connectedPinIds.has(pin.pinId) && !extendedRailPinIds.has(pin.pinId)
|
|
5147
|
+
))
|
|
5148
|
+
continue;
|
|
5149
|
+
const [first, second] = chip.pins.map(
|
|
5150
|
+
(pin) => netConnMap.getNetConnectedToId(pin.pinId)
|
|
5151
|
+
);
|
|
5152
|
+
if (!first || !second || first === second || groundNetIds.has(first) === groundNetIds.has(second)) {
|
|
5153
|
+
continue;
|
|
5154
|
+
}
|
|
5155
|
+
const key = JSON.stringify([
|
|
5156
|
+
chip.sectionId ?? null,
|
|
5157
|
+
...[first, second].sort()
|
|
5158
|
+
]);
|
|
5159
|
+
const bank = banks.get(key) ?? [];
|
|
5160
|
+
bank.push(chip.pins.map((pin) => pin.pinId));
|
|
5161
|
+
banks.set(key, bank);
|
|
5162
|
+
}
|
|
5163
|
+
const bankPinIds = new Set(
|
|
5164
|
+
[...banks.values()].filter((bank) => bank.length > 1).flat(2)
|
|
5165
|
+
);
|
|
5166
|
+
for (const pinId of [...extendedRailPinIds, ...separatedRailPinIds]) {
|
|
5167
|
+
bankPinIds.add(pinId);
|
|
5168
|
+
}
|
|
5169
|
+
const physicalConnMap = new ConnectivityMap3({});
|
|
5170
|
+
for (const connection of inputProblem.directConnections) {
|
|
5171
|
+
if (connection.netLabelWidth === void 0) {
|
|
5172
|
+
physicalConnMap.addConnections([connection.pinIds]);
|
|
5173
|
+
}
|
|
5174
|
+
}
|
|
5175
|
+
return (first, second) => {
|
|
5176
|
+
if (!bankPinIds.has(first.pinId) && !bankPinIds.has(second.pinId))
|
|
5177
|
+
return true;
|
|
5178
|
+
if (Math.abs(first.x - second.x) + Math.abs(first.y - second.y) <= maxDistance) {
|
|
5179
|
+
return true;
|
|
5180
|
+
}
|
|
5181
|
+
const physicalNetId = physicalConnMap.getNetConnectedToId(first.pinId);
|
|
5182
|
+
return physicalNetId !== void 0 && physicalNetId === physicalConnMap.getNetConnectedToId(second.pinId);
|
|
5183
|
+
};
|
|
5184
|
+
};
|
|
5185
|
+
|
|
4995
5186
|
// lib/solvers/LongDistancePairSolver/LongDistancePairSolver.ts
|
|
4996
5187
|
var NEAREST_NEIGHBOR_COUNT = 3;
|
|
4997
5188
|
var distance3 = (p1, p2) => {
|
|
4998
5189
|
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
|
|
4999
5190
|
};
|
|
5000
5191
|
var manhattanDistance = (p1, p2) => Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
|
|
5001
|
-
var
|
|
5002
|
-
var between = (value, first, second) => value >= Math.min(first, second) -
|
|
5192
|
+
var EPS7 = 1e-9;
|
|
5193
|
+
var between = (value, first, second) => value >= Math.min(first, second) - EPS7 && value <= Math.max(first, second) + EPS7;
|
|
5003
5194
|
var getAxisAlignedIntersection = (firstStart, firstEnd, secondStart, secondEnd) => {
|
|
5004
|
-
const firstIsHorizontal = Math.abs(firstStart.y - firstEnd.y) <=
|
|
5005
|
-
const firstIsVertical = Math.abs(firstStart.x - firstEnd.x) <=
|
|
5006
|
-
const secondIsHorizontal = Math.abs(secondStart.y - secondEnd.y) <=
|
|
5007
|
-
const secondIsVertical = Math.abs(secondStart.x - secondEnd.x) <=
|
|
5195
|
+
const firstIsHorizontal = Math.abs(firstStart.y - firstEnd.y) <= EPS7;
|
|
5196
|
+
const firstIsVertical = Math.abs(firstStart.x - firstEnd.x) <= EPS7;
|
|
5197
|
+
const secondIsHorizontal = Math.abs(secondStart.y - secondEnd.y) <= EPS7;
|
|
5198
|
+
const secondIsVertical = Math.abs(secondStart.x - secondEnd.x) <= EPS7;
|
|
5008
5199
|
if (firstIsHorizontal && secondIsVertical) {
|
|
5009
5200
|
const point = { x: secondStart.x, y: firstStart.y };
|
|
5010
5201
|
return between(point.x, firstStart.x, firstEnd.x) && between(point.y, secondStart.y, secondEnd.y) ? point : null;
|
|
@@ -5013,7 +5204,7 @@ var getAxisAlignedIntersection = (firstStart, firstEnd, secondStart, secondEnd)
|
|
|
5013
5204
|
const point = { x: firstStart.x, y: secondStart.y };
|
|
5014
5205
|
return between(point.y, firstStart.y, firstEnd.y) && between(point.x, secondStart.x, secondEnd.x) ? point : null;
|
|
5015
5206
|
}
|
|
5016
|
-
if (firstIsHorizontal && secondIsHorizontal && Math.abs(firstStart.y - secondStart.y) <=
|
|
5207
|
+
if (firstIsHorizontal && secondIsHorizontal && Math.abs(firstStart.y - secondStart.y) <= EPS7) {
|
|
5017
5208
|
const overlapMin = Math.max(
|
|
5018
5209
|
Math.min(firstStart.x, firstEnd.x),
|
|
5019
5210
|
Math.min(secondStart.x, secondEnd.x)
|
|
@@ -5022,13 +5213,13 @@ var getAxisAlignedIntersection = (firstStart, firstEnd, secondStart, secondEnd)
|
|
|
5022
5213
|
Math.max(firstStart.x, firstEnd.x),
|
|
5023
5214
|
Math.max(secondStart.x, secondEnd.x)
|
|
5024
5215
|
);
|
|
5025
|
-
if (overlapMin > overlapMax +
|
|
5216
|
+
if (overlapMin > overlapMax + EPS7) return null;
|
|
5026
5217
|
return {
|
|
5027
5218
|
x: Math.max(overlapMin, Math.min(firstStart.x, overlapMax)),
|
|
5028
5219
|
y: firstStart.y
|
|
5029
5220
|
};
|
|
5030
5221
|
}
|
|
5031
|
-
if (firstIsVertical && secondIsVertical && Math.abs(firstStart.x - secondStart.x) <=
|
|
5222
|
+
if (firstIsVertical && secondIsVertical && Math.abs(firstStart.x - secondStart.x) <= EPS7) {
|
|
5032
5223
|
const overlapMin = Math.max(
|
|
5033
5224
|
Math.min(firstStart.y, firstEnd.y),
|
|
5034
5225
|
Math.min(secondStart.y, secondEnd.y)
|
|
@@ -5037,7 +5228,7 @@ var getAxisAlignedIntersection = (firstStart, firstEnd, secondStart, secondEnd)
|
|
|
5037
5228
|
Math.max(firstStart.y, firstEnd.y),
|
|
5038
5229
|
Math.max(secondStart.y, secondEnd.y)
|
|
5039
5230
|
);
|
|
5040
|
-
if (overlapMin > overlapMax +
|
|
5231
|
+
if (overlapMin > overlapMax + EPS7) return null;
|
|
5041
5232
|
return {
|
|
5042
5233
|
x: firstStart.x,
|
|
5043
5234
|
y: Math.max(overlapMin, Math.min(firstStart.y, overlapMax))
|
|
@@ -5066,7 +5257,7 @@ var clipPathAtFirstIntersection = (tracePath, existingTraces) => {
|
|
|
5066
5257
|
const intersection = intersections2[0];
|
|
5067
5258
|
if (!intersection) continue;
|
|
5068
5259
|
const clippedPath = tracePath.slice(0, pathIndex + 1);
|
|
5069
|
-
if (distance3(clippedPath.at(-1), intersection) >
|
|
5260
|
+
if (distance3(clippedPath.at(-1), intersection) > EPS7) {
|
|
5070
5261
|
clippedPath.push(intersection);
|
|
5071
5262
|
}
|
|
5072
5263
|
return clippedPath;
|
|
@@ -5089,6 +5280,11 @@ var LongDistancePairSolver = class extends BaseSolver {
|
|
|
5089
5280
|
}
|
|
5090
5281
|
const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem);
|
|
5091
5282
|
this.netConnMap = netConnMap;
|
|
5283
|
+
const canRecoverParallelPair = getParallelNetLabelPolicy(
|
|
5284
|
+
inputProblem,
|
|
5285
|
+
netConnMap,
|
|
5286
|
+
primaryConnectedPinIds
|
|
5287
|
+
);
|
|
5092
5288
|
const pinMap = /* @__PURE__ */ new Map();
|
|
5093
5289
|
for (const chip of inputProblem.chips) {
|
|
5094
5290
|
this.chipMap[chip.chipId] = chip;
|
|
@@ -5121,6 +5317,7 @@ var LongDistancePairSolver = class extends BaseSolver {
|
|
|
5121
5317
|
const targetPin = pinMap.get(otherPinId);
|
|
5122
5318
|
if (!targetPin) return [];
|
|
5123
5319
|
if (!canRouteGroundPair(sourcePin.pinId, targetPin.pinId)) return [];
|
|
5320
|
+
if (!canRecoverParallelPair(sourcePin, targetPin)) return [];
|
|
5124
5321
|
const isNamedTwoPinConnection = inputProblem.netConnections.some(
|
|
5125
5322
|
(connection) => connection.pinIds.length === 2 && connection.pinIds.includes(sourcePin.pinId) && connection.pinIds.includes(targetPin.pinId)
|
|
5126
5323
|
);
|
|
@@ -6065,9 +6262,9 @@ var getRailAlignmentFallbackCoordinates = ({
|
|
|
6065
6262
|
import { distance as distance4 } from "@tscircuit/math-utils";
|
|
6066
6263
|
|
|
6067
6264
|
// lib/solvers/RailNetLabelCornerPlacementSolver/geometry.ts
|
|
6068
|
-
var
|
|
6265
|
+
var EPS8 = 1e-6;
|
|
6069
6266
|
var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
|
|
6070
|
-
var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
6267
|
+
var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS8 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS8;
|
|
6071
6268
|
var getTraceCorners = (path) => {
|
|
6072
6269
|
const corners = [];
|
|
6073
6270
|
for (let i = 1; i < path.length - 1; i++) {
|
|
@@ -6091,11 +6288,11 @@ var getUniquePinCount = (pinIds) => new Set(pinIds).size;
|
|
|
6091
6288
|
var isTraceCorner = (a, b, c) => getSegmentOrientation(a, b) !== getSegmentOrientation(b, c);
|
|
6092
6289
|
var isPointOnSegment = (point, start, end) => {
|
|
6093
6290
|
if (getSegmentOrientation(start, end) === "horizontal") {
|
|
6094
|
-
return Math.abs(point.y - start.y) <=
|
|
6291
|
+
return Math.abs(point.y - start.y) <= EPS8 && point.x >= Math.min(start.x, end.x) - EPS8 && point.x <= Math.max(start.x, end.x) + EPS8;
|
|
6095
6292
|
}
|
|
6096
|
-
return Math.abs(point.x - start.x) <=
|
|
6293
|
+
return Math.abs(point.x - start.x) <= EPS8 && point.y >= Math.min(start.y, end.y) - EPS8 && point.y <= Math.max(start.y, end.y) + EPS8;
|
|
6097
6294
|
};
|
|
6098
|
-
var getSegmentOrientation = (a, b) => Math.abs(a.y - b.y) <=
|
|
6295
|
+
var getSegmentOrientation = (a, b) => Math.abs(a.y - b.y) <= EPS8 ? "horizontal" : "vertical";
|
|
6099
6296
|
|
|
6100
6297
|
// lib/solvers/TraceCleanupSolver/sameNetRailAlignment/getFixedLabelCoordinate.ts
|
|
6101
6298
|
var getTransitivelyConnectedTraceIds = (group, traces) => {
|
|
@@ -6220,17 +6417,17 @@ var preservesLabelAnchors = (labels, before, after) => labels.every((label) => {
|
|
|
6220
6417
|
});
|
|
6221
6418
|
|
|
6222
6419
|
// lib/solvers/Example28Solver/types.ts
|
|
6223
|
-
var
|
|
6420
|
+
var EPS9 = 1e-9;
|
|
6224
6421
|
|
|
6225
6422
|
// lib/solvers/Example28Solver/segmentRunsAlongRectBoundary.ts
|
|
6226
6423
|
var segmentRunsAlongRectBoundary = (start, end, rect) => {
|
|
6227
|
-
const isVertical6 = Math.abs(start.x - end.x) <
|
|
6228
|
-
const isHorizontal5 = Math.abs(start.y - end.y) <
|
|
6424
|
+
const isVertical6 = Math.abs(start.x - end.x) < EPS9;
|
|
6425
|
+
const isHorizontal5 = Math.abs(start.y - end.y) < EPS9;
|
|
6229
6426
|
if (isVertical6) {
|
|
6230
|
-
return Math.abs(start.x - rect.minX) <
|
|
6427
|
+
return Math.abs(start.x - rect.minX) < EPS9 || Math.abs(start.x - rect.maxX) < EPS9;
|
|
6231
6428
|
}
|
|
6232
6429
|
if (isHorizontal5) {
|
|
6233
|
-
return Math.abs(start.y - rect.minY) <
|
|
6430
|
+
return Math.abs(start.y - rect.minY) < EPS9 || Math.abs(start.y - rect.maxY) < EPS9;
|
|
6234
6431
|
}
|
|
6235
6432
|
return false;
|
|
6236
6433
|
};
|
|
@@ -6245,10 +6442,10 @@ var getPathLength4 = (path) => {
|
|
|
6245
6442
|
return length;
|
|
6246
6443
|
};
|
|
6247
6444
|
var getDistance2 = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
|
|
6248
|
-
var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) <
|
|
6249
|
-
var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) <
|
|
6445
|
+
var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS9 || Math.abs(start.y - end.y) < EPS9;
|
|
6446
|
+
var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) < EPS9 ? "horizontal" : "vertical";
|
|
6250
6447
|
var projectPointToSegment = (point, start, end) => {
|
|
6251
|
-
if (Math.abs(start.x - end.x) <
|
|
6448
|
+
if (Math.abs(start.x - end.x) < EPS9) {
|
|
6252
6449
|
return {
|
|
6253
6450
|
x: start.x,
|
|
6254
6451
|
y: Math.min(
|
|
@@ -6257,7 +6454,7 @@ var projectPointToSegment = (point, start, end) => {
|
|
|
6257
6454
|
)
|
|
6258
6455
|
};
|
|
6259
6456
|
}
|
|
6260
|
-
if (Math.abs(start.y - end.y) <
|
|
6457
|
+
if (Math.abs(start.y - end.y) < EPS9) {
|
|
6261
6458
|
return {
|
|
6262
6459
|
x: Math.min(
|
|
6263
6460
|
Math.max(point.x, Math.min(start.x, end.x)),
|
|
@@ -6300,9 +6497,9 @@ var findSegmentContainingPoint = (path, point) => {
|
|
|
6300
6497
|
};
|
|
6301
6498
|
var isPointWithinSegmentPrimaryRange = (point, segment) => {
|
|
6302
6499
|
if (segment.orientation === "horizontal") {
|
|
6303
|
-
return point.x >= Math.min(segment.start.x, segment.end.x) -
|
|
6500
|
+
return point.x >= Math.min(segment.start.x, segment.end.x) - EPS9 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS9;
|
|
6304
6501
|
}
|
|
6305
|
-
return point.y >= Math.min(segment.start.y, segment.end.y) -
|
|
6502
|
+
return point.y >= Math.min(segment.start.y, segment.end.y) - EPS9 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS9;
|
|
6306
6503
|
};
|
|
6307
6504
|
var findPreferredReroutedSegment = (path, originalSegmentIndex, originalSegmentCount, orientation, anchorPoint) => {
|
|
6308
6505
|
const matchingSegments = getSegments(path).filter(
|
|
@@ -6330,18 +6527,18 @@ var projectPointToPath = (point, path) => {
|
|
|
6330
6527
|
return bestPoint;
|
|
6331
6528
|
};
|
|
6332
6529
|
var segmentsIntersect = (a1, a2, b1, b2) => {
|
|
6333
|
-
const aVertical = Math.abs(a1.x - a2.x) <
|
|
6334
|
-
const bVertical = Math.abs(b1.x - b2.x) <
|
|
6335
|
-
const between2 = (value, p1, p2) => value >= Math.min(p1, p2) -
|
|
6530
|
+
const aVertical = Math.abs(a1.x - a2.x) < EPS9;
|
|
6531
|
+
const bVertical = Math.abs(b1.x - b2.x) < EPS9;
|
|
6532
|
+
const between2 = (value, p1, p2) => value >= Math.min(p1, p2) - EPS9 && value <= Math.max(p1, p2) + EPS9;
|
|
6336
6533
|
if (aVertical && bVertical) {
|
|
6337
|
-
if (Math.abs(a1.x - b1.x) >
|
|
6534
|
+
if (Math.abs(a1.x - b1.x) > EPS9) return false;
|
|
6338
6535
|
const overlap = Math.min(Math.max(a1.y, a2.y), Math.max(b1.y, b2.y)) - Math.max(Math.min(a1.y, a2.y), Math.min(b1.y, b2.y));
|
|
6339
|
-
return overlap >
|
|
6536
|
+
return overlap > EPS9;
|
|
6340
6537
|
}
|
|
6341
6538
|
if (!aVertical && !bVertical) {
|
|
6342
|
-
if (Math.abs(a1.y - b1.y) >
|
|
6539
|
+
if (Math.abs(a1.y - b1.y) > EPS9) return false;
|
|
6343
6540
|
const overlap = Math.min(Math.max(a1.x, a2.x), Math.max(b1.x, b2.x)) - Math.max(Math.min(a1.x, a2.x), Math.min(b1.x, b2.x));
|
|
6344
|
-
return overlap >
|
|
6541
|
+
return overlap > EPS9;
|
|
6345
6542
|
}
|
|
6346
6543
|
const verticalA = aVertical ? a1 : b1;
|
|
6347
6544
|
const verticalB = aVertical ? a2 : b2;
|
|
@@ -6798,7 +6995,7 @@ var getTraceObstacles = (allTraces, excludeTraceId) => {
|
|
|
6798
6995
|
|
|
6799
6996
|
// lib/solvers/TraceCleanupSolver/sub-solver/findIntersectionsWithObstacles.ts
|
|
6800
6997
|
import { getSegmentIntersection } from "@tscircuit/math-utils/line-intersections";
|
|
6801
|
-
var
|
|
6998
|
+
var EPS10 = 1e-6;
|
|
6802
6999
|
var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
|
|
6803
7000
|
const intersections2 = [];
|
|
6804
7001
|
for (const obstacle of obstacles) {
|
|
@@ -6817,7 +7014,7 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
|
|
|
6817
7014
|
}
|
|
6818
7015
|
return intersections2;
|
|
6819
7016
|
};
|
|
6820
|
-
var isSamePoint = (first, second) => Math.abs(first.x - second.x) <
|
|
7017
|
+
var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS10 && Math.abs(first.y - second.y) < EPS10;
|
|
6821
7018
|
var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
|
|
6822
7019
|
const crossings = [];
|
|
6823
7020
|
const firstPathSegmentIndex = options.includeTerminalSegments ? 0 : 1;
|
|
@@ -6827,11 +7024,11 @@ var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
|
|
|
6827
7024
|
for (let pathSegmentIndex = firstPathSegmentIndex; pathSegmentIndex < lastPathSegmentIndex; pathSegmentIndex++) {
|
|
6828
7025
|
const start = path[pathSegmentIndex];
|
|
6829
7026
|
const end = path[pathSegmentIndex + 1];
|
|
6830
|
-
const isVertical6 = Math.abs(start.x - end.x) <
|
|
7027
|
+
const isVertical6 = Math.abs(start.x - end.x) < EPS10;
|
|
6831
7028
|
for (let otherPathSegmentIndex = firstOtherPathSegmentIndex; otherPathSegmentIndex < lastOtherPathSegmentIndex; otherPathSegmentIndex++) {
|
|
6832
7029
|
const otherStart = otherPath[otherPathSegmentIndex];
|
|
6833
7030
|
const otherEnd = otherPath[otherPathSegmentIndex + 1];
|
|
6834
|
-
const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) <
|
|
7031
|
+
const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS10;
|
|
6835
7032
|
if (isVertical6 === otherIsVertical) continue;
|
|
6836
7033
|
const intersection = getSegmentIntersection(
|
|
6837
7034
|
start,
|
|
@@ -6851,8 +7048,8 @@ var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
|
|
|
6851
7048
|
};
|
|
6852
7049
|
|
|
6853
7050
|
// lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts
|
|
6854
|
-
var
|
|
6855
|
-
var isVertical3 = (a, b, eps =
|
|
7051
|
+
var EPS11 = 1e-6;
|
|
7052
|
+
var isVertical3 = (a, b, eps = EPS11) => Math.abs(a.x - b.x) < eps;
|
|
6856
7053
|
var generateLShapeRerouteCandidates = ({
|
|
6857
7054
|
lShape,
|
|
6858
7055
|
rectangle,
|
|
@@ -6865,7 +7062,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6865
7062
|
let c2;
|
|
6866
7063
|
let i1_padded = interactionPoint1;
|
|
6867
7064
|
let i2_padded = interactionPoint2;
|
|
6868
|
-
if (Math.abs(p2.x - x) <
|
|
7065
|
+
if (Math.abs(p2.x - x) < EPS11 && Math.abs(p2.y - (y + height)) < EPS11) {
|
|
6869
7066
|
c2 = { x: x + width + padding, y: y - padding };
|
|
6870
7067
|
if (isVertical3(p1, p2)) {
|
|
6871
7068
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
|
|
@@ -6877,7 +7074,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6877
7074
|
} else {
|
|
6878
7075
|
i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
|
|
6879
7076
|
}
|
|
6880
|
-
} else if (Math.abs(p2.x - (x + width)) <
|
|
7077
|
+
} else if (Math.abs(p2.x - (x + width)) < EPS11 && Math.abs(p2.y - (y + height)) < EPS11) {
|
|
6881
7078
|
c2 = { x: x - padding, y: y - padding };
|
|
6882
7079
|
if (isVertical3(p1, p2)) {
|
|
6883
7080
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
|
|
@@ -6889,7 +7086,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6889
7086
|
} else {
|
|
6890
7087
|
i2_padded = { x: interactionPoint2.x - padding, y: interactionPoint2.y };
|
|
6891
7088
|
}
|
|
6892
|
-
} else if (Math.abs(p2.x - x) <
|
|
7089
|
+
} else if (Math.abs(p2.x - x) < EPS11 && Math.abs(p2.y - y) < EPS11) {
|
|
6893
7090
|
c2 = { x: x + width + padding, y: y + height + padding };
|
|
6894
7091
|
if (isVertical3(p1, p2)) {
|
|
6895
7092
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
|
|
@@ -6901,7 +7098,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
6901
7098
|
} else {
|
|
6902
7099
|
i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
|
|
6903
7100
|
}
|
|
6904
|
-
} else if (Math.abs(p2.x - (x + width)) <
|
|
7101
|
+
} else if (Math.abs(p2.x - (x + width)) < EPS11 && Math.abs(p2.y - y) < EPS11) {
|
|
6905
7102
|
c2 = { x: x - padding, y: y + height + padding };
|
|
6906
7103
|
if (isVertical3(p1, p2)) {
|
|
6907
7104
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
|
|
@@ -6975,7 +7172,7 @@ var generatePerpendicularTraceDetours = ({
|
|
|
6975
7172
|
const buildDetours = (path, index) => {
|
|
6976
7173
|
const start = path[index];
|
|
6977
7174
|
const end = path[index + 1];
|
|
6978
|
-
const movingAxis = Math.abs(start.x - end.x) <
|
|
7175
|
+
const movingAxis = Math.abs(start.x - end.x) < EPS11 ? "y" : "x";
|
|
6979
7176
|
const detourAxis = movingAxis === "x" ? "y" : "x";
|
|
6980
7177
|
const bounds = obstacleBounds ?? {
|
|
6981
7178
|
minX: Math.min(obstacleStart.x, obstacleEnd.x),
|
|
@@ -7602,9 +7799,9 @@ var UntangleTraceSubsolver = class extends BaseSolver {
|
|
|
7602
7799
|
};
|
|
7603
7800
|
|
|
7604
7801
|
// lib/solvers/TraceCleanupSolver/is4PointRectangle.ts
|
|
7605
|
-
var
|
|
7606
|
-
var sameX = (a, b) => Math.abs(a.x - b.x) <=
|
|
7607
|
-
var sameY = (a, b) => Math.abs(a.y - b.y) <=
|
|
7802
|
+
var EPS12 = 1e-6;
|
|
7803
|
+
var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS12;
|
|
7804
|
+
var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS12;
|
|
7608
7805
|
var is4PointRectangle = (path) => {
|
|
7609
7806
|
if (path.length !== 4) return false;
|
|
7610
7807
|
const [p0, p1, p2, p3] = path;
|
|
@@ -7614,7 +7811,7 @@ var is4PointRectangle = (path) => {
|
|
|
7614
7811
|
};
|
|
7615
7812
|
|
|
7616
7813
|
// lib/solvers/TraceCleanupSolver/rerouteGeneratedNetLabelConnectorCrossings.ts
|
|
7617
|
-
var
|
|
7814
|
+
var EPS13 = 1e-6;
|
|
7618
7815
|
var getConnectorObstacleBounds = (connector, segmentIndex, labels) => {
|
|
7619
7816
|
const start = connector.tracePath[segmentIndex];
|
|
7620
7817
|
const end = connector.tracePath[segmentIndex + 1];
|
|
@@ -7706,7 +7903,7 @@ var rerouteGeneratedNetLabelConnectorCrossings = ({
|
|
|
7706
7903
|
chipBounds: [],
|
|
7707
7904
|
clearance
|
|
7708
7905
|
}).filter(
|
|
7709
|
-
(candidate) => getPathLength4(candidate.path) <= getPathLength4(trace.tracePath) +
|
|
7906
|
+
(candidate) => getPathLength4(candidate.path) <= getPathLength4(trace.tracePath) + EPS13 && countTurns(candidate.path) <= countTurns(trace.tracePath) + 2 && !isPathCollidingWithObstacles(
|
|
7710
7907
|
candidate.path,
|
|
7711
7908
|
componentAndTextObstacles
|
|
7712
7909
|
) && !hasCollisionsWithLabels(candidate.path, foreignLabelBounds) && !isPathColliding(candidate.path, foreignTraces, trace.mspPairId).isColliding && !doesPathCoincideWithTraces(candidate.path, foreignTraces)
|
|
@@ -7717,7 +7914,7 @@ var rerouteGeneratedNetLabelConnectorCrossings = ({
|
|
|
7717
7914
|
});
|
|
7718
7915
|
candidates.sort((first, second) => {
|
|
7719
7916
|
const lengthDifference = getPathLength4(first.path) - getPathLength4(second.path);
|
|
7720
|
-
return Math.abs(lengthDifference) >
|
|
7917
|
+
return Math.abs(lengthDifference) > EPS13 ? lengthDifference : countTurns(first.path) - countTurns(second.path);
|
|
7721
7918
|
});
|
|
7722
7919
|
const bestCandidate = candidates[0];
|
|
7723
7920
|
if (!bestCandidate) break;
|
|
@@ -8099,7 +8296,7 @@ var doesPathRunAlongChipBoundary = (path, chipObstacles) => {
|
|
|
8099
8296
|
const end = path[i + 1];
|
|
8100
8297
|
for (const obstacle of chipObstacles) {
|
|
8101
8298
|
if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
|
|
8102
|
-
if (getSegmentOverlapWithRectSpan(start, end, obstacle) >
|
|
8299
|
+
if (getSegmentOverlapWithRectSpan(start, end, obstacle) > EPS9) {
|
|
8103
8300
|
return true;
|
|
8104
8301
|
}
|
|
8105
8302
|
}
|
|
@@ -8114,13 +8311,13 @@ var getChipBoundaryOverlap = (path, chipObstacles) => {
|
|
|
8114
8311
|
for (const obstacle of chipObstacles) {
|
|
8115
8312
|
if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
|
|
8116
8313
|
const overlap = getSegmentOverlapWithRectSpan(start, end, obstacle);
|
|
8117
|
-
if (overlap >
|
|
8314
|
+
if (overlap > EPS9) total += overlap;
|
|
8118
8315
|
}
|
|
8119
8316
|
}
|
|
8120
8317
|
return total;
|
|
8121
8318
|
};
|
|
8122
8319
|
var getSegmentOverlapWithRectSpan = (start, end, rect) => {
|
|
8123
|
-
const isVertical6 = Math.abs(start.x - end.x) <
|
|
8320
|
+
const isVertical6 = Math.abs(start.x - end.x) < EPS9;
|
|
8124
8321
|
if (isVertical6) {
|
|
8125
8322
|
return Math.min(Math.max(start.y, end.y), rect.maxY) - Math.max(Math.min(start.y, end.y), rect.minY);
|
|
8126
8323
|
}
|
|
@@ -8885,16 +9082,16 @@ var createPortOnlyLabelConnectorTrace = ({
|
|
|
8885
9082
|
var LABEL_SEARCH_STEP = 0.05;
|
|
8886
9083
|
var MAX_RECORDED_CANDIDATES = 2e3;
|
|
8887
9084
|
var WICK_CLEARANCE = 1e-3;
|
|
8888
|
-
var
|
|
8889
|
-
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE +
|
|
9085
|
+
var EPS14 = 1e-9;
|
|
9086
|
+
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS14;
|
|
8890
9087
|
var CANDIDATE_SELECTED_COLOR2 = "blue";
|
|
8891
9088
|
var CANDIDATE_REJECTED_COLOR2 = "red";
|
|
8892
9089
|
|
|
8893
9090
|
// lib/solvers/AvailableNetOrientationSolver/geometry.ts
|
|
8894
9091
|
var isYOrientation = (orientation) => orientation === "y+" || orientation === "y-";
|
|
8895
9092
|
var isXOrientation = (orientation) => orientation === "x+" || orientation === "x-";
|
|
8896
|
-
var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
8897
|
-
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) >
|
|
9093
|
+
var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS14 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS14;
|
|
9094
|
+
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS14;
|
|
8898
9095
|
var traceCrossesBoundsInterior = (bounds, traceMap) => {
|
|
8899
9096
|
for (const trace of Object.values(traceMap)) {
|
|
8900
9097
|
const points = trace.tracePath;
|
|
@@ -8917,7 +9114,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
|
8917
9114
|
return false;
|
|
8918
9115
|
}
|
|
8919
9116
|
if (sameX2(p1, p2)) {
|
|
8920
|
-
if (p1.x <= interiorBounds.minX +
|
|
9117
|
+
if (p1.x <= interiorBounds.minX + EPS14 || p1.x >= interiorBounds.maxX - EPS14) {
|
|
8921
9118
|
return false;
|
|
8922
9119
|
}
|
|
8923
9120
|
return rangesOverlap(
|
|
@@ -8928,7 +9125,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
|
8928
9125
|
);
|
|
8929
9126
|
}
|
|
8930
9127
|
if (sameY2(p1, p2)) {
|
|
8931
|
-
if (p1.y <= interiorBounds.minY +
|
|
9128
|
+
if (p1.y <= interiorBounds.minY + EPS14 || p1.y >= interiorBounds.maxY - EPS14) {
|
|
8932
9129
|
return false;
|
|
8933
9130
|
}
|
|
8934
9131
|
return rangesOverlap(
|
|
@@ -8976,8 +9173,8 @@ var simplifyOrthogonalPath = (path) => {
|
|
|
8976
9173
|
return simplified;
|
|
8977
9174
|
};
|
|
8978
9175
|
var pointsEqual3 = (a, b) => sameX2(a, b) && sameY2(a, b);
|
|
8979
|
-
var sameX2 = (a, b) => Math.abs(a.x - b.x) <=
|
|
8980
|
-
var sameY2 = (a, b) => Math.abs(a.y - b.y) <=
|
|
9176
|
+
var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS14;
|
|
9177
|
+
var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS14;
|
|
8981
9178
|
var getMaxSearchDistance = (inputProblem) => {
|
|
8982
9179
|
const maxChipWidth = Math.max(
|
|
8983
9180
|
...inputProblem.chips.map((chip) => chip.width),
|
|
@@ -9136,7 +9333,7 @@ var AvailableNetOrientationObstacleIndex = class {
|
|
|
9136
9333
|
}
|
|
9137
9334
|
getTraceSegmentsInBounds(bounds) {
|
|
9138
9335
|
if (!this.traceSegmentIndex) return [];
|
|
9139
|
-
const searchBounds = getPaddedBounds(bounds,
|
|
9336
|
+
const searchBounds = getPaddedBounds(bounds, EPS14);
|
|
9140
9337
|
return this.traceSegmentIndex.search(
|
|
9141
9338
|
searchBounds.minX,
|
|
9142
9339
|
searchBounds.minY,
|
|
@@ -9149,7 +9346,7 @@ var AvailableNetOrientationObstacleIndex = class {
|
|
|
9149
9346
|
for (let pointIndex = 0; pointIndex < tracePath.length - 1; pointIndex++) {
|
|
9150
9347
|
const segmentBounds = getPaddedBounds(
|
|
9151
9348
|
getSegmentBounds(tracePath[pointIndex], tracePath[pointIndex + 1]),
|
|
9152
|
-
|
|
9349
|
+
EPS14
|
|
9153
9350
|
);
|
|
9154
9351
|
for (const labelIndex of this.getLabelIndicesInBounds(segmentBounds)) {
|
|
9155
9352
|
labelIndices.add(labelIndex);
|
|
@@ -9162,7 +9359,7 @@ var AvailableNetOrientationObstacleIndex = class {
|
|
|
9162
9359
|
const start = tracePath[pointIndex];
|
|
9163
9360
|
const end = tracePath[pointIndex + 1];
|
|
9164
9361
|
const nearbyChips = this.chipObstacleSpatialIndex.getChipsInBounds(
|
|
9165
|
-
getPaddedBounds(getSegmentBounds(start, end),
|
|
9362
|
+
getPaddedBounds(getSegmentBounds(start, end), EPS14)
|
|
9166
9363
|
);
|
|
9167
9364
|
for (const chip of nearbyChips) {
|
|
9168
9365
|
if (segmentCrossesBoundsInterior(start, end, chip.bounds)) return true;
|
|
@@ -9619,7 +9816,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9619
9816
|
labelIndex,
|
|
9620
9817
|
orientations
|
|
9621
9818
|
);
|
|
9622
|
-
const rotatedCandidateNeedsLateralBranch = rotatedCandidate !== null && Math.abs(rotatedCandidate.anchorPoint.x - label.anchorPoint.x) >
|
|
9819
|
+
const rotatedCandidateNeedsLateralBranch = rotatedCandidate !== null && Math.abs(rotatedCandidate.anchorPoint.x - label.anchorPoint.x) > EPS14;
|
|
9623
9820
|
if (isDownwardGroundRail && rotatedCandidateNeedsLateralBranch) {
|
|
9624
9821
|
const downwardRailCandidate = this.findValidCandidateInShiftColumn({
|
|
9625
9822
|
label,
|
|
@@ -9678,7 +9875,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9678
9875
|
index,
|
|
9679
9876
|
pin: this.pinMap[otherLabel.pinIds[0]]
|
|
9680
9877
|
})).filter(
|
|
9681
|
-
({ index, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x +
|
|
9878
|
+
({ index, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x + EPS14
|
|
9682
9879
|
).sort((a, b) => a.pin.x - b.pin.x)[0]?.pin;
|
|
9683
9880
|
if (orientation === "y-" && nextPinToRight) return null;
|
|
9684
9881
|
const anchorX = orientation === "y-" ? Math.max(
|
|
@@ -9711,7 +9908,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9711
9908
|
const centeredAnchorY = hasUpFacingStack ? (lowestUpFacingLabelY + highestUpFacingLabelY) / 2 : stackedAnchorY;
|
|
9712
9909
|
const anchorYs = orientation === "y-" ? [centeredAnchorY, stackedAnchorY] : [stackedAnchorY];
|
|
9713
9910
|
for (const anchorY of anchorYs) {
|
|
9714
|
-
if (anchorY - label.anchorPoint.y > this.maxSearchDistance +
|
|
9911
|
+
if (anchorY - label.anchorPoint.y > this.maxSearchDistance + EPS14) {
|
|
9715
9912
|
continue;
|
|
9716
9913
|
}
|
|
9717
9914
|
const candidate = this.createCandidate(
|
|
@@ -9740,11 +9937,11 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9740
9937
|
if (trace.globalConnNetId !== label.globalConnNetId) return false;
|
|
9741
9938
|
const path = trace.tracePath;
|
|
9742
9939
|
return path.some((point, pointIndex) => {
|
|
9743
|
-
if (Math.abs(point.x - label.anchorPoint.x) >
|
|
9940
|
+
if (Math.abs(point.x - label.anchorPoint.x) > EPS14 || Math.abs(point.y - label.anchorPoint.y) > EPS14) {
|
|
9744
9941
|
return false;
|
|
9745
9942
|
}
|
|
9746
9943
|
return [path[pointIndex - 1], path[pointIndex + 1]].some(
|
|
9747
|
-
(neighbor) => neighbor && Math.abs(neighbor.x - point.x) <=
|
|
9944
|
+
(neighbor) => neighbor && Math.abs(neighbor.x - point.x) <= EPS14 && (neighbor.y - point.y) * direction.y > EPS14
|
|
9748
9945
|
);
|
|
9749
9946
|
});
|
|
9750
9947
|
});
|
|
@@ -9834,7 +10031,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9834
10031
|
orientation
|
|
9835
10032
|
);
|
|
9836
10033
|
if (outwardDirection.x === 0 && outwardDirection.y === 0) continue;
|
|
9837
|
-
for (let distance7 = LABEL_SEARCH_STEP; distance7 <= this.maxSearchDistance +
|
|
10034
|
+
for (let distance7 = LABEL_SEARCH_STEP; distance7 <= this.maxSearchDistance + EPS14; distance7 += LABEL_SEARCH_STEP) {
|
|
9838
10035
|
const anchorPoint = {
|
|
9839
10036
|
x: connectorSource.x + outwardDirection.x * distance7,
|
|
9840
10037
|
y: connectorSource.y + outwardDirection.y * distance7
|
|
@@ -9912,7 +10109,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9912
10109
|
const furthestRowPoints = points.filter(
|
|
9913
10110
|
(point) => Math.abs(
|
|
9914
10111
|
point.x * direction.x + point.y * direction.y - furthestAlong
|
|
9915
|
-
) <=
|
|
10112
|
+
) <= EPS14
|
|
9916
10113
|
);
|
|
9917
10114
|
const directHostPinIds = new Set(
|
|
9918
10115
|
[...directHostTraceIds].flatMap(
|
|
@@ -9933,7 +10130,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9933
10130
|
preferNearestBendOnOutwardRow: adjacentTraces.some(
|
|
9934
10131
|
(trace) => furthestRowPoints.some(
|
|
9935
10132
|
(point) => trace.tracePath.some(
|
|
9936
|
-
(tracePoint) => Math.abs(tracePoint.x - point.x) <=
|
|
10133
|
+
(tracePoint) => Math.abs(tracePoint.x - point.x) <= EPS14 && Math.abs(tracePoint.y - point.y) <= EPS14
|
|
9937
10134
|
)
|
|
9938
10135
|
)
|
|
9939
10136
|
)
|
|
@@ -9945,7 +10142,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9945
10142
|
for (let i = 0; i < otherTrace.tracePath.length - 1; i++) {
|
|
9946
10143
|
const start = otherTrace.tracePath[i];
|
|
9947
10144
|
const end = otherTrace.tracePath[i + 1];
|
|
9948
|
-
if (Math.abs(start.x - end.x) <=
|
|
10145
|
+
if (Math.abs(start.x - end.x) <= EPS14 && Math.abs(start.y - end.y) > EPS14) {
|
|
9949
10146
|
verticalRailXs.add(start.x);
|
|
9950
10147
|
}
|
|
9951
10148
|
}
|
|
@@ -9953,7 +10150,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9953
10150
|
for (let i = 0; i < trace.tracePath.length - 1; i++) {
|
|
9954
10151
|
const start = trace.tracePath[i];
|
|
9955
10152
|
const end = trace.tracePath[i + 1];
|
|
9956
|
-
if (Math.abs(start.x - end.x) <=
|
|
10153
|
+
if (Math.abs(start.x - end.x) <= EPS14 && Math.abs(start.y - end.y) > EPS14 && [...verticalRailXs].some((x) => Math.abs(x - start.x) <= EPS14)) {
|
|
9957
10154
|
return true;
|
|
9958
10155
|
}
|
|
9959
10156
|
}
|
|
@@ -9972,7 +10169,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9972
10169
|
);
|
|
9973
10170
|
const maxSearchDistance = this.getSearchDistanceLimit(label, orientation);
|
|
9974
10171
|
const maxOutwardDistance = outwardDirection.x === 0 && outwardDirection.y === 0 ? 0 : this.maxSearchDistance;
|
|
9975
|
-
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance +
|
|
10172
|
+
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS14; outwardDistance += LABEL_SEARCH_STEP) {
|
|
9976
10173
|
const baseAnchor = {
|
|
9977
10174
|
x: initialBaseAnchor.x + outwardDirection.x * outwardDistance,
|
|
9978
10175
|
y: initialBaseAnchor.y + outwardDirection.y * outwardDistance
|
|
@@ -10048,7 +10245,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10048
10245
|
connectorSource,
|
|
10049
10246
|
startDistance = LABEL_SEARCH_STEP
|
|
10050
10247
|
} = params;
|
|
10051
|
-
for (let distance7 = startDistance; distance7 <= maxSearchDistance +
|
|
10248
|
+
for (let distance7 = startDistance; distance7 <= maxSearchDistance + EPS14; distance7 += LABEL_SEARCH_STEP) {
|
|
10052
10249
|
const anchorPoint = {
|
|
10053
10250
|
x: baseAnchor.x + direction.x * distance7,
|
|
10054
10251
|
y: baseAnchor.y + direction.y * distance7
|
|
@@ -10161,14 +10358,14 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10161
10358
|
for (let pointIndex = 0; pointIndex < hostTrace.tracePath.length - 1; pointIndex++) {
|
|
10162
10359
|
const start = hostTrace.tracePath[pointIndex];
|
|
10163
10360
|
const end = hostTrace.tracePath[pointIndex + 1];
|
|
10164
|
-
const segmentIsPerpendicularToLabel = isYOrientation(orientation) ? Math.abs(start.y - end.y) <=
|
|
10361
|
+
const segmentIsPerpendicularToLabel = isYOrientation(orientation) ? Math.abs(start.y - end.y) <= EPS14 : Math.abs(start.x - end.x) <= EPS14;
|
|
10165
10362
|
if (!segmentIsPerpendicularToLabel) continue;
|
|
10166
10363
|
const source = isYOrientation(orientation) ? { x: targetAnchor.x, y: start.y } : { x: start.x, y: targetAnchor.y };
|
|
10167
10364
|
if (!tracePathContainsPoint([start, end], label.anchorPoint) || !tracePathContainsPoint([start, end], source)) {
|
|
10168
10365
|
continue;
|
|
10169
10366
|
}
|
|
10170
10367
|
const targetDistanceAlongOrientation = (targetAnchor.x - source.x) * orientationDirection.x + (targetAnchor.y - source.y) * orientationDirection.y;
|
|
10171
|
-
if (targetDistanceAlongOrientation >= -
|
|
10368
|
+
if (targetDistanceAlongOrientation >= -EPS14) {
|
|
10172
10369
|
projectedSources.push(source);
|
|
10173
10370
|
}
|
|
10174
10371
|
}
|
|
@@ -10427,9 +10624,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10427
10624
|
const { anchorPoint, orientation } = candidate;
|
|
10428
10625
|
const chipBounds = chip.bounds;
|
|
10429
10626
|
if (isYOrientation(orientation)) {
|
|
10430
|
-
return anchorPoint.x < chipBounds.minX -
|
|
10627
|
+
return anchorPoint.x < chipBounds.minX - EPS14 || anchorPoint.x > chipBounds.maxX + EPS14;
|
|
10431
10628
|
}
|
|
10432
|
-
return anchorPoint.y < chipBounds.minY -
|
|
10629
|
+
return anchorPoint.y < chipBounds.minY - EPS14 || anchorPoint.y > chipBounds.maxY + EPS14;
|
|
10433
10630
|
});
|
|
10434
10631
|
}
|
|
10435
10632
|
staysOutsideConnectedPinRow(params) {
|
|
@@ -10437,9 +10634,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10437
10634
|
const pin = this.pinMap[label.pinIds[0]];
|
|
10438
10635
|
if (!pin || !isYOrientation(candidate.orientation)) return false;
|
|
10439
10636
|
if (candidate.anchorPoint.x < pin.x) {
|
|
10440
|
-
return bounds.maxX <= pin.x + CONNECTED_PIN_ROW_OVERLAP_TOLERANCE +
|
|
10637
|
+
return bounds.maxX <= pin.x + CONNECTED_PIN_ROW_OVERLAP_TOLERANCE + EPS14;
|
|
10441
10638
|
}
|
|
10442
|
-
return bounds.minX >= pin.x - CONNECTED_PIN_ROW_OVERLAP_TOLERANCE -
|
|
10639
|
+
return bounds.minX >= pin.x - CONNECTED_PIN_ROW_OVERLAP_TOLERANCE - EPS14;
|
|
10443
10640
|
}
|
|
10444
10641
|
getBoundsStatus(candidateBoundsCheck) {
|
|
10445
10642
|
const { bounds, labelIndex, label, ignoreChipCollisions } = candidateBoundsCheck;
|
|
@@ -10520,14 +10717,14 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10520
10717
|
candidate.width,
|
|
10521
10718
|
candidate.height
|
|
10522
10719
|
);
|
|
10523
|
-
if (labelBounds.minY < chip.bounds.minY -
|
|
10720
|
+
if (labelBounds.minY < chip.bounds.minY - EPS14 || labelBounds.maxY > chip.bounds.maxY + EPS14) {
|
|
10524
10721
|
return false;
|
|
10525
10722
|
}
|
|
10526
|
-
if (candidate.anchorPoint.x >= chip.bounds.minX -
|
|
10723
|
+
if (candidate.anchorPoint.x >= chip.bounds.minX - EPS14 && candidate.anchorPoint.x <= chip.bounds.maxX + EPS14) {
|
|
10527
10724
|
return false;
|
|
10528
10725
|
}
|
|
10529
10726
|
return chip.pins.every(
|
|
10530
|
-
(pin) => label.pinIds.includes(pin.pinId) || pin.y <= labelBounds.minY +
|
|
10727
|
+
(pin) => label.pinIds.includes(pin.pinId) || pin.y <= labelBounds.minY + EPS14 || pin.y >= labelBounds.maxY - EPS14
|
|
10531
10728
|
);
|
|
10532
10729
|
}
|
|
10533
10730
|
getTextBlockedMultiPinRailTraces(label, orientation) {
|
|
@@ -10554,20 +10751,20 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10554
10751
|
const pins = [...connectedPinIds].map((pinId) => this.pinMap[pinId]);
|
|
10555
10752
|
const direction = dir(orientation);
|
|
10556
10753
|
const pinX = pins[0].x;
|
|
10557
|
-
if (pins.some((pin) => Math.abs(pin.x - pinX) >
|
|
10558
|
-
const sidePins = this.inputProblem.chips.find((chip) => chip.chipId === componentId).pins.filter((pin) => Math.abs(pin.x - pinX) <=
|
|
10754
|
+
if (pins.some((pin) => Math.abs(pin.x - pinX) > EPS14)) return null;
|
|
10755
|
+
const sidePins = this.inputProblem.chips.find((chip) => chip.chipId === componentId).pins.filter((pin) => Math.abs(pin.x - pinX) <= EPS14);
|
|
10559
10756
|
const minY = Math.min(...pins.map((pin) => pin.y));
|
|
10560
10757
|
const maxY = Math.max(...pins.map((pin) => pin.y));
|
|
10561
10758
|
if (sidePins.some(
|
|
10562
|
-
(pin) => pin.y >= minY -
|
|
10563
|
-
) || orientation === "y-" && minY > Math.min(...sidePins.map((pin) => pin.y)) +
|
|
10759
|
+
(pin) => pin.y >= minY - EPS14 && pin.y <= maxY + EPS14 && !connectedPinIds.has(pin.pinId)
|
|
10760
|
+
) || orientation === "y-" && minY > Math.min(...sidePins.map((pin) => pin.y)) + EPS14 || orientation === "y+" && maxY < Math.max(...sidePins.map((pin) => pin.y)) - EPS14) {
|
|
10564
10761
|
return null;
|
|
10565
10762
|
}
|
|
10566
10763
|
const outerPinPosition = Math.max(
|
|
10567
10764
|
...pins.map((pin) => pin.x * direction.x + pin.y * direction.y)
|
|
10568
10765
|
);
|
|
10569
10766
|
const blockedByText = (this.inputProblem.textBoxes ?? []).some(
|
|
10570
|
-
(textBox) => textBox.chipId === componentId && textBox.center.x * direction.x + textBox.center.y * direction.y > outerPinPosition +
|
|
10767
|
+
(textBox) => textBox.chipId === componentId && textBox.center.x * direction.x + textBox.center.y * direction.y > outerPinPosition + EPS14
|
|
10571
10768
|
);
|
|
10572
10769
|
return blockedByText ? [...connectedTraces] : null;
|
|
10573
10770
|
}
|
|
@@ -10583,7 +10780,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10583
10780
|
...new Set(
|
|
10584
10781
|
localTraces.flatMap((trace) => trace.tracePath.map((point) => point.x))
|
|
10585
10782
|
)
|
|
10586
|
-
].filter((x) => Math.abs(x - pinX) >
|
|
10783
|
+
].filter((x) => Math.abs(x - pinX) > EPS14).sort((a, b) => Math.abs(a - pinX) - Math.abs(b - pinX));
|
|
10587
10784
|
for (const x of railXs) {
|
|
10588
10785
|
const connectorSource = { x, y: connectorY };
|
|
10589
10786
|
if (!Object.values(this.traceMap).some(
|
|
@@ -10646,8 +10843,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10646
10843
|
if (!chip) return null;
|
|
10647
10844
|
const sides = new Set(
|
|
10648
10845
|
pins.map((pin) => {
|
|
10649
|
-
if (Math.abs(pin.x - chip.bounds.minX) <=
|
|
10650
|
-
if (Math.abs(pin.x - chip.bounds.maxX) <=
|
|
10846
|
+
if (Math.abs(pin.x - chip.bounds.minX) <= EPS14) return "left";
|
|
10847
|
+
if (Math.abs(pin.x - chip.bounds.maxX) <= EPS14) return "right";
|
|
10651
10848
|
return null;
|
|
10652
10849
|
})
|
|
10653
10850
|
);
|
|
@@ -10684,7 +10881,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10684
10881
|
return null;
|
|
10685
10882
|
}
|
|
10686
10883
|
const renderedWidth = this.getNetConnectionForLabel(label)?.netLabelHeight;
|
|
10687
|
-
if (renderedWidth === void 0 || renderedWidth <= label.width + label.height +
|
|
10884
|
+
if (renderedWidth === void 0 || renderedWidth <= label.width + label.height + EPS14) {
|
|
10688
10885
|
return null;
|
|
10689
10886
|
}
|
|
10690
10887
|
const placementBaseCenter = getCenterFromAnchor(
|
|
@@ -10759,16 +10956,16 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10759
10956
|
}
|
|
10760
10957
|
sharesChipBoundary(bounds) {
|
|
10761
10958
|
const boundarySearchBounds = {
|
|
10762
|
-
minX: bounds.minX - WICK_CLEARANCE -
|
|
10763
|
-
minY: bounds.minY - WICK_CLEARANCE -
|
|
10764
|
-
maxX: bounds.maxX + WICK_CLEARANCE +
|
|
10765
|
-
maxY: bounds.maxY + WICK_CLEARANCE +
|
|
10959
|
+
minX: bounds.minX - WICK_CLEARANCE - EPS14,
|
|
10960
|
+
minY: bounds.minY - WICK_CLEARANCE - EPS14,
|
|
10961
|
+
maxX: bounds.maxX + WICK_CLEARANCE + EPS14,
|
|
10962
|
+
maxY: bounds.maxY + WICK_CLEARANCE + EPS14
|
|
10766
10963
|
};
|
|
10767
10964
|
const nearbyChips = this.chipObstacleSpatialIndex.getChipsInBounds(boundarySearchBounds);
|
|
10768
10965
|
for (const chip of nearbyChips) {
|
|
10769
10966
|
const chipBounds = chip.bounds;
|
|
10770
|
-
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE +
|
|
10771
|
-
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE +
|
|
10967
|
+
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS14 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS14;
|
|
10968
|
+
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS14 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS14;
|
|
10772
10969
|
if (adjacentToVerticalSide && rangesOverlap(
|
|
10773
10970
|
bounds.minY,
|
|
10774
10971
|
bounds.maxY,
|
|
@@ -10830,7 +11027,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10830
11027
|
let nearestDistance = Number.POSITIVE_INFINITY;
|
|
10831
11028
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
10832
11029
|
const bounds = chip.bounds;
|
|
10833
|
-
if (point.x < bounds.minX -
|
|
11030
|
+
if (point.x < bounds.minX - EPS14 || point.x > bounds.maxX + EPS14 || point.y < bounds.minY - EPS14 || point.y > bounds.maxY + EPS14) {
|
|
10834
11031
|
continue;
|
|
10835
11032
|
}
|
|
10836
11033
|
for (const [side, distance7] of getSideDistances(point, bounds)) {
|
|
@@ -10847,8 +11044,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10847
11044
|
let nearestDistanceSq = Number.POSITIVE_INFINITY;
|
|
10848
11045
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
10849
11046
|
const bounds = chip.bounds;
|
|
10850
|
-
const dx = point.x < bounds.minX -
|
|
10851
|
-
const dy = point.y < bounds.minY -
|
|
11047
|
+
const dx = point.x < bounds.minX - EPS14 ? bounds.minX - point.x : point.x > bounds.maxX + EPS14 ? point.x - bounds.maxX : 0;
|
|
11048
|
+
const dy = point.y < bounds.minY - EPS14 ? bounds.minY - point.y : point.y > bounds.maxY + EPS14 ? point.y - bounds.maxY : 0;
|
|
10852
11049
|
if (dx === 0 && dy === 0) continue;
|
|
10853
11050
|
const distanceSq = dx ** 2 + dy ** 2;
|
|
10854
11051
|
if (distanceSq >= nearestDistanceSq) continue;
|
|
@@ -11164,7 +11361,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
11164
11361
|
for (const anchorPoint of getTraceCorners(path)) {
|
|
11165
11362
|
const cornerIndex = path.indexOf(anchorPoint);
|
|
11166
11363
|
const anchorAlignedToPin = pins.some(
|
|
11167
|
-
(pin) => Math.abs(pin.x - anchorPoint.x) <=
|
|
11364
|
+
(pin) => Math.abs(pin.x - anchorPoint.x) <= EPS8
|
|
11168
11365
|
);
|
|
11169
11366
|
const pinAligned = anchorAlignedToPin || allowRailAlignedFallback && this.isPinAlignedCorner(path, cornerIndex);
|
|
11170
11367
|
if (!pinAligned) continue;
|
|
@@ -11204,12 +11401,12 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
11204
11401
|
return traceCrossesBoundsInterior(bounds, otherNetTraceMap);
|
|
11205
11402
|
}
|
|
11206
11403
|
pointsEqual(a, b) {
|
|
11207
|
-
return Math.abs(a.x - b.x) <=
|
|
11404
|
+
return Math.abs(a.x - b.x) <= EPS8 && Math.abs(a.y - b.y) <= EPS8;
|
|
11208
11405
|
}
|
|
11209
11406
|
getVerticalSegmentPointIndices(path, cornerIndex) {
|
|
11210
11407
|
const corner = path[cornerIndex];
|
|
11211
|
-
const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <=
|
|
11212
|
-
const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <=
|
|
11408
|
+
const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <= EPS8;
|
|
11409
|
+
const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <= EPS8;
|
|
11213
11410
|
if (previousIsVertical === nextIsVertical) return null;
|
|
11214
11411
|
const indices = previousIsVertical ? [cornerIndex - 1, cornerIndex] : [cornerIndex, cornerIndex + 1];
|
|
11215
11412
|
return indices;
|
|
@@ -11259,7 +11456,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
11259
11456
|
const end = otherTrace.tracePath[i + 1];
|
|
11260
11457
|
if (!segmentCrossesBoundsInterior(start, end, labelBounds)) continue;
|
|
11261
11458
|
const halfLabelWidth = label.width / 2;
|
|
11262
|
-
if (Math.abs(start.x - end.x) <=
|
|
11459
|
+
if (Math.abs(start.x - end.x) <= EPS8) {
|
|
11263
11460
|
shiftedCoordinates.add(
|
|
11264
11461
|
start.x - halfLabelWidth - LABEL_TRACE_CLEARANCE3
|
|
11265
11462
|
);
|
|
@@ -11277,7 +11474,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
|
|
|
11277
11474
|
}
|
|
11278
11475
|
}
|
|
11279
11476
|
return [...shiftedCoordinates].flatMap((x) => {
|
|
11280
|
-
if (Math.abs(x - corner.x) <=
|
|
11477
|
+
if (Math.abs(x - corner.x) <= EPS8) return [];
|
|
11281
11478
|
const reroutedTracePath = simplifyPath(
|
|
11282
11479
|
path.map(
|
|
11283
11480
|
(point, pointIndex) => verticalPointIndices.includes(pointIndex) ? { ...point, x } : point
|
|
@@ -11408,11 +11605,11 @@ var getOrientationConstraint = (inputProblem, label) => {
|
|
|
11408
11605
|
};
|
|
11409
11606
|
|
|
11410
11607
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/geometry.ts
|
|
11411
|
-
var
|
|
11608
|
+
var EPS15 = 1e-6;
|
|
11412
11609
|
var TRACE_BOUNDARY_TOLERANCE2 = 1e-6;
|
|
11413
11610
|
var getLabelBounds = (label) => getRectBounds(label.center, label.width, label.height);
|
|
11414
|
-
var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
11415
|
-
var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -
|
|
11611
|
+
var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS15 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS15;
|
|
11612
|
+
var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS15 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS15;
|
|
11416
11613
|
var traceCrossesBoundsInterior2 = (bounds, traces) => {
|
|
11417
11614
|
for (const trace of traces) {
|
|
11418
11615
|
const points = trace.tracePath;
|
|
@@ -11458,7 +11655,7 @@ var getPointAtTraceDistance = (trace, distance7) => {
|
|
|
11458
11655
|
const end = trace.tracePath[i + 1];
|
|
11459
11656
|
const segmentLength = getManhattanDistance(start, end);
|
|
11460
11657
|
const nextDistance = pathDistance + segmentLength;
|
|
11461
|
-
if (distance7 <= nextDistance +
|
|
11658
|
+
if (distance7 <= nextDistance + EPS15) {
|
|
11462
11659
|
const offset = Math.max(
|
|
11463
11660
|
0,
|
|
11464
11661
|
Math.min(segmentLength, distance7 - pathDistance)
|
|
@@ -11497,7 +11694,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
11497
11694
|
return false;
|
|
11498
11695
|
}
|
|
11499
11696
|
if (isVertical4(start, end)) {
|
|
11500
|
-
if (start.x <= interior.minX +
|
|
11697
|
+
if (start.x <= interior.minX + EPS15 || start.x >= interior.maxX - EPS15) {
|
|
11501
11698
|
return false;
|
|
11502
11699
|
}
|
|
11503
11700
|
return rangesOverlap2(
|
|
@@ -11508,7 +11705,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
11508
11705
|
);
|
|
11509
11706
|
}
|
|
11510
11707
|
if (isHorizontal3(start, end)) {
|
|
11511
|
-
if (start.y <= interior.minY +
|
|
11708
|
+
if (start.y <= interior.minY + EPS15 || start.y >= interior.maxY - EPS15) {
|
|
11512
11709
|
return false;
|
|
11513
11710
|
}
|
|
11514
11711
|
return rangesOverlap2(
|
|
@@ -11522,10 +11719,10 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
11522
11719
|
};
|
|
11523
11720
|
var isPointOnSegment2 = (point, start, end) => {
|
|
11524
11721
|
if (isHorizontal3(start, end)) {
|
|
11525
|
-
return Math.abs(point.y - start.y) <=
|
|
11722
|
+
return Math.abs(point.y - start.y) <= EPS15 && point.x >= Math.min(start.x, end.x) - EPS15 && point.x <= Math.max(start.x, end.x) + EPS15;
|
|
11526
11723
|
}
|
|
11527
11724
|
if (isVertical4(start, end)) {
|
|
11528
|
-
return Math.abs(point.x - start.x) <=
|
|
11725
|
+
return Math.abs(point.x - start.x) <= EPS15 && point.y >= Math.min(start.y, end.y) - EPS15 && point.y <= Math.max(start.y, end.y) + EPS15;
|
|
11529
11726
|
}
|
|
11530
11727
|
return false;
|
|
11531
11728
|
};
|
|
@@ -11533,9 +11730,9 @@ var getSegmentDirection = (start, end) => ({
|
|
|
11533
11730
|
x: isVertical4(start, end) ? 0 : Math.sign(end.x - start.x),
|
|
11534
11731
|
y: isHorizontal3(start, end) ? 0 : Math.sign(end.y - start.y)
|
|
11535
11732
|
});
|
|
11536
|
-
var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <=
|
|
11537
|
-
var isVertical4 = (start, end) => Math.abs(start.x - end.x) <=
|
|
11538
|
-
var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) >
|
|
11733
|
+
var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <= EPS15;
|
|
11734
|
+
var isVertical4 = (start, end) => Math.abs(start.x - end.x) <= EPS15;
|
|
11735
|
+
var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS15;
|
|
11539
11736
|
var getUniquePinCount2 = (pinIds) => new Set(pinIds).size;
|
|
11540
11737
|
|
|
11541
11738
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts
|
|
@@ -11592,7 +11789,7 @@ var getCandidateDistances = (traceLength, vertexDistances) => {
|
|
|
11592
11789
|
for (const distance7 of vertexDistances) {
|
|
11593
11790
|
distances.add(roundDistance(distance7));
|
|
11594
11791
|
}
|
|
11595
|
-
return [...distances].filter((distance7) => distance7 >= -
|
|
11792
|
+
return [...distances].filter((distance7) => distance7 >= -EPS15 && distance7 <= traceLength + EPS15).sort((a, b) => a - b);
|
|
11596
11793
|
};
|
|
11597
11794
|
var getOrientationsForPoint = (params) => {
|
|
11598
11795
|
const { inputProblem, label, point, orientationConstraint } = params;
|
|
@@ -11681,13 +11878,13 @@ var getOutwardOrientationOptions = (point, chipBounds) => {
|
|
|
11681
11878
|
};
|
|
11682
11879
|
var getOutwardAxisOption = (params) => {
|
|
11683
11880
|
const { value, min, max, center, positiveOrientation, negativeOrientation } = params;
|
|
11684
|
-
if (value > max +
|
|
11881
|
+
if (value > max + EPS15) {
|
|
11685
11882
|
return {
|
|
11686
11883
|
orientation: positiveOrientation,
|
|
11687
11884
|
outwardScore: 1 + value - max
|
|
11688
11885
|
};
|
|
11689
11886
|
}
|
|
11690
|
-
if (value < min -
|
|
11887
|
+
if (value < min - EPS15) {
|
|
11691
11888
|
return {
|
|
11692
11889
|
orientation: negativeOrientation,
|
|
11693
11890
|
outwardScore: 1 + min - value
|
|
@@ -11698,7 +11895,7 @@ var getOutwardAxisOption = (params) => {
|
|
|
11698
11895
|
outwardScore: getNormalizedCenterDistance(value, center, max - min)
|
|
11699
11896
|
};
|
|
11700
11897
|
};
|
|
11701
|
-
var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(
|
|
11898
|
+
var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS15, span / 2);
|
|
11702
11899
|
var ALL_ORIENTATIONS = ["x+", "x-", "y+", "y-"];
|
|
11703
11900
|
var getFlippedOrientation = (orientation) => {
|
|
11704
11901
|
switch (orientation) {
|
|
@@ -11766,7 +11963,7 @@ var getNetLabelHeight = (inputProblem, label) => {
|
|
|
11766
11963
|
)?.netLabelHeight;
|
|
11767
11964
|
};
|
|
11768
11965
|
var roundDistance = (distance7) => Number(distance7.toFixed(6));
|
|
11769
|
-
var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <=
|
|
11966
|
+
var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS15 && Math.abs(point.y - label.anchorPoint.y) <= EPS15 && orientation === label.orientation;
|
|
11770
11967
|
|
|
11771
11968
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/visualize.ts
|
|
11772
11969
|
var CANDIDATE_SELECTED_COLOR4 = "blue";
|
|
@@ -13416,8 +13613,10 @@ var getPathFromSharedPin = ({
|
|
|
13416
13613
|
sharedPinId
|
|
13417
13614
|
}) => {
|
|
13418
13615
|
const tracePath = simplifyPath(trace.tracePath);
|
|
13419
|
-
|
|
13420
|
-
|
|
13616
|
+
const sharedPin = trace.pins.find((pin) => pin.pinId === sharedPinId);
|
|
13617
|
+
if (!sharedPin) return null;
|
|
13618
|
+
const pathFromSharedPin = trace.pins[0]?.pinId === sharedPinId ? tracePath : tracePath.reverse();
|
|
13619
|
+
return pointsEqual2(pathFromSharedPin[0], sharedPin) ? pathFromSharedPin : null;
|
|
13421
13620
|
};
|
|
13422
13621
|
var traceCanLoseSharedPrefix = ({
|
|
13423
13622
|
trace,
|
|
@@ -13458,9 +13657,10 @@ var collapseRedundantSharedEndpointStubs = ({
|
|
|
13458
13657
|
}) => {
|
|
13459
13658
|
const outputTraces = [...traces];
|
|
13460
13659
|
for (let firstIndex = 0; firstIndex < outputTraces.length; firstIndex++) {
|
|
13461
|
-
|
|
13462
|
-
|
|
13660
|
+
if (netLabelConnectorTraceIds.has(outputTraces[firstIndex].mspPairId))
|
|
13661
|
+
continue;
|
|
13463
13662
|
for (let secondIndex = firstIndex + 1; secondIndex < outputTraces.length; secondIndex++) {
|
|
13663
|
+
const firstTrace = outputTraces[firstIndex];
|
|
13464
13664
|
const secondTrace = outputTraces[secondIndex];
|
|
13465
13665
|
if (netLabelConnectorTraceIds.has(secondTrace.mspPairId) || firstTrace.globalConnNetId !== secondTrace.globalConnNetId) {
|
|
13466
13666
|
continue;
|
|
@@ -13478,6 +13678,7 @@ var collapseRedundantSharedEndpointStubs = ({
|
|
|
13478
13678
|
trace: secondTrace,
|
|
13479
13679
|
sharedPinId: sharedPin.pinId
|
|
13480
13680
|
});
|
|
13681
|
+
if (!firstPath || !secondPath) continue;
|
|
13481
13682
|
if (firstPath.length < 2 || secondPath.length < 2) continue;
|
|
13482
13683
|
const departureAxis = getSegmentAxis3(firstPath[0], firstPath[1]);
|
|
13483
13684
|
const secondDepartureAxis = getSegmentAxis3(secondPath[0], secondPath[1]);
|
|
@@ -13524,7 +13725,7 @@ var collapseRedundantSharedEndpointStubs = ({
|
|
|
13524
13725
|
});
|
|
13525
13726
|
if (!collapsedTrace2) continue;
|
|
13526
13727
|
outputTraces[traceIndexToCollapse2] = collapsedTrace2;
|
|
13527
|
-
|
|
13728
|
+
continue;
|
|
13528
13729
|
}
|
|
13529
13730
|
if (firstPath.length < 3 || secondPath.length < 3) continue;
|
|
13530
13731
|
if (!pointsEqual2(firstPath[1], secondPath[1])) continue;
|
|
@@ -13588,7 +13789,6 @@ var collapseRedundantSharedEndpointStubs = ({
|
|
|
13588
13789
|
});
|
|
13589
13790
|
if (!collapsedTrace) continue;
|
|
13590
13791
|
outputTraces[traceIndexToCollapse] = collapsedTrace;
|
|
13591
|
-
break;
|
|
13592
13792
|
}
|
|
13593
13793
|
}
|
|
13594
13794
|
return outputTraces;
|
|
@@ -15188,10 +15388,10 @@ var getInlineLabelObstacles = (inputProblem, placements) => {
|
|
|
15188
15388
|
};
|
|
15189
15389
|
|
|
15190
15390
|
// lib/solvers/InlineNetLabelSolver/getLocalTraceLabelShifts.ts
|
|
15191
|
-
var
|
|
15391
|
+
var EPS16 = 1e-6;
|
|
15192
15392
|
var CLEARANCE = 0.05;
|
|
15193
15393
|
var hits = (path, bounds) => path.slice(1).some((p, i) => segmentIntersectsRect(path[i], p, bounds));
|
|
15194
|
-
var same = (a, b) => Math.hypot(a.x - b.x, a.y - b.y) <
|
|
15394
|
+
var same = (a, b) => Math.hypot(a.x - b.x, a.y - b.y) < EPS16;
|
|
15195
15395
|
var translate = (p, axis, distance7) => ({
|
|
15196
15396
|
...p,
|
|
15197
15397
|
[axis]: p[axis] + distance7
|
|
@@ -15238,9 +15438,9 @@ function* getLocalTraceLabelShifts(inputProblem, output, pendingInlinePlacements
|
|
|
15238
15438
|
const path = simplifyPath(trace.tracePath);
|
|
15239
15439
|
for (let i = 0; i < path.length - 1; i++) {
|
|
15240
15440
|
const a = path[i], b = path[i + 1];
|
|
15241
|
-
const axis = Math.abs(a.x - b.x) <
|
|
15441
|
+
const axis = Math.abs(a.x - b.x) < EPS16 ? "x" : "y";
|
|
15242
15442
|
const along = axis === "x" ? "y" : "x";
|
|
15243
|
-
if (Math.abs(a[axis] - b[axis]) >
|
|
15443
|
+
if (Math.abs(a[axis] - b[axis]) > EPS16 || same(a, b)) continue;
|
|
15244
15444
|
const blocking = [
|
|
15245
15445
|
...output.netLabelPlacements.filter((label) => label.globalConnNetId !== trace.globalConnNetId).map(getAnchoredNetLabelRenderedBounds),
|
|
15246
15446
|
...inlineBounds,
|
|
@@ -15258,17 +15458,17 @@ function* getLocalTraceLabelShifts(inputProblem, output, pendingInlinePlacements
|
|
|
15258
15458
|
if (other.globalConnNetId !== trace.globalConnNetId) continue;
|
|
15259
15459
|
for (let j = 1; j < other.tracePath.length; j++) {
|
|
15260
15460
|
const p = other.tracePath[j - 1], q = other.tracePath[j];
|
|
15261
|
-
if (Math.abs(p[axis] - a[axis]) >
|
|
15461
|
+
if (Math.abs(p[axis] - a[axis]) > EPS16 || Math.abs(q[axis] - a[axis]) > EPS16)
|
|
15262
15462
|
continue;
|
|
15263
15463
|
const min = Math.min(p[along], q[along]), max = Math.max(p[along], q[along]);
|
|
15264
|
-
if (max < low -
|
|
15464
|
+
if (max < low - EPS16 || min > high + EPS16) continue;
|
|
15265
15465
|
if (min < low || max > high) expanded = true;
|
|
15266
15466
|
low = Math.min(low, min);
|
|
15267
15467
|
high = Math.max(high, max);
|
|
15268
15468
|
}
|
|
15269
15469
|
}
|
|
15270
15470
|
}
|
|
15271
|
-
const onRail = (p) => Math.abs(p[axis] - a[axis]) <
|
|
15471
|
+
const onRail = (p) => Math.abs(p[axis] - a[axis]) < EPS16 && p[along] >= low - EPS16 && p[along] <= high + EPS16;
|
|
15272
15472
|
if (pinPositions.some(onRail)) continue;
|
|
15273
15473
|
const minKey = axis === "x" ? "minX" : "minY";
|
|
15274
15474
|
const maxKey = axis === "x" ? "maxX" : "maxY";
|
|
@@ -15350,7 +15550,7 @@ function* getLocalTraceLabelShifts(inputProblem, output, pendingInlinePlacements
|
|
|
15350
15550
|
continue;
|
|
15351
15551
|
}
|
|
15352
15552
|
const [start, bend, end] = connector.tracePath;
|
|
15353
|
-
if (Math.abs(bend[axis] - end[axis]) >
|
|
15553
|
+
if (Math.abs(bend[axis] - end[axis]) > EPS16 || Math.abs(start[along] - bend[along]) > EPS16) {
|
|
15354
15554
|
blocked = true;
|
|
15355
15555
|
break;
|
|
15356
15556
|
}
|
|
@@ -15371,24 +15571,40 @@ function* getLocalTraceLabelShifts(inputProblem, output, pendingInlinePlacements
|
|
|
15371
15571
|
};
|
|
15372
15572
|
}
|
|
15373
15573
|
if (blocked) continue;
|
|
15574
|
+
for (const [index, other] of traces.entries()) {
|
|
15575
|
+
if (other.globalConnNetId === trace.globalConnNetId || simplifyPath(other.tracePath).length <= 4 || !shiftedPaths.some(
|
|
15576
|
+
(path2) => doesPathCoincideWithTraces(path2, [other])
|
|
15577
|
+
))
|
|
15578
|
+
continue;
|
|
15579
|
+
const simplified = minimizeTurnsWithFilteredLabels({
|
|
15580
|
+
inputProblem,
|
|
15581
|
+
traces: [...traces, ...terminalTraces],
|
|
15582
|
+
targetMspConnectionPairId: other.mspPairId,
|
|
15583
|
+
allLabelPlacements: [...labels, ...fixedLabels],
|
|
15584
|
+
mergedLabelNetIdMap: {},
|
|
15585
|
+
paddingBuffer: CLEARANCE
|
|
15586
|
+
});
|
|
15587
|
+
if (simplifyPath(simplified.tracePath).length < simplifyPath(other.tracePath).length && preservesLabelAnchors(labels, [other], [simplified]))
|
|
15588
|
+
traces[index] = simplified;
|
|
15589
|
+
}
|
|
15374
15590
|
for (const [index, proposed] of traces.entries()) {
|
|
15375
15591
|
const original = output.traces[index];
|
|
15376
15592
|
if (proposed === original) continue;
|
|
15377
15593
|
const candidate = proposed.tracePath;
|
|
15378
15594
|
const previous = original.tracePath;
|
|
15379
15595
|
if (candidate.slice(1).some(
|
|
15380
|
-
(p, index2) => Math.abs(p.x - candidate[index2].x) >
|
|
15596
|
+
(p, index2) => Math.abs(p.x - candidate[index2].x) > EPS16 && Math.abs(p.y - candidate[index2].y) > EPS16
|
|
15381
15597
|
)) {
|
|
15382
15598
|
blocked = true;
|
|
15383
15599
|
break;
|
|
15384
15600
|
}
|
|
15385
15601
|
const dot = (a2, b2, c, d) => (b2.x - a2.x) * (d.x - c.x) + (b2.y - a2.y) * (d.y - c.y);
|
|
15386
|
-
if (dot(previous[0], previous[1], candidate[0], candidate[1]) <=
|
|
15602
|
+
if (dot(previous[0], previous[1], candidate[0], candidate[1]) <= EPS16 || dot(
|
|
15387
15603
|
previous.at(-1),
|
|
15388
15604
|
previous.at(-2),
|
|
15389
15605
|
candidate.at(-1),
|
|
15390
15606
|
candidate.at(-2)
|
|
15391
|
-
) <=
|
|
15607
|
+
) <= EPS16) {
|
|
15392
15608
|
blocked = true;
|
|
15393
15609
|
break;
|
|
15394
15610
|
}
|
|
@@ -16344,15 +16560,15 @@ var pathIntersectsRenderedLabel = (path, label) => {
|
|
|
16344
16560
|
};
|
|
16345
16561
|
|
|
16346
16562
|
// lib/solvers/InlineNetLabelSolver/restoreReroutesAroundSupersededLabels.ts
|
|
16347
|
-
var
|
|
16563
|
+
var EPS17 = 1e-6;
|
|
16348
16564
|
var getPathLength7 = (path) => path.slice(1).reduce((length, point, pointIndex) => {
|
|
16349
16565
|
const previousPoint = path[pointIndex];
|
|
16350
16566
|
return length + Math.abs(point.x - previousPoint.x) + Math.abs(point.y - previousPoint.y);
|
|
16351
16567
|
}, 0);
|
|
16352
16568
|
var pathsEqual = (first, second) => first.length === second.length && first.every(
|
|
16353
|
-
(point, index) => Math.abs(point.x - second[index].x) <=
|
|
16569
|
+
(point, index) => Math.abs(point.x - second[index].x) <= EPS17 && Math.abs(point.y - second[index].y) <= EPS17
|
|
16354
16570
|
);
|
|
16355
|
-
var isStrictlySimpler = (candidate, current) => candidate.length < current.length && getPathLength7(candidate) <= getPathLength7(current) +
|
|
16571
|
+
var isStrictlySimpler = (candidate, current) => candidate.length < current.length && getPathLength7(candidate) <= getPathLength7(current) + EPS17;
|
|
16356
16572
|
var getIntersectionKeys = (path, otherPath) => {
|
|
16357
16573
|
const intersections2 = /* @__PURE__ */ new Set();
|
|
16358
16574
|
for (let pathIndex = 0; pathIndex < path.length - 1; pathIndex++) {
|
|
@@ -17652,12 +17868,12 @@ var getTraceRecoveryConnectivityMaps = (inputProblem) => {
|
|
|
17652
17868
|
};
|
|
17653
17869
|
|
|
17654
17870
|
// lib/solvers/NetLabelToTraceSolver/reduceTraceCrossings.ts
|
|
17655
|
-
var
|
|
17656
|
-
var isHorizontal4 = (start, end) => Math.abs(start.y - end.y) <
|
|
17657
|
-
var isVertical5 = (start, end) => Math.abs(start.x - end.x) <
|
|
17871
|
+
var EPS18 = 1e-9;
|
|
17872
|
+
var isHorizontal4 = (start, end) => Math.abs(start.y - end.y) < EPS18;
|
|
17873
|
+
var isVertical5 = (start, end) => Math.abs(start.x - end.x) < EPS18;
|
|
17658
17874
|
var compactConsecutivePoints = (path) => path.filter((point, index) => {
|
|
17659
17875
|
const previousPoint = path[index - 1];
|
|
17660
|
-
return !previousPoint || Math.abs(point.x - previousPoint.x) >=
|
|
17876
|
+
return !previousPoint || Math.abs(point.x - previousPoint.x) >= EPS18 || Math.abs(point.y - previousPoint.y) >= EPS18;
|
|
17661
17877
|
});
|
|
17662
17878
|
var isValidOrthogonalPath = (path) => {
|
|
17663
17879
|
if (path.length < 2 || !path.every((point, index) => {
|
|
@@ -17695,7 +17911,7 @@ var getEndpointAlignedSegmentCandidates = (tracePath) => {
|
|
|
17695
17911
|
}
|
|
17696
17912
|
const alignedCoordinates = segmentIsVertical ? [previousPoint.x, nextPoint.x] : [previousPoint.y, nextPoint.y];
|
|
17697
17913
|
for (const alignedCoordinate of alignedCoordinates) {
|
|
17698
|
-
if (Math.abs(alignedCoordinate - (segmentIsVertical ? start.x : start.y)) <
|
|
17914
|
+
if (Math.abs(alignedCoordinate - (segmentIsVertical ? start.x : start.y)) < EPS18) {
|
|
17699
17915
|
continue;
|
|
17700
17916
|
}
|
|
17701
17917
|
const candidate = tracePath.map((point) => ({ ...point }));
|
|
@@ -17784,6 +18000,13 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
17784
18000
|
);
|
|
17785
18001
|
this.chipMap = chipMap;
|
|
17786
18002
|
this.pinMap = pinMap;
|
|
18003
|
+
this.canRecoverParallelPair = getParallelNetLabelPolicy(
|
|
18004
|
+
this.inputProblem,
|
|
18005
|
+
getConnectivityMapsFromInputProblem(this.inputProblem).netConnMap,
|
|
18006
|
+
new Set(
|
|
18007
|
+
input.traces.filter((trace) => trace.pinIds.length > 1).flatMap((trace) => trace.pinIds)
|
|
18008
|
+
)
|
|
18009
|
+
);
|
|
17787
18010
|
this.queuedCandidates = this.buildCandidatePairs();
|
|
17788
18011
|
this.stats.candidateCount = this.queuedCandidates.length;
|
|
17789
18012
|
this.stats.recoveredTraceCount = 0;
|
|
@@ -17795,6 +18018,7 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
17795
18018
|
recoveredTraceIds = /* @__PURE__ */ new Set();
|
|
17796
18019
|
chipMap;
|
|
17797
18020
|
pinMap;
|
|
18021
|
+
canRecoverParallelPair;
|
|
17798
18022
|
queuedCandidates;
|
|
17799
18023
|
currentCandidate = null;
|
|
17800
18024
|
getConstructorParams() {
|
|
@@ -17845,6 +18069,7 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
17845
18069
|
const firstPin = this.pinMap.get(firstLabel.pinIds[0]);
|
|
17846
18070
|
const secondPin = this.pinMap.get(secondLabel.pinIds[0]);
|
|
17847
18071
|
if (!firstPin || !secondPin) continue;
|
|
18072
|
+
if (!this.canRecoverParallelPair(firstPin, secondPin)) continue;
|
|
17848
18073
|
const perpendicularOffset = getPerpendicularOffset(
|
|
17849
18074
|
firstPin,
|
|
17850
18075
|
secondPin
|
|
@@ -17963,6 +18188,7 @@ var NetLabelToTraceSolver = class extends BaseSolver {
|
|
|
17963
18188
|
const firstPin = this.pinMap.get(firstPinId);
|
|
17964
18189
|
const secondPin = this.pinMap.get(secondPinId);
|
|
17965
18190
|
if (!firstPin || !secondPin) continue;
|
|
18191
|
+
if (!this.canRecoverParallelPair(firstPin, secondPin)) continue;
|
|
17966
18192
|
if (isDirectConnection && firstPin.chipId === secondPin.chipId)
|
|
17967
18193
|
continue;
|
|
17968
18194
|
const perpendicularOffset = getPerpendicularOffset(
|