Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.swp
/*.stl
/*.3mf
/*.gcode
/*.diff
*.png
*.blend
40 changes: 22 additions & 18 deletions keycap_playground.scad
Original file line number Diff line number Diff line change
Expand Up @@ -54,29 +54,29 @@ VISUALIZE_LEGENDS = false; // Set to true to have the legends appear via %

// CONSTANTS
KEY_UNIT = 19.05; // Square that makes up the entire space of a key
BETWEENSPACE = 0.8; // The Betweenspace: The void between realms... And keycaps (for an 18.25mm keycap)
BETWEENSPACE = 1; // The Betweenspace: The void between realms... And keycaps (for a 17.9mm XDA keycap, as this seems to overrule the profile's length/width)

// BASIC KEYCAP PARAMETERS
// If you want to make a keycap using a common profile set this to one of: dcs, dss, dsa, kat, kam, riskeycap, gem:
KEY_PROFILE = "riskeycap"; // Any value other than a supported profile (e.g. "dsa") will use the globals specified below. In other words, an empty KEY_PROFILE means "just use the values specified here in this file."
KEY_PROFILE = "xda"; // Any value other than a supported profile (e.g. "dsa") will use the globals specified below. In other words, an empty KEY_PROFILE means "just use the values specified here in this file."
KEY_ROW = 1; // NOTE: For a spacebar make sure you also set DISH_INVERT=true
// Some settings override profile settings but most will be ignored (if using a profile)
KEY_HEIGHT = 9; // The Z (NOTE: Dish values may reduce this a bit as they carve themselves out)
KEY_HEIGHT_EXTRA = 0.0; // If you're planning on sanding the keycap you can use this to make up for lost material (normally this is only useful when using a profile e.g. DSA)
KEY_HEIGHT_EXTRA = 0.08; // If you're planning on sanding the keycap you can use this to make up for lost material (normally this is only useful when using a profile e.g. DSA)
// NOTE: You *can* just set KEY_LENGTH/KEY_WIDTH to something simple e.g. 18
KEY_LENGTH = (KEY_UNIT*1-BETWEENSPACE); // The X (NOTE: Increase DISH_FN if you make this >1U!)
// NOTE: If using a profile make sure KEY_LENGTH matches the profile's KEY_WIDTH for 1U keycaps!
KEY_WIDTH = (KEY_UNIT*1-BETWEENSPACE); // The Y (NOTE: If using POLYGON_EGDES>4 this will be ignored)
// NOTE: Spacebars don't seem to use BETWEENSPACE (for whatever reason). So to make a spacebar just use "KEY_UNIT*<spacebar unit length>" and omit the "-BETWEENSPACE" part. Or just be precise and give it a value like 119.0625 (19.05*6.25)
// NOTE: When making longer keycaps you may need to increase KEY_HEIGHT slightly in order for the height to be accurate. I recommend giving it an extra 0.3mm per extra unit of length so 2U would be +0.3, 3U would be +0.6, etc BUT DOUBLE CHECK IT. Do a side profile view and look at the ruler or render it and double-check the height in your slicer.
//KEY_ROTATION = [0,0,0]; // I *highly* recommend 3D printing keycaps on their front/back/sides! Try this:
KEY_ROTATION = [0,110.1,90]; // An example of how you'd rotate a keycap on its side. Make sure to zoom in on the bottom to make sure it's *actually* going to print flat! This should be the correct rotation for riskeycap profile. For GEM use:
KEY_ROTATION = [0,0,0]; // An example of how you'd rotate a keycap on its side. Make sure to zoom in on the bottom to make sure it's *actually* going to print flat! This should be the correct rotation for riskeycap profile. For GEM use:
//KEY_ROTATION = [0,108.6,90];
// NOTE: If you rotate a keycap to print on its side don't forget to add a built-in support via STEM_SIDE_SUPPORTS! [0,1,0,0] is what you want if you rotated to print on the right side.
KEY_TOP_DIFFERENCE = 5; // How much skinnier the key is at the top VS the bottom [x,y]
KEY_TOP_X = 0; // Move the keycap's top on the X axis (controls skew left/right)
KEY_TOP_Y = 0; // Move the keycap's top on the Y axis (controls skew forward/backward)
WALL_THICKNESS = 0.45*2.25; // Default: 0.45 extrusion width * 2.25 (nice and thick; feels/sounds good). NOTE: STEM_SIDES_WALL_THICKNESS gets added to this.
WALL_THICKNESS = 0.4*3; // Default: 0.45 extrusion width * 2.25 (nice and thick; feels/sounds good). NOTE: STEM_SIDES_WALL_THICKNESS gets added to this.
UNIFORM_WALL_THICKNESS = true; // Much more expensive rendering but the material under the dish will match the sides (even the shape of the dish will be matched)
// NOTE: UNIFORM_WALL_THICKNESS uses WALL_THICKNESS instead of DISH_THICKNESS. So DISH_THICKNESS will be ignored if you enable this option.

Expand All @@ -88,7 +88,7 @@ DISH_TYPE = "sphere"; // "inv_pyramid", "cylinder", "sphere" (aka "domed"), anyt
// NOTE: inv_pyramid doesn't work for making spacbars (kinda, "duh")
DISH_DEPTH = 1; // Distance between the top sides and the bottommost point in the dish (set to 0 for flat top)
// NOTE: When DISH_INVERT is true DISH_DEPTH becomes more like, "how far dish protrudes upwards"
DISH_THICKNESS = 0.6; // Amount of material that will be placed under the bottommost part of the dish (Note: only used if UNIFORM_WALL_THICKNESS is false)
DISH_THICKNESS = 1; // Amount of material that will be placed under the bottommost part of the dish (Note: only used if UNIFORM_WALL_THICKNESS is false)
// NOTE: If you make DISH_THICKNESS too small legends might not print properly--even with a tiny nozzle. In other words, a thick keycap top makes for nice clean (3D printed) legends.
// NOTE: Also, if you're printing white keycaps with transparent legends you want a thick dish (1.2+) to darken the non-transparent parts of the keycap
DISH_TILT = 0; // How to rotate() the dish of the key (on the Y axis)
Expand All @@ -99,13 +99,13 @@ DISH_INVERT_DIVISION_X = 4;
DISH_INVERT_DIVISION_Y = 1;
// TIP: If you're making a 1U keycap and want a truly rounded (spherical) top set DISH_INVERT_DIVISION_X to 1
// NOTE: Don't forget to increase DISH_FN if you make a longer/wider keycap!
DISH_FN = $preview ? 28 : 256; // If you want to increase or decrease the resolution of the shapes used to make the dish (Tip: Don't go <64 for "cylinder" dish types and don't go <128 for "sphere")
DISH_FN = $preview ? 28 : 512; // If you want to increase or decrease the resolution of the shapes used to make the dish (Tip: Don't go <64 for "cylinder" dish types and don't go <128 for "sphere")
// NOTE: DISH_FN does not apply if DISH_INVERT==true (because it would be too much; inverted dish doesn't need as much resolution)
DISH_CORNER_FN = $preview ? 16 : 64;
DISH_CORNER_FN = $preview ? 16 : 128;
// COOL TRICK: Set DISH_CORNER_FN to 4 to get flattened/chamfered corners (low-poly look!)

// POLYGON/SHAPE MANIPULATION
POLYGON_LAYERS = 10; // Number of layers we're going to extrude (set to 1 to get a boring keycap)
POLYGON_LAYERS = 32; // Number of layers we're going to extrude (set to 1 to get a boring keycap)
POLYGON_LAYER_ROTATION = 0; // How much to rotate per layer (set to 0 for boring keycap). Try messing with this! It's fun!
POLYGON_EDGES = 4; // How many sides the keycap will have (normal keycap is 4). Try messing with this too!
POLYGON_ROTATION = true; // If false, each layer will ALTERNATE it's rotation CW/CCW (for a low-poly effect). If true the keycap will gently rotate the given rotation amount until it reaches the final rotated destination (as it were).
Expand All @@ -121,22 +121,22 @@ STEM_HEIGHT = 4; // How far into the keycap's stem the switch's stem can go (4 i
// NOTE: For Alps you typically want STEM_HEIGHT=3.5 (slightly shorter)
STEM_TOP_THICKNESS = 0.5; // The part that resides under the keycap, connecting stems and keycap together (Note: Only used if UNIFORM_WALL_THICKNESS is false)
// TIP: Increase STEM_TOP_THICKNESS when generating underset masks; makes them easier to use as a modifier in your slicer.
STEM_INSIDE_TOLERANCE = 0.2; // Increases the size of the empty space(s) in the stem
STEM_INSIDE_TOLERANCE = 0.1; // Increases the size of the empty space(s) in the stem
// NOTE: For Alps stems I recommend reducing these two values to something like 0.1 or 0.05:
STEM_OUTSIDE_TOLERANCE_X = 0.05; // Shrinks the stem a bit on the X axis (both axis for round_cherry)
STEM_OUTSIDE_TOLERANCE_Y = 0.05; // Shrinks the stem a bit on th Y axix (unused with round_cherry)
STEM_OUTSIDE_TOLERANCE_Y = 0.05; // Shrinks the stem a bit on the Y axis (unused with round_cherry)
// For box stems (e.g. Kailh box) you want outside tolerances to be equal. For Cherry stems you (usually) want the Y tolerance to be greater (since there's plenty of room on the sides). In fact, you can go *negative* with STEM_OUTSIDE_TOLERANCE_X (e.g. -0.5) for extra strength!
// Probably leave these two alone but they're here if you really love to mess with things:
ALPS_STEM_CORNER_RADIUS = 0.25;
BOX_CHERRY_STEM_CORNER_RADIUS = 0.5;
// Convert to one variable to rule them all (down below):
STEM_CORNER_RADIUS = STEM_TYPE=="alps" ? ALPS_STEM_CORNER_RADIUS : BOX_CHERRY_STEM_CORNER_RADIUS;
// NOTE ABOUT STEM STRENGTH AND ACCURACY: Printing stems upright/flat with a 0.4mm nozzle is troublesome. They work OK but they're usually quite tight. It's better to print keys on their side (front or left/right) so that the layer lines run at an angle to the switch stem; they end up more accurate *and* much, much stronger.
STEM_INSET = 1; // How far to inset the stem (set to 0 to have the stem rest on the build plate which means you won't need supports when printing flat)
STEM_INSET = 2.4; // How far to inset the stem (set to 0 to have the stem rest on the build plate which means you won't need supports when printing flat)
STEM_FLAT_SUPPORT = false; // Add built-in support for the stem when printing flat (if inset)
STEM_SIDE_SUPPORT_THICKNESS = 1; // 1 works well for most things
// This controls which sides get (internal, under-the-top) stem supports (for printing on the side):
STEM_SIDE_SUPPORTS = [0,1,0,0]; // Left, right, front, back
STEM_SIDE_SUPPORTS = [0,0,0,0]; // Left, right, front, back
// NOTE: You can only enable left/right supports *or* front/back supports. Not both at the same time. (TODO: Fix that... Maybe? Why would you ever need *both* say, a left support *and* a top support at the same time?)
STEM_SUPPORT_DISTANCE = 0.2; // Controls the air gap between the stem and its support
// NOTE: If printing with a small nozzle like 0.25mm you might want to set the support distance to 0 to prevent "misses".
Expand All @@ -147,24 +147,28 @@ STEM_LOCATIONS = [ // Where to place stems/stabilizers
// [0,12,0], [0,-12,0], // Standard 2U Numpad + or Enter
// [50,0,0], [-50,0,0], // Cherry style 6.25U spacebar (most common)
// [57,0,0], [-57,0,0], // Cherry style 7U spacebar
// [12,0,0], [-12,0,0] // ISO enter
// [-KEY_UNIT / 2, 0, 0], [KEY_UNIT / 2, 0, 0] // 2u across 2 switches
// [0, -KEY_UNIT / 2, 0], [0, KEY_UNIT / 2, 0] // 2u across 2 switches, vertical
// [((1.75 - 1.25)/2)*KEY_UNIT, 0, 0] // stepped caps on a non-stepped caps layout
];
// SNAP-FIT STEM STUFF (see snap_fit.scad for more details)
STEM_SNAP_FIT = false; // If you want to print the stem as a separate part
STEM_SIDES_WALL_THICKNESS = 0.5; // This will add additional thickness to the interior walls of the keycap that's rendered/exported with the "stem". If you have legends on the front/back/sides of your keycap setting this to something like 0.65 will give those legends something to "sit" on when printing (so there's no mid-air printing or drooping).
STEM_SIDES_WALL_THICKNESS = 0; // This will add additional thickness to the interior walls of the keycap that's rendered/exported with the "stem". If you have legends on the front/back/sides of your keycap setting this to something like 0.65 will give those legends something to "sit" on when printing (so there's no mid-air printing or drooping).
STEM_WALLS_INSET = 0; // Makes it so the stem walls don't go all the way to the bottom of the keycap; works just like STEM_INSET but for the walls (1.05 is good for snap-fit stems)
STEM_WALLS_TOLERANCE = 0.0; // How much wiggle room the stem sides will get inside the keycap (0.2 is good for snap-fit stems)
STEM_WALLS_TOLERANCE = 0.1; // How much wiggle room the stem sides will get inside the keycap (0.2 is good for snap-fit stems)

// If you want "homing dots" for home row keys:
HOMING_DOT_LENGTH = 0; // Set to something like "3" for a good, easy-to-feel "dot"
HOMING_DOT_WIDTH = 1; // Default: 1
HOMING_DOT_X = 0; // 0 == Center
HOMING_DOT_Y = -KEY_WIDTH/4; // Default: Move it down towards the front a bit
HOMING_DOT_Z = -0.35; // 0 == Right at KEY_HEIGHT (dish type makes a big difference here)
HOMING_DOT_Z = 0.05; // 0 == Right at KEY_HEIGHT (dish type makes a big difference here)
// NOTE: ADA specifies 0.5mm as the ideal braille dot height so that's what I recommend for homing dots too! Though, 0.3mm seems to be reasonably "feelable" in my testing. Experiment!

// LEGENDARY!
LEGENDS = [ // As many legends as you want
"A",
// "A",
// "1", "!", // Just an example of multiple legends (uncomment to try it!)
// "☺", // Unicode characters work too!
];
Expand Down Expand Up @@ -1636,4 +1640,4 @@ render_keycap(RENDER);
* Riskeycap profile has been updated to the latest version (5.0). This is the result of much typing and experimentation.
1.0:
* Initial release of the Keycap Playgound.
*/
*/
19 changes: 14 additions & 5 deletions profiles.scad
Original file line number Diff line number Diff line change
Expand Up @@ -1410,9 +1410,18 @@ module GEM_stem(stem_type="box_cherry", key_height=8.2, key_length=18.25, key_wi
}
}

