@tscircuit/core 0.0.2118 → 0.0.2120
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 +31 -4
- package/dist/index.js +449 -343
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -84,6 +84,7 @@ __export(components_exports, {
|
|
|
84
84
|
PcbNotePath: () => PcbNotePath,
|
|
85
85
|
PcbNoteRect: () => PcbNoteRect,
|
|
86
86
|
PcbNoteText: () => PcbNoteText,
|
|
87
|
+
PcbReturnCurrentSimulation: () => PcbReturnCurrentSimulation,
|
|
87
88
|
PcbSoldermaskOpening: () => PcbSoldermaskOpening,
|
|
88
89
|
PcbStiffener: () => PcbStiffener,
|
|
89
90
|
PcbTrace: () => PcbTrace,
|
|
@@ -93724,6 +93725,265 @@ var balanceZShapes = ({
|
|
|
93724
93725
|
tracePath: finalSimplifiedPath
|
|
93725
93726
|
};
|
|
93726
93727
|
};
|
|
93728
|
+
var LABEL_SEARCH_STEP = 0.05;
|
|
93729
|
+
var MAX_RECORDED_CANDIDATES = 2e3;
|
|
93730
|
+
var WICK_CLEARANCE = 1e-3;
|
|
93731
|
+
var EPS8 = 1e-9;
|
|
93732
|
+
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS8;
|
|
93733
|
+
var CANDIDATE_SELECTED_COLOR = "blue";
|
|
93734
|
+
var CANDIDATE_REJECTED_COLOR = "red";
|
|
93735
|
+
var isYOrientation = (orientation2) => orientation2 === "y+" || orientation2 === "y-";
|
|
93736
|
+
var isXOrientation = (orientation2) => orientation2 === "x+" || orientation2 === "x-";
|
|
93737
|
+
var rectsOverlap = (a2, b2) => Math.min(a2.maxX, b2.maxX) - Math.max(a2.minX, b2.minX) > EPS8 && Math.min(a2.maxY, b2.maxY) - Math.max(a2.minY, b2.minY) > EPS8;
|
|
93738
|
+
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS8;
|
|
93739
|
+
var traceCrossesBoundsInterior = (bounds, traceMap) => {
|
|
93740
|
+
for (const trace of Object.values(traceMap)) {
|
|
93741
|
+
const points = trace.tracePath;
|
|
93742
|
+
for (let i2 = 0; i2 < points.length - 1; i2++) {
|
|
93743
|
+
if (segmentCrossesBoundsInterior(points[i2], points[i2 + 1], bounds)) {
|
|
93744
|
+
return true;
|
|
93745
|
+
}
|
|
93746
|
+
}
|
|
93747
|
+
}
|
|
93748
|
+
return false;
|
|
93749
|
+
};
|
|
93750
|
+
var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
93751
|
+
const interiorBounds = {
|
|
93752
|
+
minX: bounds.minX + TRACE_BOUNDARY_TOLERANCE,
|
|
93753
|
+
minY: bounds.minY + TRACE_BOUNDARY_TOLERANCE,
|
|
93754
|
+
maxX: bounds.maxX - TRACE_BOUNDARY_TOLERANCE,
|
|
93755
|
+
maxY: bounds.maxY - TRACE_BOUNDARY_TOLERANCE
|
|
93756
|
+
};
|
|
93757
|
+
if (interiorBounds.minX >= interiorBounds.maxX || interiorBounds.minY >= interiorBounds.maxY) {
|
|
93758
|
+
return false;
|
|
93759
|
+
}
|
|
93760
|
+
if (sameX(p1, p2)) {
|
|
93761
|
+
if (p1.x <= interiorBounds.minX + EPS8 || p1.x >= interiorBounds.maxX - EPS8) {
|
|
93762
|
+
return false;
|
|
93763
|
+
}
|
|
93764
|
+
return rangesOverlap(
|
|
93765
|
+
Math.min(p1.y, p2.y),
|
|
93766
|
+
Math.max(p1.y, p2.y),
|
|
93767
|
+
interiorBounds.minY,
|
|
93768
|
+
interiorBounds.maxY
|
|
93769
|
+
);
|
|
93770
|
+
}
|
|
93771
|
+
if (sameY(p1, p2)) {
|
|
93772
|
+
if (p1.y <= interiorBounds.minY + EPS8 || p1.y >= interiorBounds.maxY - EPS8) {
|
|
93773
|
+
return false;
|
|
93774
|
+
}
|
|
93775
|
+
return rangesOverlap(
|
|
93776
|
+
Math.min(p1.x, p2.x),
|
|
93777
|
+
Math.max(p1.x, p2.x),
|
|
93778
|
+
interiorBounds.minX,
|
|
93779
|
+
interiorBounds.maxX
|
|
93780
|
+
);
|
|
93781
|
+
}
|
|
93782
|
+
return false;
|
|
93783
|
+
};
|
|
93784
|
+
var tracePathCrossesAnyBounds = (tracePath, bounds) => {
|
|
93785
|
+
for (let i2 = 0; i2 < tracePath.length - 1; i2++) {
|
|
93786
|
+
if (segmentCrossesBoundsInterior(tracePath[i2], tracePath[i2 + 1], bounds)) {
|
|
93787
|
+
return true;
|
|
93788
|
+
}
|
|
93789
|
+
}
|
|
93790
|
+
return false;
|
|
93791
|
+
};
|
|
93792
|
+
var tracePathIntersectsBounds = (tracePath, bounds) => {
|
|
93793
|
+
for (let i2 = 0; i2 < tracePath.length - 1; i2++) {
|
|
93794
|
+
if (segmentIntersectsRect2(tracePath[i2], tracePath[i2 + 1], bounds)) {
|
|
93795
|
+
return true;
|
|
93796
|
+
}
|
|
93797
|
+
}
|
|
93798
|
+
return false;
|
|
93799
|
+
};
|
|
93800
|
+
var getSideDistances = (point6, bounds) => [
|
|
93801
|
+
["left", Math.abs(point6.x - bounds.minX)],
|
|
93802
|
+
["right", Math.abs(point6.x - bounds.maxX)],
|
|
93803
|
+
["bottom", Math.abs(point6.y - bounds.minY)],
|
|
93804
|
+
["top", Math.abs(point6.y - bounds.maxY)]
|
|
93805
|
+
];
|
|
93806
|
+
var getConnectorTracePath = (source, target, orientation2) => simplifyOrthogonalPath(
|
|
93807
|
+
isYOrientation(orientation2) ? [source, { x: target.x, y: source.y }, target] : [source, { x: source.x, y: target.y }, target]
|
|
93808
|
+
);
|
|
93809
|
+
var simplifyOrthogonalPath = (path) => {
|
|
93810
|
+
const deduped = path.filter(
|
|
93811
|
+
(point6, index2) => index2 === 0 || !pointsEqual3(point6, path[index2 - 1])
|
|
93812
|
+
);
|
|
93813
|
+
if (deduped.length < 3) return deduped;
|
|
93814
|
+
const simplified = [deduped[0]];
|
|
93815
|
+
for (let i2 = 1; i2 < deduped.length - 1; i2++) {
|
|
93816
|
+
const prev = simplified[simplified.length - 1];
|
|
93817
|
+
const point6 = deduped[i2];
|
|
93818
|
+
const next = deduped[i2 + 1];
|
|
93819
|
+
if (sameX(prev, point6) && sameX(point6, next) || sameY(prev, point6) && sameY(point6, next)) {
|
|
93820
|
+
continue;
|
|
93821
|
+
}
|
|
93822
|
+
simplified.push(point6);
|
|
93823
|
+
}
|
|
93824
|
+
simplified.push(deduped[deduped.length - 1]);
|
|
93825
|
+
return simplified;
|
|
93826
|
+
};
|
|
93827
|
+
var pointsEqual3 = (a2, b2) => sameX(a2, b2) && sameY(a2, b2);
|
|
93828
|
+
var sameX = (a2, b2) => Math.abs(a2.x - b2.x) <= EPS8;
|
|
93829
|
+
var sameY = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS8;
|
|
93830
|
+
var getMaxSearchDistance = (inputProblem) => {
|
|
93831
|
+
const maxChipWidth = Math.max(
|
|
93832
|
+
...inputProblem.chips.map((chip) => chip.width),
|
|
93833
|
+
1
|
|
93834
|
+
);
|
|
93835
|
+
return maxChipWidth * 3;
|
|
93836
|
+
};
|
|
93837
|
+
var EPS9 = 1e-6;
|
|
93838
|
+
var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
|
|
93839
|
+
var rectsOverlap2 = (a2, b2) => Math.min(a2.maxX, b2.maxX) - Math.max(a2.minX, b2.minX) > EPS9 && Math.min(a2.maxY, b2.maxY) - Math.max(a2.minY, b2.minY) > EPS9;
|
|
93840
|
+
var getTraceCorners = (path) => {
|
|
93841
|
+
const corners = [];
|
|
93842
|
+
for (let i2 = 1; i2 < path.length - 1; i2++) {
|
|
93843
|
+
const previousPoint = path[i2 - 1];
|
|
93844
|
+
const cornerPoint = path[i2];
|
|
93845
|
+
const nextPoint = path[i2 + 1];
|
|
93846
|
+
if (isTraceCorner(previousPoint, cornerPoint, nextPoint)) {
|
|
93847
|
+
corners.push(cornerPoint);
|
|
93848
|
+
}
|
|
93849
|
+
}
|
|
93850
|
+
return corners;
|
|
93851
|
+
};
|
|
93852
|
+
var tracePathContainsPoint = (path, point6) => {
|
|
93853
|
+
for (let i2 = 0; i2 < path.length - 1; i2++) {
|
|
93854
|
+
if (isPointOnSegment(point6, path[i2], path[i2 + 1])) return true;
|
|
93855
|
+
}
|
|
93856
|
+
return false;
|
|
93857
|
+
};
|
|
93858
|
+
var getDistance2 = (a2, b2) => Math.abs(a2.x - b2.x) + Math.abs(a2.y - b2.y);
|
|
93859
|
+
var getUniquePinCount = (pinIds) => new Set(pinIds).size;
|
|
93860
|
+
var isTraceCorner = (a2, b2, c2) => getSegmentOrientation(a2, b2) !== getSegmentOrientation(b2, c2);
|
|
93861
|
+
var isPointOnSegment = (point6, start, end) => {
|
|
93862
|
+
if (getSegmentOrientation(start, end) === "horizontal") {
|
|
93863
|
+
return Math.abs(point6.y - start.y) <= EPS9 && point6.x >= Math.min(start.x, end.x) - EPS9 && point6.x <= Math.max(start.x, end.x) + EPS9;
|
|
93864
|
+
}
|
|
93865
|
+
return Math.abs(point6.x - start.x) <= EPS9 && point6.y >= Math.min(start.y, end.y) - EPS9 && point6.y <= Math.max(start.y, end.y) + EPS9;
|
|
93866
|
+
};
|
|
93867
|
+
var getSegmentOrientation = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS9 ? "horizontal" : "vertical";
|
|
93868
|
+
var getGroundNetIds = (inputProblem, netConnMap) => {
|
|
93869
|
+
const groundNetIds = /* @__PURE__ */ new Set();
|
|
93870
|
+
for (const connection of inputProblem.netConnections) {
|
|
93871
|
+
if (!connection.isGround) continue;
|
|
93872
|
+
const netId = netConnMap.getNetConnectedToId(connection.netId);
|
|
93873
|
+
if (netId) groundNetIds.add(netId);
|
|
93874
|
+
}
|
|
93875
|
+
return groundNetIds;
|
|
93876
|
+
};
|
|
93877
|
+
var placeGroundRailLabelsAtOuterEnd = ({
|
|
93878
|
+
inputProblem,
|
|
93879
|
+
traces,
|
|
93880
|
+
netLabelPlacements
|
|
93881
|
+
}) => {
|
|
93882
|
+
const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem);
|
|
93883
|
+
const groundNetIds = getGroundNetIds(inputProblem, netConnMap);
|
|
93884
|
+
if (groundNetIds.size === 0) return netLabelPlacements;
|
|
93885
|
+
const chipMap = new Map(inputProblem.chips.map((chip) => [chip.chipId, chip]));
|
|
93886
|
+
const traceMap = Object.fromEntries(
|
|
93887
|
+
traces.map((trace) => [trace.mspPairId, trace])
|
|
93888
|
+
);
|
|
93889
|
+
const obstacles = getObstacleRects(inputProblem);
|
|
93890
|
+
const output = [...netLabelPlacements];
|
|
93891
|
+
for (const rail of traces) {
|
|
93892
|
+
if (!groundNetIds.has(rail.globalConnNetId)) continue;
|
|
93893
|
+
const [a2, b2] = rail.pins;
|
|
93894
|
+
if (a2.chipId === b2.chipId || !nearlyEqual(a2.y, b2.y) || ![a2, b2].every(
|
|
93895
|
+
(pin) => pin._facingDirection === "y-" && chipMap.get(pin.chipId)?.pins.length === 2
|
|
93896
|
+
))
|
|
93897
|
+
continue;
|
|
93898
|
+
const path = simplifyPath(rail.tracePath);
|
|
93899
|
+
if (path.length !== 4 || !isVertical2(path[0], path[1]) || !isHorizontal22(path[1], path[2]) || !isVertical2(path[2], path[3]) || path[1].y >= a2.y)
|
|
93900
|
+
continue;
|
|
93901
|
+
for (const feed of traces) {
|
|
93902
|
+
if (feed.globalConnNetId !== rail.globalConnNetId) continue;
|
|
93903
|
+
const shared = feed.pins.find((pin) => rail.pinIds.includes(pin.pinId));
|
|
93904
|
+
const icPin = feed.pins.find(
|
|
93905
|
+
(pin) => !rail.pinIds.includes(pin.pinId) && (chipMap.get(pin.chipId)?.pins.length ?? 0) > 2
|
|
93906
|
+
);
|
|
93907
|
+
if (!shared || !icPin || !nearlyEqual(icPin.y, path[1].y)) continue;
|
|
93908
|
+
const outer = shared.pinId === a2.pinId ? b2 : a2;
|
|
93909
|
+
if (Math.abs(outer.x - icPin.x) <= Math.abs(shared.x - icPin.x)) continue;
|
|
93910
|
+
const anchorPoint = { x: outer.x, y: path[1].y };
|
|
93911
|
+
if (!tracePathContainsPoint(rail.tracePath, anchorPoint)) continue;
|
|
93912
|
+
for (let index2 = 0; index2 < output.length; index2++) {
|
|
93913
|
+
const label = output[index2];
|
|
93914
|
+
if (label.globalConnNetId !== rail.globalConnNetId || label.orientation !== "y-" || !label.mspConnectionPairIds.some(
|
|
93915
|
+
(id) => id === feed.mspPairId || id === rail.mspPairId
|
|
93916
|
+
) || !tracePathContainsPoint(feed.tracePath, label.anchorPoint) && !tracePathContainsPoint(rail.tracePath, label.anchorPoint))
|
|
93917
|
+
continue;
|
|
93918
|
+
const center = getCenterFromAnchor(
|
|
93919
|
+
anchorPoint,
|
|
93920
|
+
label.orientation,
|
|
93921
|
+
label.width,
|
|
93922
|
+
label.height
|
|
93923
|
+
);
|
|
93924
|
+
const bounds = getRectBounds(center, label.width, label.height);
|
|
93925
|
+
if (obstacles.some((obstacle) => rectsOverlap2(bounds, obstacle)) || traceCrossesBoundsInterior(bounds, traceMap) || output.some(
|
|
93926
|
+
(other, otherIndex) => otherIndex !== index2 && rectsOverlap2(
|
|
93927
|
+
bounds,
|
|
93928
|
+
getRectBounds(other.center, other.width, other.height)
|
|
93929
|
+
)
|
|
93930
|
+
))
|
|
93931
|
+
continue;
|
|
93932
|
+
output[index2] = {
|
|
93933
|
+
...label,
|
|
93934
|
+
anchorPoint,
|
|
93935
|
+
center,
|
|
93936
|
+
mspConnectionPairIds: [rail.mspPairId],
|
|
93937
|
+
pinIds: [...rail.pinIds]
|
|
93938
|
+
};
|
|
93939
|
+
}
|
|
93940
|
+
}
|
|
93941
|
+
}
|
|
93942
|
+
for (let index2 = 0; index2 < output.length; index2++) {
|
|
93943
|
+
const label = output[index2];
|
|
93944
|
+
if (label.orientation !== "y-" || !groundNetIds.has(label.globalConnNetId))
|
|
93945
|
+
continue;
|
|
93946
|
+
const hasSharedRail = inputProblem.netConnections.some(
|
|
93947
|
+
(candidate) => candidate.pinIds.length > 2 && netConnMap.getNetConnectedToId(candidate.netId) === label.globalConnNetId
|
|
93948
|
+
);
|
|
93949
|
+
if (!hasSharedRail) continue;
|
|
93950
|
+
const columnSegments = traces.filter((trace) => trace.globalConnNetId === label.globalConnNetId).flatMap(
|
|
93951
|
+
(trace) => trace.tracePath.slice(1).flatMap((end, pointIndex) => {
|
|
93952
|
+
const start = trace.tracePath[pointIndex];
|
|
93953
|
+
return nearlyEqual(start.x, label.anchorPoint.x) && nearlyEqual(end.x, label.anchorPoint.x) ? [
|
|
93954
|
+
{
|
|
93955
|
+
minY: Math.min(start.y, end.y),
|
|
93956
|
+
maxY: Math.max(start.y, end.y)
|
|
93957
|
+
}
|
|
93958
|
+
] : [];
|
|
93959
|
+
})
|
|
93960
|
+
).sort((a2, b2) => b2.maxY - a2.maxY);
|
|
93961
|
+
let lowestY = label.anchorPoint.y;
|
|
93962
|
+
for (const segment2 of columnSegments) {
|
|
93963
|
+
if (segment2.maxY + RAIL_ALIGNMENT_EPSILON >= lowestY && segment2.minY < lowestY) {
|
|
93964
|
+
lowestY = segment2.minY;
|
|
93965
|
+
}
|
|
93966
|
+
}
|
|
93967
|
+
if (nearlyEqual(lowestY, label.anchorPoint.y)) continue;
|
|
93968
|
+
const anchorPoint = { x: label.anchorPoint.x, y: lowestY };
|
|
93969
|
+
const center = getCenterFromAnchor(
|
|
93970
|
+
anchorPoint,
|
|
93971
|
+
label.orientation,
|
|
93972
|
+
label.width,
|
|
93973
|
+
label.height
|
|
93974
|
+
);
|
|
93975
|
+
const bounds = getRectBounds(center, label.width, label.height);
|
|
93976
|
+
if (obstacles.some((obstacle) => rectsOverlap2(bounds, obstacle)) || traceCrossesBoundsInterior(bounds, traceMap) || output.some(
|
|
93977
|
+
(other, otherIndex) => otherIndex !== index2 && rectsOverlap2(
|
|
93978
|
+
bounds,
|
|
93979
|
+
getRectBounds(other.center, other.width, other.height)
|
|
93980
|
+
)
|
|
93981
|
+
))
|
|
93982
|
+
continue;
|
|
93983
|
+
output[index2] = { ...label, anchorPoint, center };
|
|
93984
|
+
}
|
|
93985
|
+
return output;
|
|
93986
|
+
};
|
|
93727
93987
|
var getAlongBounds = (orientation2, minAlong, maxAlong) => orientation2 === "vertical" ? { minX: 0, maxX: 0, minY: minAlong, maxY: maxAlong } : { minX: minAlong, maxX: maxAlong, minY: 0, maxY: 0 };
|
|
93728
93988
|
var hasPositiveAlongOverlap = (orientation2, first, second) => {
|
|
93729
93989
|
const overlap = boundsIntersection(first, second);
|
|
@@ -93768,37 +94028,6 @@ var getRailAlignmentFallbackCoordinates = ({
|
|
|
93768
94028
|
}
|
|
93769
94029
|
return getDistinctCoordinates(coordinates);
|
|
93770
94030
|
};
|
|
93771
|
-
var EPS8 = 1e-6;
|
|
93772
|
-
var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
|
|
93773
|
-
var rectsOverlap = (a2, b2) => Math.min(a2.maxX, b2.maxX) - Math.max(a2.minX, b2.minX) > EPS8 && Math.min(a2.maxY, b2.maxY) - Math.max(a2.minY, b2.minY) > EPS8;
|
|
93774
|
-
var getTraceCorners = (path) => {
|
|
93775
|
-
const corners = [];
|
|
93776
|
-
for (let i2 = 1; i2 < path.length - 1; i2++) {
|
|
93777
|
-
const previousPoint = path[i2 - 1];
|
|
93778
|
-
const cornerPoint = path[i2];
|
|
93779
|
-
const nextPoint = path[i2 + 1];
|
|
93780
|
-
if (isTraceCorner(previousPoint, cornerPoint, nextPoint)) {
|
|
93781
|
-
corners.push(cornerPoint);
|
|
93782
|
-
}
|
|
93783
|
-
}
|
|
93784
|
-
return corners;
|
|
93785
|
-
};
|
|
93786
|
-
var tracePathContainsPoint = (path, point6) => {
|
|
93787
|
-
for (let i2 = 0; i2 < path.length - 1; i2++) {
|
|
93788
|
-
if (isPointOnSegment(point6, path[i2], path[i2 + 1])) return true;
|
|
93789
|
-
}
|
|
93790
|
-
return false;
|
|
93791
|
-
};
|
|
93792
|
-
var getDistance2 = (a2, b2) => Math.abs(a2.x - b2.x) + Math.abs(a2.y - b2.y);
|
|
93793
|
-
var getUniquePinCount = (pinIds) => new Set(pinIds).size;
|
|
93794
|
-
var isTraceCorner = (a2, b2, c2) => getSegmentOrientation(a2, b2) !== getSegmentOrientation(b2, c2);
|
|
93795
|
-
var isPointOnSegment = (point6, start, end) => {
|
|
93796
|
-
if (getSegmentOrientation(start, end) === "horizontal") {
|
|
93797
|
-
return Math.abs(point6.y - start.y) <= EPS8 && point6.x >= Math.min(start.x, end.x) - EPS8 && point6.x <= Math.max(start.x, end.x) + EPS8;
|
|
93798
|
-
}
|
|
93799
|
-
return Math.abs(point6.x - start.x) <= EPS8 && point6.y >= Math.min(start.y, end.y) - EPS8 && point6.y <= Math.max(start.y, end.y) + EPS8;
|
|
93800
|
-
};
|
|
93801
|
-
var getSegmentOrientation = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS8 ? "horizontal" : "vertical";
|
|
93802
94031
|
var hasLabelOnAdjacentInteriorLeg = (segment2, trace, anchorPoint) => {
|
|
93803
94032
|
const pathsFromRailEnds = [
|
|
93804
94033
|
trace.tracePath.slice(0, segment2.segmentIndex + 1).reverse(),
|
|
@@ -93937,15 +94166,15 @@ var preservesLabelAnchors = (labels, before, after) => labels.every((label) => {
|
|
|
93937
94166
|
const anchoredAfter = getAnchoredTraceIds(label, after);
|
|
93938
94167
|
return [...anchoredBefore].every((traceId) => anchoredAfter.has(traceId));
|
|
93939
94168
|
});
|
|
93940
|
-
var
|
|
94169
|
+
var EPS10 = 1e-9;
|
|
93941
94170
|
var segmentRunsAlongRectBoundary = (start, end, rect) => {
|
|
93942
|
-
const isVertical6 = Math.abs(start.x - end.x) <
|
|
93943
|
-
const isHorizontal5 = Math.abs(start.y - end.y) <
|
|
94171
|
+
const isVertical6 = Math.abs(start.x - end.x) < EPS10;
|
|
94172
|
+
const isHorizontal5 = Math.abs(start.y - end.y) < EPS10;
|
|
93944
94173
|
if (isVertical6) {
|
|
93945
|
-
return Math.abs(start.x - rect.minX) <
|
|
94174
|
+
return Math.abs(start.x - rect.minX) < EPS10 || Math.abs(start.x - rect.maxX) < EPS10;
|
|
93946
94175
|
}
|
|
93947
94176
|
if (isHorizontal5) {
|
|
93948
|
-
return Math.abs(start.y - rect.minY) <
|
|
94177
|
+
return Math.abs(start.y - rect.minY) < EPS10 || Math.abs(start.y - rect.maxY) < EPS10;
|
|
93949
94178
|
}
|
|
93950
94179
|
return false;
|
|
93951
94180
|
};
|
|
@@ -93958,10 +94187,10 @@ var getPathLength4 = (path) => {
|
|
|
93958
94187
|
return length8;
|
|
93959
94188
|
};
|
|
93960
94189
|
var getDistance22 = (a2, b2) => Math.abs(a2.x - b2.x) + Math.abs(a2.y - b2.y);
|
|
93961
|
-
var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) <
|
|
93962
|
-
var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) <
|
|
94190
|
+
var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS10 || Math.abs(start.y - end.y) < EPS10;
|
|
94191
|
+
var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) < EPS10 ? "horizontal" : "vertical";
|
|
93963
94192
|
var projectPointToSegment = (point6, start, end) => {
|
|
93964
|
-
if (Math.abs(start.x - end.x) <
|
|
94193
|
+
if (Math.abs(start.x - end.x) < EPS10) {
|
|
93965
94194
|
return {
|
|
93966
94195
|
x: start.x,
|
|
93967
94196
|
y: Math.min(
|
|
@@ -93970,7 +94199,7 @@ var projectPointToSegment = (point6, start, end) => {
|
|
|
93970
94199
|
)
|
|
93971
94200
|
};
|
|
93972
94201
|
}
|
|
93973
|
-
if (Math.abs(start.y - end.y) <
|
|
94202
|
+
if (Math.abs(start.y - end.y) < EPS10) {
|
|
93974
94203
|
return {
|
|
93975
94204
|
x: Math.min(
|
|
93976
94205
|
Math.max(point6.x, Math.min(start.x, end.x)),
|
|
@@ -94013,9 +94242,9 @@ var findSegmentContainingPoint = (path, point6) => {
|
|
|
94013
94242
|
};
|
|
94014
94243
|
var isPointWithinSegmentPrimaryRange = (point6, segment2) => {
|
|
94015
94244
|
if (segment2.orientation === "horizontal") {
|
|
94016
|
-
return point6.x >= Math.min(segment2.start.x, segment2.end.x) -
|
|
94245
|
+
return point6.x >= Math.min(segment2.start.x, segment2.end.x) - EPS10 && point6.x <= Math.max(segment2.start.x, segment2.end.x) + EPS10;
|
|
94017
94246
|
}
|
|
94018
|
-
return point6.y >= Math.min(segment2.start.y, segment2.end.y) -
|
|
94247
|
+
return point6.y >= Math.min(segment2.start.y, segment2.end.y) - EPS10 && point6.y <= Math.max(segment2.start.y, segment2.end.y) + EPS10;
|
|
94019
94248
|
};
|
|
94020
94249
|
var findPreferredReroutedSegment = (path, originalSegmentIndex, originalSegmentCount, orientation2, anchorPoint) => {
|
|
94021
94250
|
const matchingSegments = getSegments3(path).filter(
|
|
@@ -94043,18 +94272,18 @@ var projectPointToPath = (point6, path) => {
|
|
|
94043
94272
|
return bestPoint;
|
|
94044
94273
|
};
|
|
94045
94274
|
var segmentsIntersect2 = (a1, a2, b1, b2) => {
|
|
94046
|
-
const aVertical = Math.abs(a1.x - a2.x) <
|
|
94047
|
-
const bVertical = Math.abs(b1.x - b2.x) <
|
|
94048
|
-
const between2 = (value, p1, p2) => value >= Math.min(p1, p2) -
|
|
94275
|
+
const aVertical = Math.abs(a1.x - a2.x) < EPS10;
|
|
94276
|
+
const bVertical = Math.abs(b1.x - b2.x) < EPS10;
|
|
94277
|
+
const between2 = (value, p1, p2) => value >= Math.min(p1, p2) - EPS10 && value <= Math.max(p1, p2) + EPS10;
|
|
94049
94278
|
if (aVertical && bVertical) {
|
|
94050
|
-
if (Math.abs(a1.x - b1.x) >
|
|
94279
|
+
if (Math.abs(a1.x - b1.x) > EPS10) return false;
|
|
94051
94280
|
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));
|
|
94052
|
-
return overlap >
|
|
94281
|
+
return overlap > EPS10;
|
|
94053
94282
|
}
|
|
94054
94283
|
if (!aVertical && !bVertical) {
|
|
94055
|
-
if (Math.abs(a1.y - b1.y) >
|
|
94284
|
+
if (Math.abs(a1.y - b1.y) > EPS10) return false;
|
|
94056
94285
|
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));
|
|
94057
|
-
return overlap >
|
|
94286
|
+
return overlap > EPS10;
|
|
94058
94287
|
}
|
|
94059
94288
|
const verticalA = aVertical ? a1 : b1;
|
|
94060
94289
|
const verticalB = aVertical ? a2 : b2;
|
|
@@ -94125,6 +94354,7 @@ var tracePathChanged = (original, candidate) => original.tracePath.length !== ca
|
|
|
94125
94354
|
(point6, index2) => !pointsEqual22(point6, original.tracePath[index2])
|
|
94126
94355
|
);
|
|
94127
94356
|
var evaluateRailGroup = ({
|
|
94357
|
+
inputProblem,
|
|
94128
94358
|
group,
|
|
94129
94359
|
traces,
|
|
94130
94360
|
netLabelPlacements,
|
|
@@ -94147,6 +94377,11 @@ var evaluateRailGroup = ({
|
|
|
94147
94377
|
const otherNetTraces = traces.filter(
|
|
94148
94378
|
(trace) => trace.globalConnNetId !== group[0].globalConnNetId
|
|
94149
94379
|
);
|
|
94380
|
+
const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem);
|
|
94381
|
+
const groundNetIds = getGroundNetIds(inputProblem, netConnMap);
|
|
94382
|
+
const groundLabelIndices = netLabelPlacements.flatMap(
|
|
94383
|
+
(label, index2) => label.globalConnNetId === group[0].globalConnNetId && groundNetIds.has(label.globalConnNetId) ? [index2] : []
|
|
94384
|
+
);
|
|
94150
94385
|
const immutableSameNetTraces = traces.filter(
|
|
94151
94386
|
(trace) => trace.globalConnNetId === group[0].globalConnNetId && !eligibleTraceIds.has(trace.mspPairId)
|
|
94152
94387
|
);
|
|
@@ -94166,11 +94401,24 @@ var evaluateRailGroup = ({
|
|
|
94166
94401
|
const allCandidateTraces = traces.map(
|
|
94167
94402
|
(trace) => candidateMap.get(trace.mspPairId) ?? trace
|
|
94168
94403
|
);
|
|
94404
|
+
const placedGroundLabels = groundLabelIndices.length ? placeGroundRailLabelsAtOuterEnd({
|
|
94405
|
+
inputProblem,
|
|
94406
|
+
traces: allCandidateTraces,
|
|
94407
|
+
netLabelPlacements
|
|
94408
|
+
}) : netLabelPlacements;
|
|
94409
|
+
const groundLabelBounds = groundLabelIndices.map((index2) => {
|
|
94410
|
+
const label = placedGroundLabels[index2];
|
|
94411
|
+
return getRectBounds(label.center, label.width, label.height);
|
|
94412
|
+
});
|
|
94169
94413
|
const candidatesAreClear = candidateTraces.every(
|
|
94170
94414
|
(candidate2) => !isPathCollidingWithObstacles(candidate2.tracePath, obstacles) && detectTraceLabelOverlap({
|
|
94171
94415
|
traces: [candidate2],
|
|
94172
94416
|
netLabels: netLabelPlacements
|
|
94173
|
-
}).length === 0 &&
|
|
94417
|
+
}).length === 0 && // Ground labels may move to the new rail end later in the pipeline.
|
|
94418
|
+
// Reject alignment if even that placement leaves a symbol crossed.
|
|
94419
|
+
!groundLabelBounds.some(
|
|
94420
|
+
(bounds) => tracePathCrossesAnyBounds(candidate2.tracePath, bounds)
|
|
94421
|
+
) && !doesPathOverlapTraceStrokes(candidate2.tracePath, otherNetTraces) && !doesPathCoincideWithTraces(
|
|
94174
94422
|
candidate2.tracePath,
|
|
94175
94423
|
immutableSameNetTraces.filter(
|
|
94176
94424
|
(trace) => trace.mspPairId !== candidate2.mspPairId
|
|
@@ -94439,6 +94687,7 @@ var alignSameNetRails = ({
|
|
|
94439
94687
|
let applied = null;
|
|
94440
94688
|
for (const group of groups) {
|
|
94441
94689
|
applied = evaluateRailGroup({
|
|
94690
|
+
inputProblem,
|
|
94442
94691
|
group,
|
|
94443
94692
|
traces: outputTraces,
|
|
94444
94693
|
netLabelPlacements,
|
|
@@ -94493,7 +94742,7 @@ var getTraceObstacles = (allTraces, excludeTraceId) => {
|
|
|
94493
94742
|
}
|
|
94494
94743
|
return obstacles;
|
|
94495
94744
|
};
|
|
94496
|
-
var
|
|
94745
|
+
var EPS11 = 1e-6;
|
|
94497
94746
|
var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
|
|
94498
94747
|
const intersections2 = [];
|
|
94499
94748
|
for (const obstacle of obstacles) {
|
|
@@ -94512,7 +94761,7 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
|
|
|
94512
94761
|
}
|
|
94513
94762
|
return intersections2;
|
|
94514
94763
|
};
|
|
94515
|
-
var isSamePoint = (first, second) => Math.abs(first.x - second.x) <
|
|
94764
|
+
var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS11 && Math.abs(first.y - second.y) < EPS11;
|
|
94516
94765
|
var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
|
|
94517
94766
|
const crossings = [];
|
|
94518
94767
|
const firstPathSegmentIndex = options.includeTerminalSegments ? 0 : 1;
|
|
@@ -94522,11 +94771,11 @@ var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
|
|
|
94522
94771
|
for (let pathSegmentIndex = firstPathSegmentIndex; pathSegmentIndex < lastPathSegmentIndex; pathSegmentIndex++) {
|
|
94523
94772
|
const start = path[pathSegmentIndex];
|
|
94524
94773
|
const end = path[pathSegmentIndex + 1];
|
|
94525
|
-
const isVertical6 = Math.abs(start.x - end.x) <
|
|
94774
|
+
const isVertical6 = Math.abs(start.x - end.x) < EPS11;
|
|
94526
94775
|
for (let otherPathSegmentIndex = firstOtherPathSegmentIndex; otherPathSegmentIndex < lastOtherPathSegmentIndex; otherPathSegmentIndex++) {
|
|
94527
94776
|
const otherStart = otherPath[otherPathSegmentIndex];
|
|
94528
94777
|
const otherEnd = otherPath[otherPathSegmentIndex + 1];
|
|
94529
|
-
const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) <
|
|
94778
|
+
const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS11;
|
|
94530
94779
|
if (isVertical6 === otherIsVertical) continue;
|
|
94531
94780
|
const intersection2 = getSegmentIntersection(
|
|
94532
94781
|
start,
|
|
@@ -94544,8 +94793,8 @@ var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
|
|
|
94544
94793
|
}
|
|
94545
94794
|
return crossings;
|
|
94546
94795
|
};
|
|
94547
|
-
var
|
|
94548
|
-
var isVertical3 = (a2, b2, eps =
|
|
94796
|
+
var EPS12 = 1e-6;
|
|
94797
|
+
var isVertical3 = (a2, b2, eps = EPS12) => Math.abs(a2.x - b2.x) < eps;
|
|
94549
94798
|
var generateLShapeRerouteCandidates = ({
|
|
94550
94799
|
lShape,
|
|
94551
94800
|
rectangle,
|
|
@@ -94558,7 +94807,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
94558
94807
|
let c2;
|
|
94559
94808
|
let i1_padded = interactionPoint1;
|
|
94560
94809
|
let i2_padded = interactionPoint2;
|
|
94561
|
-
if (Math.abs(p2.x - x2) <
|
|
94810
|
+
if (Math.abs(p2.x - x2) < EPS12 && Math.abs(p2.y - (y2 + height)) < EPS12) {
|
|
94562
94811
|
c2 = { x: x2 + width + padding, y: y2 - padding };
|
|
94563
94812
|
if (isVertical3(p1, p2)) {
|
|
94564
94813
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
|
|
@@ -94570,7 +94819,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
94570
94819
|
} else {
|
|
94571
94820
|
i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
|
|
94572
94821
|
}
|
|
94573
|
-
} else if (Math.abs(p2.x - (x2 + width)) <
|
|
94822
|
+
} else if (Math.abs(p2.x - (x2 + width)) < EPS12 && Math.abs(p2.y - (y2 + height)) < EPS12) {
|
|
94574
94823
|
c2 = { x: x2 - padding, y: y2 - padding };
|
|
94575
94824
|
if (isVertical3(p1, p2)) {
|
|
94576
94825
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
|
|
@@ -94582,7 +94831,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
94582
94831
|
} else {
|
|
94583
94832
|
i2_padded = { x: interactionPoint2.x - padding, y: interactionPoint2.y };
|
|
94584
94833
|
}
|
|
94585
|
-
} else if (Math.abs(p2.x - x2) <
|
|
94834
|
+
} else if (Math.abs(p2.x - x2) < EPS12 && Math.abs(p2.y - y2) < EPS12) {
|
|
94586
94835
|
c2 = { x: x2 + width + padding, y: y2 + height + padding };
|
|
94587
94836
|
if (isVertical3(p1, p2)) {
|
|
94588
94837
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
|
|
@@ -94594,7 +94843,7 @@ var generateLShapeRerouteCandidates = ({
|
|
|
94594
94843
|
} else {
|
|
94595
94844
|
i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
|
|
94596
94845
|
}
|
|
94597
|
-
} else if (Math.abs(p2.x - (x2 + width)) <
|
|
94846
|
+
} else if (Math.abs(p2.x - (x2 + width)) < EPS12 && Math.abs(p2.y - y2) < EPS12) {
|
|
94598
94847
|
c2 = { x: x2 - padding, y: y2 + height + padding };
|
|
94599
94848
|
if (isVertical3(p1, p2)) {
|
|
94600
94849
|
i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
|
|
@@ -94668,7 +94917,7 @@ var generatePerpendicularTraceDetours = ({
|
|
|
94668
94917
|
const buildDetours = (path, index2) => {
|
|
94669
94918
|
const start = path[index2];
|
|
94670
94919
|
const end = path[index2 + 1];
|
|
94671
|
-
const movingAxis = Math.abs(start.x - end.x) <
|
|
94920
|
+
const movingAxis = Math.abs(start.x - end.x) < EPS12 ? "y" : "x";
|
|
94672
94921
|
const detourAxis = movingAxis === "x" ? "y" : "x";
|
|
94673
94922
|
const bounds = obstacleBounds ?? {
|
|
94674
94923
|
minX: Math.min(obstacleStart.x, obstacleEnd.x),
|
|
@@ -95274,14 +95523,14 @@ var UntangleTraceSubsolver = class extends BaseSolver10 {
|
|
|
95274
95523
|
}
|
|
95275
95524
|
}
|
|
95276
95525
|
};
|
|
95277
|
-
var
|
|
95278
|
-
var
|
|
95279
|
-
var
|
|
95526
|
+
var EPS13 = 1e-6;
|
|
95527
|
+
var sameX2 = (a2, b2) => Math.abs(a2.x - b2.x) <= EPS13;
|
|
95528
|
+
var sameY2 = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS13;
|
|
95280
95529
|
var is4PointRectangle = (path) => {
|
|
95281
95530
|
if (path.length !== 4) return false;
|
|
95282
95531
|
const [p0, p1, p2, p3] = path;
|
|
95283
|
-
const isHVHC =
|
|
95284
|
-
const isVHVC =
|
|
95532
|
+
const isHVHC = sameY2(p0, p1) && sameX2(p1, p2) && sameY2(p2, p3) && sameX2(p0, p3);
|
|
95533
|
+
const isVHVC = sameX2(p0, p1) && sameY2(p1, p2) && sameX2(p2, p3) && sameY2(p0, p3);
|
|
95285
95534
|
return isHVHC || isVHVC;
|
|
95286
95535
|
};
|
|
95287
95536
|
var getInteriorShortcutPaths = (path) => {
|
|
@@ -95312,7 +95561,7 @@ var getInteriorShortcutPaths = (path) => {
|
|
|
95312
95561
|
}
|
|
95313
95562
|
return candidates;
|
|
95314
95563
|
};
|
|
95315
|
-
var
|
|
95564
|
+
var EPS14 = 1e-6;
|
|
95316
95565
|
var getConnectorObstacleBounds = (connector, segmentIndex, labels) => {
|
|
95317
95566
|
const start = connector.tracePath[segmentIndex];
|
|
95318
95567
|
const end = connector.tracePath[segmentIndex + 1];
|
|
@@ -95409,7 +95658,7 @@ var rerouteGeneratedNetLabelConnectorCrossings = ({
|
|
|
95409
95658
|
path
|
|
95410
95659
|
}))
|
|
95411
95660
|
).filter(
|
|
95412
|
-
(candidate) => getPathLength4(candidate.path) <= getPathLength4(trace.tracePath) +
|
|
95661
|
+
(candidate) => getPathLength4(candidate.path) <= getPathLength4(trace.tracePath) + EPS14 && countTurns(candidate.path) <= countTurns(trace.tracePath) + 2 && !isPathCollidingWithObstacles(
|
|
95413
95662
|
candidate.path,
|
|
95414
95663
|
componentAndTextObstacles
|
|
95415
95664
|
) && !hasCollisionsWithLabels(candidate.path, foreignLabelBounds) && !isPathColliding(candidate.path, foreignTraces, trace.mspPairId).isColliding && !doesPathCoincideWithTraces(candidate.path, foreignTraces)
|
|
@@ -95420,7 +95669,7 @@ var rerouteGeneratedNetLabelConnectorCrossings = ({
|
|
|
95420
95669
|
});
|
|
95421
95670
|
candidates.sort((first, second) => {
|
|
95422
95671
|
const lengthDifference = getPathLength4(first.path) - getPathLength4(second.path);
|
|
95423
|
-
return Math.abs(lengthDifference) >
|
|
95672
|
+
return Math.abs(lengthDifference) > EPS14 ? lengthDifference : countTurns(first.path) - countTurns(second.path);
|
|
95424
95673
|
});
|
|
95425
95674
|
const bestCandidate = candidates[0];
|
|
95426
95675
|
if (!bestCandidate) break;
|
|
@@ -95788,7 +96037,7 @@ var doesPathRunAlongChipBoundary = (path, chipObstacles) => {
|
|
|
95788
96037
|
const end = path[i2 + 1];
|
|
95789
96038
|
for (const obstacle of chipObstacles) {
|
|
95790
96039
|
if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
|
|
95791
|
-
if (getSegmentOverlapWithRectSpan(start, end, obstacle) >
|
|
96040
|
+
if (getSegmentOverlapWithRectSpan(start, end, obstacle) > EPS10) {
|
|
95792
96041
|
return true;
|
|
95793
96042
|
}
|
|
95794
96043
|
}
|
|
@@ -95803,13 +96052,13 @@ var getChipBoundaryOverlap = (path, chipObstacles) => {
|
|
|
95803
96052
|
for (const obstacle of chipObstacles) {
|
|
95804
96053
|
if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
|
|
95805
96054
|
const overlap = getSegmentOverlapWithRectSpan(start, end, obstacle);
|
|
95806
|
-
if (overlap >
|
|
96055
|
+
if (overlap > EPS10) total += overlap;
|
|
95807
96056
|
}
|
|
95808
96057
|
}
|
|
95809
96058
|
return total;
|
|
95810
96059
|
};
|
|
95811
96060
|
var getSegmentOverlapWithRectSpan = (start, end, rect) => {
|
|
95812
|
-
const isVertical6 = Math.abs(start.x - end.x) <
|
|
96061
|
+
const isVertical6 = Math.abs(start.x - end.x) < EPS10;
|
|
95813
96062
|
if (isVertical6) {
|
|
95814
96063
|
return Math.min(Math.max(start.y, end.y), rect.maxY) - Math.max(Math.min(start.y, end.y), rect.minY);
|
|
95815
96064
|
}
|
|
@@ -96255,8 +96504,8 @@ var scoreSolutionTracePath = (params) => {
|
|
|
96255
96504
|
}
|
|
96256
96505
|
return { chipEdgeRuns, traceCrossings };
|
|
96257
96506
|
};
|
|
96258
|
-
var
|
|
96259
|
-
var
|
|
96507
|
+
var CANDIDATE_SELECTED_COLOR2 = "blue";
|
|
96508
|
+
var CANDIDATE_REJECTED_COLOR2 = "red";
|
|
96260
96509
|
var visualizeExample28Solver = (state) => {
|
|
96261
96510
|
const graphics = visualizeInputProblem(state.inputProblem);
|
|
96262
96511
|
drawTraces(graphics, state);
|
|
@@ -96302,7 +96551,7 @@ label intersections: ${candidate.score.labelIntersections}
|
|
|
96302
96551
|
trace intersections: ${candidate.score.traceIntersections}` : "";
|
|
96303
96552
|
graphics.lines.push({
|
|
96304
96553
|
points: candidate.path,
|
|
96305
|
-
strokeColor: candidate.selected ?
|
|
96554
|
+
strokeColor: candidate.selected ? CANDIDATE_SELECTED_COLOR2 : CANDIDATE_REJECTED_COLOR2,
|
|
96306
96555
|
strokeDash: candidate.selected ? void 0 : "4 2",
|
|
96307
96556
|
label: `${candidate.selected ? "selected" : candidate.status} reroute${scoreLabel}`
|
|
96308
96557
|
});
|
|
@@ -96316,7 +96565,7 @@ var drawCurrentOverlap = (graphics, state) => {
|
|
|
96316
96565
|
width: label.width,
|
|
96317
96566
|
height: label.height,
|
|
96318
96567
|
fill: "rgba(255, 0, 0, 0.2)",
|
|
96319
|
-
strokeColor:
|
|
96568
|
+
strokeColor: CANDIDATE_REJECTED_COLOR2,
|
|
96320
96569
|
label: `overlap target
|
|
96321
96570
|
${label.netId ?? label.globalConnNetId}`
|
|
96322
96571
|
});
|
|
@@ -96559,107 +96808,6 @@ var createPortOnlyLabelConnectorTrace = ({
|
|
|
96559
96808
|
pinIds: label.pinIds
|
|
96560
96809
|
};
|
|
96561
96810
|
};
|
|
96562
|
-
var LABEL_SEARCH_STEP = 0.05;
|
|
96563
|
-
var MAX_RECORDED_CANDIDATES = 2e3;
|
|
96564
|
-
var WICK_CLEARANCE = 1e-3;
|
|
96565
|
-
var EPS14 = 1e-9;
|
|
96566
|
-
var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS14;
|
|
96567
|
-
var CANDIDATE_SELECTED_COLOR2 = "blue";
|
|
96568
|
-
var CANDIDATE_REJECTED_COLOR2 = "red";
|
|
96569
|
-
var isYOrientation = (orientation2) => orientation2 === "y+" || orientation2 === "y-";
|
|
96570
|
-
var isXOrientation = (orientation2) => orientation2 === "x+" || orientation2 === "x-";
|
|
96571
|
-
var rectsOverlap2 = (a2, b2) => Math.min(a2.maxX, b2.maxX) - Math.max(a2.minX, b2.minX) > EPS14 && Math.min(a2.maxY, b2.maxY) - Math.max(a2.minY, b2.minY) > EPS14;
|
|
96572
|
-
var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS14;
|
|
96573
|
-
var traceCrossesBoundsInterior = (bounds, traceMap) => {
|
|
96574
|
-
for (const trace of Object.values(traceMap)) {
|
|
96575
|
-
const points = trace.tracePath;
|
|
96576
|
-
for (let i2 = 0; i2 < points.length - 1; i2++) {
|
|
96577
|
-
if (segmentCrossesBoundsInterior(points[i2], points[i2 + 1], bounds)) {
|
|
96578
|
-
return true;
|
|
96579
|
-
}
|
|
96580
|
-
}
|
|
96581
|
-
}
|
|
96582
|
-
return false;
|
|
96583
|
-
};
|
|
96584
|
-
var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
|
|
96585
|
-
const interiorBounds = {
|
|
96586
|
-
minX: bounds.minX + TRACE_BOUNDARY_TOLERANCE,
|
|
96587
|
-
minY: bounds.minY + TRACE_BOUNDARY_TOLERANCE,
|
|
96588
|
-
maxX: bounds.maxX - TRACE_BOUNDARY_TOLERANCE,
|
|
96589
|
-
maxY: bounds.maxY - TRACE_BOUNDARY_TOLERANCE
|
|
96590
|
-
};
|
|
96591
|
-
if (interiorBounds.minX >= interiorBounds.maxX || interiorBounds.minY >= interiorBounds.maxY) {
|
|
96592
|
-
return false;
|
|
96593
|
-
}
|
|
96594
|
-
if (sameX2(p1, p2)) {
|
|
96595
|
-
if (p1.x <= interiorBounds.minX + EPS14 || p1.x >= interiorBounds.maxX - EPS14) {
|
|
96596
|
-
return false;
|
|
96597
|
-
}
|
|
96598
|
-
return rangesOverlap(
|
|
96599
|
-
Math.min(p1.y, p2.y),
|
|
96600
|
-
Math.max(p1.y, p2.y),
|
|
96601
|
-
interiorBounds.minY,
|
|
96602
|
-
interiorBounds.maxY
|
|
96603
|
-
);
|
|
96604
|
-
}
|
|
96605
|
-
if (sameY2(p1, p2)) {
|
|
96606
|
-
if (p1.y <= interiorBounds.minY + EPS14 || p1.y >= interiorBounds.maxY - EPS14) {
|
|
96607
|
-
return false;
|
|
96608
|
-
}
|
|
96609
|
-
return rangesOverlap(
|
|
96610
|
-
Math.min(p1.x, p2.x),
|
|
96611
|
-
Math.max(p1.x, p2.x),
|
|
96612
|
-
interiorBounds.minX,
|
|
96613
|
-
interiorBounds.maxX
|
|
96614
|
-
);
|
|
96615
|
-
}
|
|
96616
|
-
return false;
|
|
96617
|
-
};
|
|
96618
|
-
var tracePathIntersectsBounds = (tracePath, bounds) => {
|
|
96619
|
-
for (let i2 = 0; i2 < tracePath.length - 1; i2++) {
|
|
96620
|
-
if (segmentIntersectsRect2(tracePath[i2], tracePath[i2 + 1], bounds)) {
|
|
96621
|
-
return true;
|
|
96622
|
-
}
|
|
96623
|
-
}
|
|
96624
|
-
return false;
|
|
96625
|
-
};
|
|
96626
|
-
var getSideDistances = (point6, bounds) => [
|
|
96627
|
-
["left", Math.abs(point6.x - bounds.minX)],
|
|
96628
|
-
["right", Math.abs(point6.x - bounds.maxX)],
|
|
96629
|
-
["bottom", Math.abs(point6.y - bounds.minY)],
|
|
96630
|
-
["top", Math.abs(point6.y - bounds.maxY)]
|
|
96631
|
-
];
|
|
96632
|
-
var getConnectorTracePath = (source, target, orientation2) => simplifyOrthogonalPath(
|
|
96633
|
-
isYOrientation(orientation2) ? [source, { x: target.x, y: source.y }, target] : [source, { x: source.x, y: target.y }, target]
|
|
96634
|
-
);
|
|
96635
|
-
var simplifyOrthogonalPath = (path) => {
|
|
96636
|
-
const deduped = path.filter(
|
|
96637
|
-
(point6, index2) => index2 === 0 || !pointsEqual3(point6, path[index2 - 1])
|
|
96638
|
-
);
|
|
96639
|
-
if (deduped.length < 3) return deduped;
|
|
96640
|
-
const simplified = [deduped[0]];
|
|
96641
|
-
for (let i2 = 1; i2 < deduped.length - 1; i2++) {
|
|
96642
|
-
const prev = simplified[simplified.length - 1];
|
|
96643
|
-
const point6 = deduped[i2];
|
|
96644
|
-
const next = deduped[i2 + 1];
|
|
96645
|
-
if (sameX2(prev, point6) && sameX2(point6, next) || sameY2(prev, point6) && sameY2(point6, next)) {
|
|
96646
|
-
continue;
|
|
96647
|
-
}
|
|
96648
|
-
simplified.push(point6);
|
|
96649
|
-
}
|
|
96650
|
-
simplified.push(deduped[deduped.length - 1]);
|
|
96651
|
-
return simplified;
|
|
96652
|
-
};
|
|
96653
|
-
var pointsEqual3 = (a2, b2) => sameX2(a2, b2) && sameY2(a2, b2);
|
|
96654
|
-
var sameX2 = (a2, b2) => Math.abs(a2.x - b2.x) <= EPS14;
|
|
96655
|
-
var sameY2 = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS14;
|
|
96656
|
-
var getMaxSearchDistance = (inputProblem) => {
|
|
96657
|
-
const maxChipWidth = Math.max(
|
|
96658
|
-
...inputProblem.chips.map((chip) => chip.width),
|
|
96659
|
-
1
|
|
96660
|
-
);
|
|
96661
|
-
return maxChipWidth * 3;
|
|
96662
|
-
};
|
|
96663
96811
|
var isPortOnlyLabel = (label) => label.mspConnectionPairIds.length === 0;
|
|
96664
96812
|
var orderRoutedLabelsBeforeOverlappingPortLabels = ({
|
|
96665
96813
|
labelIndices,
|
|
@@ -96685,7 +96833,7 @@ var orderRoutedLabelsBeforeOverlappingPortLabels = ({
|
|
|
96685
96833
|
portOnlyLabel.width,
|
|
96686
96834
|
portOnlyLabel.height
|
|
96687
96835
|
);
|
|
96688
|
-
return
|
|
96836
|
+
return rectsOverlap(routedBounds, portOnlyBounds);
|
|
96689
96837
|
});
|
|
96690
96838
|
const routedPosition = orderedLabelIndices.indexOf(routedLabelIndex);
|
|
96691
96839
|
if (blockingPosition === -1 || blockingPosition > routedPosition) continue;
|
|
@@ -96738,7 +96886,7 @@ var drawCurrentLabel = (graphics, currentLabel, solved) => {
|
|
|
96738
96886
|
width: currentLabel.width,
|
|
96739
96887
|
height: currentLabel.height,
|
|
96740
96888
|
fill: "rgba(255, 0, 0, 0.2)",
|
|
96741
|
-
strokeColor:
|
|
96889
|
+
strokeColor: CANDIDATE_REJECTED_COLOR,
|
|
96742
96890
|
label: `available orientation target
|
|
96743
96891
|
${currentLabel.netId ?? currentLabel.globalConnNetId}`
|
|
96744
96892
|
});
|
|
@@ -96746,7 +96894,7 @@ ${currentLabel.netId ?? currentLabel.globalConnNetId}`
|
|
|
96746
96894
|
var drawCurrentCandidates2 = (graphics, candidates, solved) => {
|
|
96747
96895
|
if (solved) return;
|
|
96748
96896
|
for (const candidate of candidates) {
|
|
96749
|
-
const color3 = candidate.selected ?
|
|
96897
|
+
const color3 = candidate.selected ? CANDIDATE_SELECTED_COLOR : CANDIDATE_REJECTED_COLOR;
|
|
96750
96898
|
const distanceLabel = candidate.distance === void 0 ? "" : `
|
|
96751
96899
|
distance: ${candidate.distance.toFixed(3)}`;
|
|
96752
96900
|
const outwardDistanceLabel = candidate.outwardDistance === void 0 || candidate.outwardDistance === 0 ? "" : `
|
|
@@ -96804,7 +96952,7 @@ var AvailableNetOrientationObstacleIndex = class {
|
|
|
96804
96952
|
}
|
|
96805
96953
|
getTraceSegmentsInBounds(bounds) {
|
|
96806
96954
|
if (!this.traceSegmentIndex) return [];
|
|
96807
|
-
const searchBounds = getPaddedBounds(bounds,
|
|
96955
|
+
const searchBounds = getPaddedBounds(bounds, EPS8);
|
|
96808
96956
|
return this.traceSegmentIndex.search(
|
|
96809
96957
|
searchBounds.minX,
|
|
96810
96958
|
searchBounds.minY,
|
|
@@ -96817,7 +96965,7 @@ var AvailableNetOrientationObstacleIndex = class {
|
|
|
96817
96965
|
for (let pointIndex = 0; pointIndex < tracePath.length - 1; pointIndex++) {
|
|
96818
96966
|
const segmentBounds = getPaddedBounds(
|
|
96819
96967
|
getSegmentBounds(tracePath[pointIndex], tracePath[pointIndex + 1]),
|
|
96820
|
-
|
|
96968
|
+
EPS8
|
|
96821
96969
|
);
|
|
96822
96970
|
for (const labelIndex of this.getLabelIndicesInBounds(segmentBounds)) {
|
|
96823
96971
|
labelIndices.add(labelIndex);
|
|
@@ -96830,7 +96978,7 @@ var AvailableNetOrientationObstacleIndex = class {
|
|
|
96830
96978
|
const start = tracePath[pointIndex];
|
|
96831
96979
|
const end = tracePath[pointIndex + 1];
|
|
96832
96980
|
const nearbyChips = this.chipObstacleSpatialIndex.getChipsInBounds(
|
|
96833
|
-
getPaddedBounds(getSegmentBounds(start, end),
|
|
96981
|
+
getPaddedBounds(getSegmentBounds(start, end), EPS8)
|
|
96834
96982
|
);
|
|
96835
96983
|
for (const chip of nearbyChips) {
|
|
96836
96984
|
if (segmentCrossesBoundsInterior(start, end, chip.bounds)) return true;
|
|
@@ -97088,7 +97236,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97088
97236
|
if (otherIndex === labelIndex) return false;
|
|
97089
97237
|
if (otherLabel.globalConnNetId === label.globalConnNetId) return false;
|
|
97090
97238
|
const otherBounds = this.getHorizontalConstraintMismatchBounds(otherLabel);
|
|
97091
|
-
return otherBounds ?
|
|
97239
|
+
return otherBounds ? rectsOverlap(bounds2, otherBounds) : false;
|
|
97092
97240
|
});
|
|
97093
97241
|
if (overlapsHorizontalConstraintMismatch) return true;
|
|
97094
97242
|
}
|
|
@@ -97097,7 +97245,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97097
97245
|
return this.outputNetLabelPlacements.some((otherLabel, otherIndex) => {
|
|
97098
97246
|
if (otherIndex === labelIndex) return false;
|
|
97099
97247
|
if (otherLabel.globalConnNetId === label.globalConnNetId) return false;
|
|
97100
|
-
return
|
|
97248
|
+
return rectsOverlap(
|
|
97101
97249
|
bounds,
|
|
97102
97250
|
getRectBounds(otherLabel.center, otherLabel.width, otherLabel.height)
|
|
97103
97251
|
);
|
|
@@ -97134,7 +97282,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97134
97282
|
const bounds = getRectBounds(label.center, label.width, label.height);
|
|
97135
97283
|
return labelIndices.slice(position + 1).some((otherIndex) => {
|
|
97136
97284
|
const other = this.outputNetLabelPlacements[otherIndex];
|
|
97137
|
-
return
|
|
97285
|
+
return rectsOverlap(
|
|
97138
97286
|
bounds,
|
|
97139
97287
|
getRectBounds(other.center, other.width, other.height)
|
|
97140
97288
|
);
|
|
@@ -97285,7 +97433,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97285
97433
|
labelIndex,
|
|
97286
97434
|
orientations
|
|
97287
97435
|
);
|
|
97288
|
-
const rotatedCandidateNeedsLateralBranch = rotatedCandidate !== null && Math.abs(rotatedCandidate.anchorPoint.x - label.anchorPoint.x) >
|
|
97436
|
+
const rotatedCandidateNeedsLateralBranch = rotatedCandidate !== null && Math.abs(rotatedCandidate.anchorPoint.x - label.anchorPoint.x) > EPS8;
|
|
97289
97437
|
if (isDownwardGroundRail && rotatedCandidateNeedsLateralBranch) {
|
|
97290
97438
|
const downwardRailCandidate = this.findValidCandidateInShiftColumn({
|
|
97291
97439
|
label,
|
|
@@ -97344,7 +97492,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97344
97492
|
index: index2,
|
|
97345
97493
|
pin: this.pinMap[otherLabel.pinIds[0]]
|
|
97346
97494
|
})).filter(
|
|
97347
|
-
({ index: index2, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index2) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x +
|
|
97495
|
+
({ index: index2, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index2) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x + EPS8
|
|
97348
97496
|
).sort((a2, b2) => a2.pin.x - b2.pin.x)[0]?.pin;
|
|
97349
97497
|
if (orientation2 === "y-" && nextPinToRight) return null;
|
|
97350
97498
|
const anchorX = orientation2 === "y-" ? Math.max(
|
|
@@ -97377,7 +97525,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97377
97525
|
const centeredAnchorY = hasUpFacingStack ? (lowestUpFacingLabelY + highestUpFacingLabelY) / 2 : stackedAnchorY;
|
|
97378
97526
|
const anchorYs = orientation2 === "y-" ? [centeredAnchorY, stackedAnchorY] : [stackedAnchorY];
|
|
97379
97527
|
for (const anchorY of anchorYs) {
|
|
97380
|
-
if (anchorY - label.anchorPoint.y > this.maxSearchDistance +
|
|
97528
|
+
if (anchorY - label.anchorPoint.y > this.maxSearchDistance + EPS8) {
|
|
97381
97529
|
continue;
|
|
97382
97530
|
}
|
|
97383
97531
|
const candidate = this.createCandidate(
|
|
@@ -97406,11 +97554,11 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97406
97554
|
if (trace.globalConnNetId !== label.globalConnNetId) return false;
|
|
97407
97555
|
const path = trace.tracePath;
|
|
97408
97556
|
return path.some((point6, pointIndex) => {
|
|
97409
|
-
if (Math.abs(point6.x - label.anchorPoint.x) >
|
|
97557
|
+
if (Math.abs(point6.x - label.anchorPoint.x) > EPS8 || Math.abs(point6.y - label.anchorPoint.y) > EPS8) {
|
|
97410
97558
|
return false;
|
|
97411
97559
|
}
|
|
97412
97560
|
return [path[pointIndex - 1], path[pointIndex + 1]].some(
|
|
97413
|
-
(neighbor) => neighbor && Math.abs(neighbor.x - point6.x) <=
|
|
97561
|
+
(neighbor) => neighbor && Math.abs(neighbor.x - point6.x) <= EPS8 && (neighbor.y - point6.y) * direction.y > EPS8
|
|
97414
97562
|
);
|
|
97415
97563
|
});
|
|
97416
97564
|
});
|
|
@@ -97500,7 +97648,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97500
97648
|
orientation2
|
|
97501
97649
|
);
|
|
97502
97650
|
if (outwardDirection2.x === 0 && outwardDirection2.y === 0) continue;
|
|
97503
|
-
for (let distance33 = LABEL_SEARCH_STEP; distance33 <= this.maxSearchDistance +
|
|
97651
|
+
for (let distance33 = LABEL_SEARCH_STEP; distance33 <= this.maxSearchDistance + EPS8; distance33 += LABEL_SEARCH_STEP) {
|
|
97504
97652
|
const anchorPoint = {
|
|
97505
97653
|
x: connectorSource.x + outwardDirection2.x * distance33,
|
|
97506
97654
|
y: connectorSource.y + outwardDirection2.y * distance33
|
|
@@ -97578,7 +97726,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97578
97726
|
const furthestRowPoints = points.filter(
|
|
97579
97727
|
(point6) => Math.abs(
|
|
97580
97728
|
point6.x * direction.x + point6.y * direction.y - furthestAlong
|
|
97581
|
-
) <=
|
|
97729
|
+
) <= EPS8
|
|
97582
97730
|
);
|
|
97583
97731
|
const directHostPinIds = new Set(
|
|
97584
97732
|
[...directHostTraceIds].flatMap(
|
|
@@ -97599,7 +97747,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97599
97747
|
preferNearestBendOnOutwardRow: adjacentTraces.some(
|
|
97600
97748
|
(trace) => furthestRowPoints.some(
|
|
97601
97749
|
(point6) => trace.tracePath.some(
|
|
97602
|
-
(tracePoint) => Math.abs(tracePoint.x - point6.x) <=
|
|
97750
|
+
(tracePoint) => Math.abs(tracePoint.x - point6.x) <= EPS8 && Math.abs(tracePoint.y - point6.y) <= EPS8
|
|
97603
97751
|
)
|
|
97604
97752
|
)
|
|
97605
97753
|
)
|
|
@@ -97611,7 +97759,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97611
97759
|
for (let i2 = 0; i2 < otherTrace.tracePath.length - 1; i2++) {
|
|
97612
97760
|
const start = otherTrace.tracePath[i2];
|
|
97613
97761
|
const end = otherTrace.tracePath[i2 + 1];
|
|
97614
|
-
if (Math.abs(start.x - end.x) <=
|
|
97762
|
+
if (Math.abs(start.x - end.x) <= EPS8 && Math.abs(start.y - end.y) > EPS8) {
|
|
97615
97763
|
verticalRailXs.add(start.x);
|
|
97616
97764
|
}
|
|
97617
97765
|
}
|
|
@@ -97619,7 +97767,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97619
97767
|
for (let i2 = 0; i2 < trace.tracePath.length - 1; i2++) {
|
|
97620
97768
|
const start = trace.tracePath[i2];
|
|
97621
97769
|
const end = trace.tracePath[i2 + 1];
|
|
97622
|
-
if (Math.abs(start.x - end.x) <=
|
|
97770
|
+
if (Math.abs(start.x - end.x) <= EPS8 && Math.abs(start.y - end.y) > EPS8 && [...verticalRailXs].some((x2) => Math.abs(x2 - start.x) <= EPS8)) {
|
|
97623
97771
|
return true;
|
|
97624
97772
|
}
|
|
97625
97773
|
}
|
|
@@ -97638,7 +97786,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97638
97786
|
);
|
|
97639
97787
|
const maxSearchDistance = this.getSearchDistanceLimit(label, orientation2);
|
|
97640
97788
|
const maxOutwardDistance = outwardDirection2.x === 0 && outwardDirection2.y === 0 ? 0 : this.maxSearchDistance;
|
|
97641
|
-
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance +
|
|
97789
|
+
for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS8; outwardDistance += LABEL_SEARCH_STEP) {
|
|
97642
97790
|
const baseAnchor = {
|
|
97643
97791
|
x: initialBaseAnchor.x + outwardDirection2.x * outwardDistance,
|
|
97644
97792
|
y: initialBaseAnchor.y + outwardDirection2.y * outwardDistance
|
|
@@ -97714,7 +97862,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97714
97862
|
connectorSource,
|
|
97715
97863
|
startDistance = LABEL_SEARCH_STEP
|
|
97716
97864
|
} = params;
|
|
97717
|
-
for (let distance33 = startDistance; distance33 <= maxSearchDistance +
|
|
97865
|
+
for (let distance33 = startDistance; distance33 <= maxSearchDistance + EPS8; distance33 += LABEL_SEARCH_STEP) {
|
|
97718
97866
|
const anchorPoint = {
|
|
97719
97867
|
x: baseAnchor.x + direction.x * distance33,
|
|
97720
97868
|
y: baseAnchor.y + direction.y * distance33
|
|
@@ -97828,14 +97976,14 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
97828
97976
|
for (let pointIndex = 0; pointIndex < hostTrace.tracePath.length - 1; pointIndex++) {
|
|
97829
97977
|
const start = hostTrace.tracePath[pointIndex];
|
|
97830
97978
|
const end = hostTrace.tracePath[pointIndex + 1];
|
|
97831
|
-
const segmentIsPerpendicularToLabel = isYOrientation(orientation2) ? Math.abs(start.y - end.y) <=
|
|
97979
|
+
const segmentIsPerpendicularToLabel = isYOrientation(orientation2) ? Math.abs(start.y - end.y) <= EPS8 : Math.abs(start.x - end.x) <= EPS8;
|
|
97832
97980
|
if (!segmentIsPerpendicularToLabel) continue;
|
|
97833
97981
|
const source = isYOrientation(orientation2) ? { x: targetAnchor.x, y: start.y } : { x: start.x, y: targetAnchor.y };
|
|
97834
97982
|
if (!tracePathContainsPoint([start, end], label.anchorPoint) || !tracePathContainsPoint([start, end], source)) {
|
|
97835
97983
|
continue;
|
|
97836
97984
|
}
|
|
97837
97985
|
const targetDistanceAlongOrientation = (targetAnchor.x - source.x) * orientationDirection.x + (targetAnchor.y - source.y) * orientationDirection.y;
|
|
97838
|
-
if (targetDistanceAlongOrientation >= -
|
|
97986
|
+
if (targetDistanceAlongOrientation >= -EPS8) {
|
|
97839
97987
|
projectedSources.push(source);
|
|
97840
97988
|
}
|
|
97841
97989
|
}
|
|
@@ -98094,9 +98242,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98094
98242
|
const { anchorPoint, orientation: orientation2 } = candidate;
|
|
98095
98243
|
const chipBounds = chip.bounds;
|
|
98096
98244
|
if (isYOrientation(orientation2)) {
|
|
98097
|
-
return anchorPoint.x < chipBounds.minX -
|
|
98245
|
+
return anchorPoint.x < chipBounds.minX - EPS8 || anchorPoint.x > chipBounds.maxX + EPS8;
|
|
98098
98246
|
}
|
|
98099
|
-
return anchorPoint.y < chipBounds.minY -
|
|
98247
|
+
return anchorPoint.y < chipBounds.minY - EPS8 || anchorPoint.y > chipBounds.maxY + EPS8;
|
|
98100
98248
|
});
|
|
98101
98249
|
}
|
|
98102
98250
|
staysOutsideConnectedPinRow(params) {
|
|
@@ -98104,9 +98252,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98104
98252
|
const pin = this.pinMap[label.pinIds[0]];
|
|
98105
98253
|
if (!pin || !isYOrientation(candidate.orientation)) return false;
|
|
98106
98254
|
if (candidate.anchorPoint.x < pin.x) {
|
|
98107
|
-
return bounds.maxX <= pin.x + CONNECTED_PIN_ROW_OVERLAP_TOLERANCE +
|
|
98255
|
+
return bounds.maxX <= pin.x + CONNECTED_PIN_ROW_OVERLAP_TOLERANCE + EPS8;
|
|
98108
98256
|
}
|
|
98109
|
-
return bounds.minX >= pin.x - CONNECTED_PIN_ROW_OVERLAP_TOLERANCE -
|
|
98257
|
+
return bounds.minX >= pin.x - CONNECTED_PIN_ROW_OVERLAP_TOLERANCE - EPS8;
|
|
98110
98258
|
}
|
|
98111
98259
|
getBoundsStatus(candidateBoundsCheck) {
|
|
98112
98260
|
const { bounds, labelIndex, label, ignoreChipCollisions } = candidateBoundsCheck;
|
|
@@ -98187,14 +98335,14 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98187
98335
|
candidate.width,
|
|
98188
98336
|
candidate.height
|
|
98189
98337
|
);
|
|
98190
|
-
if (labelBounds.minY < chip.bounds.minY -
|
|
98338
|
+
if (labelBounds.minY < chip.bounds.minY - EPS8 || labelBounds.maxY > chip.bounds.maxY + EPS8) {
|
|
98191
98339
|
return false;
|
|
98192
98340
|
}
|
|
98193
|
-
if (candidate.anchorPoint.x >= chip.bounds.minX -
|
|
98341
|
+
if (candidate.anchorPoint.x >= chip.bounds.minX - EPS8 && candidate.anchorPoint.x <= chip.bounds.maxX + EPS8) {
|
|
98194
98342
|
return false;
|
|
98195
98343
|
}
|
|
98196
98344
|
return chip.pins.every(
|
|
98197
|
-
(pin) => label.pinIds.includes(pin.pinId) || pin.y <= labelBounds.minY +
|
|
98345
|
+
(pin) => label.pinIds.includes(pin.pinId) || pin.y <= labelBounds.minY + EPS8 || pin.y >= labelBounds.maxY - EPS8
|
|
98198
98346
|
);
|
|
98199
98347
|
}
|
|
98200
98348
|
getTextBlockedMultiPinRailTraces(label, orientation2) {
|
|
@@ -98221,20 +98369,20 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98221
98369
|
const pins = [...connectedPinIds].map((pinId) => this.pinMap[pinId]);
|
|
98222
98370
|
const direction = dir(orientation2);
|
|
98223
98371
|
const pinX = pins[0].x;
|
|
98224
|
-
if (pins.some((pin) => Math.abs(pin.x - pinX) >
|
|
98225
|
-
const sidePins = this.inputProblem.chips.find((chip) => chip.chipId === componentId).pins.filter((pin) => Math.abs(pin.x - pinX) <=
|
|
98372
|
+
if (pins.some((pin) => Math.abs(pin.x - pinX) > EPS8)) return null;
|
|
98373
|
+
const sidePins = this.inputProblem.chips.find((chip) => chip.chipId === componentId).pins.filter((pin) => Math.abs(pin.x - pinX) <= EPS8);
|
|
98226
98374
|
const minY = Math.min(...pins.map((pin) => pin.y));
|
|
98227
98375
|
const maxY = Math.max(...pins.map((pin) => pin.y));
|
|
98228
98376
|
if (sidePins.some(
|
|
98229
|
-
(pin) => pin.y >= minY -
|
|
98230
|
-
) || orientation2 === "y-" && minY > Math.min(...sidePins.map((pin) => pin.y)) +
|
|
98377
|
+
(pin) => pin.y >= minY - EPS8 && pin.y <= maxY + EPS8 && !connectedPinIds.has(pin.pinId)
|
|
98378
|
+
) || orientation2 === "y-" && minY > Math.min(...sidePins.map((pin) => pin.y)) + EPS8 || orientation2 === "y+" && maxY < Math.max(...sidePins.map((pin) => pin.y)) - EPS8) {
|
|
98231
98379
|
return null;
|
|
98232
98380
|
}
|
|
98233
98381
|
const outerPinPosition = Math.max(
|
|
98234
98382
|
...pins.map((pin) => pin.x * direction.x + pin.y * direction.y)
|
|
98235
98383
|
);
|
|
98236
98384
|
const blockedByText = (this.inputProblem.textBoxes ?? []).some(
|
|
98237
|
-
(textBox) => textBox.chipId === componentId && textBox.center.x * direction.x + textBox.center.y * direction.y > outerPinPosition +
|
|
98385
|
+
(textBox) => textBox.chipId === componentId && textBox.center.x * direction.x + textBox.center.y * direction.y > outerPinPosition + EPS8
|
|
98238
98386
|
);
|
|
98239
98387
|
return blockedByText ? [...connectedTraces] : null;
|
|
98240
98388
|
}
|
|
@@ -98250,7 +98398,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98250
98398
|
...new Set(
|
|
98251
98399
|
localTraces.flatMap((trace) => trace.tracePath.map((point6) => point6.x))
|
|
98252
98400
|
)
|
|
98253
|
-
].filter((x2) => Math.abs(x2 - pinX) >
|
|
98401
|
+
].filter((x2) => Math.abs(x2 - pinX) > EPS8).sort((a2, b2) => Math.abs(a2 - pinX) - Math.abs(b2 - pinX));
|
|
98254
98402
|
for (const x2 of railXs) {
|
|
98255
98403
|
const connectorSource = { x: x2, y: connectorY };
|
|
98256
98404
|
if (!Object.values(this.traceMap).some(
|
|
@@ -98313,8 +98461,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98313
98461
|
if (!chip) return null;
|
|
98314
98462
|
const sides = new Set(
|
|
98315
98463
|
pins.map((pin) => {
|
|
98316
|
-
if (Math.abs(pin.x - chip.bounds.minX) <=
|
|
98317
|
-
if (Math.abs(pin.x - chip.bounds.maxX) <=
|
|
98464
|
+
if (Math.abs(pin.x - chip.bounds.minX) <= EPS8) return "left";
|
|
98465
|
+
if (Math.abs(pin.x - chip.bounds.maxX) <= EPS8) return "right";
|
|
98318
98466
|
return null;
|
|
98319
98467
|
})
|
|
98320
98468
|
);
|
|
@@ -98351,7 +98499,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98351
98499
|
return null;
|
|
98352
98500
|
}
|
|
98353
98501
|
const renderedWidth = this.getNetConnectionForLabel(label)?.netLabelHeight;
|
|
98354
|
-
if (renderedWidth === void 0 || renderedWidth <= label.width + label.height +
|
|
98502
|
+
if (renderedWidth === void 0 || renderedWidth <= label.width + label.height + EPS8) {
|
|
98355
98503
|
return null;
|
|
98356
98504
|
}
|
|
98357
98505
|
const placementBaseCenter = getCenterFromAnchor(
|
|
@@ -98420,22 +98568,22 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98420
98568
|
otherBounds.minX -= LABEL_SEARCH_STEP;
|
|
98421
98569
|
otherBounds.maxX += LABEL_SEARCH_STEP;
|
|
98422
98570
|
}
|
|
98423
|
-
if (
|
|
98571
|
+
if (rectsOverlap(bounds, otherBounds)) return true;
|
|
98424
98572
|
}
|
|
98425
98573
|
return false;
|
|
98426
98574
|
}
|
|
98427
98575
|
sharesChipBoundary(bounds) {
|
|
98428
98576
|
const boundarySearchBounds = {
|
|
98429
|
-
minX: bounds.minX - WICK_CLEARANCE -
|
|
98430
|
-
minY: bounds.minY - WICK_CLEARANCE -
|
|
98431
|
-
maxX: bounds.maxX + WICK_CLEARANCE +
|
|
98432
|
-
maxY: bounds.maxY + WICK_CLEARANCE +
|
|
98577
|
+
minX: bounds.minX - WICK_CLEARANCE - EPS8,
|
|
98578
|
+
minY: bounds.minY - WICK_CLEARANCE - EPS8,
|
|
98579
|
+
maxX: bounds.maxX + WICK_CLEARANCE + EPS8,
|
|
98580
|
+
maxY: bounds.maxY + WICK_CLEARANCE + EPS8
|
|
98433
98581
|
};
|
|
98434
98582
|
const nearbyChips = this.chipObstacleSpatialIndex.getChipsInBounds(boundarySearchBounds);
|
|
98435
98583
|
for (const chip of nearbyChips) {
|
|
98436
98584
|
const chipBounds = chip.bounds;
|
|
98437
|
-
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE +
|
|
98438
|
-
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE +
|
|
98585
|
+
const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS8 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS8;
|
|
98586
|
+
const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS8 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS8;
|
|
98439
98587
|
if (adjacentToVerticalSide && rangesOverlap(
|
|
98440
98588
|
bounds.minY,
|
|
98441
98589
|
bounds.maxY,
|
|
@@ -98497,7 +98645,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98497
98645
|
let nearestDistance = Number.POSITIVE_INFINITY;
|
|
98498
98646
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
98499
98647
|
const bounds = chip.bounds;
|
|
98500
|
-
if (point6.x < bounds.minX -
|
|
98648
|
+
if (point6.x < bounds.minX - EPS8 || point6.x > bounds.maxX + EPS8 || point6.y < bounds.minY - EPS8 || point6.y > bounds.maxY + EPS8) {
|
|
98501
98649
|
continue;
|
|
98502
98650
|
}
|
|
98503
98651
|
for (const [side, distance33] of getSideDistances(point6, bounds)) {
|
|
@@ -98514,8 +98662,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
|
|
|
98514
98662
|
let nearestDistanceSq = Number.POSITIVE_INFINITY;
|
|
98515
98663
|
for (const chip of this.chipObstacleSpatialIndex.chips) {
|
|
98516
98664
|
const bounds = chip.bounds;
|
|
98517
|
-
const dx2 = point6.x < bounds.minX -
|
|
98518
|
-
const dy2 = point6.y < bounds.minY -
|
|
98665
|
+
const dx2 = point6.x < bounds.minX - EPS8 ? bounds.minX - point6.x : point6.x > bounds.maxX + EPS8 ? point6.x - bounds.maxX : 0;
|
|
98666
|
+
const dy2 = point6.y < bounds.minY - EPS8 ? bounds.minY - point6.y : point6.y > bounds.maxY + EPS8 ? point6.y - bounds.maxY : 0;
|
|
98519
98667
|
if (dx2 === 0 && dy2 === 0) continue;
|
|
98520
98668
|
const distanceSq = dx2 ** 2 + dy2 ** 2;
|
|
98521
98669
|
if (distanceSq >= nearestDistanceSq) continue;
|
|
@@ -98667,7 +98815,7 @@ var getRemovableRailLabelConnectors = ({
|
|
|
98667
98815
|
const endpoints = [connector.tracePath[0], connector.tracePath.at(-1)];
|
|
98668
98816
|
if (!endpoints[0] || !endpoints[1]) continue;
|
|
98669
98817
|
const labelEnd = endpoints.findIndex(
|
|
98670
|
-
(point6) => getDistance2(point6, label.anchorPoint) <=
|
|
98818
|
+
(point6) => getDistance2(point6, label.anchorPoint) <= EPS9
|
|
98671
98819
|
);
|
|
98672
98820
|
if (labelEnd === -1) continue;
|
|
98673
98821
|
const source = endpoints[1 - labelEnd];
|
|
@@ -98714,11 +98862,11 @@ var getStraightPortConnectorCandidate = ({
|
|
|
98714
98862
|
continue;
|
|
98715
98863
|
const path = simplifyPath(connector.tracePath);
|
|
98716
98864
|
if (path.length < 4) continue;
|
|
98717
|
-
if (getDistance2(path.at(-1), pin) <=
|
|
98718
|
-
if (getDistance2(path[0], pin) >
|
|
98865
|
+
if (getDistance2(path.at(-1), pin) <= EPS9) path.reverse();
|
|
98866
|
+
if (getDistance2(path[0], pin) > EPS9 || getDistance2(path.at(-1), label.anchorPoint) > EPS9 || Math.abs(path[1].y - pin.y) > EPS9)
|
|
98719
98867
|
continue;
|
|
98720
98868
|
const anchorPoint = { x: label.anchorPoint.x, y: pin.y };
|
|
98721
|
-
if ((anchorPoint.x - pin.x) * (path[1].x - pin.x) <=
|
|
98869
|
+
if ((anchorPoint.x - pin.x) * (path[1].x - pin.x) <= EPS9) continue;
|
|
98722
98870
|
const reroutedTracePath = [path[0], anchorPoint];
|
|
98723
98871
|
const protectedPoints = [
|
|
98724
98872
|
...getSameNetJunctions(connector, traces),
|
|
@@ -98756,13 +98904,13 @@ var getSimplifiedRailConnectorCandidates = (params) => {
|
|
|
98756
98904
|
if (countTurns(path) < 2) continue;
|
|
98757
98905
|
for (const source of getTraceCorners(simplifyPath(rail.tracePath))) {
|
|
98758
98906
|
const anchor = label.anchorPoint;
|
|
98759
|
-
if ((anchor.y - source.y) * direction < -
|
|
98907
|
+
if ((anchor.y - source.y) * direction < -EPS9) continue;
|
|
98760
98908
|
const reroutedTracePath = simplifyPath([
|
|
98761
98909
|
source,
|
|
98762
98910
|
{ x: anchor.x, y: source.y },
|
|
98763
98911
|
anchor
|
|
98764
98912
|
]);
|
|
98765
|
-
if (countTurns(reroutedTracePath) >= countTurns(path) || getPathLength4(reroutedTracePath) > getPathLength4(path) +
|
|
98913
|
+
if (countTurns(reroutedTracePath) >= countTurns(path) || getPathLength4(reroutedTracePath) > getPathLength4(path) + EPS9)
|
|
98766
98914
|
continue;
|
|
98767
98915
|
if (traces.some(
|
|
98768
98916
|
(other) => other.globalConnNetId !== connector.globalConnNetId && countPathIntersections(reroutedTracePath, other.tracePath) > countPathIntersections(path, other.tracePath)
|
|
@@ -98996,13 +99144,13 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
|
|
|
98996
99144
|
}
|
|
98997
99145
|
intersectsAnyChip(bounds) {
|
|
98998
99146
|
return this.inputProblem.chips.some(
|
|
98999
|
-
(chip) =>
|
|
99147
|
+
(chip) => rectsOverlap2(bounds, getRectBounds(chip.center, chip.width, chip.height))
|
|
99000
99148
|
);
|
|
99001
99149
|
}
|
|
99002
99150
|
intersectsAnyOtherNetLabel(bounds, labelIndex) {
|
|
99003
99151
|
return this.outputNetLabelPlacements.some((label, index2) => {
|
|
99004
99152
|
if (index2 === labelIndex) return false;
|
|
99005
|
-
return
|
|
99153
|
+
return rectsOverlap2(
|
|
99006
99154
|
bounds,
|
|
99007
99155
|
getRectBounds(label.center, label.width, label.height)
|
|
99008
99156
|
);
|
|
@@ -99023,7 +99171,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
|
|
|
99023
99171
|
for (const anchorPoint of getTraceCorners(path)) {
|
|
99024
99172
|
const cornerIndex = path.indexOf(anchorPoint);
|
|
99025
99173
|
const anchorAlignedToPin = pins.some(
|
|
99026
|
-
(pin) => Math.abs(pin.x - anchorPoint.x) <=
|
|
99174
|
+
(pin) => Math.abs(pin.x - anchorPoint.x) <= EPS9
|
|
99027
99175
|
);
|
|
99028
99176
|
const pinAligned = anchorAlignedToPin || allowRailAlignedFallback && this.isPinAlignedCorner(path, cornerIndex);
|
|
99029
99177
|
if (!pinAligned) continue;
|
|
@@ -99116,7 +99264,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
|
|
|
99116
99264
|
return [];
|
|
99117
99265
|
}
|
|
99118
99266
|
const pins = this.inputProblem.chips.flatMap((chip) => chip.pins).filter((pin) => label.pinIds.includes(pin.pinId));
|
|
99119
|
-
if (pins.length !== 2 || pins[0]._facingDirection !== pins[1]._facingDirection || pins[0]._facingDirection !== "x+" && pins[0]._facingDirection !== "x-" || Math.abs(pins[0].y - pins[1].y) >
|
|
99267
|
+
if (pins.length !== 2 || pins[0]._facingDirection !== pins[1]._facingDirection || pins[0]._facingDirection !== "x+" && pins[0]._facingDirection !== "x-" || Math.abs(pins[0].y - pins[1].y) > EPS9) {
|
|
99120
99268
|
return [];
|
|
99121
99269
|
}
|
|
99122
99270
|
const configuredOrientations = this.inputProblem.availableNetLabelOrientations[label.netId];
|
|
@@ -99141,7 +99289,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
|
|
|
99141
99289
|
getMaxSearchDistance(this.inputProblem),
|
|
99142
99290
|
label.height * 2
|
|
99143
99291
|
);
|
|
99144
|
-
for (let distance33 = WICK_CLEARANCE + LABEL_SEARCH_STEP; distance33 <= maxSearchDistance +
|
|
99292
|
+
for (let distance33 = WICK_CLEARANCE + LABEL_SEARCH_STEP; distance33 <= maxSearchDistance + EPS9; distance33 += LABEL_SEARCH_STEP) {
|
|
99145
99293
|
const anchorPoint = {
|
|
99146
99294
|
x: sourcePoint.x,
|
|
99147
99295
|
y: sourcePoint.y + direction * distance33
|
|
@@ -99193,12 +99341,12 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
|
|
|
99193
99341
|
return traceCrossesBoundsInterior(bounds, this.traceMap);
|
|
99194
99342
|
}
|
|
99195
99343
|
pointsEqual(a2, b2) {
|
|
99196
|
-
return Math.abs(a2.x - b2.x) <=
|
|
99344
|
+
return Math.abs(a2.x - b2.x) <= EPS9 && Math.abs(a2.y - b2.y) <= EPS9;
|
|
99197
99345
|
}
|
|
99198
99346
|
getVerticalSegmentPointIndices(path, cornerIndex) {
|
|
99199
99347
|
const corner = path[cornerIndex];
|
|
99200
|
-
const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <=
|
|
99201
|
-
const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <=
|
|
99348
|
+
const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <= EPS9;
|
|
99349
|
+
const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <= EPS9;
|
|
99202
99350
|
if (previousIsVertical === nextIsVertical) return null;
|
|
99203
99351
|
const indices = previousIsVertical ? [cornerIndex - 1, cornerIndex] : [cornerIndex, cornerIndex + 1];
|
|
99204
99352
|
return indices;
|
|
@@ -99235,7 +99383,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
|
|
|
99235
99383
|
label.height
|
|
99236
99384
|
);
|
|
99237
99385
|
const labelBounds = getRectBounds(center, label.width, label.height);
|
|
99238
|
-
const collidingChipBounds = this.inputProblem.chips.map((chip) => getRectBounds(chip.center, chip.width, chip.height)).filter((chipBounds) =>
|
|
99386
|
+
const collidingChipBounds = this.inputProblem.chips.map((chip) => getRectBounds(chip.center, chip.width, chip.height)).filter((chipBounds) => rectsOverlap2(labelBounds, chipBounds));
|
|
99239
99387
|
const shiftedCoordinates = /* @__PURE__ */ new Set();
|
|
99240
99388
|
for (const chipBounds of collidingChipBounds) {
|
|
99241
99389
|
shiftedCoordinates.add(chipBounds.minX - label.width / 2);
|
|
@@ -99248,7 +99396,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
|
|
|
99248
99396
|
const end = otherTrace.tracePath[i2 + 1];
|
|
99249
99397
|
if (!segmentCrossesBoundsInterior(start, end, labelBounds)) continue;
|
|
99250
99398
|
const halfLabelWidth = label.width / 2;
|
|
99251
|
-
if (Math.abs(start.x - end.x) <=
|
|
99399
|
+
if (Math.abs(start.x - end.x) <= EPS9) {
|
|
99252
99400
|
shiftedCoordinates.add(
|
|
99253
99401
|
start.x - halfLabelWidth - LABEL_TRACE_CLEARANCE3
|
|
99254
99402
|
);
|
|
@@ -99266,7 +99414,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
|
|
|
99266
99414
|
}
|
|
99267
99415
|
}
|
|
99268
99416
|
return [...shiftedCoordinates].flatMap((x2) => {
|
|
99269
|
-
if (Math.abs(x2 - corner.x) <=
|
|
99417
|
+
if (Math.abs(x2 - corner.x) <= EPS9) return [];
|
|
99270
99418
|
const reroutedTracePath = simplifyPath(
|
|
99271
99419
|
path.map(
|
|
99272
99420
|
(point6, pointIndex) => verticalPointIndices.includes(pointIndex) ? { ...point6, x: x2 } : point6
|
|
@@ -102705,7 +102853,7 @@ var candidateIsClear = ({
|
|
|
102705
102853
|
}
|
|
102706
102854
|
}
|
|
102707
102855
|
for (const obstacle of obstacles) {
|
|
102708
|
-
if (
|
|
102856
|
+
if (rectsOverlap2(candidateBounds, obstacle) && !rectsOverlap2(originalBounds, obstacle)) {
|
|
102709
102857
|
return false;
|
|
102710
102858
|
}
|
|
102711
102859
|
}
|
|
@@ -102723,7 +102871,7 @@ var candidateIsClear = ({
|
|
|
102723
102871
|
candidateOther.width,
|
|
102724
102872
|
candidateOther.height
|
|
102725
102873
|
);
|
|
102726
|
-
if (
|
|
102874
|
+
if (rectsOverlap2(candidateBounds, candidateOtherBounds) && !rectsOverlap2(originalBounds, originalOtherBounds)) {
|
|
102727
102875
|
return false;
|
|
102728
102876
|
}
|
|
102729
102877
|
}
|
|
@@ -103036,100 +103184,6 @@ var alignSameNetJunctions = ({
|
|
|
103036
103184
|
collapsedCycleCount: cycleCollapse.collapsedCycleCount
|
|
103037
103185
|
};
|
|
103038
103186
|
};
|
|
103039
|
-
var placeGroundRailLabelsAtOuterEnd = ({
|
|
103040
|
-
inputProblem,
|
|
103041
|
-
traces,
|
|
103042
|
-
netLabelPlacements
|
|
103043
|
-
}) => {
|
|
103044
|
-
const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem);
|
|
103045
|
-
const groundNetId = netConnMap.getNetConnectedToId("GND");
|
|
103046
|
-
if (!groundNetId) return netLabelPlacements;
|
|
103047
|
-
const chipMap = new Map(inputProblem.chips.map((chip) => [chip.chipId, chip]));
|
|
103048
|
-
const traceMap = Object.fromEntries(
|
|
103049
|
-
traces.map((trace) => [trace.mspPairId, trace])
|
|
103050
|
-
);
|
|
103051
|
-
const obstacles = getObstacleRects(inputProblem);
|
|
103052
|
-
const output = [...netLabelPlacements];
|
|
103053
|
-
for (const rail of traces) {
|
|
103054
|
-
if (rail.globalConnNetId !== groundNetId) continue;
|
|
103055
|
-
const [a2, b2] = rail.pins;
|
|
103056
|
-
if (a2.chipId === b2.chipId || !nearlyEqual(a2.y, b2.y) || ![a2, b2].every(
|
|
103057
|
-
(pin) => pin._facingDirection === "y-" && chipMap.get(pin.chipId)?.pins.length === 2
|
|
103058
|
-
))
|
|
103059
|
-
continue;
|
|
103060
|
-
const path = simplifyPath(rail.tracePath);
|
|
103061
|
-
if (path.length !== 4 || !isVertical2(path[0], path[1]) || !isHorizontal22(path[1], path[2]) || !isVertical2(path[2], path[3]) || path[1].y >= a2.y)
|
|
103062
|
-
continue;
|
|
103063
|
-
for (const feed of traces) {
|
|
103064
|
-
if (feed.globalConnNetId !== groundNetId) continue;
|
|
103065
|
-
const shared = feed.pins.find((pin) => rail.pinIds.includes(pin.pinId));
|
|
103066
|
-
const icPin = feed.pins.find(
|
|
103067
|
-
(pin) => !rail.pinIds.includes(pin.pinId) && (chipMap.get(pin.chipId)?.pins.length ?? 0) > 2
|
|
103068
|
-
);
|
|
103069
|
-
if (!shared || !icPin || !nearlyEqual(icPin.y, path[1].y)) continue;
|
|
103070
|
-
const outer = shared.pinId === a2.pinId ? b2 : a2;
|
|
103071
|
-
if (Math.abs(outer.x - icPin.x) <= Math.abs(shared.x - icPin.x)) continue;
|
|
103072
|
-
const anchorPoint = { x: outer.x, y: path[1].y };
|
|
103073
|
-
if (!tracePathContainsPoint(rail.tracePath, anchorPoint)) continue;
|
|
103074
|
-
for (let index2 = 0; index2 < output.length; index2++) {
|
|
103075
|
-
const label = output[index2];
|
|
103076
|
-
if (label.globalConnNetId !== groundNetId || label.orientation !== "y-" || !label.mspConnectionPairIds.some(
|
|
103077
|
-
(id) => id === feed.mspPairId || id === rail.mspPairId
|
|
103078
|
-
) || !tracePathContainsPoint(feed.tracePath, label.anchorPoint) && !tracePathContainsPoint(rail.tracePath, label.anchorPoint))
|
|
103079
|
-
continue;
|
|
103080
|
-
const center = getCenterFromAnchor(
|
|
103081
|
-
anchorPoint,
|
|
103082
|
-
label.orientation,
|
|
103083
|
-
label.width,
|
|
103084
|
-
label.height
|
|
103085
|
-
);
|
|
103086
|
-
const bounds = getRectBounds(center, label.width, label.height);
|
|
103087
|
-
if (obstacles.some((obstacle) => rectsOverlap(bounds, obstacle)) || traceCrossesBoundsInterior(bounds, traceMap) || output.some(
|
|
103088
|
-
(other, otherIndex) => otherIndex !== index2 && rectsOverlap(
|
|
103089
|
-
bounds,
|
|
103090
|
-
getRectBounds(other.center, other.width, other.height)
|
|
103091
|
-
)
|
|
103092
|
-
))
|
|
103093
|
-
continue;
|
|
103094
|
-
output[index2] = {
|
|
103095
|
-
...label,
|
|
103096
|
-
anchorPoint,
|
|
103097
|
-
center,
|
|
103098
|
-
mspConnectionPairIds: [rail.mspPairId],
|
|
103099
|
-
pinIds: [...rail.pinIds]
|
|
103100
|
-
};
|
|
103101
|
-
}
|
|
103102
|
-
}
|
|
103103
|
-
}
|
|
103104
|
-
for (let index2 = 0; index2 < output.length; index2++) {
|
|
103105
|
-
const label = output[index2];
|
|
103106
|
-
if (label.orientation !== "y-") continue;
|
|
103107
|
-
const connection = inputProblem.netConnections.find(
|
|
103108
|
-
(candidate) => candidate.isGround && candidate.netId === label.netId && candidate.pinIds.length > 2
|
|
103109
|
-
);
|
|
103110
|
-
if (!connection) continue;
|
|
103111
|
-
const anchorPoint = traces.filter((trace) => trace.globalConnNetId === label.globalConnNetId).flatMap((trace) => trace.tracePath).filter(
|
|
103112
|
-
(point6) => nearlyEqual(point6.x, label.anchorPoint.x) && point6.y < label.anchorPoint.y
|
|
103113
|
-
).sort((a2, b2) => a2.y - b2.y)[0];
|
|
103114
|
-
if (!anchorPoint) continue;
|
|
103115
|
-
const center = getCenterFromAnchor(
|
|
103116
|
-
anchorPoint,
|
|
103117
|
-
label.orientation,
|
|
103118
|
-
label.width,
|
|
103119
|
-
label.height
|
|
103120
|
-
);
|
|
103121
|
-
const bounds = getRectBounds(center, label.width, label.height);
|
|
103122
|
-
if (obstacles.some((obstacle) => rectsOverlap(bounds, obstacle)) || traceCrossesBoundsInterior(bounds, traceMap) || output.some(
|
|
103123
|
-
(other, otherIndex) => otherIndex !== index2 && rectsOverlap(
|
|
103124
|
-
bounds,
|
|
103125
|
-
getRectBounds(other.center, other.width, other.height)
|
|
103126
|
-
)
|
|
103127
|
-
))
|
|
103128
|
-
continue;
|
|
103129
|
-
output[index2] = { ...label, anchorPoint, center };
|
|
103130
|
-
}
|
|
103131
|
-
return output;
|
|
103132
|
-
};
|
|
103133
103187
|
var MAX_LOCAL_RAIL_SHIFT = 0.5;
|
|
103134
103188
|
var MIN_ESCAPE_LENGTH = 1;
|
|
103135
103189
|
var shortenSameSideRailToLabelAnchor = ({
|
|
@@ -118287,7 +118341,7 @@ function Group_getRoutingPhasePlans(group) {
|
|
|
118287
118341
|
var package_default = {
|
|
118288
118342
|
name: "@tscircuit/core",
|
|
118289
118343
|
type: "module",
|
|
118290
|
-
version: "0.0.
|
|
118344
|
+
version: "0.0.2119",
|
|
118291
118345
|
types: "dist/index.d.ts",
|
|
118292
118346
|
main: "dist/index.js",
|
|
118293
118347
|
module: "dist/index.js",
|
|
@@ -118346,9 +118400,9 @@ var package_default = {
|
|
|
118346
118400
|
"@tscircuit/miniflex": "^0.0.4",
|
|
118347
118401
|
"@tscircuit/modelprinter": "^0.0.18",
|
|
118348
118402
|
"@tscircuit/ngspice-spice-engine": "^0.0.20",
|
|
118349
|
-
"@tscircuit/props": "^0.0.
|
|
118403
|
+
"@tscircuit/props": "^0.0.698",
|
|
118350
118404
|
"@tscircuit/schematic-match-adapt": "^0.0.18",
|
|
118351
|
-
"@tscircuit/schematic-trace-solver": "https://jscdn.tscircuit.com/@tscircuit/schematic-trace-solver/0.0.
|
|
118405
|
+
"@tscircuit/schematic-trace-solver": "https://jscdn.tscircuit.com/@tscircuit/schematic-trace-solver/0.0.230.tgz",
|
|
118352
118406
|
"@tscircuit/solver-utils": "^0.0.16",
|
|
118353
118407
|
"@tscircuit/soup-util": "^0.0.41",
|
|
118354
118408
|
"@tscircuit/via-stitch-solver": "github:tscircuit/via-stitch-solver#64f2ac7781b795bdc0d74ba411988e60767fa653",
|
|
@@ -118430,7 +118484,7 @@ var package_default = {
|
|
|
118430
118484
|
},
|
|
118431
118485
|
overrides: {
|
|
118432
118486
|
"@tscircuit/circuit-json-util": "^0.0.119",
|
|
118433
|
-
"@tscircuit/props": "^0.0.
|
|
118487
|
+
"@tscircuit/props": "^0.0.698",
|
|
118434
118488
|
"circuit-json": "^0.0.525",
|
|
118435
118489
|
"@tscircuit/cableprinter": "^0.0.6"
|
|
118436
118490
|
}
|
|
@@ -133037,6 +133091,49 @@ var AnalogSweepParameter = class extends PrimitiveComponent2 {
|
|
|
133037
133091
|
}
|
|
133038
133092
|
};
|
|
133039
133093
|
|
|
133094
|
+
// lib/components/primitive-components/PcbReturnCurrentSimulation.ts
|
|
133095
|
+
import { pcbReturnCurrentSimulationProps } from "@tscircuit/props";
|
|
133096
|
+
var PcbReturnCurrentSimulation = class extends PrimitiveComponent2 {
|
|
133097
|
+
simulation_experiment_id = null;
|
|
133098
|
+
get config() {
|
|
133099
|
+
return {
|
|
133100
|
+
componentName: "PcbReturnCurrentSimulation",
|
|
133101
|
+
zodProps: pcbReturnCurrentSimulationProps
|
|
133102
|
+
};
|
|
133103
|
+
}
|
|
133104
|
+
doInitialSimulationRender() {
|
|
133105
|
+
if (this.root?.pcbDisabled) return;
|
|
133106
|
+
if (this.parent?.componentName === "PcbReturnCurrentSimulation") {
|
|
133107
|
+
this.renderError(
|
|
133108
|
+
"A PCB return-current simulation cannot contain another simulation."
|
|
133109
|
+
);
|
|
133110
|
+
}
|
|
133111
|
+
if (this.children.some(
|
|
133112
|
+
(child) => child.componentName !== "PcbReturnCurrentExcitation"
|
|
133113
|
+
)) {
|
|
133114
|
+
this.renderError(
|
|
133115
|
+
"A PCB return-current simulation can contain only return-current excitations."
|
|
133116
|
+
);
|
|
133117
|
+
}
|
|
133118
|
+
const experiment = this.root.db.simulation_experiment.insert({
|
|
133119
|
+
name: this._parsedProps.name ?? "PCB return current",
|
|
133120
|
+
experiment_type: "pcb_return_current"
|
|
133121
|
+
});
|
|
133122
|
+
this.simulation_experiment_id = experiment.simulation_experiment_id;
|
|
133123
|
+
}
|
|
133124
|
+
updateSimulationRender() {
|
|
133125
|
+
if (!this.simulation_experiment_id) return;
|
|
133126
|
+
this.root.db.simulation_experiment.update(this.simulation_experiment_id, {
|
|
133127
|
+
name: this._parsedProps.name ?? "PCB return current"
|
|
133128
|
+
});
|
|
133129
|
+
}
|
|
133130
|
+
removeSimulationRender() {
|
|
133131
|
+
if (!this.simulation_experiment_id) return;
|
|
133132
|
+
this.root.db.simulation_experiment.delete(this.simulation_experiment_id);
|
|
133133
|
+
this.simulation_experiment_id = null;
|
|
133134
|
+
}
|
|
133135
|
+
};
|
|
133136
|
+
|
|
133040
133137
|
// lib/components/primitive-components/VoltageProbe.ts
|
|
133041
133138
|
import { voltageProbeProps } from "@tscircuit/props";
|
|
133042
133139
|
|
|
@@ -134491,6 +134588,13 @@ var enclosure = {
|
|
|
134491
134588
|
}
|
|
134492
134589
|
};
|
|
134493
134590
|
|
|
134591
|
+
// lib/namespaced-elements/simulation.ts
|
|
134592
|
+
var simulation = {
|
|
134593
|
+
pcbreturncurrentsimulation: createNamespacedElement(
|
|
134594
|
+
"pcbreturncurrentsimulation"
|
|
134595
|
+
)
|
|
134596
|
+
};
|
|
134597
|
+
|
|
134494
134598
|
// lib/RootCircuit.ts
|
|
134495
134599
|
var RootCircuit = class extends IsolatedCircuit {
|
|
134496
134600
|
isRootCircuit = true;
|
|
@@ -134808,6 +134912,7 @@ export {
|
|
|
134808
134912
|
PcbNotePath,
|
|
134809
134913
|
PcbNoteRect,
|
|
134810
134914
|
PcbNoteText,
|
|
134915
|
+
PcbReturnCurrentSimulation,
|
|
134811
134916
|
PcbSoldermaskOpening,
|
|
134812
134917
|
PcbStiffener,
|
|
134813
134918
|
PcbTrace,
|
|
@@ -134879,6 +134984,7 @@ export {
|
|
|
134879
134984
|
renderPhaseIndexMap,
|
|
134880
134985
|
resolveStaticFileImport,
|
|
134881
134986
|
sel,
|
|
134987
|
+
simulation,
|
|
134882
134988
|
unrouteCircuitJson,
|
|
134883
134989
|
useCapacitor,
|
|
134884
134990
|
useChip,
|