@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 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
- ...path.slice(index + 2)
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 isPortOnly = label.mspConnectionPairIds.length === 0;
12569
- if (isPortOnly) {
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
- const labelOwnsTrace = label.mspConnectionPairIds.includes(trace.mspPairId) || label.mspConnectionPairIds.length === 0 && label.globalConnNetId === trace.globalConnNetId;
13663
- return labelOwnsTrace && tracePathContainsPoint(trace.tracePath, label.anchorPoint) ? [index] : [];
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
- const isPortOnly = label.mspConnectionPairIds.length === 0
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 (isPortOnly) {
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
- const labelOwnsTrace =
186
- label.mspConnectionPairIds.includes(trace.mspPairId) ||
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
- ? [index]
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
- ...path.slice(index + 2),
245
+ ...remainingPath,
242
246
  ]),
243
247
  )
244
248
  }
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/tscircuit/schematic-trace-solver.git"
6
6
  },
7
7
  "main": "dist/index.js",
8
- "version": "0.0.188",
8
+ "version": "0.0.189",
9
9
  "type": "module",
10
10
  "scripts": {
11
11
  "start": "cosmos",
@@ -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
+ )