make this library a lot more modular

This commit is contained in:
Bob - Home - Windows 2018-02-04 15:43:17 -05:00
parent 2368961370
commit aa795c4958
31 changed files with 467 additions and 443 deletions

View file

@ -1,5 +1,10 @@
include <libraries/geodesic_sphere.scad>
include <shapes.scad>
include <dishes/cylindrical.scad>
include <dishes/old_spherical.scad>
include <dishes/sideways_cylindrical.scad>
include <dishes/spherical.scad>
//geodesic looks much better, but runs very slow for anything above a 2u
geodesic=false;
@ -18,93 +23,7 @@ module dish(width, height, depth, inverted) {
old_spherical_dish(width, height, depth, inverted);
} else {
// else no dish, "no dish" is the value
// switchted to actually diffing a cube here due to (hopeful) changes to stems being differenced from the dish instead of the inside
// switchted to actually diffing a cube here due to changes to stems being differenced from the dish instead of the inside
translate([0,0,500]) cube([width, height, 1000], center=true);
}
}
module cylindrical_dish(width, height, depth, inverted){
// .5 has problems starting around 3u
$fa=.25;
/* we do some funky math here
* basically you want to have the dish "dig in" to the keycap x millimeters
* in order to do that you have to solve a small (2d) system of equations
* where the chord of the spherical cross section of the dish is
* the width of the keycap.
*/
// the distance you have to move the dish so it digs in depth millimeters
chord_length = (pow(width, 2) - 4 * pow(depth, 2)) / (8 * depth);
//the radius of the dish
rad = (pow(width, 2) + 4 * pow(depth, 2)) / (8 * depth);
direction = inverted ? -1 : 1;
translate([0,0, chord_length * direction]){
rotate([90, 0, 0]) cylinder(h=height + 20, r=rad, center=true);
}
}
module sideways_cylindrical_dish(width, height, depth, inverted){
$fa=1;
chord_length = (pow(height, 2) - 4 * pow(depth, 2)) / (8 * depth);
rad = (pow(height, 2) + 4 * pow(depth, 2)) / (8 * depth);
direction = inverted ? -1 : 1;
translate([0,0, chord_length * direction]){
// cylinder is rendered facing up, so we rotate it on the y axis first
rotate([0,90,0]) cylinder(h = width + 20,r=rad, center=true); // +20 for fudge factor
}
}
module spherical_dish(width, height, depth, inverted){
//same thing as the cylindrical dish here, but we need the corners to just touch - so we have to find the hypotenuse of the top
chord = pow((pow(width,2) + pow(height, 2)),0.5); //getting diagonal of the top
// the distance you have to move the dish up so it digs in depth millimeters
chord_length = (pow(chord, 2) - 4 * pow(depth, 2)) / (8 * depth);
//the radius of the dish
rad = (pow(chord, 2) + 4 * pow(depth, 2)) / (8 * depth);
direction = inverted ? -1 : 1;
translate([0,0,0 * direction]){
if (geodesic){
$fa=20;
scale([chord/2/depth, chord/2/depth]) {
geodesic_sphere(r=depth);
}
} else {
$fa=7;
// rotate 1 because the bottom of the sphere looks like trash.
scale([chord/2/depth, chord/2/depth]) {
geodesic_sphere(r=depth);
}
}
}
}
//the older, 'more accurate', and MUCH slower spherical dish.
// generates the largest sphere possible that still contains the chord we are looking for
// much more graduated curvature at an immense cost
module old_spherical_dish(width, height, depth, inverted){
//same thing as the cylindrical dish here, but we need the corners to just touch - so we have to find the hypotenuse of the top
chord = pow((pow(width,2) + pow(height, 2)),0.5); //getting diagonal of the top
// the distance you have to move the dish up so it digs in depth millimeters
chord_length = (pow(chord, 2) - 4 * pow(depth, 2)) / (8 * depth);
//the radius of the dish
rad = (pow(chord, 2) + 4 * pow(depth, 2)) / (8 * depth);
direction = inverted ? -1 : 1;
translate([0,0,chord_length * direction]){
if (geodesic){
$fa=7;
geodesic_sphere(r=rad);
} else {
$fa=1;
// rotate 1 because the bottom of the sphere looks like trash
sphere(r=rad);
}
}
}

