cleanup, fix inverted dishes with sculpted sides, add oem key profile

This commit is contained in:
Bob - Home - Windows 2017-09-25 00:04:34 -04:00
parent 7e9e2f0e1e
commit 72173cffc8
9 changed files with 115708 additions and 7473 deletions

View File

@ -3,6 +3,19 @@ include <util.scad>
//geodesic looks much better, but runs very slow for anything above a 2u //geodesic looks much better, but runs very slow for anything above a 2u
geodesic=false; geodesic=false;
//dish selector
module dish(width, height, depth, inverted, tilt) {
if($dish_type == "cylindrical"){
cylindrical_dish(width, height, depth, inverted, tilt);
}
else if ($dish_type == "spherical") {
spherical_dish(width, height, depth, inverted, tilt);
}
else if ($dish_type == "sideways cylindrical"){
sideways_cylindrical_dish(width, height, depth, inverted, tilt);
}
// else no dish, "no dish" is the value
}
module cylindrical_dish(width, height, depth, inverted, tilt){ module cylindrical_dish(width, height, depth, inverted, tilt){
// .5 has problems starting around 3u // .5 has problems starting around 3u
@ -26,6 +39,20 @@ module cylindrical_dish(width, height, depth, inverted, tilt){
} }
} }
module sideways_cylindrical_dish(width, height, depth, inverted, tilt){
$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;
rotate([90,tilt,90]){
translate([0,chord_length * direction,0]){
cylinder(h = width + 20,r=rad, center=true); // +20 for fudge factor
}
}
}
module spherical_dish(width, height, depth, inverted, tilt, txt=""){ module spherical_dish(width, height, depth, inverted, tilt, txt=""){
//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 //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
@ -58,8 +85,8 @@ module spherical_dish(width, height, depth, inverted, tilt, txt=""){
} }
//the older, 'more accurate', and MUCH slower spherical dish. //the older, 'more accurate', and MUCH slower spherical dish.
/* I guess this stuff requires some explaining: // 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, tilt, txt=""){ module old_spherical_dish(width, height, depth, inverted, tilt, txt=""){
//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 //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
@ -91,17 +118,3 @@ module old_spherical_dish(width, height, depth, inverted, tilt, txt=""){
/*translate([0,0,0]) roundedRect([width, height, depth], 1.5);*/ /*translate([0,0,0]) roundedRect([width, height, depth], 1.5);*/
/*}*/ /*}*/
} }
module sideways_cylindrical_dish(width, height, depth, inverted, tilt){
$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;
rotate([90,tilt,90]){
translate([0,chord_length * direction,0]){
cylinder(h = width + 20,r=rad, center=true); // +20 for fudge factor
}
}
}

52180
key-dsa_oem_test.stl Normal file

File diff suppressed because it is too large Load Diff

126
key.scad
View File

