Skip to content

Commit 96c5307

Browse files
authored
Merge branch 'tscircuit:main' into main
2 parents d964618 + fb2e753 commit 96c5307

File tree

8 files changed

+169
-115
lines changed

8 files changed

+169
-115
lines changed

lib/testing/utils/convertToCircuitJson.ts

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,45 @@ function createPcbPorts(srj: SimpleRouteJson): AnyCircuitElement[] {
304304
return Array.from(portMap.values())
305305
}
306306

307+
function getPcbPortPositionMap(srj: SimpleRouteJson) {
308+
const portPositionMap = new Map<string, { x: number; y: number }>()
309+
310+
for (const connection of srj.connections) {
311+
for (const point of connection.pointsToConnect) {
312+
if (!point.pcb_port_id) continue
313+
portPositionMap.set(point.pcb_port_id, { x: point.x, y: point.y })
314+
}
315+
}
316+
317+
return portPositionMap
318+
}
319+
320+
function getBestObstaclePcbPortId(
321+
obstacleCenter: Obstacle["center"],
322+
candidatePortIds: string[],
323+
portPositionMap: Map<string, { x: number; y: number }>,
324+
): string | undefined {
325+
let bestPcbPortId: string | undefined
326+
let bestDistance = Number.POSITIVE_INFINITY
327+
328+
for (const pcbPortId of candidatePortIds) {
329+
const position = portPositionMap.get(pcbPortId)
330+
if (!position) continue
331+
332+
const distance = Math.hypot(
333+
position.x - obstacleCenter.x,
334+
position.y - obstacleCenter.y,
335+
)
336+
337+
if (distance < bestDistance) {
338+
bestDistance = distance
339+
bestPcbPortId = pcbPortId
340+
}
341+
}
342+
343+
return bestPcbPortId ?? candidatePortIds[0]
344+
}
345+
307346
/**
308347
* Create pad-like circuit-json elements from SRJ obstacles.
309348
* Multi-layer obstacles represent plated holes and must not be deduped away
@@ -313,41 +352,34 @@ function createPcbPadElements(srj: SimpleRouteJson): AnyCircuitElement[] {
313352
const pads: AnyCircuitElement[] = []
314353
const addedSmtPadIds = new Set<string>()
315354
const addedPlatedHoleIds = new Set<string>()
355+
const portPositionMap = getPcbPortPositionMap(srj)
316356

317-
for (const obstacle of srj.obstacles as any[]) {
318-
const connectedTo: string[] = obstacle?.connectedTo || []
357+
for (const obstacle of srj.obstacles) {
358+
const connectedTo = obstacle.connectedTo
319359
const smtPadId: string | undefined = connectedTo.find((id) =>
320360
id.startsWith("pcb_smtpad_"),
321361
)
322362
const platedHoleId: string | undefined = connectedTo.find((id) =>
323363
id.startsWith("pcb_plated_hole_"),
324364
)
325-
const pcbPortId: string | undefined = connectedTo.find((id) =>
365+
const candidatePortIds = connectedTo.filter((id) =>
326366
id.startsWith("pcb_port_"),
327367
)
368+
const pcbPortId = getBestObstaclePcbPortId(
369+
obstacle.center,
370+
candidatePortIds,
371+
portPositionMap,
372+
)
328373

329374
if (!smtPadId && !platedHoleId && !pcbPortId) continue
330375

331-
const layers: string[] = Array.isArray(obstacle.layers)
332-
? obstacle.layers
333-
: obstacle.layer
334-
? [obstacle.layer]
335-
: []
376+
const layers = obstacle.layers
336377
if (layers.length === 0) continue
337378

338-
const width = obstacle.width ?? 0
339-
const height = obstacle.height ?? 0
340-
const x = obstacle.center?.x ?? obstacle.x
341-
const y = obstacle.center?.y ?? obstacle.y
342-
343-
if (
344-
typeof x !== "number" ||
345-
typeof y !== "number" ||
346-
typeof width !== "number" ||
347-
typeof height !== "number"
348-
) {
349-
continue
350-
}
379+
const width = obstacle.width
380+
const height = obstacle.height
381+
const x = obstacle.center.x
382+
const y = obstacle.center.y
351383

352384
const isMultiLayerObstacle = layers.length > 1
353385

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@tscircuit/capacity-autorouter",
33
"main": "./dist/index.js",
4-
"version": "0.0.380",
4+
"version": "0.0.381",
55
"type": "module",
66
"files": [
77
"dist"
@@ -72,7 +72,7 @@
7272
"dependencies": {
7373
"@tscircuit/high-density-a01": "^0.0.25",
7474
"fast-json-stable-stringify": "^2.1.0",
75-
"high-density-repair02": "git+https://github.com/tscircuit/high-density-repair02.git#6ebacc31e987b093e6d16fb35e15af86848f7682",
75+
"high-density-repair02": "git+https://github.com/tscircuit/high-density-repair02.git#5509821634433b6a4f74fa76e530004dffc2f907",
7676
"object-hash": "^3.0.0"
7777
}
7878
}

tests/bugs/__snapshots__/bugreport44-0ec411.snap.svg

Lines changed: 1 addition & 1 deletion
Loading

tests/bugs/__snapshots__/bugreport47-8ee80e-esp32-breakout.snap.svg

Lines changed: 1 addition & 1 deletion
Loading

tests/features/__snapshots__/pipeline4-dataset01-circuit006-unreported-drc-visual.snap.svg

Lines changed: 0 additions & 72 deletions
This file was deleted.

tests/features/pcb_trace_id-should-return-root-connection-name/__snapshots__/pcb_trace_id-should-return-root-connection-name.snap.svg

Lines changed: 1 addition & 1 deletion
Loading

tests/features/pipeline4-dataset01-circuit006-unreported-drc-visual.test.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { expect, test } from "bun:test"
2+
import { convertToCircuitJson } from "lib/testing/utils/convertToCircuitJson"
3+
import type { SimpleRouteJson, SimplifiedPcbTrace } from "lib/types"
4+
5+
test("obstacles use the nearest pcb_port_id instead of the first connected port", () => {
6+
const srj: SimpleRouteJson = {
7+
layerCount: 2,
8+
minTraceWidth: 0.15,
9+
bounds: { minX: -5, maxX: 5, minY: -5, maxY: 5 },
10+
obstacles: [
11+
{
12+
type: "rect",
13+
layers: ["top"],
14+
center: { x: -2, y: 0 },
15+
width: 1.2,
16+
height: 1.2,
17+
connectedTo: [
18+
"pcb_smtpad_0",
19+
"pcb_port_0",
20+
"pcb_smtpad_1",
21+
"pcb_port_1",
22+
"pcb_smtpad_2",
23+
"pcb_port_2",
24+
],
25+
},
26+
{
27+
type: "rect",
28+
layers: ["top"],
29+
center: { x: 2, y: 0 },
30+
width: 1.2,
31+
height: 1.2,
32+
connectedTo: [
33+
"pcb_smtpad_1",
34+
"pcb_port_0",
35+
"pcb_smtpad_1",
36+
"pcb_port_1",
37+
"pcb_smtpad_2",
38+
"pcb_port_2",
39+
],
40+
},
41+
{
42+
type: "rect",
43+
layers: ["top"],
44+
center: { x: 2, y: 2 },
45+
width: 1.2,
46+
height: 1.2,
47+
connectedTo: [
48+
"pcb_smtpad_2",
49+
"pcb_port_0",
50+
"pcb_smtpad_1",
51+
"pcb_port_1",
52+
"pcb_smtpad_2",
53+
"pcb_port_2",
54+
],
55+
},
56+
],
57+
connections: [
58+
{
59+
name: "source_trace_0",
60+
pointsToConnect: [
61+
{ x: -2, y: 0, layer: "top", pcb_port_id: "pcb_port_0" },
62+
{ x: 2, y: 0, layer: "top", pcb_port_id: "pcb_port_1" },
63+
],
64+
},
65+
{
66+
name: "source_trace_1",
67+
pointsToConnect: [
68+
{ x: 2, y: 2, layer: "top", pcb_port_id: "pcb_port_2" },
69+
],
70+
},
71+
],
72+
}
73+
74+
const traces: SimplifiedPcbTrace[] = [
75+
{
76+
type: "pcb_trace",
77+
pcb_trace_id: "source_trace_0_0",
78+
connection_name: "source_trace_0",
79+
route: [
80+
{ route_type: "wire", x: -2, y: 0, width: 0.15, layer: "top" },
81+
{ route_type: "wire", x: 2, y: 0, width: 0.15, layer: "top" },
82+
],
83+
},
84+
{
85+
type: "pcb_trace",
86+
pcb_trace_id: "source_trace_1_0",
87+
connection_name: "source_trace_1",
88+
route: [
89+
{ route_type: "wire", x: 2, y: 0, width: 0.15, layer: "top" },
90+
{ route_type: "wire", x: 2, y: 2, width: 0.15, layer: "top" },
91+
],
92+
},
93+
]
94+
95+
const circuitJson = convertToCircuitJson(srj, traces, srj.minTraceWidth)
96+
const smtPads = circuitJson.filter(
97+
(
98+
element,
99+
): element is Extract<
100+
(typeof circuitJson)[number],
101+
{ type: "pcb_smtpad" }
102+
> => element.type === "pcb_smtpad",
103+
)
104+
105+
expect(smtPads).toHaveLength(3)
106+
expect(smtPads.map((pad) => pad.pcb_port_id)).toEqual([
107+
"pcb_port_0",
108+
"pcb_port_1",
109+
"pcb_port_2",
110+
])
111+
})

0 commit comments

Comments
 (0)