add a massive chunk of stuff because you forgot to keep doing atomic commits

This commit is contained in:
Bob - Home - Windows 2017-12-20 00:47:03 -05:00
parent f252ec2c30
commit 6d2bb24ccb
31 changed files with 668 additions and 674 deletions

27
README.md Normal file
View File

@ -0,0 +1,27 @@
# Parametric Mechanical Keycap Library
this library is meant to be a keycap and keyset construction library for mechanical keyboards.
## Let's Go! I wanna make some keycaps!
At the highest level this library supports Cherry and Alps switches, and has pre-defined key profiles for SA, DSA, DCS, and (some form of) OEM keycaps. `keys.scad` is meant as an entry point for everything but the most technical use; there should already be an example at the bottom to get you started! Pre-programmed key profiles can be found at `key_profiles.scad`.
## What if I want to customize my keycaps?
There is a bevy of supporting functions to customize your keycaps. You can add a brim to more easily print the stem, switch up the stem support type, make 2x2 keycaps for a POS system, add legends, rotate stems, and more. These functions can be found in `key_profiles.scad`, `key_sizes.scad`, `key_transformations.scad`, and `key_types.scad` currently, and can be referenced directly in `keys.scad`.
The `key()` function also supports children, and will place them in the center of the top of the keycap, if you want to quickly design your own artisan keycaps. I'll post an example later!
## What if I want to get _really_ technical?
If you're not afraid to write some code yourself, at the base level this library _should_ function well as a key profile design library. by loading up `key.scad` (notice no s) you can tweak variables in `settings.scad` to make your own profiles. You can design your own keyset with custom top skew, width and height, dish tilt, fonts, wall thickness, etc.
##TODO:
* pull out side sculpting options to let people tweak them?
* can now measure keycaps very accurately. need to redo measurements: [x] SA [ ] DCS [X] DSA [X] OEM?
* Add inset stem to all profiles that need it. [x] OEM [ ] DCS?
* customizer version where everything is copy/pasted in. needs to be last.
* generate dishes via math? kind of hard, maybe later

147
key_profiles.scad Normal file
View File

@ -0,0 +1,147 @@
// key profile definitions
module dcs_row(n=1) {
// names, so I don't go crazy
$bottom_key_width = 18.16;
$bottom_key_height = 18.16;
$width_difference = 6;
$height_difference = 4;
$dish_type = "cylindrical";
$dish_depth = 1;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 1.75;
if (n == 5) {
$total_depth = 11.5;
$top_tilt = -6;
children();
} else if (n == 1) {
$total_depth = 8.5;
$top_tilt = -1;
children();
} else if (n == 2) {
$total_depth = 7.5;
$top_tilt = 3;
children();
} else if (n == 3) {
$total_depth = 6;
$top_tilt = 7;
children();
} else if (n == 4) {
$total_depth = 6;
$top_tilt = 16;
children();
}
}
module oem_row(n=1) {
$bottom_key_width = 18.05;
$bottom_key_height = 18.05;
$width_difference = 5.8;
$height_difference = 4;
$dish_type = "cylindrical";
$dish_depth = 1;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 1.75;
$stem_inset = 1.2;
if (n == 5) {
$total_depth = 11.2;
$top_tilt = -3;
children();
} else if (n == 1) {
$total_depth = 9.45;
$top_tilt = 1;
children();
} else if (n == 2) {
$total_depth = 9;
$top_tilt = 6;
children();
} else if (n == 3) {
$total_depth = 9.25;
$top_tilt = 9;
children();
} else if (n == 4) {
$total_depth = 9.25;
$top_tilt = 10;
children();
}
}
module dsa_row(n=3) {
$bottom_key_width = 18.24; // 18.4;
$bottom_key_height = 18.24; // 18.4;
$width_difference = 6; // 5.7;
$height_difference = 6; // 5.7;
$total_depth = 8.1;
$top_tilt = (n-1) * 7 - 14;
$top_skew = 0;
$dish_type = "spherical";
$dish_depth = 1.2;
$dish_skew_x = 0;
$dish_skew_y = 0;
$height_slices = 10;
$enable_side_sculpting = true;
// might wanna change this if you don't minkowski
// do you even minkowski bro
$corner_radius = 0.25;
children();
}
module sa_row(n=1) {
$bottom_key_width = 18.4;
$bottom_key_height = 18.4;
$width_difference = 5.7;
$height_difference = 5.7;
$dish_type = "spherical";
$dish_depth = 0.85;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 0;
$height_slices = 10;
$enable_side_sculpting = true;
// might wanna change this if you don't minkowski
// do you even minkowski bro
$corner_radius = 0.25;
if (n == 1){
$total_depth = 14.89;
$top_tilt = -13;
children();
} else if (n == 2) {
$total_depth = 12.925;
$top_tilt = -7;
children();
} else if (n == 3) {
$total_depth = 12.5;
$top_tilt = 0;
children();
} else if (n == 4){
$total_depth = 12.925;
$top_tilt = 7;
children();
}
}
module g20() {
$bottom_key_width = 18.16;
$bottom_key_height = 18.16;
$width_difference = 2;
$height_difference = 2;
$total_depth = 6;
$top_tilt = 2.5;
$top_skew = 0.75;
$dish_type = "no dish";
$dish_depth = 0;
$dish_skew_x = 0;
$dish_skew_y = 0;
$minkowski_radius = 1.75;
children();
//also,
/*$rounded_key = true;*/
}

