From 0209dcfb1ee777478a35810ec66cf39af96e25ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?0hm=E2=98=98=EF=B8=8F?= Date: Thu, 25 Dec 2025 18:55:32 +0530 Subject: [PATCH 1/2] WIP --- lib/RectDiffPipeline.ts | 28 +++++++++++++- .../ExpandEdgesToEmptySpaceSolver.ts | 38 ++++++++++++++++--- .../GapFillSolver/GapFillSolverPipeline.ts | 13 +++++-- .../RectDiffGridSolverPipeline.ts | 16 ++++---- .../buildObstacleIndexes.ts | 15 ++++---- 5 files changed, 84 insertions(+), 26 deletions(-) diff --git a/lib/RectDiffPipeline.ts b/lib/RectDiffPipeline.ts index 4fafba1..b810a96 100644 --- a/lib/RectDiffPipeline.ts +++ b/lib/RectDiffPipeline.ts @@ -4,12 +4,13 @@ import { type PipelineStep, } from "@tscircuit/solver-utils" import type { SimpleRouteJson } from "./types/srj-types" -import type { GridFill3DOptions } from "./rectdiff-types" +import type { GridFill3DOptions, XYRect } from "./rectdiff-types" import type { CapacityMeshNode } from "./types/capacity-mesh-types" import type { GraphicsObject } from "graphics-debug" import { GapFillSolverPipeline } from "./solvers/GapFillSolver/GapFillSolverPipeline" import { RectDiffGridSolverPipeline } from "./solvers/RectDiffGridSolverPipeline/RectDiffGridSolverPipeline" import { createBaseVisualization } from "./rectdiff-visualization" +import { computeInverseRects } from "./solvers/RectDiffSeedingSolver/computeInverseRects" export interface RectDiffPipelineInput { simpleRouteJson: SimpleRouteJson @@ -19,6 +20,7 @@ export interface RectDiffPipelineInput { export class RectDiffPipeline extends BasePipelineSolver { rectDiffGridSolverPipeline?: RectDiffGridSolverPipeline gapFillSolver?: GapFillSolverPipeline + boardVoidRects: XYRect[] | undefined override pipelineDef: PipelineStep[] = [ definePipelineStep( @@ -28,6 +30,7 @@ export class RectDiffPipeline extends BasePipelineSolver { simpleRouteJson: rectDiffPipeline.inputProblem.simpleRouteJson, gridOptions: rectDiffPipeline.inputProblem.gridOptions, + boardVoidRects: rectDiffPipeline.boardVoidRects, }, ], ), @@ -39,11 +42,34 @@ export class RectDiffPipeline extends BasePipelineSolver meshNodes: rectDiffPipeline.rectDiffGridSolverPipeline?.getOutput() .meshNodes ?? [], + boardVoid: { + boardVoidRects: rectDiffPipeline.boardVoidRects || [], + layerCount: + rectDiffPipeline.inputProblem.simpleRouteJson.layerCount || 0, + }, }, ], ), ] + override _setup(): void { + if (this.inputProblem.simpleRouteJson.outline) { + this.boardVoidRects = computeInverseRects( + { + x: this.inputProblem.simpleRouteJson.bounds.minX, + y: this.inputProblem.simpleRouteJson.bounds.minY, + width: + this.inputProblem.simpleRouteJson.bounds.maxX - + this.inputProblem.simpleRouteJson.bounds.minX, + height: + this.inputProblem.simpleRouteJson.bounds.maxY - + this.inputProblem.simpleRouteJson.bounds.minY, + }, + this.inputProblem.simpleRouteJson.outline ?? [], + ) + } + } + override getConstructorParams() { return [this.inputProblem] } diff --git a/lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts b/lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts index 109cbe5..fb21c92 100644 --- a/lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts +++ b/lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts @@ -7,9 +7,19 @@ import { EDGE_MAP, EDGES } from "./edge-constants" import { getBoundsFromCorners } from "./getBoundsFromCorners" import type { Bounds } from "@tscircuit/math-utils" import { midpoint, segmentToBoxMinDistance } from "@tscircuit/math-utils" +import type { XYRect } from "lib/rectdiff-types" const EPS = 1e-4 +export type ExpandEdgesToEmptySpaceSolverInput = { + inputMeshNodes: CapacityMeshNode[] + segmentsWithAdjacentEmptySpace: Array + boardVoid?: { + boardVoidRects: XYRect[] + layerCount: number + } +} + export interface ExpandedSegment { segment: SegmentWithAdjacentEmptySpace newNode: CapacityMeshNode @@ -28,15 +38,31 @@ export class ExpandEdgesToEmptySpaceSolver extends BaseSolver { rectSpatialIndex: RBush - constructor( - private input: { - inputMeshNodes: CapacityMeshNode[] - segmentsWithAdjacentEmptySpace: Array - }, - ) { + constructor(private input: ExpandEdgesToEmptySpaceSolverInput) { super() this.unprocessedSegments = [...this.input.segmentsWithAdjacentEmptySpace] this.rectSpatialIndex = new RBush() + // create fake bound for the boardVoidRects + this.rectSpatialIndex.load( + this.input.boardVoid?.boardVoidRects.map((rect, index) => ({ + capacityMeshNodeId: `void-rect-${index}`, + center: { + x: rect.x + rect.width / 2, + y: rect.y + rect.height / 2, + }, + width: rect.width, + height: rect.height, + availableZ: Array.from( + { length: this.input.boardVoid?.layerCount || 0 }, + (_, i) => i, + ), + layer: "void", + minX: rect.x, + minY: rect.y, + maxX: rect.x + rect.width, + maxY: rect.y + rect.height, + })) || [], + ) this.rectSpatialIndex.load( this.input.inputMeshNodes.map((n) => ({ ...n, diff --git a/lib/solvers/GapFillSolver/GapFillSolverPipeline.ts b/lib/solvers/GapFillSolver/GapFillSolverPipeline.ts index 465117a..cb2e231 100644 --- a/lib/solvers/GapFillSolver/GapFillSolverPipeline.ts +++ b/lib/solvers/GapFillSolver/GapFillSolverPipeline.ts @@ -3,15 +3,21 @@ import { definePipelineStep, type PipelineStep, } from "@tscircuit/solver-utils" -import type { SimpleRouteJson } from "lib/types/srj-types" import type { CapacityMeshNode } from "lib/types/capacity-mesh-types" import type { GraphicsObject } from "graphics-debug" import { FindSegmentsWithAdjacentEmptySpaceSolver } from "./FindSegmentsWithAdjacentEmptySpaceSolver" import { ExpandEdgesToEmptySpaceSolver } from "./ExpandEdgesToEmptySpaceSolver" +import type { XYRect } from "lib/rectdiff-types" -export class GapFillSolverPipeline extends BasePipelineSolver<{ +type GapFillSolverInput = { meshNodes: CapacityMeshNode[] -}> { + boardVoid?: { + boardVoidRects: XYRect[] + layerCount: number + } +} + +export class GapFillSolverPipeline extends BasePipelineSolver { findSegmentsWithAdjacentEmptySpaceSolver?: FindSegmentsWithAdjacentEmptySpaceSolver expandEdgesToEmptySpaceSolver?: ExpandEdgesToEmptySpaceSolver @@ -39,6 +45,7 @@ export class GapFillSolverPipeline extends BasePipelineSolver<{ segmentsWithAdjacentEmptySpace: gapFillPipeline.findSegmentsWithAdjacentEmptySpaceSolver!.getOutput() .segmentsWithAdjacentEmptySpace, + boardVoid: gapFillPipeline.inputProblem.boardVoid, }, ], { diff --git a/lib/solvers/RectDiffGridSolverPipeline/RectDiffGridSolverPipeline.ts b/lib/solvers/RectDiffGridSolverPipeline/RectDiffGridSolverPipeline.ts index 583d48f..faafa3f 100644 --- a/lib/solvers/RectDiffGridSolverPipeline/RectDiffGridSolverPipeline.ts +++ b/lib/solvers/RectDiffGridSolverPipeline/RectDiffGridSolverPipeline.ts @@ -10,26 +10,26 @@ import { RectDiffSeedingSolver } from "lib/solvers/RectDiffSeedingSolver/RectDif import { RectDiffExpansionSolver } from "lib/solvers/RectDiffExpansionSolver/RectDiffExpansionSolver" import type { GraphicsObject } from "graphics-debug" import RBush from "rbush" -import { buildObstacleIndexes } from "./buildObstacleIndexes" +import { buildObstacleIndexesByLayer } from "./buildObstacleIndexes" export type RectDiffGridSolverPipelineInput = { simpleRouteJson: SimpleRouteJson gridOptions?: Partial + boardVoidRects?: XYRect[] } export class RectDiffGridSolverPipeline extends BasePipelineSolver { rectDiffSeedingSolver?: RectDiffSeedingSolver rectDiffExpansionSolver?: RectDiffExpansionSolver - private boardVoidRects?: XYRect[] private obstacleIndexByLayer: Array> constructor(inputProblem: RectDiffGridSolverPipelineInput) { super(inputProblem) - const { obstacleIndexByLayer, boardVoidRects } = buildObstacleIndexes( - inputProblem.simpleRouteJson, - ) + const { obstacleIndexByLayer } = buildObstacleIndexesByLayer({ + srj: inputProblem.simpleRouteJson, + boardVoidRects: inputProblem.boardVoidRects, + }) this.obstacleIndexByLayer = obstacleIndexByLayer - this.boardVoidRects = boardVoidRects } override pipelineDef: PipelineStep[] = [ @@ -41,7 +41,7 @@ export class RectDiffGridSolverPipeline extends BasePipelineSolver> - boardVoidRects: XYRect[] } => { + const { srj, boardVoidRects } = params const { layerNames, zIndexByName } = buildZIndexMap(srj) const layerCount = Math.max(1, layerNames.length, srj.layerCount || 1) const bounds: XYRect = { @@ -39,10 +40,8 @@ export const buildObstacleIndexes = ( obstacleIndexByLayer[z]?.insert(treeRect) } - let boardVoidRects: XYRect[] = [] if (srj.outline && srj.outline.length > 2) { - boardVoidRects = computeInverseRects(bounds, srj.outline as any) - for (const voidRect of boardVoidRects) { + for (const voidRect of boardVoidRects ?? []) { for (let z = 0; z < layerCount; z++) insertObstacle(voidRect, z) } } @@ -66,5 +65,5 @@ export const buildObstacleIndexes = ( for (const z of zLayers) insertObstacle(rect, z) } - return { obstacleIndexByLayer, boardVoidRects } + return { obstacleIndexByLayer } } From 7e32cce24338d7405b4569101c636d3222595df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?0hm=E2=98=98=EF=B8=8F?= Date: Thu, 25 Dec 2025 19:07:39 +0530 Subject: [PATCH 2/2] removed unnned code and fixed the test --- tests/__snapshots__/board-outline.snap.svg | 17 +-- tests/board-outline.test.ts | 13 +- tests/fixtures/getPerLayerVisualizations.ts | 130 -------------------- 3 files changed, 11 insertions(+), 149 deletions(-) delete mode 100644 tests/fixtures/getPerLayerVisualizations.ts diff --git a/tests/__snapshots__/board-outline.snap.svg b/tests/__snapshots__/board-outline.snap.svg index 0e96bff..8f9b27f 100644 --- a/tests/__snapshots__/board-outline.snap.svg +++ b/tests/__snapshots__/board-outline.snap.svg @@ -1,19 +1,4 @@ -