module XDA_keycap(row=1, length=18.41, width=18.41, height_extra=0, wall_thickness=1.5, dish_thickness=1.5, dish_fn=$preview ? 28 : 256, dish_corner_fn=$preview ? 16 : 64, dish_depth=1, dish_invert=false, stem_clips=false, stem_walls_inset=0, stem_walls_tolerance=0.25, top_difference=19.05/5, key_rotation=[0,0,0], corner_radius=0.3, corner_radius_curve=8, legends=[""], legend_font_sizes=[6], legend_fonts=["Roboto"], legend_trans=[[0,0,0]], legend_trans2=[[0,0,0]], legend_rotation=[[0,0,0]], legend_rotation2=[[0,0,0]], legend_scale=[[0,0,0]], legend_underset=[[0,0,0]], legend_carved=false, homing_dot_length=0, homing_dot_width=0, homing_dot_x=0, homing_dot_y=0, homing_dot_z=0, polygon_layers=10, visualize_legends=false, uniform_wall_thickness=true, debug=false) {
module XDA_keycap(
row=1, length=18.2, width=18.2, height_extra=0, top_difference=4.15, wall_thickness=1.5, uniform_wall_thickness=true, key_rotation=[0,0,0],
dish_thickness=1.5, dish_fn=$preview ? 28 : 256, dish_corner_fn=$preview ? 16 : 64, dish_depth=1.1, dish_invert=false,
stem_clips=false, stem_walls_inset=0, stem_walls_tolerance=0.25,
corner_radius=0.2, corner_radius_curve=17.9,
visualize_legends=false, legend_carved=false, legends=[""], legend_font_sizes=[6], legend_fonts=["Roboto"], legend_trans=[[0,0,0]], legend_trans2=[[0,0,0]], legend_rotation=[[0,0,0]], legend_rotation2=[[0,0,0]], legend_scale=[[0,0,0]], legend_underset=[[0,0,0]],
homing_dot_length=0, homing_dot_width=0, homing_dot_x=0, homing_dot_y=0, homing_dot_z=0, polygon_layers=10,
debug=false
) {

// NOTE: The 0-index values are ignored (there's no row 0 in XDA)
row_height = dish_invert ? 8.1+height_extra : 9.1+height_extra; // One less if we're generating a spacebar
row_height = dish_invert ? 8.95+height_extra : 9.95+height_extra; // One less if we're generating a spacebar
if (row < 1) {
warning("We only support rows 1 for XDA profile caps!");
}
Expand All @@ -1435,7 +1444,7 @@ module XDA_keycap(row=1, length=18.41, width=18.41, height_extra=0, wall_thickne
legend_rotation=legend_rotation, legend_rotation2=legend_rotation2,
legend_underset=legend_underset, legend_carved=legend_carved,
polygon_layers=polygon_layers, polygon_layer_rotation=0,
polygon_edges=4, polygon_curve=5,
polygon_edges=4, polygon_curve=3.5,
key_rotation=key_rotation,
homing_dot_length=homing_dot_length, homing_dot_width=homing_dot_width,
homing_dot_x=homing_dot_x, homing_dot_y=homing_dot_y, homing_dot_z=homing_dot_z,
Expand All @@ -1444,8 +1453,8 @@ module XDA_keycap(row=1, length=18.41, width=18.41, height_extra=0, wall_thickne
debug=debug);
}

module XDA_stem(stem_type="box_cherry", key_height=7.3914, key_length=18.41, key_width=18.41, height_extra=0, dish_depth=1, dish_fn=128, dish_corner_fn=64, dish_thickness=1.5, dish_invert=false, depth=4, top_difference=19.05/5, wall_thickness=1.5, wall_extra=0.65, wall_inset=0, wall_tolerance=0.25, corner_radius=0.3, key_corner_radius=0.3, top_x=0, top_y=0, outside_tolerance_x=0.2, outside_tolerance_y=0.2, inside_tolerance=0.25, inset=0, top_thickness=1, side_support_thickness=0, side_supports=[0,0,0,0], flat_support=false, locations=[[0,0,0]], key_rotation=[0,0,0], polygon_layers=10, polygon_layer_rotation=0, hollow=false, uniform_wall_thickness=true) {
row_height = dish_invert ? 8.1+height_extra : 9.1+height_extra; // One less if we're generating a spacebar
module XDA_stem(stem_type="box_cherry", key_height=9.95, key_length=17.9, key_width=17.9, height_extra=0, dish_depth=1, dish_fn=128, dish_corner_fn=64, dish_thickness=1.5, dish_invert=false, depth=4, top_difference=3.6, wall_thickness=1.5, wall_extra=0.65, wall_inset=0, wall_tolerance=0.25, corner_radius=0.3, key_corner_radius=0.3, top_x=0, top_y=0, outside_tolerance_x=0.2, outside_tolerance_y=0.2, inside_tolerance=0.25, inset=0, top_thickness=1, side_support_thickness=0, side_supports=[0,0,0,0], flat_support=false, locations=[[0,0,0]], key_rotation=[0,0,0], polygon_layers=10, polygon_layer_rotation=0, hollow=false, uniform_wall_thickness=true) {
row_height = dish_invert ? 8.95+height_extra : 9.95+height_extra; // One less if we're generating a spacebar
dish_type = "sphere";
dish_z = 0.111; // NOTE: Width of the top dish (at widest) should be ~12.7mm
corner_radius_curve = 8;
Expand Down