diff --git a/bun.lockb b/bun.lockb index 66ec48a8..517ac95c 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/lib/components/index.ts b/lib/components/index.ts index 4a8e05c4..088d7077 100644 --- a/lib/components/index.ts +++ b/lib/components/index.ts @@ -20,3 +20,4 @@ export { PlatedHole } from "./primitive-components/PlatedHole" export { Constraint } from "./primitive-components/Constraint" export { Hole } from "./primitive-components/Hole" export { SilkscreenText } from "./primitive-components/SilkscreenText" +export { Keepout } from "./primitive-components/Keepout" diff --git a/lib/components/primitive-components/Keepout.ts b/lib/components/primitive-components/Keepout.ts new file mode 100644 index 00000000..56ec8607 --- /dev/null +++ b/lib/components/primitive-components/Keepout.ts @@ -0,0 +1,58 @@ +import { PrimitiveComponent } from "../base-components/PrimitiveComponent" +import { pcbKeepoutProps } from "@tscircuit/props" +import type { RenderPhaseFn } from "../base-components/Renderable" +import type { PCBKeepout } from "@tscircuit/soup" +import { decomposeTSR } from "transformation-matrix" + +export class Keepout extends PrimitiveComponent { + pcb_keepout_id: string | null = null + + isPcbPrimitive = true + + get config() { + return { + zodProps: pcbKeepoutProps, + } + } + + doInitialPcbPrimitiveRender(): void { + const { db } = this.root! + const { _parsedProps: props } = this + const position = this._getGlobalPcbPositionBeforeLayout() + const decomposedMat = decomposeTSR( + this._computePcbGlobalTransformBeforeLayout(), + ) + const isRotated90 = + Math.abs(decomposedMat.rotation.angle * (180 / Math.PI) - 90) < 0.01 + + let pcb_keepout: PCBKeepout | null = null + if (props.shape === "circle") { + pcb_keepout = db.pcb_keepout.insert({ + layers: ["top"], + shape: "circle", + // @ts-ignore: no idea why this is triggering + radius: props.radius, + center: { + x: position.x, + y: position.y, + }, + }) + } else if (props.shape === "rect") { + pcb_keepout = db.pcb_keepout.insert({ + layers: ["top"], + shape: "rect", + ...(isRotated90 + ? { width: props.height, height: props.width } + : { width: props.width, height: props.height }), + // @ts-ignore: no idea why this is triggering + center: { + x: position.x, + y: position.y, + }, + }) + } + if (pcb_keepout) { + this.pcb_keepout_id = pcb_keepout.pcb_keepout_id + } + } +} diff --git a/lib/components/primitive-components/Trace.ts b/lib/components/primitive-components/Trace.ts index ef02cfea..9599a51b 100644 --- a/lib/components/primitive-components/Trace.ts +++ b/lib/components/primitive-components/Trace.ts @@ -294,7 +294,8 @@ export class Trace extends PrimitiveComponent { elm.type === "pcb_hole" || elm.type === "source_port" || elm.type === "pcb_port" || - elm.type === "source_trace", + elm.type === "source_trace" || + elm.type === "pcb_keepout", ) const source_trace = db.source_trace.get(this.source_trace_id!)! diff --git a/lib/fiber/intrinsic-jsx.ts b/lib/fiber/intrinsic-jsx.ts index 7868d4f6..17e75a9f 100644 --- a/lib/fiber/intrinsic-jsx.ts +++ b/lib/fiber/intrinsic-jsx.ts @@ -21,6 +21,7 @@ declare global { schematictext: Props.SchematicTextProps smtpad: Props.SmtPadProps platedhole: Props.PlatedHoleProps + keepout: Props.PcbKeepoutProps hole: Props.HoleProps port: Props.PortProps group: Props.GroupProps diff --git a/lib/utils/createComponentsFromSoup.ts b/lib/utils/createComponentsFromSoup.ts index a7ca82e6..6eabd4db 100644 --- a/lib/utils/createComponentsFromSoup.ts +++ b/lib/utils/createComponentsFromSoup.ts @@ -3,6 +3,7 @@ import type { PrimitiveComponent } from "../components/base-components/Primitive import { SmtPad } from "lib/components/primitive-components/SmtPad" import { SilkscreenPath } from "lib/components/primitive-components/SilkscreenPath" import { PlatedHole } from "lib/components/primitive-components/PlatedHole" +import { Keepout } from "lib/components/primitive-components/Keepout" export const createComponentsFromSoup = ( soup: AnySoupElement[], @@ -53,6 +54,25 @@ export const createComponentsFromSoup = ( }), ) } + } else if (elm.type === "pcb_keepout" && elm.shape === "circle") { + components.push( + new Keepout({ + pcbX: elm.center.x, + pcbY: elm.center.y, + shape: "circle", + radius: elm.radius, + }), + ) + } else if (elm.type === "pcb_keepout" && elm.shape === "rect") { + components.push( + new Keepout({ + pcbX: elm.center.x, + pcbY: elm.center.y, + shape: "rect", + width: elm.width, + height: elm.height, + }), + ) } } return components diff --git a/package.json b/package.json index bb5ebd29..759c0f88 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ "@lume/kiwi": "^0.4.3", "@tscircuit/infgrid-ijump-astar": "^0.0.9", "@tscircuit/props": "^0.0.62", - "@tscircuit/soup": "^0.0.66", - "@tscircuit/soup-util": "0.0.18", + "@tscircuit/soup": "^0.0.67", + "@tscircuit/soup-util": "^0.0.23", "footprinter": "^0.0.44", "react": "^18.3.1", "react-reconciler": "^0.29.2",