Skip to content

Commit

Permalink
Merge pull request #6 from ShiboSoftwareDev/main
Browse files Browse the repository at this point in the history
gerber now outputs drill file
  • Loading branch information
seveibar authored Sep 9, 2024
2 parents 4fc4c70 + 3e9a5e3 commit 17bf1fa
Show file tree
Hide file tree
Showing 31 changed files with 458 additions and 38 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ dist
.DS_Store

.vscode

# yalc
.yalc
yalc.lock
yalc.lock

gerber-output
Binary file modified bun.lockb
Binary file not shown.
26 changes: 26 additions & 0 deletions src/excellon-drill/any-excellon-drill-command-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { z } from "zod"
import type{ ExcellonDrillCommandDef } from "./define-excellon-drill-command"
import * as EDCMD from "./commands"

export const excellon_drill_command_map = {
M48: EDCMD.M48,
M95: EDCMD.M95,
FMAT: EDCMD.FMAT,
unit_format: EDCMD.unit_format,
aper_function_header: EDCMD.aper_function_header,
percent_sign: EDCMD.percent_sign,
T: EDCMD.define_tool,
define_tool: EDCMD.define_tool,
use_tool: EDCMD.use_tool,
G90: EDCMD.G90,
G05: EDCMD.G05,
M30: EDCMD.M30,
drill_at: EDCMD.drill_at,
header_comment: EDCMD.header_comment,
header_attribute: EDCMD.header_attribute,
rewind: EDCMD.rewind,
} satisfies Record<string, ExcellonDrillCommandDef<string, any>>

export type AnyExcellonDrillCommand = z.infer<
(typeof excellon_drill_command_map)[keyof typeof excellon_drill_command_map]["schema"]
>
11 changes: 11 additions & 0 deletions src/excellon-drill/commands/FMAT.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const FMAT = defineExcellonDrillCommand({
command_code: "FMAT",
schema: z.object({
command_code: z.literal("FMAT").default("FMAT"),
format: z.number(),
}),
stringify: (c) => `FMAT,${c.format}`,
})
10 changes: 10 additions & 0 deletions src/excellon-drill/commands/G05.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const G05 = defineExcellonDrillCommand({
command_code: "G05",
schema: z.object({
command_code: z.literal("G05").default("G05"),
}),
stringify: () => "G05",
})
10 changes: 10 additions & 0 deletions src/excellon-drill/commands/G90.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const G90 = defineExcellonDrillCommand({
command_code: "G90",
schema: z.object({
command_code: z.literal("G90").default("G90"),
}),
stringify: () => "G90",
})
10 changes: 10 additions & 0 deletions src/excellon-drill/commands/M30.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const M30 = defineExcellonDrillCommand({
command_code: "M30",
schema: z.object({
command_code: z.literal("M30").default("M30"),
}),
stringify: () => "M30",
})
10 changes: 10 additions & 0 deletions src/excellon-drill/commands/M48.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const M48 = defineExcellonDrillCommand({
command_code: "M48",
schema: z.object({
command_code: z.literal("M48").default("M48"),
}),
stringify: () => "M48",
})
10 changes: 10 additions & 0 deletions src/excellon-drill/commands/M95.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const M95 = defineExcellonDrillCommand({
command_code: "M95",
schema: z.object({
command_code: z.literal("M95").default("M95"),
}),
stringify: () => "M95",
})
18 changes: 18 additions & 0 deletions src/excellon-drill/commands/aper_function_header.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const aper_function_header = defineExcellonDrillCommand({
command_code: "aper_function_header",
schema: z.object({
command_code: z
.literal("aper_function_header")
.default("aper_function_header"),
is_plated: z.boolean(),
}),
stringify({ is_plated }) {
if (!is_plated) {
throw new Error("not implemented")
}
return `; #@! TA.AperFunction,Plated,PTH,ComponentDrill`
},
})
12 changes: 12 additions & 0 deletions src/excellon-drill/commands/define_tool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const define_tool = defineExcellonDrillCommand({
command_code: "define_tool",
schema: z.object({
command_code: z.literal("define_tool").default("define_tool"),
tool_number: z.number(),
diameter: z.number(),
}),
stringify: (c) => `T${c.tool_number}C${c.diameter.toFixed(6)}`,
})
12 changes: 12 additions & 0 deletions src/excellon-drill/commands/drill_at.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const drill_at = defineExcellonDrillCommand({
command_code: "drill_at",
schema: z.object({
command_code: z.literal("drill_at").default("drill_at"),
x: z.number(),
y: z.number(),
}),
stringify: (c) => `X${c.x.toFixed(4)}Y${c.y.toFixed(4)}`,
})
14 changes: 14 additions & 0 deletions src/excellon-drill/commands/header_attribute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const header_attribute = defineExcellonDrillCommand({
command_code: "header_attribute",
schema: z.object({
command_code: z.literal("header_attribute").default("header_attribute"),
attribute_name: z.string(),
attribute_value: z.string(),
}),
stringify({ attribute_name, attribute_value }) {
return `; #@! ${attribute_name},${attribute_value}`
},
})
13 changes: 13 additions & 0 deletions src/excellon-drill/commands/header_comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const header_comment = defineExcellonDrillCommand({
command_code: "header_comment",
schema: z.object({
command_code: z.literal("header_comment").default("header_comment"),
text: z.string(),
}),
stringify({ text }) {
return `; ${text}`
},
})
15 changes: 15 additions & 0 deletions src/excellon-drill/commands/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export * from "./FMAT"
export * from "./G05"
export * from "./G90"
export * from "./M30"
export * from "./M48"
export * from "./M95"
export * from "./define_tool"
export * from "./drill_at"
export * from "./header_attribute"
export * from "./header_comment"
export * from "./rewind"
export * from "./unit_format"
export * from "./use_tool"
export * from "./aper_function_header"
export * from "./percent_sign"
10 changes: 10 additions & 0 deletions src/excellon-drill/commands/percent_sign.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const percent_sign = defineExcellonDrillCommand({
command_code: "percent_sign",
schema: z.object({
command_code: z.literal("percent_sign").default("percent_sign"),
}),
stringify: () => "%",
})
10 changes: 10 additions & 0 deletions src/excellon-drill/commands/rewind.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const rewind = defineExcellonDrillCommand({
command_code: "rewind",
schema: z.object({
command_code: z.literal("rewind").default("rewind"),
}),
stringify: () => "%",
})
17 changes: 17 additions & 0 deletions src/excellon-drill/commands/unit_format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const unit_format = defineExcellonDrillCommand({
command_code: "unit_format",
schema: z.object({
command_code: z.literal("unit_format").default("unit_format"),
unit: z.union([z.literal("INCH"), z.literal("METRIC")]),
lz: z
.union([z.literal("LZ"), z.literal("TZ")])
.nullable()
.default(null),
}),
stringify(c) {
return `${c.unit}${!c.lz ? "" : `,${c.lz}`}`
},
})
11 changes: 11 additions & 0 deletions src/excellon-drill/commands/use_tool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { z } from "zod"
import { defineExcellonDrillCommand } from "../define-excellon-drill-command"

