@tscircuit/rectdiff 0.0.18 → 0.0.20

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
@@ -113,6 +113,7 @@ type RTreeRect = XYRect & {
113
113
  minY: number;
114
114
  maxX: number;
115
115
  maxY: number;
116
+ zLayers: number[];
116
117
  };
117
118
 
118
119
  interface SegmentWithAdjacentEmptySpace {
@@ -278,7 +279,7 @@ declare class RectDiffSeedingSolver extends BaseSolver {
278
279
  visualize(): GraphicsObject;
279
280
  }
280
281
 
281
- type RectDiffExpansionSolverSnapshot = {
282
+ type RectDiffExpansionSolverInput = {
282
283
  srj: SimpleRouteJson;
283
284
  layerNames: string[];
284
285
  layerCount: number;
@@ -295,9 +296,6 @@ type RectDiffExpansionSolverSnapshot = {
295
296
  edgeAnalysisDone: boolean;
296
297
  totalSeedsThisGrid: number;
297
298
  consumedSeedsThisGrid: number;
298
- };
299
- type RectDiffExpansionSolverInput = {
300
- initialSnapshot: RectDiffExpansionSolverSnapshot;
301
299
  obstacleIndexByLayer: Array<RBush<RTreeRect>>;
302
300
  };
303
301
  /**
@@ -308,21 +306,8 @@ type RectDiffExpansionSolverInput = {
308
306
  */
309
307
  declare class RectDiffExpansionSolver extends BaseSolver {
310
308
  private input;
311
- private srj;
312
- private layerNames;
313
- private layerCount;
314
- private bounds;
315
- private options;
316
- private boardVoidRects;
317
- private gridIndex;
318
- private candidates;
319
- private placed;
320
- private placedIndexByLayer;
321
- private expansionIndex;
322
- private edgeAnalysisDone;
323
- private totalSeedsThisGrid;
324
- private consumedSeedsThisGrid;
325
- private _meshNodes;
309
+ placedIndexByLayer: Array<RBush<RTreeRect>>;
310
+ _meshNodes: CapacityMeshNode[];
326
311
  constructor(input: RectDiffExpansionSolverInput);
327
312
  _setup(): void;
328
313
  _step(): void;
package/dist/index.js CHANGED
@@ -897,6 +897,48 @@ function obstacleToXYRect(ob) {
897
897
  return { x: ob.center.x - w / 2, y: ob.center.y - h / 2, width: w, height: h };
898
898
  }
899
899
 
900
+ // lib/utils/isSelfRect.ts
901
+ var EPS5 = 1e-9;
902
+ var isSelfRect = (params) => Math.abs(params.rect.x + params.rect.width / 2 - params.startX) < EPS5 && Math.abs(params.rect.y + params.rect.height / 2 - params.startY) < EPS5 && Math.abs(params.rect.width - params.initialW) < EPS5 && Math.abs(params.rect.height - params.initialH) < EPS5;
903
+
904
+ // lib/utils/searchStrip.ts
905
+ var searchStripRight = ({
906
+ rect,
907
+ bounds
908
+ }) => ({
909
+ x: rect.x,
910
+ y: rect.y,
911
+ width: bounds.x + bounds.width - rect.x,
912
+ height: rect.height
913
+ });
914
+ var searchStripDown = ({
915
+ rect,
916
+ bounds
917
+ }) => ({
918
+ x: rect.x,
919
+ y: rect.y,
920
+ width: rect.width,
921
+ height: bounds.y + bounds.height - rect.y
922
+ });
923
+ var searchStripLeft = ({
924
+ rect,
925
+ bounds
926
+ }) => ({
927
+ x: bounds.x,
928
+ y: rect.y,
929
+ width: rect.x - bounds.x,
930
+ height: rect.height
931
+ });
932
+ var searchStripUp = ({
933
+ rect,
934
+ bounds
935
+ }) => ({
936
+ x: rect.x,
937
+ y: bounds.y,
938
+ width: rect.width,
939
+ height: rect.y - bounds.y
940
+ });
941
+
900
942
  // lib/utils/expandRectFromSeed.ts
901
943
  function maxExpandRight(params) {
902
944
  const { r, bounds, blockers, maxAspect } = params;
@@ -982,13 +1024,36 @@ function maxExpandUp(params) {
982
1024
  }
983
1025
  return Math.max(0, e);
984
1026
  }
1027
+ var toRect = (tree) => ({
1028
+ x: tree.minX,
1029
+ y: tree.minY,
1030
+ width: tree.maxX - tree.minX,
1031
+ height: tree.maxY - tree.minY
1032
+ });
1033
+ var addBlocker = (params) => {
1034
+ const { rect, seen, blockers } = params;
1035
+ const key = `${rect.x}|${rect.y}|${rect.width}|${rect.height}`;
1036
+ if (seen.has(key)) return;
1037
+ seen.add(key);
1038
+ blockers.push(rect);
1039
+ };
1040
+ var toQueryRect = (params) => {
1041
+ const { bounds, rect } = params;
1042
+ const minX = Math.max(bounds.x, rect.x);
1043
+ const minY = Math.max(bounds.y, rect.y);
1044
+ const maxX = Math.min(bounds.x + bounds.width, rect.x + rect.width);
1045
+ const maxY = Math.min(bounds.y + bounds.height, rect.y + rect.height);
1046
+ if (maxX <= minX + EPS4 || maxY <= minY + EPS4) return null;
1047
+ return { minX, minY, maxX, maxY };
1048
+ };
985
1049
  function expandRectFromSeed(params) {
986
1050
  const {
987
1051
  startX,
988
1052
  startY,
989
1053
  gridSize,
990
1054
  bounds,
991
- blockers,
1055
+ obsticalIndexByLayer,
1056
+ placedIndexByLayer,
992
1057
  initialCellRatio,
993
1058
  maxAspectRatio,
994
1059
  minReq
@@ -996,6 +1061,37 @@ function expandRectFromSeed(params) {
996
1061
  const minSide = Math.max(1e-9, gridSize * initialCellRatio);
997
1062
  const initialW = Math.max(minSide, minReq.width);
998
1063
  const initialH = Math.max(minSide, minReq.height);
1064
+ const blockers = [];
1065
+ const seen = /* @__PURE__ */ new Set();
1066
+ const totalLayers = placedIndexByLayer.length;
1067
+ const collectBlockers = (searchRect) => {
1068
+ const query = toQueryRect({ bounds, rect: searchRect });
1069
+ if (!query) return;
1070
+ for (const z of params.zLayers) {
1071
+ const blockersIndex = obsticalIndexByLayer[z];
1072
+ if (blockersIndex) {
1073
+ for (const entry of blockersIndex.search(query))
1074
+ addBlocker({ rect: toRect(entry), seen, blockers });
1075
+ }
1076
+ const placedLayer = placedIndexByLayer[z];
1077
+ if (placedLayer) {
1078
+ for (const entry of placedLayer.search(query)) {
1079
+ const isFullStack = entry.zLayers.length >= totalLayers;
1080
+ if (!isFullStack) continue;
1081
+ const rect = toRect(entry);
1082
+ if (isSelfRect({
1083
+ rect,
1084
+ startX,
1085
+ startY,
1086
+ initialW,
1087
+ initialH
1088
+ }))
1089
+ continue;
1090
+ addBlocker({ rect, seen, blockers });
1091
+ }
1092
+ }
1093
+ }
1094
+ };
999
1095
  const strategies = [
1000
1096
  { ox: 0, oy: 0 },
1001
1097
  { ox: -initialW, oy: 0 },
@@ -1012,6 +1108,7 @@ function expandRectFromSeed(params) {
1012
1108
  width: initialW,
1013
1109
  height: initialH
1014
1110
  };
1111
+ collectBlockers(r);
1015
1112
  if (lt(r.x, bounds.x) || lt(r.y, bounds.y) || gt(r.x + r.width, bounds.x + bounds.width) || gt(r.y + r.height, bounds.y + bounds.height)) {
1016
1113
  continue;
1017
1114
  }
@@ -1020,24 +1117,32 @@ function expandRectFromSeed(params) {
1020
1117
  while (improved) {
1021
1118
  improved = false;
1022
1119
  const commonParams = { bounds, blockers, maxAspect: maxAspectRatio };
1120
+ collectBlockers(searchStripRight({ rect: r, bounds }));
1023
1121
  const eR = maxExpandRight({ ...commonParams, r });
1024
1122
  if (eR > 0) {
1025
1123
  r = { ...r, width: r.width + eR };
1124
+ collectBlockers(r);
1026
1125
  improved = true;
1027
1126
  }
1127
+ collectBlockers(searchStripDown({ rect: r, bounds }));
1028
1128
  const eD = maxExpandDown({ ...commonParams, r });
1029
1129
  if (eD > 0) {
1030
1130
  r = { ...r, height: r.height + eD };
1131
+ collectBlockers(r);
1031
1132
  improved = true;
1032
1133
  }
1134
+ collectBlockers(searchStripLeft({ rect: r, bounds }));
1033
1135
  const eL = maxExpandLeft({ ...commonParams, r });
1034
1136
  if (eL > 0) {
1035
1137
  r = { x: r.x - eL, y: r.y, width: r.width + eL, height: r.height };
1138
+ collectBlockers(r);
1036
1139
  improved = true;
1037
1140
  }
1141
+ collectBlockers(searchStripUp({ rect: r, bounds }));
1038
1142
  const eU = maxExpandUp({ ...commonParams, r });
1039
1143
  if (eU > 0) {
1040
1144
  r = { x: r.x, y: r.y - eU, width: r.width, height: r.height + eU };
1145
+ collectBlockers(r);
1041
1146
  improved = true;
1042
1147
  }
1043
1148
  }
@@ -1471,6 +1576,16 @@ function allLayerNode(params) {
1471
1576
  return out;
1472
1577
  }
1473
1578
 
1579
+ // lib/utils/rectToTree.ts
1580
+ var rectToTree = (rect, opts) => ({
1581
+ ...rect,
1582
+ minX: rect.x,
1583
+ minY: rect.y,
1584
+ maxX: rect.x + rect.width,
1585
+ maxY: rect.y + rect.height,
1586
+ zLayers: opts.zLayers
1587
+ });
1588
+
1474
1589
  // lib/utils/resizeSoftOverlaps.ts
1475
1590
  function resizeSoftOverlaps(params, newIndex) {
1476
1591
  const newcomer = params.placed[newIndex];
@@ -1505,20 +1620,17 @@ function resizeSoftOverlaps(params, newIndex) {
1505
1620
  }
1506
1621
  }
1507
1622
  }
1508
- const rectToTree2 = (rect) => ({
1509
- ...rect,
1510
- minX: rect.x,
1511
- minY: rect.y,
1512
- maxX: rect.x + rect.width,
1513
- maxY: rect.y + rect.height
1514
- });
1515
1623
  const sameRect = (a, b) => a.minX === b.minX && a.minY === b.minY && a.maxX === b.maxX && a.maxY === b.maxY;
1516
1624
  removeIdx.sort((a, b) => b - a).forEach((idx) => {
1517
1625
  const rem = params.placed.splice(idx, 1)[0];
1518
1626
  if (params.placedIndexByLayer) {
1519
1627
  for (const z of rem.zLayers) {
1520
1628
  const tree = params.placedIndexByLayer[z];
1521
- if (tree) tree.remove(rectToTree2(rem.rect), sameRect);
1629
+ if (tree)
1630
+ tree.remove(
1631
+ rectToTree(rem.rect, { zLayers: rem.zLayers }),
1632
+ sameRect
1633
+ );
1522
1634
  }
1523
1635
  }
1524
1636
  });
@@ -1528,13 +1640,7 @@ function resizeSoftOverlaps(params, newIndex) {
1528
1640
  if (params.placedIndexByLayer) {
1529
1641
  const idx = params.placedIndexByLayer[z];
1530
1642
  if (idx) {
1531
- idx.insert({
1532
- ...p.rect,
1533
- minX: p.rect.x,
1534
- minY: p.rect.y,
1535
- maxX: p.rect.x + p.rect.width,
1536
- maxY: p.rect.y + p.rect.height
1537
- });
1643
+ idx.insert(rectToTree(p.rect, { zLayers: p.zLayers.slice() }));
1538
1644
  }
1539
1645
  }
1540
1646
  }
@@ -1719,21 +1825,17 @@ var RectDiffSeedingSolver = class extends BaseSolver3 {
1719
1825
  });
1720
1826
  const ordered = preferMultiLayer ? attempts : attempts.reverse();
1721
1827
  for (const attempt of ordered) {
1722
- const hardBlockers = [];
1723
- for (const z of attempt.layers) {
1724
- const obstacleLayer = this.input.obstacleIndexByLayer[z];
1725
- if (obstacleLayer) hardBlockers.push(...obstacleLayer.all());
1726
- if (hardPlacedByLayer[z]) hardBlockers.push(...hardPlacedByLayer[z]);
1727
- }
1728
1828
  const rect = expandRectFromSeed({
1729
1829
  startX: cand.x,
1730
1830
  startY: cand.y,
1731
1831
  gridSize: grid,
1732
1832
  bounds: this.bounds,
1733
- blockers: hardBlockers,
1833
+ obsticalIndexByLayer: this.input.obstacleIndexByLayer,
1834
+ placedIndexByLayer: this.placedIndexByLayer,
1734
1835
  initialCellRatio,
1735
1836
  maxAspectRatio,
1736
- minReq: attempt.minReq
1837
+ minReq: attempt.minReq,
1838
+ zLayers: attempt.layers
1737
1839
  });
1738
1840
  if (!rect) continue;
1739
1841
  const placed = { rect, zLayers: [...attempt.layers] };
@@ -1741,13 +1843,7 @@ var RectDiffSeedingSolver = class extends BaseSolver3 {
1741
1843
  for (const z of attempt.layers) {
1742
1844
  const idx = this.placedIndexByLayer[z];
1743
1845
  if (idx) {
1744
- idx.insert({
1745
- ...rect,
1746
- minX: rect.x,
1747
- minY: rect.y,
1748
- maxX: rect.x + rect.width,
1749
- maxY: rect.y + rect.height
1750
- });
1846
+ idx.insert(rectToTree(rect, { zLayers: placed.zLayers }));
1751
1847
  }
1752
1848
  }
1753
1849
  resizeSoftOverlaps(
@@ -1979,15 +2075,6 @@ function rectsToMeshNodes(rects) {
1979
2075
  // lib/solvers/RectDiffExpansionSolver/RectDiffExpansionSolver.ts
1980
2076
  import RBush4 from "rbush";
1981
2077
 
1982
- // lib/utils/rectToTree.ts
1983
- var rectToTree = (rect) => ({
1984
- ...rect,
1985
- minX: rect.x,
1986
- minY: rect.y,
1987
- maxX: rect.x + rect.width,
1988
- maxY: rect.y + rect.height
1989
- });
1990
-
1991
2078
  // lib/utils/sameTreeRect.ts
1992
2079
  var sameTreeRect = (a, b) => a.minX === b.minX && a.minY === b.minY && a.maxX === b.maxX && a.maxY === b.maxY;
1993
2080
 
@@ -1996,148 +2083,116 @@ var RectDiffExpansionSolver = class extends BaseSolver4 {
1996
2083
  constructor(input) {
1997
2084
  super();
1998
2085
  this.input = input;
1999
- Object.assign(this, this.input.initialSnapshot);
2000
2086
  }
2001
- // Engine fields (same shape used by rectdiff/engine.ts)
2002
- srj;
2003
- layerNames;
2004
- layerCount;
2005
- bounds;
2006
- options;
2007
- boardVoidRects;
2008
- gridIndex;
2009
- candidates;
2010
- placed;
2011
- placedIndexByLayer;
2012
- expansionIndex;
2013
- edgeAnalysisDone;
2014
- totalSeedsThisGrid;
2015
- consumedSeedsThisGrid;
2087
+ placedIndexByLayer = [];
2016
2088
  _meshNodes = [];
2017
2089
  _setup() {
2018
2090
  this.stats = {
2019
- gridIndex: this.gridIndex
2091
+ gridIndex: this.input.gridIndex
2020
2092
  };
2021
- if (this.input.obstacleIndexByLayer) {
2022
- } else {
2023
- const { zIndexByName } = buildZIndexMap(this.srj);
2024
- this.input.obstacleIndexByLayer = Array.from(
2025
- { length: this.layerCount },
2026
- () => new RBush4()
2027
- );
2028
- const insertObstacle = (rect, z) => {
2029
- const tree = this.input.obstacleIndexByLayer[z];
2030
- if (tree) tree.insert(rectToTree(rect));
2031
- };
2032
- for (const voidRect of this.boardVoidRects ?? []) {
2033
- for (let z = 0; z < this.layerCount; z++) insertObstacle(voidRect, z);
2034
- }
2035
- for (const obstacle of this.srj.obstacles ?? []) {
2036
- const rect = obstacleToXYRect(obstacle);
2037
- if (!rect) continue;
2038
- const zLayers = obstacle.zLayers?.length && obstacle.zLayers.length > 0 ? obstacle.zLayers : obstacleZs(obstacle, zIndexByName);
2039
- zLayers.forEach((z) => {
2040
- if (z >= 0 && z < this.layerCount) insertObstacle(rect, z);
2041
- });
2042
- }
2043
- }
2044
2093
  this.placedIndexByLayer = Array.from(
2045
- { length: this.layerCount },
2094
+ { length: this.input.layerCount },
2046
2095
  () => new RBush4()
2047
2096
  );
2048
- for (const placement of this.placed ?? []) {
2097
+ for (const placement of this.input.placed) {
2049
2098
  for (const z of placement.zLayers) {
2050
- const tree = this.placedIndexByLayer[z];
2051
- if (tree) tree.insert(rectToTree(placement.rect));
2099
+ const placedIndex = this.placedIndexByLayer[z];
2100
+ if (placedIndex)
2101
+ placedIndex.insert(
2102
+ rectToTree(placement.rect, { zLayers: placement.zLayers })
2103
+ );
2052
2104
  }
2053
2105
  }
2054
2106
  }
2055
2107
  _step() {
2056
2108
  if (this.solved) return;
2057
2109
  this._stepExpansion();
2058
- this.stats.gridIndex = this.gridIndex;
2059
- this.stats.placed = this.placed.length;
2060
- if (this.expansionIndex >= this.placed.length) {
2110
+ this.stats.gridIndex = this.input.gridIndex;
2111
+ this.stats.placed = this.input.placed.length;
2112
+ if (this.input.expansionIndex >= this.input.placed.length) {
2061
2113
  this.finalizeIfNeeded();
2062
2114
  }
2063
2115
  }
2064
2116
  _stepExpansion() {
2065
- if (this.expansionIndex >= this.placed.length) {
2117
+ if (this.input.expansionIndex >= this.input.placed.length) {
2066
2118
  return;
2067
2119
  }
2068
- const idx = this.expansionIndex;
2069
- const p = this.placed[idx];
2070
- const lastGrid = this.options.gridSizes[this.options.gridSizes.length - 1];
2071
- const hardPlacedByLayer = allLayerNode({
2072
- layerCount: this.layerCount,
2073
- placed: this.placed
2074
- });
2075
- const hardBlockers = [];
2076
- for (const z of p.zLayers) {
2077
- const obstacleTree = this.input.obstacleIndexByLayer[z];
2078
- if (obstacleTree) hardBlockers.push(...obstacleTree.all());
2079
- hardBlockers.push(...hardPlacedByLayer[z] ?? []);
2080
- }
2120
+ const idx = this.input.expansionIndex;
2121
+ const p = this.input.placed[idx];
2122
+ const lastGrid = this.input.options.gridSizes[this.input.options.gridSizes.length - 1];
2081
2123
  const oldRect = p.rect;
2082
2124
  const expanded = expandRectFromSeed({
2083
2125
  startX: p.rect.x + p.rect.width / 2,
2084
2126
  startY: p.rect.y + p.rect.height / 2,
2085
2127
  gridSize: lastGrid,
2086
- bounds: this.bounds,
2087
- blockers: hardBlockers,
2128
+ bounds: this.input.bounds,
2129
+ obsticalIndexByLayer: this.input.obstacleIndexByLayer,
2130
+ placedIndexByLayer: this.placedIndexByLayer,
2088
2131
  initialCellRatio: 0,
2089
2132
  maxAspectRatio: null,
2090
- minReq: { width: p.rect.width, height: p.rect.height }
2133
+ minReq: { width: p.rect.width, height: p.rect.height },
2134
+ zLayers: p.zLayers
2091
2135
  });
2092
2136
  if (expanded) {
2093
- this.placed[idx] = { rect: expanded, zLayers: p.zLayers };
2137
+ this.input.placed[idx] = { rect: expanded, zLayers: p.zLayers };
2094
2138
  for (const z of p.zLayers) {
2095
2139
  const tree = this.placedIndexByLayer[z];
2096
2140
  if (tree) {
2097
- tree.remove(rectToTree(oldRect), sameTreeRect);
2098
- tree.insert(rectToTree(expanded));
2141
+ tree.remove(rectToTree(oldRect, { zLayers: p.zLayers }), sameTreeRect);
2142
+ tree.insert(rectToTree(expanded, { zLayers: p.zLayers }));
2099
2143
  }
2100
2144
  }
2101
2145
  resizeSoftOverlaps(
2102
2146
  {
2103
- layerCount: this.layerCount,
2104
- placed: this.placed,
2105
- options: this.options,
2147
+ layerCount: this.input.layerCount,
2148
+ placed: this.input.placed,
2149
+ options: this.input.options,
2106
2150
  placedIndexByLayer: this.placedIndexByLayer
2107
2151
  },
2108
2152
  idx
2109
2153
  );
2110
2154
  }
2111
- this.expansionIndex += 1;
2155
+ this.input.expansionIndex += 1;
2112
2156
  }
2113
2157
  finalizeIfNeeded() {
2114
2158
  if (this.solved) return;
2115
2159
  const rects = finalizeRects({
2116
- placed: this.placed,
2117
- srj: this.srj,
2118
- boardVoidRects: this.boardVoidRects
2160
+ placed: this.input.placed,
2161
+ srj: this.input.srj,
2162
+ boardVoidRects: this.input.boardVoidRects
2119
2163
  });
2120
2164
  this._meshNodes = rectsToMeshNodes(rects);
2121
2165
  this.solved = true;
2122
2166
  }
2123
2167
  computeProgress() {
2124
2168
  if (this.solved) return 1;
2125
- const grids = this.options.gridSizes.length;
2169
+ const grids = this.input.options.gridSizes.length;
2126
2170
  const base = grids / (grids + 1);
2127
- const denom = Math.max(1, this.placed.length);
2128
- const frac = denom ? this.expansionIndex / denom : 1;
2171
+ const denom = Math.max(1, this.input.placed.length);
2172
+ const frac = denom ? this.input.expansionIndex / denom : 1;
2129
2173
  return Math.min(0.999, base + frac * (1 / (grids + 1)));
2130
2174
  }
2131
2175
  getOutput() {
2132
- if (!this.solved && this._meshNodes.length === 0) {
2133
- this.finalizeIfNeeded();
2134
- }
2135
- return { meshNodes: this._meshNodes };
2176
+ if (this.solved) return { meshNodes: this._meshNodes };
2177
+ const previewNodes = this.input.placed.map(
2178
+ (placement, idx) => ({
2179
+ capacityMeshNodeId: `expand-preview-${idx}`,
2180
+ center: {
2181
+ x: placement.rect.x + placement.rect.width / 2,
2182
+ y: placement.rect.y + placement.rect.height / 2
2183
+ },
2184
+ width: placement.rect.width,
2185
+ height: placement.rect.height,
2186
+ availableZ: placement.zLayers.slice(),
2187
+ layer: `z${placement.zLayers.join(",")}`
2188
+ })
2189
+ );
2190
+ return { meshNodes: previewNodes };
2136
2191
  }
2137
2192
  /** Simple visualization of expanded placements. */
2138
2193
  visualize() {
2139
2194
  const rects = [];
2140
- for (const placement of this.placed ?? []) {
2195
+ for (const placement of this.input.placed ?? []) {
2141
2196
  rects.push({
2142
2197
  center: {
2143
2198
  x: placement.rect.x + placement.rect.width / 2,
@@ -2187,7 +2242,8 @@ var buildObstacleIndexesByLayer = (params) => {
2187
2242
  minX: rect.x,
2188
2243
  minY: rect.y,
2189
2244
  maxX: rect.x + rect.width,
2190
- maxY: rect.y + rect.height
2245
+ maxY: rect.y + rect.height,
2246
+ zLayers: [z]
2191
2247
  };
2192
2248
  obstacleIndexByLayer[z]?.insert(treeRect);
2193
2249
  };
@@ -2243,15 +2299,30 @@ var RectDiffGridSolverPipeline = class extends BasePipelineSolver2 {
2243
2299
  definePipelineStep2(
2244
2300
  "rectDiffExpansionSolver",
2245
2301
  RectDiffExpansionSolver,
2246
- (pipeline) => [
2247
- {
2248
- initialSnapshot: {
2249
- ...pipeline.rectDiffSeedingSolver.getOutput(),
2250
- boardVoidRects: pipeline.inputProblem.boardVoidRects ?? []
2251
- },
2252
- obstacleIndexByLayer: pipeline.obstacleIndexByLayer
2302
+ (pipeline) => {
2303
+ const output = pipeline.rectDiffSeedingSolver?.getOutput();
2304
+ if (!output) {
2305
+ throw new Error("RectDiffSeedingSolver did not produce output");
2253
2306
  }
2254
- ]
2307
+ return [
2308
+ {
2309
+ srj: pipeline.inputProblem.simpleRouteJson,
2310
+ layerNames: output.layerNames ?? [],
2311
+ boardVoidRects: pipeline.inputProblem.boardVoidRects ?? [],
2312
+ layerCount: pipeline.inputProblem.simpleRouteJson.layerCount,
2313
+ bounds: output.bounds,
2314
+ candidates: output.candidates,
2315
+ consumedSeedsThisGrid: output.placed.length,
2316
+ totalSeedsThisGrid: output.candidates.length,
2317
+ placed: output.placed,
2318
+ edgeAnalysisDone: output.edgeAnalysisDone,
2319
+ gridIndex: output.gridIndex,
2320
+ expansionIndex: output.expansionIndex,
2321
+ obstacleIndexByLayer: pipeline.obstacleIndexByLayer,
2322
+ options: output.options
2323
+ }
2324
+ ];
2325
+ }
2255
2326
  )
2256
2327
  ];
2257
2328
  getConstructorParams() {
@@ -1,8 +1,5 @@
1
1
  import RBush from "rbush"
2
- import type {
3
- RectDiffExpansionSolverInput,
4
- RectDiffExpansionSolverSnapshot,
5
- } from "../solvers/RectDiffExpansionSolver/RectDiffExpansionSolver"
2
+ import type { RectDiffExpansionSolverInput } from "../solvers/RectDiffExpansionSolver/RectDiffExpansionSolver"
6
3
  import type { SimpleRouteJson } from "../types/srj-types"
7
4
  import type { XYRect } from "../rectdiff-types"
8
5
  import type { RTreeRect } from "lib/types/capacity-mesh-types"
@@ -34,7 +31,7 @@ export const createTwoNodeExpansionInput = (): RectDiffExpansionSolverInput => {
34
31
  )
35
32
  // Start with all-empty obstacle indexes for a "clean" scenario
36
33
 
37
- const initialSnapshot: RectDiffExpansionSolverSnapshot = {
34
+ return {
38
35
  srj,
39
36
  layerNames: ["top"],
40
37
  layerCount,
@@ -57,10 +54,6 @@ export const createTwoNodeExpansionInput = (): RectDiffExpansionSolverInput => {
57
54
  edgeAnalysisDone: true,
58
55
  totalSeedsThisGrid: 0,
59
56
  consumedSeedsThisGrid: 0,
60
- }
61
-
62
- return {
63
- initialSnapshot,
64
57
  obstacleIndexByLayer,
65
58
  }
66
59
  }