70
key_sizes.scad Normal file
View File

@ -0,0 +1,70 @@
// key width functions
module u(u=1) {
$key_length = u;
children();
}
module 1u() {
u(1) children();
}
module 1_25u() {
u(1.25) children();
}
module 1_5u() {
u(1.5) children();
}
module 2u() {
u(2) children();
}
module 2_25u() {
u(2.25) children();
}
module 2_75u() {
u(2.75) children();
}
module 6_25u() {
u(6.25) children();
}
// key height functions
module uh(u=1) {
$key_height = u;
children();
}
module 1uh() {
uh(1) children();
}
module 2uh() {
uh(2) children();
}
module 1_25uh() {
uh(1.25) children();
}
module 1_5uh() {
uh(1.5) children();
}
module 2_25uh() {
uh(2.25) children();
}
module 2_75uh() {
uh(2.75) children();
}
module 6_25uh() {
uh(6.25) children();
}

100
key_transformations.scad Normal file
View File

@ -0,0 +1,100 @@
// kind of a catch-all at this point for any directive that doesn't fit in the other files
module brimmed() {
$has_brim = true;
children();
}
module rounded() {
$rounded_key = true;
children();
}
module inverted() {
$inverted_dish = true;
children();
}
module rotated() {
$stem_rotation = 90;
children();
}
module stabilized(mm=12, vertical = false) {
if (vertical) {
$connectors = [
[0, 0],
[0, mm],
[0, -mm]
];
children();
} else {
$connectors = [
[0, 0],
[mm, 0],
[-mm, 0]
];
children();
}
}
module dishless() {
$dish_type = "no dish";
children();
}
module inset(val=1) {
$stem_inset = val;
children();
}
module filled() {
$stem_profile = "filled";
children();
}
module blank() {
$stem_profile = "blank";
children();
}
module cherry(slop = 0.3) {
$slop = slop;
$stem_profile = "cherry";
children();
}
module alps(slop = 0.3) {
$slop = slop;
$stem_profile = "alps";
children();
}
module rounded_cherry(slop = 0.3) {
$slop = slop;
$stem_profile = "cherry_rounded";
children();
}
module legend(text, inset=false) {
$text=text;
$inset_text = inset;
children();
}
module flared_support() {
$support_type = "flared";
children();
}
module bar_support() {
$support_type = "bars";
children();
}
module flat_support() {
$support_type = "flat";
children();
}

63
key_types.scad Normal file
View File

@ -0,0 +1,63 @@
module spacebar() {
$inverted_dish = true;
if ($dish_type == "cylindrical") {
$dish_type = "sideways cylindrical";
6_25u() stabilized(mm=50) children();
} else {
6_25u() stabilized(mm=50) children();
}
}
module lshift() {
2_25u() stabilized() children();
}
module rshift() {
2_75u() stabilized() children();
}
module backspace() {
2u() stabilized() children();
}
module enter() {
2_25u() stabilized() children();
}
module numpad_enter() {
2uh() stabilized(vertical=true) children();
}
module numpad_plus() {
numpad_enter() children();
}
module numpad_0() {
backspace() children();
}
module stepped_caps_lock() {
u(1.75) {
$connectors = [
[-5, 0]
];
children();
}
}
module iso_enter() {
$key_length = 1.5;
$key_height = 2;
$top_tilt = 0;
$key_shape_type = "iso_enter";
$linear_extrude_shape = true;
$linear_extrude_height_adjustment = 19.05 * 0.5;
// (unit_length(1.5) - unit_length(1.25)) / 2
$dish_overdraw_width = 2.38125;
stabilized(vertical=true) {
children();
}
}

419
keys.scad
View File