View file

@ -0,0 +1,19 @@
module cylindrical_dish(width, height, depth, inverted){
// .5 has problems starting around 3u
$fa=.25;
/* we do some funky math here
* basically you want to have the dish "dig in" to the keycap x millimeters
* in order to do that you have to solve a small (2d) system of equations
* where the chord of the spherical cross section of the dish is
* the width of the keycap.
*/
// the distance you have to move the dish so it digs in depth millimeters
chord_length = (pow(width, 2) - 4 * pow(depth, 2)) / (8 * depth);
//the radius of the dish
rad = (pow(width, 2) + 4 * pow(depth, 2)) / (8 * depth);
direction = inverted ? -1 : 1;
translate([0,0, chord_length * direction]){
rotate([90, 0, 0]) cylinder(h=height + 20, r=rad, center=true);
}
}

View file

@ -0,0 +1,25 @@
//the older, 'more accurate', and MUCH slower spherical dish.
// generates the largest sphere possible that still contains the chord we are looking for
// much more graduated curvature at an immense cost
module old_spherical_dish(width, height, depth, inverted){
//same thing as the cylindrical dish here, but we need the corners to just touch - so we have to find the hypotenuse of the top
chord = pow((pow(width,2) + pow(height, 2)),0.5); //getting diagonal of the top
// the distance you have to move the dish up so it digs in depth millimeters
chord_length = (pow(chord, 2) - 4 * pow(depth, 2)) / (8 * depth);
//the radius of the dish
rad = (pow(chord, 2) + 4 * pow(depth, 2)) / (8 * depth);
direction = inverted ? -1 : 1;
translate([0,0,chord_length * direction]){
if (geodesic){
$fa=7;
geodesic_sphere(r=rad);
} else {
$fa=1;
// rotate 1 because the bottom of the sphere looks like trash
sphere(r=rad);
}
}
}

View file

@ -0,0 +1,12 @@
module sideways_cylindrical_dish(width, height, depth, inverted){
$fa=1;
chord_length = (pow(height, 2) - 4 * pow(depth, 2)) / (8 * depth);
rad = (pow(height, 2) + 4 * pow(depth, 2)) / (8 * depth);
direction = inverted ? -1 : 1;
translate([0,0, chord_length * direction]){
// cylinder is rendered facing up, so we rotate it on the y axis first
rotate([0,90,0]) cylinder(h = width + 20,r=rad, center=true); // +20 for fudge factor
}
}

26
src/dishes/spherical.scad Normal file
View file

@ -0,0 +1,26 @@
module spherical_dish(width, height, depth, inverted){
//same thing as the cylindrical dish here, but we need the corners to just touch - so we have to find the hypotenuse of the top
chord = pow((pow(width,2) + pow(height, 2)),0.5); //getting diagonal of the top
// the distance you have to move the dish up so it digs in depth millimeters
chord_length = (pow(chord, 2) - 4 * pow(depth, 2)) / (8 * depth);
//the radius of the dish
rad = (pow(chord, 2) + 4 * pow(depth, 2)) / (8 * depth);
direction = inverted ? -1 : 1;
translate([0,0,0 * direction]){
if (geodesic){
$fa=20;
scale([chord/2/depth, chord/2/depth]) {
geodesic_sphere(r=depth);
}
} else {
$fa=7;
// rotate 1 because the bottom of the sphere looks like trash.
scale([chord/2/depth, chord/2/depth]) {
geodesic_sphere(r=depth);
}
}
}
}

8
src/key_profiles.scad Normal file
View file

@ -0,0 +1,8 @@
// key profile definitions
// unlike the other files with their own dedicated folders, this one doesn't need a selector. it just collects all the functions
include <key_profiles/dcs.scad>
include <key_profiles/oem.scad>
include <key_profiles/dsa.scad>
include <key_profiles/sa.scad>
include <key_profiles/g20.scad>

