Created
October 29, 2024 04:05
-
-
Save dogtopus/13adb7adc5c13ec003a90794f0d8f620 to your computer and use it in GitHub Desktop.
Parametric bitting profile (incomplete)
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
include <MCAD/units.scad> | |
/* [Key parameters] */ | |
// The type of the key. | |
Key_Type = "sc1"; // [kw1: Kwikset KW1, sc1: Schlage SC1, american_5: American 5-pin, american_6: American 6-pin] | |
// An array of numbers that represent the cuts on the bitting, usually from the shoulder of the key to the tip. The exact meaning of this option depends on the key type. | |
Bitting_Code = [3, 4, 2, 5, 1, 0]; | |
// End of customizer variables. | |
/* [Hidden] */ | |
// Enums | |
// MACS | |
PARAM_MACS = 0; | |
// Distance between shoulder to first cut (in mil/thou). | |
PARAM_SHOULDER_TO_FIRST_CUT = 1; | |
// Width of a cut (excluding the angled out sections) (in mil/thou). | |
PARAM_CUT_WIDTH = 2; | |
// Root-to-root distance (in mil/thou). | |
PARAM_ROOT_TO_ROOT = 3; | |
// Included angle of the cut (in deg). | |
PARAM_CUT_INCLUDED_ANGLE = 4; | |
// Depth table (in mil/thou). | |
PARAM_DEPTH_TABLE = 5; | |
// Functions | |
function mil2mm(mil) = mil / 1000 * inch; | |
function get_first(a, k) = a[search([k], a)[0]][1]; | |
/** | |
* Linear depth estimation function. | |
* | |
* Generate depth table for linearly incrementing pin lengths/linearly decrementing root depth. | |
* @param depth_increment Increment for pin length. | |
* @param end_code The largest bitting code digit the key can possibly have. | |
* @param start_code Optional. The smallest bitting code digit the key can possibly have. Defaults to 0 | |
* @param start_depth Optional. The depth of the cut when the bitting code == start_code. | |
* @return The depth table that contains all possible bitting code digits and their depth, which are the difference between the key blade width and root depths. | |
*/ | |
function linear_depth(depth_increment, end_code, start_code = 0, start_depth = 0) = [for (i = [start_code:end_code]) [i, start_depth + depth_increment * i]]; | |
// macs, shoulder_to_first_cut, cut_width, root_to_root, cut_included_angle, depth_table | |
BITTING_KW1 = [6, 247, 90, 150, 90, linear_depth(23, 7, start_code = 1)]; | |
BITTING_SCHLAGE = [7, 231, 31, 156.2, 100, linear_depth(15, 9, start_depth = 8)]; | |
BITTING_MASTER = [6, 156, 40, 125, 90, linear_depth(15.6, 8)]; | |
// Dimension (in mm * 100): https://www.sindark.com/genre/pen-testing/decoding-master/Key%20Measurments/Key%20Measurments%20-%20American.png | |
BITTING_AMERICAN = [6, 156, 40, 125, 90, linear_depth(15.6, 8, start_code = 1)]; | |
// The global parameter table. All parameters related to a key belongs to here. | |
// https://lockreference.com/how-key-bitting-specifications-work/ | |
PARAMS = [ | |
/* name, bitting_table */ | |
["kw1", BITTING_KW1], | |
["sc1", BITTING_SCHLAGE], | |
["sc4", BITTING_SCHLAGE], | |
["american_5", BITTING_AMERICAN], | |
["american_6", BITTING_AMERICAN], | |
]; | |
/** | |
* translate() but in mils instead of the default unit (assumed to be mm). | |
* @param xyz The xy/xyz coordinate. | |
* @see translate | |
*/ | |
module translate_mil(xyz) { | |
translate(mil2mm(xyz)) children(); | |
} | |
/** | |
* Individual cut. | |
* @param depth_table The depth table. | |
* @param cut_width Bottom width of the cut. | |
* @param angle Included angle between the 2 sides of the cut. | |
* @param num Cut number. This will be translated using the depth_table. | |
*/ | |
module cut(depth_table, cut_width, angle, num) { | |
cut_depth = lookup(num, depth_table); | |
tz_bottom_offset = cut_depth * tan(angle / 2); | |
translate_mil([0, -cut_depth]) | |
polygon(mil2mm([ | |
[-cut_width/2, 0], | |
[cut_width/2, 0], | |
[cut_width/2+tz_bottom_offset, cut_depth + epsilon], | |
[-cut_width/2-tz_bottom_offset, cut_depth + epsilon], | |
])); | |
} | |
/** | |
* Bitting mask. Intended to be used with difference() with a blank key model, with the top aligned with the top of the blade. | |
* @param param Parameter array from PARAMS. | |
* @param code Bitting code array. | |
*/ | |
module bitting(param, code) { | |
translate_mil([param[PARAM_SHOULDER_TO_FIRST_CUT], 0]) | |
for (index = [0:len(code)-1]) { | |
next_cut = code[index+1]; | |
this_cut = code[index]; | |
if (!is_undef(next_cut) && abs(next_cut - this_cut) > param[PARAM_MACS]) { | |
echo("WARNING: Cut exceeds MACS. This key will most likely not work.", this_pin_index = index); | |
} | |
translate_mil([index * param[PARAM_ROOT_TO_ROOT], 0]) | |
cut( | |
param[PARAM_DEPTH_TABLE], | |
param[PARAM_CUT_WIDTH], | |
param[PARAM_CUT_INCLUDED_ANGLE], | |
this_cut | |
); | |
} | |
} | |
difference() { | |
translate_mil([0, -343]) square(mil2mm([1200, 343]), center = false); | |
bitting(get_first(PARAMS, Key_Type), Bitting_Code); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment