-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduced new footprint type:
breakoutheaders
(#98)
* Introduced new footprint type: * renamed getTriangleDir to getTrianglePath and change defualt value of od to 1.5mm * renamed routes to silkscreenTriangleRoutes
- Loading branch information
1 parent
dff0a4d
commit d589f7a
Showing
5 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
import { | ||
length, | ||
type AnyCircuitElement, | ||
type PcbPlatedHole, | ||
type PcbSilkscreenPath, | ||
} from "circuit-json" | ||
import { z } from "zod" | ||
import { rectpad } from "../helpers/rectpad" | ||
import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" | ||
import { platedhole } from "src/helpers/platedhole" | ||
|
||
export const breakoutheaders_def = z.object({ | ||
fn: z.string(), | ||
w: length.default("10mm"), | ||
h: length.optional(), | ||
left: length.optional().default(20), | ||
right: length.optional().default(20), | ||
top: length.optional().default(0), | ||
bottom: length.optional().default(0), | ||
p: length.default(length.parse("2.54mm")), | ||
id: length.optional().default(length.parse("1mm")), | ||
od: length.optional().default(length.parse("1.5mm")), | ||
}) | ||
|
||
export type breakoutheaders_def = z.input<typeof breakoutheaders_def> | ||
|
||
const getHeight = (parameters: breakoutheaders_def): number => { | ||
const params = breakoutheaders_def.parse(parameters) | ||
|
||
// Calculate height based on the presence of left and right parameters | ||
if (params.left && params.right) { | ||
return Math.max(params.left, params.right) * params.p | ||
} | ||
|
||
if (params.left) { | ||
return params.left * params.p | ||
} | ||
|
||
if (params.right) { | ||
return params.right * params.p | ||
} | ||
|
||
return 51 | ||
} | ||
|
||
type Point = { x: number; y: number } | ||
type Direction = "left" | "right" | "top" | "bottom" | ||
|
||
const getTrianglePath = ( | ||
x: number, | ||
y: number, | ||
side: Direction, | ||
triangleHeight = 1, | ||
triangleWidth = 0.6, | ||
): Point[] => { | ||
const halfHeight = triangleHeight / 2 | ||
const halfWidth = triangleWidth / 2 | ||
|
||
const silkscreenTriangleRoutes: Record<Direction, Point[]> = { | ||
left: [ | ||
{ x: x + halfHeight, y }, | ||
{ x: x - halfHeight, y: y + halfWidth }, | ||
{ x: x - halfHeight, y: y - halfWidth }, | ||
{ x: x + halfHeight, y }, | ||
], | ||
right: [ | ||
{ x: x - halfHeight, y }, | ||
{ x: x + halfHeight, y: y + halfWidth }, | ||
{ x: x + halfHeight, y: y - halfWidth }, | ||
{ x: x - halfHeight, y }, | ||
], | ||
top: [ | ||
{ x, y: y - halfHeight }, | ||
{ x: x - halfWidth, y: y + halfHeight }, | ||
{ x: x + halfWidth, y: y + halfHeight }, | ||
{ x, y: y - halfHeight }, | ||
], | ||
bottom: [ | ||
{ x, y: y + halfHeight }, | ||
{ x: x - halfWidth, y: y - halfHeight }, | ||
{ x: x + halfWidth, y: y - halfHeight }, | ||
{ x, y: y + halfHeight }, | ||
], | ||
} | ||
|
||
return silkscreenTriangleRoutes[side] | ||
} | ||
export const breakoutheaders = ( | ||
raw_params: breakoutheaders_def, | ||
): { circuitJson: AnyCircuitElement[]; parameters: any } => { | ||
const params = breakoutheaders_def.parse(raw_params) | ||
const height = params.h ?? getHeight(params) | ||
const holes: PcbPlatedHole[] = [] | ||
const innerDiameter = params.id | ||
const outerDiameter = params.od | ||
let silkscreenTriangleRoutes: { x: number; y: number }[] = [] | ||
if (params.right) { | ||
const yoff = -((params.right - 1) / 2) * params.p | ||
for (let i = 0; i < params.right; i++) { | ||
if (i === 0 && !params.left && !params.bottom) { | ||
silkscreenTriangleRoutes = getTrianglePath( | ||
params.w / 2 + outerDiameter * 1.4, | ||
yoff + i * params.p, | ||
"right", | ||
) | ||
} | ||
holes.push( | ||
platedhole( | ||
i + 1 + params.left + (params.bottom ?? 0), | ||
params.w / 2, | ||
yoff + i * params.p, | ||
innerDiameter, | ||
outerDiameter, | ||
), | ||
) | ||
} | ||
} | ||
if (params.left) { | ||
const yoff = -((params.left - 1) / 2) * params.p | ||
for (let i = 0; i < params.left; i++) { | ||
if (i === params.left - 1) { | ||
silkscreenTriangleRoutes = getTrianglePath( | ||
-params.w / 2 - outerDiameter * 1.4, | ||
yoff + i * params.p, | ||
"left", | ||
) | ||
} | ||
holes.push( | ||
platedhole( | ||
i + 1, | ||
-params.w / 2, | ||
yoff + i * params.p, | ||
innerDiameter, | ||
outerDiameter, | ||
), | ||
) | ||
} | ||
} | ||
if (params.top) { | ||
const xoff = -((params.top - 1) / 2) * params.p | ||
for (let i = 0; i < params.top; i++) { | ||
if ( | ||
i === params.top - 1 && | ||
!params.left && | ||
!params.bottom && | ||
!params.right | ||
) { | ||
silkscreenTriangleRoutes = getTrianglePath( | ||
xoff + i * params.p, | ||
height / 2 + outerDiameter * 1.4, | ||
"top", | ||
) | ||
} | ||
holes.push( | ||
platedhole( | ||
i + 1 + params.right + (params.bottom ?? 0) + params.left, | ||
xoff + i * params.p, | ||
height / 2, | ||
innerDiameter, | ||
outerDiameter, | ||
), | ||
) | ||
} | ||
} | ||
if (params.bottom) { | ||
const xoff = -((params.bottom - 1) / 2) * params.p | ||
for (let i = 0; i < params.bottom; i++) { | ||
if (i === 0 && !params.left) { | ||
silkscreenTriangleRoutes = getTrianglePath( | ||
xoff + i * params.p, | ||
-height / 2 - outerDiameter * 1.4, | ||
"bottom", | ||
) | ||
} | ||
holes.push( | ||
platedhole( | ||
i + 1 + params.left, | ||
xoff + i * params.p, | ||
-height / 2, | ||
innerDiameter, | ||
outerDiameter, | ||
), | ||
) | ||
} | ||
} | ||
|
||
const silkscreenTriangle: PcbSilkscreenPath = { | ||
type: "pcb_silkscreen_path", | ||
pcb_silkscreen_path_id: "1", | ||
pcb_component_id: "1", | ||
layer: "top", | ||
route: silkscreenTriangleRoutes, | ||
stroke_width: 0.1, | ||
} | ||
|
||
const silkscreenPath: PcbSilkscreenPath = { | ||
type: "pcb_silkscreen_path", | ||
pcb_silkscreen_path_id: "pcb_silkscreen_path_1", | ||
pcb_component_id: "1", | ||
route: [ | ||
{ | ||
x: -params.w / 2 - outerDiameter, | ||
y: height / 2 + outerDiameter, | ||
}, | ||
{ | ||
x: params.w / 2 + outerDiameter, | ||
y: height / 2 + outerDiameter, | ||
}, | ||
{ | ||
x: params.w / 2 + outerDiameter, | ||
y: -height / 2 - outerDiameter, | ||
}, | ||
{ | ||
x: -params.w / 2 - outerDiameter, | ||
y: -height / 2 - outerDiameter, | ||
}, | ||
{ | ||
x: -params.w / 2 - outerDiameter, | ||
y: height / 2 + outerDiameter, | ||
}, | ||
], | ||
stroke_width: 0.1, | ||
layer: "top", | ||
} | ||
const silkscreenRefText: SilkscreenRef = silkscreenRef( | ||
0, | ||
height / 1.7, | ||
height / 25, | ||
) | ||
return { | ||
circuitJson: [ | ||
...holes, | ||
silkscreenPath, | ||
silkscreenRefText, | ||
silkscreenTriangle, | ||
], | ||
parameters: params, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
tests/__snapshots__/breakoutheaders_left20_right20_w8mm_p2.54mm.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { test, expect } from "bun:test" | ||
import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" | ||
import { fp } from "../src/footprinter" | ||
|
||
test("breakoutheaders", () => { | ||
const soup = fp | ||
.string("breakoutheaders_left15_right15_w8mm_p1.54mm") | ||
.circuitJson() | ||
const svgContent = convertCircuitJsonToPcbSvg(soup) | ||
expect(svgContent).toMatchSvgSnapshot( | ||
import.meta.path, | ||
"breakoutheaders_left20_right20_w8mm_p2.54mm", | ||
) | ||
}) |