Skip to content

Commit 19c9a60

Browse files
committed
Fix GlobalDrcForceImproveSolver’s DRC14 Visualization Blind Spot With Native Board Outlines
1 parent e20f54a commit 19c9a60

2 files changed

Lines changed: 115 additions & 76 deletions

File tree

fixtures/drc14-problems.fixture.tsx

Lines changed: 1 addition & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { GenericSolverDebugger } from "@tscircuit/solver-utils/react"
22
import samples from "dataset-drc14"
3-
import type { GraphicsObject } from "graphics-debug"
43
import { useMemo, useState } from "react"
54
import {
65
GlobalDrcForceImproveSolver,
@@ -150,80 +149,6 @@ const sampleToSolverInput = (sample: DatasetSample): SolverInput => {
150149
}
151150
}
152151

153-
const layerColor = (z: number) => {
154-
if (z === 0) return "#0f766e"
155-
if (z === 1) return "#b45309"
156-
return "#4f46e5"
157-
}
158-
159-
const routesToGraphics = (
160-
srj: SimpleRouteJson,
161-
routes: HighDensityRoute[],
162-
): GraphicsObject => ({
163-
title: "DRC14 route repair",
164-
rects: srj.obstacles.map((obstacle) => ({
165-
center: obstacle.center,
166-
width: obstacle.width,
167-
height: obstacle.height,
168-
ccwRotationDegrees: obstacle.ccwRotationDegrees,
169-
fill: obstacle.connectedTo.length > 0 ? "rgba(2, 132, 199, 0.22)" : "#eee",
170-
stroke: "#334155",
171-
label: obstacle.connectedTo[0],
172-
})),
173-
lines: routes.flatMap((route) =>
174-
route.route.slice(1).map((point, index) => {
175-
const previousPoint = route.route[index]
176-
if (!previousPoint) {
177-
return {
178-
points: [
179-
{ x: point.x, y: point.y },
180-
{ x: point.x, y: point.y },
181-
],
182-
strokeColor: layerColor(point.z),
183-
strokeWidth: route.traceThickness,
184-
label: route.connectionName,
185-
}
186-
}
187-
return {
188-
points: [
189-
{ x: previousPoint.x, y: previousPoint.y },
190-
{ x: point.x, y: point.y },
191-
],
192-
strokeColor: layerColor(point.z),
193-
strokeWidth: route.traceThickness,
194-
label: route.connectionName,
195-
}
196-
}),
197-
),
198-
circles: routes.flatMap((route) =>
199-
route.vias.map((via) => ({
200-
center: via,
201-
radius: route.viaDiameter / 2,
202-
fill: "rgba(15, 23, 42, 0.25)",
203-
stroke: "#0f172a",
204-
label: route.connectionName,
205-
})),
206-
),
207-
points: srj.connections.flatMap((connection) =>
208-
connection.pointsToConnect.map((point) => ({
209-
x: point.x,
210-
y: point.y,
211-
color: "#dc2626",
212-
label: connection.name,
213-
})),
214-
),
215-
})
216-
217-
class VisualGlobalDrcForceImproveSolver extends GlobalDrcForceImproveSolver {
218-
override visualize(): GraphicsObject {
219-
return routesToGraphics(this.srj, this.outputHdRoutes)
220-
}
221-
222-
override preview(): GraphicsObject {
223-
return this.visualize()
224-
}
225-
}
226-
227152
const parsePositiveIntegerInput = (value: string) => {
228153
const parsedValue = Number.parseInt(value, 10)
229154
return Number.isFinite(parsedValue) && parsedValue > 0
@@ -342,7 +267,7 @@ export default function Drc14ProblemsFixture() {
342267
<GenericSolverDebugger
343268
key={`${selectedSample.id ?? safeSampleNumber}-${effort}-${maxIterations ?? "auto"}`}
344269
createSolver={() =>
345-
new VisualGlobalDrcForceImproveSolver({
270+
new GlobalDrcForceImproveSolver({
346271
srj: input.solverInput.srj,
347272
hdRoutes: input.solverInput.hdRoutes,
348273
effort,

lib/solvers/GlobalDrcForceImproveSolver/GlobalDrcForceImproveSolver.ts

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { BaseSolver } from "../BaseSolver"
2+
import type { GraphicsObject } from "graphics-debug"
23
import {
34
BROAD_FALLBACK_SMALL_ROUTE_LIMIT,
45
LARGE_DRC_COUNT_THRESHOLD,
@@ -33,6 +34,111 @@ import type {
3334
import type { SimpleRouteJson } from "../../types"
3435
import type { HighDensityRoute } from "../../types/high-density-types"
3536

37+
const layerColor = (z: number) => {
38+
if (z === 0) return "#FF0000"
39+
if (z === 1) return "#0000FF"
40+
return "#4f46e5"
41+
}
42+
43+
const getBoardOutlineGraphics = (srj: SimpleRouteJson): GraphicsObject => {
44+
if (srj.outline && srj.outline.length >= 3) {
45+
return {
46+
polygons: [
47+
{
48+
points: srj.outline,
49+
stroke: "#1d4ed8",
50+
fill: "rgba(29, 78, 216, 0.0)",
51+
label: "board-outline",
52+
},
53+
],
54+
}
55+
}
56+
57+
return {
58+
rects: [
59+
{
60+
center: {
61+
x: (srj.bounds.minX + srj.bounds.maxX) / 2,
62+
y: (srj.bounds.minY + srj.bounds.maxY) / 2,
63+
},
64+
width: srj.bounds.maxX - srj.bounds.minX,
65+
height: srj.bounds.maxY - srj.bounds.minY,
66+
stroke: "#1d4ed8",
67+
fill: "rgba(29, 78, 216, 0.0)",
68+
label: "board-outline",
69+
},
70+
],
71+
}
72+
}
73+
74+
const routesToGraphics = (
75+
srj: SimpleRouteJson,
76+
routes: HighDensityRoute[],
77+
): GraphicsObject => {
78+
const boardOutlineGraphics = getBoardOutlineGraphics(srj)
79+
80+
return {
81+
coordinateSystem: "cartesian",
82+
title: "Global DRC Force Improve Solver visualization",
83+
rects: [
84+
...(boardOutlineGraphics.rects ?? []),
85+
...srj.obstacles.map((obstacle) => ({
86+
center: obstacle.center,
87+
width: obstacle.width,
88+
height: obstacle.height,
89+
ccwRotationDegrees: obstacle.ccwRotationDegrees,
90+
fill:
91+
obstacle.connectedTo.length > 0 ? "rgba(2, 132, 199, 0.22)" : "#eee",
92+
stroke: "#334155",
93+
label: obstacle.connectedTo[0],
94+
})),
95+
],
96+
polygons: boardOutlineGraphics.polygons,
97+
lines: routes.flatMap((route) =>
98+
route.route.slice(1).map((point, index) => {
99+
const previousPoint = route.route[index]
100+
if (!previousPoint) {
101+
return {
102+
points: [
103+
{ x: point.x, y: point.y },
104+
{ x: point.x, y: point.y },
105+
],
106+
strokeColor: layerColor(point.z),
107+
strokeWidth: route.traceThickness,
108+
label: route.connectionName,
109+
}
110+
}
111+
return {
112+
points: [
113+
{ x: previousPoint.x, y: previousPoint.y },
114+
{ x: point.x, y: point.y },
115+
],
116+
strokeColor: layerColor(point.z),
117+
strokeWidth: route.traceThickness,
118+
label: route.connectionName,
119+
}
120+
}),
121+
),
122+
circles: routes.flatMap((route) =>
123+
route.vias.map((via) => ({
124+
center: via,
125+
radius: route.viaDiameter / 2,
126+
fill: "rgba(15, 23, 42, 0.25)",
127+
stroke: "#0f172a",
128+
label: route.connectionName,
129+
})),
130+
),
131+
points: srj.connections.flatMap((connection) =>
132+
connection.pointsToConnect.map((point) => ({
133+
x: point.x,
134+
y: point.y,
135+
color: "#dc2626",
136+
label: connection.name,
137+
})),
138+
),
139+
}
140+
}
141+
36142
export class GlobalDrcForceImproveSolver extends BaseSolver {
37143
readonly srj: SimpleRouteJson
38144
readonly inputHdRoutes: HighDensityRoute[]
@@ -364,4 +470,12 @@ export class GlobalDrcForceImproveSolver extends BaseSolver {
364470
override getOutput() {
365471
return this.outputHdRoutes
366472
}
473+
474+
override visualize(): GraphicsObject {
475+
return routesToGraphics(this.srj, this.outputHdRoutes)
476+
}
477+
478+
override preview(): GraphicsObject {
479+
return this.visualize()
480+
}
367481
}

0 commit comments

Comments
 (0)