From f0bc99b81ed95c67e58e685808c5a014033afa10 Mon Sep 17 00:00:00 2001 From: seveibar Date: Tue, 1 Oct 2024 12:48:25 -0700 Subject: [PATCH] create cad_component for any component with a footprint --- .../base-components/NormalComponent.ts | 115 ++++++++++-------- .../normal-components/chip.test.tsx | 1 + tests/examples/example1.test.tsx | 4 + 3 files changed, 70 insertions(+), 50 deletions(-) diff --git a/lib/components/base-components/NormalComponent.ts b/lib/components/base-components/NormalComponent.ts index 8d85a4a..e3068fe 100644 --- a/lib/components/base-components/NormalComponent.ts +++ b/lib/components/base-components/NormalComponent.ts @@ -19,7 +19,12 @@ import { createComponentsFromSoup } from "lib/utils/createComponentsFromSoup" import { Net } from "../primitive-components/Net" import { createNetsFromProps } from "lib/utils/components/createNetsFromProps" import { getBoundsOfPcbComponents } from "lib/utils/get-bounds-of-pcb-components" -import type { CadModelProp } from "@tscircuit/props" +import type { + CadModelJscad, + CadModelObj, + CadModelProp, + CadModelStl, +} from "@tscircuit/props" import { rotation } from "circuit-json" const rotation3 = z.object({ @@ -442,59 +447,69 @@ export class NormalComponent< doInitialCadModelRender(): void { const { db } = this.root! const { boardThickness = 0 } = this.root?._getBoard() ?? {} - const cadModel = this._parsedProps.cadModel as CadModelProp + const cadModel = this._parsedProps.cadModel as CadModelProp | undefined - if (cadModel) { - // Use post-layout bounds - const bounds = this._getPcbCircuitJsonBounds() + if (!this.pcb_component_id) return + if (!cadModel && !this.props.footprint) return - const pcb_component = db.pcb_component.get(this.pcb_component_id!) + // Use post-layout bounds + const bounds = this._getPcbCircuitJsonBounds() - if (typeof cadModel === "string") { - throw new Error("String cadModel not yet implemented") - } + const pcb_component = db.pcb_component.get(this.pcb_component_id!) - const rotationOffset = rotation3.parse({ - x: 0, - y: 0, - z: - typeof cadModel.rotationOffset === "number" - ? cadModel.rotationOffset - : 0, - ...(typeof cadModel.rotationOffset === "object" - ? (cadModel.rotationOffset ?? {}) - : {}), - }) - - const cad_model = db.cad_component.insert({ - // TODO z maybe depends on layer - position: { - x: bounds.center.x, - y: bounds.center.y, - z: - this.props.layer === "bottom" - ? -boardThickness / 2 - : boardThickness / 2, - }, - rotation: { - x: rotationOffset.x, - y: (this.props.layer === "top" ? 0 : 180) + rotationOffset.y, - z: - (pcb_component?.rotation ?? 0) + - (this.props.layer === "bottom" ? 180 : 0) + - rotationOffset.z, - }, - pcb_component_id: this.pcb_component_id!, - source_component_id: this.source_component_id!, - model_stl_url: "stlUrl" in cadModel ? cadModel.stlUrl : undefined, - model_obj_url: "objUrl" in cadModel ? cadModel.objUrl : undefined, - model_jscad: "jscad" in cadModel ? cadModel.jscad : undefined, - - footprinter_string: - typeof this.props.footprint === "string" && !cadModel - ? this.props.footprint - : undefined, - }) + if (typeof cadModel === "string") { + throw new Error("String cadModel not yet implemented") } + + const rotationOffset = rotation3.parse({ + x: 0, + y: 0, + z: + typeof cadModel?.rotationOffset === "number" + ? cadModel.rotationOffset + : 0, + ...(typeof cadModel?.rotationOffset === "object" + ? (cadModel.rotationOffset ?? {}) + : {}), + }) + + const cad_model = db.cad_component.insert({ + // TODO z maybe depends on layer + position: { + x: bounds.center.x, + y: bounds.center.y, + z: + this.props.layer === "bottom" + ? -boardThickness / 2 + : boardThickness / 2, + }, + rotation: { + x: rotationOffset.x, + y: (this.props.layer === "top" ? 0 : 180) + rotationOffset.y, + z: + (pcb_component?.rotation ?? 0) + + (this.props.layer === "bottom" ? 180 : 0) + + rotationOffset.z, + }, + pcb_component_id: this.pcb_component_id!, + source_component_id: this.source_component_id!, + model_stl_url: + "stlUrl" in (cadModel ?? {}) + ? (cadModel as CadModelStl).stlUrl + : undefined, + model_obj_url: + "objUrl" in (cadModel ?? {}) + ? (cadModel as CadModelObj).objUrl + : undefined, + model_jscad: + "jscad" in (cadModel ?? {}) + ? (cadModel as CadModelJscad).jscad + : undefined, + + footprinter_string: + typeof this.props.footprint === "string" && !cadModel + ? this.props.footprint + : undefined, + }) } } diff --git a/tests/components/normal-components/chip.test.tsx b/tests/components/normal-components/chip.test.tsx index 65122b1..0ad63c3 100644 --- a/tests/components/normal-components/chip.test.tsx +++ b/tests/components/normal-components/chip.test.tsx @@ -82,6 +82,7 @@ it("should create a Chip component with cadModel prop", async () => { circuit.render() const cadComponents = circuit.db.cad_component.list() + expect(cadComponents).toHaveLength(1) expect(cadComponents[0].position.x).toBeCloseTo(4) expect(cadComponents[0].model_stl_url).toBe("https://example.com/chip.stl") diff --git a/tests/examples/example1.test.tsx b/tests/examples/example1.test.tsx index d14ad2c..94be396 100644 --- a/tests/examples/example1.test.tsx +++ b/tests/examples/example1.test.tsx @@ -53,6 +53,10 @@ test("example1", async () => { circuit.db.pcb_smtpad.list().map((smtpad) => smtpad.pcb_port_id), ).not.toContain(null) + // We should have a cad_component for each component + const cadComponents = circuit.db.cad_component.list() + expect(cadComponents).toHaveLength(4) + await expect( circuit.getSvg({ view: "pcb",