@tscircuit/rectdiff 0.0.22 → 0.0.23

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.
@@ -602,7 +602,7 @@ export const SolverDebugger3d: React.FC<SolverDebugger3dProps> = ({
602
602
  useEffect(() => {
603
603
  const interval = setInterval(() => {
604
604
  // Only update if solver has output available
605
- if (solver.solved || (solver as any).stats?.placed > 0) {
605
+ if (solver.solved || solver.stats?.placed > 0) {
606
606
  updateMeshNodes()
607
607
  }
608
608
  }, 100) // Poll every 100ms during active solving
@@ -731,7 +731,7 @@ export const SolverDebugger3d: React.FC<SolverDebugger3dProps> = ({
731
731
  {/* Render 2D view */}
732
732
  {renderMode === "2d" && (
733
733
  <GenericSolverDebugger
734
- solver={solver as any}
734
+ solver={solver}
735
735
  onSolverCompleted={handleSolverCompleted}
736
736
  />
737
737
  )}
package/dist/index.d.ts CHANGED
@@ -220,6 +220,9 @@ type RectDiffSeedingSolverInput = {
220
220
  obstacleIndexByLayer: Array<RBush<RTreeRect>>;
221
221
  gridOptions?: Partial<GridFill3DOptions>;
222
222
  boardVoidRects?: XYRect[];
223
+ layerNames: string[];
224
+ zIndexByName: Map<string, number>;
225
+ obstacleClearance?: number;
223
226
  };
224
227
  /**
225
228
  * First phase of RectDiff: grid-based seeding and placement.
@@ -258,7 +261,6 @@ declare class RectDiffSeedingSolver extends BaseSolver {
258
261
  * expansion phase solver.
259
262
  */
260
263
  getOutput(): {
261
- srj: SimpleRouteJson;
262
264
  layerNames: string[];
263
265
  layerCount: number;
264
266
  bounds: XYRect;
@@ -274,13 +276,14 @@ declare class RectDiffSeedingSolver extends BaseSolver {
274
276
  edgeAnalysisDone: boolean;
275
277
  totalSeedsThisGrid: number;
276
278
  consumedSeedsThisGrid: number;
279
+ obstacles: Obstacle[];
280
+ obstacleClearance: number | undefined;
277
281
  };
278
282
  /** Visualization focused on the grid seeding phase. */
279
283
  visualize(): GraphicsObject;
280
284
  }
281
285
 
282
286
  type RectDiffExpansionSolverInput = {
283
- srj: SimpleRouteJson;
284
287
  layerNames: string[];
285
288
  layerCount: number;
286
289
  bounds: XYRect;
@@ -297,6 +300,10 @@ type RectDiffExpansionSolverInput = {
297
300
  totalSeedsThisGrid: number;
298
301
  consumedSeedsThisGrid: number;
299
302
  obstacleIndexByLayer: Array<RBush<RTreeRect>>;
303
+ zIndexByName: Map<string, number>;
304
+ layerNamesCanonical: string[];
305
+ obstacles: Obstacle[];
306
+ obstacleClearance?: number;
300
307
  };
301
308
  /**
302
309
  * Second phase of RectDiff: expand placed rects to their maximal extents.
@@ -322,14 +329,24 @@ declare class RectDiffExpansionSolver extends BaseSolver {
322
329
  }
323
330
 
324
331
  type RectDiffGridSolverPipelineInput = {
325
- simpleRouteJson: SimpleRouteJson;
332
+ bounds: Bounds;
333
+ obstacles: Obstacle[];
334
+ connections: SimpleRouteConnection[];
335
+ outline?: Pick<SimpleRouteJson, "outline">;
336
+ layerCount: number;
337
+ minTraceWidth: number;
338
+ obstacleClearance?: number;
326
339
  gridOptions?: Partial<GridFill3DOptions>;
327
340
  boardVoidRects?: XYRect[];
341
+ layerNames?: string[];
342
+ zIndexByName?: Map<string, number>;
328
343
  };
329
344
  declare class RectDiffGridSolverPipeline extends BasePipelineSolver<RectDiffGridSolverPipelineInput> {
330
345
  rectDiffSeedingSolver?: RectDiffSeedingSolver;
331
346
  rectDiffExpansionSolver?: RectDiffExpansionSolver;
332
347
  private obstacleIndexByLayer;
348
+ private layerNames;
349
+ private zIndexByName;
333
350
  constructor(inputProblem: RectDiffGridSolverPipelineInput);
334
351
  pipelineDef: PipelineStep<any>[];
335
352
  getConstructorParams(): RectDiffGridSolverPipelineInput[];
@@ -342,11 +359,14 @@ declare class RectDiffGridSolverPipeline extends BasePipelineSolver<RectDiffGrid
342
359
  interface RectDiffPipelineInput {
343
360
  simpleRouteJson: SimpleRouteJson;
344
361
  gridOptions?: Partial<GridFill3DOptions>;
362
+ obstacleClearance?: number;
345
363
  }
346
364
  declare class RectDiffPipeline extends BasePipelineSolver<RectDiffPipelineInput> {
347
365
  rectDiffGridSolverPipeline?: RectDiffGridSolverPipeline;
348
366
  gapFillSolver?: GapFillSolverPipeline;
349
367
  boardVoidRects: XYRect[] | undefined;
368
+ zIndexByName?: Map<string, number>;
369
+ layerNames?: string[];
350
370
  pipelineDef: PipelineStep<any>[];
351
371
  _setup(): void;
352
372
  getConstructorParams(): RectDiffPipelineInput[];
package/dist/index.js CHANGED
@@ -859,11 +859,11 @@ function canonicalizeLayerOrder(names) {
859
859
  return a.localeCompare(b);
860
860
  });
861
861
  }
862
- function buildZIndexMap(srj) {
862
+ function buildZIndexMap(params) {
863
863
  const names = canonicalizeLayerOrder(
864
- (srj.obstacles ?? []).flatMap((o) => o.layers ?? [])
864
+ (params.obstacles ?? []).flatMap((o) => o.layers ?? [])
865
865
  );
866
- const declaredLayerCount = Math.max(1, srj.layerCount || names.length || 1);
866
+ const declaredLayerCount = Math.max(1, params.layerCount || names.length || 1);
867
867
  const fallback = Array.from(
868
868
  { length: declaredLayerCount },
869
869
  (_, i) => i === 0 ? "top" : i === declaredLayerCount - 1 ? "bottom" : `inner${i}`
@@ -1710,7 +1710,14 @@ var RectDiffSeedingSolver = class extends BaseSolver3 {
1710
1710
  _setup() {
1711
1711
  const srj = this.input.simpleRouteJson;
1712
1712
  const opts = this.input.gridOptions ?? {};
1713
- const { layerNames, zIndexByName } = buildZIndexMap(srj);
1713
+ const precomputed = this.input.layerNames && this.input.zIndexByName;
1714
+ const { layerNames, zIndexByName } = precomputed ? {
1715
+ layerNames: this.input.layerNames,
1716
+ zIndexByName: this.input.zIndexByName
1717
+ } : buildZIndexMap({
1718
+ obstacles: srj.obstacles,
1719
+ layerCount: srj.layerCount
1720
+ });
1714
1721
  const layerCount = Math.max(1, layerNames.length, srj.layerCount || 1);
1715
1722
  const bounds = {
1716
1723
  x: srj.bounds.minX,
@@ -1908,7 +1915,6 @@ var RectDiffSeedingSolver = class extends BaseSolver3 {
1908
1915
  */
1909
1916
  getOutput() {
1910
1917
  return {
1911
- srj: this.srj,
1912
1918
  layerNames: this.layerNames,
1913
1919
  layerCount: this.layerCount,
1914
1920
  bounds: this.bounds,
@@ -1920,7 +1926,9 @@ var RectDiffSeedingSolver = class extends BaseSolver3 {
1920
1926
  expansionIndex: this.expansionIndex,
1921
1927
  edgeAnalysisDone: this.edgeAnalysisDone,
1922
1928
  totalSeedsThisGrid: this.totalSeedsThisGrid,
1923
- consumedSeedsThisGrid: this.consumedSeedsThisGrid
1929
+ consumedSeedsThisGrid: this.consumedSeedsThisGrid,
1930
+ obstacles: this.srj.obstacles,
1931
+ obstacleClearance: this.input.obstacleClearance
1924
1932
  };
1925
1933
  }
1926
1934
  /** Visualization focused on the grid seeding phase. */
@@ -1968,6 +1976,29 @@ var RectDiffSeedingSolver = class extends BaseSolver3 {
1968
1976
  });
1969
1977
  }
1970
1978
  }
1979
+ if (this.input.obstacleClearance && this.input.obstacleClearance > 0) {
1980
+ for (const obstacle of srj.obstacles ?? []) {
1981
+ const pad = this.input.obstacleClearance;
1982
+ const expanded = {
1983
+ x: obstacle.center.x - obstacle.width / 2 - pad,
1984
+ y: obstacle.center.y - obstacle.height / 2 - pad,
1985
+ width: obstacle.width + 2 * pad,
1986
+ height: obstacle.height + 2 * pad
1987
+ };
1988
+ rects.push({
1989
+ center: {
1990
+ x: expanded.x + expanded.width / 2,
1991
+ y: expanded.y + expanded.height / 2
1992
+ },
1993
+ width: expanded.width,
1994
+ height: expanded.height,
1995
+ fill: "rgba(234, 179, 8, 0.15)",
1996
+ stroke: "rgba(202, 138, 4, 0.9)",
1997
+ layer: "obstacle-clearance",
1998
+ label: "clearance"
1999
+ });
2000
+ }
2001
+ }
1971
2002
  if (this.boardVoidRects) {
1972
2003
  let outlineBBox = null;
1973
2004
  if (srj.outline && srj.outline.length > 0) {
@@ -2001,8 +2032,6 @@ var RectDiffSeedingSolver = class extends BaseSolver3 {
2001
2032
  points.push({
2002
2033
  x: cand.x,
2003
2034
  y: cand.y,
2004
- fill: "#9333ea",
2005
- stroke: "#6b21a8",
2006
2035
  label: `z:${cand.z}`
2007
2036
  });
2008
2037
  }
@@ -2047,12 +2076,17 @@ function finalizeRects(params) {
2047
2076
  maxY: p.rect.y + p.rect.height,
2048
2077
  zLayers: [...p.zLayers].sort((a, b) => a - b)
2049
2078
  }));
2050
- const { zIndexByName } = buildZIndexMap(params.srj);
2051
2079
  const layersByKey = /* @__PURE__ */ new Map();
2052
- for (const obstacle of params.srj.obstacles ?? []) {
2053
- const rect = obstacleToXYRect(obstacle);
2054
- if (!rect) continue;
2055
- const zLayers = obstacle.zLayers?.length && obstacle.zLayers.length > 0 ? obstacle.zLayers : obstacleZs(obstacle, zIndexByName);
2080
+ for (const obstacle of params.obstacles ?? []) {
2081
+ const baseRect = obstacleToXYRect(obstacle);
2082
+ if (!baseRect) continue;
2083
+ const rect = params.obstacleClearance ? {
2084
+ x: baseRect.x - params.obstacleClearance,
2085
+ y: baseRect.y - params.obstacleClearance,
2086
+ width: baseRect.width + 2 * params.obstacleClearance,
2087
+ height: baseRect.height + 2 * params.obstacleClearance
2088
+ } : baseRect;
2089
+ const zLayers = obstacle.zLayers?.length && obstacle.zLayers.length > 0 ? obstacle.zLayers : obstacleZs(obstacle, params.zIndexByName);
2056
2090
  const key = `${rect.x}:${rect.y}:${rect.width}:${rect.height}`;
2057
2091
  let entry = layersByKey.get(key);
2058
2092
  if (!entry) {
@@ -2182,8 +2216,10 @@ var RectDiffExpansionSolver = class extends BaseSolver4 {
2182
2216
  if (this.solved) return;
2183
2217
  const rects = finalizeRects({
2184
2218
  placed: this.input.placed,
2185
- srj: this.input.srj,
2186
- boardVoidRects: this.input.boardVoidRects
2219
+ obstacles: this.input.obstacles,
2220
+ zIndexByName: this.input.zIndexByName,
2221
+ boardVoidRects: this.input.boardVoidRects,
2222
+ obstacleClearance: this.input.obstacleClearance
2187
2223
  });
2188
2224
  this._meshNodes = rectsToMeshNodes(rects);
2189
2225
  this.solved = true;
@@ -2246,9 +2282,25 @@ import "rbush";
2246
2282
 
2247
2283
  // lib/solvers/RectDiffGridSolverPipeline/buildObstacleIndexes.ts
2248
2284
  import RBush5 from "rbush";
2285
+
2286
+ // lib/utils/padRect.ts
2287
+ var padRect = (rect, clearance) => {
2288
+ if (!clearance || clearance <= 0) return rect;
2289
+ return {
2290
+ x: rect.x - clearance,
2291
+ y: rect.y - clearance,
2292
+ width: rect.width + 2 * clearance,
2293
+ height: rect.height + 2 * clearance
2294
+ };
2295
+ };
2296
+
2297
+ // lib/solvers/RectDiffGridSolverPipeline/buildObstacleIndexes.ts
2249
2298
  var buildObstacleIndexesByLayer = (params) => {
2250
- const { srj, boardVoidRects } = params;
2251
- const { layerNames, zIndexByName } = buildZIndexMap(srj);
2299
+ const { srj, boardVoidRects, obstacleClearance } = params;
2300
+ const { layerNames, zIndexByName } = buildZIndexMap({
2301
+ obstacles: srj.obstacles,
2302
+ layerCount: srj.layerCount
2303
+ });
2252
2304
  const layerCount = Math.max(1, layerNames.length, srj.layerCount || 1);
2253
2305
  const bounds = {
2254
2306
  x: srj.bounds.minX,
@@ -2277,8 +2329,9 @@ var buildObstacleIndexesByLayer = (params) => {
2277
2329
  }
2278
2330
  }
2279
2331
  for (const obstacle of srj.obstacles ?? []) {
2280
- const rect = obstacleToXYRect(obstacle);
2281
- if (!rect) continue;
2332
+ const rectBase = obstacleToXYRect(obstacle);
2333
+ if (!rectBase) continue;
2334
+ const rect = padRect(rectBase, obstacleClearance ?? 0);
2282
2335
  const zLayers = obstacleZs(obstacle, zIndexByName);
2283
2336
  const invalidZs = zLayers.filter((z) => z < 0 || z >= layerCount);
2284
2337
  if (invalidZs.length) {
@@ -2291,7 +2344,7 @@ var buildObstacleIndexesByLayer = (params) => {
2291
2344
  }
2292
2345
  for (const z of zLayers) insertObstacle(rect, z);
2293
2346
  }
2294
- return { obstacleIndexByLayer };
2347
+ return { obstacleIndexByLayer, layerNames, zIndexByName };
2295
2348
  };
2296
2349
 
2297
2350
  // lib/solvers/RectDiffGridSolverPipeline/RectDiffGridSolverPipeline.ts
@@ -2299,13 +2352,25 @@ var RectDiffGridSolverPipeline = class extends BasePipelineSolver2 {
2299
2352
  rectDiffSeedingSolver;
2300
2353
  rectDiffExpansionSolver;
2301
2354
  obstacleIndexByLayer;
2355
+ layerNames;
2356
+ zIndexByName;
2302
2357
  constructor(inputProblem) {
2303
2358
  super(inputProblem);
2304
- const { obstacleIndexByLayer } = buildObstacleIndexesByLayer({
2305
- srj: inputProblem.simpleRouteJson,
2306
- boardVoidRects: inputProblem.boardVoidRects
2359
+ const { obstacleIndexByLayer, layerNames, zIndexByName } = buildObstacleIndexesByLayer({
2360
+ srj: {
2361
+ bounds: inputProblem.bounds,
2362
+ obstacles: inputProblem.obstacles,
2363
+ connections: inputProblem.connections,
2364
+ outline: inputProblem.outline?.outline,
2365
+ layerCount: inputProblem.layerCount,
2366
+ minTraceWidth: inputProblem.minTraceWidth
2367
+ },
2368
+ boardVoidRects: inputProblem.boardVoidRects,
2369
+ obstacleClearance: inputProblem.obstacleClearance
2307
2370
  });
2308
2371
  this.obstacleIndexByLayer = obstacleIndexByLayer;
2372
+ this.layerNames = inputProblem.layerNames ?? layerNames;
2373
+ this.zIndexByName = inputProblem.zIndexByName ?? zIndexByName;
2309
2374
  }
2310
2375
  pipelineDef = [
2311
2376
  definePipelineStep2(
@@ -2313,10 +2378,20 @@ var RectDiffGridSolverPipeline = class extends BasePipelineSolver2 {
2313
2378
  RectDiffSeedingSolver,
2314
2379
  (pipeline) => [
2315
2380
  {
2316
- simpleRouteJson: pipeline.inputProblem.simpleRouteJson,
2381
+ simpleRouteJson: {
2382
+ bounds: pipeline.inputProblem.bounds,
2383
+ obstacles: pipeline.inputProblem.obstacles,
2384
+ connections: pipeline.inputProblem.connections,
2385
+ outline: pipeline.inputProblem.outline?.outline,
2386
+ layerCount: pipeline.inputProblem.layerCount,
2387
+ minTraceWidth: pipeline.inputProblem.minTraceWidth
2388
+ },
2317
2389
  gridOptions: pipeline.inputProblem.gridOptions,
2318
2390
  obstacleIndexByLayer: pipeline.obstacleIndexByLayer,
2319
- boardVoidRects: pipeline.inputProblem.boardVoidRects
2391
+ boardVoidRects: pipeline.inputProblem.boardVoidRects,
2392
+ layerNames: pipeline.layerNames,
2393
+ zIndexByName: pipeline.zIndexByName,
2394
+ obstacleClearance: pipeline.inputProblem.obstacleClearance
2320
2395
  }
2321
2396
  ]
2322
2397
  ),
@@ -2330,10 +2405,9 @@ var RectDiffGridSolverPipeline = class extends BasePipelineSolver2 {
2330
2405
  }
2331
2406
  return [
2332
2407
  {
2333
- srj: pipeline.inputProblem.simpleRouteJson,
2334
2408
  layerNames: output.layerNames ?? [],
2335
2409
  boardVoidRects: pipeline.inputProblem.boardVoidRects ?? [],
2336
- layerCount: pipeline.inputProblem.simpleRouteJson.layerCount,
2410
+ layerCount: pipeline.inputProblem.layerCount,
2337
2411
  bounds: output.bounds,
2338
2412
  candidates: output.candidates,
2339
2413
  consumedSeedsThisGrid: output.placed.length,
@@ -2343,7 +2417,11 @@ var RectDiffGridSolverPipeline = class extends BasePipelineSolver2 {
2343
2417
  gridIndex: output.gridIndex,
2344
2418
  expansionIndex: output.expansionIndex,
2345
2419
  obstacleIndexByLayer: pipeline.obstacleIndexByLayer,
2346
- options: output.options
2420
+ options: output.options,
2421
+ zIndexByName: pipeline.zIndexByName,
2422
+ layerNamesCanonical: pipeline.layerNames,
2423
+ obstacles: pipeline.inputProblem.obstacles,
2424
+ obstacleClearance: pipeline.inputProblem.obstacleClearance
2347
2425
  }
2348
2426
  ];
2349
2427
  }
@@ -2424,6 +2502,7 @@ function createBaseVisualization(srj, title = "RectDiff") {
2424
2502
  }
2425
2503
  for (const obstacle of srj.obstacles ?? []) {
2426
2504
  if (obstacle.type === "rect" || obstacle.type === "oval") {
2505
+ const layerLabel = (obstacle.zLayers ?? []).join(",") || "all";
2427
2506
  rects.push({
2428
2507
  center: { x: obstacle.center.x, y: obstacle.center.y },
2429
2508
  width: obstacle.width,
@@ -2431,7 +2510,8 @@ function createBaseVisualization(srj, title = "RectDiff") {
2431
2510
  fill: "#fee2e2",
2432
2511
  stroke: "#ef4444",
2433
2512
  layer: "obstacle",
2434
- label: "obstacle"
2513
+ label: `obstacle
2514
+ z:${layerLabel}`
2435
2515
  });
2436
2516
  }
2437
2517
  }
@@ -2444,20 +2524,72 @@ function createBaseVisualization(srj, title = "RectDiff") {
2444
2524
  };
2445
2525
  }
2446
2526
 
2527
+ // lib/utils/renderObstacleClearance.ts
2528
+ var buildObstacleClearanceGraphics = (params) => {
2529
+ const { srj, clearance } = params;
2530
+ const c = clearance ?? 0;
2531
+ if (c <= 0) {
2532
+ return {
2533
+ title: "Obstacle Clearance",
2534
+ coordinateSystem: "cartesian",
2535
+ rects: []
2536
+ };
2537
+ }
2538
+ const rects = [];
2539
+ for (const obstacle of srj.obstacles ?? []) {
2540
+ if (obstacle.type !== "rect" && obstacle.type !== "oval") continue;
2541
+ const expanded = {
2542
+ x: obstacle.center.x - obstacle.width / 2 - c,
2543
+ y: obstacle.center.y - obstacle.height / 2 - c,
2544
+ width: obstacle.width + 2 * c,
2545
+ height: obstacle.height + 2 * c
2546
+ };
2547
+ rects.push({
2548
+ center: {
2549
+ x: expanded.x + expanded.width / 2,
2550
+ y: expanded.y + expanded.height / 2
2551
+ },
2552
+ width: expanded.width,
2553
+ height: expanded.height,
2554
+ stroke: "rgba(202, 138, 4, 0.9)",
2555
+ fill: "rgba(234, 179, 8, 0.15)",
2556
+ layer: "obstacle-clearance",
2557
+ label: `clearance
2558
+ z:${(obstacle.zLayers ?? []).join(",") || "all"}`
2559
+ });
2560
+ }
2561
+ return {
2562
+ title: "Obstacle Clearance",
2563
+ coordinateSystem: "cartesian",
2564
+ rects
2565
+ };
2566
+ };
2567
+
2447
2568
  // lib/RectDiffPipeline.ts
2569
+ import { mergeGraphics } from "graphics-debug";
2448
2570
  var RectDiffPipeline = class extends BasePipelineSolver3 {
2449
2571
  rectDiffGridSolverPipeline;
2450
2572
  gapFillSolver;
2451
2573
  boardVoidRects;
2574
+ zIndexByName;
2575
+ layerNames;
2452
2576
  pipelineDef = [
2453
2577
  definePipelineStep3(
2454
2578
  "rectDiffGridSolverPipeline",
2455
2579
  RectDiffGridSolverPipeline,
2456
2580
  (rectDiffPipeline) => [
2457
2581
  {
2458
- simpleRouteJson: rectDiffPipeline.inputProblem.simpleRouteJson,
2582
+ bounds: rectDiffPipeline.inputProblem.simpleRouteJson.bounds,
2583
+ obstacles: rectDiffPipeline.inputProblem.simpleRouteJson.obstacles,
2584
+ connections: rectDiffPipeline.inputProblem.simpleRouteJson.connections,
2585
+ outline: rectDiffPipeline.inputProblem.simpleRouteJson.outline ? { outline: rectDiffPipeline.inputProblem.simpleRouteJson.outline } : void 0,
2586
+ layerCount: rectDiffPipeline.inputProblem.simpleRouteJson.layerCount,
2459
2587
  gridOptions: rectDiffPipeline.inputProblem.gridOptions,
2460
- boardVoidRects: rectDiffPipeline.boardVoidRects
2588
+ boardVoidRects: rectDiffPipeline.boardVoidRects,
2589
+ layerNames: rectDiffPipeline.layerNames,
2590
+ zIndexByName: rectDiffPipeline.zIndexByName,
2591
+ minTraceWidth: rectDiffPipeline.inputProblem.simpleRouteJson.minTraceWidth,
2592
+ obstacleClearance: rectDiffPipeline.inputProblem.obstacleClearance
2461
2593
  }
2462
2594
  ]
2463
2595
  ),
@@ -2476,6 +2608,12 @@ var RectDiffPipeline = class extends BasePipelineSolver3 {
2476
2608
  )
2477
2609
  ];
2478
2610
  _setup() {
2611
+ const { zIndexByName, layerNames } = buildZIndexMap({
2612
+ obstacles: this.inputProblem.simpleRouteJson.obstacles,
2613
+ layerCount: this.inputProblem.simpleRouteJson.layerCount
2614
+ });
2615
+ this.zIndexByName = zIndexByName;
2616
+ this.layerNames = layerNames;
2479
2617
  if (this.inputProblem.simpleRouteJson.outline) {
2480
2618
  this.boardVoidRects = computeInverseRects(
2481
2619
  {
@@ -2502,13 +2640,19 @@ var RectDiffPipeline = class extends BasePipelineSolver3 {
2502
2640
  return { meshNodes: [] };
2503
2641
  }
2504
2642
  initialVisualize() {
2505
- const graphics = createBaseVisualization(
2643
+ const base = createBaseVisualization(
2506
2644
  this.inputProblem.simpleRouteJson,
2507
2645
  "RectDiffPipeline - Initial"
2508
2646
  );
2647
+ const clearance = buildObstacleClearanceGraphics({
2648
+ srj: this.inputProblem.simpleRouteJson,
2649
+ clearance: this.inputProblem.obstacleClearance
2650
+ });
2509
2651
  const initialNodes = this.rectDiffGridSolverPipeline?.getOutput().meshNodes ?? [];
2510
- for (const node of initialNodes) {
2511
- graphics.rects.push({
2652
+ const nodeRects = {
2653
+ title: "Initial Nodes",
2654
+ coordinateSystem: "cartesian",
2655
+ rects: initialNodes.map((node) => ({
2512
2656
  center: node.center,
2513
2657
  width: node.width,
2514
2658
  height: node.height,
@@ -2519,37 +2663,45 @@ var RectDiffPipeline = class extends BasePipelineSolver3 {
2519
2663
  `node ${node.capacityMeshNodeId}`,
2520
2664
  `z:${node.availableZ.join(",")}`
2521
2665
  ].join("\n")
2522
- });
2523
- }
2524
- return graphics;
2666
+ }))
2667
+ };
2668
+ return mergeGraphics(mergeGraphics(base, clearance), nodeRects);
2525
2669
  }
2526
2670
  finalVisualize() {
2527
- const graphics = createBaseVisualization(
2671
+ const base = createBaseVisualization(
2528
2672
  this.inputProblem.simpleRouteJson,
2529
2673
  "RectDiffPipeline - Final"
2530
2674
  );
2675
+ const clearance = buildObstacleClearanceGraphics({
2676
+ srj: this.inputProblem.simpleRouteJson,
2677
+ clearance: this.inputProblem.obstacleClearance
2678
+ });
2531
2679
  const { meshNodes: outputNodes } = this.getOutput();
2532
2680
  const initialNodeIds = new Set(
2533
2681
  (this.rectDiffGridSolverPipeline?.getOutput().meshNodes ?? []).map(
2534
2682
  (n) => n.capacityMeshNodeId
2535
2683
  )
2536
2684
  );
2537
- for (const node of outputNodes) {
2538
- const isExpanded = !initialNodeIds.has(node.capacityMeshNodeId);
2539
- graphics.rects.push({
2540
- center: node.center,
2541
- width: node.width,
2542
- height: node.height,
2543
- stroke: isExpanded ? "rgba(0, 128, 0, 0.8)" : "rgba(0, 0, 0, 0.3)",
2544
- fill: isExpanded ? "rgba(0, 200, 0, 0.3)" : "rgba(100, 100, 100, 0.1)",
2545
- layer: `z${node.availableZ.join(",")}`,
2546
- label: [
2547
- `${isExpanded ? "[expanded] " : ""}node ${node.capacityMeshNodeId}`,
2548
- `z:${node.availableZ.join(",")}`
2549
- ].join("\n")
2550
- });
2551
- }
2552
- return graphics;
2685
+ const nodeRects = {
2686
+ title: "Final Nodes",
2687
+ coordinateSystem: "cartesian",
2688
+ rects: outputNodes.map((node) => {
2689
+ const isExpanded = !initialNodeIds.has(node.capacityMeshNodeId);
2690
+ return {
2691
+ center: node.center,
2692
+ width: node.width,
2693
+ height: node.height,
2694
+ stroke: isExpanded ? "rgba(0, 128, 0, 0.8)" : "rgba(0, 0, 0, 0.3)",
2695
+ fill: isExpanded ? "rgba(0, 200, 0, 0.3)" : "rgba(100, 100, 100, 0.1)",
2696
+ layer: `z${node.availableZ.join(",")}`,
2697
+ label: [
2698
+ `${isExpanded ? "[expanded] " : ""}node ${node.capacityMeshNodeId}`,
2699
+ `z:${node.availableZ.join(",")}`
2700
+ ].join("\n")
2701
+ };
2702
+ })
2703
+ };
2704
+ return mergeGraphics(mergeGraphics(base, clearance), nodeRects);
2553
2705
  }
2554
2706
  };
2555
2707
  export {