export const use_tool = defineExcellonDrillCommand({
command_code: "use_tool",
schema: z.object({
command_code: z.literal("use_tool").default("use_tool"),
tool_number: z.number(),
}),
stringify: (c) => `T${c.tool_number}`,
})
106 changes: 106 additions & 0 deletions src/excellon-drill/convert-soup-to-excellon-drill-commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import type { AnySoupElement } from "@tscircuit/soup"
import type { AnyExcellonDrillCommand } from "./any-excellon-drill-command-map"
import { excellonDrill } from "./excellon-drill-builder"

export const inchToMm = (mm: number) => {
return mm * 25.4
}

export const convertSoupToExcellonDrillCommands = ({
soup,
is_plated,
flip_y_axis = false,
}: {
soup: Array<AnySoupElement>
is_plated: boolean
flip_y_axis?: boolean
}): Array<AnyExcellonDrillCommand> => {
const builder = excellonDrill()

// Start sequence commands
builder.add("M48", {})

// Add header comments
const date_str = new Date().toISOString()
builder
.add("header_comment", {
text: `DRILL file {tscircuit} date ${date_str}`,
})
.add("header_comment", {
text: "FORMAT={-:-/ absolute / metric / decimal}",
})
.add("header_attribute", {
attribute_name: "TF.CreationDate",
attribute_value: date_str,
})
.add("header_attribute", {
attribute_name: "TF.GenerationSoftware",
attribute_value: "tscircuit",
})
.add("header_attribute", {
attribute_name: "TF.FileFunction",
attribute_value: "Plated,1,2,PTH",
})
.add("FMAT", { format: 2 }) // Assuming format 2 for the example
.add("unit_format", { unit: "METRIC", lz: null })

let tool_counter = 10 // Start tool numbering from 10 for example

const diameterToToolNumber: Record<number, number> = {}

// Define tools
for (const element of soup) {
if (
element.type === "pcb_plated_hole" ||
element.type === "pcb_hole" ||
element.type === "pcb_via"
) {
if (!("hole_diameter" in element)) continue
if (!diameterToToolNumber[element.hole_diameter]) {
builder.add("aper_function_header", {
is_plated: true,
})
builder.add("define_tool", {
tool_number: tool_counter,
diameter: inchToMm(element.hole_diameter),
})
diameterToToolNumber[element.hole_diameter] = tool_counter
tool_counter++
}
}
}

builder.add("percent_sign", {})
builder.add("G90", {})
builder.add("G05", {})

// Execute drills for tool N
for (let i = 10; i < tool_counter; i++) {
builder.add("use_tool", { tool_number: i })
for (const element of soup) {
if (
element.type === "pcb_plated_hole" ||
element.type === "pcb_hole" ||
element.type === "pcb_via"
) {
if (is_plated && element.type === "pcb_hole") continue
if (
!is_plated &&
(element.type === "pcb_plated_hole" || element.type === "pcb_via")
)
continue
if (!("hole_diameter" in element)) continue
if (diameterToToolNumber[element.hole_diameter] === i) {
builder.add("drill_at", {
x: inchToMm(element.x),
y: inchToMm(element.y) * (flip_y_axis ? -1 : 1),
})
}
}
}
}

builder.add("M30", {})

return builder.build()
}
29 changes: 29 additions & 0 deletions src/excellon-drill/define-excellon-drill-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { AnyZodObject, z } from "zod"

export interface ExcellonDrillCommandDef<
K extends string,
T extends AnyZodObject | z.ZodIntersection<any, any>
> {
command_code: K
schema: T
stringify: (c: z.infer<T>) => string
}

export const defineExcellonDrillCommand = <
K extends string,
T extends AnyZodObject | z.ZodIntersection<any, any>
>({
command_code,
schema,
stringify,
}: {
command_code: K
schema: T
stringify: (c: z.infer<T>) => string
}): ExcellonDrillCommandDef<K, T> => {
return {
command_code,
schema,
stringify,
}
}
Loading

0 comments on commit 17bf1fa

Please sign in to comment.