@tscircuit/capacity-autorouter 0.0.239 → 0.0.241

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
@@ -2,7 +2,7 @@ import * as graphics_debug from 'graphics-debug';
2
2
  import { GraphicsObject, Rect, Circle, Line, Point as Point$5 } from 'graphics-debug';
3
3
  import { ConnectivityMap } from 'circuit-json-to-connectivity-map';
4
4
  import { RectDiffPipeline } from '@tscircuit/rectdiff';
5
- import { JumperGraphSolver } from '@tscircuit/hypergraph';
5
+ import { JumperGraphSolver, JRegion } from '@tscircuit/hypergraph';
6
6
  import { ConnectivityMap as ConnectivityMap$1 } from 'connectivity-map';
7
7
  import { Polygon } from '@tscircuit/math-utils';
8
8
 
@@ -27,6 +27,17 @@ type MultiLayerConnectionPoint = {
27
27
  pcb_port_id?: string;
28
28
  };
29
29
  type ConnectionPoint = SingleLayerConnectionPoint | MultiLayerConnectionPoint;
30
+ type Jumper$1 = {
31
+ jumper_footprint: "0603" | "1206x4";
32
+ center: {
33
+ x: number;
34
+ y: number;
35
+ };
36
+ orientation: "horizontal" | "vertical";
37
+ width: number;
38
+ height: number;
39
+ pads: Obstacle[];
40
+ };
30
41
  interface SimpleRouteJson {
31
42
  layerCount: number;
32
43
  minTraceWidth: number;
@@ -46,6 +57,7 @@ interface SimpleRouteJson {
46
57
  y: number;
47
58
  }>;
48
59
  traces?: SimplifiedPcbTraces;
60
+ jumpers?: Jumper$1[];
49
61
  allowJumpers?: boolean;
50
62
  }
