diff --git a/package-lock.json b/package-lock.json index e841f122..3284422b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tscircuit/builder", - "version": "1.5.154", + "version": "1.5.155", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@tscircuit/builder", - "version": "1.5.154", + "version": "1.5.155", "license": "MIT", "dependencies": { "@lume/kiwi": "^0.1.0", diff --git a/src/lib/builder/component-builder/BugBuilder.ts b/src/lib/builder/component-builder/BugBuilder.ts index 2e2df37f..c6672adc 100644 --- a/src/lib/builder/component-builder/BugBuilder.ts +++ b/src/lib/builder/component-builder/BugBuilder.ts @@ -9,14 +9,13 @@ import getPortPosition, { DEFAULT_PIN_SPACING, getPortArrangementSize, getPortIndices, - type PortArrangement, } from "../../utils/get-port-position" import { associatePcbPortsWithPads } from "../footprint-builder/associate-pcb-ports-with-pads" import type { ProjectBuilder } from "../project-builder" import { transformSchematicElements } from "../transform-elements" import { - ComponentBuilderClass, type BaseComponentBuilder, + ComponentBuilderClass, } from "./ComponentBuilder" const debug = Debug("tscircuit:builder:bug-builder") @@ -28,7 +27,7 @@ export interface BugBuilder extends BaseComponentBuilder { properties: Except< SourceSimpleBugInput, "type" | "source_component_id" | "ftype" | "name" - > & { name?: string } + > & { name?: string; schWidth?: number } ): BugBuilder } @@ -44,7 +43,12 @@ export class BugBuilderClass ...this.source_properties, ftype: "simple_bug", } - this.settable_schematic_properties.push("port_labels", "port_arrangement") + this.settable_schematic_properties.push( + "port_labels", + "port_arrangement", + "pin_spacing", + "schWidth" + ) } setSourceProperties(props) { @@ -55,6 +59,14 @@ export class BugBuilderClass return this } + setSchematicProperties(props) { + this.schematic_properties = { + ...this.schematic_properties, + ...props, + } + return this + } + async build(bc): Promise { const elements: Type.AnyElement[] = [] const { project_builder } = this @@ -73,42 +85,33 @@ export class BugBuilderClass } elements.push(source_component) - let port_arrangement: PortArrangement = - this.schematic_properties?.port_arrangement - - /** This can be used as a fallback if pinLabels or a port arrangement aren't explicitly given */ - const footprintPinLabels = this.footprint.getFootprintPinLabels() - const footprintPinCount = Object.entries(footprintPinLabels).length + const port_arrangement = this.schematic_properties?.port_arrangement if (!port_arrangement) { - if (footprintPinCount === 0) { - throw new Error( - "port_arrangement/schPortArrangement is required when building a without a footprint (footprint has no pins)" - ) - } - port_arrangement = { - left_size: Math.floor(footprintPinCount / 2 + 0.500001), - right_size: Math.floor(footprintPinCount / 2), - } + throw new Error("port_arrangement is required when building a ") } const pin_spacing = this.schematic_properties?.pin_spacing ?? DEFAULT_PIN_SPACING + const extended_port_arrangement = { ...port_arrangement, pin_spacing: this.schematic_properties.pin_spacing, + schWidth: this.source_properties.schPortArrangement.schWidth, } + const port_arrangement_size = getPortArrangementSize( extended_port_arrangement ) + const schematic_component: Soup.SchematicComponent = { type: "schematic_component", source_component_id, schematic_component_id, rotation: this.schematic_rotation ?? 0, size: { - width: port_arrangement_size.width - pin_spacing, - height: port_arrangement_size.height - pin_spacing, + width: port_arrangement_size.width, + height: port_arrangement_size.height, }, center: this.schematic_position || { x: 0, y: 0 }, ...this.schematic_properties, @@ -122,20 +125,14 @@ export class BugBuilderClass const textElements: SchematicText[] = [] // add ports based on port arrangement and give appropriate labels - let { port_labels } = this.schematic_properties + const { port_labels } = this.schematic_properties + const { total_ports } = port_arrangement_size if (!port_labels) { - if (footprintPinCount === 0) { - throw new Error( - "port_labels/pinLabels is required when building a without a footprint (footprint has no pins)" - ) - } - - port_labels = footprintPinLabels - debug("inferring port_labels from footprint pin labels") + throw new Error("port_labels is required when building a ") } - const port_indices = getPortIndices(port_arrangement) + const port_indices = getPortIndices(extended_port_arrangement) for (const pn of port_indices) { const portPosition = getPortPosition(extended_port_arrangement, pn) this.ports.addPort({ @@ -155,9 +152,7 @@ export class BugBuilderClass schematic_component_id, text: port_labels[pn], anchor: is_left ? "left" : "right", - rotation: 0, - position: { x: portPosition.x + (is_left ? 0.8 : -0.8) * pin_spacing, y: portPosition.y, @@ -173,7 +168,6 @@ export class BugBuilderClass text: port_labels[pn], anchor: "right", rotation: Math.PI / 2, - position: { x: portPosition.x, y: portPosition.y - 0.4, @@ -189,7 +183,6 @@ export class BugBuilderClass text: port_labels[pn], anchor: "left", rotation: Math.PI / 2, - position: { x: portPosition.x, y: portPosition.y + 0.4, @@ -229,13 +222,6 @@ export class BugBuilderClass associatePcbPortsWithPads(elements) - // TODO use this standard method: - // matchPCBPortsWithFootprintAndMutate({ - // footprint_elements, - // pcb_ports: elements.filter((elm) => elm.type === "pcb_port"), - // source_ports: elements.filter((elm) => elm.type === "source_port"), - // } as any) - elements.push( ...this._getCadElements({ source_component_id, pcb_component }, bc) ) diff --git a/src/lib/builder/component-builder/remap-prop.ts b/src/lib/builder/component-builder/remap-prop.ts index fbd88d97..309f5b44 100644 --- a/src/lib/builder/component-builder/remap-prop.ts +++ b/src/lib/builder/component-builder/remap-prop.ts @@ -15,6 +15,7 @@ export const remapProp = (prop: string, val: any): [string, any] => { right_side: val.rightSide, top_side: val.topSide, bottom_side: val.bottomSide, + schWidth: val.schWidth, }), ] case "pcbX": diff --git a/src/lib/utils/get-port-position.ts b/src/lib/utils/get-port-position.ts index 56df8ab9..e464e704 100644 --- a/src/lib/utils/get-port-position.ts +++ b/src/lib/utils/get-port-position.ts @@ -26,6 +26,7 @@ export type PortArrangement = SideSizes | ExplicitPinMappingArrangement export type ExtendedPortArrangement = PortArrangement & { pin_spacing?: number + schWidth?: number } export const hasExplicitPinMapping = ( @@ -162,18 +163,22 @@ export const getPortArrangementSize = ( const total_ports = top_size + right_size + bottom_size + left_size - const width = Math.max( - // MIN_SIDE_DIST is multiplied by the ratio of pin spacing to create more - // square-like bugs + const calculatedWidth = Math.max( MIN_SIDE_DIST * (pinSpacing / DEFAULT_PIN_SPACING), (top_size + 1) * pinSpacing, (bottom_size + 1) * pinSpacing ) + + const width = + port_arrangement.schWidth !== undefined + ? port_arrangement.schWidth + : calculatedWidth const height = Math.max( MIN_SIDE_DIST, (left_size + 1) * pinSpacing, (right_size + 1) * pinSpacing ) + return { width, height, total_ports } } diff --git a/tests/bug-builder/bug-with-width-resizing.test.tsx b/tests/bug-builder/bug-with-width-resizing.test.tsx new file mode 100644 index 00000000..38e65148 --- /dev/null +++ b/tests/bug-builder/bug-with-width-resizing.test.tsx @@ -0,0 +1,48 @@ +import test from "ava" +import { getTestFixture } from "../fixtures/get-test-fixture" + +test("bug with width resizing", async (t) => { + const { logSoup, pb } = await getTestFixture(t) + + const soup = await pb + .add("board", (board) => + board + .setProps({ + pcbX: 0, + pcbY: 0, + width: 10, + height: 10, + }) + .add("bug", (bug) => + bug.setProps({ + schPinLabels: { + 1: "P1", + 2: "P2", + 3: "P3", + 4: "P4", + 5: "P5", + 6: "P6", + 7: "P7", + 8: "P8", + }, + schPortArrangement: { + leftSize: 4, + rightSize: 4, + schWidth: 2, + }, + pcbRotation: "90deg", + cadModel: { + objUrl: + "https://modelcdn.tscircuit.com/easyeda_models/download?pn=C128415&uuid=dc694c23844346e9981bdbac7bb76421", + }, + footprint: "soic8_w7.2mm", + pcbX: 3, + pcbY: 3, + }) + ) + ) + .build() + + await logSoup(soup) + t.pass() +})