34
src/key_profiles/dcs.scad Normal file
View file

@ -0,0 +1,34 @@
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();
}
}

20
src/key_profiles/dsa.scad Normal file
View file

@ -0,0 +1,20 @@
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 + abs((n-3) * 1);
$top_tilt = (n-3) * -7;
$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();
}

20
src/key_profiles/g20.scad Normal file
View file

@ -0,0 +1,20 @@
module g20_row(n=3) {
$bottom_key_width = 18.16;
$bottom_key_height = 18.16;
$width_difference = 2;
$height_difference = 2;
$total_depth = 6;
$top_tilt = 2.5;
$top_tilt = (n-3) * -7 + 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;
//also,
/*$rounded_key = true;*/
children();
}

34
src/key_profiles/oem.scad Normal file
View file

@ -0,0 +1,34 @@
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();
}
}

34
src/key_profiles/sa.scad Normal file
View file

@ -0,0 +1,34 @@
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();
}
}

69
src/key_sizes.scad Normal file
View file

@ -0,0 +1,69 @@
// 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();
}

View file

@ -0,0 +1,94 @@
// 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_type = "filled";
children();
}
module blank() {
$stem_type = "blank";
children();
}
module cherry(slop = 0.3) {
$stem_slop = slop;
$stem_type = "cherry";
children();
}
module alps(slop = 0.3) {
$stem_slop = slop;
$stem_type = "alps";
children();
}
module rounded_cherry(slop = 0.3) {
$stem_slop = slop;
$stem_type = "cherry_rounded";
children();
}
module flared_support() {
$support_type = "flared";
children();
}
module bar_support() {
$support_type = "bars";
children();
}
module flat_support() {
$support_type = "flat";
children();
}

59
src/key_types.scad Normal file
View file

@ -0,0 +1,59 @@
module spacebar() {
$inverted_dish = true;
$dish_type = "sideways cylindrical";
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();
}
}

View file

@ -1,96 +1,21 @@
$fs=.1;
unit = 19.05;
// side sculpting functions
// bows the sides out on stuff like SA and DSA keycaps
function side_sculpting(progress) = (1 - progress) * 2.5;
// makes the rounded corners of the keycap grow larger as they move upwards
function corner_sculpting(progress) = pow(progress, 2);
include <shapes/ISO_enter.scad>
include <shapes/rounded_square.scad>
include <shapes/square.scad>
include <shapes/oblong.scad>
module key_shape(size, delta, progress = 0) {
if ($key_shape_type == "iso_enter") {
ISO_enter(size, delta, progress);
ISO_enter_shape(size, delta, progress);
} else if ($key_shape_type == "rounded_square") {
roundedSquare(size, delta, progress);
rounded_square_shape(size, delta, progress);
} else if ($key_shape_type == "square") {
square(size - delta, center = true);
} else if ($key_shape_type == "spherical") {
spherical(size, delta, progress);
square_shape(size, delta, progress);
} else if ($key_shape_type == "oblong") {
oblong_shape(size, delta, progress);
} else {
echo("Warning: unsupported $key_shape_type");
}
}
module spherical(size, delta, progress) {
// .05 is because of offset. if we set offset to be half the height of the shape, and then subtract height from the shape, the height of the shape will be zero (because the shape would be [width - height, height - height]). that doesn't play well with openSCAD (understandably), so we add this tiny fudge factor to make sure the shape we offset has a positive width
height = size[1] - delta[1] * progress - .05;
if (progress < 0.5) {
} else {
offset(r=height / 2) {
square(size - [height, height] - delta * progress, center=true);
}
}
}
module roundedSquare(size, delta, progress, center = true) {
width = size[0];
height = size[1];
width_difference = delta[0];
height_difference = delta[1];
// makes the sides bow
extra_side_size = $enable_side_sculpting ? side_sculpting(progress) : 0;
// makes the rounded corners of the keycap grow larger as they move upwards
extra_corner_size = $enable_side_sculpting ? corner_sculpting(progress) : 0;
// computed values for this slice
extra_width_this_slice = (width_difference - extra_side_size) * progress;
extra_height_this_slice = (height_difference - extra_side_size) * progress;
extra_corner_radius_this_slice = ($corner_radius + extra_corner_size);
offset(r=extra_corner_radius_this_slice){
square(
[
width - extra_width_this_slice - extra_corner_radius_this_slice * 2,
height - extra_height_this_slice - extra_corner_radius_this_slice * 2
],
center=center
);
}
}
// corollary is roundedSquare
// NOT 3D
module ISO_enter(size, delta, progress){
width = size[0];
height = size[1];
function unit_length(length) = unit * (length - 1) + 18.16;
// in order to make the ISO keycap shape generic, we are going to express the
// 'elbow point' in terms of ratios. an ISO enter is just a 1.5u key stuck on
// top of a 1.25u key, but since our key_shape function doesnt understand that
// and wants to pass just width and height, we make these ratios to know where
// to put the elbow joint
width_ratio = unit_length(1.25) / unit_length(1.5);
height_ratio = unit_length(1) / unit_length(2);
pointArray = [
[ 0, 0], // top right
[ 0, -height], // bottom right
[-width * width_ratio, -height], // bottom left
[-width * width_ratio,-height * height_ratio], // inner middle point
[ -width,-height * height_ratio], // outer middle point
[ -width, 0] // top left
];
minkowski(){
circle(r=corner_size);
// gives us rounded inner corner
offset(r=-corner_size*2) {
translate([(width * width_ratio)/2, height/2]) polygon(points=pointArray);
}
}
}