51
63
  interface Obstacle {
@@ -244,6 +256,7 @@ type HighDensityIntraNodeRoute$1 = {
244
256
  x: number;
245
257
  y: number;
246
258
  z: number;
259
+ insideJumperPad?: boolean;
247
260
  }>;
248
261
  vias: Array<{
249
262
  x: number;
@@ -1827,7 +1840,11 @@ interface CreatePortPointSectionInput {
1827
1840
  connectionResults?: ConnectionPathResult[];
1828
1841
  }
1829
1842
 
1843
+ type HyperParameterScheduleEntry = PortPointPathingHyperParameters & {
1844
+ EXPANSION_DEGREES: number;
1845
+ };
1830
1846
  interface MultiSectionPortPointOptimizerParams {
1847
+ JUMPER_PF_FN_ENABLED?: boolean;
1831
1848
  simpleRouteJson: SimpleRouteJson;
1832
1849
  inputNodes: InputNodeWithPortPoints[];
1833
1850
  capacityMeshNodes: CapacityMeshNode[];
@@ -1853,6 +1870,21 @@ interface MultiSectionPortPointOptimizerParams {
1853
1870
  * even if they would otherwise be kept due to FRACTION_TO_REPLACE.
1854
1871
  */
1855
1872
  ALWAYS_RIP_INTERSECTIONS?: boolean;
1873
+ /**
1874
+ * Maximum number of attempts to fix a single node before moving on.
1875
+ * Default is 100.
1876
+ */
1877
+ MAX_ATTEMPTS_PER_NODE?: number;
1878
+ /**
1879
+ * Maximum total number of section optimization attempts.
1880
+ * Default is 500.
1881
+ */
1882
+ MAX_SECTION_ATTEMPTS?: number;
1883
+ /**
1884
+ * Custom hyperparameter schedule for optimization.
1885
+ * Each entry defines parameters for one optimization attempt.
1886
+ */
1887
+ HYPERPARAMETER_SCHEDULE?: HyperParameterScheduleEntry[];
1856
1888
  }
1857
1889
  /**
1858
1890
  * MultiSectionPortPointOptimizer runs local optimization on sections of the
@@ -1907,6 +1939,7 @@ declare class MultiSectionPortPointOptimizer extends BaseSolver {
1907
1939
  * Default 1 means rip all connections. Values less than 1 keep some traces.
1908
1940
  */
1909
1941
  FRACTION_TO_REPLACE: number;
1942
+ JUMPER_PF_FN_ENABLED: boolean;
1910
1943
  /**
1911
1944
  * If true, always rip connections that have same-layer intersections,
1912
1945
  * even if they would otherwise be kept due to FRACTION_TO_REPLACE.
@@ -1917,6 +1950,8 @@ declare class MultiSectionPortPointOptimizer extends BaseSolver {
1917
1950
  */
1918
1951
  ALWAYS_RIP_INTERSECTIONS: boolean;
1919
1952
  effort: number;
1953
+ /** Hyperparameter schedule for optimization attempts */
1954
+ HYPERPARAMETER_SCHEDULE: HyperParameterScheduleEntry[];
1920
1955
  constructor(params: MultiSectionPortPointOptimizerParams);
1921
1956
  /**
1922
1957
  * Compute initial Pf map for all nodes
@@ -1926,6 +1961,11 @@ declare class MultiSectionPortPointOptimizer extends BaseSolver {
1926
1961
  * Compute the score for the ENTIRE board (all nodes with port points).
1927
1962
  */
1928
1963
  computeBoardScore(): number;
1964
+ /**
1965
+ * Compute score for a set of nodes, using the appropriate scoring function
1966
+ * based on JUMPER_PF_FN_ENABLED.
1967
+ */
1968
+ computeScoreForNodes(nodesWithPortPoints: NodeWithPortPoints[]): number;
1929
1969
  /**
1930
1970
  * Recompute Pf for nodes in a section
1931
1971
  */
@@ -3036,7 +3076,16 @@ declare class JumperPrepatternSolver2_HyperGraph extends BaseSolver {
3036
3076
  minY: number;
3037
3077
  maxY: number;
3038
3078
  } | null;
3079
+ jumperLocations: Array<{
3080
+ center: {
3081
+ x: number;
3082
+ y: number;
3083
+ };
3084
+ orientation: "vertical" | "horizontal";
3085
+ padRegions: JRegion[];
3086
+ }>;
3039
3087
  solvedRoutes: HighDensityIntraNodeRouteWithJumpers[];
3088
+ jumpers: Jumper$1[];
3040
3089
  constructor(params: JumperPrepatternSolver2Params);
3041
3090
  getConstructorParams(): JumperPrepatternSolver2Params;
3042
3091
  private _buildColorMap;
@@ -3044,7 +3093,26 @@ declare class JumperPrepatternSolver2_HyperGraph extends BaseSolver {
3044
3093
  private _initializeGraph;
3045
3094
  _step(): void;
3046
3095
  private _processResults;
3096
+ /**
3097
+ * Post-process routes to add offset midpoints for collinear overlapping segments.
3098
+ *
3099
+ * When two segments are collinear and overlap (arranged as A-C-D-B where AB
3100
+ * is one segment and CD is another), the outer segment (AB) needs a midpoint
3101
+ * pushed to the side to hint to the force-directed graph that it should route
3102
+ * around the inner segment.
3103
+ *
3104
+ * This handles both:
3105
+ * 1. Segments from different connections that overlap
3106
+ * 2. Segments from the SAME connection that overlap (when a route doubles back)
3107
+ */
3108
+ private _addMidpointsForCollinearOverlaps;
3047
3109
  getOutput(): HighDensityIntraNodeRouteWithJumpers[];
3110
+ /**
3111
+ * Returns all jumpers from the baseGraph as SRJ Jumper objects.
3112
+ * The pads have connectedTo set based on which routes use each jumper.
3113
+ * Must be called after the solver is solved.
3114
+ */
3115
+ getOutputJumpers(): Jumper$1[];
3048
3116
  visualize(): GraphicsObject;
3049
3117
  private _drawJumperPads;
3050
3118
  }
@@ -3078,6 +3146,7 @@ declare class HyperJumperPrepatternSolver2 extends HyperParameterSupervisorSolve
3078
3146
  connMap?: ConnectivityMap;
3079
3147
  baseHyperParameters?: JumperPrepatternSolver2HyperParameters;
3080
3148
  solvedRoutes: HighDensityIntraNodeRouteWithJumpers[];
3149
+ jumpers: Jumper$1[];
3081
3150
  constructor(params: HyperJumperPrepatternSolver2Params);
3082
3151
  getConstructorParams(): HyperJumperPrepatternSolver2Params;
3083
3152
  getHyperParameterDefs(): ({
@@ -3097,6 +3166,7 @@ declare class HyperJumperPrepatternSolver2 extends HyperParameterSupervisorSolve
3097
3166
  computeH(solver: JumperPrepatternSolver2_HyperGraph): number;
3098
3167
  onSolve(solver: SupervisedSolver<JumperPrepatternSolver2_HyperGraph>): void;
3099
3168
  getOutput(): HighDensityIntraNodeRouteWithJumpers[];
3169
+ getOutputJumpers(): Jumper$1[];
3100
3170
  visualize(): GraphicsObject;
3101
3171
  }
3102
3172
 
@@ -3127,6 +3197,7 @@ declare class JumperHighDensitySolver extends BaseSolver {
3127
3197
  jumperSolvers: HyperJumperPrepatternSolver2[];
3128
3198
  currentJumperSolverIndex: number;
3129
3199
  phase: "analyzing" | "simple" | "jumpers" | "done";
3200
+ jumpers: Jumper$1[];
3130
3201
  constructor({ nodePortPoints, colorMap, traceWidth, viaDiameter, connMap, hyperParameters, }: {
3131
3202
  nodePortPoints: NodeWithPortPoints[];
3132
3203
  colorMap?: Record<string, string>;
@@ -3152,6 +3223,13 @@ declare class JumperHighDensitySolver extends BaseSolver {
3152
3223
  connMap: ConnectivityMap | undefined;
3153
3224
  hyperParameters: Partial<HighDensityHyperParameters> | undefined;
3154
3225
  };
3226
+ /**
3227
+ * Returns ALL jumpers collected from the jumper solvers.
3228
+ * These include all jumpers placed in the grid (from baseGraph.jumperLocations),
3229
+ * not just the ones used by routes. The pads have connectedTo set based on
3230
+ * which routes use each jumper.
3231
+ */
3232
+ getOutputJumpers(): Jumper$1[];
3155
3233
  visualize(): GraphicsObject;
3156
3234
  }
3157
3235
 
@@ -3193,6 +3271,7 @@ type HighDensityIntraNodeRoute = {
3193
3271
  x: number;
3194
3272
  y: number;
3195
3273
  z: number;
3274
+ insideJumperPad?: boolean;
3196
3275
  }>;
3197
3276
  vias: Array<{
3198
3277
  x: number;
@@ -3247,10 +3326,13 @@ interface Point2D$1 {
3247
3326
  }
3248
3327
  interface Point3D$1 extends Point2D$1 {
3249
3328
  z: number;
3329
+ insideJumperPad?: boolean;
3250
3330
  }
3251
3331
  interface TraceKeepoutSolverInput {
3252
3332
  hdRoutes: HighDensityRoute$1[];
3253
3333
  obstacles: Obstacle[];
3334
+ /** SRJ Jumpers with pre-computed pad obstacles. These will be added to the obstacle index. */
3335
+ jumpers?: Jumper$1[];
3254
3336
  connMap: ConnectivityMap;
3255
3337
  colorMap: Record<string, string>;
3256
3338
  keepoutRadiusSchedule?: number[];
@@ -3284,16 +3366,38 @@ declare class TraceKeepoutSolver extends BaseSolver {
3284
3366
  currentTraceSegmentT: number;
3285
3367
  recordedDrawPositions: Point3D$1[];
3286
3368
  lastCollidingSegments: Segment[];
3369
+ /** Maps segment index to the jumper that occupies that segment */
3370
+ currentTraceJumperSegments: Map<number, Jumper>;
3287
3371
  obstacleSHI: ObstacleSpatialHashIndex;
3288
3372
  hdRouteSHI: HighDensityRouteSpatialIndex;
3289
3373
  boardOutlineRoutes: HighDensityRoute$1[];
3290
3374
  constructor(input: TraceKeepoutSolverInput);
3291
3375
  getSmoothDistance(): number;
3376
+ /**
3377
+ * Extracts pad obstacles from the passed-in SRJ jumpers.
3378
+ * The pads already have connectedTo set based on which routes use each jumper.
3379
+ */
3380
+ private getJumperPadObstacles;
3381
+ /**
3382
+ * Builds a map from segment index to the jumper that occupies that segment.
3383
+ * A segment is considered a jumper segment if it connects points near the
3384
+ * jumper's start and end positions.
3385
+ *
3386
+ * Uses a larger tolerance for matching because routes may be modified during
3387
+ * collision avoidance passes, but we still need to find the segment that
3388
+ * represents each jumper.
3389
+ */
3390
+ private buildJumperSegmentMap;
3292
3391
  _step(): void;
3293
3392
  getStepDistance(): number;
3393
+ /**
3394
+ * Check if we're about to enter a jumper segment.
3395
+ * Returns the jumper if we're at the start of a jumper segment (T=0), null otherwise.
3396
+ */
3397
+ private getJumperAtCurrentSegmentStart;
3294
3398
  /**
3295
3399
  * Steps the cursor forward by CURSOR_STEP_DISTANCE along the trace
3296
- * Returns false if we've reached the end of the trace
3400
+ * Returns: "stepped" if normal step, "end" if reached end, "jumper" if crossed a jumper
3297
3401
  */
3298
3402
  private stepCursorForward;
3299
3403
  /**
@@ -3305,12 +3409,22 @@ declare class TraceKeepoutSolver extends BaseSolver {
3305
3409
  y: number;
3306
3410
  z: number;
3307
3411
  }, margin?: number): boolean;
3412
+ /**
3413
+ * Checks if a new segment would intersect with any route from unprocessedRoutes,
3414
+ * smoothedCursorRoutes, or processedRoutes (excluding routes with the same connection name).
3415
+ */
3416
+ private segmentIntersectsOtherRoutes;
3308
3417
  /**
3309
3418
  * Finalizes the current trace with the recorded draw positions
3310
3419
  */
3311
3420
  private finalizeCurrentTrace;
3312
3421
  /**
3313
- * Simplifies the route by removing collinear points
3422
+ * Checks if a point is a jumper endpoint.
3423
+ */
3424
+ private isJumperEndpoint;
3425
+ /**
3426
+ * Simplifies the route by removing collinear points, but preserves
3427
+ * jumper endpoints which must remain fixed.
3314
3428
  */
3315
3429
  private simplifyRoute;
3316
3430
  /**
@@ -3366,9 +3480,6 @@ declare class TraceWidthSolver extends BaseSolver {
3366
3480
  currentScheduleIndex: number;
3367
3481
  currentTargetWidth: number;
3368
3482
  hasInsufficientClearance: boolean;
3369
- currentWalkMinClearance: number;
3370
- bestMinClearance: number;
3371
- bestWidth: number;
3372
3483
  lastCollidingObstacles: Obstacle[];
3373
3484
  lastCollidingRoutes: HighDensityRoute$1[];
3374
3485
  lastClearance: number;
@@ -3386,8 +3497,14 @@ declare class TraceWidthSolver extends BaseSolver {
3386
3497
  /**
3387
3498
  * Steps the cursor forward by CURSOR_STEP_DISTANCE along the trace
3388
3499
  * Returns false if we've reached the end of the trace
3500
+ * Skips segments where both endpoints are inside jumper pads
3389
3501
  */
3390
3502
  private stepCursorForward;
3503
+ /**
3504
+ * Checks if an obstacle is a jumper pad belonging to the current trace's jumpers.
3505
+ * This is needed because jumper pads may not have connectedTo set properly.
3506
+ */
3507
+ private isObstacleOwnJumperPad;
3391
3508
  /**
3392
3509
  * Gets the minimum clearance at a given position from obstacles and other traces
3393
3510
  * Also updates lastCollidingObstacles and lastCollidingRoutes for visualization