Skip to content

Commit 79e6593

Browse files
authored
fix board outline (#49)
1 parent 66456b5 commit 79e6593

8 files changed

Lines changed: 95 additions & 175 deletions

File tree

lib/RectDiffPipeline.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import {
44
type PipelineStep,
55
} from "@tscircuit/solver-utils"
66
import type { SimpleRouteJson } from "./types/srj-types"
7-
import type { GridFill3DOptions } from "./rectdiff-types"
7+
import type { GridFill3DOptions, XYRect } from "./rectdiff-types"
88
import type { CapacityMeshNode } from "./types/capacity-mesh-types"
99
import type { GraphicsObject } from "graphics-debug"
1010
import { GapFillSolverPipeline } from "./solvers/GapFillSolver/GapFillSolverPipeline"
1111
import { RectDiffGridSolverPipeline } from "./solvers/RectDiffGridSolverPipeline/RectDiffGridSolverPipeline"
1212
import { createBaseVisualization } from "./rectdiff-visualization"
13+
import { computeInverseRects } from "./solvers/RectDiffSeedingSolver/computeInverseRects"
1314

1415
export interface RectDiffPipelineInput {
1516
simpleRouteJson: SimpleRouteJson
@@ -19,6 +20,7 @@ export interface RectDiffPipelineInput {
1920
export class RectDiffPipeline extends BasePipelineSolver<RectDiffPipelineInput> {
2021
rectDiffGridSolverPipeline?: RectDiffGridSolverPipeline
2122
gapFillSolver?: GapFillSolverPipeline
23+
boardVoidRects: XYRect[] | undefined
2224

2325
override pipelineDef: PipelineStep<any>[] = [
2426
definePipelineStep(
@@ -28,6 +30,7 @@ export class RectDiffPipeline extends BasePipelineSolver<RectDiffPipelineInput>
2830
{
2931
simpleRouteJson: rectDiffPipeline.inputProblem.simpleRouteJson,
3032
gridOptions: rectDiffPipeline.inputProblem.gridOptions,
33+
boardVoidRects: rectDiffPipeline.boardVoidRects,
3134
},
3235
],
3336
),
@@ -39,11 +42,34 @@ export class RectDiffPipeline extends BasePipelineSolver<RectDiffPipelineInput>
3942
meshNodes:
4043
rectDiffPipeline.rectDiffGridSolverPipeline?.getOutput()
4144
.meshNodes ?? [],
45+
boardVoid: {
46+
boardVoidRects: rectDiffPipeline.boardVoidRects || [],
47+
layerCount:
48+
rectDiffPipeline.inputProblem.simpleRouteJson.layerCount || 0,
49+
},
4250
},
4351
],
4452
),
4553
]
4654

55+
override _setup(): void {
56+
if (this.inputProblem.simpleRouteJson.outline) {
57+
this.boardVoidRects = computeInverseRects(
58+
{
59+
x: this.inputProblem.simpleRouteJson.bounds.minX,
60+
y: this.inputProblem.simpleRouteJson.bounds.minY,
61+
width:
62+
this.inputProblem.simpleRouteJson.bounds.maxX -
63+
this.inputProblem.simpleRouteJson.bounds.minX,
64+
height:
65+
this.inputProblem.simpleRouteJson.bounds.maxY -
66+
this.inputProblem.simpleRouteJson.bounds.minY,
67+
},
68+
this.inputProblem.simpleRouteJson.outline ?? [],
69+
)
70+
}
71+
}
72+
4773
override getConstructorParams() {
4874
return [this.inputProblem]
4975
}

lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,19 @@ import { EDGE_MAP, EDGES } from "./edge-constants"
77
import { getBoundsFromCorners } from "./getBoundsFromCorners"
88
import type { Bounds } from "@tscircuit/math-utils"
99
import { midpoint, segmentToBoxMinDistance } from "@tscircuit/math-utils"
10+
import type { XYRect } from "lib/rectdiff-types"
1011

1112
const EPS = 1e-4
1213