34
src/shapes/ISO_enter.scad Normal file
View file

@ -0,0 +1,34 @@
// corollary is rounded_square
// NOT 3D
module ISO_enter_shape(size, delta, progress){
width = size[0];
height = size[1];
function unit_length(length) = unit * (length - 1) + 18.16;
// in order to make the ISO keycap shape generic, we are going to express the
// 'elbow point' in terms of ratios. an ISO enter is just a 1.5u key stuck on
// top of a 1.25u key, but since our key_shape function doesnt understand that
// and wants to pass just width and height, we make these ratios to know where
// to put the elbow joint
width_ratio = unit_length(1.25) / unit_length(1.5);
height_ratio = unit_length(1) / unit_length(2);
pointArray = [
[ 0, 0], // top right
[ 0, -height], // bottom right
[-width * width_ratio, -height], // bottom left
[-width * width_ratio,-height * height_ratio], // inner middle point
[ -width,-height * height_ratio], // outer middle point
[ -width, 0] // top left
];
minkowski(){
circle(r=corner_size);
// gives us rounded inner corner
offset(r=-corner_size*2) {
translate([(width * width_ratio)/2, height/2]) polygon(points=pointArray);
}
}
}

11
src/shapes/oblong.scad Normal file
View file

@ -0,0 +1,11 @@
module oblong_shape(size, delta, progress) {
// .05 is because of offset. if we set offset to be half the height of the shape, and then subtract height from the shape, the height of the shape will be zero (because the shape would be [width - height, height - height]). that doesn't play well with openSCAD (understandably), so we add this tiny fudge factor to make sure the shape we offset has a positive width
height = size[1] - delta[1] * progress - .05;
if (progress < 0.5) {
} else {
offset(r=height / 2) {
square(size - [height, height] - delta * progress, center=true);
}
}
}

View file

@ -0,0 +1,32 @@
// side sculpting functions
// bows the sides out on stuff like SA and DSA keycaps
function side_sculpting(progress) = (1 - progress) * 2.5;
// makes the rounded corners of the keycap grow larger as they move upwards
function corner_sculpting(progress) = pow(progress, 2);
module rounded_square_shape(size, delta, progress, center = true) {
width = size[0];
height = size[1];
width_difference = delta[0];
height_difference = delta[1];
// makes the sides bow
extra_side_size = $enable_side_sculpting ? side_sculpting(progress) : 0;
// makes the rounded corners of the keycap grow larger as they move upwards
extra_corner_size = $enable_side_sculpting ? corner_sculpting(progress) : 0;
// computed values for this slice
extra_width_this_slice = (width_difference - extra_side_size) * progress;
extra_height_this_slice = (height_difference - extra_side_size) * progress;
extra_corner_radius_this_slice = ($corner_radius + extra_corner_size);
offset(r=extra_corner_radius_this_slice){
square(
[
width - extra_width_this_slice - extra_corner_radius_this_slice * 2,
height - extra_height_this_slice - extra_corner_radius_this_slice * 2
],
center=center
);
}
}

