@tscircuit/schematic-trace-solver 0.0.176 → 0.0.178
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 +4 -1
- package/dist/index.js +292 -120
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +1 -0
- package/lib/solvers/MspConnectionPairSolver/getGroundConnectionPolicy.ts +13 -0
- package/lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver.ts +6 -1
- package/lib/solvers/TraceCleanupSolver/TraceCleanupSolver.ts +25 -0
- package/lib/solvers/TraceCleanupSolver/rerouteGeneratedNetLabelConnectorCrossings.ts +194 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/findIntersectionsWithObstacles.ts +19 -5
- package/lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts +35 -5
- package/package.json +1 -1
- package/tests/repros/__snapshots__/repro-smartwatch-power-sheet.snap.svg +451 -0
- package/tests/repros/__snapshots__/repro-wireless-mouse-charger-section.snap.svg +2 -2
- package/tests/repros/assets/repro-smartwatch-power-sheet.input.json +1112 -0
- package/tests/repros/repro-smartwatch-power-sheet.test.ts +27 -0
- package/tests/solvers/MspConnectionPairSolver/ground-direct-connection-groups.test.ts +11 -0
- package/tests/solvers/TraceCleanupSolver/alignSameNetRails-pipeline-label-connector.test.ts +4 -2
- package/tests/solvers/TraceCleanupSolver/reroute-generated-net-label-connector-crossings.test.ts +160 -0
package/dist/index.js
CHANGED
|
@@ -325,19 +325,19 @@ var doesPairCrossRestrictedCenterLines = (params) => {
|
|
|
325
325
|
chipMap
|
|
326
326
|
});
|
|
327
327
|
if (restrictedCenterLines.size === 0) return false;
|
|
328
|
-
const
|
|
328
|
+
const EPS17 = 1e-9;
|
|
329
329
|
const crossesSegment = (a, b) => {
|
|
330
330
|
for (const [, rcl] of restrictedCenterLines) {
|
|
331
331
|
if (rcl.axes.has("x") && typeof rcl.x === "number") {
|
|
332
|
-
if ((a.x - rcl.x) * (b.x - rcl.x) < -
|
|
332
|
+
if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS17) return true;
|
|
333
333
|
}
|
|
334
334
|
if (rcl.axes.has("y") && typeof rcl.y === "number") {
|
|
335
|
-
if ((a.y - rcl.y) * (b.y - rcl.y) < -
|
|
335
|
+
if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS17) return true;
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
return false;
|
|
339
339
|
};
|
|
340
|
-
if (Math.abs(p1.x - p2.x) <
|
|
340
|
+
if (Math.abs(p1.x - p2.x) < EPS17 || Math.abs(p1.y - p2.y) < EPS17) {
|
|
341
341
|
return crossesSegment({ x: p1.x, y: p1.y }, { x: p2.x, y: p2.y });
|
|
342
342
|
}
|
|
343
343
|
const elbowHV = { x: p2.x, y: p1.y };
|
|
@@ -396,6 +396,12 @@ var getGroundConnectionPolicy = (inputProblem) => {
|
|
|
396
396
|
);
|
|
397
397
|
});
|
|
398
398
|
const areSeparateExplicitGroundIslands = (firstPinId, secondPinId) => {
|
|
399
|
+
const firstChipId = pins.get(firstPinId)?.chip.chipId;
|
|
400
|
+
const secondChipId = pins.get(secondPinId)?.chip.chipId;
|
|
401
|
+
const pinsShareChip = firstChipId !== void 0 && firstChipId === secondChipId;
|
|
402
|
+
if (pinsShareChip && !physicalConnMap.getNetConnectedToId(firstPinId) && !physicalConnMap.getNetConnectedToId(secondPinId)) {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
399
405
|
const firstGlobalNetId = netConnMap.getNetConnectedToId(firstPinId);
|
|
400
406
|
const secondGlobalNetId = netConnMap.getNetConnectedToId(secondPinId);
|
|
401
407
|
if (!firstGlobalNetId || firstGlobalNetId !== secondGlobalNetId || !explicitlyWiredGroundNetIds.has(firstGlobalNetId)) {
|
|
@@ -1575,8 +1581,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
1575
1581
|
if (!collision) {
|
|
1576
1582
|
const first = path[0];
|
|
1577
1583
|
const last = path[path.length - 1];
|
|
1578
|
-
const
|
|
1579
|
-
const samePoint = (p, q) => Math.abs(p.x - q.x) <
|
|
1584
|
+
const EPS17 = 1e-9;
|
|
1585
|
+
const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS17 && Math.abs(p.y - q.y) < EPS17;
|
|
1580
1586
|
if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
|
|
1581
1587
|
this.solvedTracePath = path;
|
|
1582
1588
|
this.solved = true;
|
|
@@ -1887,13 +1893,13 @@ var applyJogToTerminalSegment = ({
|
|
|
1887
1893
|
segmentIndex: si,
|
|
1888
1894
|
offset,
|
|
1889
1895
|
JOG_SIZE,
|
|
1890
|
-
EPS:
|
|
1896
|
+
EPS: EPS17 = 1e-6
|
|
1891
1897
|
}) => {
|
|
1892
1898
|
if (si !== 0 && si !== pts.length - 2) return;
|
|
1893
1899
|
const start = pts[si];
|
|
1894
1900
|
const end = pts[si + 1];
|
|
1895
|
-
const isVertical6 = Math.abs(start.x - end.x) <
|
|
1896
|
-
const isHorizontal5 = Math.abs(start.y - end.y) <
|
|
1901
|
+
const isVertical6 = Math.abs(start.x - end.x) < EPS17;
|
|
1902
|
+
const isHorizontal5 = Math.abs(start.y - end.y) < EPS17;
|
|
1897
1903
|
if (!isVertical6 && !isHorizontal5) return;
|
|
1898
1904
|
const segDir = isVertical6 ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
|
|
1899
1905
|
if (pts.length === 2) {
|
|
@@ -2327,7 +2333,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2327
2333
|
return islands;
|
|
2328
2334
|
}
|
|
2329
2335
|
findNextOverlapIssue() {
|
|
2330
|
-
const
|
|
2336
|
+
const EPS17 = 2e-3;
|
|
2331
2337
|
const netIds = Object.keys(this.traceNetIslands);
|
|
2332
2338
|
for (let i = 0; i < netIds.length; i++) {
|
|
2333
2339
|
for (let j = i + 1; j < netIds.length; j++) {
|
|
@@ -2354,7 +2360,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2354
2360
|
segmentBIndex,
|
|
2355
2361
|
rangeOverlap
|
|
2356
2362
|
}) => {
|
|
2357
|
-
if (rangeOverlap >
|
|
2363
|
+
if (rangeOverlap > EPS17) {
|
|
2358
2364
|
const keyA = `${pathAIndex}:${segmentAIndex}`;
|
|
2359
2365
|
const keyB = `${pathBIndex}:${segmentBIndex}`;
|
|
2360
2366
|
if (!seenA.has(keyA)) {
|
|
@@ -2373,7 +2379,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2373
2379
|
}
|
|
2374
2380
|
return;
|
|
2375
2381
|
}
|
|
2376
|
-
if (rangeOverlap < -
|
|
2382
|
+
if (rangeOverlap < -EPS17) return;
|
|
2377
2383
|
const pathA = pathsA[pathAIndex].tracePath;
|
|
2378
2384
|
const pathB = pathsB[pathBIndex].tracePath;
|
|
2379
2385
|
const segmentAStart = pathA[segmentAIndex];
|
|
@@ -2396,8 +2402,8 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2396
2402
|
for (let sa = 0; sa < ptsA.length - 1; sa++) {
|
|
2397
2403
|
const a1 = ptsA[sa];
|
|
2398
2404
|
const a2 = ptsA[sa + 1];
|
|
2399
|
-
const aVert = Math.abs(a1.x - a2.x) <
|
|
2400
|
-
const aHorz = Math.abs(a1.y - a2.y) <
|
|
2405
|
+
const aVert = Math.abs(a1.x - a2.x) < EPS17;
|
|
2406
|
+
const aHorz = Math.abs(a1.y - a2.y) < EPS17;
|
|
2401
2407
|
if (!aVert && !aHorz) continue;
|
|
2402
2408
|
for (let pb = 0; pb < pathsB.length; pb++) {
|
|
2403
2409
|
const pathB = pathsB[pb];
|
|
@@ -2408,11 +2414,11 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2408
2414
|
for (let sb = 0; sb < ptsB.length - 1; sb++) {
|
|
2409
2415
|
const b1 = ptsB[sb];
|
|
2410
2416
|
const b2 = ptsB[sb + 1];
|
|
2411
|
-
const bVert = Math.abs(b1.x - b2.x) <
|
|
2412
|
-
const bHorz = Math.abs(b1.y - b2.y) <
|
|
2417
|
+
const bVert = Math.abs(b1.x - b2.x) < EPS17;
|
|
2418
|
+
const bHorz = Math.abs(b1.y - b2.y) < EPS17;
|
|
2413
2419
|
if (!bVert && !bHorz) continue;
|
|
2414
2420
|
if (aVert && bVert) {
|
|
2415
|
-
if (Math.abs(a1.x - b1.x) <
|
|
2421
|
+
if (Math.abs(a1.x - b1.x) < EPS17) {
|
|
2416
2422
|
recordCollinearInteraction({
|
|
2417
2423
|
pathAIndex: pa,
|
|
2418
2424
|
segmentAIndex: sa,
|
|
@@ -2422,7 +2428,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2422
2428
|
});
|
|
2423
2429
|
}
|
|
2424
2430
|
} else if (aHorz && bHorz) {
|
|
2425
|
-
if (Math.abs(a1.y - b1.y) <
|
|
2431
|
+
if (Math.abs(a1.y - b1.y) < EPS17) {
|
|
2426
2432
|
recordCollinearInteraction({
|
|
2427
2433
|
pathAIndex: pa,
|
|
2428
2434
|
segmentAIndex: sa,
|
|
@@ -2478,14 +2484,14 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2478
2484
|
return null;
|
|
2479
2485
|
}
|
|
2480
2486
|
findNextDiagonalSegment() {
|
|
2481
|
-
const
|
|
2487
|
+
const EPS17 = 2e-3;
|
|
2482
2488
|
for (const mspPairId in this.correctedTraceMap) {
|
|
2483
2489
|
const tracePath = this.correctedTraceMap[mspPairId].tracePath;
|
|
2484
2490
|
for (let i = 0; i < tracePath.length - 1; i++) {
|
|
2485
2491
|
const p1 = tracePath[i];
|
|
2486
2492
|
const p2 = tracePath[i + 1];
|
|
2487
|
-
const isHorizontal5 = Math.abs(p1.y - p2.y) <
|
|
2488
|
-
const isVertical6 = Math.abs(p1.x - p2.x) <
|
|
2493
|
+
const isHorizontal5 = Math.abs(p1.y - p2.y) < EPS17;
|
|
2494
|
+
const isVertical6 = Math.abs(p1.x - p2.x) < EPS17;
|
|
2489
2495
|
if (!isHorizontal5 && !isVertical6) {
|
|
2490
2496
|
return { mspPairId, tracePath, i, p1, p2 };
|
|
2491
2497
|
}
|
|
@@ -2499,13 +2505,13 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
2499
2505
|
return false;
|
|
2500
2506
|
}
|
|
2501
2507
|
const { mspPairId, tracePath, i, p1, p2 } = diagonalInfo;
|
|
2502
|
-
const
|
|
2508
|
+
const EPS17 = 2e-3;
|
|
2503
2509
|
const p0 = i > 0 ? tracePath[i - 1] : null;
|
|
2504
2510
|
const p3 = i + 2 < tracePath.length ? tracePath[i + 2] : null;
|
|
2505
|
-
const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) <
|
|
2506
|
-
const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) <
|
|
2507
|
-
const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) <
|
|
2508
|
-
const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) <
|
|
2511
|
+
const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS17 : false;
|
|
2512
|
+
const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS17 : false;
|
|
2513
|
+
const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS17 : false;
|
|
2514
|
+
const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS17 : false;
|
|
2509
2515
|
const elbow1 = { x: p1.x, y: p2.y };
|
|
2510
2516
|
const elbow2 = { x: p2.x, y: p1.y };
|
|
2511
2517
|
let score1 = 0;
|
|
@@ -2667,24 +2673,24 @@ var ChipObstacleSpatialIndex = class {
|
|
|
2667
2673
|
};
|
|
2668
2674
|
|
|
2669
2675
|
// lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions.ts
|
|
2670
|
-
function segmentIntersectsRect2(p1, p2, rect,
|
|
2671
|
-
const isVert = Math.abs(p1.x - p2.x) <
|
|
2672
|
-
const isHorz = Math.abs(p1.y - p2.y) <
|
|
2676
|
+
function segmentIntersectsRect2(p1, p2, rect, EPS17 = 1e-9) {
|
|
2677
|
+
const isVert = Math.abs(p1.x - p2.x) < EPS17;
|
|
2678
|
+
const isHorz = Math.abs(p1.y - p2.y) < EPS17;
|
|
2673
2679
|
if (!isVert && !isHorz) return false;
|
|
2674
2680
|
if (isVert) {
|
|
2675
2681
|
const x = p1.x;
|
|
2676
|
-
if (x < rect.minX -
|
|
2682
|
+
if (x < rect.minX - EPS17 || x > rect.maxX + EPS17) return false;
|
|
2677
2683
|
const segMinY = Math.min(p1.y, p2.y);
|
|
2678
2684
|
const segMaxY = Math.max(p1.y, p2.y);
|
|
2679
2685
|
const overlap = Math.min(segMaxY, rect.maxY) - Math.max(segMinY, rect.minY);
|
|
2680
|
-
return overlap >
|
|
2686
|
+
return overlap > EPS17;
|
|
2681
2687
|
} else {
|
|
2682
2688
|
const y = p1.y;
|
|
2683
|
-
if (y < rect.minY -
|
|
2689
|
+
if (y < rect.minY - EPS17 || y > rect.maxY + EPS17) return false;
|
|
2684
2690
|
const segMinX = Math.min(p1.x, p2.x);
|
|
2685
2691
|
const segMaxX = Math.max(p1.x, p2.x);
|
|
2686
2692
|
const overlap = Math.min(segMaxX, rect.maxX) - Math.max(segMinX, rect.minX);
|
|
2687
|
-
return overlap >
|
|
2693
|
+
return overlap > EPS17;
|
|
2688
2694
|
}
|
|
2689
2695
|
}
|
|
2690
2696
|
function rectIntersectsAnyTrace(bounds, inputTraceMap, hostPathId, hostSegIndex) {
|
|
@@ -3083,14 +3089,14 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
|
|
|
3083
3089
|
};
|
|
3084
3090
|
let bestCandidate = null;
|
|
3085
3091
|
let bestScore = -Infinity;
|
|
3086
|
-
const
|
|
3092
|
+
const EPS17 = 1e-6;
|
|
3087
3093
|
for (const curr of tracesToScan) {
|
|
3088
3094
|
const pts = curr.tracePath.slice();
|
|
3089
3095
|
for (let si = 0; si < pts.length - 1; si++) {
|
|
3090
3096
|
const a = pts[si];
|
|
3091
3097
|
const b = pts[si + 1];
|
|
3092
|
-
const isH = Math.abs(a.y - b.y) <
|
|
3093
|
-
const isV = Math.abs(a.x - b.x) <
|
|
3098
|
+
const isH = Math.abs(a.y - b.y) < EPS17;
|
|
3099
|
+
const isV = Math.abs(a.x - b.x) < EPS17;
|
|
3094
3100
|
if (!isH && !isV) continue;
|
|
3095
3101
|
const segmentAllowed = isH ? ["y+", "y-"] : ["x+", "x-"];
|
|
3096
3102
|
const candidateOrients = orientations.filter(
|
|
@@ -6613,13 +6619,17 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
|
|
|
6613
6619
|
return intersections;
|
|
6614
6620
|
};
|
|
6615
6621
|
var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS9 && Math.abs(first.y - second.y) < EPS9;
|
|
6616
|
-
var findPerpendicularPathCrossings = (path, otherPath) => {
|
|
6622
|
+
var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
|
|
6617
6623
|
const crossings = [];
|
|
6618
|
-
|
|
6624
|
+
const firstPathSegmentIndex = options.includeTerminalSegments ? 0 : 1;
|
|
6625
|
+
const lastPathSegmentIndex = options.includeTerminalSegments ? path.length - 1 : path.length - 2;
|
|
6626
|
+
const firstOtherPathSegmentIndex = options.includeTerminalSegments ? 0 : 1;
|
|
6627
|
+
const lastOtherPathSegmentIndex = options.includeTerminalSegments ? otherPath.length - 1 : otherPath.length - 2;
|
|
6628
|
+
for (let pathSegmentIndex = firstPathSegmentIndex; pathSegmentIndex < lastPathSegmentIndex; pathSegmentIndex++) {
|
|
6619
6629
|
const start = path[pathSegmentIndex];
|
|
6620
6630
|
const end = path[pathSegmentIndex + 1];
|
|
6621
6631
|
const isVertical6 = Math.abs(start.x - end.x) < EPS9;
|
|
6622
|
-
for (let otherPathSegmentIndex =
|
|
6632
|
+
for (let otherPathSegmentIndex = firstOtherPathSegmentIndex; otherPathSegmentIndex < lastOtherPathSegmentIndex; otherPathSegmentIndex++) {
|
|
6623
6633
|
const otherStart = otherPath[otherPathSegmentIndex];
|
|
6624
6634
|
const otherEnd = otherPath[otherPathSegmentIndex + 1];
|
|
6625
6635
|
const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS9;
|
|
@@ -6759,6 +6769,7 @@ var generatePerpendicularTraceDetours = ({
|
|
|
6759
6769
|
segmentIndex,
|
|
6760
6770
|
obstacleStart,
|
|
6761
6771
|
obstacleEnd,
|
|
6772
|
+
obstacleBounds,
|
|
6762
6773
|
chipBounds,
|
|
6763
6774
|
clearance
|
|
6764
6775
|
}) => {
|
|
@@ -6767,18 +6778,34 @@ var generatePerpendicularTraceDetours = ({
|
|
|
6767
6778
|
const end = path[index + 1];
|
|
6768
6779
|
const movingAxis = Math.abs(start.x - end.x) < EPS10 ? "y" : "x";
|
|
6769
6780
|
const detourAxis = movingAxis === "x" ? "y" : "x";
|
|
6770
|
-
const
|
|
6771
|
-
|
|
6781
|
+
const bounds = obstacleBounds ?? {
|
|
6782
|
+
minX: Math.min(obstacleStart.x, obstacleEnd.x),
|
|
6783
|
+
minY: Math.min(obstacleStart.y, obstacleEnd.y),
|
|
6784
|
+
maxX: Math.max(obstacleStart.x, obstacleEnd.x),
|
|
6785
|
+
maxY: Math.max(obstacleStart.y, obstacleEnd.y)
|
|
6786
|
+
};
|
|
6787
|
+
const movingLowBound = movingAxis === "x" ? "minX" : "minY";
|
|
6788
|
+
const movingHighBound = movingAxis === "x" ? "maxX" : "maxY";
|
|
6789
|
+
let gate = obstacleStart[movingAxis] + Math.sign(start[movingAxis] - obstacleStart[movingAxis]) * clearance;
|
|
6790
|
+
if (obstacleBounds) {
|
|
6791
|
+
const startSide = start[movingAxis] < (bounds[movingLowBound] + bounds[movingHighBound]) / 2 ? -1 : 1;
|
|
6792
|
+
gate = bounds[startSide < 0 ? movingLowBound : movingHighBound] + startSide * clearance;
|
|
6793
|
+
}
|
|
6772
6794
|
const lowBound = detourAxis === "x" ? "minX" : "minY";
|
|
6773
6795
|
const highBound = detourAxis === "x" ? "maxX" : "maxY";
|
|
6796
|
+
const minDetour = bounds[lowBound] - clearance;
|
|
6797
|
+
const maxDetour = bounds[highBound] + clearance;
|
|
6798
|
+
const nextAnchor = obstacleBounds ? path[index + 2] : void 0;
|
|
6799
|
+
const balancedDetour = nextAnchor ? nextAnchor[detourAxis] < minDetour ? (nextAnchor[detourAxis] + minDetour) / 2 : nextAnchor[detourAxis] > maxDetour ? (nextAnchor[detourAxis] + maxDetour) / 2 : void 0 : void 0;
|
|
6774
6800
|
const detourCoordinates = [
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6801
|
+
balancedDetour,
|
|
6802
|
+
minDetour,
|
|
6803
|
+
maxDetour,
|
|
6804
|
+
...chipBounds.flatMap((bounds2) => [
|
|
6805
|
+
bounds2[lowBound] - clearance,
|
|
6806
|
+
bounds2[highBound] + clearance
|
|
6780
6807
|
])
|
|
6781
|
-
];
|
|
6808
|
+
].filter((coordinate) => coordinate !== void 0);
|
|
6782
6809
|
return [...new Set(detourCoordinates)].map(
|
|
6783
6810
|
(detour) => simplifyPath([
|
|
6784
6811
|
...path.slice(0, index + 1),
|
|
@@ -7385,6 +7412,126 @@ var is4PointRectangle = (path) => {
|
|
|
7385
7412
|
return isHVHC || isVHVC;
|
|
7386
7413
|
};
|
|
7387
7414
|
|
|
7415
|
+
// lib/solvers/TraceCleanupSolver/rerouteGeneratedNetLabelConnectorCrossings.ts
|
|
7416
|
+
var EPS12 = 1e-6;
|
|
7417
|
+
var getConnectorObstacleBounds = (connector, segmentIndex, labels) => {
|
|
7418
|
+
const start = connector.tracePath[segmentIndex];
|
|
7419
|
+
const end = connector.tracePath[segmentIndex + 1];
|
|
7420
|
+
const bounds = {
|
|
7421
|
+
minX: Math.min(start.x, end.x),
|
|
7422
|
+
minY: Math.min(start.y, end.y),
|
|
7423
|
+
maxX: Math.max(start.x, end.x),
|
|
7424
|
+
maxY: Math.max(start.y, end.y)
|
|
7425
|
+
};
|
|
7426
|
+
for (const label of labels) {
|
|
7427
|
+
if (label.globalConnNetId !== connector.globalConnNetId) continue;
|
|
7428
|
+
if (!label.pinIds.every((pinId) => connector.pinIds.includes(pinId)))
|
|
7429
|
+
continue;
|
|
7430
|
+
if (!tracePathContainsPoint(connector.tracePath, label.anchorPoint))
|
|
7431
|
+
continue;
|
|
7432
|
+
const labelBounds = getRectBounds(label.center, label.width, label.height);
|
|
7433
|
+
bounds.minX = Math.min(bounds.minX, labelBounds.minX);
|
|
7434
|
+
bounds.minY = Math.min(bounds.minY, labelBounds.minY);
|
|
7435
|
+
bounds.maxX = Math.max(bounds.maxX, labelBounds.maxX);
|
|
7436
|
+
bounds.maxY = Math.max(bounds.maxY, labelBounds.maxY);
|
|
7437
|
+
}
|
|
7438
|
+
return bounds;
|
|
7439
|
+
};
|
|
7440
|
+
var getEligibleConnectorCrossings = (traces, connectorTraceIds, eligibleTraceIds) => {
|
|
7441
|
+
const crossings = [];
|
|
7442
|
+
for (const connector of traces) {
|
|
7443
|
+
if (!connectorTraceIds.has(connector.mspPairId)) continue;
|
|
7444
|
+
for (let traceIndex = 0; traceIndex < traces.length; traceIndex++) {
|
|
7445
|
+
const trace = traces[traceIndex];
|
|
7446
|
+
if (trace.mspPairId === connector.mspPairId) continue;
|
|
7447
|
+
if (connectorTraceIds.has(trace.mspPairId)) continue;
|
|
7448
|
+
if (trace.globalConnNetId === connector.globalConnNetId) continue;
|
|
7449
|
+
if (eligibleTraceIds && !eligibleTraceIds.has(trace.mspPairId)) continue;
|
|
7450
|
+
for (const crossing of findPerpendicularPathCrossings(
|
|
7451
|
+
trace.tracePath,
|
|
7452
|
+
connector.tracePath,
|
|
7453
|
+
{ includeTerminalSegments: true }
|
|
7454
|
+
)) {
|
|
7455
|
+
crossings.push({
|
|
7456
|
+
traceIndex,
|
|
7457
|
+
connector,
|
|
7458
|
+
connectorSegmentIndex: crossing.otherPathSegmentIndex,
|
|
7459
|
+
traceSegmentIndex: crossing.pathSegmentIndex
|
|
7460
|
+
});
|
|
7461
|
+
}
|
|
7462
|
+
}
|
|
7463
|
+
}
|
|
7464
|
+
return crossings;
|
|
7465
|
+
};
|
|
7466
|
+
var rerouteGeneratedNetLabelConnectorCrossings = ({
|
|
7467
|
+
inputProblem,
|
|
7468
|
+
traces,
|
|
7469
|
+
netLabelPlacements,
|
|
7470
|
+
mergedLabelNetIdMap,
|
|
7471
|
+
clearance,
|
|
7472
|
+
eligibleTraceIds,
|
|
7473
|
+
connectorTraceIds
|
|
7474
|
+
}) => {
|
|
7475
|
+
const outputTraces = [...traces];
|
|
7476
|
+
const componentAndTextObstacles = getObstacleRects(inputProblem).filter(
|
|
7477
|
+
(obstacle) => obstacle.kind === "chip" || obstacle.kind === "text_box"
|
|
7478
|
+
);
|
|
7479
|
+
let reroutedTraceCount = 0;
|
|
7480
|
+
while (true) {
|
|
7481
|
+
const candidates = getEligibleConnectorCrossings(
|
|
7482
|
+
outputTraces,
|
|
7483
|
+
connectorTraceIds,
|
|
7484
|
+
eligibleTraceIds
|
|
7485
|
+
).flatMap((crossing) => {
|
|
7486
|
+
const trace = outputTraces[crossing.traceIndex];
|
|
7487
|
+
const obstacleBounds = getConnectorObstacleBounds(
|
|
7488
|
+
crossing.connector,
|
|
7489
|
+
crossing.connectorSegmentIndex,
|
|
7490
|
+
netLabelPlacements
|
|
7491
|
+
);
|
|
7492
|
+
const foreignTraces = outputTraces.filter(
|
|
7493
|
+
(otherTrace) => otherTrace.mspPairId !== trace.mspPairId && otherTrace.globalConnNetId !== trace.globalConnNetId
|
|
7494
|
+
);
|
|
7495
|
+
const foreignLabelBounds = netLabelPlacements.filter((label) => {
|
|
7496
|
+
const mergedNetIds = mergedLabelNetIdMap[label.globalConnNetId];
|
|
7497
|
+
return mergedNetIds ? !mergedNetIds.has(trace.globalConnNetId) : label.globalConnNetId !== trace.globalConnNetId;
|
|
7498
|
+
}).map((label) => getRectBounds(label.center, label.width, label.height));
|
|
7499
|
+
return generatePerpendicularTraceDetours({
|
|
7500
|
+
trace,
|
|
7501
|
+
segmentIndex: crossing.traceSegmentIndex,
|
|
7502
|
+
obstacleStart: crossing.connector.tracePath[crossing.connectorSegmentIndex],
|
|
7503
|
+
obstacleEnd: crossing.connector.tracePath[crossing.connectorSegmentIndex + 1],
|
|
7504
|
+
obstacleBounds,
|
|
7505
|
+
chipBounds: [],
|
|
7506
|
+
clearance
|
|
7507
|
+
}).filter(
|
|
7508
|
+
(candidate) => getPathLength2(candidate.path) <= getPathLength2(trace.tracePath) + EPS12 && countTurns(candidate.path) <= countTurns(trace.tracePath) + 2 && !isPathCollidingWithObstacles(
|
|
7509
|
+
candidate.path,
|
|
7510
|
+
componentAndTextObstacles
|
|
7511
|
+
) && !hasCollisionsWithLabels(candidate.path, foreignLabelBounds) && !isPathColliding(candidate.path, foreignTraces, trace.mspPairId).isColliding && !doesPathCoincideWithTraces(candidate.path, foreignTraces)
|
|
7512
|
+
).map((candidate) => ({
|
|
7513
|
+
...candidate,
|
|
7514
|
+
traceIndex: crossing.traceIndex
|
|
7515
|
+
}));
|
|
7516
|
+
});
|
|
7517
|
+
candidates.sort((first, second) => {
|
|
7518
|
+
const lengthDifference = getPathLength2(first.path) - getPathLength2(second.path);
|
|
7519
|
+
return Math.abs(lengthDifference) > EPS12 ? lengthDifference : countTurns(first.path) - countTurns(second.path);
|
|
7520
|
+
});
|
|
7521
|
+
const bestCandidate = candidates[0];
|
|
7522
|
+
if (!bestCandidate) break;
|
|
7523
|
+
outputTraces[bestCandidate.traceIndex] = {
|
|
7524
|
+
...outputTraces[bestCandidate.traceIndex],
|
|
7525
|
+
tracePath: bestCandidate.path
|
|
7526
|
+
};
|
|
7527
|
+
reroutedTraceCount++;
|
|
7528
|
+
}
|
|
7529
|
+
return {
|
|
7530
|
+
traces: outputTraces,
|
|
7531
|
+
reroutedTraceCount
|
|
7532
|
+
};
|
|
7533
|
+
};
|
|
7534
|
+
|
|
7388
7535
|
// lib/solvers/TraceCleanupSolver/TraceCleanupSolver.ts
|
|
7389
7536
|
var DEFAULT_OPERATIONS = [
|
|
7390
7537
|
"untangling_traces",
|
|
@@ -7436,6 +7583,9 @@ var TraceCleanupSolver = class extends BaseSolver {
|
|
|
7436
7583
|
case "untangling_traces":
|
|
7437
7584
|
this._runUntangleTracesStep();
|
|
7438
7585
|
break;
|
|
7586
|
+
case "rerouting_generated_net_label_connector_crossings":
|
|
7587
|
+
this._runGeneratedNetLabelConnectorCrossingRerouteStep();
|
|
7588
|
+
break;
|
|
7439
7589
|
case "minimizing_turns":
|
|
7440
7590
|
this._runMinimizeTurnsStep();
|
|
7441
7591
|
break;
|
|
@@ -7459,6 +7609,23 @@ var TraceCleanupSolver = class extends BaseSolver {
|
|
|
7459
7609
|
allTraces: Array.from(this.tracesMap.values())
|
|
7460
7610
|
});
|
|
7461
7611
|
}
|
|
7612
|
+
_runGeneratedNetLabelConnectorCrossingRerouteStep() {
|
|
7613
|
+
const result = rerouteGeneratedNetLabelConnectorCrossings({
|
|
7614
|
+
inputProblem: this.input.inputProblem,
|
|
7615
|
+
traces: this.outputTraces,
|
|
7616
|
+
netLabelPlacements: this.input.allLabelPlacements,
|
|
7617
|
+
mergedLabelNetIdMap: this.input.mergedLabelNetIdMap,
|
|
7618
|
+
clearance: this.input.paddingBuffer,
|
|
7619
|
+
eligibleTraceIds: this.input.eligibleTraceIds,
|
|
7620
|
+
connectorTraceIds: this.input.netLabelConnectorTraceIds ?? /* @__PURE__ */ new Set()
|
|
7621
|
+
});
|
|
7622
|
+
this.outputTraces = result.traces;
|
|
7623
|
+
this.tracesMap = new Map(
|
|
7624
|
+
this.outputTraces.map((trace) => [trace.mspPairId, trace])
|
|
7625
|
+
);
|
|
7626
|
+
this.stats.reroutedGeneratedConnectorCrossingTraceCount = result.reroutedTraceCount;
|
|
7627
|
+
this._advancePipeline();
|
|
7628
|
+
}
|
|
7462
7629
|
_runMinimizeTurnsStep() {
|
|
7463
7630
|
if (this.traceIdQueue.length === 0) {
|
|
7464
7631
|
this._advancePipeline();
|
|
@@ -8496,16 +8663,16 @@ var createPortOnlyLabelConnectorTrace = ({
|
|
|
8496
8663
|
var LABEL_SEARCH_STEP = 0.05;
|
|
8497
8664
|
var MAX_RECORDED_CANDIDATES = 2e3;
|
|
8498
8665
|
var WICK_CLEARANCE = 1e-3;
|
|
8499
|
-
var
|
|
8500
|
-
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE +
|
|
8666
|
+
var EPS13 = 1e-9;
|
|
8667
|
+
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS13;
|
|
8501
8668
|
var CANDIDATE_SELECTED_COLOR2 = "blue";
|
|
8502
8669
|
var CANDIDATE_REJECTED_COLOR2 = "red";
|
|
8503
8670
|
|
|
8504
8671
|
// lib/solvers/AvailableNetOrientationSolver/geometry.ts
|
|
8505
8672
|
var isYOrientation = (orientation) => orientation === "y+" || orientation === "y-";
|
|
8506
8673
|
var isXOrientation = (orientation) => orientation === "x+" || orientation === "x-";
|
|
8507
|
-
var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
8508
|
-
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) >
|
|
8674
|
+
var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS13 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS13;
|
|
8675
|
+
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS13;
|
|
8509
8676
|
var traceCrossesBoundsInterior = (bounds, traceMap) => {
|
|
8510
8677
|
for (const trace of Object.values(traceMap)) {
|
|
8511
8678
|
const points = trace.tracePath;
|
|
@@ -8528,7 +8695,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
|
8528
8695
|
return false;
|
|
8529
8696
|
}
|
|
8530
8697
|
if (sameX2(p1, p2)) {
|
|
8531
|
-
if (p1.x <= interiorBounds.minX +
|
|
8698
|
+
if (p1.x <= interiorBounds.minX + EPS13 || p1.x >= interiorBounds.maxX - EPS13) {
|
|
8532
8699
|
return false;
|
|
8533
8700
|
}
|
|
8534
8701
|
return rangesOverlap(
|
|
@@ -8539,7 +8706,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
|
8539
8706
|
);
|
|
8540
8707
|
}
|
|
8541
8708
|
if (sameY2(p1, p2)) {
|
|
8542
|
-
if (p1.y <= interiorBounds.minY +
|
|
8709
|
+
if (p1.y <= interiorBounds.minY + EPS13 || p1.y >= interiorBounds.maxY - EPS13) {
|
|
8543
8710
|
return false;
|
|
8544
8711
|
}
|
|
8545
8712
|
return rangesOverlap(
|
|
@@ -8587,8 +8754,8 @@ var simplifyOrthogonalPath = (path) => {
|
|
|
8587
8754
|
return simplified;
|
|
8588
8755
|
};
|
|
8589
8756
|
var pointsEqual2 = (a, b) => sameX2(a, b) && sameY2(a, b);
|
|
8590
|
-
var sameX2 = (a, b) => Math.abs(a.x - b.x) <=
|
|
8591
|
-
var sameY2 = (a, b) => Math.abs(a.y - b.y) <=
|
|
8757
|
+
var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS13;
|
|
8758
|
+
var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS13;
|
|
8592
8759
|
var getMaxSearchDistance = (inputProblem) => {
|
|
8593
8760
|
const maxChipWidth = Math.max(
|
|
8594
8761
|
...inputProblem.chips.map((chip) => chip.width),
|
|
@@ -8747,7 +8914,7 @@ var AvailableNetOrientationObstacleIndex = class {
|
|
|
8747
8914
|
}
|
|
8748
8915
|
getTraceSegmentsInBounds(bounds) {
|
|
8749
8916
|
if (!this.traceSegmentIndex) return [];
|
|
8750
|
-
const searchBounds = getPaddedBounds(bounds,
|
|
8917
|
+
const searchBounds = getPaddedBounds(bounds, EPS13);
|
|
8751
8918
|
return this.traceSegmentIndex.search(
|
|
8752
8919
|
searchBounds.minX,
|
|
8753
8920
|
searchBounds.minY,
|
|
@@ -8760,7 +8927,7 @@ var AvailableNetOrientationObstacleIndex = class {
|
|
|
8760
8927
|
for (let pointIndex = 0; pointIndex < tracePath.length - 1; pointIndex++) {
|
|
8761
8928
|
const segmentBounds = getPaddedBounds(
|
|
8762
8929
|
getSegmentBounds(tracePath[pointIndex], tracePath[pointIndex + 1]),
|
|
8763
|
-
|
|
8930
|
+
EPS13
|
|
8764
8931
|
);
|
|
8765
8932
|
for (const labelIndex of this.getLabelIndicesInBounds(segmentBounds)) {
|
|
8766
8933
|
labelIndices.add(labelIndex);
|
|
@@ -8773,7 +8940,7 @@ var AvailableNetOrientationObstacleIndex = class {
|
|
|
8773
8940
|
const start = tracePath[pointIndex];
|
|
8774
8941
|
const end = tracePath[pointIndex + 1];
|
|
8775
8942
|
const nearbyChips = this.chipObstacleSpatialIndex.getChipsInBounds(
|
|
8776
|
-
getPaddedBounds(getSegmentBounds(start, end),
|
|
8943
|
+
getPaddedBounds(getSegmentBounds(start, end), EPS13)
|
|
8777
8944
|
);
|
|
8778
8945
|
for (const chip of nearbyChips) {
|
|
8779
8946
|
if (segmentCrossesBoundsInterior(start, end, chip.bounds)) return true;
|
|
@@ -8920,7 +9087,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8920
9087
|
getOutput() {
|
|
8921
9088
|
return {
|
|
8922
9089
|
traces: this.traces,
|
|
8923
|
-
netLabelPlacements: this.outputNetLabelPlacements
|
|
9090
|
+
netLabelPlacements: this.outputNetLabelPlacements,
|
|
9091
|
+
netLabelConnectorTraceIds: this.netLabelConnectorTraceIds
|
|
8924
9092
|
};
|
|
8925
9093
|
}
|
|
8926
9094
|
getProcessableLabelIndices() {
|
|
@@ -9241,7 +9409,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9241
9409
|
index,
|
|
9242
9410
|
pin: this.pinMap[otherLabel.pinIds[0]]
|
|
9243
9411
|
})).filter(
|
|
9244
|
-
({ index, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x +
|
|
9412
|
+
({ index, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x + EPS13
|
|
9245
9413
|
).sort((a, b) => a.pin.x - b.pin.x)[0]?.pin;
|
|
9246
9414
|
if (orientation === "y-" && nextPinToRight) return null;
|
|
9247
9415
|
const anchorX = orientation === "y-" ? Math.max(
|
|
@@ -9274,7 +9442,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9274
9442
|
const centeredAnchorY = hasUpFacingStack ? (lowestUpFacingLabelY + highestUpFacingLabelY) / 2 : stackedAnchorY;
|
|
9275
9443
|
const anchorYs = orientation === "y-" ? [centeredAnchorY, stackedAnchorY] : [stackedAnchorY];
|
|
9276
9444
|
for (const anchorY of anchorYs) {
|
|
9277
|
-
if (anchorY - label.anchorPoint.y > this.maxSearchDistance +
|
|
9445
|
+
if (anchorY - label.anchorPoint.y > this.maxSearchDistance + EPS13) {
|
|
9278
9446
|
continue;
|
|
9279
9447
|
}
|
|
9280
9448
|
const candidate = this.createCandidate(
|
|
@@ -9303,11 +9471,11 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9303
9471
|
if (trace.globalConnNetId !== label.globalConnNetId) return false;
|
|
9304
9472
|
const path = trace.tracePath;
|
|
9305
9473
|
return path.some((point, pointIndex) => {
|
|
9306
|
-
if (Math.abs(point.x - label.anchorPoint.x) >
|
|
9474
|
+
if (Math.abs(point.x - label.anchorPoint.x) > EPS13 || Math.abs(point.y - label.anchorPoint.y) > EPS13) {
|
|
9307
9475
|
return false;
|
|
9308
9476
|
}
|
|
9309
9477
|
return [path[pointIndex - 1], path[pointIndex + 1]].some(
|
|
9310
|
-
(neighbor) => neighbor && Math.abs(neighbor.x - point.x) <=
|
|
9478
|
+
(neighbor) => neighbor && Math.abs(neighbor.x - point.x) <= EPS13 && (neighbor.y - point.y) * direction.y > EPS13
|
|
9311
9479
|
);
|
|
9312
9480
|
});
|
|
9313
9481
|
});
|
|
@@ -9397,7 +9565,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9397
9565
|
orientation
|
|
9398
9566
|
);
|
|
9399
9567
|
if (outwardDirection.x === 0 && outwardDirection.y === 0) continue;
|
|
9400
|
-
for (let distance7 = LABEL_SEARCH_STEP; distance7 <= this.maxSearchDistance +
|
|
9568
|
+
for (let distance7 = LABEL_SEARCH_STEP; distance7 <= this.maxSearchDistance + EPS13; distance7 += LABEL_SEARCH_STEP) {
|
|
9401
9569
|
const anchorPoint = {
|
|
9402
9570
|
x: connectorSource.x + outwardDirection.x * distance7,
|
|
9403
9571
|
y: connectorSource.y + outwardDirection.y * distance7
|
|
@@ -9475,7 +9643,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9475
9643
|
const furthestRowPoints = points.filter(
|
|
9476
9644
|
(point) => Math.abs(
|
|
9477
9645
|
point.x * direction.x + point.y * direction.y - furthestAlong
|
|
9478
|
-
) <=
|
|
9646
|
+
) <= EPS13
|
|
9479
9647
|
);
|
|
9480
9648
|
const directHostPinIds = new Set(
|
|
9481
9649
|
[...directHostTraceIds].flatMap(
|
|
@@ -9496,7 +9664,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9496
9664
|
preferNearestBendOnOutwardRow: adjacentTraces.some(
|
|
9497
9665
|
(trace) => furthestRowPoints.some(
|
|
9498
9666
|
(point) => trace.tracePath.some(
|
|
9499
|
-
(tracePoint) => Math.abs(tracePoint.x - point.x) <=
|
|
9667
|
+
(tracePoint) => Math.abs(tracePoint.x - point.x) <= EPS13 && Math.abs(tracePoint.y - point.y) <= EPS13
|
|
9500
9668
|
)
|
|
9501
9669
|
)
|
|
9502
9670
|
)
|
|
@@ -9508,7 +9676,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9508
9676
|
for (let i = 0; i < otherTrace.tracePath.length - 1; i++) {
|
|
9509
9677
|
const start = otherTrace.tracePath[i];
|
|
9510
9678
|
const end = otherTrace.tracePath[i + 1];
|
|
9511
|
-
if (Math.abs(start.x - end.x) <=
|
|
9679
|
+
if (Math.abs(start.x - end.x) <= EPS13 && Math.abs(start.y - end.y) > EPS13) {
|
|
9512
9680
|
verticalRailXs.add(start.x);
|
|
9513
9681
|
}
|
|
9514
9682
|
}
|
|
@@ -9516,7 +9684,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9516
9684
|
for (let i = 0; i < trace.tracePath.length - 1; i++) {
|
|
9517
9685
|
const start = trace.tracePath[i];
|
|
9518
9686
|
const end = trace.tracePath[i + 1];
|
|
9519
|
-
if (Math.abs(start.x - end.x) <=
|
|
9687
|
+
if (Math.abs(start.x - end.x) <= EPS13 && Math.abs(start.y - end.y) > EPS13 && [...verticalRailXs].some((x) => Math.abs(x - start.x) <= EPS13)) {
|
|
9520
9688
|
return true;
|
|
9521
9689
|
}
|
|
9522
9690
|
}
|
|
@@ -9535,7 +9703,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9535
9703
|
);
|
|
9536
9704
|
const maxSearchDistance = this.getSearchDistanceLimit(label, orientation);
|
|
9537
9705
|
const maxOutwardDistance = outwardDirection.x === 0 && outwardDirection.y === 0 ? 0 : this.maxSearchDistance;
|
|
9538
|
-
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance +
|
|
9706
|
+
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS13; outwardDistance += LABEL_SEARCH_STEP) {
|
|
9539
9707
|
const baseAnchor = {
|
|
9540
9708
|
x: initialBaseAnchor.x + outwardDirection.x * outwardDistance,
|
|
9541
9709
|
y: initialBaseAnchor.y + outwardDirection.y * outwardDistance
|
|
@@ -9611,7 +9779,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9611
9779
|
connectorSource,
|
|
9612
9780
|
startDistance = LABEL_SEARCH_STEP
|
|
9613
9781
|
} = params;
|
|
9614
|
-
for (let distance7 = startDistance; distance7 <= maxSearchDistance +
|
|
9782
|
+
for (let distance7 = startDistance; distance7 <= maxSearchDistance + EPS13; distance7 += LABEL_SEARCH_STEP) {
|
|
9615
9783
|
const anchorPoint = {
|
|
9616
9784
|
x: baseAnchor.x + direction.x * distance7,
|
|
9617
9785
|
y: baseAnchor.y + direction.y * distance7
|
|
@@ -9940,9 +10108,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9940
10108
|
const { anchorPoint, orientation } = candidate;
|
|
9941
10109
|
const chipBounds = chip.bounds;
|
|
9942
10110
|
if (isYOrientation(orientation)) {
|
|
9943
|
-
return anchorPoint.x < chipBounds.minX -
|
|
10111
|
+
return anchorPoint.x < chipBounds.minX - EPS13 || anchorPoint.x > chipBounds.maxX + EPS13;
|
|
9944
10112
|
}
|
|
9945
|
-
return anchorPoint.y < chipBounds.minY -
|
|
10113
|
+
return anchorPoint.y < chipBounds.minY - EPS13 || anchorPoint.y > chipBounds.maxY + EPS13;
|
|
9946
10114
|
});
|
|
9947
10115
|
}
|
|
9948
10116
|
staysOutsideConnectedPinRow(params) {
|
|
@@ -9950,9 +10118,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
9950
10118
|
const pin = this.pinMap[label.pinIds[0]];
|
|
9951
10119
|
if (!pin || !isYOrientation(candidate.orientation)) return false;
|
|
9952
10120
|
if (candidate.anchorPoint.x < pin.x) {
|
|
9953
|
-
return bounds.maxX <= pin.x + CONNECTED_PIN_ROW_OVERLAP_TOLERANCE +
|
|
10121
|
+
return bounds.maxX <= pin.x + CONNECTED_PIN_ROW_OVERLAP_TOLERANCE + EPS13;
|
|
9954
10122
|
}
|
|
9955
|
-
return bounds.minX >= pin.x - CONNECTED_PIN_ROW_OVERLAP_TOLERANCE -
|
|
10123
|
+
return bounds.minX >= pin.x - CONNECTED_PIN_ROW_OVERLAP_TOLERANCE - EPS13;
|
|
9956
10124
|
}
|
|
9957
10125
|
getBoundsStatus(candidateBoundsCheck) {
|
|
9958
10126
|
const { bounds, labelIndex, label, ignoreChipCollisions } = candidateBoundsCheck;
|
|
@@ -10033,14 +10201,14 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10033
10201
|
candidate.width,
|
|
10034
10202
|
candidate.height
|
|
10035
10203
|
);
|
|
10036
|
-
if (labelBounds.minY < chip.bounds.minY -
|
|
10204
|
+
if (labelBounds.minY < chip.bounds.minY - EPS13 || labelBounds.maxY > chip.bounds.maxY + EPS13) {
|
|
10037
10205
|
return false;
|
|
10038
10206
|
}
|
|
10039
|
-
if (candidate.anchorPoint.x >= chip.bounds.minX -
|
|
10207
|
+
if (candidate.anchorPoint.x >= chip.bounds.minX - EPS13 && candidate.anchorPoint.x <= chip.bounds.maxX + EPS13) {
|
|
10040
10208
|
return false;
|
|
10041
10209
|
}
|
|
10042
10210
|
return chip.pins.every(
|
|
10043
|
-
(pin) => label.pinIds.includes(pin.pinId) || pin.y <= labelBounds.minY +
|
|
10211
|
+
(pin) => label.pinIds.includes(pin.pinId) || pin.y <= labelBounds.minY + EPS13 || pin.y >= labelBounds.maxY - EPS13
|
|
10044
10212
|
);
|
|
10045
10213
|
}
|
|
10046
10214
|
getTextBlockedMultiPinRailTraces(label, orientation) {
|
|
@@ -10067,20 +10235,20 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10067
10235
|
const pins = [...connectedPinIds].map((pinId) => this.pinMap[pinId]);
|
|
10068
10236
|
const direction = dir(orientation);
|
|
10069
10237
|
const pinX = pins[0].x;
|
|
10070
|
-
if (pins.some((pin) => Math.abs(pin.x - pinX) >
|
|
10071
|
-
const sidePins = this.inputProblem.chips.find((chip) => chip.chipId === componentId).pins.filter((pin) => Math.abs(pin.x - pinX) <=
|
|
10238
|
+
if (pins.some((pin) => Math.abs(pin.x - pinX) > EPS13)) return null;
|
|
10239
|
+
const sidePins = this.inputProblem.chips.find((chip) => chip.chipId === componentId).pins.filter((pin) => Math.abs(pin.x - pinX) <= EPS13);
|
|
10072
10240
|
const minY = Math.min(...pins.map((pin) => pin.y));
|
|
10073
10241
|
const maxY = Math.max(...pins.map((pin) => pin.y));
|
|
10074
10242
|
if (sidePins.some(
|
|
10075
|
-
(pin) => pin.y >= minY -
|
|
10076
|
-
) || orientation === "y-" && minY > Math.min(...sidePins.map((pin) => pin.y)) +
|
|
10243
|
+
(pin) => pin.y >= minY - EPS13 && pin.y <= maxY + EPS13 && !connectedPinIds.has(pin.pinId)
|
|
10244
|
+
) || orientation === "y-" && minY > Math.min(...sidePins.map((pin) => pin.y)) + EPS13 || orientation === "y+" && maxY < Math.max(...sidePins.map((pin) => pin.y)) - EPS13) {
|
|
10077
10245
|
return null;
|
|
10078
10246
|
}
|
|
10079
10247
|
const outerPinPosition = Math.max(
|
|
10080
10248
|
...pins.map((pin) => pin.x * direction.x + pin.y * direction.y)
|
|
10081
10249
|
);
|
|
10082
10250
|
const blockedByText = (this.inputProblem.textBoxes ?? []).some(
|
|
10083
|
-
(textBox) => textBox.chipId === componentId && textBox.center.x * direction.x + textBox.center.y * direction.y > outerPinPosition +
|
|
10251
|
+
(textBox) => textBox.chipId === componentId && textBox.center.x * direction.x + textBox.center.y * direction.y > outerPinPosition + EPS13
|
|
10084
10252
|
);
|
|
10085
10253
|
return blockedByText ? [...connectedTraces] : null;
|
|
10086
10254
|
}
|
|
@@ -10096,7 +10264,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10096
10264
|
...new Set(
|
|
10097
10265
|
localTraces.flatMap((trace) => trace.tracePath.map((point) => point.x))
|
|
10098
10266
|
)
|
|
10099
|
-
].filter((x) => Math.abs(x - pinX) >
|
|
10267
|
+
].filter((x) => Math.abs(x - pinX) > EPS13).sort((a, b) => Math.abs(a - pinX) - Math.abs(b - pinX));
|
|
10100
10268
|
for (const x of railXs) {
|
|
10101
10269
|
const connectorSource = { x, y: connectorY };
|
|
10102
10270
|
if (!Object.values(this.traceMap).some(
|
|
@@ -10159,8 +10327,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10159
10327
|
if (!chip) return null;
|
|
10160
10328
|
const sides = new Set(
|
|
10161
10329
|
pins.map((pin) => {
|
|
10162
|
-
if (Math.abs(pin.x - chip.bounds.minX) <=
|
|
10163
|
-
if (Math.abs(pin.x - chip.bounds.maxX) <=
|
|
10330
|
+
if (Math.abs(pin.x - chip.bounds.minX) <= EPS13) return "left";
|
|
10331
|
+
if (Math.abs(pin.x - chip.bounds.maxX) <= EPS13) return "right";
|
|
10164
10332
|
return null;
|
|
10165
10333
|
})
|
|
10166
10334
|
);
|
|
@@ -10199,16 +10367,16 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10199
10367
|
}
|
|
10200
10368
|
sharesChipBoundary(bounds) {
|
|
10201
10369
|
const boundarySearchBounds = {
|
|
10202
|
-
minX: bounds.minX - WICK_CLEARANCE -
|
|
10203
|
-
minY: bounds.minY - WICK_CLEARANCE -
|
|
10204
|
-
maxX: bounds.maxX + WICK_CLEARANCE +
|
|
10205
|
-
maxY: bounds.maxY + WICK_CLEARANCE +
|
|
10370
|
+
minX: bounds.minX - WICK_CLEARANCE - EPS13,
|
|
10371
|
+
minY: bounds.minY - WICK_CLEARANCE - EPS13,
|
|
10372
|
+
maxX: bounds.maxX + WICK_CLEARANCE + EPS13,
|
|
10373
|
+
maxY: bounds.maxY + WICK_CLEARANCE + EPS13
|
|
10206
10374
|
};
|
|
10207
10375
|
const nearbyChips = this.chipObstacleSpatialIndex.getChipsInBounds(boundarySearchBounds);
|
|
10208
10376
|
for (const chip of nearbyChips) {
|
|
10209
10377
|
const chipBounds = chip.bounds;
|
|
10210
|
-
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE +
|
|
10211
|
-
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE +
|
|
10378
|
+
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS13 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS13;
|
|
10379
|
+
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS13 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS13;
|
|
10212
10380
|
if (adjacentToVerticalSide && rangesOverlap(
|
|
10213
10381
|
bounds.minY,
|
|
10214
10382
|
bounds.maxY,
|
|
@@ -10270,7 +10438,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10270
10438
|
let nearestDistance = Number.POSITIVE_INFINITY;
|
|
10271
10439
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
10272
10440
|
const bounds = chip.bounds;
|
|
10273
|
-
if (point.x < bounds.minX -
|
|
10441
|
+
if (point.x < bounds.minX - EPS13 || point.x > bounds.maxX + EPS13 || point.y < bounds.minY - EPS13 || point.y > bounds.maxY + EPS13) {
|
|
10274
10442
|
continue;
|
|
10275
10443
|
}
|
|
10276
10444
|
for (const [side, distance7] of getSideDistances(point, bounds)) {
|
|
@@ -10287,8 +10455,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
10287
10455
|
let nearestDistanceSq = Number.POSITIVE_INFINITY;
|
|
10288
10456
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
10289
10457
|
const bounds = chip.bounds;
|
|
10290
|
-
const dx = point.x < bounds.minX -
|
|
10291
|
-
const dy = point.y < bounds.minY -
|
|
10458
|
+
const dx = point.x < bounds.minX - EPS13 ? bounds.minX - point.x : point.x > bounds.maxX + EPS13 ? point.x - bounds.maxX : 0;
|
|
10459
|
+
const dy = point.y < bounds.minY - EPS13 ? bounds.minY - point.y : point.y > bounds.maxY + EPS13 ? point.y - bounds.maxY : 0;
|
|
10292
10460
|
if (dx === 0 && dy === 0) continue;
|
|
10293
10461
|
const distanceSq = dx ** 2 + dy ** 2;
|
|
10294
10462
|
if (distanceSq >= nearestDistanceSq) continue;
|
|
@@ -10848,11 +11016,11 @@ var getOrientationConstraint = (inputProblem, label) => {
|
|
|
10848
11016
|
};
|
|
10849
11017
|
|
|
10850
11018
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/geometry.ts
|
|
10851
|
-
var
|
|
11019
|
+
var EPS14 = 1e-6;
|
|
10852
11020
|
var TRACE_BOUNDARY_TOLERANCE2 = 1e-6;
|
|
10853
11021
|
var getLabelBounds = (label) => getRectBounds(label.center, label.width, label.height);
|
|
10854
|
-
var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >
|
|
10855
|
-
var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -
|
|
11022
|
+
var rectsOverlap3 = (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;
|
|
11023
|
+
var rectsTouchOrOverlap = (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;
|
|
10856
11024
|
var traceCrossesBoundsInterior2 = (bounds, traces) => {
|
|
10857
11025
|
for (const trace of traces) {
|
|
10858
11026
|
const points = trace.tracePath;
|
|
@@ -10898,7 +11066,7 @@ var getPointAtTraceDistance = (trace, distance7) => {
|
|
|
10898
11066
|
const end = trace.tracePath[i + 1];
|
|
10899
11067
|
const segmentLength = getManhattanDistance(start, end);
|
|
10900
11068
|
const nextDistance = pathDistance + segmentLength;
|
|
10901
|
-
if (distance7 <= nextDistance +
|
|
11069
|
+
if (distance7 <= nextDistance + EPS14) {
|
|
10902
11070
|
const offset = Math.max(
|
|
10903
11071
|
0,
|
|
10904
11072
|
Math.min(segmentLength, distance7 - pathDistance)
|
|
@@ -10937,7 +11105,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
10937
11105
|
return false;
|
|
10938
11106
|
}
|
|
10939
11107
|
if (isVertical4(start, end)) {
|
|
10940
|
-
if (start.x <= interior.minX +
|
|
11108
|
+
if (start.x <= interior.minX + EPS14 || start.x >= interior.maxX - EPS14) {
|
|
10941
11109
|
return false;
|
|
10942
11110
|
}
|
|
10943
11111
|
return rangesOverlap2(
|
|
@@ -10948,7 +11116,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
10948
11116
|
);
|
|
10949
11117
|
}
|
|
10950
11118
|
if (isHorizontal3(start, end)) {
|
|
10951
|
-
if (start.y <= interior.minY +
|
|
11119
|
+
if (start.y <= interior.minY + EPS14 || start.y >= interior.maxY - EPS14) {
|
|
10952
11120
|
return false;
|
|
10953
11121
|
}
|
|
10954
11122
|
return rangesOverlap2(
|
|
@@ -10962,10 +11130,10 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
|
|
|
10962
11130
|
};
|
|
10963
11131
|
var isPointOnSegment2 = (point, start, end) => {
|
|
10964
11132
|
if (isHorizontal3(start, end)) {
|
|
10965
|
-
return Math.abs(point.y - start.y) <=
|
|
11133
|
+
return Math.abs(point.y - start.y) <= EPS14 && point.x >= Math.min(start.x, end.x) - EPS14 && point.x <= Math.max(start.x, end.x) + EPS14;
|
|
10966
11134
|
}
|
|
10967
11135
|
if (isVertical4(start, end)) {
|
|
10968
|
-
return Math.abs(point.x - start.x) <=
|
|
11136
|
+
return Math.abs(point.x - start.x) <= EPS14 && point.y >= Math.min(start.y, end.y) - EPS14 && point.y <= Math.max(start.y, end.y) + EPS14;
|
|
10969
11137
|
}
|
|
10970
11138
|
return false;
|
|
10971
11139
|
};
|
|
@@ -10973,9 +11141,9 @@ var getSegmentDirection = (start, end) => ({
|
|
|
10973
11141
|
x: isVertical4(start, end) ? 0 : Math.sign(end.x - start.x),
|
|
10974
11142
|
y: isHorizontal3(start, end) ? 0 : Math.sign(end.y - start.y)
|
|
10975
11143
|
});
|
|
10976
|
-
var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <=
|
|
10977
|
-
var isVertical4 = (start, end) => Math.abs(start.x - end.x) <=
|
|
10978
|
-
var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) >
|
|
11144
|
+
var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <= EPS14;
|
|
11145
|
+
var isVertical4 = (start, end) => Math.abs(start.x - end.x) <= EPS14;
|
|
11146
|
+
var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS14;
|
|
10979
11147
|
var getUniquePinCount2 = (pinIds) => new Set(pinIds).size;
|
|
10980
11148
|
|
|
10981
11149
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts
|
|
@@ -11032,7 +11200,7 @@ var getCandidateDistances = (traceLength, vertexDistances) => {
|
|
|
11032
11200
|
for (const distance7 of vertexDistances) {
|
|
11033
11201
|
distances.add(roundDistance(distance7));
|
|
11034
11202
|
}
|
|
11035
|
-
return [...distances].filter((distance7) => distance7 >= -
|
|
11203
|
+
return [...distances].filter((distance7) => distance7 >= -EPS14 && distance7 <= traceLength + EPS14).sort((a, b) => a - b);
|
|
11036
11204
|
};
|
|
11037
11205
|
var getOrientationsForPoint = (params) => {
|
|
11038
11206
|
const { inputProblem, label, point, orientationConstraint } = params;
|
|
@@ -11121,13 +11289,13 @@ var getOutwardOrientationOptions = (point, chipBounds) => {
|
|
|
11121
11289
|
};
|
|
11122
11290
|
var getOutwardAxisOption = (params) => {
|
|
11123
11291
|
const { value, min, max, center, positiveOrientation, negativeOrientation } = params;
|
|
11124
|
-
if (value > max +
|
|
11292
|
+
if (value > max + EPS14) {
|
|
11125
11293
|
return {
|
|
11126
11294
|
orientation: positiveOrientation,
|
|
11127
11295
|
outwardScore: 1 + value - max
|
|
11128
11296
|
};
|
|
11129
11297
|
}
|
|
11130
|
-
if (value < min -
|
|
11298
|
+
if (value < min - EPS14) {
|
|
11131
11299
|
return {
|
|
11132
11300
|
orientation: negativeOrientation,
|
|
11133
11301
|
outwardScore: 1 + min - value
|
|
@@ -11138,7 +11306,7 @@ var getOutwardAxisOption = (params) => {
|
|
|
11138
11306
|
outwardScore: getNormalizedCenterDistance(value, center, max - min)
|
|
11139
11307
|
};
|
|
11140
11308
|
};
|
|
11141
|
-
var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(
|
|
11309
|
+
var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS14, span / 2);
|
|
11142
11310
|
var ALL_ORIENTATIONS = ["x+", "x-", "y+", "y-"];
|
|
11143
11311
|
var getFlippedOrientation = (orientation) => {
|
|
11144
11312
|
switch (orientation) {
|
|
@@ -11206,7 +11374,7 @@ var getNetLabelHeight = (inputProblem, label) => {
|
|
|
11206
11374
|
)?.netLabelHeight;
|
|
11207
11375
|
};
|
|
11208
11376
|
var roundDistance = (distance7) => Number(distance7.toFixed(6));
|
|
11209
|
-
var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <=
|
|
11377
|
+
var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS14 && Math.abs(point.y - label.anchorPoint.y) <= EPS14 && orientation === label.orientation;
|
|
11210
11378
|
|
|
11211
11379
|
// lib/solvers/TraceAnchoredNetLabelOverlapSolver/visualize.ts
|
|
11212
11380
|
var CANDIDATE_SELECTED_COLOR4 = "blue";
|
|
@@ -15026,15 +15194,15 @@ var pathIntersectsRenderedLabel = (path, label) => {
|
|
|
15026
15194
|
};
|
|
15027
15195
|
|
|
15028
15196
|
// lib/solvers/InlineNetLabelSolver/restoreReroutesAroundSupersededLabels.ts
|
|
15029
|
-
var
|
|
15197
|
+
var EPS15 = 1e-6;
|
|
15030
15198
|
var getPathLength5 = (path) => path.slice(1).reduce((length, point, pointIndex) => {
|
|
15031
15199
|
const previousPoint = path[pointIndex];
|
|
15032
15200
|
return length + Math.abs(point.x - previousPoint.x) + Math.abs(point.y - previousPoint.y);
|
|
15033
15201
|
}, 0);
|
|
15034
15202
|
var pathsEqual = (first, second) => first.length === second.length && first.every(
|
|
15035
|
-
(point, index) => Math.abs(point.x - second[index].x) <=
|
|
15203
|
+
(point, index) => Math.abs(point.x - second[index].x) <= EPS15 && Math.abs(point.y - second[index].y) <= EPS15
|
|
15036
15204
|
);
|
|
15037
|
-
var isStrictlySimpler = (candidate, current) => candidate.length < current.length && getPathLength5(candidate) <= getPathLength5(current) +
|
|
15205
|
+
var isStrictlySimpler = (candidate, current) => candidate.length < current.length && getPathLength5(candidate) <= getPathLength5(current) + EPS15;
|
|
15038
15206
|
var getIntersectionKeys = (path, otherPath) => {
|
|
15039
15207
|
const intersections = /* @__PURE__ */ new Set();
|
|
15040
15208
|
for (let pathIndex = 0; pathIndex < path.length - 1; pathIndex++) {
|
|
@@ -16089,12 +16257,12 @@ var getTraceRecoveryConnectivityMaps = (inputProblem) => {
|
|
|
16089
16257
|
};
|
|
16090
16258
|
|
|
16091
16259
|
// lib/solvers/NetLabelToTraceSolver/reduceTraceCrossings.ts
|
|
16092
|
-
var
|
|
16093
|
-
var isHorizontal4 = (start, end) => Math.abs(start.y - end.y) <
|
|
16094
|
-
var isVertical5 = (start, end) => Math.abs(start.x - end.x) <
|
|
16260
|
+
var EPS16 = 1e-9;
|
|
16261
|
+
var isHorizontal4 = (start, end) => Math.abs(start.y - end.y) < EPS16;
|
|
16262
|
+
var isVertical5 = (start, end) => Math.abs(start.x - end.x) < EPS16;
|
|
16095
16263
|
var compactConsecutivePoints = (path) => path.filter((point, index) => {
|
|
16096
16264
|
const previousPoint = path[index - 1];
|
|
16097
|
-
return !previousPoint || Math.abs(point.x - previousPoint.x) >=
|
|
16265
|
+
return !previousPoint || Math.abs(point.x - previousPoint.x) >= EPS16 || Math.abs(point.y - previousPoint.y) >= EPS16;
|
|
16098
16266
|
});
|
|
16099
16267
|
var isValidOrthogonalPath = (path) => {
|
|
16100
16268
|
if (path.length < 2 || !path.every((point, index) => {
|
|
@@ -16132,7 +16300,7 @@ var getEndpointAlignedSegmentCandidates = (tracePath) => {
|
|
|
16132
16300
|
}
|
|
16133
16301
|
const alignedCoordinates = segmentIsVertical ? [previousPoint.x, nextPoint.x] : [previousPoint.y, nextPoint.y];
|
|
16134
16302
|
for (const alignedCoordinate of alignedCoordinates) {
|
|
16135
|
-
if (Math.abs(alignedCoordinate - (segmentIsVertical ? start.x : start.y)) <
|
|
16303
|
+
if (Math.abs(alignedCoordinate - (segmentIsVertical ? start.x : start.y)) < EPS16) {
|
|
16136
16304
|
continue;
|
|
16137
16305
|
}
|
|
16138
16306
|
const candidate = tracePath.map((point) => ({ ...point }));
|
|
@@ -16908,10 +17076,14 @@ var SchematicTracePipelineSolver = class extends BaseSolver {
|
|
|
16908
17076
|
allLabelPlacements: collisionOutput.netLabelPlacements,
|
|
16909
17077
|
mergedLabelNetIdMap: labelMergingOutput.mergedLabelNetIdMap,
|
|
16910
17078
|
paddingBuffer: 0.1,
|
|
16911
|
-
operations: [
|
|
17079
|
+
operations: [
|
|
17080
|
+
"rerouting_generated_net_label_connector_crossings",
|
|
17081
|
+
"aligning_same_net_rails"
|
|
17082
|
+
],
|
|
16912
17083
|
eligibleTraceIds: new Set(
|
|
16913
17084
|
instance.traceCleanupSolver.getOutput().traces.map((trace) => trace.mspPairId)
|
|
16914
|
-
)
|
|
17085
|
+
),
|
|
17086
|
+
netLabelConnectorTraceIds: instance.availableNetOrientationSolver.netLabelConnectorTraceIds
|
|
16915
17087
|
}
|
|
16916
17088
|
];
|
|
16917
17089
|
}
|