From a352f1aad3c9bd5b8450083f5ed6e7ad2136fc1c Mon Sep 17 00:00:00 2001 From: seveibar Date: Tue, 10 Sep 2024 20:23:15 -0700 Subject: [PATCH 1/2] fix duplicate traces being returned --- .../intersection-with-margin.snap.svg | 11 +++++++ .../tests/intersection-with-margin.test.tsx | 31 ++++++++++++++++++ .../v2/lib/GeneralizedAstar.ts | 1 - bun.lockb | Bin 424162 -> 427610 bytes package.json | 1 + 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg create mode 100644 algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx diff --git a/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg b/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg new file mode 100644 index 0000000..c601ce6 --- /dev/null +++ b/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx b/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx new file mode 100644 index 0000000..c20b718 --- /dev/null +++ b/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx @@ -0,0 +1,31 @@ +import { getSimpleRouteJson } from "autorouting-dataset" +import { test, expect } from "bun:test" +import { circuitJsonToPcbSvg } from "circuit-to-svg" +import { IJumpAutorouter } from "../v2" +import { Circuit } from "@tscircuit/core" + +test("ijump-astar: multilayer trace", () => { + const circuit = new Circuit() + + circuit.add( + + + + + , + ) + + const circuitJson = circuit.getCircuitJson() + + const input = getSimpleRouteJson(circuitJson) + + const autorouter = new IJumpAutorouter({ + input, + }) + + const traces = autorouter.solveAndMapToTraces() + + expect( + circuitJsonToPcbSvg(circuitJson.concat(traces as any)), + ).toMatchSvgSnapshot(import.meta.path) +}) diff --git a/algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar.ts b/algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar.ts index 1cbdbad..e62d558 100644 --- a/algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar.ts +++ b/algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar.ts @@ -249,7 +249,6 @@ export class GeneralizedAstarAutorouter { } if (result.solved) { - solutions.push(result) obstaclesFromTraces.push( ...getObstaclesFromRoute( result.route.map((p) => ({ diff --git a/bun.lockb b/bun.lockb index 7a58d1fc30af80822c2ebda15b5c1073007dee7d..d24955e8d033ee5786e213181f91f55dbb586ae9 100755 GIT binary patch delta 62759 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�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 diff --git a/package.json b/package.json index cf8db67..58d99d8 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@biomejs/biome": "^1.8.3", "@timohausmann/quadtree-ts": "^2.2.2", "@tscircuit/builder": "1.11.2", + "@tscircuit/core": "^0.0.54", "@tscircuit/pcb-viewer": "1.4.5", "@tscircuit/props": "^0.0.26", "@tscircuit/soup": "^0.0.68", From e2da5d9f85ed66edd3e4b16367423b79a4208d76 Mon Sep 17 00:00:00 2001 From: seveibar Date: Wed, 11 Sep 2024 10:41:48 -0700 Subject: [PATCH 2/2] add debug svg --- .../intersection-with-margin.snap.svg | 3 +- .../tests/fixtures/get-debug-svg.ts | 46 ++++++++++++++++++ .../tests/get-debug-svg.test.tsx | 36 ++++++++++++++ .../tests/intersection-with-margin.test.tsx | 19 +++++--- .../v2/lib/GeneralizedAstar.ts | 6 +++ bun.lockb | Bin 427610 -> 427610 bytes package.json | 4 +- 7 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 algos/infinite-grid-ijump-astar/tests/fixtures/get-debug-svg.ts create mode 100644 algos/infinite-grid-ijump-astar/tests/get-debug-svg.test.tsx diff --git a/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg b/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg index c601ce6..a860000 100644 --- a/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg +++ b/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg @@ -8,4 +8,5 @@ .pcb-silkscreen { fill: none; } .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } - \ No newline at end of file + .pcb-silkscreen-text { fill: #f2eda1; } + X0t1_iter[0]X01t1_iter[1]X01t1_iter[2]X01t1_iter[3] \ No newline at end of file diff --git a/algos/infinite-grid-ijump-astar/tests/fixtures/get-debug-svg.ts b/algos/infinite-grid-ijump-astar/tests/fixtures/get-debug-svg.ts new file mode 100644 index 0000000..c8ffff5 --- /dev/null +++ b/algos/infinite-grid-ijump-astar/tests/fixtures/get-debug-svg.ts @@ -0,0 +1,46 @@ +import { getSimpleRouteJson } from "autorouting-dataset" +import { test, expect } from "bun:test" +import { circuitJsonToPcbSvg } from "circuit-to-svg" +import { Circuit } from "@tscircuit/core" +import { transformPCBElements } from "@tscircuit/soup-util" +import { translate } from "transformation-matrix" +import type { AnySoupElement } from "@tscircuit/soup" +import type { GeneralizedAstarAutorouter } from "algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar" + +export const getDebugSvg = ( + inputCircuitJson: AnySoupElement[], + autorouter: GeneralizedAstarAutorouter, +) => { + const debugSolutions = Object.entries(autorouter.debugSolutions!).map( + ([debugSolutionName, solutionCircuitJson]) => ({ + debugSolutionName, + solutionCircuitJson, + }), + ) + + const aggCircuitJson: AnySoupElement[] = [] + + for (let i = 0; i < debugSolutions.length; i++) { + const { debugSolutionName, solutionCircuitJson } = debugSolutions[i] + const translatedCircuitJson = transformPCBElements( + JSON.parse( + JSON.stringify( + solutionCircuitJson.concat(inputCircuitJson).concat({ + type: "pcb_fabrication_note_text", + text: debugSolutionName, + pcb_component_id: "unknown", + layer: "top", + font: "tscircuit2024", + font_size: 0.2, + anchor_position: { x: -5, y: 0 }, + anchor_alignment: "center", + }), + ), + ), + translate(0, -2 * i), + ) + aggCircuitJson.push(...translatedCircuitJson) + } + + return circuitJsonToPcbSvg(aggCircuitJson) +} diff --git a/algos/infinite-grid-ijump-astar/tests/get-debug-svg.test.tsx b/algos/infinite-grid-ijump-astar/tests/get-debug-svg.test.tsx new file mode 100644 index 0000000..60fc676 --- /dev/null +++ b/algos/infinite-grid-ijump-astar/tests/get-debug-svg.test.tsx @@ -0,0 +1,36 @@ +import { getSimpleRouteJson } from "autorouting-dataset" +import { test, expect } from "bun:test" +import { circuitJsonToPcbSvg } from "circuit-to-svg" +import { IJumpAutorouter } from "../v2" +import { Circuit } from "@tscircuit/core" +import { transformPCBElements } from "@tscircuit/soup-util" +import { translate } from "transformation-matrix" +import type { AnySoupElement } from "@tscircuit/soup" +import { getDebugSvg } from "./fixtures/get-debug-svg" + +test("ijump-astar: intersection with margin", () => { + const circuit = new Circuit() + + circuit.add( + + + + + , + ) + + const inputCircuitJson = circuit.getCircuitJson() + + const input = getSimpleRouteJson(inputCircuitJson) + + const autorouter = new IJumpAutorouter({ + input, + debug: true, + }) + + const traces = autorouter.solveAndMapToTraces() + + expect(getDebugSvg(inputCircuitJson, autorouter)).toMatchSvgSnapshot( + import.meta.path, + ) +}) diff --git a/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx b/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx index c20b718..60fc676 100644 --- a/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx +++ b/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx @@ -3,29 +3,34 @@ import { test, expect } from "bun:test" import { circuitJsonToPcbSvg } from "circuit-to-svg" import { IJumpAutorouter } from "../v2" import { Circuit } from "@tscircuit/core" +import { transformPCBElements } from "@tscircuit/soup-util" +import { translate } from "transformation-matrix" +import type { AnySoupElement } from "@tscircuit/soup" +import { getDebugSvg } from "./fixtures/get-debug-svg" -test("ijump-astar: multilayer trace", () => { +test("ijump-astar: intersection with margin", () => { const circuit = new Circuit() circuit.add( - + , ) - const circuitJson = circuit.getCircuitJson() + const inputCircuitJson = circuit.getCircuitJson() - const input = getSimpleRouteJson(circuitJson) + const input = getSimpleRouteJson(inputCircuitJson) const autorouter = new IJumpAutorouter({ input, + debug: true, }) const traces = autorouter.solveAndMapToTraces() - expect( - circuitJsonToPcbSvg(circuitJson.concat(traces as any)), - ).toMatchSvgSnapshot(import.meta.path) + expect(getDebugSvg(inputCircuitJson, autorouter)).toMatchSvgSnapshot( + import.meta.path, + ) }) diff --git a/algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar.ts b/algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar.ts index e62d558..8f10758 100644 --- a/algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar.ts +++ b/algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar.ts @@ -26,6 +26,7 @@ export type ConnectionSolveResult = export class GeneralizedAstarAutorouter { openSet: Node[] = [] closedSet: Set = new Set() + debug = false debugSolutions?: Record debugMessage: string | null = null @@ -57,6 +58,7 @@ export class GeneralizedAstarAutorouter { GRID_STEP?: number OBSTACLE_MARGIN?: number MAX_ITERATIONS?: number + debug?: boolean }) { this.input = opts.input this.allObstacles = opts.input.obstacles @@ -65,6 +67,10 @@ export class GeneralizedAstarAutorouter { this.GRID_STEP = opts.GRID_STEP ?? 0.1 this.OBSTACLE_MARGIN = opts.OBSTACLE_MARGIN ?? 0.15 this.MAX_ITERATIONS = opts.MAX_ITERATIONS ?? 100 + this.debug = opts.debug ?? debug.enabled + if (this.debug) { + debug.enabled = true + } if (debug.enabled) { this.debugSolutions = {} diff --git a/bun.lockb b/bun.lockb index d24955e8d033ee5786e213181f91f55dbb586ae9..f91915ec534e7996ceb7cfbba96243aeb60f6507 100755 GIT binary patch delta 278 zcmV+x0qOqQj2haE8jvm^N9Me6D^qiS9m zlT}(l)abEx@|hazPU;6%;yTi}>;zYvI3@&WvnPQ@KsHT{2<0)Fu(@;1g@{c9ttYpg z;{tFNK=Glxz~Id>;JP~>Fb8^1w50xtJ9S~}`a1r0Js1%vjI@M3%gIibs{Xwt$xWOI z