@tscircuit/schematic-trace-solver 0.0.143 → 0.0.145
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 +22 -16
- package/dist/index.js +105 -95
- package/lib/solvers/InlineNetLabelSolver/InlineNetLabelSolver.ts +70 -57
- package/lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver.ts +14 -5
- package/lib/solvers/MspConnectionPairSolver/isLabeledPeripheralConnection.ts +46 -10
- package/lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver.ts +7 -0
- package/lib/types/InputProblem.ts +7 -4
- package/package.json +1 -1
- package/tests/assets/inline-net-label-two-pin-net.json +67 -0
- package/tests/repros/__snapshots__/repro-tida010076-page02.snap.svg +10 -30
- package/tests/repros/assets/repro-tida010076-page02.input.json +2 -0
- package/tests/repros/repro-tida010076-page02.test.ts +31 -0
- package/tests/solvers/InlineNetLabelSolver/__snapshots__/inline-net-label-two-pin-net.snap.svg +57 -0
- package/tests/solvers/InlineNetLabelSolver/inline-net-label-two-pin-net.test.ts +38 -0
- package/tests/solvers/InlineNetLabelSolver/two-pin-terminal-stubs-atomic.test.ts +78 -0
- package/tests/solvers/MspConnectionPairSolver/msp-connection-pair-solver-direct-connection-distance.test.ts +80 -0
|
@@ -52,8 +52,9 @@ export interface InlineNetLabelPlacement {
|
|
|
52
52
|
pinIds: PinId[]
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* A generated single-ended trace stub. Present
|
|
56
|
-
*
|
|
55
|
+
* A generated single-ended trace stub. Present for a single-pin net or for
|
|
56
|
+
* one endpoint of an unrouted two-pin net; routed point-to-point traces omit
|
|
57
|
+
* it.
|
|
57
58
|
*/
|
|
58
59
|
stubTracePath?: [Point, Point]
|
|
59
60
|
|
|
@@ -85,12 +86,15 @@ interface InlineNetLabelSolverInput {
|
|
|
85
86
|
netLabelPlacements: NetLabelPlacement[]
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
type InlineEligibleConnection = InputDirectConnection | InputNetConnection
|
|
90
|
+
|
|
88
91
|
const getPinPairKey = (pinIds: readonly string[]) =>
|
|
89
92
|
[...pinIds].sort().join("::")
|
|
90
93
|
|
|
91
94
|
/**
|
|
92
95
|
* Places "inline net labels" - net names drawn alongside the trace they belong
|
|
93
|
-
* to - for
|
|
96
|
+
* to - for one- or two-pin connections that opted in via
|
|
97
|
+
* `allowInlineNetLabel`.
|
|
94
98
|
*
|
|
95
99
|
* Any regular (anchored) net label placement for the same net is dropped, so a
|
|
96
100
|
* net is never labeled twice.
|
|
@@ -102,11 +106,8 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
102
106
|
|
|
103
107
|
inlineNetLabelPlacements: InlineNetLabelPlacement[] = []
|
|
104
108
|
|
|
105
|
-
/**
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
/** Single-pin net connections that opted in, still waiting to be processed */
|
|
109
|
-
queuedPortOnlyNetConnections: InputNetConnection[]
|
|
109
|
+
/** Eligible one- or two-pin connections still waiting to be processed. */
|
|
110
|
+
queuedConnections: InlineEligibleConnection[]
|
|
110
111
|
|
|
111
112
|
private tracesByPinPairKey: Map<string, SolvedTracePath[]>
|
|
112
113
|
private hasAlignedPortOnlyStubs = false
|
|
@@ -117,12 +118,18 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
117
118
|
this.traces = input.traces
|
|
118
119
|
this.inputNetLabelPlacements = input.netLabelPlacements
|
|
119
120
|
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
121
|
+
this.queuedConnections = [
|
|
122
|
+
...this.inputProblem.directConnections.filter(
|
|
123
|
+
(connection) => connection.allowInlineNetLabel && connection.netId,
|
|
124
|
+
),
|
|
125
|
+
...this.inputProblem.netConnections.filter(
|
|
126
|
+
(connection) =>
|
|
127
|
+
connection.allowInlineNetLabel &&
|
|
128
|
+
connection.pinIds.length >= 1 &&
|
|
129
|
+
connection.pinIds.length <= 2 &&
|
|
130
|
+
connection.netId,
|
|
131
|
+
),
|
|
132
|
+
]
|
|
126
133
|
|
|
127
134
|
this.tracesByPinPairKey = new Map()
|
|
128
135
|
for (const trace of this.traces) {
|
|
@@ -147,22 +154,28 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
147
154
|
}
|
|
148
155
|
|
|
149
156
|
override _step() {
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
157
|
+
const connection = this.queuedConnections.shift()
|
|
158
|
+
if (connection) {
|
|
159
|
+
const routedTraces =
|
|
160
|
+
connection.pinIds.length === 2
|
|
161
|
+
? (this.tracesByPinPairKey.get(getPinPairKey(connection.pinIds)) ??
|
|
162
|
+
[])
|
|
163
|
+
: []
|
|
164
|
+
|
|
165
|
+
if (routedTraces.length > 0) {
|
|
166
|
+
const placement = this.computeInlinePlacement(connection)
|
|
167
|
+
if (placement) this.inlineNetLabelPlacements.push(placement)
|
|
168
|
+
} else {
|
|
169
|
+
// A one-pin net has one conventional endpoint label, while a skipped
|
|
170
|
+
// two-pin route has one at each endpoint. Convert a two-pin pair
|
|
171
|
+
// atomically so a collision at one endpoint cannot leave mixed inline
|
|
172
|
+
// and anchored representations for the same net.
|
|
173
|
+
const terminalPlacements = connection.pinIds.map((pinId) =>
|
|
174
|
+
this.computeTerminalInlinePlacement(connection, pinId),
|
|
175
|
+
)
|
|
176
|
+
if (terminalPlacements.every((placement) => placement !== null)) {
|
|
177
|
+
this.inlineNetLabelPlacements.push(...terminalPlacements)
|
|
178
|
+
}
|
|
166
179
|
}
|
|
167
180
|
return
|
|
168
181
|
}
|
|
@@ -183,20 +196,20 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
183
196
|
}
|
|
184
197
|
|
|
185
198
|
/**
|
|
186
|
-
* Converts
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
199
|
+
* Converts one conventional endpoint placement into an inline label on a
|
|
200
|
+
* generated outward stub. The stub follows the pin's true facing direction;
|
|
201
|
+
* an anchored label may finish in another direction after an elbow, which is
|
|
202
|
+
* not the direction a terminal stub should leave the pin.
|
|
190
203
|
*/
|
|
191
|
-
private
|
|
192
|
-
|
|
204
|
+
private computeTerminalInlinePlacement(
|
|
205
|
+
connection: InlineEligibleConnection,
|
|
206
|
+
pinId: PinId,
|
|
193
207
|
): InlineNetLabelPlacement | null {
|
|
194
|
-
|
|
195
|
-
if (!pinId) return null
|
|
208
|
+
if (!connection.netId) return null
|
|
196
209
|
|
|
197
210
|
const anchoredPlacement = this.inputNetLabelPlacements.find(
|
|
198
211
|
(placement) =>
|
|
199
|
-
placement.netId ===
|
|
212
|
+
placement.netId === connection.netId &&
|
|
200
213
|
placement.pinIds.length === 1 &&
|
|
201
214
|
placement.pinIds[0] === pinId,
|
|
202
215
|
)
|
|
@@ -208,11 +221,11 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
208
221
|
const inputPin = inputChip?.pins.find((pin) => pin.pinId === pinId)
|
|
209
222
|
|
|
210
223
|
const height =
|
|
211
|
-
|
|
224
|
+
connection.inlineNetLabelHeight ?? DEFAULT_INLINE_NET_LABEL_HEIGHT
|
|
212
225
|
const width =
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
estimateInlineNetLabelWidth(
|
|
226
|
+
connection.inlineNetLabelWidth ??
|
|
227
|
+
connection.netLabelWidth ??
|
|
228
|
+
estimateInlineNetLabelWidth(connection.netId, height)
|
|
216
229
|
|
|
217
230
|
// Leave a small wire tail at both ends of the text so it unmistakably
|
|
218
231
|
// reads as a label on a trace rather than free-standing text.
|
|
@@ -273,7 +286,7 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
273
286
|
|
|
274
287
|
return {
|
|
275
288
|
globalConnNetId: anchoredPlacement.globalConnNetId,
|
|
276
|
-
netId:
|
|
289
|
+
netId: connection.netId,
|
|
277
290
|
pinIds: [pinId],
|
|
278
291
|
stubTracePath: [start, end],
|
|
279
292
|
axis,
|
|
@@ -286,12 +299,12 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
286
299
|
}
|
|
287
300
|
|
|
288
301
|
private computeInlinePlacement(
|
|
289
|
-
|
|
302
|
+
connection: InlineEligibleConnection,
|
|
290
303
|
): InlineNetLabelPlacement | null {
|
|
291
304
|
// Only connections the router actually drew a trace for can carry an inline
|
|
292
305
|
// label - there's nothing to run parallel to otherwise.
|
|
293
306
|
const traces =
|
|
294
|
-
this.tracesByPinPairKey.get(getPinPairKey(
|
|
307
|
+
this.tracesByPinPairKey.get(getPinPairKey(connection.pinIds)) ?? []
|
|
295
308
|
if (traces.length === 0) return null
|
|
296
309
|
|
|
297
310
|
const trace = traces[0]!
|
|
@@ -299,11 +312,11 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
299
312
|
if (segments.length === 0) return null
|
|
300
313
|
|
|
301
314
|
const height =
|
|
302
|
-
|
|
315
|
+
connection.inlineNetLabelHeight ?? DEFAULT_INLINE_NET_LABEL_HEIGHT
|
|
303
316
|
const width =
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
estimateInlineNetLabelWidth(
|
|
317
|
+
connection.inlineNetLabelWidth ??
|
|
318
|
+
connection.netLabelWidth ??
|
|
319
|
+
estimateInlineNetLabelWidth(connection.netId!, height)
|
|
307
320
|
|
|
308
321
|
const offset = height / 2 + INLINE_NET_LABEL_TRACE_MARGIN
|
|
309
322
|
|
|
@@ -360,9 +373,9 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
360
373
|
|
|
361
374
|
return {
|
|
362
375
|
globalConnNetId: trace.globalConnNetId,
|
|
363
|
-
netId:
|
|
376
|
+
netId: connection.netId,
|
|
364
377
|
mspPairId: trace.mspPairId,
|
|
365
|
-
pinIds: [...
|
|
378
|
+
pinIds: [...connection.pinIds],
|
|
366
379
|
axis: segment.axis,
|
|
367
380
|
anchorPoint,
|
|
368
381
|
center,
|
|
@@ -380,7 +393,7 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
380
393
|
// endpoints.
|
|
381
394
|
const spanPlacement = this.computeSpanPlacement({
|
|
382
395
|
trace,
|
|
383
|
-
|
|
396
|
+
connection,
|
|
384
397
|
width,
|
|
385
398
|
height,
|
|
386
399
|
offset,
|
|
@@ -400,13 +413,13 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
400
413
|
*/
|
|
401
414
|
private computeSpanPlacement({
|
|
402
415
|
trace,
|
|
403
|
-
|
|
416
|
+
connection,
|
|
404
417
|
width,
|
|
405
418
|
height,
|
|
406
419
|
offset,
|
|
407
420
|
}: {
|
|
408
421
|
trace: SolvedTracePath
|
|
409
|
-
|
|
422
|
+
connection: InlineEligibleConnection
|
|
410
423
|
width: number
|
|
411
424
|
height: number
|
|
412
425
|
offset: number
|
|
@@ -496,9 +509,9 @@ export class InlineNetLabelSolver extends BaseSolver {
|
|
|
496
509
|
|
|
497
510
|
return {
|
|
498
511
|
globalConnNetId: trace.globalConnNetId,
|
|
499
|
-
netId:
|
|
512
|
+
netId: connection.netId,
|
|
500
513
|
mspPairId: trace.mspPairId,
|
|
501
|
-
pinIds: [...
|
|
514
|
+
pinIds: [...connection.pinIds],
|
|
502
515
|
axis,
|
|
503
516
|
anchorPoint,
|
|
504
517
|
center,
|
|
@@ -14,7 +14,7 @@ import { visualizeInputProblem } from "../SchematicTracePipelineSolver/visualize
|
|
|
14
14
|
import { doesPairCrossRestrictedCenterLines } from "./doesPairCrossRestrictedCenterLines"
|
|
15
15
|
import { getConnectivityMapsFromInputProblem } from "./getConnectivityMapFromInputProblem"
|
|
16
16
|
import { getOrthogonalMinimumSpanningTree } from "./getMspConnectionPairsFromPins"
|
|
17
|
-
import {
|
|
17
|
+
import { getLabeledConnectionRouteReason } from "./isLabeledPeripheralConnection"
|
|
18
18
|
|
|
19
19
|
export type MspConnectionPairId = string
|
|
20
20
|
export const DEFAULT_MAX_MSP_PAIR_DISTANCE = 1
|
|
@@ -26,6 +26,8 @@ export type MspConnectionPair = {
|
|
|
26
26
|
dcConnNetId: string
|
|
27
27
|
globalConnNetId: string
|
|
28
28
|
userNetId?: string
|
|
29
|
+
/** The trace replaces fallback labels that could not fit between its pins. */
|
|
30
|
+
suppressNetLabel?: boolean
|
|
29
31
|
pins: [InputPin & { chipId: string }, InputPin & { chipId: string }]
|
|
30
32
|
}
|
|
31
33
|
|
|
@@ -121,14 +123,17 @@ export class MspConnectionPairSolver extends BaseSolver {
|
|
|
121
123
|
if (this.directConnectionPinPairKeys.has(pinPairKey)) {
|
|
122
124
|
pairDistance = distance(p1, p2)
|
|
123
125
|
}
|
|
124
|
-
// Labeled one-pin peripherals
|
|
125
|
-
//
|
|
126
|
-
const
|
|
126
|
+
// Labeled one-pin peripherals and opposed pins whose fallback labels
|
|
127
|
+
// cannot fit need a real trace even when they are far apart.
|
|
128
|
+
const labeledConnectionRouteReason = getLabeledConnectionRouteReason({
|
|
127
129
|
inputProblem: this.inputProblem,
|
|
128
130
|
chipMap: this.chipMap,
|
|
129
131
|
pins: [p1, p2],
|
|
130
132
|
})
|
|
131
|
-
if (
|
|
133
|
+
if (
|
|
134
|
+
pairDistance > this.maxMspPairDistance &&
|
|
135
|
+
!labeledConnectionRouteReason
|
|
136
|
+
) {
|
|
132
137
|
// Too far apart; skip creating an MSP pair for this net
|
|
133
138
|
return
|
|
134
139
|
}
|
|
@@ -155,12 +160,16 @@ export class MspConnectionPairSolver extends BaseSolver {
|
|
|
155
160
|
const globalConnNetId = this.globalConnMap.getNetConnectedToId(pin1!)!
|
|
156
161
|
const userNetId =
|
|
157
162
|
this.userNetIdByPinId[pin1!] ?? this.userNetIdByPinId[pin2!]
|
|
163
|
+
const suppressNetLabel =
|
|
164
|
+
pairDistance > this.maxMspPairDistance &&
|
|
165
|
+
labeledConnectionRouteReason === "overlapping-fallback-labels"
|
|
158
166
|
|
|
159
167
|
this.mspConnectionPairs.push({
|
|
160
168
|
mspPairId: `${pin1}-${pin2}`,
|
|
161
169
|
dcConnNetId: dcNetId,
|
|
162
170
|
globalConnNetId,
|
|
163
171
|
userNetId,
|
|
172
|
+
suppressNetLabel,
|
|
164
173
|
pins: [p1, p2],
|
|
165
174
|
})
|
|
166
175
|
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { InputChip, InputPin, InputProblem } from "lib/types/InputProblem"
|
|
2
|
+
import { NET_LABEL_HORIZONTAL_HEIGHT } from "../NetLabelPlacementSolver/SingleNetLabelPlacementSolver/geometry"
|
|
2
3
|
import { getPinDirection } from "../SchematicTraceLinesSolver/SchematicTraceSingleLineSolver/getPinDirection"
|
|
3
4
|
|
|
4
5
|
type PinWithChipId = InputPin & { chipId: string }
|
|
5
6
|
|
|
6
|
-
export
|
|
7
|
+
export type LabeledConnectionRouteReason =
|
|
8
|
+
| "single-pin-peripheral"
|
|
9
|
+
| "overlapping-fallback-labels"
|
|
10
|
+
|
|
11
|
+
export const getLabeledConnectionRouteReason = ({
|
|
7
12
|
inputProblem,
|
|
8
13
|
chipMap,
|
|
9
14
|
pins,
|
|
@@ -11,22 +16,18 @@ export const isLabeledPeripheralConnection = ({
|
|
|
11
16
|
inputProblem: InputProblem
|
|
12
17
|
chipMap: Record<string, InputChip>
|
|
13
18
|
pins: [PinWithChipId, PinWithChipId]
|
|
14
|
-
}):
|
|
19
|
+
}): LabeledConnectionRouteReason | null => {
|
|
15
20
|
const [firstPin, secondPin] = pins
|
|
16
21
|
const directConnection = inputProblem.directConnections.find(
|
|
17
22
|
(connection) =>
|
|
18
23
|
connection.pinIds.includes(firstPin.pinId) &&
|
|
19
24
|
connection.pinIds.includes(secondPin.pinId),
|
|
20
25
|
)
|
|
21
|
-
if (directConnection?.netLabelWidth === undefined) return
|
|
26
|
+
if (directConnection?.netLabelWidth === undefined) return null
|
|
22
27
|
|
|
23
28
|
const firstChip = chipMap[firstPin.chipId]
|
|
24
29
|
const secondChip = chipMap[secondPin.chipId]
|
|
25
|
-
if (!firstChip || !secondChip) return
|
|
26
|
-
|
|
27
|
-
const hasSinglePinPeripheral =
|
|
28
|
-
firstChip.pins.length === 1 || secondChip.pins.length === 1
|
|
29
|
-
if (!hasSinglePinPeripheral) return false
|
|
30
|
+
if (!firstChip || !secondChip) return null
|
|
30
31
|
|
|
31
32
|
let firstFacingDirection = firstPin._facingDirection
|
|
32
33
|
if (!firstFacingDirection) {
|
|
@@ -37,8 +38,43 @@ export const isLabeledPeripheralConnection = ({
|
|
|
37
38
|
secondFacingDirection = getPinDirection(secondPin, secondChip)
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
const hasOpposingHorizontalDirections =
|
|
41
42
|
(firstFacingDirection === "x-" && secondFacingDirection === "x+") ||
|
|
42
43
|
(firstFacingDirection === "x+" && secondFacingDirection === "x-")
|
|
43
|
-
)
|
|
44
|
+
if (!hasOpposingHorizontalDirections) return null
|
|
45
|
+
|
|
46
|
+
const hasSinglePinPeripheral =
|
|
47
|
+
firstChip.pins.length === 1 || secondChip.pins.length === 1
|
|
48
|
+
if (hasSinglePinPeripheral) return "single-pin-peripheral"
|
|
49
|
+
|
|
50
|
+
// The overlap fallback is intended for explicitly grouped schematic
|
|
51
|
+
// sections, where hierarchy boxes and their nearby connectors are laid out
|
|
52
|
+
// as one visual unit. Applying it to ordinary sheets can reroute unrelated
|
|
53
|
+
// component-to-component labels elsewhere in the design.
|
|
54
|
+
const sharedSectionId =
|
|
55
|
+
firstChip.sectionId && firstChip.sectionId === secondChip.sectionId
|
|
56
|
+
? firstChip.sectionId
|
|
57
|
+
: null
|
|
58
|
+
if (!sharedSectionId) return null
|
|
59
|
+
|
|
60
|
+
// When two multi-pin components face each other across a short gap, the
|
|
61
|
+
// fallback label at each pin can be wider than the available space. Route
|
|
62
|
+
// the explicit connection instead of rendering two copies of the long net
|
|
63
|
+
// name on top of one another.
|
|
64
|
+
const firstIsLeft = firstPin.x <= secondPin.x
|
|
65
|
+
const directionsPointTowardEachOther = firstIsLeft
|
|
66
|
+
? firstFacingDirection === "x+" && secondFacingDirection === "x-"
|
|
67
|
+
: firstFacingDirection === "x-" && secondFacingDirection === "x+"
|
|
68
|
+
const labelsOverlapAlongX =
|
|
69
|
+
Math.abs(firstPin.x - secondPin.x) < directConnection.netLabelWidth * 2
|
|
70
|
+
const labelsOverlapAlongY =
|
|
71
|
+
Math.abs(firstPin.y - secondPin.y) < NET_LABEL_HORIZONTAL_HEIGHT
|
|
72
|
+
|
|
73
|
+
const fallbackLabelsOverlap =
|
|
74
|
+
directionsPointTowardEachOther && labelsOverlapAlongX && labelsOverlapAlongY
|
|
75
|
+
return fallbackLabelsOverlap ? "overlapping-fallback-labels" : null
|
|
44
76
|
}
|
|
77
|
+
|
|
78
|
+
export const isLabeledPeripheralConnection = (
|
|
79
|
+
params: Parameters<typeof getLabeledConnectionRouteReason>[0],
|
|
80
|
+
) => getLabeledConnectionRouteReason(params) !== null
|
|
@@ -188,6 +188,13 @@ export class NetLabelPlacementSolver extends BaseSolver {
|
|
|
188
188
|
)
|
|
189
189
|
|
|
190
190
|
if (compTraces.length > 0) {
|
|
191
|
+
// This routed trace exists specifically because two endpoint labels
|
|
192
|
+
// could not fit in the available gap. Do not replace that pair with
|
|
193
|
+
// one redundant long label on the newly routed wire. If routing had
|
|
194
|
+
// failed there would be no trace here, so the port-only fallback
|
|
195
|
+
// branch below would still label both endpoints.
|
|
196
|
+
if (compTraces.some((trace) => trace.suppressNetLabel)) continue
|
|
197
|
+
|
|
191
198
|
// Choose a representative trace (longest by L1 length)
|
|
192
199
|
const lengthOf = (path: SolvedTracePath) => {
|
|
193
200
|
let sum = 0
|
|
@@ -43,7 +43,9 @@ export interface InputDirectConnection {
|
|
|
43
43
|
*
|
|
44
44
|
* Only set this for connections whose net name is worth showing on the wire -
|
|
45
45
|
* the solver trusts the caller (e.g. @tscircuit/core) to make that decision.
|
|
46
|
-
*
|
|
46
|
+
* When the connection is routed, the label is placed along the trace. If
|
|
47
|
+
* routing is intentionally skipped, both endpoint labels may instead become
|
|
48
|
+
* outward inline stubs.
|
|
47
49
|
*/
|
|
48
50
|
allowInlineNetLabel?: boolean
|
|
49
51
|
|
|
@@ -67,9 +69,10 @@ export interface InputNetConnection {
|
|
|
67
69
|
netLabelHeight?: number
|
|
68
70
|
|
|
69
71
|
/**
|
|
70
|
-
* When true, a named
|
|
71
|
-
*
|
|
72
|
-
*
|
|
72
|
+
* When true, a named one- or two-pin net may use inline labels. A single-pin
|
|
73
|
+
* net gets an outward stub. A routed two-pin net gets one label along its
|
|
74
|
+
* trace; when that route is intentionally skipped, both endpoints get
|
|
75
|
+
* outward stubs. Nets with more than two pins retain anchored labels.
|
|
73
76
|
*/
|
|
74
77
|
allowInlineNetLabel?: boolean
|
|
75
78
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"chips": [
|
|
3
|
+
{
|
|
4
|
+
"chipId": "U1",
|
|
5
|
+
"center": { "x": -1, "y": 1 },
|
|
6
|
+
"width": 1,
|
|
7
|
+
"height": 1,
|
|
8
|
+
"sectionId": "routed",
|
|
9
|
+
"pins": [
|
|
10
|
+
{ "pinId": "U1.1", "x": -0.5, "y": 1, "_facingDirection": "x+" }
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"chipId": "U2",
|
|
15
|
+
"center": { "x": 1, "y": 1 },
|
|
16
|
+
"width": 1,
|
|
17
|
+
"height": 1,
|
|
18
|
+
"sectionId": "routed",
|
|
19
|
+
"pins": [
|
|
20
|
+
{ "pinId": "U2.1", "x": 0.5, "y": 1, "_facingDirection": "x-" }
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"chipId": "U3",
|
|
25
|
+
"center": { "x": -2, "y": -1 },
|
|
26
|
+
"width": 1,
|
|
27
|
+
"height": 1,
|
|
28
|
+
"sectionId": "left",
|
|
29
|
+
"pins": [
|
|
30
|
+
{ "pinId": "U3.1", "x": -1.5, "y": -1, "_facingDirection": "x+" }
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"chipId": "U4",
|
|
35
|
+
"center": { "x": 2, "y": -1 },
|
|
36
|
+
"width": 1,
|
|
37
|
+
"height": 1,
|
|
38
|
+
"sectionId": "right",
|
|
39
|
+
"pins": [
|
|
40
|
+
{ "pinId": "U4.1", "x": 1.5, "y": -1, "_facingDirection": "x-" }
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"directConnections": [],
|
|
45
|
+
"netConnections": [
|
|
46
|
+
{
|
|
47
|
+
"netId": "NET_ROUTED",
|
|
48
|
+
"pinIds": ["U1.1", "U2.1"],
|
|
49
|
+
"netLabelWidth": 0.9,
|
|
50
|
+
"allowInlineNetLabel": true,
|
|
51
|
+
"inlineNetLabelWidth": 0.9,
|
|
52
|
+
"inlineNetLabelHeight": 0.12
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"netId": "NET_SECTIONED",
|
|
56
|
+
"pinIds": ["U3.1", "U4.1"],
|
|
57
|
+
"netLabelWidth": 1.1,
|
|
58
|
+
"allowInlineNetLabel": true,
|
|
59
|
+
"inlineNetLabelWidth": 1.1,
|
|
60
|
+
"inlineNetLabelHeight": 0.12
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"availableNetLabelOrientations": {
|
|
64
|
+
"NET_ROUTED": ["x-", "x+"],
|
|
65
|
+
"NET_SECTIONED": ["x-", "x+"]
|
|
66
|
+
}
|
|
67
|
+
}
|