Skip to content

Commit

Permalink
can now draw boards rectangular and outlined (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShiboSoftwareDev authored Sep 17, 2024
1 parent 6b8b46d commit 8c8e2a9
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 19 deletions.
36 changes: 30 additions & 6 deletions src/lib/circuit-to-pcb-svg.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { AnyCircuitElement } from "@tscircuit/soup"
import type { Point, AnyCircuitElement } from "@tscircuit/soup"
import { type INode as SvgObject, stringify } from "svgson"
import {
type Matrix,
Expand All @@ -14,6 +14,7 @@ import { createSvgObjectsFromPcbSilkscreenPath } from "./svg-object-fns/create-s
import { createSvgObjectsFromPcbSilkscreenText } from "./svg-object-fns/create-svg-objects-from-pcb-silkscreen-text"
import { createSvgObjectsFromPcbTrace } from "./svg-object-fns/create-svg-objects-from-pcb-trace"
import { createSvgObjectsFromSmtPad } from "./svg-object-fns/create-svg-objects-from-smt-pads"
import { createSvgObjectsFromPcbBoard } from "./svg-object-fns/create-svg-objects-from-pcb-board"
import { createSvgObjectsFromPcbVia } from "./svg-object-fns/create-svg-objects-from-pcb-via"

const OBJECT_ORDER: AnyCircuitElement["type"][] = [
Expand All @@ -26,6 +27,7 @@ const OBJECT_ORDER: AnyCircuitElement["type"][] = [
"pcb_trace",
"pcb_smtpad",
"pcb_component",
"pcb_board",
]

interface PointObjectNotation {
Expand All @@ -49,8 +51,15 @@ function circuitJsonToPcbSvg(

// Process all elements to determine bounds
for (const item of soup) {
if ("center" in item && "width" in item && "height" in item) {
updateBounds(item.center, item.width, item.height)
if (item.type === "pcb_board") {
if (
item.outline &&
Array.isArray(item.outline) &&
item.outline.length >= 3
)
updateBoundsToIncludeOutline(item.outline)
else if ("center" in item && "width" in item && "height" in item)
updateBounds(item.center, item.width, item.height)
} else if ("x" in item && "y" in item) {
updateBounds({ x: item.x, y: item.y }, 0, 0)
} else if ("route" in item) {
Expand Down Expand Up @@ -122,7 +131,8 @@ function circuitJsonToPcbSvg(
{
type: "text",
value: `
.pcb-board { fill: #000; }
.boundary { fill: #000; }
.pcb-board { fill: none; }
.pcb-trace { fill: none; }
.pcb-hole-outer { fill: rgb(200, 52, 52); }
.pcb-hole-inner { fill: rgb(255, 38, 226); }
Expand All @@ -140,7 +150,7 @@ function circuitJsonToPcbSvg(
name: "rect",
type: "element",
attributes: {
class: "pcb-board",
class: "boundary",
x: "0",
y: "0",
width: svgWidth.toString(),
Expand Down Expand Up @@ -168,6 +178,15 @@ function circuitJsonToPcbSvg(
maxY = Math.max(maxY, center.y + halfHeight)
}

function updateBoundsToIncludeOutline(outline: Point[]) {
for (const point of outline) {
minX = Math.min(minX, point.x)
minY = Math.min(minY, point.y)
maxX = Math.max(maxX, point.x)
maxY = Math.max(maxY, point.y)
}
}

function updateTraceBounds(route: any[]) {
for (const point of route) {
minX = Math.min(minX, point.x)
Expand All @@ -178,7 +197,10 @@ function circuitJsonToPcbSvg(
}
}

function createSvgObjects(elm: AnyCircuitElement, transform: Matrix): SvgObject[] {
function createSvgObjects(
elm: AnyCircuitElement,
transform: Matrix,
): SvgObject[] {
switch (elm.type) {
case "pcb_component":
return [createSvgObjectsFromPcbComponent(elm, transform)].filter(Boolean)
Expand All @@ -196,6 +218,8 @@ function createSvgObjects(elm: AnyCircuitElement, transform: Matrix): SvgObject[
return createSvgObjectsFromPcbFabricationNoteText(elm, transform)
case "pcb_silkscreen_path":
return createSvgObjectsFromPcbSilkscreenPath(elm, transform)
case "pcb_board":
return createSvgObjectsFromPcbBoard(elm, transform)
case "pcb_via":
return createSvgObjectsFromPcbVia(elm, transform)
default:
Expand Down
63 changes: 63 additions & 0 deletions src/lib/svg-object-fns/create-svg-objects-from-pcb-board.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { PCBBoard, Point } from "@tscircuit/soup"
import { applyToPoint, type Matrix } from "transformation-matrix"
import type { SvgObject } from "../svg-object"

export function createSvgObjectsFromPcbBoard(
pcbBoard: PCBBoard,
transform: Matrix,
): SvgObject[] {
const { width, height, center, outline } = pcbBoard

let path: string
if (outline && Array.isArray(outline) && outline.length >= 3) {
path = outline
.map((point: Point, index: number) => {
const [x, y] = applyToPoint(transform, [point.x, point.y])
return index === 0 ? `M ${x} ${y}` : `L ${x} ${y}`
})
.join(" ")
} else {
const halfWidth = width / 2
const halfHeight = height / 2

const topLeft = applyToPoint(transform, [
center.x - halfWidth,
center.y - halfHeight,
])
const topRight = applyToPoint(transform, [
center.x + halfWidth,
center.y - halfHeight,
])
const bottomRight = applyToPoint(transform, [
center.x + halfWidth,
center.y + halfHeight,
])
const bottomLeft = applyToPoint(transform, [
center.x - halfWidth,
center.y + halfHeight,
])

path =
`M ${topLeft[0]} ${topLeft[1]} ` +
`L ${topRight[0]} ${topRight[1]} ` +
`L ${bottomRight[0]} ${bottomRight[1]} ` +
`L ${bottomLeft[0]} ${bottomLeft[1]}`
}

path += " Z"

return [
{
name: "path",
type: "element",
value: "",
children: [],
attributes: {
class: "pcb-board",
d: path,
stroke: "rgba(255, 255, 255, 0.5)",
"stroke-width": (0.1 * Math.abs(transform.a)).toString(),
},
},
]
}
5 changes: 3 additions & 2 deletions tests/__snapshots__/bottom-smtpads-in-blue.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions tests/__snapshots__/bottom-trace-in-blue.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions tests/__snapshots__/colored-fabnotes.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions tests/__snapshots__/fabnotes.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 8c8e2a9

Please sign in to comment.