diff --git a/resources/medeco.svg b/resources/medeco.svg new file mode 100644 index 0000000..3822beb --- /dev/null +++ b/resources/medeco.svg @@ -0,0 +1,281 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + A1515 + + + 1515 + + + + + + A1517 + + + + + 1542 + + + + + 1518 + + + + + 1543 + + + + + 1517 + + + diff --git a/scad/keygen.scad b/scad/keygen.scad index 68b68d9..cd4df33 100644 --- a/scad/keygen.scad +++ b/scad/keygen.scad @@ -149,15 +149,16 @@ module key_bitting(heights, flat, angle=100, cutter_width=5, - cutter_height=5) { + cutter_height=5, + angles=[]) { // Rotate the cutting tool to the proper orientation rotate(-90, [0, 0, 1]) rotate(90, [1, 0, 0]) // Union together a handful of trapezoids // that comprise the cuts union() { for(i=key_enum(heights)) { - // Move to the proper location and height - translate([locations[i], heights[i]]) + // Move to the proper location and height, and maybe rotate + translate([locations[i], heights[i]]) rotate(i >= len(angles) ? 0 : angles[i], [0, 1, 0]) linear_extrude(height=cutter_width, center=true) key_bitting_cutter(flat, angle, cutter_height); } diff --git a/scad/medeco_classic.scad b/scad/medeco_classic.scad new file mode 100644 index 0000000..4c562c3 --- /dev/null +++ b/scad/medeco_classic.scad @@ -0,0 +1,109 @@ +use +include + + +module medeco_classic(bitting="", + outline_name="1515", + warding_name="1515") { + + name = "Medeco Classic"; + + /* + Bitting is specified from bow to tip, 1-6, with 1 being the shallowest cut and 6 being the deepest. + + After each number, a letter L, C, or R is specified for the cut angle: left, center or right. + + Example: 2L5C3C6R3R + */ + + outlines_k = ["A1515", + "1515", + "A1517", + "1517", + "1518", + "1542", + "1543"]; + outlines_v = [[outline_a1515_points, outline_a1515_paths, + [-outline_a1515_points[52][0], -outline_a1515_points[52][1]], + engrave_a1515_points, + engrave_a1515_paths], + [outline_1515_points, outline_1515_paths, + [-outline_1515_points[25][0], -outline_1515_points[25][1]], + engrave_1515_points, + engrave_1515_paths], + [outline_a1517_points, outline_a1517_paths, + [-outline_a1517_points[47][0], -outline_a1517_points[48][1]], + engrave_a1517_points, + engrave_a1517_paths], + [outline_1517_points, outline_1517_paths, + [-outline_1517_points[47][0], -outline_1517_points[48][1]], + engrave_1517_points, + engrave_1517_paths], + [outline_1518_points, outline_1518_paths, + [-outline_1518_points[40][0], -outline_1518_points[28][1]], + engrave_1518_points, + engrave_1518_paths], + [outline_1542_points, outline_1542_paths, + [-outline_1542_points[92][0], -outline_1542_points[98][1]], + engrave_1542_points, + engrave_1542_paths], + [outline_1543_points, outline_1543_paths, + [-outline_1543_points[48][0], -outline_1543_points[48][1]], + engrave_1543_points, + engrave_1543_paths]]; + + wardings_k = ["1515", + "1517", + "1518", + "1542", + "1543"]; + wardings_v = [warding_1515_points, + warding_1517_points, + warding_1518_points, + warding_1542_points, + warding_1543_points]; + + outline_param = key_lkup(outlines_k, outlines_v, outline_name); + outline_points = outline_param[0]; + outline_paths = outline_param[1]; + offset = outline_param[2]; + engrave_points = outline_param[3]; + engrave_paths = outline_param[4]; + + warding_points = key_lkup(wardings_k, wardings_v, warding_name); + + cut_locations = [for(i=[0.244, 0.414, 0.584, 0.754, 0.924, 1.094]) i*25.4]; + depth_table = [for(i=[0.266+0.025:-0.025:0.115]) i*25.4]; + angles_k = ["L", "C", "R"]; + angles_v = [-20, 0, 20]; + + bitting_depth = [for(i=[0:2:len(bitting)-1]) bitting[i]]; + bitting_angle = [for(i=[1:2:len(bitting)-1]) bitting[i]]; + heights = key_code_to_heights(bitting_depth, depth_table); + angles = [for(c=bitting_angle) key_lkup(angles_k, angles_v, c)]; + + difference() { + if($children == 0) { + key_blank(outline_points, + warding_points, + outline_paths=outline_paths, + engrave_right_points=engrave_points, + engrave_right_paths=engrave_paths, + engrave_left_points=engrave_points, + engrave_left_paths=engrave_paths, + offset=offset, + plug_diameter=12.7); + } else { + children(0); + } + key_bitting(heights, cut_locations, + flat=.381, angle=86, // from CW-1012 cutter specs + angles=angles); + } +} + +// Defaults +bitting=""; +outline="1515"; +warding="1515"; +medeco_classic(bitting, outline, warding); diff --git a/scad/schlage_primus.scad b/scad/schlage_primus.scad new file mode 100644 index 0000000..9ed0358 --- /dev/null +++ b/scad/schlage_primus.scad @@ -0,0 +1,130 @@ +use +include + +module side_bit_milling(cut_locations, bitting="") { + sbm_cut_locations = [for(i=[0:len(cut_locations)-2]) 0.5 * (cut_locations[i] + cut_locations[i+1])]; + + sbm_offsets_mil = [[], [-32, 48], [-32, 24], [0, 60], [0, 36], [32, 48], [32, 24]]; + sbm_offsets = [for(p=sbm_offsets_mil) [for(e=p) e * 0.0254]]; + sbm_angle = 120; + sbm_max_height = 140 * 0.0254; + sbm_cutter_radius= 29 * 0.0254; + sbm_dist = 5; + sbm_eps = 0.1; + sbm_on_ramp = 29; + + heights = key_code_to_heights(bitting, sbm_offsets); + + rotate(-90, [0, 1, 0]) rotate(-90, [0, 0, 1]) + linear_extrude(height=sbm_dist) + minkowski() { + union() { + for(i=key_enum(heights)) { + translate([sbm_cut_locations[i], 0]) + polygon([[heights[i][0], heights[i][1] + sbm_cutter_radius], + [tan(0.5 * sbm_angle) * (sbm_max_height-heights[i][1]-2*sbm_cutter_radius), sbm_max_height - sbm_cutter_radius], + [-tan(0.5 * sbm_angle) * (sbm_max_height-heights[i][1]-2*sbm_cutter_radius), sbm_max_height - sbm_cutter_radius]]); + } + translate([sbm_on_ramp + sbm_cutter_radius, 0]) + polygon([[0, 0], + [tan(0.5 * sbm_angle) * (sbm_max_height-2*sbm_cutter_radius), sbm_max_height - sbm_cutter_radius], + [-tan(0.5 * sbm_angle) * (sbm_max_height-2*sbm_cutter_radius), sbm_max_height - sbm_cutter_radius]]); + polygon([[sbm_cut_locations[0], sbm_max_height - sbm_cutter_radius], + [sbm_on_ramp, sbm_max_height - sbm_cutter_radius], + [sbm_on_ramp, sbm_max_height - sbm_cutter_radius - sbm_eps], + [sbm_cut_locations[0], sbm_max_height - sbm_cutter_radius - sbm_eps]]); + } + circle(r=sbm_cutter_radius, center=true, $fn=$fn ? 4*$fn : 48); + } +} + +module schlage_primus(bitting="", + outline_name="6-pin", + warding_name="C") { + + name = "Schlage Primus Classic"; + + /* + Bitting is specified from bow to tip, 0-9, with 0 being the shallowest cut and 9 being the deepest. + + Then, side-bit milling is specified from bow to tip, 1-6. + + A dash separates the two. + + Example: 253636-24436 + */ + + // TODO is 5-pin primus a thing?? + + outlines_k = ["6-pin"]; + outlines_v = [[outline_6pin_points, outline_6pin_paths, + [-outline_6pin_points[92][0], -outline_6pin_points[98][1]], + engrave_6pin_points, + engrave_6pin_paths]]; + + // TODO add primus keyways + + wardings_k = ["C", + "CE", + "E", + "EF", + "F", + "FG", + "H", + "J", + "K", + "L"]; + wardings_v = [warding_c_points, + warding_ce_points, + warding_e_points, + warding_ef_points, + warding_f_points, + warding_fg_points, + warding_h_points, + warding_j_points, + warding_k_points, + warding_l_points]; + + outline_param = key_lkup(outlines_k, outlines_v, outline_name); + outline_points = outline_param[0]; + outline_paths = outline_param[1]; + offset = outline_param[2]; + engrave_points = outline_param[3]; + engrave_paths = outline_param[4]; + + warding_points = key_lkup(wardings_k, wardings_v, warding_name); + + cut_locations = [for(i=[.231, .3872, .5434, .6996, .8558, 1.012]) i*25.4]; + depth_table = [for(i=[0.335:-0.015:0.199]) i*25.4]; + + bitting_list = key_split_on_dash(bitting); + top_bitting = bitting_list[0]; + side_bitting = len(bitting_list) > 1 ? bitting_list[1] : ""; + + heights = key_code_to_heights(top_bitting, depth_table); + + + difference() { + if($children == 0) { + key_blank(outline_points, + warding_points, + outline_paths=outline_paths, + engrave_right_points=engrave_points, + engrave_right_paths=engrave_paths, + engrave_left_points=engrave_points, + engrave_left_paths=engrave_paths, + offset=offset, + plug_diameter=12.7); + } else { + children(0); + } + key_bitting(heights, cut_locations, .7874); + side_bit_milling(cut_locations, side_bitting); + } +} + +// Defaults +bitting=""; +outline="6-pin"; +warding="C"; +schlage_primus(bitting, outline, warding);