@tscircuit/schematic-trace-solver 0.0.62 → 0.0.63

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
@@ -83,6 +83,7 @@ interface InputNetConnection {
83
83
  netId: string;
84
84
  pinIds: Array<PinId>;
85
85
  netLabelWidth?: number;
86
+ netLabelHeight?: number;
86
87
  }
87
88
  interface InputProblem {
88
89
  chips: Array<InputChip>;
@@ -288,6 +289,7 @@ declare class SingleNetLabelPlacementSolver extends BaseSolver {
288
289
  availableOrientations: Array<FacingDirection>;
289
290
  chipObstacleSpatialIndex: ChipObstacleSpatialIndex;
290
291
  netLabelWidth?: number;
292
+ netLabelHeight?: number;
291
293
  netLabelPlacement: NetLabelPlacement | null;
292
294
  testedCandidates: Array<{
293
295
  center: {
@@ -316,6 +318,7 @@ declare class SingleNetLabelPlacementSolver extends BaseSolver {
316
318
  overlappingSameNetTraceGroup: OverlappingSameNetTraceGroup;
317
319
  availableOrientations: FacingDirection[];
318
320
  netLabelWidth?: number;
321
+ netLabelHeight?: number;
319
322
  });
320
323
  getConstructorParams(): ConstructorParameters<typeof SingleNetLabelPlacementSolver>[0];
321
324
  _step(): void;
@@ -385,6 +388,7 @@ declare class NetLabelPlacementSolver extends BaseSolver {
385
388
  });
386
389
  computeOverlappingSameNetTraceGroups(): Array<OverlappingSameNetTraceGroup>;
387
390
  private getNetLabelWidthForGroup;
391
+ private getNetLabelHeightForGroup;
388
392
  _step(): void;
389
393
  visualize(): GraphicsObject;
390
394
  }
@@ -707,6 +711,7 @@ declare class AvailableNetOrientationSolver extends BaseSolver {
707
711
  private getLateralColumnMaxDistance;
708
712
  private createCandidate;
709
713
  private getNetLabelWidth;
714
+ private getNetLabelHeight;
710
715
  private getCandidateStatus;
711
716
  private getBoundsStatus;
712
717
  private intersectsAnyOtherNetLabel;
@@ -911,6 +916,7 @@ declare class NetLabelNetLabelCollisionSolver extends BaseSolver {
911
916
  private collisionKey;
912
917
  private findNextCollidingPair;
913
918
  private netLabelWidthOf;
919
+ private netLabelHeightOf;
914
920
  private buildCandidatesForLabel;
915
921
  private checkCandidate;
916
922
  private beginSearchForLabel;
package/dist/index.js CHANGED
@@ -1511,18 +1511,19 @@ var ChipObstacleSpatialIndex = class {
1511
1511
  var NET_LABEL_HORIZONTAL_WIDTH = 0.45;
1512
1512
  var NET_LABEL_HORIZONTAL_HEIGHT = 0.2;
1513
1513
  function getDimsForOrientation(params) {
1514
- const { orientation, netLabelWidth } = params;
1514
+ const { orientation, netLabelWidth, netLabelHeight } = params;
1515
1515
  const horizWidth = typeof netLabelWidth === "number" ? netLabelWidth : NET_LABEL_HORIZONTAL_WIDTH;
1516
+ const horizHeight = typeof netLabelHeight === "number" ? netLabelHeight : NET_LABEL_HORIZONTAL_HEIGHT;
1516
1517
  if (orientation === "y+" || orientation === "y-") {
1517
1518
  return {
1518
- // Rotated, so width/height swap
1519
- width: NET_LABEL_HORIZONTAL_HEIGHT,
1519
+ // Rotated: horizontal length = netLabelHeight, vertical length = netLabelWidth
1520
+ width: horizHeight,
1520
1521
  height: horizWidth
1521
1522
  };
1522
1523
  }
1523
1524
  return {
1524
1525
  width: horizWidth,
1525
- height: NET_LABEL_HORIZONTAL_HEIGHT
1526
+ height: horizHeight
1526
1527
  };
1527
1528
  }
1528
1529
  function getCenterFromAnchor(anchor, orientation, width, height) {
@@ -1651,7 +1652,8 @@ function solveNetLabelPlacementForPortOnlyPin(params) {
1651
1652
  chipObstacleSpatialIndex,
1652
1653
  overlappingSameNetTraceGroup,
1653
1654
  availableOrientations,
1654
- netLabelWidth
1655
+ netLabelWidth,
1656
+ netLabelHeight
1655
1657
  } = params;
1656
1658
  const pinId = overlappingSameNetTraceGroup.portOnlyPinId;
1657
1659
  if (!pinId) {
@@ -1685,7 +1687,8 @@ function solveNetLabelPlacementForPortOnlyPin(params) {
1685
1687
  for (const orientation of orientations) {
1686
1688
  const { width: width2, height: height2 } = getDimsForOrientation({
1687
1689
  orientation,
1688
- netLabelWidth
1690
+ netLabelWidth,
1691
+ netLabelHeight
1689
1692
  });
1690
1693
  const baseCenter2 = getCenterFromAnchor(anchor, orientation, width2, height2);
1691
1694
  const outward2 = outwardOf(orientation);
@@ -1857,8 +1860,9 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
1857
1860
  overlappingSameNetTraceGroup;
1858
1861
  availableOrientations;
1859
1862
  chipObstacleSpatialIndex;
1860
- // Optional override for the width of the net label (per netId)
1863
+ // Optional override for the width/height of the net label (per netId)
1861
1864
  netLabelWidth;
1865
+ netLabelHeight;
1862
1866
  netLabelPlacement = null;
1863
1867
  testedCandidates = [];
1864
1868
  constructor(params) {
@@ -1868,6 +1872,7 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
1868
1872
  this.overlappingSameNetTraceGroup = params.overlappingSameNetTraceGroup;
1869
1873
  this.availableOrientations = params.availableOrientations;
1870
1874
  this.netLabelWidth = params.netLabelWidth;
1875
+ this.netLabelHeight = params.netLabelHeight;
1871
1876
  this.chipObstacleSpatialIndex = params.inputProblem._chipObstacleSpatialIndex ?? new ChipObstacleSpatialIndex(params.inputProblem.chips);
1872
1877
  }
1873
1878
  getConstructorParams() {
@@ -1876,7 +1881,8 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
1876
1881
  inputTraceMap: this.inputTraceMap,
1877
1882
  overlappingSameNetTraceGroup: this.overlappingSameNetTraceGroup,
1878
1883
  availableOrientations: this.availableOrientations,
1879
- netLabelWidth: this.netLabelWidth
1884
+ netLabelWidth: this.netLabelWidth,
1885
+ netLabelHeight: this.netLabelHeight
1880
1886
  };
1881
1887
  }
1882
1888
  _step() {
@@ -1891,7 +1897,8 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
1891
1897
  chipObstacleSpatialIndex: this.chipObstacleSpatialIndex,
1892
1898
  overlappingSameNetTraceGroup: this.overlappingSameNetTraceGroup,
1893
1899
  availableOrientations: this.availableOrientations,
1894
- netLabelWidth: this.netLabelWidth
1900
+ netLabelWidth: this.netLabelWidth,
1901
+ netLabelHeight: this.netLabelHeight
1895
1902
  });
1896
1903
  this.testedCandidates.push(...res.testedCandidates);
1897
1904
  if (res.placement) {
@@ -1961,7 +1968,8 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
1961
1968
  for (const orientation of candidateOrients) {
1962
1969
  const { width, height } = getDimsForOrientation({
1963
1970
  orientation,
1964
- netLabelWidth: this.netLabelWidth
1971
+ netLabelWidth: this.netLabelWidth,
1972
+ netLabelHeight: this.netLabelHeight
1965
1973
  });
1966
1974
  const center = getCenterFromAnchor(
1967
1975
  anchor,
@@ -2250,6 +2258,21 @@ var NetLabelPlacementSolver = class extends BaseSolver {
2250
2258
  (nc) => nc.pinIds.some((pid) => pinIds.includes(pid))
2251
2259
  )?.netLabelWidth;
2252
2260
  }
2261
+ getNetLabelHeightForGroup(group) {
2262
+ if (group.netId) {
2263
+ const ncHeight = this.inputProblem.netConnections.find(
2264
+ (nc) => nc.netId === group.netId
2265
+ )?.netLabelHeight;
2266
+ if (ncHeight !== void 0) return ncHeight;
2267
+ }
2268
+ const pinIds = group.overlappingTraces?.pins.map((p) => p.pinId) ?? [];
2269
+ if (group.portOnlyPinId) {
2270
+ pinIds.push(group.portOnlyPinId);
2271
+ }
2272
+ return this.inputProblem.netConnections.find(
2273
+ (nc) => nc.pinIds.some((pid) => pinIds.includes(pid))
2274
+ )?.netLabelHeight;
2275
+ }
2253
2276
  _step() {
2254
2277
  if (this.activeSubSolver?.solved) {
2255
2278
  this.netLabelPlacements.push(this.activeSubSolver.netLabelPlacement);
@@ -2265,12 +2288,14 @@ var NetLabelPlacementSolver = class extends BaseSolver {
2265
2288
  if (!this.triedAnyOrientationFallbackForCurrentGroup && !isAlreadyFull && this.currentGroup) {
2266
2289
  this.triedAnyOrientationFallbackForCurrentGroup = true;
2267
2290
  const netLabelWidth2 = this.getNetLabelWidthForGroup(this.currentGroup);
2291
+ const netLabelHeight2 = this.getNetLabelHeightForGroup(this.currentGroup);
2268
2292
  this.activeSubSolver = new SingleNetLabelPlacementSolver({
2269
2293
  inputProblem: this.inputProblem,
2270
2294
  inputTraceMap: this.inputTraceMap,
2271
2295
  overlappingSameNetTraceGroup: this.currentGroup,
2272
2296
  availableOrientations: fullOrients,
2273
- netLabelWidth: netLabelWidth2
2297
+ netLabelWidth: netLabelWidth2,
2298
+ netLabelHeight: netLabelHeight2
2274
2299
  });
2275
2300
  return;
2276
2301
  }
@@ -2291,12 +2316,14 @@ var NetLabelPlacementSolver = class extends BaseSolver {
2291
2316
  this.currentGroup = nextOverlappingSameNetTraceGroup;
2292
2317
  this.triedAnyOrientationFallbackForCurrentGroup = false;
2293
2318
  const netLabelWidth = this.getNetLabelWidthForGroup(this.currentGroup);
2319
+ const netLabelHeight = this.getNetLabelHeightForGroup(this.currentGroup);
2294
2320
  this.activeSubSolver = new SingleNetLabelPlacementSolver({
2295
2321
  inputProblem: this.inputProblem,
2296
2322
  inputTraceMap: this.inputTraceMap,
2297
2323
  overlappingSameNetTraceGroup: nextOverlappingSameNetTraceGroup,
2298
2324
  availableOrientations: this.inputProblem.availableNetLabelOrientations[netId] ?? ["x+", "x-", "y+", "y-"],
2299
- netLabelWidth
2325
+ netLabelWidth,
2326
+ netLabelHeight
2300
2327
  });
2301
2328
  }
2302
2329
  visualize() {
@@ -6084,7 +6111,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6084
6111
  const anchorPoint = this.getWickOffsetAnchor(label.anchorPoint, orientation);
6085
6112
  const { width, height } = getDimsForOrientation({
6086
6113
  orientation,
6087
- netLabelWidth: this.getNetLabelWidth(label)
6114
+ netLabelWidth: this.getNetLabelWidth(label),
6115
+ netLabelHeight: this.getNetLabelHeight(label)
6088
6116
  });
6089
6117
  return this.getSideOffsetAnchor({
6090
6118
  anchorPoint,
@@ -6133,7 +6161,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6133
6161
  getSearchDistanceLimit(label, orientation) {
6134
6162
  const { width, height } = getDimsForOrientation({
6135
6163
  orientation,
6136
- netLabelWidth: this.getNetLabelWidth(label)
6164
+ netLabelWidth: this.getNetLabelWidth(label),
6165
+ netLabelHeight: this.getNetLabelHeight(label)
6137
6166
  });
6138
6167
  const labelLength = orientation === "y+" || orientation === "y-" ? height : width;
6139
6168
  return Math.min(this.maxSearchDistance, labelLength * 2);
@@ -6156,7 +6185,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6156
6185
  createCandidate(label, anchorPoint, orientation) {
6157
6186
  const { width, height } = getDimsForOrientation({
6158
6187
  orientation,
6159
- netLabelWidth: this.getNetLabelWidth(label)
6188
+ netLabelWidth: this.getNetLabelWidth(label),
6189
+ netLabelHeight: this.getNetLabelHeight(label)
6160
6190
  });
6161
6191
  return {
6162
6192
  orientation,
@@ -6185,6 +6215,17 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6185
6215
  (nc) => nc.pinIds.some((pid) => label.pinIds.includes(pid))
6186
6216
  )?.netLabelWidth;
6187
6217
  }
6218
+ getNetLabelHeight(label) {
6219
+ if (label.netId) {
6220
+ const ncHeight = this.inputProblem.netConnections.find(
6221
+ (connection) => connection.netId === label.netId
6222
+ )?.netLabelHeight;
6223
+ if (ncHeight !== void 0) return ncHeight;
6224
+ }
6225
+ return this.inputProblem.netConnections.find(
6226
+ (nc) => nc.pinIds.some((pid) => label.pinIds.includes(pid))
6227
+ )?.netLabelHeight;
6228
+ }
6188
6229
  getCandidateStatus(candidate, label, labelIndex) {
6189
6230
  const boundsStatus = this.getBoundsStatus(
6190
6231
  getRectBounds(candidate.center, candidate.width, candidate.height),
@@ -6798,6 +6839,7 @@ var generateCandidatesAlongTrace = (params) => {
6798
6839
  getTraceVertexDistances(traceLocation.trace)
6799
6840
  );
6800
6841
  const netLabelWidth = getNetLabelWidth(inputProblem, label);
6842
+ const netLabelHeight = getNetLabelHeight(inputProblem, label);
6801
6843
  const candidates = [];
6802
6844
  const seenCandidateKeys = /* @__PURE__ */ new Set();
6803
6845
  for (const pathDistance of candidateDistances) {
@@ -6820,6 +6862,7 @@ var generateCandidatesAlongTrace = (params) => {
6820
6862
  point,
6821
6863
  orientation,
6822
6864
  netLabelWidth,
6865
+ netLabelHeight,
6823
6866
  traceLocation,
6824
6867
  pathDistance,
6825
6868
  label
@@ -6857,13 +6900,15 @@ var createCandidate = (params) => {
6857
6900
  point,
6858
6901
  orientation,
6859
6902
  netLabelWidth,
6903
+ netLabelHeight,
6860
6904
  traceLocation,
6861
6905
  pathDistance,
6862
6906
  label
6863
6907
  } = params;
6864
6908
  const { width, height } = getDimsForOrientation({
6865
6909
  orientation,
6866
- netLabelWidth
6910
+ netLabelWidth,
6911
+ netLabelHeight
6867
6912
  });
6868
6913
  return {
6869
6914
  anchorPoint: point,
@@ -7026,6 +7071,15 @@ var getNetLabelWidth = (inputProblem, label) => {
7026
7071
  }
7027
7072
  return label.width;
7028
7073
  };
7074
+ var getNetLabelHeight = (inputProblem, label) => {
7075
+ const ncHeightByNetId = inputProblem.netConnections.find(
7076
+ (connection) => connection.netId === label.netId
7077
+ )?.netLabelHeight;
7078
+ if (ncHeightByNetId !== void 0) return ncHeightByNetId;
7079
+ return inputProblem.netConnections.find(
7080
+ (nc) => nc.pinIds.some((pid) => label.pinIds.includes(pid))
7081
+ )?.netLabelHeight;
7082
+ };
7029
7083
  var roundDistance = (distance3) => Number(distance3.toFixed(6));
7030
7084
  var dedupeOrientations = (orientations) => [
7031
7085
  ...new Set(orientations)
@@ -7702,13 +7756,20 @@ var NetLabelNetLabelCollisionSolver = class extends BaseSolver {
7702
7756
  return label.width;
7703
7757
  return label.height;
7704
7758
  }
7759
+ netLabelHeightOf(label) {
7760
+ if (label.orientation === "x+" || label.orientation === "x-")
7761
+ return label.height;
7762
+ return label.width;
7763
+ }
7705
7764
  buildCandidatesForLabel(label) {
7706
7765
  const netLabelWidth = this.netLabelWidthOf(label);
7766
+ const netLabelHeight = this.netLabelHeightOf(label);
7707
7767
  const candidates = [];
7708
7768
  const buildCandidate = (orientation, anchor, hostPairId, hostSegIndex) => {
7709
7769
  const { width, height } = getDimsForOrientation({
7710
7770
  orientation,
7711
- netLabelWidth
7771
+ netLabelWidth,
7772
+ netLabelHeight
7712
7773
  });
7713
7774
  const baseCenter = getCenterFromAnchor(anchor, orientation, width, height);
7714
7775
  const outwardDir = OUTWARD_DIR[orientation];
@@ -429,6 +429,7 @@ export class AvailableNetOrientationSolver extends BaseSolver {
429
429
  const { width, height } = getDimsForOrientation({
430
430
  orientation,
431
431
  netLabelWidth: this.getNetLabelWidth(label),
432
+ netLabelHeight: this.getNetLabelHeight(label),
432
433
  })
433
434
 
434
435
  return this.getSideOffsetAnchor({
@@ -494,6 +495,7 @@ export class AvailableNetOrientationSolver extends BaseSolver {
494
495
  const { width, height } = getDimsForOrientation({
495
496
  orientation,
496
497
  netLabelWidth: this.getNetLabelWidth(label),
498
+ netLabelHeight: this.getNetLabelHeight(label),
497
499
  })
498
500
  const labelLength =
499
501
  orientation === "y+" || orientation === "y-" ? height : width
@@ -534,6 +536,7 @@ export class AvailableNetOrientationSolver extends BaseSolver {
534
536
  const { width, height } = getDimsForOrientation({
535
537
  orientation,
536
538
  netLabelWidth: this.getNetLabelWidth(label),
539
+ netLabelHeight: this.getNetLabelHeight(label),
537
540
  })
538
541
  return {
539
542
  orientation,
@@ -567,6 +570,19 @@ export class AvailableNetOrientationSolver extends BaseSolver {
567
570
  )?.netLabelWidth
568
571
  }
569
572
 
573
+ private getNetLabelHeight(label: NetLabelPlacement) {
574
+ if (label.netId) {
575
+ const ncHeight = this.inputProblem.netConnections.find(
576
+ (connection) => connection.netId === label.netId,
577
+ )?.netLabelHeight
578
+ if (ncHeight !== undefined) return ncHeight
579
+ }
580
+
581
+ return this.inputProblem.netConnections.find((nc) =>
582
+ nc.pinIds.some((pid) => label.pinIds.includes(pid)),
583
+ )?.netLabelHeight
584
+ }
585
+
570
586
  private getCandidateStatus(
571
587
  candidate: CandidateLabel,
572
588
  label: NetLabelPlacement,
@@ -170,8 +170,15 @@ export class NetLabelNetLabelCollisionSolver extends BaseSolver {
170
170
  return label.height
171
171
  }
172
172
 
173
+ private netLabelHeightOf(label: NetLabelPlacement): number | undefined {
174
+ if (label.orientation === "x+" || label.orientation === "x-")
175
+ return label.height
176
+ return label.width
177
+ }
178
+
173
179
  private buildCandidatesForLabel(label: NetLabelPlacement): Candidate[] {
174
180
  const netLabelWidth = this.netLabelWidthOf(label)
181
+ const netLabelHeight = this.netLabelHeightOf(label)
175
182
  const candidates: Candidate[] = []
176
183
 
177
184
  const buildCandidate = (
@@ -183,6 +190,7 @@ export class NetLabelNetLabelCollisionSolver extends BaseSolver {
183
190
  const { width, height } = getDimsForOrientation({
184
191
  orientation,
185
192
  netLabelWidth,
193
+ netLabelHeight,
186
194
  })
187
195
  const baseCenter = getCenterFromAnchor(anchor, orientation, width, height)
188
196
  const outwardDir = OUTWARD_DIR[orientation]
@@ -280,6 +280,26 @@ export class NetLabelPlacementSolver extends BaseSolver {
280
280
  )?.netLabelWidth
281
281
  }
282
282
 
283
+ private getNetLabelHeightForGroup(
284
+ group: OverlappingSameNetTraceGroup,
285
+ ): number | undefined {
286
+ if (group.netId) {
287
+ const ncHeight = this.inputProblem.netConnections.find(
288
+ (nc) => nc.netId === group.netId,
289
+ )?.netLabelHeight
290
+ if (ncHeight !== undefined) return ncHeight
291
+ }
292
+
293
+ const pinIds = group.overlappingTraces?.pins.map((p) => p.pinId) ?? []
294
+ if (group.portOnlyPinId) {
295
+ pinIds.push(group.portOnlyPinId)
296
+ }
297
+
298
+ return this.inputProblem.netConnections.find((nc) =>
299
+ nc.pinIds.some((pid) => pinIds.includes(pid)),
300
+ )?.netLabelHeight
301
+ }
302
+
283
303
  override _step() {
284
304
  if (this.activeSubSolver?.solved) {
285
305
  this.netLabelPlacements.push(this.activeSubSolver.netLabelPlacement!)
@@ -304,12 +324,14 @@ export class NetLabelPlacementSolver extends BaseSolver {
304
324
  ) {
305
325
  this.triedAnyOrientationFallbackForCurrentGroup = true
306
326
  const netLabelWidth = this.getNetLabelWidthForGroup(this.currentGroup)
327
+ const netLabelHeight = this.getNetLabelHeightForGroup(this.currentGroup)
307
328
  this.activeSubSolver = new SingleNetLabelPlacementSolver({
308
329
  inputProblem: this.inputProblem,
309
330
  inputTraceMap: this.inputTraceMap,
310
331
  overlappingSameNetTraceGroup: this.currentGroup,
311
332
  availableOrientations: fullOrients,
312
333
  netLabelWidth,
334
+ netLabelHeight,
313
335
  })
314
336
  return
315
337
  }
@@ -340,6 +362,7 @@ export class NetLabelPlacementSolver extends BaseSolver {
340
362
  this.triedAnyOrientationFallbackForCurrentGroup = false
341
363
 
342
364
  const netLabelWidth = this.getNetLabelWidthForGroup(this.currentGroup)
365
+ const netLabelHeight = this.getNetLabelHeightForGroup(this.currentGroup)
343
366
 
344
367
  this.activeSubSolver = new SingleNetLabelPlacementSolver({
345
368
  inputProblem: this.inputProblem,
@@ -349,6 +372,7 @@ export class NetLabelPlacementSolver extends BaseSolver {
349
372
  netId
350
373
  ] ?? ["x+", "x-", "y+", "y-"],
351
374
  netLabelWidth,
375
+ netLabelHeight,
352
376
  })
353
377
  }
354
378
 
@@ -58,8 +58,9 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
58
58
 
59
59
  chipObstacleSpatialIndex: ChipObstacleSpatialIndex
60
60
 
61
- // Optional override for the width of the net label (per netId)
61
+ // Optional override for the width/height of the net label (per netId)
62
62
  netLabelWidth?: number
63
+ netLabelHeight?: number
63
64
 
64
65
  netLabelPlacement: NetLabelPlacement | null = null
65
66
  testedCandidates: Array<{
@@ -79,6 +80,7 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
79
80
  overlappingSameNetTraceGroup: OverlappingSameNetTraceGroup
80
81
  availableOrientations: FacingDirection[]
81
82
  netLabelWidth?: number
83
+ netLabelHeight?: number
82
84
  }) {
83
85
  super()
84
86
  this.inputProblem = params.inputProblem
@@ -86,6 +88,7 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
86
88
  this.overlappingSameNetTraceGroup = params.overlappingSameNetTraceGroup
87
89
  this.availableOrientations = params.availableOrientations
88
90
  this.netLabelWidth = params.netLabelWidth
91
+ this.netLabelHeight = params.netLabelHeight
89
92
 
90
93
  this.chipObstacleSpatialIndex =
91
94
  params.inputProblem._chipObstacleSpatialIndex ??
@@ -101,6 +104,7 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
101
104
  overlappingSameNetTraceGroup: this.overlappingSameNetTraceGroup,
102
105
  availableOrientations: this.availableOrientations,
103
106
  netLabelWidth: this.netLabelWidth,
107
+ netLabelHeight: this.netLabelHeight,
104
108
  }
105
109
  }
106
110
 
@@ -119,6 +123,7 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
119
123
  overlappingSameNetTraceGroup: this.overlappingSameNetTraceGroup,
120
124
  availableOrientations: this.availableOrientations,
121
125
  netLabelWidth: this.netLabelWidth,
126
+ netLabelHeight: this.netLabelHeight,
122
127
  })
123
128
  this.testedCandidates.push(...res.testedCandidates)
124
129
  if (res.placement) {
@@ -230,6 +235,7 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
230
235
  const { width, height } = getDimsForOrientation({
231
236
  orientation,
232
237
  netLabelWidth: this.netLabelWidth,
238
+ netLabelHeight: this.netLabelHeight,
233
239
  })
234
240
  const center = getCenterFromAnchor(
235
241
  anchor,
@@ -6,23 +6,28 @@ export const NET_LABEL_HORIZONTAL_HEIGHT = 0.2
6
6
  export function getDimsForOrientation(params: {
7
7
  orientation: FacingDirection
8
8
  netLabelWidth?: number
9
+ netLabelHeight?: number
9
10
  }) {
10
- const { orientation, netLabelWidth } = params
11
+ const { orientation, netLabelWidth, netLabelHeight } = params
11
12
  const horizWidth =
12
13
  typeof netLabelWidth === "number"
13
14
  ? netLabelWidth
14
15
  : NET_LABEL_HORIZONTAL_WIDTH
16
+ const horizHeight =
17
+ typeof netLabelHeight === "number"
18
+ ? netLabelHeight
19
+ : NET_LABEL_HORIZONTAL_HEIGHT
15
20
 
16
21
  if (orientation === "y+" || orientation === "y-") {
17
22
  return {
18
- // Rotated, so width/height swap
19
- width: NET_LABEL_HORIZONTAL_HEIGHT,
23
+ // Rotated: horizontal length = netLabelHeight, vertical length = netLabelWidth
24
+ width: horizHeight,
20
25
  height: horizWidth,
21
26
  }
22
27
  }
23
28
  return {
24
29
  width: horizWidth,
25
- height: NET_LABEL_HORIZONTAL_HEIGHT,
30
+ height: horizHeight,
26
31
  }
27
32
  }
28
33
 
@@ -22,6 +22,7 @@ export function solveNetLabelPlacementForPortOnlyPin(params: {
22
22
  overlappingSameNetTraceGroup: OverlappingSameNetTraceGroup
23
23
  availableOrientations: FacingDirection[]
24
24
  netLabelWidth?: number
25
+ netLabelHeight?: number
25
26
  }): {
26
27
  placement: NetLabelPlacement | null
27
28
  testedCandidates: Array<{
@@ -43,6 +44,7 @@ export function solveNetLabelPlacementForPortOnlyPin(params: {
43
44
  overlappingSameNetTraceGroup,
44
45
  availableOrientations,
45
46
  netLabelWidth,
47
+ netLabelHeight,
46
48
  } = params
47
49
 
48
50
  const pinId = overlappingSameNetTraceGroup.portOnlyPinId
@@ -103,6 +105,7 @@ export function solveNetLabelPlacementForPortOnlyPin(params: {
103
105
  const { width, height } = getDimsForOrientation({
104
106
  orientation,
105
107
  netLabelWidth,
108
+ netLabelHeight,
106
109
  })
107
110
  // Place label fully outside the chip: shift center slightly outward
108
111
  const baseCenter = getCenterFromAnchor(anchor, orientation, width, height)
@@ -30,6 +30,7 @@ export const generateCandidatesAlongTrace = (params: {
30
30
  getTraceVertexDistances(traceLocation.trace),
31
31
  )
32
32
  const netLabelWidth = getNetLabelWidth(inputProblem, label)
33
+ const netLabelHeight = getNetLabelHeight(inputProblem, label)
33
34
  const candidates: LabelCandidate[] = []
34
35
  const seenCandidateKeys = new Set<string>()
35
36
 
@@ -55,6 +56,7 @@ export const generateCandidatesAlongTrace = (params: {
55
56
  point,
56
57
  orientation,
57
58
  netLabelWidth,
59
+ netLabelHeight,
58
60
  traceLocation,
59
61
  pathDistance,
60
62
  label,
@@ -109,6 +111,7 @@ const createCandidate = (params: {
109
111
  point: Point
110
112
  orientation: FacingDirection
111
113
  netLabelWidth: number
114
+ netLabelHeight?: number
112
115
  traceLocation: TraceLocation
113
116
  pathDistance: number
114
117
  label: NetLabelPlacement
@@ -117,6 +120,7 @@ const createCandidate = (params: {
117
120
  point,
118
121
  orientation,
119
122
  netLabelWidth,
123
+ netLabelHeight,
120
124
  traceLocation,
121
125
  pathDistance,
122
126
  label,
@@ -124,6 +128,7 @@ const createCandidate = (params: {
124
128
  const { width, height } = getDimsForOrientation({
125
129
  orientation,
126
130
  netLabelWidth,
131
+ netLabelHeight,
127
132
  })
128
133
 
129
134
  return {
@@ -360,6 +365,20 @@ const getNetLabelWidth = (
360
365
  return label.width
361
366
  }
362
367
 
368
+ const getNetLabelHeight = (
369
+ inputProblem: InputProblem,
370
+ label: NetLabelPlacement,
371
+ ): number | undefined => {
372
+ const ncHeightByNetId = inputProblem.netConnections.find(
373
+ (connection) => connection.netId === label.netId,
374
+ )?.netLabelHeight
375
+ if (ncHeightByNetId !== undefined) return ncHeightByNetId
376
+
377
+ return inputProblem.netConnections.find((nc) =>
378
+ nc.pinIds.some((pid) => label.pinIds.includes(pid)),
379
+ )?.netLabelHeight
380
+ }
381
+
363
382
  const roundDistance = (distance: number) => Number(distance.toFixed(6))
364
383
 
365
384
  const dedupeOrientations = (orientations: FacingDirection[]) => [
@@ -31,6 +31,7 @@ export interface InputNetConnection {
31
31
  netId: string
32
32
  pinIds: Array<PinId>
33
33
  netLabelWidth?: number
34
+ netLabelHeight?: number
34
35
  }
35
36
 
36
37
  export interface InputProblem {
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.62",
4
+ "version": "0.0.63",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "cosmos",
@@ -65,7 +65,8 @@
65
65
  {
66
66
  "netId": "SWD",
67
67
  "pinIds": ["U3.25", "R5.2"],
68
- "netLabelWidth": 0.48
68
+ "netLabelWidth": 0.48,
69
+ "netLabelHeight": 0.48
69
70
  },
70
71
  {
71
72
  "netId": "CLK",
@@ -26,7 +26,7 @@ orientation: x-" data-x="-7.65" data-y="-0.22999999999999998" cx="325.9574468085
26
26
  </g>
27
27
  <g>
28
28
  <circle data-type="point" data-label="anchorPoint
29
- orientation: y+" data-x="-8.549999999999999" data-y="-0.4299999999999998" cx="218.72340425531945" cy="331.9148936170212" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
29
+ orientation: y+" data-x="-8.65" data-y="-0.4299999999999998" cx="206.808510638298" cy="331.9148936170212" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
30
30
  </g>
31
31
  <g>
32
32
  <circle data-type="point" data-label="anchorPoint
@@ -53,7 +53,7 @@ globalConnNetId: connectivity_net1" data-x="-8.011" data-y="-0.22999999999999998
53
53
  </g>
54
54
  <g>
55
55
  <rect data-type="rect" data-label="netId: SWD
56
- globalConnNetId: connectivity_net0" data-x="-8.549999999999999" data-y="-0.18989999999999985" x="206.80851063829823" y="274.7114893617021" width="23.829787234042442" height="57.19148936170211" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.008392857142857145" />
56
+ globalConnNetId: connectivity_net0" data-x="-8.65" data-y="-0.18989999999999985" x="178.2127659574469" y="274.7114893617021" width="57.191489361702224" height="57.19148936170211" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.008392857142857145" />
57
57
  </g>
58
58
  <g>
59
59
  <rect data-type="rect" data-label="netId: CLK