@tscircuit/schematic-trace-solver 0.0.153 → 0.0.154
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.js +57 -8
- package/lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions.ts +81 -8
- package/package.json +1 -1
- package/site/bug-reports/bug-report-20260825T103621Z.page.tsx +4 -0
- package/tests/bug-reports/bug-report-20260825T103621Z/__snapshots__/bug-report-20260825T103621Z.snap.svg +452 -0
- package/tests/bug-reports/bug-report-20260825T103621Z/bug-report-20260825T103621Z.json +1696 -0
- package/tests/bug-reports/bug-report-20260825T103621Z/bug-report-20260825T103621Z.test.ts +12 -0
- package/tests/repros/__snapshots__/repro-pga300-c6-trace-alignment.snap.svg +88 -0
- package/tests/repros/assets/repro-pga300-c6-trace-alignment.input.json +97 -0
- package/tests/repros/repro-pga300-c6-trace-alignment.test.ts +36 -0
package/dist/index.js
CHANGED
|
@@ -12139,6 +12139,7 @@ var pathEntersAnyNetLabel = ({
|
|
|
12139
12139
|
// lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions.ts
|
|
12140
12140
|
var MAX_ALIGNED_LOAD_PIN_OFFSET = 0.2;
|
|
12141
12141
|
var MAX_SAME_NET_LABEL_BOUNDARY_RAIL_OFFSET = 0.2;
|
|
12142
|
+
var MAX_SHARED_PIN_RAIL_OFFSET = 0.05;
|
|
12142
12143
|
var getSharedPin = ({
|
|
12143
12144
|
donorTrace,
|
|
12144
12145
|
branchTrace
|
|
@@ -12178,6 +12179,28 @@ var railIsOnFacingSide = ({
|
|
|
12178
12179
|
if (pin._facingDirection === "y+") return railY > pin.y;
|
|
12179
12180
|
return false;
|
|
12180
12181
|
};
|
|
12182
|
+
var railIsOnSharedPinFacingSide = ({
|
|
12183
|
+
railY,
|
|
12184
|
+
pin
|
|
12185
|
+
}) => {
|
|
12186
|
+
if (pin._facingDirection === "y+") return railY > pin.y;
|
|
12187
|
+
if (pin._facingDirection === "y-") return railY < pin.y;
|
|
12188
|
+
return false;
|
|
12189
|
+
};
|
|
12190
|
+
var getHorizontalPinApproachPoint = ({
|
|
12191
|
+
branchTrace,
|
|
12192
|
+
sharedPin,
|
|
12193
|
+
otherPin
|
|
12194
|
+
}) => {
|
|
12195
|
+
if (otherPin._facingDirection !== "x-" && otherPin._facingDirection !== "x+") {
|
|
12196
|
+
return null;
|
|
12197
|
+
}
|
|
12198
|
+
const sharedToOtherPath = branchTrace.pins[0].pinId === sharedPin.pinId ? branchTrace.tracePath : [...branchTrace.tracePath].reverse();
|
|
12199
|
+
const approachPoint = sharedToOtherPath.at(-2);
|
|
12200
|
+
if (!approachPoint || !nearlyEqual(approachPoint.y, otherPin.y)) return null;
|
|
12201
|
+
const approachesFromFacingSide = otherPin._facingDirection === "x-" ? approachPoint.x < otherPin.x : approachPoint.x > otherPin.x;
|
|
12202
|
+
return approachesFromFacingSide ? approachPoint : null;
|
|
12203
|
+
};
|
|
12181
12204
|
var getAttachedLabelIndexes = (trace, netLabelPlacements) => netLabelPlacements.flatMap((label, index) => {
|
|
12182
12205
|
const labelOwnsTrace = label.mspConnectionPairIds.includes(trace.mspPairId) || label.mspConnectionPairIds.length === 0 && label.globalConnNetId === trace.globalConnNetId;
|
|
12183
12206
|
return labelOwnsTrace && tracePathContainsPoint(trace.tracePath, label.anchorPoint) ? [index] : [];
|
|
@@ -12226,19 +12249,45 @@ var getAlignedBranchPath = ({
|
|
|
12226
12249
|
if (branchRail && nearlyEqual(branchRail.start.y, donorRail.start.y)) {
|
|
12227
12250
|
return null;
|
|
12228
12251
|
}
|
|
12229
|
-
|
|
12252
|
+
const railFacesOtherPin = railIsOnFacingSide({
|
|
12253
|
+
railY: donorRail.start.y,
|
|
12254
|
+
pin: otherPin
|
|
12255
|
+
});
|
|
12256
|
+
const railFacesSharedPin = railIsOnSharedPinFacingSide({
|
|
12257
|
+
railY: donorRail.start.y,
|
|
12258
|
+
pin: sharedPin
|
|
12259
|
+
}) && Math.abs(donorRail.start.y - sharedPin.y) <= MAX_SHARED_PIN_RAIL_OFFSET;
|
|
12260
|
+
if (!railFacesOtherPin && !railFacesSharedPin) {
|
|
12230
12261
|
return null;
|
|
12231
12262
|
}
|
|
12232
12263
|
const junction = getJunctionPoint({ segment: donorRail, sharedPin });
|
|
12233
12264
|
const extendsDonorRail = donorOtherPin.x < junction.x && otherPin.x > junction.x || donorOtherPin.x > junction.x && otherPin.x < junction.x;
|
|
12234
12265
|
if (!extendsDonorRail) return null;
|
|
12235
|
-
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
|
|
12239
|
-
|
|
12240
|
-
|
|
12241
|
-
|
|
12266
|
+
let sharedToOther;
|
|
12267
|
+
if (!railFacesOtherPin && railFacesSharedPin) {
|
|
12268
|
+
const approachPoint = getHorizontalPinApproachPoint({
|
|
12269
|
+
branchTrace,
|
|
12270
|
+
sharedPin,
|
|
12271
|
+
otherPin
|
|
12272
|
+
});
|
|
12273
|
+
if (!approachPoint) return null;
|
|
12274
|
+
sharedToOther = simplifyPath([
|
|
12275
|
+
{ x: sharedPin.x, y: sharedPin.y },
|
|
12276
|
+
{ x: junction.x, y: sharedPin.y },
|
|
12277
|
+
{ x: junction.x, y: junction.y },
|
|
12278
|
+
{ x: approachPoint.x, y: junction.y },
|
|
12279
|
+
{ x: approachPoint.x, y: otherPin.y },
|
|
12280
|
+
{ x: otherPin.x, y: otherPin.y }
|
|
12281
|
+
]);
|
|
12282
|
+
} else {
|
|
12283
|
+
sharedToOther = simplifyPath([
|
|
12284
|
+
{ x: sharedPin.x, y: sharedPin.y },
|
|
12285
|
+
{ x: junction.x, y: sharedPin.y },
|
|
12286
|
+
{ x: junction.x, y: junction.y },
|
|
12287
|
+
{ x: otherPin.x, y: junction.y },
|
|
12288
|
+
{ x: otherPin.x, y: otherPin.y }
|
|
12289
|
+
]);
|
|
12290
|
+
}
|
|
12242
12291
|
if (branchTrace.pins[0].pinId === sharedPin.pinId) return sharedToOther;
|
|
12243
12292
|
return [...sharedToOther].reverse();
|
|
12244
12293
|
};
|
|
@@ -34,6 +34,9 @@ interface HorizontalSegment {
|
|
|
34
34
|
const MAX_ALIGNED_LOAD_PIN_OFFSET = 0.2
|
|
35
35
|
// Limit label-boundary alignment to small corrections that cannot create spikes.
|
|
36
36
|
const MAX_SAME_NET_LABEL_BOUNDARY_RAIL_OFFSET = 0.2
|
|
37
|
+
// A shared vertical pin can anchor an existing rail when the rail is only a
|
|
38
|
+
// symbol-stem correction away from the pin itself.
|
|
39
|
+
const MAX_SHARED_PIN_RAIL_OFFSET = 0.05
|
|
37
40
|
|
|
38
41
|
const getSharedPin = ({
|
|
39
42
|
donorTrace,
|
|
@@ -96,6 +99,48 @@ const railIsOnFacingSide = ({
|
|
|
96
99
|
return false
|
|
97
100
|
}
|
|
98
101
|
|
|
102
|
+
const railIsOnSharedPinFacingSide = ({
|
|
103
|
+
railY,
|
|
104
|
+
pin,
|
|
105
|
+
}: {
|
|
106
|
+
railY: number
|
|
107
|
+
pin: InputPin
|
|
108
|
+
}) => {
|
|
109
|
+
if (pin._facingDirection === "y+") return railY > pin.y
|
|
110
|
+
if (pin._facingDirection === "y-") return railY < pin.y
|
|
111
|
+
return false
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const getHorizontalPinApproachPoint = ({
|
|
115
|
+
branchTrace,
|
|
116
|
+
sharedPin,
|
|
117
|
+
otherPin,
|
|
118
|
+
}: {
|
|
119
|
+
branchTrace: SolvedTracePath
|
|
120
|
+
sharedPin: InputPin
|
|
121
|
+
otherPin: InputPin
|
|
122
|
+
}): Point | null => {
|
|
123
|
+
if (
|
|
124
|
+
otherPin._facingDirection !== "x-" &&
|
|
125
|
+
otherPin._facingDirection !== "x+"
|
|
126
|
+
) {
|
|
127
|
+
return null
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const sharedToOtherPath =
|
|
131
|
+
branchTrace.pins[0].pinId === sharedPin.pinId
|
|
132
|
+
? branchTrace.tracePath
|
|
133
|
+
: [...branchTrace.tracePath].reverse()
|
|
134
|
+
const approachPoint = sharedToOtherPath.at(-2)
|
|
135
|
+
if (!approachPoint || !nearlyEqual(approachPoint.y, otherPin.y)) return null
|
|
136
|
+
|
|
137
|
+
const approachesFromFacingSide =
|
|
138
|
+
otherPin._facingDirection === "x-"
|
|
139
|
+
? approachPoint.x < otherPin.x
|
|
140
|
+
: approachPoint.x > otherPin.x
|
|
141
|
+
return approachesFromFacingSide ? approachPoint : null
|
|
142
|
+
}
|
|
143
|
+
|
|
99
144
|
const getAttachedLabelIndexes = (
|
|
100
145
|
trace: SolvedTracePath,
|
|
101
146
|
netLabelPlacements: NetLabelPlacement[],
|
|
@@ -165,7 +210,17 @@ const getAlignedBranchPath = ({
|
|
|
165
210
|
if (branchRail && nearlyEqual(branchRail.start.y, donorRail.start.y)) {
|
|
166
211
|
return null
|
|
167
212
|
}
|
|
168
|
-
|
|
213
|
+
const railFacesOtherPin = railIsOnFacingSide({
|
|
214
|
+
railY: donorRail.start.y,
|
|
215
|
+
pin: otherPin,
|
|
216
|
+
})
|
|
217
|
+
const railFacesSharedPin =
|
|
218
|
+
railIsOnSharedPinFacingSide({
|
|
219
|
+
railY: donorRail.start.y,
|
|
220
|
+
pin: sharedPin,
|
|
221
|
+
}) &&
|
|
222
|
+
Math.abs(donorRail.start.y - sharedPin.y) <= MAX_SHARED_PIN_RAIL_OFFSET
|
|
223
|
+
if (!railFacesOtherPin && !railFacesSharedPin) {
|
|
169
224
|
return null
|
|
170
225
|
}
|
|
171
226
|
|
|
@@ -175,13 +230,31 @@ const getAlignedBranchPath = ({
|
|
|
175
230
|
(donorOtherPin.x > junction.x && otherPin.x < junction.x)
|
|
176
231
|
if (!extendsDonorRail) return null
|
|
177
232
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
233
|
+
let sharedToOther: Point[]
|
|
234
|
+
if (!railFacesOtherPin && railFacesSharedPin) {
|
|
235
|
+
const approachPoint = getHorizontalPinApproachPoint({
|
|
236
|
+
branchTrace,
|
|
237
|
+
sharedPin,
|
|
238
|
+
otherPin,
|
|
239
|
+
})
|
|
240
|
+
if (!approachPoint) return null
|
|
241
|
+
sharedToOther = simplifyPath([
|
|
242
|
+
{ x: sharedPin.x, y: sharedPin.y },
|
|
243
|
+
{ x: junction.x, y: sharedPin.y },
|
|
244
|
+
{ x: junction.x, y: junction.y },
|
|
245
|
+
{ x: approachPoint.x, y: junction.y },
|
|
246
|
+
{ x: approachPoint.x, y: otherPin.y },
|
|
247
|
+
{ x: otherPin.x, y: otherPin.y },
|
|
248
|
+
])
|
|
249
|
+
} else {
|
|
250
|
+
sharedToOther = simplifyPath([
|
|
251
|
+
{ x: sharedPin.x, y: sharedPin.y },
|
|
252
|
+
{ x: junction.x, y: sharedPin.y },
|
|
253
|
+
{ x: junction.x, y: junction.y },
|
|
254
|
+
{ x: otherPin.x, y: junction.y },
|
|
255
|
+
{ x: otherPin.x, y: otherPin.y },
|
|
256
|
+
])
|
|
257
|
+
}
|
|
185
258
|
|
|
186
259
|
if (branchTrace.pins[0].pinId === sharedPin.pinId) return sharedToOther
|
|
187
260
|
return [...sharedToOther].reverse()
|
package/package.json
CHANGED