@tscircuit/schematic-trace-solver 0.0.114 → 0.0.115
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 -8
- package/dist/index.js +17 -3
- package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/SchematicTraceSingleLineSolver2.ts +9 -9
- package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect.ts +25 -9
- package/package.json +2 -2
- package/tests/bug-reports/bug-report-20260721T221026Z/__snapshots__/bug-report-20260721T221026Z.snap.svg +1 -1
- package/tests/repros/__snapshots__/repro-type-c-16pin-self-connection.snap.svg +54 -0
- package/tests/repros/__snapshots__/repro-type-c-16pin-to-resistor.snap.svg +56 -0
- package/tests/repros/__snapshots__/repro48-555-timer-vcc-rail-label.snap.svg +87 -0
- package/tests/repros/assets/repro48-555-timer-vcc-rail-label.input.json +276 -0
- package/tests/repros/repro-type-c-16pin-self-connection.test.ts +97 -0
- package/tests/repros/repro-type-c-16pin-to-resistor.test.ts +120 -0
- package/tests/repros/repro48-555-timer-vcc-rail-label.test.ts +23 -0
- package/tests/solvers/SchematicTraceSingleLineSolver2/text-box-obstacle-gap.test.ts +43 -0
package/dist/index.d.ts
CHANGED
|
@@ -146,17 +146,11 @@ type RectPadding = {
|
|
|
146
146
|
maxY?: number;
|
|
147
147
|
};
|
|
148
148
|
|
|
149
|
-
type
|
|
150
|
-
minX: number;
|
|
151
|
-
minY: number;
|
|
152
|
-
maxX: number;
|
|
153
|
-
maxY: number;
|
|
154
|
-
};
|
|
155
|
-
type ChipObstacleRect = RectBounds & {
|
|
149
|
+
type ChipObstacleRect = Bounds & {
|
|
156
150
|
kind: "chip";
|
|
157
151
|
chipId: string;
|
|
158
152
|
};
|
|
159
|
-
type TextBoxObstacleRect =
|
|
153
|
+
type TextBoxObstacleRect = Bounds & {
|
|
160
154
|
kind: "text_box";
|
|
161
155
|
textBox: NonNullable<InputProblem["textBoxes"]>[number];
|
|
162
156
|
};
|
package/dist/index.js
CHANGED
|
@@ -1116,6 +1116,9 @@ var generateInternalSegmentCollisionDetours = ({
|
|
|
1116
1116
|
]).filter(hasOnlyNonzeroOrthogonalSegments);
|
|
1117
1117
|
};
|
|
1118
1118
|
|
|
1119
|
+
// lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect.ts
|
|
1120
|
+
import { boundsDistance } from "@tscircuit/math-utils";
|
|
1121
|
+
|
|
1119
1122
|
// lib/solvers/GuidelinesSolver/getInputChipBounds.ts
|
|
1120
1123
|
function getInputChipBounds(chip) {
|
|
1121
1124
|
const halfWidth = chip.width / 2;
|
|
@@ -1129,6 +1132,7 @@ function getInputChipBounds(chip) {
|
|
|
1129
1132
|
}
|
|
1130
1133
|
|
|
1131
1134
|
// lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect.ts
|
|
1135
|
+
var MIN_ROUTABLE_OBSTACLE_GAP = 0.05;
|
|
1132
1136
|
var isTextBoxObstacle = (obstacle) => obstacle.kind === "text_box";
|
|
1133
1137
|
var chipToRect = (chip) => {
|
|
1134
1138
|
const b = getInputChipBounds(chip);
|
|
@@ -1137,7 +1141,17 @@ var chipToRect = (chip) => {
|
|
|
1137
1141
|
var getObstacleRects = (problem, opts = {}) => {
|
|
1138
1142
|
const chipRects = problem.chips.map(chipToRect);
|
|
1139
1143
|
const textBoxRects = (problem.textBoxes ?? []).map((textBox) => {
|
|
1140
|
-
const
|
|
1144
|
+
const textBounds = getTextBoxBounds(textBox, opts.textBoxPadding);
|
|
1145
|
+
const attachedChipBounds = chipRects.find(
|
|
1146
|
+
(chip) => chip.chipId === textBox.chipId
|
|
1147
|
+
);
|
|
1148
|
+
const gap = attachedChipBounds ? boundsDistance(textBounds, attachedChipBounds) : Number.POSITIVE_INFINITY;
|
|
1149
|
+
const b = attachedChipBounds && gap > 0 && gap < MIN_ROUTABLE_OBSTACLE_GAP ? {
|
|
1150
|
+
minX: Math.min(textBounds.minX, attachedChipBounds.maxX),
|
|
1151
|
+
maxX: Math.max(textBounds.maxX, attachedChipBounds.minX),
|
|
1152
|
+
minY: Math.min(textBounds.minY, attachedChipBounds.maxY),
|
|
1153
|
+
maxY: Math.max(textBounds.maxY, attachedChipBounds.minY)
|
|
1154
|
+
} : textBounds;
|
|
1141
1155
|
return {
|
|
1142
1156
|
kind: "text_box",
|
|
1143
1157
|
textBox,
|
|
@@ -1207,9 +1221,9 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
1207
1221
|
this.textObstacles = new Set(this.obstacles.filter(isTextBoxObstacle));
|
|
1208
1222
|
const endpointChipIds = new Set(this.pins.map((pin) => pin.chipId));
|
|
1209
1223
|
this.endpointTextObstacles = new Set(
|
|
1210
|
-
|
|
1224
|
+
this.obstacles.filter(isTextBoxObstacle).filter(
|
|
1211
1225
|
(obstacle) => obstacle.textBox.chipId !== void 0 && endpointChipIds.has(obstacle.textBox.chipId)
|
|
1212
|
-
)
|
|
1226
|
+
)
|
|
1213
1227
|
);
|
|
1214
1228
|
const [pin1, pin2] = this.pins;
|
|
1215
1229
|
const directShortPath = calculateDirectShortPath(pin1, pin2);
|
|
@@ -123,16 +123,16 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
|
|
|
123
123
|
})
|
|
124
124
|
this.textObstacles = new Set(this.obstacles.filter(isTextBoxObstacle))
|
|
125
125
|
const endpointChipIds = new Set(this.pins.map((pin) => pin.chipId))
|
|
126
|
+
// Same-chip routes also need these obstacles so they can escape around
|
|
127
|
+
// attached text after a narrow chip-to-text channel is closed.
|
|
126
128
|
this.endpointTextObstacles = new Set(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
)
|
|
135
|
-
: [],
|
|
129
|
+
this.obstacles
|
|
130
|
+
.filter(isTextBoxObstacle)
|
|
131
|
+
.filter(
|
|
132
|
+
(obstacle) =>
|
|
133
|
+
obstacle.textBox.chipId !== undefined &&
|
|
134
|
+
endpointChipIds.has(obstacle.textBox.chipId),
|
|
135
|
+
),
|
|
136
136
|
)
|
|
137
137
|
|
|
138
138
|
const [pin1, pin2] = this.pins
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
+
import { boundsDistance, type Bounds } from "@tscircuit/math-utils"
|
|
1
2
|
import { getInputChipBounds } from "lib/solvers/GuidelinesSolver/getInputChipBounds"
|
|
2
3
|
import type { InputChip, InputProblem } from "lib/types/InputProblem"
|
|
3
4
|
import { getTextBoxBounds, type RectPadding } from "lib/utils/textBoxBounds"
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
6
|
+
// Component text is normally placed 0.04 units from its chip. A trace
|
|
7
|
+
// centerline can fit mathematically, but its rendered stroke cannot usefully
|
|
8
|
+
// occupy that channel.
|
|
9
|
+
const MIN_ROUTABLE_OBSTACLE_GAP = 0.05
|
|
10
|
+
|
|
11
|
+
export type { Bounds as RectBounds } from "@tscircuit/math-utils"
|
|
11
12
|
|
|
12
|
-
export type ChipObstacleRect =
|
|
13
|
+
export type ChipObstacleRect = Bounds & {
|
|
13
14
|
kind: "chip"
|
|
14
15
|
chipId: string
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
export type TextBoxObstacleRect =
|
|
18
|
+
export type TextBoxObstacleRect = Bounds & {
|
|
18
19
|
kind: "text_box"
|
|
19
20
|
textBox: NonNullable<InputProblem["textBoxes"]>[number]
|
|
20
21
|
}
|
|
@@ -36,7 +37,22 @@ export const getObstacleRects = (
|
|
|
36
37
|
): ObstacleRect[] => {
|
|
37
38
|
const chipRects = problem.chips.map(chipToRect)
|
|
38
39
|
const textBoxRects = (problem.textBoxes ?? []).map((textBox) => {
|
|
39
|
-
const
|
|
40
|
+
const textBounds = getTextBoxBounds(textBox, opts.textBoxPadding)
|
|
41
|
+
const attachedChipBounds = chipRects.find(
|
|
42
|
+
(chip) => chip.chipId === textBox.chipId,
|
|
43
|
+
)
|
|
44
|
+
const gap = attachedChipBounds
|
|
45
|
+
? boundsDistance(textBounds, attachedChipBounds)
|
|
46
|
+
: Number.POSITIVE_INFINITY
|
|
47
|
+
const b =
|
|
48
|
+
attachedChipBounds && gap > 0 && gap < MIN_ROUTABLE_OBSTACLE_GAP
|
|
49
|
+
? {
|
|
50
|
+
minX: Math.min(textBounds.minX, attachedChipBounds.maxX),
|
|
51
|
+
maxX: Math.max(textBounds.maxX, attachedChipBounds.minX),
|
|
52
|
+
minY: Math.min(textBounds.minY, attachedChipBounds.maxY),
|
|
53
|
+
maxY: Math.max(textBounds.maxY, attachedChipBounds.minY),
|
|
54
|
+
}
|
|
55
|
+
: textBounds
|
|
40
56
|
return {
|
|
41
57
|
kind: "text_box" as const,
|
|
42
58
|
textBox,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/schematic-trace-solver",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.115",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "cosmos",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"devDependencies": {
|
|
14
14
|
"@biomejs/biome": "^2.2.2",
|
|
15
15
|
"@react-hook/resize-observer": "^2.0.2",
|
|
16
|
-
"@tscircuit/math-utils": "^0.0.
|
|
16
|
+
"@tscircuit/math-utils": "^0.0.36",
|
|
17
17
|
"@types/bun": "^1.2.21",
|
|
18
18
|
"bun-match-svg": "^0.0.13",
|
|
19
19
|
"calculate-elbow": "^0.0.12",
|