Skip to content

Commit

Permalink
Merge pull request #68 from tscircuit/merge-session
Browse files Browse the repository at this point in the history
Remove Y Axis Flip in DSN PCB Conversion, Merge Dsn Session into Dsn PCB, Minor Refactoring, Lots of Debug statements, Include vias in DSN stringification, Improve Circuit Json to DSN PCB conversion for traces/vias
  • Loading branch information
seveibar authored Dec 16, 2024
2 parents b7c8c6a + 24ea730 commit 33ad560
Show file tree
Hide file tree
Showing 18 changed files with 564 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,11 @@ export function convertCircuitJsonToDsnSession(
dsnPcb: DsnPcb,
circuitJson: AnyCircuitElement[],
): DsnSession {
// First convert to DSN PCB to reuse component/pad processing
// const dsnPcb = convertCircuitJsonToDsnJson(circuitJson)

// console.dir(dsnPcb, { depth: null })

const pcb_traces = su(circuitJson as any).pcb_trace.list()
const source_traces = su(circuitJson as any).source_trace.list()
const source_ports = su(circuitJson as any).source_port.list()
const nets = su(circuitJson as any).source_net.list()

// Only applies to the traces (components are not getting affected)
const transformMmToSesUnit = scale(10000)
const session: DsnSession = {
is_dsn_session: true,
Expand All @@ -31,54 +25,54 @@ export function convertCircuitJsonToDsnSession(
resolution: dsnPcb.resolution,
parser: dsnPcb.parser,
library_out: {
// TODO Just add vias here
padstacks: [],
},
network_out: {
nets: dsnPcb.network.nets
.map((net) => {
const source_net = nets.find((n) => n.name === net.name)
if (!source_net) return null
const pcb_traces_for_net = pcb_traces.filter((pcb_trace) => {
const source_trace = source_traces.find(
(st) => st.source_trace_id === pcb_trace.source_trace_id,
)
nets: pcb_traces.map((trace) => {
const source_trace = source_traces.find(
(st) => st.source_trace_id === trace.source_trace_id,
)
const source_net =
source_trace &&
nets.find((n) =>
source_trace.connected_source_net_ids.includes(n.source_net_id),
)
const net_name = source_net?.name || trace.source_trace_id

// TODO only supports single layer traces
const traceLayer =
"layer" in trace.route[0] && trace.route[0].layer === "bottom"
? "bottom"
: "top"

return source_trace?.connected_source_net_ids.includes(
source_net.source_net_id,
)
})
const traceWidth =
"width" in trace.route[0] ? trace.route[0].width : 0.16

return {
name: net.name,
wires: pcb_traces_for_net.flatMap((trace): Wire => {
// TODO whenever the pcb trace changes layers or changes width,
// we have to create a new wire
return {
path: {
layer: "F.Cu",
width: 0.1, // TODO get width
coordinates: trace.route
.filter(
(rp): rp is PcbTraceRoutePointWire =>
rp.route_type === "wire",
)
.map((rp) =>
// Circuit JSON space to the SES space
applyToPoint(transformMmToSesUnit, {
x: rp.x,
y: rp.y,
}),
)
.flatMap((trp) => [trp.x, trp.y]),
},
}
}),
}
})
.filter((net): net is { name: string; wires: Wire[] } =>
Boolean(net),
),
return {
name: net_name!,
wires: [
{
path: {
layer: traceLayer === "bottom" ? "B.Cu" : "F.Cu",
width: traceWidth * 1000,
coordinates: trace.route
.filter(
(rp): rp is PcbTraceRoutePointWire =>
rp.route_type === "wire",
)
.map((rp) =>
// Circuit JSON space to the SES space
applyToPoint(transformMmToSesUnit, {
x: rp.x,
y: rp.y,
}),
)
.flatMap((trp) => [trp.x, trp.y]),
},
},
],
}
}),
},
},
}
Expand Down
41 changes: 0 additions & 41 deletions lib/dsn-pcb/circuit-json-to-dsn-json/process-pcb-traces.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { DsnPcb, Padstack } from "lib/dsn-pcb/types"

export function findOrCreateViaPadstack(
pcb: DsnPcb,
outerDiameter: number,
holeDiameter: number,
): string {
const viaName = `Via[0-1]_${outerDiameter}:${holeDiameter}_um`

// Check if padstack already exists
const existingPadstack = pcb.library.padstacks.find((p) => p.name === viaName)

if (existingPadstack) {
return viaName
}

// Create new padstack for via
const viaPadstack: Padstack = {
name: viaName,
attach: "off",
shapes: [
{
shapeType: "circle",
layer: "F.Cu",
diameter: outerDiameter,
},
{
shapeType: "circle",
layer: "B.Cu",
diameter: outerDiameter,
},
],
hole: {
shape: "circle",
diameter: holeDiameter,
},
}

pcb.library.padstacks.push(viaPadstack)
return viaName
}
155 changes: 155 additions & 0 deletions lib/dsn-pcb/circuit-json-to-dsn-json/process-pcb-traces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import type {
AnyCircuitElement,
LayerRef,
PcbTrace,
PcbTraceRoutePoint,
} from "circuit-json"
import type { DsnPcb, DsnSession } from "../../types"
import Debug from "debug"
import { findOrCreateViaPadstack } from "./findOrCreateViaPadstack"

const debug = Debug("dsn-converter:process-pcb-traces")

const DEFAULT_VIA_DIAMETER = 600 // μm
const DEFAULT_VIA_HOLE = 300 // μm

interface Wire {
path: {
layer: string
width: number
coordinates: number[]
}
net: string
type: string
}

function createWire(opts: {
layer: LayerRef
widthMm: number
netName: string
}): Wire {
return {
path: {
layer: opts.layer === "top" ? "F.Cu" : "B.Cu",
width: opts.widthMm * 1000,
coordinates: [],
},
net: opts.netName,
type: "route",
}
}

export function processPcbTraces(
circuitElements: AnyCircuitElement[],
pcb: DsnPcb,
) {
for (const element of circuitElements) {
if (element.type === "pcb_trace") {
const pcbTrace = element
debug("PCB TRACE\n----------\n", pcbTrace)
const netName =
pcbTrace.source_trace_id || `Net-${pcb.network.nets.length + 1}`

let currentLayer = ""
let currentWire: Wire | null = null

// Process each point in the route
for (let i = 0; i < pcbTrace.route.length; i++) {
const point = pcbTrace.route[i] as PcbTraceRoutePoint
debug("POINT\n------\n", point)

if (point.route_type === "wire") {
// If layer changed or this is the first point, start a new wire
const hasLayerChanged = currentLayer && point.layer !== currentLayer
const isFirstPoint = !currentWire

if (isFirstPoint) {
// Start new wire on new layer
currentWire = createWire({
layer: point.layer,
widthMm: point.width,
netName,
})

pcb.wiring.wires.push(currentWire)
currentLayer = point.layer
}

if (currentWire && !hasLayerChanged) {
// Add coordinates to current wire
currentWire.path.coordinates.push(point.x * 1000)
currentWire.path.coordinates.push(point.y * 1000)
continue
}

if (hasLayerChanged) {
const prevPoint = pcbTrace.route[i - 1]
const viaPadstackName = findOrCreateViaPadstack(
pcb,
DEFAULT_VIA_DIAMETER,
DEFAULT_VIA_HOLE,
)

// Add via reference to structure if not already there
if (!pcb.structure.via) {
pcb.structure.via = viaPadstackName
}

// Create wire segment for via placement
pcb.wiring.wires.push({
path: {
layer: currentLayer === "top" ? "F.Cu" : "B.Cu",
width: DEFAULT_VIA_DIAMETER,
coordinates: [prevPoint.x * 1000, prevPoint.y * 1000],
},
net: netName,
type: "via",
})
}
continue
}

if (point.route_type === "via") {
debug("VIA\n----\n", point)

// End current wire
if (currentWire) {
currentWire.path.coordinates.push(point.x * 1000)
currentWire.path.coordinates.push(point.y * 1000)
currentWire = null
}

// Handle explicit via points
const viaPadstackName = findOrCreateViaPadstack(
pcb,
DEFAULT_VIA_DIAMETER,
DEFAULT_VIA_HOLE,
)

debug("VIA PADSTACK NAME:", viaPadstackName)

// Add via reference to structure if not already there
if (!pcb.structure.via) {
pcb.structure.via = viaPadstackName
}

// Create wire segment for via placement
pcb.wiring.wires.push({
path: {
layer: point.from_layer === "top" ? "F.Cu" : "B.Cu",
width: DEFAULT_VIA_DIAMETER,
coordinates: [point.x * 1000, point.y * 1000],
},
net: netName,
type: "via",
})
debug("WIRING", pcb.wiring)

currentLayer = point.to_layer
currentWire = null // Start fresh wire after via
}
}
}
}
debug("PCB WIRING AT END", pcb.wiring)
}
6 changes: 5 additions & 1 deletion lib/dsn-pcb/circuit-json-to-dsn-json/stringify-dsn-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,11 @@ export const stringifyDsnJson = (dsnJson: DsnPcb): string => {
// Wiring section
result += `${indent}(wiring\n`
;(dsnJson.wiring?.wires ?? []).forEach((wire) => {
result += `${indent}${indent}(wire ${stringifyPath(wire.path, 3)}(net ${stringifyValue(wire.net)})(type ${wire.type}))\n`
if (wire.type === "via") {
result += `${indent}${indent}(via ${stringifyPath(wire.path, 3)}(net ${stringifyValue(wire.net)}))\n`
} else {
result += `${indent}${indent}(wire ${stringifyPath(wire.path, 3)}(net ${stringifyValue(wire.net)})(type ${wire.type}))\n`
}
})
result += `${indent})\n`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { fromTriangles, scale, applyToPoint } from "transformation-matrix"
import type { AnyCircuitElement, PcbBoard } from "circuit-json"
import type { DsnPcb, DsnSession } from "../types"
import { convertPadstacksToSmtPads } from "./dsn-component-converters/convert-padstacks-to-smtpads"
import { convertWiresToPcbTraces } from "./dsn-component-converters/convert-wire-to-trace"
import { convertWiresToPcbTraces } from "./dsn-component-converters/convert-wires-to-traces"
import { pairs } from "lib/utils/pairs"
import { convertDsnPcbToCircuitJson } from "./convert-dsn-pcb-to-circuit-json"
import { convertDsnSessionToCircuitJson } from "./convert-dsn-session-to-circuit-json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { fromTriangles, scale, applyToPoint } from "transformation-matrix"
import type { AnyCircuitElement, PcbBoard } from "circuit-json"
import type { DsnPcb } from "../types"
import { convertPadstacksToSmtPads } from "./dsn-component-converters/convert-padstacks-to-smtpads"
import { convertWiresToPcbTraces } from "./dsn-component-converters/convert-wire-to-trace"
import { convertWiresToPcbTraces } from "./dsn-component-converters/convert-wires-to-traces"
import { pairs } from "lib/utils/pairs"
import { convertNetsToSourceNetsAndTraces } from "./dsn-component-converters/convert-nets-to-source-nets-and-traces"
import { convertDsnPcbComponentsToSourceComponentsAndPorts } from "./dsn-component-converters/convert-dsn-pcb-components-to-source-components-and-ports"
Expand Down
Loading

0 comments on commit 33ad560

Please sign in to comment.