Skip to content

Commit

Permalink
Merge pull request #4 from tscircuit/schematic-traces
Browse files Browse the repository at this point in the history
checkpoint schematic traces, v0.0.1, publishing and test workflows
  • Loading branch information
seveibar authored Aug 24, 2024
2 parents 65719a7 + 6de668b commit a2562a1
Show file tree
Hide file tree
Showing 17 changed files with 220 additions and 30 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/bun-pver-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Created using @tscircuit/plop (npm install -g @tscircuit/plop)
name: Publish to npm
on:
push:
branches:
- main
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- uses: actions/setup-node@v3
with:
node-version: 20
registry-url: https://registry.npmjs.org/
- run: npm install -g pver
- run: bun install --frozen-lockfile
- run: bun run build
- run: pver release
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
24 changes: 24 additions & 0 deletions .github/workflows/bun-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Created using @tscircuit/plop (npm install -g @tscircuit/plop)
name: Bun Test

on:
pull_request:

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Run tests
run: bun test
Binary file modified bun.lockb
Binary file not shown.
4 changes: 1 addition & 3 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
export { Board } from "./lib/components/normal-components/Board"
export { Project } from "./lib/Project"
export { Resistor } from "./lib/components/normal-components/Resistor"
export * from "./lib/index"
2 changes: 1 addition & 1 deletion lib/components/base-components/PrimitiveComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export abstract class PrimitiveComponent<
*/
computePcbPropsTransform(): Matrix {
// TODO rotations
return compose(translate(this.props.pcbX, this.props.pcbY))
return compose(translate(this.props.pcbX ?? 0, this.props.pcbY ?? 0))
}