3
src/shapes/square.scad Normal file
View file

@ -0,0 +1,3 @@
module square_shape(size, delta, progress){
square(size - delta * progress, center = true);
}

View file

@ -1,85 +1,20 @@
include <stems/cherry.scad>
include <stems/rounded_cherry.scad>
include <stems/alps.scad>
include <stems/filled.scad>
//whole stem, alps or cherry, trimmed to fit
module stem(stem_type, depth, has_brim){
if (stem_type == "alps") {
alps_stem(depth, has_brim);
} else if (stem_type == "cherry_rounded") {
cherry_stem_rounded(depth, has_brim);
rounded_cherry_stem(depth, has_brim);
} else if (stem_type == "cherry") {
cherry_stem(depth, has_brim);
} else if (stem_type == "filled") {
// just a cube, so no args
filled_stem();
} else {
echo("Warning: unsupported $stem_type");
}
}
module cherry_stem(depth, has_brim) {
difference(){
union() {
// outside shape
linear_extrude(height = depth) {
offset(r=1){
square($cherry_stem - [2,2], center=true);
}
}
// brim, if applicable
if(has_brim) {
linear_extrude(height = brim_height){
offset(r=1){
square($cherry_stem - [2,2], center=true);
}
}
}
}
// inside cross
// translation purely for aesthetic purposes, to get rid of that awful lattice
translate([0,0,-0.005]) {
linear_extrude(height = $stem_throw) {
square($cherry_cross[0], center=true);
square($cherry_cross[1], center=true);
}
}
}
}
module cherry_stem_rounded(depth, has_brim) {
difference(){
union(){
cylinder(d=$rounded_cherry_stem_d, h=depth);
if(has_brim) {
cylinder(d=$rounded_cherry_stem_d * 2, h=brim_height);
}
}
// inside cross
// translation purely for aesthetic purposes, to get rid of that awful lattice
translate([0,0,-0.005]) {
linear_extrude(height = $stem_throw) {
square($cherry_cross[0], center=true);
square($cherry_cross[1], center=true);
}
}
}
}
module alps_stem(depth, has_brim){
if(has_brim) {
linear_extrude(h=brim_height) {
square($alps_stem * [2,2], center = true);
}
}
linear_extrude(h=depth) {
square($alps_stem, 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(1000, center=true);
}

10
src/stems/alps.scad Normal file
View file

@ -0,0 +1,10 @@
module alps_stem(depth, has_brim){
if(has_brim) {
linear_extrude(h=brim_height) {
square($alps_stem * [2,2], center = true);
}
}
linear_extrude(h=depth) {
square($alps_stem, center = true);
}
}

30
src/stems/cherry.scad Normal file
View file

@ -0,0 +1,30 @@
module cherry_stem(depth, has_brim) {
difference(){
union() {
// outside shape
linear_extrude(height = depth) {
offset(r=1){
square($cherry_stem - [2,2], center=true);
}
}
// brim, if applicable
if(has_brim) {
linear_extrude(height = brim_height){
offset(r=1){
square($cherry_stem - [2,2], center=true);
}
}
}
}
// inside cross
// translation purely for aesthetic purposes, to get rid of that awful lattice
translate([0,0,-0.005]) {
linear_extrude(height = $stem_throw) {
square($cherry_cross[0], center=true);
square($cherry_cross[1], center=true);
}
}
}
}

5
src/stems/filled.scad Normal file
View file

@ -0,0 +1,5 @@
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);
}

View file

