From cc599e6e3495936dfb1ac2f5460f2604fe88c8a3 Mon Sep 17 00:00:00 2001 From: mohan-bee Date: Sat, 18 Apr 2026 11:44:28 +0530 Subject: [PATCH 1/5] Respect min via rules throughout autorouting and PCB output --- lib/components/normal-components/Board.ts | 20 +++++- .../primitive-components/Group/Group.ts | 48 +++++++++++-- .../Group/Group_phasedAutoroutingUtils.ts | 18 +++-- .../Subcircuit/inflators/inflatePcbBoard.ts | 9 ++- lib/fiber/intrinsic-jsx.ts | 12 +++- lib/utils/autorouting/SimpleRouteJson.ts | 4 ++ .../getSimpleRouteJsonFromCircuitJson.ts | 4 ++ lib/utils/autorouting/min-via-rules.ts | 19 +++++ tests/features/board-min-via-rules.test.tsx | 69 +++++++++++++++++++ tests/groups/group-min-via-rules.test.tsx | 26 +++++++ 10 files changed, 211 insertions(+), 18 deletions(-) create mode 100644 lib/utils/autorouting/min-via-rules.ts create mode 100644 tests/features/board-min-via-rules.test.tsx create mode 100644 tests/groups/group-min-via-rules.test.tsx diff --git a/lib/components/normal-components/Board.ts b/lib/components/normal-components/Board.ts index 00e04b555..bb17fbb61 100644 --- a/lib/components/normal-components/Board.ts +++ b/lib/components/normal-components/Board.ts @@ -9,6 +9,10 @@ import { boardProps } from "@tscircuit/props" import type { AnyCircuitElement, PcbBoard } from "circuit-json" import { type Matrix, compose, translate } from "transformation-matrix" import { getDescendantSubcircuitIds } from "../../utils/autorouting/getAncestorSubcircuitIds" +import { + getMinViaRuleValues, + minViaRuleProps, +} from "../../utils/autorouting/min-via-rules" import { getBoardCenterFromAnchor } from "../../utils/boards/get-board-center-from-anchor" import { inflateCircuitJson } from "../../utils/circuit-json/inflate-circuit-json" import { NormalComponent } from "../base-components/NormalComponent/NormalComponent" @@ -20,6 +24,7 @@ import { Subcircuit_getSubcircuitPropHash } from "../primitive-components/Group/ import type { BoardI } from "./BoardI" const MIN_EFFECTIVE_BORDER_RADIUS_MM = 0.01 +const boardPropsWithMinViaRules = boardProps.extend(minViaRuleProps) const getRoundedRectOutline = ( width: number, @@ -89,7 +94,7 @@ const getRoundedRectOutline = ( } export class Board - extends Group + extends Group implements BoardI, SubcircuitI { pcb_board_id: string | null = null @@ -110,7 +115,7 @@ export class Board get config() { return { componentName: "Board", - zodProps: boardProps, + zodProps: boardPropsWithMinViaRules, } } @@ -383,11 +388,16 @@ export class Board super.doInitialSourceRender() const { db } = this.root! + const { minViaDiameter, minViaHole } = getMinViaRuleValues( + this._parsedProps, + ) const source_board = db.source_board.insert({ source_group_id: this.source_group_id!, title: this.props.title || this.props.name, - }) + ...(minViaDiameter != null ? { min_via_diameter: minViaDiameter } : {}), + ...(minViaHole != null ? { min_via_hole: minViaHole } : {}), + } as any) this.source_board_id = source_board.source_board_id } @@ -509,6 +519,8 @@ export class Board } } + const { minViaDiameter, minViaHole } = getMinViaRuleValues(props) + const pcb_board = db.pcb_board.insert({ source_board_id: this.source_board_id, center, @@ -523,6 +535,8 @@ export class Board y: point.y + (props.outlineOffsetY ?? 0) + outlineTranslation.y, })), material: props.material, + ...(minViaDiameter != null ? { min_via_diameter: minViaDiameter } : {}), + ...(minViaHole != null ? { min_via_hole: minViaHole } : {}), } as Omit) this.pcb_board_id = pcb_board.pcb_board_id! diff --git a/lib/components/primitive-components/Group/Group.ts b/lib/components/primitive-components/Group/Group.ts index f3650c9b1..055559b3c 100644 --- a/lib/components/primitive-components/Group/Group.ts +++ b/lib/components/primitive-components/Group/Group.ts @@ -29,6 +29,11 @@ import { getBoundsOfPcbComponents } from "lib/utils/get-bounds-of-pcb-components import { getViaDiameterDefaults } from "lib/utils/pcbStyle/getViaDiameterDefaults" import { getSimpleRouteJsonFromCircuitJson } from "lib/utils/public-exports" import { z } from "zod" +import { + getMinViaRuleValues, + minViaRuleProps, + type MinViaRuleProps, +} from "../../../utils/autorouting/min-via-rules" import { NormalComponent } from "../../base-components/NormalComponent/NormalComponent" import type { Trace } from "../Trace/Trace" import { TraceHint } from "../TraceHint" @@ -57,7 +62,14 @@ import { insertAutoplacedJumpers } from "./insert-autoplaced-jumpers" import { splitPcbTracesOnJumperSegments } from "./split-pcb-traces-on-jumper-segments" import { computeCenterFromAnchorPosition } from "./utils/computeCenterFromAnchorPosition" -export class Group = typeof groupProps> +const groupPropsWithMinViaRules = z.discriminatedUnion("subcircuit", [ + groupProps.options[0], + groupProps.options[1].extend(minViaRuleProps), +]) + +export class Group< + Props extends z.ZodType = typeof groupPropsWithMinViaRules, + > extends NormalComponent implements ISubcircuit { @@ -126,13 +138,16 @@ export class Group = typeof groupProps> get config() { return { - zodProps: groupProps as unknown as Props, + zodProps: groupPropsWithMinViaRules as unknown as Props, componentName: "Group", } } doInitialSourceGroupRender() { const { db } = this.root! + const { minViaDiameter, minViaHole } = getMinViaRuleValues( + this._parsedProps as MinViaRuleProps, + ) const hasExplicitName = typeof (this._parsedProps as { name?: unknown }).name === "string" && (this._parsedProps as { name?: string }).name!.length > 0 @@ -141,7 +156,9 @@ export class Group = typeof groupProps> name: this.name, is_subcircuit: this.isSubcircuit, was_automatically_named: !hasExplicitName, - }) + ...(minViaDiameter != null ? { min_via_diameter: minViaDiameter } : {}), + ...(minViaHole != null ? { min_via_hole: minViaHole } : {}), + } as any) this.source_group_id = source_group.source_group_id if (this.isSubcircuit) { this.subcircuit_id = `subcircuit_${source_group.source_group_id}` as any @@ -185,6 +202,9 @@ export class Group = typeof groupProps> const groupProps = props as SubcircuitGroupProps const hasOutline = groupProps.outline && groupProps.outline.length > 0 + const { minViaDiameter, minViaHole } = getMinViaRuleValues( + props as SubcircuitGroupProps & MinViaRuleProps, + ) const numericOutline = hasOutline ? groupProps.outline!.map((point) => ({ @@ -211,7 +231,9 @@ export class Group = typeof groupProps> } : undefined, anchor_alignment: props.pcbAnchorAlignment ?? null, - }) + ...(minViaDiameter != null ? { min_via_diameter: minViaDiameter } : {}), + ...(minViaHole != null ? { min_via_hole: minViaHole } : {}), + } as any) this.pcb_group_id = pcb_group.pcb_group_id for (const child of this.children) { @@ -609,7 +631,10 @@ export class Group = typeof groupProps> ) simpleRouteJson.obstacles = [ ...simpleRouteJson.obstacles, - ...Group_getObstaclesFromRoutedTraces(outputTraces), + ...Group_getObstaclesFromRoutedTraces( + outputTraces, + baseSimpleRouteJson.minViaDiameter, + ), ] } @@ -904,6 +929,9 @@ export class Group = typeof groupProps> // Apply each routed trace to the corresponding circuit trace const pcbStyle = this.getInheritedMergedProperty("pcbStyle") const { holeDiameter, padDiameter } = getViaDiameterDefaults(pcbStyle) + const { minViaDiameter, minViaHole } = getMinViaRuleValues( + this._parsedProps as MinViaRuleProps, + ) // First, create jumper components from getOutputJumpers() result if (output_jumpers && output_jumpers.length > 0) { @@ -958,12 +986,18 @@ export class Group = typeof groupProps> if (pcb_trace.type === "pcb_trace") { for (const point of pcb_trace.route) { if (point.route_type === "via") { + const routeVia = point as typeof point & { + via_diameter?: number + via_hole_diameter?: number + } db.pcb_via.insert({ pcb_trace_id: pcb_trace.pcb_trace_id, x: point.x, y: point.y, - hole_diameter: holeDiameter, - outer_diameter: padDiameter, + hole_diameter: + routeVia.via_hole_diameter ?? minViaHole ?? holeDiameter, + outer_diameter: + routeVia.via_diameter ?? minViaDiameter ?? padDiameter, layers: [ point.from_layer as LayerRef, point.to_layer as LayerRef, diff --git a/lib/components/primitive-components/Group/Group_phasedAutoroutingUtils.ts b/lib/components/primitive-components/Group/Group_phasedAutoroutingUtils.ts index b9d21e0ba..f997f471b 100644 --- a/lib/components/primitive-components/Group/Group_phasedAutoroutingUtils.ts +++ b/lib/components/primitive-components/Group/Group_phasedAutoroutingUtils.ts @@ -114,14 +114,15 @@ function createViaObstacle( point: Extract, connectedTo: string, obstacleIndex: number, + defaultViaDiameter: number, ): Obstacle { return { obstacleId: `${connectedTo}_phase_via_obstacle_${obstacleIndex}`, type: "rect", layers: [point.from_layer, point.to_layer], center: { x: point.x, y: point.y }, - width: 0.6, - height: 0.6, + width: point.via_diameter ?? defaultViaDiameter, + height: point.via_diameter ?? defaultViaDiameter, connectedTo: [connectedTo], } } @@ -129,13 +130,21 @@ function createViaObstacle( function addTraceObstacles( obstacles: Obstacle[], trace: SimplifiedPcbTrace, + defaultViaDiameter: number, ): void { const connectedTo = getTraceConnectionName(trace) for (let routeIndex = 0; routeIndex < trace.route.length; routeIndex++) { const routePoint = trace.route[routeIndex] if (isViaPoint(routePoint)) { - obstacles.push(createViaObstacle(routePoint, connectedTo, routeIndex)) + obstacles.push( + createViaObstacle( + routePoint, + connectedTo, + routeIndex, + defaultViaDiameter, + ), + ) } else if (isJumperPoint(routePoint)) { obstacles.push(createJumperObstacle(routePoint, connectedTo, routeIndex)) } @@ -198,10 +207,11 @@ export function Group_filterSimpleRouteJsonForPhase( export function Group_getObstaclesFromRoutedTraces( traces: SimplifiedPcbTrace[], + defaultViaDiameter = 0.6, ): Obstacle[] { const obstacles: Obstacle[] = [] for (const trace of traces) { - addTraceObstacles(obstacles, trace) + addTraceObstacles(obstacles, trace, defaultViaDiameter) } return obstacles } diff --git a/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts b/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts index 48e9bda5e..e9588422b 100644 --- a/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts +++ b/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts @@ -2,6 +2,7 @@ import type { PcbBoard } from "circuit-json" import type { InflatorContext } from "../InflatorFn" import { Board } from "lib/components/normal-components/Board" import type { BoardProps } from "@tscircuit/props" +import type { MinViaRuleProps } from "lib/utils/autorouting/min-via-rules" export function inflatePcbBoard( pcbBoard: PcbBoard, @@ -24,7 +25,7 @@ export function inflatePcbBoard( } // Create board props from PCB data - const boardProps: BoardProps = { + const boardProps: BoardProps & MinViaRuleProps = { name: "inflated_board", } @@ -38,6 +39,12 @@ export function inflatePcbBoard( if (pcbBoard.outline) boardProps.outline = pcbBoard.outline if (pcbBoard.thickness) boardProps.thickness = pcbBoard.thickness if (pcbBoard.material) boardProps.material = pcbBoard.material + if ((pcbBoard as any).min_via_diameter != null) { + boardProps.minViaDiameter = (pcbBoard as any).min_via_diameter + } + if ((pcbBoard as any).min_via_hole != null) { + boardProps.minViaHole = (pcbBoard as any).min_via_hole + } // Create the Board instance const board = new Board(boardProps) diff --git a/lib/fiber/intrinsic-jsx.ts b/lib/fiber/intrinsic-jsx.ts index 4729457b2..9b63f4a78 100644 --- a/lib/fiber/intrinsic-jsx.ts +++ b/lib/fiber/intrinsic-jsx.ts @@ -1,5 +1,11 @@ import type * as Props from "@tscircuit/props" import type { DetailedHTMLProps, SVGProps } from "react" +import type { MinViaRuleProps } from "lib/utils/autorouting/min-via-rules" + +type BoardPropsWithMinViaRules = Props.BoardProps & MinViaRuleProps +type GroupPropsWithMinViaRules = Props.GroupProps & MinViaRuleProps +type SubcircuitGroupPropsWithMinViaRules = Props.SubcircuitGroupProps & + MinViaRuleProps export interface TscircuitElements { resistor: Props.ResistorProps @@ -9,7 +15,7 @@ export interface TscircuitElements { diode: Props.DiodeProps fuse: Props.FuseProps led: Props.LedProps - board: Props.BoardProps + board: BoardPropsWithMinViaRules mountedboard: Props.MountedBoardProps panel: Props.PanelProps subpanel: Props.SubpanelProps @@ -37,7 +43,7 @@ export interface TscircuitElements { keepout: Props.PcbKeepoutProps hole: Props.HoleProps port: Props.PortProps - group: Props.GroupProps + group: GroupPropsWithMinViaRules netlabel: Props.NetLabelProps opamp: Props.OpAmpProps cadmodel: Props.CadModelProps @@ -77,7 +83,7 @@ export interface TscircuitElements { connector: Props.ConnectorProps pinheader: Props.PinHeaderProps resonator: Props.ResonatorProps - subcircuit: Props.SubcircuitGroupProps + subcircuit: SubcircuitGroupPropsWithMinViaRules transistor: Props.TransistorProps switch: Props.SwitchProps mosfet: Props.MosfetProps diff --git a/lib/utils/autorouting/SimpleRouteJson.ts b/lib/utils/autorouting/SimpleRouteJson.ts index d17cc193f..64d2b7615 100644 --- a/lib/utils/autorouting/SimpleRouteJson.ts +++ b/lib/utils/autorouting/SimpleRouteJson.ts @@ -16,6 +16,8 @@ export type SimplifiedPcbTrace = { y: number to_layer: string from_layer: string + via_diameter?: number + via_hole_diameter?: number } | { route_type: "jumper" @@ -60,6 +62,8 @@ export interface SimpleRouteJson { layerCount: number minTraceWidth: number nominalTraceWidth?: number + minViaDiameter?: number + minViaHole?: number obstacles: Obstacle[] connections: Array bounds: { minX: number; maxX: number; minY: number; maxY: number } diff --git a/lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts b/lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts index 06ce3d5e6..280c31b27 100644 --- a/lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts +++ b/lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts @@ -464,6 +464,10 @@ export const getSimpleRouteJsonFromCircuitJson = ({ // subcircuit layerCount: board?.num_layers ?? 2, minTraceWidth, + minViaDiameter: + (board as any)?.min_via_diameter ?? (pcbGroup as any)?.min_via_diameter, + minViaHole: + (board as any)?.min_via_hole ?? (pcbGroup as any)?.min_via_hole, nominalTraceWidth, outline: board?.outline?.map((point) => ({ ...point })), }, diff --git a/lib/utils/autorouting/min-via-rules.ts b/lib/utils/autorouting/min-via-rules.ts new file mode 100644 index 000000000..e16760440 --- /dev/null +++ b/lib/utils/autorouting/min-via-rules.ts @@ -0,0 +1,19 @@ +import { distance } from "circuit-json" +import { z } from "zod" + +export const minViaRuleProps = { + minViaDiameter: z.number().or(z.string()).optional(), + minViaHole: z.number().or(z.string()).optional(), +} + +export type MinViaRuleProps = { + minViaDiameter?: number | string + minViaHole?: number | string +} + +export const getMinViaRuleValues = (props?: MinViaRuleProps) => ({ + minViaDiameter: + props?.minViaDiameter != null ? distance.parse(props.minViaDiameter) : null, + minViaHole: + props?.minViaHole != null ? distance.parse(props.minViaHole) : null, +}) diff --git a/tests/features/board-min-via-rules.test.tsx b/tests/features/board-min-via-rules.test.tsx new file mode 100644 index 000000000..4a62d48a2 --- /dev/null +++ b/tests/features/board-min-via-rules.test.tsx @@ -0,0 +1,69 @@ +import { expect, test } from "bun:test" +import { getTestFixture } from "tests/fixtures/get-test-fixture" +import { createBasicAutorouter } from "tests/fixtures/createBasicAutorouter" +import type { SimpleRouteJson } from "lib/utils/autorouting/SimpleRouteJson" + +test("board min via rules flow into srj and routed vias", async () => { + const { circuit } = getTestFixture() + + let capturedSimpleRouteJson: SimpleRouteJson | undefined + + circuit.add( + { + capturedSimpleRouteJson = simpleRouteJson + + return [ + { + type: "pcb_trace", + pcb_trace_id: "trace_0", + connection_name: simpleRouteJson.connections[0]!.name, + route: [ + { + route_type: "wire", + x: -4, + y: 0, + width: 0.15, + layer: "top", + }, + { + route_type: "via", + x: 0, + y: 0, + from_layer: "top", + to_layer: "bottom", + }, + { + route_type: "wire", + x: 4, + y: 0, + width: 0.15, + layer: "bottom", + }, + ], + }, + ] + }), + }} + > + + + + , + ) + + await circuit.renderUntilSettled() + + expect(capturedSimpleRouteJson?.minViaDiameter).toBe(0.6) + expect(capturedSimpleRouteJson?.minViaHole).toBe(0.3) + + const via = circuit.db.pcb_via.list()[0] + expect(via?.outer_diameter).toBe(0.6) + expect(via?.hole_diameter).toBe(0.3) +}) diff --git a/tests/groups/group-min-via-rules.test.tsx b/tests/groups/group-min-via-rules.test.tsx new file mode 100644 index 000000000..8a8206196 --- /dev/null +++ b/tests/groups/group-min-via-rules.test.tsx @@ -0,0 +1,26 @@ +import { expect, test } from "bun:test" +import { getTestFixture } from "tests/fixtures/get-test-fixture" +import { getSimpleRouteJsonFromCircuitJson } from "lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson" + +test("group min via rules flow into simple route json", async () => { + const { circuit } = getTestFixture() + + circuit.add( + + + + + , + ) + + await circuit.renderUntilSettled() + + const subcircuitId = circuit.db.source_group.list()[0]?.subcircuit_id + const { simpleRouteJson } = getSimpleRouteJsonFromCircuitJson({ + db: circuit.db, + subcircuit_id: subcircuitId, + }) + + expect(simpleRouteJson.minViaDiameter).toBe(0.55) + expect(simpleRouteJson.minViaHole).toBe(0.25) +}) From c58b96201ad1475007d13505915e35523eaa8fcb Mon Sep 17 00:00:00 2001 From: mohan-bee Date: Sat, 18 Apr 2026 11:50:37 +0530 Subject: [PATCH 2/5] up --- lib/components/normal-components/Board.ts | 13 +++++++------ lib/components/primitive-components/Group/Group.ts | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/components/normal-components/Board.ts b/lib/components/normal-components/Board.ts index bb17fbb61..b50f28aa5 100644 --- a/lib/components/normal-components/Board.ts +++ b/lib/components/normal-components/Board.ts @@ -11,7 +11,7 @@ import { type Matrix, compose, translate } from "transformation-matrix" import { getDescendantSubcircuitIds } from "../../utils/autorouting/getAncestorSubcircuitIds" import { getMinViaRuleValues, - minViaRuleProps, + type MinViaRuleProps, } from "../../utils/autorouting/min-via-rules" import { getBoardCenterFromAnchor } from "../../utils/boards/get-board-center-from-anchor" import { inflateCircuitJson } from "../../utils/circuit-json/inflate-circuit-json" @@ -24,7 +24,6 @@ import { Subcircuit_getSubcircuitPropHash } from "../primitive-components/Group/ import type { BoardI } from "./BoardI" const MIN_EFFECTIVE_BORDER_RADIUS_MM = 0.01 -const boardPropsWithMinViaRules = boardProps.extend(minViaRuleProps) const getRoundedRectOutline = ( width: number, @@ -94,7 +93,7 @@ const getRoundedRectOutline = ( } export class Board - extends Group + extends Group implements BoardI, SubcircuitI { pcb_board_id: string | null = null @@ -115,7 +114,7 @@ export class Board get config() { return { componentName: "Board", - zodProps: boardPropsWithMinViaRules, + zodProps: boardProps, } } @@ -389,7 +388,7 @@ export class Board const { db } = this.root! const { minViaDiameter, minViaHole } = getMinViaRuleValues( - this._parsedProps, + this.props as MinViaRuleProps, ) const source_board = db.source_board.insert({ @@ -519,7 +518,9 @@ export class Board } } - const { minViaDiameter, minViaHole } = getMinViaRuleValues(props) + const { minViaDiameter, minViaHole } = getMinViaRuleValues( + this.props as MinViaRuleProps, + ) const pcb_board = db.pcb_board.insert({ source_board_id: this.source_board_id, diff --git a/lib/components/primitive-components/Group/Group.ts b/lib/components/primitive-components/Group/Group.ts index 055559b3c..0fea40ccb 100644 --- a/lib/components/primitive-components/Group/Group.ts +++ b/lib/components/primitive-components/Group/Group.ts @@ -930,7 +930,7 @@ export class Group< const pcbStyle = this.getInheritedMergedProperty("pcbStyle") const { holeDiameter, padDiameter } = getViaDiameterDefaults(pcbStyle) const { minViaDiameter, minViaHole } = getMinViaRuleValues( - this._parsedProps as MinViaRuleProps, + this.props as MinViaRuleProps, ) // First, create jumper components from getOutputJumpers() result From 538ae79a2658ed3c9884004074953aecfabe83d2 Mon Sep 17 00:00:00 2001 From: mohan-bee Date: Sat, 18 Apr 2026 11:54:21 +0530 Subject: [PATCH 3/5] up --- .../primitive-components/Group/Group.ts | 16 ++++------------ lib/fiber/intrinsic-jsx.ts | 11 +++-------- lib/utils/autorouting/min-via-rules.ts | 6 ------ 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/lib/components/primitive-components/Group/Group.ts b/lib/components/primitive-components/Group/Group.ts index 0fea40ccb..fbc85b62e 100644 --- a/lib/components/primitive-components/Group/Group.ts +++ b/lib/components/primitive-components/Group/Group.ts @@ -31,7 +31,6 @@ import { getSimpleRouteJsonFromCircuitJson } from "lib/utils/public-exports" import { z } from "zod" import { getMinViaRuleValues, - minViaRuleProps, type MinViaRuleProps, } from "../../../utils/autorouting/min-via-rules" import { NormalComponent } from "../../base-components/NormalComponent/NormalComponent" @@ -62,14 +61,7 @@ import { insertAutoplacedJumpers } from "./insert-autoplaced-jumpers" import { splitPcbTracesOnJumperSegments } from "./split-pcb-traces-on-jumper-segments" import { computeCenterFromAnchorPosition } from "./utils/computeCenterFromAnchorPosition" -const groupPropsWithMinViaRules = z.discriminatedUnion("subcircuit", [ - groupProps.options[0], - groupProps.options[1].extend(minViaRuleProps), -]) - -export class Group< - Props extends z.ZodType = typeof groupPropsWithMinViaRules, - > +export class Group = typeof groupProps> extends NormalComponent implements ISubcircuit { @@ -138,7 +130,7 @@ export class Group< get config() { return { - zodProps: groupPropsWithMinViaRules as unknown as Props, + zodProps: groupProps as unknown as Props, componentName: "Group", } } @@ -146,7 +138,7 @@ export class Group< doInitialSourceGroupRender() { const { db } = this.root! const { minViaDiameter, minViaHole } = getMinViaRuleValues( - this._parsedProps as MinViaRuleProps, + this.props as MinViaRuleProps, ) const hasExplicitName = typeof (this._parsedProps as { name?: unknown }).name === "string" && @@ -203,7 +195,7 @@ export class Group< const groupProps = props as SubcircuitGroupProps const hasOutline = groupProps.outline && groupProps.outline.length > 0 const { minViaDiameter, minViaHole } = getMinViaRuleValues( - props as SubcircuitGroupProps & MinViaRuleProps, + this.props as MinViaRuleProps, ) const numericOutline = hasOutline diff --git a/lib/fiber/intrinsic-jsx.ts b/lib/fiber/intrinsic-jsx.ts index 9b63f4a78..332a6967e 100644 --- a/lib/fiber/intrinsic-jsx.ts +++ b/lib/fiber/intrinsic-jsx.ts @@ -2,11 +2,6 @@ import type * as Props from "@tscircuit/props" import type { DetailedHTMLProps, SVGProps } from "react" import type { MinViaRuleProps } from "lib/utils/autorouting/min-via-rules" -type BoardPropsWithMinViaRules = Props.BoardProps & MinViaRuleProps -type GroupPropsWithMinViaRules = Props.GroupProps & MinViaRuleProps -type SubcircuitGroupPropsWithMinViaRules = Props.SubcircuitGroupProps & - MinViaRuleProps - export interface TscircuitElements { resistor: Props.ResistorProps capacitor: Props.CapacitorProps @@ -15,7 +10,7 @@ export interface TscircuitElements { diode: Props.DiodeProps fuse: Props.FuseProps led: Props.LedProps - board: BoardPropsWithMinViaRules + board: Props.BoardProps & MinViaRuleProps mountedboard: Props.MountedBoardProps panel: Props.PanelProps subpanel: Props.SubpanelProps @@ -43,7 +38,7 @@ export interface TscircuitElements { keepout: Props.PcbKeepoutProps hole: Props.HoleProps port: Props.PortProps - group: GroupPropsWithMinViaRules + group: Props.GroupProps & MinViaRuleProps netlabel: Props.NetLabelProps opamp: Props.OpAmpProps cadmodel: Props.CadModelProps @@ -83,7 +78,7 @@ export interface TscircuitElements { connector: Props.ConnectorProps pinheader: Props.PinHeaderProps resonator: Props.ResonatorProps - subcircuit: SubcircuitGroupPropsWithMinViaRules + subcircuit: Props.SubcircuitGroupProps & MinViaRuleProps transistor: Props.TransistorProps switch: Props.SwitchProps mosfet: Props.MosfetProps diff --git a/lib/utils/autorouting/min-via-rules.ts b/lib/utils/autorouting/min-via-rules.ts index e16760440..1858d2b05 100644 --- a/lib/utils/autorouting/min-via-rules.ts +++ b/lib/utils/autorouting/min-via-rules.ts @@ -1,10 +1,4 @@ import { distance } from "circuit-json" -import { z } from "zod" - -export const minViaRuleProps = { - minViaDiameter: z.number().or(z.string()).optional(), - minViaHole: z.number().or(z.string()).optional(), -} export type MinViaRuleProps = { minViaDiameter?: number | string From c90024b66faa2b4225c2cdd608895a7b21b87641 Mon Sep 17 00:00:00 2001 From: mohan-bee Date: Sat, 18 Apr 2026 12:01:29 +0530 Subject: [PATCH 4/5] up --- .../Group/Subcircuit/inflators/inflatePcbBoard.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts b/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts index e9588422b..eaddd881d 100644 --- a/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts +++ b/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts @@ -28,6 +28,10 @@ export function inflatePcbBoard( const boardProps: BoardProps & MinViaRuleProps = { name: "inflated_board", } + const pcbBoardWithMinViaRules = pcbBoard as PcbBoard & { + min_via_diameter?: number + min_via_hole?: number + } // Add PCB-specific properties if (pcbBoard.width) boardProps.width = pcbBoard.width @@ -39,11 +43,11 @@ export function inflatePcbBoard( if (pcbBoard.outline) boardProps.outline = pcbBoard.outline if (pcbBoard.thickness) boardProps.thickness = pcbBoard.thickness if (pcbBoard.material) boardProps.material = pcbBoard.material - if ((pcbBoard as any).min_via_diameter != null) { - boardProps.minViaDiameter = (pcbBoard as any).min_via_diameter + if (pcbBoardWithMinViaRules.min_via_diameter != null) { + boardProps.minViaDiameter = pcbBoardWithMinViaRules.min_via_diameter } - if ((pcbBoard as any).min_via_hole != null) { - boardProps.minViaHole = (pcbBoard as any).min_via_hole + if (pcbBoardWithMinViaRules.min_via_hole != null) { + boardProps.minViaHole = pcbBoardWithMinViaRules.min_via_hole } // Create the Board instance From d7c3894920650457c7cbc9ffd68fe9782263262f Mon Sep 17 00:00:00 2001 From: mohan-bee Date: Sat, 18 Apr 2026 12:21:24 +0530 Subject: [PATCH 5/5] up --- lib/components/normal-components/Board.ts | 14 +++--------- .../primitive-components/Group/Group.ts | 22 ++++++------------- .../Subcircuit/inflators/inflatePcbBoard.ts | 15 +++++-------- lib/fiber/intrinsic-jsx.ts | 7 +++--- .../getSimpleRouteJsonFromCircuitJson.ts | 6 ++--- lib/utils/autorouting/min-via-rules.ts | 13 ----------- 6 files changed, 20 insertions(+), 57 deletions(-) delete mode 100644 lib/utils/autorouting/min-via-rules.ts diff --git a/lib/components/normal-components/Board.ts b/lib/components/normal-components/Board.ts index b50f28aa5..3412fa309 100644 --- a/lib/components/normal-components/Board.ts +++ b/lib/components/normal-components/Board.ts @@ -9,10 +9,6 @@ import { boardProps } from "@tscircuit/props" import type { AnyCircuitElement, PcbBoard } from "circuit-json" import { type Matrix, compose, translate } from "transformation-matrix" import { getDescendantSubcircuitIds } from "../../utils/autorouting/getAncestorSubcircuitIds" -import { - getMinViaRuleValues, - type MinViaRuleProps, -} from "../../utils/autorouting/min-via-rules" import { getBoardCenterFromAnchor } from "../../utils/boards/get-board-center-from-anchor" import { inflateCircuitJson } from "../../utils/circuit-json/inflate-circuit-json" import { NormalComponent } from "../base-components/NormalComponent/NormalComponent" @@ -387,16 +383,14 @@ export class Board super.doInitialSourceRender() const { db } = this.root! - const { minViaDiameter, minViaHole } = getMinViaRuleValues( - this.props as MinViaRuleProps, - ) + const { minViaDiameter, minViaHole } = this._parsedProps const source_board = db.source_board.insert({ source_group_id: this.source_group_id!, title: this.props.title || this.props.name, ...(minViaDiameter != null ? { min_via_diameter: minViaDiameter } : {}), ...(minViaHole != null ? { min_via_hole: minViaHole } : {}), - } as any) + }) this.source_board_id = source_board.source_board_id } @@ -518,9 +512,7 @@ export class Board } } - const { minViaDiameter, minViaHole } = getMinViaRuleValues( - this.props as MinViaRuleProps, - ) + const { minViaDiameter, minViaHole } = this._parsedProps const pcb_board = db.pcb_board.insert({ source_board_id: this.source_board_id, diff --git a/lib/components/primitive-components/Group/Group.ts b/lib/components/primitive-components/Group/Group.ts index fbc85b62e..b52380756 100644 --- a/lib/components/primitive-components/Group/Group.ts +++ b/lib/components/primitive-components/Group/Group.ts @@ -29,10 +29,6 @@ import { getBoundsOfPcbComponents } from "lib/utils/get-bounds-of-pcb-components import { getViaDiameterDefaults } from "lib/utils/pcbStyle/getViaDiameterDefaults" import { getSimpleRouteJsonFromCircuitJson } from "lib/utils/public-exports" import { z } from "zod" -import { - getMinViaRuleValues, - type MinViaRuleProps, -} from "../../../utils/autorouting/min-via-rules" import { NormalComponent } from "../../base-components/NormalComponent/NormalComponent" import type { Trace } from "../Trace/Trace" import { TraceHint } from "../TraceHint" @@ -137,9 +133,8 @@ export class Group = typeof groupProps> doInitialSourceGroupRender() { const { db } = this.root! - const { minViaDiameter, minViaHole } = getMinViaRuleValues( - this.props as MinViaRuleProps, - ) + const { minViaDiameter, minViaHole } = this + ._parsedProps as SubcircuitGroupProps const hasExplicitName = typeof (this._parsedProps as { name?: unknown }).name === "string" && (this._parsedProps as { name?: string }).name!.length > 0 @@ -150,7 +145,7 @@ export class Group = typeof groupProps> was_automatically_named: !hasExplicitName, ...(minViaDiameter != null ? { min_via_diameter: minViaDiameter } : {}), ...(minViaHole != null ? { min_via_hole: minViaHole } : {}), - } as any) + }) this.source_group_id = source_group.source_group_id if (this.isSubcircuit) { this.subcircuit_id = `subcircuit_${source_group.source_group_id}` as any @@ -194,9 +189,7 @@ export class Group = typeof groupProps> const groupProps = props as SubcircuitGroupProps const hasOutline = groupProps.outline && groupProps.outline.length > 0 - const { minViaDiameter, minViaHole } = getMinViaRuleValues( - this.props as MinViaRuleProps, - ) + const { minViaDiameter, minViaHole } = groupProps const numericOutline = hasOutline ? groupProps.outline!.map((point) => ({ @@ -225,7 +218,7 @@ export class Group = typeof groupProps> anchor_alignment: props.pcbAnchorAlignment ?? null, ...(minViaDiameter != null ? { min_via_diameter: minViaDiameter } : {}), ...(minViaHole != null ? { min_via_hole: minViaHole } : {}), - } as any) + }) this.pcb_group_id = pcb_group.pcb_group_id for (const child of this.children) { @@ -921,9 +914,8 @@ export class Group = typeof groupProps> // Apply each routed trace to the corresponding circuit trace const pcbStyle = this.getInheritedMergedProperty("pcbStyle") const { holeDiameter, padDiameter } = getViaDiameterDefaults(pcbStyle) - const { minViaDiameter, minViaHole } = getMinViaRuleValues( - this.props as MinViaRuleProps, - ) + const { minViaDiameter, minViaHole } = this + ._parsedProps as SubcircuitGroupProps // First, create jumper components from getOutputJumpers() result if (output_jumpers && output_jumpers.length > 0) { diff --git a/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts b/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts index eaddd881d..62d2988a0 100644 --- a/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts +++ b/lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts @@ -2,7 +2,6 @@ import type { PcbBoard } from "circuit-json" import type { InflatorContext } from "../InflatorFn" import { Board } from "lib/components/normal-components/Board" import type { BoardProps } from "@tscircuit/props" -import type { MinViaRuleProps } from "lib/utils/autorouting/min-via-rules" export function inflatePcbBoard( pcbBoard: PcbBoard, @@ -25,13 +24,9 @@ export function inflatePcbBoard( } // Create board props from PCB data - const boardProps: BoardProps & MinViaRuleProps = { + const boardProps: BoardProps = { name: "inflated_board", } - const pcbBoardWithMinViaRules = pcbBoard as PcbBoard & { - min_via_diameter?: number - min_via_hole?: number - } // Add PCB-specific properties if (pcbBoard.width) boardProps.width = pcbBoard.width @@ -43,11 +38,11 @@ export function inflatePcbBoard( if (pcbBoard.outline) boardProps.outline = pcbBoard.outline if (pcbBoard.thickness) boardProps.thickness = pcbBoard.thickness if (pcbBoard.material) boardProps.material = pcbBoard.material - if (pcbBoardWithMinViaRules.min_via_diameter != null) { - boardProps.minViaDiameter = pcbBoardWithMinViaRules.min_via_diameter + if (pcbBoard.min_via_diameter != null) { + boardProps.minViaDiameter = pcbBoard.min_via_diameter } - if (pcbBoardWithMinViaRules.min_via_hole != null) { - boardProps.minViaHole = pcbBoardWithMinViaRules.min_via_hole + if (pcbBoard.min_via_hole != null) { + boardProps.minViaHole = pcbBoard.min_via_hole } // Create the Board instance diff --git a/lib/fiber/intrinsic-jsx.ts b/lib/fiber/intrinsic-jsx.ts index 332a6967e..4729457b2 100644 --- a/lib/fiber/intrinsic-jsx.ts +++ b/lib/fiber/intrinsic-jsx.ts @@ -1,6 +1,5 @@ import type * as Props from "@tscircuit/props" import type { DetailedHTMLProps, SVGProps } from "react" -import type { MinViaRuleProps } from "lib/utils/autorouting/min-via-rules" export interface TscircuitElements { resistor: Props.ResistorProps @@ -10,7 +9,7 @@ export interface TscircuitElements { diode: Props.DiodeProps fuse: Props.FuseProps led: Props.LedProps - board: Props.BoardProps & MinViaRuleProps + board: Props.BoardProps mountedboard: Props.MountedBoardProps panel: Props.PanelProps subpanel: Props.SubpanelProps @@ -38,7 +37,7 @@ export interface TscircuitElements { keepout: Props.PcbKeepoutProps hole: Props.HoleProps port: Props.PortProps - group: Props.GroupProps & MinViaRuleProps + group: Props.GroupProps netlabel: Props.NetLabelProps opamp: Props.OpAmpProps cadmodel: Props.CadModelProps @@ -78,7 +77,7 @@ export interface TscircuitElements { connector: Props.ConnectorProps pinheader: Props.PinHeaderProps resonator: Props.ResonatorProps - subcircuit: Props.SubcircuitGroupProps & MinViaRuleProps + subcircuit: Props.SubcircuitGroupProps transistor: Props.TransistorProps switch: Props.SwitchProps mosfet: Props.MosfetProps diff --git a/lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts b/lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts index 280c31b27..a08ff91b1 100644 --- a/lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts +++ b/lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts @@ -464,10 +464,8 @@ export const getSimpleRouteJsonFromCircuitJson = ({ // subcircuit layerCount: board?.num_layers ?? 2, minTraceWidth, - minViaDiameter: - (board as any)?.min_via_diameter ?? (pcbGroup as any)?.min_via_diameter, - minViaHole: - (board as any)?.min_via_hole ?? (pcbGroup as any)?.min_via_hole, + minViaDiameter: board?.min_via_diameter ?? pcbGroup?.min_via_diameter, + minViaHole: board?.min_via_hole ?? pcbGroup?.min_via_hole, nominalTraceWidth, outline: board?.outline?.map((point) => ({ ...point })), }, diff --git a/lib/utils/autorouting/min-via-rules.ts b/lib/utils/autorouting/min-via-rules.ts deleted file mode 100644 index 1858d2b05..000000000 --- a/lib/utils/autorouting/min-via-rules.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { distance } from "circuit-json" - -export type MinViaRuleProps = { - minViaDiameter?: number | string - minViaHole?: number | string -} - -export const getMinViaRuleValues = (props?: MinViaRuleProps) => ({ - minViaDiameter: - props?.minViaDiameter != null ? distance.parse(props.minViaDiameter) : null, - minViaHole: - props?.minViaHole != null ? distance.parse(props.minViaHole) : null, -})