/**
Expand Down
5 changes: 4 additions & 1 deletion lib/components/primitive-components/Port.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class Port extends PrimitiveComponent<typeof portProps> {

schematicSymbolPortDef: SchSymbol["ports"][number] | null = null
matchedComponents: PrimitiveComponent[]
facingDirection: "up" | "down" | "left" | "right" | null = null

constructor(props: z.input<typeof portProps>) {
if (!props.name && props.pinNumber) props.name = `pin${props.pinNumber}`
Expand Down Expand Up @@ -172,11 +173,13 @@ export class Port extends PrimitiveComponent<typeof portProps> {
const center = this.getGlobalSchematicPosition()
const parentCenter = this.parent?.getGlobalSchematicPosition()

this.facingDirection = getRelativeDirection(parentCenter, center)

const schematic_port = db.schematic_port.insert({
schematic_component_id: this.parent?.schematic_component_id!,
center,
source_port_id: this.source_port_id!,
facing_direction: getRelativeDirection(parentCenter, center),
facing_direction: this.facingDirection,
})

this.schematic_port_id = schematic_port.schematic_port_id
Expand Down
91 changes: 75 additions & 16 deletions lib/components/primitive-components/Trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ import { traceProps } from "@tscircuit/props"
import { PrimitiveComponent } from "../base-components/PrimitiveComponent"
import type { Port } from "./Port"
import { IJumpAutorouter, autoroute } from "@tscircuit/infgrid-ijump-astar"
import type { AnySoupElement } from "@tscircuit/soup"
import type { AnySoupElement, SchematicTrace } from "@tscircuit/soup"
import type {
Obstacle,
SimpleRouteConnection,
SimpleRouteJson,
} from "lib/utils/autorouting/SimpleRouteJson"
import { computeObstacleBounds } from "lib/utils/autorouting/computeObstacleBounds"
import { projectPointInDirection } from "lib/utils/projectPointInDirection"

export class Trace extends PrimitiveComponent<typeof traceProps> {
source_trace_id: string | null = null
Expand Down Expand Up @@ -138,23 +145,75 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {

if (!allPortsFound) return

// const schematicElements: AnySoupElement[] = db
// .toArray()
// .filter(
// (elm) =>
// elm.type === "schematic_component" ||
// elm.type === "schematic_line" ||
// elm.type === "schematic_path" ||
// elm.type === "schematic_text" ||
// elm.type === "schematic_port",
// )
const obstacles: Obstacle[] = []
const connection: SimpleRouteConnection = {
name: this.source_trace_id!,
pointsToConnect: [],
}

for (const elm of db.toArray()) {
if (elm.type === "schematic_component") {
obstacles.push({
type: "rect",
center: elm.center,
width: elm.size.width,
height: elm.size.height,
connectedTo: [],
})
}
}

// const trace = db.schematic_trace.insert({
// source_trace_id: this.source_trace_id!,
for (const { port } of ports) {
connection.pointsToConnect.push(
projectPointInDirection(
port.getGlobalSchematicPosition(),
port.facingDirection!,
0.1501,
),
)
}

const bounds = computeObstacleBounds(obstacles)

const simpleRouteJsonInput: SimpleRouteJson = {
obstacles,
connections: [connection],
bounds,
layerCount: 1,
}

const autorouter = new IJumpAutorouter({
input: simpleRouteJsonInput,
})
const results = autorouter.solve()

// // edges:
// })
if (results.length === 0) return

const [result] = results

if (!result.solved) return

const { route } = result

const edges: SchematicTrace["edges"] = []

for (let i = 0; i < route.length - 1; i++) {
const from = route[i]
const to = route[i + 1]

edges.push({
from,
to,
// TODO to_schematic_port_id and from_schematic_port_id
})
}

const trace = db.schematic_trace.insert({
source_trace_id: this.source_trace_id!,

edges,
})

// this.schematic_trace_id = trace.schematic_trace_id
this.schematic_trace_id = trace.schematic_trace_id
}
}
37 changes: 37 additions & 0 deletions lib/utils/autorouting/SimpleRouteJson.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export type SimplifiedPcbTrace = {
type: "pcb_trace"
pcb_trace_id: string
route: Array<{
route_type: "wire" | "via"
x: number
y: number
width: number
layer: string
}>
}
export type Obstacle = {
// TODO include ovals
type: "rect" // NOTE: most datasets do not contain ovals
center: { x: number; y: number }
width: number
height: number
connectedTo: string[]
}

export interface SimpleRouteConnection {
name: string
pointsToConnect: Array<{ x: number; y: number }>
}

export interface SimpleRouteJson {
layerCount: number
obstacles: Obstacle[]
connections: Array<SimpleRouteConnection>
bounds: { minX: number; maxX: number; minY: number; maxY: number }
}

// declare module "autorouting-dataset" {
// export type Obstacle = SimpleRouteJson["obstacles"][number]
// export type SimpleRouteConnection = SimpleRouteJson["connections"][number]
// export type SimplifiedPcbTrace = SimpleRouteJson["connections"][number]
// }
10 changes: 10 additions & 0 deletions lib/utils/autorouting/computeObstacleBounds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Obstacle } from "./SimpleRouteJson"

export const computeObstacleBounds = (obstacles: Array<Obstacle>) => {
const minX = Math.min(...obstacles.map((o) => o.center.x))
const maxX = Math.max(...obstacles.map((o) => o.center.x))
const minY = Math.min(...obstacles.map((o) => o.center.y))
const maxY = Math.max(...obstacles.map((o) => o.center.y))

return { minX, maxX, minY, maxY }
}
18 changes: 18 additions & 0 deletions lib/utils/projectPointInDirection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const projectPointInDirection = (
point: { x: number; y: number },
direction: "up" | "down" | "left" | "right",
distance: number,
) => {
switch (direction) {
case "up":
return { x: point.x, y: point.y - distance }
case "down":
return { x: point.x, y: point.y + distance }
case "left":
return { x: point.x - distance, y: point.y }
case "right":
return { x: point.x + distance, y: point.y }
default:
throw new Error(`Unknown direction "${direction}"`)
}
}
18 changes: 15 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
{
"name": "core",
"name": "@tscircuit/core",
"module": "index.ts",
"type": "module",
"types": "index.ts",
"version": "0.0.1",
"main": "dist/index.cjs",
"files": [
"index.ts",
"lib",
"dist"
],
"scripts": {
"build": "tsup index.ts"
},
"devDependencies": {
"@biomejs/biome": "^1.8.3",
"@tscircuit/log-soup": "^1.0.2",
"@types/bun": "latest",
"@types/react": "^18.3.3",
"@types/react-reconciler": "^0.28.8",
"circuit-to-svg": "^0.0.3",
"looks-same": "^9.0.1"
"looks-same": "^9.0.1",
"tsup": "^8.2.4"
},
"peerDependencies": {
"typescript": "^5.0.0"
Expand All @@ -25,4 +37,4 @@
"schematic-symbols": "0.0.10",
"transformation-matrix": "^2.16.1"
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion tests/components/primitive-components/trace-hint.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ it("simple trace with trace hint test", async () => {

project.render()

await logSoup("simple trace with trace hint test")
expect(project).toMatchPcbSnapshot(import.meta.path)
expect(project).toMatchSchematicSnapshot(import.meta.path)
})
1 change: 0 additions & 1 deletion tests/components/primitive-components/trace.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ it("simple trace test", async () => {

project.render()

await logSoup("simple trace test")
expect(project).toMatchPcbSnapshot(import.meta.path)
expect(project).toMatchSchematicSnapshot(import.meta.path)
})
4 changes: 2 additions & 2 deletions tests/fixtures/__snapshots__/circuit-snapshot-pcb.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions tests/fixtures/circuit-snapshot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@ it("should be able to snapshot a circuit", async () => {

project.render()

const pcb_smtpads = project.db.pcb_smtpad.list()
expect(pcb_smtpads.every((smt) => !Number.isNaN(smt.x))).toBe(true)
expect(pcb_smtpads.every((smt) => !Number.isNaN(smt.y))).toBe(true)

await expect(project.getSoup()).toMatchPcbSnapshot(import.meta.path)
})

0 comments on commit a2562a1

Please sign in to comment.