@ -35,7 +35,7 @@ top_tilt = -6;
// how skewed towards the back the top is (0 for center) // how skewed towards the back the top is (0 for center)
top_skew = 1.7; top_skew = 1.7;
// what type of dish the key has. 0 for cylindrical, 1 for spherical, 2 for something else idk TODO // what type of dish the key has. 0 for cylindrical, 1 for spherical, 2 for something else idk TODO
dish_type = 0; 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 // 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; dish_depth = 1;
// how skewed in the x direction the dish is // how skewed in the x direction the dish is
@ -95,7 +95,7 @@ $minkowski_radius = .75;
// derived functions. can't be variables if we want them to change when the special variables do // derived values. can't be variables if we want them to change when the special variables do
// actual mm key width and height // actual mm key width and height
function total_key_width() = $bottom_key_width + (unit * ($key_length - 1)); function total_key_width() = $bottom_key_width + (unit * ($key_length - 1));
@ -105,37 +105,15 @@ function total_key_height() = $bottom_key_height + (unit * ($key_height - 1));
function top_total_key_width() = $bottom_key_width + (unit * ($key_length - 1)) - $width_difference; function top_total_key_width() = $bottom_key_width + (unit * ($key_length - 1)) - $width_difference;
function top_total_key_height() = $bottom_key_height + (unit * ($key_height - 1)) - $height_difference; function top_total_key_height() = $bottom_key_height + (unit * ($key_height - 1)) - $height_difference;
// bottom clipping shape we can use to anchor the stem, just a big ol cube with the inside of
// the keycap hollowed out
module inside(){
difference(){
//TODO why 50?
translate([0,0,50]) cube([100000,100000,100000],center=true);
shape(wall_thickness, keytop_thickness);
}
}
// conicalish clipping shape to trim things off the outside of the keycap
// literally just a key with height of 2 to make sure nothing goes awry with dishing etc
module outside(thickness_difference){
difference(){
cube([100000,100000,100000],center = true);
shape_hull(thickness_difference, 0, 2);
}
}
// key shape including dish. used as the ouside and inside shape in key() // key shape including dish. used as the ouside and inside shape in key()
module shape(thickness_difference, depth_difference){ module shape(thickness_difference, depth_difference){
difference(){ intersection(){
union(){ dished(depth_difference, $inverted_dish) {
shape_hull(thickness_difference, depth_difference, 1); shape_hull(thickness_difference, depth_difference, 1);
if ($inverted_dish) { dish(depth_difference); }
} }
if (!$inverted_dish) { if ($inverted_dish) {
dish(depth_difference); // larger shape_hull to clip off bits of the inverted dish
} else { shape_hull(thickness_difference, 0, 1, 2);
// needed to trim the edges of an inverted dish
inside();
} }
} }
} }
@ -156,12 +134,13 @@ module rounded_shape() {
// modifier multiplies the height and top differences of the shape, // modifier multiplies the height and top differences of the shape,
// which is only used for dishing to cut the dish off correctly // which is only used for dishing to cut the dish off correctly
// $height_difference used for keytop thickness // $height_difference used for keytop thickness
module shape_hull(thickness_difference, depth_difference, modifier){ // extra_slices is a hack to make inverted dishes still work
module shape_hull(thickness_difference, depth_difference, modifier, extra_slices = 0){
if ($ISOEnter) { if ($ISOEnter) {
ISOEnterShapeHull(thickness_difference, depth_difference, modifier); ISOEnterShapeHull(thickness_difference, depth_difference, modifier);
} else { } else {
slices = 10; slices = 10;
for (index = [0:$height_slices-1]) { for (index = [0:$height_slices - 1 + extra_slices]) {
color("red") hull() { color("red") hull() {
shape_slice(index, $height_slices, thickness_difference, depth_difference, modifier); shape_slice(index, $height_slices, thickness_difference, depth_difference, modifier);
shape_slice(index + 1, $height_slices, thickness_difference, depth_difference, modifier); shape_slice(index + 1, $height_slices, thickness_difference, depth_difference, modifier);
@ -172,7 +151,8 @@ module shape_hull(thickness_difference, depth_difference, modifier){
module shape_slice(index, total, thickness_difference, depth_difference, modifier) { module shape_slice(index, total, thickness_difference, depth_difference, modifier) {
progress = index / (total); progress = index / (total);
extra_side_size = $enable_side_sculpting ? abs(index - total)/4 : 0; // TODO extract these out somehow so you can make custom rounded sides
extra_side_size = $enable_side_sculpting ? (total - index)/4 : 0;
extra_corner_size = $enable_side_sculpting ? pow(progress, 2) : 0; extra_corner_size = $enable_side_sculpting ? pow(progress, 2) : 0;
translate([ translate([
@ -188,48 +168,26 @@ module shape_slice(index, total, thickness_difference, depth_difference, modifie
} }
} }
module oldshape_hull(thickness_difference, depth_difference, modifier){ module dished(depth_difference, inverted = false) {
if ($ISOEnter) { if (inverted) {
ISOEnterShapeHull(thickness_difference, depth_difference, modifier); union() {
} else { children();
hull(){
// $bottom_key_width + ($key_length -1) * unit is the correct length of the
// key. only 1u of the key should be $bottom_key_width long; all others
// should be 1u
roundedRect([total_key_width() - thickness_difference, total_key_height() - thickness_difference, .001],$corner_radius);
//depth_difference outside of modifier because that doesnt make sense
translate([0,$top_skew,$total_depth * modifier - depth_difference]){
rotate([-$top_tilt / $key_height,0,0]){
roundedRect([
total_key_width() - thickness_difference - $width_difference * modifier,
total_key_height() - thickness_difference - $height_difference * modifier,
.001
],$corner_radius);
}
}
}
}
}
//dish selector
module dish(depth_difference){
translate([$dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference]){ translate([$dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference]){
if($dish_type == 0){ dish(top_total_key_width(), top_total_key_height(), $dish_depth, $inverted_dish, $top_tilt / $key_height);
cylindrical_dish(top_total_key_width(), top_total_key_height(), $dish_depth, $inverted_dish, $top_tilt / $key_height);
} }
else if ($dish_type == 1) {
spherical_dish(top_total_key_width(), top_total_key_height(), $dish_depth, $inverted_dish, $top_tilt / $key_height);
} }
else if ($dish_type == 2){ } else {
sideways_cylindrical_dish(top_total_key_width(), top_total_key_height(), $dish_depth, $inverted_dish, $top_tilt / $key_height); difference() {
children();
translate([$dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference]){
dish(top_total_key_width(), top_total_key_height(), $dish_depth, $inverted_dish, $top_tilt / $key_height);
}
} }
// else no dish
} }
} }
module keytext() { module keytext() {
extra_dish_depth = ($dish_type > 2) ? 0 : $dish_depth; extra_dish_depth = ($dish_type == "no dish") ? 0 : $dish_depth;
extra_inset_depth = ($inset_text) ? keytop_thickness/4 : 0; extra_inset_depth = ($inset_text) ? keytop_thickness/4 : 0;
translate([$dish_skew_x, $top_skew + $dish_skew_y, $total_depth - extra_dish_depth - extra_inset_depth]){ translate([$dish_skew_x, $top_skew + $dish_skew_y, $total_depth - extra_dish_depth - extra_inset_depth]){
@ -242,7 +200,7 @@ module keytext() {
} }
module connectors($stem_profile) { module connectors($stem_profile) {
difference() { intersection() {
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]){
@ -250,7 +208,8 @@ module connectors($stem_profile) {
} }
} }
} }
inside(); // used to be difference of the inside() but really I want intersection
shape(wall_thickness, keytop_thickness);
} }
} }
@ -348,7 +307,7 @@ example_key();
// Experimental stuff // Experimental stuff, except not really anymore
// corollary is roundedRect // corollary is roundedRect
// NOT 3D // NOT 3D
@ -392,3 +351,32 @@ module ISOEnterShapeHull(thickness_difference, depth_difference, modifier){
translate([unit(-.5), unit(-1) + 0.86]) fakeISOEnter(thickness_difference); translate([unit(-.5), unit(-1) + 0.86]) fakeISOEnter(thickness_difference);
} }
} }
// old stuff
// old non-sliced shape hull
/*module oldshape_hull(thickness_difference, depth_difference, modifier){
if ($ISOEnter) {
ISOEnterShapeHull(thickness_difference, depth_difference, modifier);
} else {
hull(){
// $bottom_key_width + ($key_length -1) * unit is the correct length of the
// key. only 1u of the key should be $bottom_key_width long; all others
// should be 1u
roundedRect([total_key_width() - thickness_difference, total_key_height() - thickness_difference, .001],$corner_radius);
//depth_difference outside of modifier because that doesnt make sense
translate([0,$top_skew,$total_depth * modifier - depth_difference]){
rotate([-$top_tilt / $key_height,0,0]){
roundedRect([
total_key_width() - thickness_difference - $width_difference * modifier,
total_key_height() - thickness_difference - $height_difference * modifier,
.001
],$corner_radius);
}
}
}
}
}*/

18620
key.scad.stl

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
// key.scad uses, it doesn't generate anything itself until the end. This // key.scad uses, it doesn't generate anything itself until the end. This
// makes it remain easy to use key.scad like before (except without key profiles) // makes it remain easy to use key.scad like before (except without key profiles)
// 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'll have to work around // special variables, but that's a limitation of SCAD we have to work around
/* TODO: /* TODO:
* fix stem inset * fix stem inset
@ -11,7 +11,6 @@
* make OEM profile from my WASD keyset * make OEM profile from my WASD keyset
* Pregenerated keysets for DCS (rounded tops too intense) WITH rounded spacebar [ ] 60% [ ] TKL [ ] full * Pregenerated keysets for DCS (rounded tops too intense) WITH rounded spacebar [ ] 60% [ ] TKL [ ] full
* Add inset stem to all profiles that need it (DCS?) * Add inset stem to all profiles that need it (DCS?)
* sideways cylindrical dish needs to be used for some spacebars but not others. currently none of them use it
* generate dishes via math? kind of hard * generate dishes via math? kind of hard
* customizer version where everything is copy/pasted in * customizer version where everything is copy/pasted in
*/ */
@ -28,7 +27,7 @@ $height_difference = 4;
$total_depth = 11.5; $total_depth = 11.5;
$top_tilt = -6; $top_tilt = -6;
$top_skew = 1.7; $top_skew = 1.7;
$dish_type = 0; $dish_type = "cylindrical";
$dish_depth = 1; $dish_depth = 1;
$dish_skew_x = 0; $dish_skew_x = 0;
$dish_skew_y = 0; $dish_skew_y = 0;
@ -55,7 +54,7 @@ module dcs_row(n=1) {
$bottom_key_height = 18.16; $bottom_key_height = 18.16;
$width_difference = 6; $width_difference = 6;
$height_difference = 4; $height_difference = 4;
$dish_type = 0; $dish_type = "cylindrical";
$dish_depth = 1; $dish_depth = 1;
$dish_skew_x = 0; $dish_skew_x = 0;
$dish_skew_y = 0; $dish_skew_y = 0;
@ -84,15 +83,49 @@ module dcs_row(n=1) {
} }
} }
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;
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) { module dsa_row(n=3) {
$bottom_key_width = 18.4; $bottom_key_width = 18.24; // 18.4;
$bottom_key_height = 18.4; $bottom_key_height = 18.24; // 18.4;
$width_difference = 5.7; $width_difference = 6; // 5.7;
$height_difference = 5.7; $height_difference = 6; // 5.7;
$total_depth = 8; $total_depth = 8;
$top_tilt = (n-1) * 7 - 14; $top_tilt = (n-1) * 7 - 14;
$top_skew = 0; $top_skew = 0;
$dish_type = 1; $dish_type = "spherical";
$dish_depth = 1.2; $dish_depth = 1.2;
$dish_skew_x = 0; $dish_skew_x = 0;
$dish_skew_y = 0; $dish_skew_y = 0;
@ -110,7 +143,7 @@ module sa_row(n=1) {
$bottom_key_height = 18.4; $bottom_key_height = 18.4;
$width_difference = 5.7; $width_difference = 5.7;
$height_difference = 5.7; $height_difference = 5.7;
$dish_type = 1; $dish_type = "spherical";
$dish_depth = 0.85; $dish_depth = 0.85;
$dish_skew_x = 0; $dish_skew_x = 0;
$dish_skew_y = 0; $dish_skew_y = 0;
@ -148,7 +181,7 @@ module g20() {
$total_depth = 6; $total_depth = 6;
$top_tilt = 2.5; $top_tilt = 2.5;
$top_skew = 0.75; $top_skew = 0.75;
$dish_type = 3; $dish_type = "no dish";
$dish_depth = 0; $dish_depth = 0;
$dish_skew_x = 0; $dish_skew_x = 0;
$dish_skew_y = 0; $dish_skew_y = 0;
@ -168,7 +201,7 @@ module fake_iso_enter() {
$total_depth = 7; $total_depth = 7;
$top_tilt = 0; $top_tilt = 0;
$top_skew = 1.75; $top_skew = 1.75;
$dish_type = 0; $dish_type = "cylindrical";
$dish_depth = 1; $dish_depth = 1;
$dish_skew_x = 0; $dish_skew_x = 0;
$dish_skew_y = 0; $dish_skew_y = 0;
@ -220,13 +253,18 @@ module stabilized(mm=12, vertical = false) {
} }
module dishless() { module dishless() {
$dish_type = 3; $dish_type = "no dish";
children(); children();
} }
module spacebar() { module spacebar() {
$inverted_dish = true; $inverted_dish = true;
if ($dish_type == "cylindrical") {
$dish_type = "sideways cylindrical";
6_25u() stabilized(mm=50) children(); 6_25u() stabilized(mm=50) children();
} else {
6_25u() stabilized(mm=50) children();
}
} }
module lshift() { module lshift() {
@ -341,6 +379,10 @@ module 6_25uh() {
uh(6.25) children(); uh(6.25) children();
} }
module filled() {
$stem_profile = "filled";
children();
}
module blank() { module blank() {
$stem_profile = "blank"; $stem_profile = "blank";
children(); children();
@ -364,24 +406,16 @@ module rounded_cherry() {
module legend(text, inset=false) { module legend(text, inset=false) {
$text=text; $text=text;
$inset_text = inset; $inset_text = inset;
children();
} }
translate([0,0,0]){ rows = [4,3,2,1,5];
for (x = [0:4]){
translate_u(0,(x-1)){
/*sa_row(5-x) blank() key();*/
translate_u(1) dcs_row(5-x) blank() key();
}
}
}
brimmed() translate_u(2.1) { translate_u(-.5, -.5) cube([40,115,.3]);
translate_u(0, 1.5) fake_iso_enter() cherry() key(); translate([0,0,.3]) {
dsa_row() alps() key(); dsa_row(3) filled() key();
translate_u(0, 3) g20() rounded_cherry() key(); for (y = [0:4]) {
translate_u(0, y+1) oem_row(rows[y]) filled() key();
}
} }
/*
sa_row(1) blank() key();*/
/*blank() dishless() rounded() sa_row(1) blank() key();*/

52096
keys.scad.stl Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,6 @@
// same syntax and semantics as built-in sphere, so should be a drop-in replacement // same syntax and semantics as built-in sphere, so should be a drop-in replacement
// it's a bit slow for large numbers of facets // it's a bit slow for large numbers of facets
module geodesic_sphere(r=-1, d=-1) { module geodesic_sphere(r=-1, d=-1) {
echo(r);
// if neither parameter specified, radius is taken to be 1 // if neither parameter specified, radius is taken to be 1
rad = r > 0 ? r : d > 0 ? d/2 : 1; rad = r > 0 ? r : d > 0 ? d/2 : 1;
@ -92,7 +90,6 @@ module geodesic_sphere(r=-1, d=-1) {
// actually a chord and not circumference but let's say it's close enough // actually a chord and not circumference but let's say it's close enough
// subdivision factor should be rad*2*tan(edge_subtend/2)/$fs // subdivision factor should be rad*2*tan(edge_subtend/2)/$fs
side_levels = ceil(log(rad*2*tan(edge_subtend/2)/$fs)/log(2)); side_levels = ceil(log(rad*2*tan(edge_subtend/2)/$fs)/log(2));
echo(side_levels);
// subdivision level based on $fn: (fragments around circumference, not total facets) // subdivision level based on $fn: (fragments around circumference, not total facets)
// icosahedron circumference around equator is about 5 (level 1 is exactly 10) // icosahedron circumference around equator is about 5 (level 1 is exactly 10)

View File

@ -97,6 +97,12 @@ module alps_stem(has_brim = false){
} }
} }
module filled_stem(has_brim=false) {
// 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);
}
//whole connector, alps or cherry, trimmed to fit //whole connector, alps or cherry, trimmed to fit
module connector(stem_profile, has_brim){ module connector(stem_profile, has_brim){
@ -106,5 +112,7 @@ module connector(stem_profile, has_brim){
cherry_stem_rounded(has_brim); cherry_stem_rounded(has_brim);
} else if (stem_profile == "cherry") { } else if (stem_profile == "cherry") {
cherry_stem(has_brim); cherry_stem(has_brim);
} else if (stem_profile == "filled") {
filled_stem();
} }
} }

View File

@ -37,7 +37,6 @@ module functional_scaled_extrude(height = 10, slices=[]) {
for (index = [0 : len(slices)-2]){ for (index = [0 : len(slices)-2]){
slice1 = slices[index]; slice1 = slices[index];
slice2 = slices[index+1]; slice2 = slices[index+1];
echo(slice2);
hull(){ hull(){
translate([0,0,nominal_height * index]) { translate([0,0,nominal_height * index]) {
scale(slice1) children(); scale(slice1) children();