@ -0,0 +1,19 @@
module rounded_cherry_stem(depth, has_brim) {
difference(){
union(){
cylinder(d=$rounded_cherry_stem_d, h=depth);
if(has_brim) {
cylinder(d=$rounded_cherry_stem_d * 2, h=brim_height);
}
}
// inside cross
// translation purely for aesthetic purposes, to get rid of that awful lattice
translate([0,0,-0.005]) {
linear_extrude(height = $stem_throw) {
square($cherry_cross[0], center=true);
square($cherry_cross[1], center=true);
}
}
}
}

View file

@ -1,51 +1,15 @@
// figures out the scale factor needed to make a 45 degree wall
function scale_for_45(height, starting_size) = (height * 2 + starting_size) / starting_size;
include <supports/flared.scad>
include <supports/flat.scad>
include <supports/bars.scad>
module supports(type, stem_type, loft, height) {
if (type == "flared") {
flared(stem_type, loft, height);
flared_support(stem_type, loft, height);
} else if (type == "flat") {
flat(stem_type, loft, height);
flat_support(stem_type, loft, height);
} else if (type == "bars") {
bars(stem_type, loft, height);
bars_support(stem_type, loft, height);
} else {
echo("Warning: unsupported $support_type");
}
}
// complicated since we want the different stems to work well
// also kind of messy... oh well
module flared(stem_type, loft, height) {
translate([0,0,loft]){
if(stem_type == "cherry") {
cherry_scale = [scale_for_45(height, $cherry_stem[0]), scale_for_45(height, $cherry_stem[1])];
linear_extrude(height=height, scale = cherry_scale){
offset(r=1){
square($cherry_stem - [2,2], center=true);
}
}
} else if (stem_type == "cherry_rounded") {
linear_extrude(height=height, scale = scale_for_45(height, $rounded_cherry_stem_d)){
circle(d=$rounded_cherry_stem_d);
}
} else if (stem_type == "alps") {
alps_scale = [scale_for_45(height, $alps_stem[0]), scale_for_45(height, $alps_stem[1])];
linear_extrude(height=height, scale = alps_scale){
square($alps_stem, center=true);
}
}
}
}
module flat(stem_type, loft, height) {
translate([0,0,loft + 500]){
cube(1000, center=true);
}
}
module bars(stem_type, loft, height) {
translate([0,0,loft + height / 2]){
cube([2, 100, height], center = true);
cube([100, 2, height], center = true);
}
}

6
src/supports/bars.scad Normal file
View file

@ -0,0 +1,6 @@
module bars_support(stem_type, loft, height) {
translate([0,0,loft + height / 2]){
cube([2, 100, height], center = true);
cube([100, 2, height], center = true);
}
}

26
src/supports/flared.scad Normal file
View file

@ -0,0 +1,26 @@
// figures out the scale factor needed to make a 45 degree wall
function scale_for_45(height, starting_size) = (height * 2 + starting_size) / starting_size;
// complicated since we want the different stems to work well
// also kind of messy... oh well
module flared_support(stem_type, loft, height) {
translate([0,0,loft]){
if(stem_type == "cherry") {
cherry_scale = [scale_for_45(height, $cherry_stem[0]), scale_for_45(height, $cherry_stem[1])];
linear_extrude(height=height, scale = cherry_scale){
offset(r=1){
square($cherry_stem - [2,2], center=true);
}
}
} else if (stem_type == "cherry_rounded") {
linear_extrude(height=height, scale = scale_for_45(height, $rounded_cherry_stem_d)){
circle(d=$rounded_cherry_stem_d);
}
} else if (stem_type == "alps") {
alps_scale = [scale_for_45(height, $alps_stem[0]), scale_for_45(height, $alps_stem[1])];
linear_extrude(height=height, scale = alps_scale){
square($alps_stem, center=true);
}
}
}
}

5
src/supports/flat.scad Normal file
View file

@ -0,0 +1,5 @@
module flat_support(stem_type, loft, height) {
translate([0,0,loft + 500]){
cube(1000, center=true);
}
}