@tscircuit/schematic-trace-solver 0.0.188 → 0.0.189
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +23 -5
- package/lib/solvers/InlineNetLabelSolver/InlineNetLabelSolver.ts +1 -0
- package/lib/solvers/InlineNetLabelSolver/getAnchoredNetLabelRenderedBounds.ts +13 -0
- package/lib/solvers/NetLabelNetLabelCollisionSolver/NetLabelNetLabelCollisionSolver.ts +11 -2
- package/lib/solvers/SameNetJunctionAlignmentSolver/alignSameNetJunctions.ts +7 -7
- package/lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts +5 -1
- package/package.json +1 -1
- package/site/SchematicTracePipelineSolver/repro-robot-controller-imu-tof.page.tsx +7 -0
- package/tests/bug-reports/bug-report-20260730T061837Z/__snapshots__/bug-report-20260730T061837Z.snap.svg +2 -2
- package/tests/repros/__snapshots__/repro-robot-controller-imu-tof.snap.svg +199 -0
- package/tests/repros/__snapshots__/repro-robot-controller-imu-tof.source.svg +33 -0
- package/tests/repros/__snapshots__/rp2040-robot-controller-disconnected-gnd.snap.svg +103 -0
- package/tests/repros/assets/repro-robot-controller-imu-tof.input.json +540 -0
- package/tests/repros/assets/rp2040-robot-controller.input.json +349 -0
- package/tests/repros/repro-robot-controller-imu-tof.test.ts +83 -0
- package/tests/repros/rp2040-robot-controller-disconnected-gnd.test.ts +59 -0
- package/tests/solvers/InlineNetLabelSolver/get-anchored-net-label-rendered-bounds.test.ts +24 -0
- package/tests/solvers/TraceCleanupSolver/perpendicular-detours-preserve-endpoints.test.ts +60 -0
package/dist/index.d.ts
CHANGED
|
@@ -1148,6 +1148,8 @@ interface NetLabelNetLabelCollisionSolverParams {
|
|
|
1148
1148
|
useRenderedLabelBounds?: boolean;
|
|
1149
1149
|
/** Already placed labels that are obstacles, but must not be moved. */
|
|
1150
1150
|
fixedNetLabelPlacements?: NetLabelPlacement[];
|
|
1151
|
+
/** Existing connector identities from AvailableNetOrientationSolver. */
|
|
1152
|
+
netLabelConnectorTraceIds?: ReadonlySet<MspConnectionPairId>;
|
|
1151
1153
|
inputProblem: InputProblem;
|
|
1152
1154
|
traces: SolvedTracePath[];
|
|
1153
1155
|
netLabelPlacements: NetLabelPlacement[];
|
package/dist/index.js
CHANGED
|
@@ -7005,13 +7005,15 @@ var generatePerpendicularTraceDetours = ({
|
|
|
7005
7005
|
bounds2[highBound] + clearance
|
|
7006
7006
|
])
|
|
7007
7007
|
].filter((coordinate) => coordinate !== void 0);
|
|
7008
|
+
const remainingPath = path.slice(index + 2);
|
|
7009
|
+
if (remainingPath.length === 0) remainingPath.push(end);
|
|
7008
7010
|
return [...new Set(detourCoordinates)].map(
|
|
7009
7011
|
(detour) => simplifyPath([
|
|
7010
7012
|
...path.slice(0, index + 1),
|
|
7011
7013
|
{ ...start, [movingAxis]: gate },
|
|
7012
7014
|
{ ...start, [movingAxis]: gate, [detourAxis]: detour },
|
|
7013
7015
|
{ ...end, [detourAxis]: detour },
|
|
7014
|
-
...
|
|
7016
|
+
...remainingPath
|
|
7015
7017
|
])
|
|
7016
7018
|
);
|
|
7017
7019
|
};
|
|
@@ -12403,6 +12405,17 @@ globalConnNetId: ${label.globalConnNetId}`
|
|
|
12403
12405
|
// lib/solvers/InlineNetLabelSolver/getAnchoredNetLabelRenderedBounds.ts
|
|
12404
12406
|
var getAnchoredNetLabelRenderedBounds = (placement) => {
|
|
12405
12407
|
if (placement.orientation !== "x-" && placement.orientation !== "x+") {
|
|
12408
|
+
if (placement.netLabelText && placement.width > placement.height) {
|
|
12409
|
+
const width2 = placement.height;
|
|
12410
|
+
const height2 = placement.width;
|
|
12411
|
+
const center2 = getCenterFromAnchor(
|
|
12412
|
+
placement.anchorPoint,
|
|
12413
|
+
placement.orientation,
|
|
12414
|
+
width2,
|
|
12415
|
+
height2
|
|
12416
|
+
);
|
|
12417
|
+
return getRectBounds(center2, width2, height2);
|
|
12418
|
+
}
|
|
12406
12419
|
return getRectBounds(placement.center, placement.width, placement.height);
|
|
12407
12420
|
}
|
|
12408
12421
|
const width = Math.max(placement.width, placement.height);
|
|
@@ -12565,8 +12578,10 @@ var NetLabelNetLabelCollisionSolver = class extends BaseSolver {
|
|
|
12565
12578
|
status: null
|
|
12566
12579
|
};
|
|
12567
12580
|
};
|
|
12568
|
-
const
|
|
12569
|
-
|
|
12581
|
+
const isAnchoredOnConnector = this.traces.some(
|
|
12582
|
+
(trace) => this.params.netLabelConnectorTraceIds?.has(trace.mspPairId) && trace.globalConnNetId === label.globalConnNetId && tracePathContainsPoint(trace.tracePath, label.anchorPoint)
|
|
12583
|
+
);
|
|
12584
|
+
if (label.mspConnectionPairIds.length === 0 || isAnchoredOnConnector) {
|
|
12570
12585
|
const allOrientations = ["x+", "x-", "y+", "y-"];
|
|
12571
12586
|
const orderedOrientations = [
|
|
12572
12587
|
label.orientation,
|
|
@@ -13659,8 +13674,10 @@ var getHorizontalPinApproachPoint = ({
|
|
|
13659
13674
|
return approachesFromFacingSide ? approachPoint : null;
|
|
13660
13675
|
};
|
|
13661
13676
|
var getAttachedLabelIndexes = (trace, netLabelPlacements) => netLabelPlacements.flatMap((label, index) => {
|
|
13662
|
-
|
|
13663
|
-
|
|
13677
|
+
if (isLabelAttachedToTrace(label, trace) && tracePathContainsPoint(trace.tracePath, label.anchorPoint)) {
|
|
13678
|
+
return [index];
|
|
13679
|
+
}
|
|
13680
|
+
return [];
|
|
13664
13681
|
});
|
|
13665
13682
|
var moveAttachedLabels = ({
|
|
13666
13683
|
trace,
|
|
@@ -17098,6 +17115,7 @@ var InlineNetLabelSolver = class _InlineNetLabelSolver extends BaseSolver {
|
|
|
17098
17115
|
traces: [...outputTraces, ...terminalTraces],
|
|
17099
17116
|
netLabelPlacements: retainedNetLabelPlacements,
|
|
17100
17117
|
fixedNetLabelPlacements: fixedLabels,
|
|
17118
|
+
netLabelConnectorTraceIds: this.netLabelConnectorTraceIds,
|
|
17101
17119
|
useRenderedLabelBounds: activeInlinePlacements.length > 0
|
|
17102
17120
|
});
|
|
17103
17121
|
if (activeInlinePlacements.length > 0) labelCollisionSolver.solve();
|
|
@@ -1193,6 +1193,7 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
1193
1193
|
traces: [...outputTraces, ...terminalTraces],
|
|
1194
1194
|
netLabelPlacements: retainedNetLabelPlacements,
|
|
1195
1195
|
fixedNetLabelPlacements: fixedLabels,
|
|
1196
|
+
netLabelConnectorTraceIds: this.netLabelConnectorTraceIds,
|
|
1196
1197
|
useRenderedLabelBounds: activeInlinePlacements.length > 0,
|
|
1197
1198
|
})
|
|
1198
1199
|
if (activeInlinePlacements.length > 0) labelCollisionSolver.solve()
|
|
@@ -19,6 +19,19 @@ export const getAnchoredNetLabelRenderedBounds = (
|
|
|
19
19
|
placement: NetLabelPlacement,
|
|
20
20
|
): Bounds => {
|
|
21
21
|
if (placement.orientation !== "x-" && placement.orientation !== "x+") {
|
|
22
|
+
// Named vertical tags render their long text extent along y. Width-only
|
|
23
|
+
// placeholders retain the supplied envelope instead.
|
|
24
|
+
if (placement.netLabelText && placement.width > placement.height) {
|
|
25
|
+
const width = placement.height
|
|
26
|
+
const height = placement.width
|
|
27
|
+
const center = getCenterFromAnchor(
|
|
28
|
+
placement.anchorPoint,
|
|
29
|
+
placement.orientation,
|
|
30
|
+
width,
|
|
31
|
+
height,
|
|
32
|
+
)
|
|
33
|
+
return getRectBounds(center, width, height)
|
|
34
|
+
}
|
|
22
35
|
return getRectBounds(placement.center, placement.width, placement.height)
|
|
23
36
|
}
|
|
24
37
|
|
|
@@ -2,6 +2,7 @@ import { getAnchoredNetLabelRenderedBounds } from "../InlineNetLabelSolver/getAn
|
|
|
2
2
|
import type { GraphicsObject } from "graphics-debug"
|
|
3
3
|
import { BaseSolver } from "lib/solvers/BaseSolver/BaseSolver"
|
|
4
4
|
import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
|
|
5
|
+
import { tracePathContainsPoint } from "lib/solvers/RailNetLabelCornerPlacementSolver/geometry"
|
|
5
6
|
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
6
7
|
import type { MspConnectionPairId } from "lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver"
|
|
7
8
|
import type { InputProblem } from "lib/types/InputProblem"
|
|
@@ -96,6 +97,8 @@ export interface NetLabelNetLabelCollisionSolverParams {
|
|
|
96
97
|
useRenderedLabelBounds?: boolean
|
|
97
98
|
/** Already placed labels that are obstacles, but must not be moved. */
|
|
98
99
|
fixedNetLabelPlacements?: NetLabelPlacement[]
|
|
100
|
+
/** Existing connector identities from AvailableNetOrientationSolver. */
|
|
101
|
+
netLabelConnectorTraceIds?: ReadonlySet<MspConnectionPairId>
|
|
99
102
|
inputProblem: InputProblem
|
|
100
103
|
traces: SolvedTracePath[]
|
|
101
104
|
netLabelPlacements: NetLabelPlacement[]
|
|
@@ -245,9 +248,15 @@ export class NetLabelNetLabelCollisionSolver extends BaseSolver {
|
|
|
245
248
|
}
|
|
246
249
|
}
|
|
247
250
|
|
|
248
|
-
|
|
251
|
+
// A label on an extended connector must keep that attachment point.
|
|
252
|
+
const isAnchoredOnConnector = this.traces.some(
|
|
253
|
+
(trace) =>
|
|
254
|
+
this.params.netLabelConnectorTraceIds?.has(trace.mspPairId) &&
|
|
255
|
+
trace.globalConnNetId === label.globalConnNetId &&
|
|
256
|
+
tracePathContainsPoint(trace.tracePath, label.anchorPoint),
|
|
257
|
+
)
|
|
249
258
|
|
|
250
|
-
if (
|
|
259
|
+
if (label.mspConnectionPairIds.length === 0 || isAnchoredOnConnector) {
|
|
251
260
|
const allOrientations: FacingDirection[] = ["x+", "x-", "y+", "y-"]
|
|
252
261
|
const orderedOrientations = [
|
|
253
262
|
label.orientation,
|
|
@@ -8,6 +8,7 @@ import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/Sche
|
|
|
8
8
|
import { isPathCollidingWithObstacles } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/collisions"
|
|
9
9
|
import { getObstacleRects } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect"
|
|
10
10
|
import { getMovedAnchorPointForReroute } from "lib/solvers/Example28Solver/getMovedAnchorPointForReroute"
|
|
11
|
+
import { isLabelAttachedToTrace } from "lib/solvers/Example28Solver/isLabelAttachedToTrace"
|
|
11
12
|
import { moveAttachedLabelsToReroutedTrace } from "lib/solvers/Example28Solver/labelMovement"
|
|
12
13
|
import {
|
|
13
14
|
rectsOverlap,
|
|
@@ -182,14 +183,13 @@ const getAttachedLabelIndexes = (
|
|
|
182
183
|
netLabelPlacements: NetLabelPlacement[],
|
|
183
184
|
) =>
|
|
184
185
|
netLabelPlacements.flatMap((label, index) => {
|
|
185
|
-
|
|
186
|
-
label
|
|
187
|
-
(label.mspConnectionPairIds.length === 0 &&
|
|
188
|
-
label.globalConnNetId === trace.globalConnNetId)
|
|
189
|
-
return labelOwnsTrace &&
|
|
186
|
+
if (
|
|
187
|
+
isLabelAttachedToTrace(label, trace) &&
|
|
190
188
|
tracePathContainsPoint(trace.tracePath, label.anchorPoint)
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
) {
|
|
190
|
+
return [index]
|
|
191
|
+
}
|
|
192
|
+
return []
|
|
193
193
|
})
|
|
194
194
|
|
|
195
195
|
const moveAttachedLabels = ({
|
|
@@ -232,13 +232,17 @@ export const generatePerpendicularTraceDetours = ({
|
|
|
232
232
|
]),
|
|
233
233
|
].filter((coordinate): coordinate is number => coordinate !== undefined)
|
|
234
234
|
|
|
235
|
+
const remainingPath = path.slice(index + 2)
|
|
236
|
+
// A terminal segment has no following leg to reconnect the detour.
|
|
237
|
+
if (remainingPath.length === 0) remainingPath.push(end)
|
|
238
|
+
|
|
235
239
|
return [...new Set(detourCoordinates)].map((detour) =>
|
|
236
240
|
simplifyPath([
|
|
237
241
|
...path.slice(0, index + 1),
|
|
238
242
|
{ ...start, [movingAxis]: gate },
|
|
239
243
|
{ ...start, [movingAxis]: gate, [detourAxis]: detour },
|
|
240
244
|
{ ...end, [detourAxis]: detour },
|
|
241
|
-
...
|
|
245
|
+
...remainingPath,
|
|
242
246
|
]),
|
|
243
247
|
)
|
|
244
248
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PipelineDebugger } from "site/components/PipelineDebugger"
|
|
2
|
+
import type { InputProblem } from "lib/types/InputProblem"
|
|
3
|
+
import inputProblem from "../../tests/repros/assets/repro-robot-controller-imu-tof.input.json"
|
|
4
|
+
|
|
5
|
+
export default () => (
|
|
6
|
+
<PipelineDebugger inputProblem={inputProblem as InputProblem} />
|
|
7
|
+
)
|