Skip to content

Commit

Permalink
use G85 for hole drilling
Browse files Browse the repository at this point in the history
  • Loading branch information
seveibar committed Oct 25, 2024
1 parent cfaf70c commit 124595f
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 25 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ Some components of this gerber system:
## References

- [Gerber Format Specification (2022)](https://www.ucamco.com/files/downloads/file_en/456/gerber-layer-format-specification-revision-2022-02_en.pdf?7b3ca7f0753aa2d77f5f9afe31b9f826)
- [Excellon Drill Format Specification](https://gist.github.com/katyo/5692b935abc085b1037e)
2 changes: 2 additions & 0 deletions src/excellon-drill/any-excellon-drill-command-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { ExcellonDrillCommandDef } from "./define-excellon-drill-command"
import * as EDCMD from "./commands"

export const excellon_drill_command_map = {
G01: EDCMD.G01,
G85: EDCMD.G85,
M48: EDCMD.M48,
M95: EDCMD.M95,
FMAT: EDCMD.FMAT,
Expand Down
10 changes: 10 additions & 0 deletions src/excellon-drill/commands/G01.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 G01 = defineExcellonDrillCommand({
command_code: "G01",
schema: z.object({
command_code: z.literal("G01").default("G01"),
}),
stringify: () => "G01",
})
10 changes: 10 additions & 0 deletions src/excellon-drill/commands/G85.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 G85 = defineExcellonDrillCommand({
command_code: "G85",
schema: z.object({
command_code: z.literal("G85").default("G85"),
}),
stringify: () => "G85",
})
2 changes: 2 additions & 0 deletions src/excellon-drill/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export * from "./FMAT"
export * from "./G01"
export * from "./G05"
export * from "./G85"
export * from "./G90"
export * from "./M30"
export * from "./M48"
Expand Down
39 changes: 35 additions & 4 deletions src/excellon-drill/convert-soup-to-excellon-drill-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,41 @@ export const convertSoupToExcellonDrillCommands = ({
hole_diameter = element.hole_diameter
} else if (element.type === "pcb_plated_hole" && element.shape === "pill") {
hole_diameter = Math.min(element.hole_width, element.hole_height)
}

if (!hole_diameter) continue
if (diameterToToolNumber[hole_diameter] === i) {

// For pill shapes, we need to route the hole
if (diameterToToolNumber[hole_diameter] === i) {
const y_multiplier = flip_y_axis ? -1 : 1

if (element.hole_width > element.hole_height) {
// Horizontal pill
const offset = (element.hole_width - element.hole_height) / 2
builder
.add("G85", {})
.add("drill_at", {
x: element.x - offset,
y: element.y * y_multiplier,
})
.add("drill_at", {
x: element.x + offset,
y: element.y * y_multiplier,
})
} else {
// Vertical pill
const offset = (element.hole_height - element.hole_width) / 2
builder
.add("G85", {})
.add("drill_at", {
x: element.x,
y: (element.y - offset) * y_multiplier,
})
.add("drill_at", {
x: element.x,
y: (element.y + offset) * y_multiplier,
})
}
}
} else if (!hole_diameter) continue
else if (diameterToToolNumber[hole_diameter] === i) {
builder.add("drill_at", {
x: element.x,
y: element.y * (flip_y_axis ? -1 : 1),
Expand Down
66 changes: 59 additions & 7 deletions src/gerber/convert-soup-to-gerber-commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,67 @@ export const convertSoupToGerberCommands = (
glayers[getGerberLayerName(layer, "copper")],
glayers[getGerberLayerName(layer, "soldermask")],
]) {
const apertureConfig = getApertureConfigFromPcbPlatedHole(element)
glayer.push(
...gerberBuilder()
if (element.shape === "pill") {
// For pill shapes, use a circular aperture and draw the connecting line
const circleApertureConfig = {
standard_template_code: "C" as const,
diameter: element.outer_width > element.outer_height ?
element.outer_height : element.outer_width
}

// Find existing aperture number or get next available
let aperture_number = 10
try {
aperture_number = findApertureNumber(glayer, circleApertureConfig)
} catch {
aperture_number = Math.max(...glayer
.filter(cmd => 'aperture_number' in cmd)
.map(cmd => (cmd as any).aperture_number), 9) + 1

// Add the aperture definition
glayer.push(
...gerberBuilder()
.add("define_aperture_template", {
aperture_number,
...circleApertureConfig
})
.build()
)
}

const gb = gerberBuilder()
.add("select_aperture", {
aperture_number: findApertureNumber(glayer, apertureConfig),
aperture_number,
})
.add("flash_operation", { x: element.x, y: mfy(element.y) })
.build(),
)

if (element.outer_width > element.outer_height) {
// Horizontal pill
const offset = (element.outer_width - element.outer_height) / 2
gb.add("flash_operation", { x: element.x - offset, y: mfy(element.y) })
.add("move_operation", { x: element.x - offset, y: mfy(element.y) })
.add("plot_operation", { x: element.x + offset, y: mfy(element.y) })
.add("flash_operation", { x: element.x + offset, y: mfy(element.y) })
} else {
// Vertical pill
const offset = (element.outer_height - element.outer_width) / 2
gb.add("flash_operation", { x: element.x, y: mfy(element.y - offset) })
.add("move_operation", { x: element.x, y: mfy(element.y - offset) })
.add("plot_operation", { x: element.x, y: mfy(element.y + offset) })
.add("flash_operation", { x: element.x, y: mfy(element.y + offset) })
}

glayer.push(...gb.build())
} else {
const apertureConfig = getApertureConfigFromPcbPlatedHole(element)
glayer.push(
...gerberBuilder()
.add("select_aperture", {
aperture_number: findApertureNumber(glayer, apertureConfig),
})
.add("flash_operation", { x: element.x, y: mfy(element.y) })
.build(),
)
}
}
}
} else if (element.type === "pcb_hole") {
Expand Down
14 changes: 7 additions & 7 deletions tests/gerber/__snapshots__/pill-shape-bottom.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 7 additions & 7 deletions tests/gerber/__snapshots__/pill-shape-top.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 124595f

Please sign in to comment.