14+
export type ExpandEdgesToEmptySpaceSolverInput = {
15+
inputMeshNodes: CapacityMeshNode[]
16+
segmentsWithAdjacentEmptySpace: Array<SegmentWithAdjacentEmptySpace>
17+
boardVoid?: {
18+
boardVoidRects: XYRect[]
19+
layerCount: number
20+
}
21+
}
22+
1323
export interface ExpandedSegment {
1424
segment: SegmentWithAdjacentEmptySpace
1525
newNode: CapacityMeshNode
@@ -28,15 +38,31 @@ export class ExpandEdgesToEmptySpaceSolver extends BaseSolver {
2838

2939
rectSpatialIndex: RBush<CapacityMeshNode>
3040

31-
constructor(
32-
private input: {
33-
inputMeshNodes: CapacityMeshNode[]
34-
segmentsWithAdjacentEmptySpace: Array<SegmentWithAdjacentEmptySpace>
35-
},
36-
) {
41+
constructor(private input: ExpandEdgesToEmptySpaceSolverInput) {
3742
super()
3843
this.unprocessedSegments = [...this.input.segmentsWithAdjacentEmptySpace]
3944
this.rectSpatialIndex = new RBush<CapacityMeshNode>()
45+
// create fake bound for the boardVoidRects
46+
this.rectSpatialIndex.load(
47+
this.input.boardVoid?.boardVoidRects.map((rect, index) => ({
48+
capacityMeshNodeId: `void-rect-${index}`,
49+
center: {
50+
x: rect.x + rect.width / 2,
51+
y: rect.y + rect.height / 2,
52+
},
53+
width: rect.width,
54+
height: rect.height,
55+
availableZ: Array.from(
56+
{ length: this.input.boardVoid?.layerCount || 0 },
57+
(_, i) => i,
58+
),
59+
layer: "void",
60+
minX: rect.x,
61+
minY: rect.y,
62+
maxX: rect.x + rect.width,
63+
maxY: rect.y + rect.height,
64+
})) || [],
65+
)
4066
this.rectSpatialIndex.load(
4167
this.input.inputMeshNodes.map((n) => ({
4268
...n,

lib/solvers/GapFillSolver/GapFillSolverPipeline.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@ import {
33
definePipelineStep,
44
type PipelineStep,
55
} from "@tscircuit/solver-utils"
6-
import type { SimpleRouteJson } from "lib/types/srj-types"
76
import type { CapacityMeshNode } from "lib/types/capacity-mesh-types"
87
import type { GraphicsObject } from "graphics-debug"
98
import { FindSegmentsWithAdjacentEmptySpaceSolver } from "./FindSegmentsWithAdjacentEmptySpaceSolver"
109
import { ExpandEdgesToEmptySpaceSolver } from "./ExpandEdgesToEmptySpaceSolver"
10+
import type { XYRect } from "lib/rectdiff-types"
1111

12-
export class GapFillSolverPipeline extends BasePipelineSolver<{
12+
type GapFillSolverInput = {
1313
meshNodes: CapacityMeshNode[]
14-
}> {
14+
boardVoid?: {
15+
boardVoidRects: XYRect[]
16+
layerCount: number
17+
}
18+
}
19+
20+
export class GapFillSolverPipeline extends BasePipelineSolver<GapFillSolverInput> {
1521
findSegmentsWithAdjacentEmptySpaceSolver?: FindSegmentsWithAdjacentEmptySpaceSolver
1622
expandEdgesToEmptySpaceSolver?: ExpandEdgesToEmptySpaceSolver
1723

@@ -39,6 +45,7 @@ export class GapFillSolverPipeline extends BasePipelineSolver<{
3945
segmentsWithAdjacentEmptySpace:
4046
gapFillPipeline.findSegmentsWithAdjacentEmptySpaceSolver!.getOutput()
4147
.segmentsWithAdjacentEmptySpace,
48+
boardVoid: gapFillPipeline.inputProblem.boardVoid,
4249
},
4350
],
4451
{

lib/solvers/RectDiffGridSolverPipeline/RectDiffGridSolverPipeline.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,26 @@ import { RectDiffSeedingSolver } from "lib/solvers/RectDiffSeedingSolver/RectDif
1010
import { RectDiffExpansionSolver } from "lib/solvers/RectDiffExpansionSolver/RectDiffExpansionSolver"
1111
import type { GraphicsObject } from "graphics-debug"
1212
import RBush from "rbush"
13-
import { buildObstacleIndexes } from "./buildObstacleIndexes"
13+
import { buildObstacleIndexesByLayer } from "./buildObstacleIndexes"
1414

1515
export type RectDiffGridSolverPipelineInput = {
1616
simpleRouteJson: SimpleRouteJson
1717
gridOptions?: Partial<GridFill3DOptions>
18+
boardVoidRects?: XYRect[]
1819
}
1920

2021
export class RectDiffGridSolverPipeline extends BasePipelineSolver<RectDiffGridSolverPipelineInput> {
2122
rectDiffSeedingSolver?: RectDiffSeedingSolver
2223
rectDiffExpansionSolver?: RectDiffExpansionSolver
23-
private boardVoidRects?: XYRect[]
2424
private obstacleIndexByLayer: Array<RBush<RTreeRect>>
2525

2626
constructor(inputProblem: RectDiffGridSolverPipelineInput) {
2727
super(inputProblem)
28-
const { obstacleIndexByLayer, boardVoidRects } = buildObstacleIndexes(
29-
inputProblem.simpleRouteJson,
30-
)
28+
const { obstacleIndexByLayer } = buildObstacleIndexesByLayer({
29+
srj: inputProblem.simpleRouteJson,
30+
boardVoidRects: inputProblem.boardVoidRects,
31+
})
3132
this.obstacleIndexByLayer = obstacleIndexByLayer
32-
this.boardVoidRects = boardVoidRects
3333
}
3434

3535
override pipelineDef: PipelineStep<any>[] = [
@@ -41,7 +41,7 @@ export class RectDiffGridSolverPipeline extends BasePipelineSolver<RectDiffGridS
4141
simpleRouteJson: pipeline.inputProblem.simpleRouteJson,
4242
gridOptions: pipeline.inputProblem.gridOptions,
4343
obstacleIndexByLayer: pipeline.obstacleIndexByLayer,
44-
boardVoidRects: pipeline.boardVoidRects,
44+
boardVoidRects: pipeline.inputProblem.boardVoidRects,
4545
},
4646
],
4747
),
@@ -52,7 +52,7 @@ export class RectDiffGridSolverPipeline extends BasePipelineSolver<RectDiffGridS
5252
{
5353
initialSnapshot: {
5454
...pipeline.rectDiffSeedingSolver!.getOutput(),
55-
boardVoidRects: pipeline.boardVoidRects ?? [],
55+
boardVoidRects: pipeline.inputProblem.boardVoidRects ?? [],
5656
},
5757
obstacleIndexByLayer: pipeline.obstacleIndexByLayer,
5858
},

lib/solvers/RectDiffGridSolverPipeline/buildObstacleIndexes.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import {
99
import type { XYRect } from "lib/rectdiff-types"
1010
import type { RTreeRect } from "lib/types/capacity-mesh-types"
1111

12-
export const buildObstacleIndexes = (
13-
srj: SimpleRouteJson,
14-
): {
12+
export const buildObstacleIndexesByLayer = (params: {
13+
srj: SimpleRouteJson
14+
boardVoidRects?: XYRect[]
15+
}): {
1516
obstacleIndexByLayer: Array<RBush<RTreeRect>>
16-
boardVoidRects: XYRect[]
1717
} => {
18+
const { srj, boardVoidRects } = params
1819
const { layerNames, zIndexByName } = buildZIndexMap(srj)
1920
const layerCount = Math.max(1, layerNames.length, srj.layerCount || 1)
2021
const bounds: XYRect = {
@@ -39,10 +40,8 @@ export const buildObstacleIndexes = (
3940
obstacleIndexByLayer[z]?.insert(treeRect)
4041
}
4142

42-
let boardVoidRects: XYRect[] = []
4343
if (srj.outline && srj.outline.length > 2) {
44-
boardVoidRects = computeInverseRects(bounds, srj.outline as any)
45-
for (const voidRect of boardVoidRects) {
44+
for (const voidRect of boardVoidRects ?? []) {
4645
for (let z = 0; z < layerCount; z++) insertObstacle(voidRect, z)
4746
}
4847
}
@@ -66,5 +65,5 @@ export const buildObstacleIndexes = (
6665
for (const z of zLayers) insertObstacle(rect, z)
6766
}
6867

69-
return { obstacleIndexByLayer, boardVoidRects }
68+
return { obstacleIndexByLayer }
7069
}

tests/__snapshots__/board-outline.snap.svg

Lines changed: 1 addition & 16 deletions
Loading

0 commit comments

Comments
 (0)