maker_panel/
drill.rs

1//! Generates drill files.
2
3use super::InnerAtom;
4use std::collections::HashMap;
5
6pub fn serialize<W: std::io::Write>(
7    features: &Vec<InnerAtom>,
8    w: &mut W,
9    want_plated: bool,
10) -> Result<(), std::io::Error> {
11    w.write(b"M48\n")?; // Start of header
12    w.write(b";DRILL file {KiCad 5.0.2 compatible}\n")?;
13    w.write(b";FORMAT={-:-/ absolute / inch / decimal}\n")?;
14    w.write(b"FMAT,2\n")?; // Uses format 2 commands
15    w.write(b"INCH,TZ\n")?; // Units are inches, trailing zeroes included.
16
17    let mut circle_dia = HashMap::new();
18    for f in features {
19        if let InnerAtom::Drill {
20            center: _,
21            radius,
22            plated,
23        } = f
24        {
25            if want_plated == *plated {
26                let dia_inches = format!("{:.4}", radius * 2.0 / 25.4);
27                circle_dia.insert(dia_inches, ());
28            }
29        }
30    }
31    let circle_tools: Vec<_> = circle_dia.keys().enumerate().collect();
32    for (i, c) in &circle_tools {
33        w.write(format!("T{}C{}\n", i + 1, c).as_bytes())?;
34    }
35    w.write(b"%\n")?; // Rewind, used instead of end of header M95.
36
37    w.write(b"G90\n")?; // Absolute mode
38    w.write(b"G05\n")?; // Turn on drill mode
39
40    let mut current_tool: Option<usize> = None;
41    for f in features {
42        if let InnerAtom::Drill {
43            center,
44            radius,
45            plated,
46        } = f
47        {
48            if want_plated == *plated {
49                let dia_inches = format!("{:.4}", radius * 2.0 / 25.4);
50                let tool_idx = circle_tools
51                    .iter()
52                    .find(|&&(_, dia)| *dia == dia_inches)
53                    .unwrap()
54                    .0;
55                if current_tool != Some(tool_idx + 1) {
56                    w.write(format!("T{}\n", tool_idx + 1).as_bytes())?;
57                    current_tool = Some(tool_idx + 1);
58                }
59
60                let (x, y) = (center.x / 25.4, center.y / 25.4);
61                w.write(format!("X{:.4}Y{:.4}\n", x, y).as_bytes())?;
62            }
63        }
64    }
65
66    w.write(b"T0\n")?; // Remove tool from spindle.
67    w.write(b"M30\n")?; // End of file (last line)
68    Ok(())
69}
70
71// FMAT,2
72// INCH,TZ
73// T1C0.1220
74// %
75// G90
76// G05
77// T1
78// X0.8031Y-0.1673
79// X0.Y-0.1673
80// X0.8031Y0.1673
81// X-0.8031Y-0.1673
82// X0.4016Y-0.1673
83// X-0.4016Y-0.1673
84// X-0.4016Y0.1673
85// X0.Y0.1673
86// X-0.8031Y0.1673
87// X0.4016Y0.1673
88// T0
89// M30