@ -5,426 +5,21 @@
// without having to rely on this file. Unfortunately that means setting tons of // without having to rely on this file. Unfortunately that means setting tons of
// special variables, but that's a limitation of SCAD we have to work around // special variables, but that's a limitation of SCAD we have to work around
/* TODO:
* add keys.scad function for fudge factor in stem
* pull out side sculpting options to let people tweak them?
* can now measure keycaps very accurately. need to redo measurements: [x] SA [ ] DCS [X] DSA [X] OEM?
* Add inset stem to all profiles that need it. [x] OEM [ ] DCS?
* customizer version where everything is copy/pasted in. needs to be last.
* generate dishes via math? kind of hard, maybe later
*/
use <key.scad>
//TODO duplicate def to not make this a special var. maybe not worth it //TODO duplicate def to not make this a special var. maybe not worth it
unit = 19.05; unit = 19.05;
// defaults use <src/key.scad>
$bottom_key_width = 18.16;
$bottom_key_height = 18.16;
$width_difference = 6;
$height_difference = 4;
$total_depth = 11.5;
$top_tilt = -6;
$top_skew = 1.7;
$dish_type = "cylindrical";
$dish_depth = 1;
$dish_skew_x = 0;
$dish_skew_y = 0;
$key_length = 1;
$key_height = 1;
$has_brim = false;
$inverted_dish = false;
$connectors = [[0,0]];
$linear_extrude_shape = false;
$rounded_key = false;
$stem_profile = 0;
$stem_inset = 0;
$stem_rotation = 0;
$text = "";
$inset_text = false;
$corner_radius = 1;
$height_slices = 1;
$slop = 0.3;
$support_type = "bars";
$key_shape_type = "normal";
$linear_extrude_height_adjustment = 0;
$dish_overdraw_width = 0;
$dish_overdraw_height = 0;
// key profile definitions include <src/settings.scad>
include <key_sizes.scad>
module dcs_row(n=1) { include <key_profiles.scad>
// names, so I don't go crazy include <key_types.scad>
$bottom_key_width = 18.16; include <key_transformations.scad>
$bottom_key_height = 18.16;
$width_difference = 6;
$height_difference = 4;
$dish_type = "cylindrical";
$dish_depth = 1;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 1.75;
if (n == 5) {
$total_depth = 11.5;
$top_tilt = -6;
children();
} else if (n == 1) {
$total_depth = 8.5;
$top_tilt = -1;
children();
} else if (n == 2) {
$total_depth = 7.5;
$top_tilt = 3;
children();
} else if (n == 3) {
$total_depth = 6;
$top_tilt = 7;
children();
} else if (n == 4) {
$total_depth = 6;
$top_tilt = 16;
children();
}
}
module oem_row(n=1) {
$bottom_key_width = 18.05;
$bottom_key_height = 18.05;
$width_difference = 5.8;
$height_difference = 4;
$dish_type = "cylindrical";
$dish_depth = 1;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 1.75;
$stem_inset = 1.2;
if (n == 5) {
$total_depth = 11.2;
$top_tilt = -3;
children();
} else if (n == 1) {
$total_depth = 9.45;
$top_tilt = 1;
children();
} else if (n == 2) {
$total_depth = 9;
$top_tilt = 6;
children();
} else if (n == 3) {
$total_depth = 9.25;
$top_tilt = 9;
children();
} else if (n == 4) {
$total_depth = 9.25;
$top_tilt = 10;
children();
}
}
module dsa_row(n=3) {
$bottom_key_width = 18.24; // 18.4;
$bottom_key_height = 18.24; // 18.4;
$width_difference = 6; // 5.7;
$height_difference = 6; // 5.7;
$total_depth = 8.1;
$top_tilt = (n-1) * 7 - 14;
$top_skew = 0;
$dish_type = "spherical";
$dish_depth = 1.2;
$dish_skew_x = 0;
$dish_skew_y = 0;
$height_slices = 10;
$enable_side_sculpting = true;
// might wanna change this if you don't minkowski
// do you even minkowski bro
$corner_radius = 0.25;
children();
}
module sa_row(n=1) {
$bottom_key_width = 18.4;
$bottom_key_height = 18.4;
$width_difference = 5.7;
$height_difference = 5.7;
$dish_type = "spherical";
$dish_depth = 0.85;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 0;
$height_slices = 10;
$enable_side_sculpting = true;
// might wanna change this if you don't minkowski
// do you even minkowski bro
$corner_radius = 0.25;
if (n == 1){
$total_depth = 14.89;
$top_tilt = -13;
children();
} else if (n == 2) {
$total_depth = 12.925;
$top_tilt = -7;
children();
} else if (n == 3) {
$total_depth = 12.5;
$top_tilt = 0;
children();
} else if (n == 4){
$total_depth = 12.925;
$top_tilt = 7;
children();
}
}
module g20() {
$bottom_key_width = 18.16;
$bottom_key_height = 18.16;
$width_difference = 2;
$height_difference = 2;
$total_depth = 6;
$top_tilt = 2.5;
$top_skew = 0.75;
$dish_type = "no dish";
$dish_depth = 0;
$dish_skew_x = 0;
$dish_skew_y = 0;
$minkowski_radius = 1.75;
children();
//also,
/*$rounded_key = true;*/
}
module iso_enter() {
$key_length = 1.5;
$key_height = 2;
$top_tilt = -3;
$key_shape_type = "iso_enter";
$linear_extrude_shape = true;
$linear_extrude_height_adjustment = 19.05 * 0.5;
// (unit_length(1.5) - unit_length(1.25)) / 2
$dish_overdraw_width = 2.38125;
stabilized(vertical=true) {
children();
}
}
module brimmed() {
$has_brim = true;
children();
}
module rounded() {
$rounded_key = true;
children();
}
module inverted() {
$inverted_dish = true;
children();
}
module rotated() {
$stem_rotation = 90;
children();
}
module stabilized(mm=12, vertical = false) {
if (vertical) {
$connectors = [
[0, 0],
[0, mm],
[0, -mm]
];
children();
} else {
$connectors = [
[0, 0],
[mm, 0],
[-mm, 0]
];
children();
}
}
module dishless() {
$dish_type = "no dish";
children();
}
module inset(val=1) {
$stem_inset = val;
children();
}
module spacebar() {
$inverted_dish = true;
if ($dish_type == "cylindrical") {
$dish_type = "sideways cylindrical";
6_25u() stabilized(mm=50) children();
} else {
6_25u() stabilized(mm=50) children();
}
}
module lshift() {
2_25u() stabilized() children();
}
module rshift() {
2_75u() stabilized() children();
}
module backspace() {
2u() stabilized() children();
}
module enter() {
2_25u() stabilized() children();
}
module numpad_enter() {
2uh() stabilized(vertical=true) children();
}
module numpad_plus() {
numpad_enter() children();
}
module numpad_0() {
backspace() children();
}
module stepped_caps_lock() {
u(1.75) {
$connectors = [
[-5, 0]
];
children();
}
}
module translate_u(x=0, y=0, z=0){ module translate_u(x=0, y=0, z=0){
translate([x * unit, y*unit, z*unit]) children(); translate([x * unit, y*unit, z*unit]) children();
} }
// key width functions translate_u(1.125, 0.5) sa_row(4) u(2) bar_support() cherry(){
module u(u=1) {
$key_length = u;
children();
}
module 1u() {
u(1) children();
}
module 1_25u() {
u(1.25) children();
}
module 1_5u() {
u(1.5) children();
}
module 2u() {
u(2) children();
}
module 2_25u() {
u(2.25) children();
}
module 2_75u() {
u(2.75) children();
}
module 6_25u() {
u(6.25) children();
}
// key height functions
module uh(u=1) {
$key_height = u;
children();
}
module 1uh() {
uh(1) children();
}
module 2uh() {
uh(2) children();
}
module 1_25uh() {
uh(1.25) children();
}
module 1_5uh() {
uh(1.5) children();
}
module 2_25uh() {
uh(2.25) children();
}
module 2_75uh() {
uh(2.75) children();
}
module 6_25uh() {
uh(6.25) children();
}
module filled() {
$stem_profile = "filled";
children();
}
module blank() {
$stem_profile = "blank";
children();
}
module cherry(slop = 0.3) {
$slop = slop;
$stem_profile = "cherry";
children();
}
module alps(slop = 0.3) {
$slop = slop;
$stem_profile = "alps";
children();
}
module rounded_cherry(slop = 0.3) {
$slop = slop;
$stem_profile = "cherry_rounded";
children();
}
module legend(text, inset=false) {
$text=text;
$inset_text = inset;
children();
}
translate_u(1.125, 0.5) oem_row(2) iso_enter() cherry() {
$top_tilt = 0;
$width_difference = 4.35;
$height_difference = 3.8;
key(); key();
} }

View File

@ -3,88 +3,6 @@ include <shapes.scad>
include <stems.scad> include <stems.scad>
include <dishes.scad> include <dishes.scad>
include <libraries/geodesic_sphere.scad> include <libraries/geodesic_sphere.scad>
/* [Settings] */
// keytop thickness, aka how many millimeters between the inside and outside of the top surface of the key
keytop_thickness = 1;
// wall thickness, aka the thickness of the sides of the keycap. note this is the total thickness, aka 3 = 1.5mm walls
wall_thickness = 3;
//whether stabilizer connectors are enabled
stabilizers = false;
// font used for text
font="DejaVu Sans Mono:style=Book";
// font size used for text
font_size = 6;
// whether or not to render fake keyswitches to check clearances
clearance_check = false;
/* [Key profile] */
// width of the very bottom of the key
bottom_key_width = 18.16;
// height (from the front) of the very bottom of the ke
bottom_key_height = 18.16;
// how much less width there is on the top. eg top_key_width = bottom_key_width - width_difference
width_difference = 6;
// how much less height there is on the top
height_difference = 4;
// how deep the key is, before adding a dish
total_depth = 11.5;
// the tilt of the dish in degrees. divided by key height
top_tilt = -6;
// how skewed towards the back the top is (0 for center)
top_skew = 1.7;
// what type of dish the key has. 0 for cylindrical, 1 for spherical, 2 for something else idk TODO
dish_type = "cylindrical";
// how deep the dish 'digs' into the top of the keycap. this is max depth, so you can't find the height from total_depth - dish_depth. besides the top is skewed anyways
dish_depth = 1;
// how skewed in the x direction the dish is
dish_skew_x = 0;
// how skewed in the y direction (height) the dish is
dish_skew_y = 0;
//length in units of key
key_length = 1;
//height in units of key. should remain 1 for most uses
key_height = 1;
//print brim for connector to help with bed adhesion
has_brim = false;
// invert dishing. mostly for spacebar
inverted_dish = false;
// array of positions of all stems. includes stabilizers as well, for now
// ternary is a bad hack to keep the stabilizers flag working
connectors = stabilizers ? [[0,0],[-50,0],[50,0]] : [[0,0]];
// use linear_extrude instead of hull slices to make the shape of the key
// should be faster, also required for concave shapes
linear_extrude_shape = false;
//should the key be rounded? unnecessary for most printers, and very slow
rounded_key = false;
// 'cherry', 'alps' or 'cherry_rounded'
stem_profile = "cherry";
// how much higher the stem is than the bottom of the keycap.
// inset stem requires support but is more accurate in some profiles
stem_inset = 0;
// how many degrees to rotate the stems. useful for sideways keycaps, maybe
stem_rotation = 0;
//text to be rendered in the center of the key, if any
text = "";
// is the text on the key inset? inset text is still experimental
inset_text = false;
// radius of corners of keycap
corner_radius = 1;
// keystem slop - lengthens the cross and thins out the connector
slop = 0.3;
// support type. default is 'flared' for easy FDM printing
support_type = "flared";
// key shape type. default is 'normal'. only other supported option is 'iso_enter'
key_shape_type = "normal";
// ISO enter needs to be linear extruded NOT from the center. this tells the program how far up 'not from the center' is
linear_extrude_height_adjustment = 0;
// if you need the dish to extend further, you can 'overdraw' the rectangle it will hit
dish_overdraw_width = 0;
// same as width but for height
dish_overdraw_height = 0;
/* [Fancy Bowed Sides] */ /* [Fancy Bowed Sides] */
@ -255,7 +173,7 @@ module keytext() {
translate([0, 0, -extra_inset_depth]){ translate([0, 0, -extra_inset_depth]){
top_of_key(){ top_of_key(){
linear_extrude(height=$dish_depth){ linear_extrude(height=$dish_depth){
text(text=$text, font=font, size=font_size, halign="center", valign="center"); text(text=$text, font=$font, size=$font_size, halign="center", valign="center");
} }
} }
} }
@ -266,18 +184,18 @@ module connectors() {
for (connector_pos = $connectors) { for (connector_pos = $connectors) {
translate([connector_pos[0], connector_pos[1], $stem_inset]) { translate([connector_pos[0], connector_pos[1], $stem_inset]) {
rotate([0, 0, $stem_rotation]){ rotate([0, 0, $stem_rotation]){
color([1, .6941, .2]) connector($stem_profile, $has_brim, $slop, $support_type); color([1, .6941, .2]) connector($stem_profile, $total_depth, $has_brim, $slop, $stem_inset, $support_type);
} }
} }
} }
// cut off anything that isn't underneath the keytop // cut off anything that isn't underneath the keytop
shape(wall_thickness, keytop_thickness); shape($wall_thickness, $keytop_thickness);
} }
} }
//approximate (fully depressed) cherry key to check clearances //approximate (fully depressed) cherry key to check clearances
module clearance_check() { module clearance_check() {
if(clearance_check == true && ($stem_profile == "cherry" || $stem_profile == "cherry_rounded")){ if($clearance_check == true && ($stem_profile == "cherry" || $stem_profile == "cherry_rounded")){
color([1,0,0, 0.5]){ color([1,0,0, 0.5]){
translate([0,0,3.6 + $stem_inset - 5]) { translate([0,0,3.6 + $stem_inset - 5]) {
%hull() { %hull() {
@ -300,7 +218,7 @@ module keytop() {
} else { } else {
shape(0, 0); shape(0, 0);
} }
translate([0,0,-0.01]) shape(wall_thickness, keytop_thickness); translate([0,0,-0.01]) shape($wall_thickness, $keytop_thickness);
} }
} }
@ -325,39 +243,7 @@ module key() {
// actual full key with space carved out and keystem/stabilizer connectors // actual full key with space carved out and keystem/stabilizer connectors
// this is an example key with all the fixins // this is an example key with all the fixins
module example_key(){ module example_key(){
$bottom_key_width = bottom_key_width; include <settings.scad>
$bottom_key_height = bottom_key_height;
$width_difference = width_difference;
$height_difference = height_difference;
$total_depth = total_depth;
$top_tilt = top_tilt;
$top_skew = top_skew;
$dish_type = dish_type;
$dish_depth = dish_depth;
$dish_skew_x = dish_skew_x;
$dish_skew_y = dish_skew_y;
$key_length = key_length;
$key_height = key_height;
$has_brim = has_brim;
$inverted_dish = inverted_dish;
$connectors = connectors;
$linear_extrude_shape = linear_extrude_shape;
$rounded_key = rounded_key;
$stem_profile = stem_profile;
$stem_inset = stem_inset;
$stem_rotation = stem_rotation;
$text = text;
$inset_text = inset_text;
$corner_radius = corner_radius;
$height_slices = height_slices;
$enable_side_sculpting = enable_side_sculpting;
$slop = slop;
$support_type = support_type;
$linear_extrude_height_adjustment = linear_extrude_height_adjustment;
$dish_overdraw_width = dish_overdraw_width;
$dish_overdraw_height = dish_overdraw_height;
key(); key();
} }

80
src/settings.scad Normal file
View File

@ -0,0 +1,80 @@
// keytop thickness, aka how many millimeters between the inside and outside of the top surface of the key
$keytop_thickness = 1;
// wall thickness, aka the thickness of the sides of the keycap. note this is the total thickness, aka 3 = 1.5mm walls
$wall_thickness = 3;
//whether stabilizer connectors are enabled
$stabilizers = false;
// font used for text
$font="DejaVu Sans Mono:style=Book";
// font size used for text
$font_size = 6;
// whether or not to render fake keyswitches to check clearances
$clearance_check = false;
/* [Key profile] */
// width of the very bottom of the key
$bottom_key_width = 18.16;
// height (from the front) of the very bottom of the ke
$bottom_key_height = 18.16;
// how much less width there is on the top. eg top_key_width = bottom_key_width - width_difference
$width_difference = 6;
// how much less height there is on the top
$height_difference = 4;
// how deep the key is, before adding a dish
$total_depth = 11.5;
// the tilt of the dish in degrees. divided by key height
$top_tilt = -6;
// how skewed towards the back the top is (0 for center)
$top_skew = 1.7;
// what type of dish the key has. 0 for cylindrical, 1 for spherical, 2 for something else idk TODO
$dish_type = "cylindrical";
// how deep the dish 'digs' into the top of the keycap. this is max depth, so you can't find the height from total_depth - dish_depth. besides the top is skewed anyways
$dish_depth = 1;
// how skewed in the x direction the dish is
$dish_skew_x = 0;
// how skewed in the y direction (height) the dish is
$dish_skew_y = 0;
//length in units of key
$key_length = 1;
//height in units of key. should remain 1 for most uses
$key_height = 1;
//print brim for connector to help with bed adhesion
$has_brim = false;
// invert dishing. mostly for spacebar
$inverted_dish = false;
// array of positions of all stems. includes stabilizers as well, for now
// ternary is a bad hack to keep the stabilizers flag working
$connectors = $stabilizers ? [[0,0],[-50,0],[50,0]] : [[0,0]];
// use linear_extrude instead of hull slices to make the shape of the key
// should be faster, also required for concave shapes
$linear_extrude_shape = false;
//should the key be rounded? unnecessary for most printers, and very slow
$rounded_key = false;
// 'cherry', 'alps' or 'cherry_rounded'
$stem_profile = "cherry";
// how much higher the stem is than the bottom of the keycap.
// inset stem requires support but is more accurate in some profiles
$stem_inset = 0;
// how many degrees to rotate the stems. useful for sideways keycaps, maybe
$stem_rotation = 0;
//text to be rendered in the center of the key, if any
$text = "";
// is the text on the key inset? inset text is still experimental
$inset_text = false;
// radius of corners of keycap
$corner_radius = 1;
// keystem slop - lengthens the cross and thins out the connector
$slop = 0.3;
// support type. default is 'flared' for easy FDM printing
$support_type = "flared";
// key shape type. default is 'normal'. only other supported option is 'iso_enter'
$key_shape_type = "normal";
// ISO enter needs to be linear extruded NOT from the center. this tells the program how far up 'not from the center' is
$linear_extrude_height_adjustment = 0;
// if you need the dish to extend further, you can 'overdraw' the rectangle it will hit
$dish_overdraw_width = 0;
// same as width but for height
$dish_overdraw_height = 0;
// how many slices will be made, to approximate curves on corners. Leave at 1 if you are not curving corners
$height_slices = 1;

146
src/stems.scad Normal file
View File

@ -0,0 +1,146 @@
include <supports.scad>
brim_height = 0.4;
//whole connector, alps or cherry, trimmed to fit
module connector(stem_profile, depth, has_brim, slop, stem_inset, support_type){
echo(slop);
if (stem_profile == "alps") {
alps_stem(depth, has_brim, slop, stem_inset, support_type);
} else if (stem_profile == "cherry_rounded") {
cherry_stem_rounded(depth, has_brim, slop, stem_inset, support_type);
} else if (stem_profile == "cherry") {
cherry_stem(depth, has_brim, slop, stem_inset, support_type);
} else if (stem_profile == "filled") {
// just a cube, so no args
filled_stem();
}
}
module cherry_stem(depth, has_brim, slop, stem_inset, support_type) {
stem_width = 7.2 - slop * 2;
stem_height = 5.5 - slop * 2;
vertical_cross_width = 1.25;
// currently unused, as we want a split stem
vertical_cross_length = 3.93;
horizontal_cross_width = 1.15;
horizontal_cross_length = 4.03;
cross_depth = 4;
stem = [stem_width, stem_height];
vertical_cross = [vertical_cross_width, stem_height];
horizontal_cross = [horizontal_cross_length + slop, horizontal_cross_width];
translate([0,0,stem_inset]) {
difference(){
union() {
linear_extrude(height = depth) {
roundedSquare(stem, 1, center=true);
}
if(has_brim) {
roundedRect([stem_width*2, stem_height*2,brim_height], 1, 1, center=true);
}
}
linear_extrude(height = cross_depth) {
square(vertical_cross, center=true);
square(horizontal_cross, center=true);
}
}
// supports
if (support_type == "flared") {
flared(cross_depth, (depth - cross_depth), [stem_width, stem_height]) {
roundedSquare(stem, 1, center=true);
}
} else if (support_type == "flat") {
flat(cross_depth, (depth - cross_depth), [stem_width, stem_height]);
} else if (support_type == "bars") {
bars(cross_depth, (depth - cross_depth), [stem_width, stem_height]);
}
}
}
module cherry_stem_rounded(depth, has_brim, slop, stem_inset, support_type) {
// cross length
cross_length = 4.4;
//dimensions of connector
// outer cross extra length in y
extra_outer_cross_height = 1.1;
// dimensions of cross
// horizontal cross bar width
horizontal_cross_width = 1.4;
// vertical cross bar width
vertical_cross_width = 1.3;
// cross depth, stem height is 3.4mm
cross_depth = 4;
total_diameter = cross_length+extra_outer_cross_height;
translate([0,0,stem_inset]){
difference(){
union(){
cylinder(d=total_diameter, h=depth);
if(has_brim) {
cylinder(d=total_diameter * 2, h=brim_height);
}
}
//the cross part of the steam
translate([0,0,(cross_depth)/2]){
cube([vertical_cross_width,cross_length,cross_depth], center=true );
cube([cross_length,horizontal_cross_width,cross_depth], center=true );
}
}
// supports
if (support_type == "flared") {
flared(cross_depth, (depth - cross_depth)) {
circle(d = cross_length+extra_outer_cross_height);
}
} else if (support_type == "flat") {
flat(cross_depth, (depth - cross_depth));
} else if (support_type == "bars") {
bars(cross_depth, (depth - cross_depth));
}
}
}
module alps_stem(depth, has_brim, slop, stem_inset, support_type){
// not really cross depth, basically just the max length of stem we need for the key to function properly
cross_depth = 4;
width = 4.45;
height = 2.25;
base_width = 12;
base_height = 15;
translate([0,0,stem_inset]){
if(has_brim) {
translate([0,0,brim_height / 2]) cube([width*2,height*2,brim_height], center = true);
}
translate([0,0,depth/2]){
cube([width,height,depth], center = true);
}
}
translate([0, 0, stem_inset]){
if (support_type == "flared") {
flared(cross_depth, (depth - cross_depth)) {
square([width,height]);
}
} else if (support_type == "flat") {
flat(cross_depth, (depth - cross_depth));
} else if (support_type == "bars") {
bars(cross_depth, (depth - cross_depth));
}
}
}
module filled_stem() {
// this is mostly for testing. we don't pass the size of the keycp in here
// so we can't make this work for all keys
cube(1000, center=true);
}

21
src/supports.scad Normal file
View File

@ -0,0 +1,21 @@
// flared support designed for FDM printing, for the normal cherry stem
module flared(loft, height) {
translate([0,0,loft]){
linear_extrude(height=height, scale = [height/2,height/2]){
children();
}
}
}
module flat(loft, height) {
translate([0,0,loft + 500]){
cube(1000, center=true);
}
}
module bars(loft, height) {
translate([0,0,loft + height / 2]){
cube([2, 100, height], center = true);
cube([100, 2, height], center = true);
}
}

View File

@ -1,117 +0,0 @@
include <util.scad>
include <supports.scad>
stem_depth = 240;
//whole connector, alps or cherry, trimmed to fit
module connector(stem_profile, has_brim, slop, support_type){
echo(slop);
if (stem_profile == "alps") {
alps_stem(has_brim, slop);
} else if (stem_profile == "cherry_rounded") {
cherry_stem_rounded(has_brim, slop);
} else if (stem_profile == "cherry") {
cherry_stem(has_brim, slop, support_type);
} else if (stem_profile == "filled") {
filled_stem();
}
}
module brim(has_brim) {
//brim radius. 11 ensconces normal keycap stem in normal keycap
brim_radius = 6;
//brim depth
brim_depth = .3;
if (has_brim) color([0,1,0]) cube([brim_radius, brim_radius, brim_depth]);
}
module cherry_stem(has_brim, slop, support_type) {
stem_width = 7.2 - slop * 2;
stem_height = 5.5 - slop * 2;
vertical_cross_width = 1.25;
vertical_cross_length = 3.93;
horizontal_cross_width = 1.15;
horizontal_cross_length = 4.03;
cross_depth = 4;
stem = [stem_width, stem_height];
vertical_cross = [vertical_cross_width, vertical_cross_length + slop + 12];
horizontal_cross = [horizontal_cross_length + slop, horizontal_cross_width];
translate([0,0,stem_inset]) {
brim(has_brim);
difference(){
linear_extrude(height = stem_depth) {
roundedSquare(stem, 1, center=true);
}
linear_extrude(height = cross_depth) {
square(vertical_cross, center=true);
square(horizontal_cross, center=true);
}
}
// flared support
echo(support_type);
if (support_type == "flared") {
cherry_flared(cross_depth, (stem_depth - cross_depth), [stem_width, stem_height]);
} else if (support_type == "flat") {
flat(cross_depth, (stem_depth - cross_depth), [stem_width, stem_height]);
} else if (support_type == "bars") {
bars(cross_depth, (stem_depth - cross_depth), [stem_width, stem_height]);
}
}
}
module cherry_stem_rounded(has_brim, slop) {
// cross length
cross_length = 4.4;
//dimensions of connector
// outer cross extra length in y
extra_outer_cross_height = 1.1;
// dimensions of cross
// horizontal cross bar width
horizontal_cross_width = 1.4;
// vertical cross bar width
vertical_cross_width = 1.3;
// cross depth, stem height is 3.4mm
cross_depth = 4;
difference(){
union(){
cylinder(
d = cross_length+extra_outer_cross_height,
h = stem_depth
);
brim(has_brim);
}
//the cross part of the steam
translate([0,0,(cross_depth)/2 + stem_inset]){
cube([vertical_cross_width,cross_length,cross_depth], center=true );
cube([cross_length,horizontal_cross_width,cross_depth], center=true );
}
}
}
module alps_stem(has_brim, slop){
cross_depth = 40;
width = 4.45;
height = 2.25;
base_width = 12;
base_height = 15;
brim(has_brim);
translate([0,0,cross_depth/2 + stem_inset]){
cube([width,height,cross_depth], center = true);
}
}
module filled_stem() {
// this is mostly for testing. we don't pass the size of the keycp in here
// so we can't make this work for all keys
cube(100, center=true);
}

View File

@ -1,24 +0,0 @@
// flared support designed for FDM printing, for the normal cherry stem
module cherry_flared(loft, height, stem_bottom) {
// 6 and 8 are magic numbers I got from trying to make the sides of the flared part of the stem 45 degree overhangs
translate([0,0,loft]){
linear_extrude(height=height, scale = [6,8]){
roundedSquare(stem_bottom, 1, center=true);
}
}
}
module flat(loft, height, stem_bottom) {
// 6 and 8 are magic numbers I got from trying to make the sides of the flared part of the stem 45 degree overhangs
translate([0,0,loft + 500]){
cube(1000, center=true);
}
}
module bars(loft, height, stem_bottom) {
// 6 and 8 are magic numbers I got from trying to make the sides of the flared part of the stem 45 degree overhangs
translate([0,0,loft + height / 2]){
cube([2, 100, height], center = true);
cube([100, 2, height], center = true);
}
}