adding supports, switching util to shape, and trying to abstract ISO enter shape

This commit is contained in:
Bob - Home - Windows 2017-11-12 13:01:17 -05:00
parent 035c4c52cf
commit 65d6656056
8 changed files with 196 additions and 393 deletions

View File

@ -1,5 +1,5 @@
include <libraries/geodesic_sphere.scad>
include <util.scad>
include <shapes.scad>
//geodesic looks much better, but runs very slow for anything above a 2u
geodesic=false;
@ -84,9 +84,6 @@ module spherical_dish(width, height, depth, inverted, tilt, txt=""){
}
}
}
// this line causes openscad to die. maybe re-enable when that doesn't happen instead of differencing the inside() when we add the dish to the shape()
/*translate([0,0,0]) roundedRect([width, height, depth], 1.5);*/
/*}*/
}
//the older, 'more accurate', and MUCH slower spherical dish.
@ -116,7 +113,4 @@ module old_spherical_dish(width, height, depth, inverted, tilt, txt=""){
}
}
}
// this line causes openscad to die. maybe re-enable when that doesn't happen instead of differencing the inside() when we add the dish to the shape()
/*translate([0,0,0]) roundedRect([width, height, depth], 1.5);*/
/*}*/
}

122
key.scad
View File

@ -1,5 +1,5 @@
// files
include <util.scad>
include <shapes.scad>
include <stems.scad>
include <dishes.scad>
include <libraries/geodesic_sphere.scad>
@ -53,9 +53,9 @@ 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]];
// whether or not we use the functions to generate an ISO enter
// NOTE this uses data in the profile so be sure to set the profile to ISO enter too
ISOEnter = false;
// 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'
@ -73,6 +73,12 @@ inset_text = false;
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;
@ -100,22 +106,29 @@ $minkowski_radius = .33;
// derived values. can't be variables if we want them to change when the special variables do
// actual mm key width and height
function total_key_width() = $bottom_key_width + (unit * ($key_length - 1));
function total_key_height() = $bottom_key_height + (unit * ($key_height - 1));
function total_key_width() = $bottom_key_width + unit * ($key_length - 1);
function total_key_height() = $bottom_key_height + unit * ($key_height - 1);
// actual mm key width and height at the top
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;
// 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);
// key shape including dish. used as the ouside and inside shape in key()
module shape(thickness_difference, depth_difference){
intersection(){
dished(depth_difference, $inverted_dish) {
color([.2667,.5882,1]) shape_hull(thickness_difference, depth_difference, 1);
color([.2667,.5882,1]) shape_hull(thickness_difference, depth_difference);
}
if ($inverted_dish) {
// larger shape_hull to clip off bits of the inverted dish
color([.5412, .4784, 1]) shape_hull(thickness_difference, 0, 1, 2);
color([.5412, .4784, 1]) shape_hull(thickness_difference, 0, 2);
}
}
}
@ -135,67 +148,71 @@ module rounded_shape() {
}
}
// basic key shape, no dish, no inside
// which is only used for dishing to cut the dish off correctly
// $height_difference used for keytop thickness
// extra_slices is a hack to make inverted dishes still work
module shape_hull(thickness_difference, depth_difference, extra_slices = 0){
render() {
if ($linear_extrude_shape) {
linear_extrude_shape_hull(thickness_difference, depth_difference);
} else {
hull_shape_hull(thickness_difference, depth_difference, extra_slices);
}
}
}
//corollary is shape_hull
module ISOEnterShapeHull(thickness_difference, depth_difference, modifier){
module linear_extrude_shape_hull(thickness_difference, depth_difference){
height = $total_depth - depth_difference;
width_scale = top_total_key_width() / total_key_width();
height_scale = top_total_key_height() / total_key_height();
translate([0,19.05 * 0.5,0])
translate([0,$linear_extrude_height_adjustment,0]){
linear_extrude(height = height, scale = [width_scale, height_scale]) {
// TODO completely making up these numbers here
// 0.86mm is from the unit function, 18.16 - 19.02. no idea what the 18 is, shows me for not leaving better comments
translate([0,-19.05 * 0.5,0])
fakeISOEnter(thickness_difference/2);
translate([0,-$linear_extrude_height_adjustment,0]){
key_shape(total_key_width(), total_key_height(), thickness_difference, thickness_difference, $corner_radius);
}
}
}
}
// basic key shape, no dish, no inside
// modifier multiplies the height and top differences of the shape,
// which is only used for dishing to cut the dish off correctly
// $height_difference used for keytop thickness
// extra_slices is a hack to make inverted dishes still work
module shape_hull(thickness_difference, depth_difference, modifier, extra_slices = 0){
render() {
if ($ISOEnter) {
ISOEnterShapeHull(thickness_difference, depth_difference, modifier);
} else {
module hull_shape_hull(thickness_difference, depth_difference, extra_slices = 0) {
slices = 10;
for (index = [0:$height_slices - 1 + extra_slices]) {
hull() {
shape_slice(index, $height_slices, thickness_difference, depth_difference, modifier);
shape_slice(index + 1, $height_slices, thickness_difference, depth_difference, modifier);
}
}
shape_slice(index / $height_slices, thickness_difference, depth_difference);
shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
}
}
}
module shape_slice(index, total, thickness_difference, depth_difference, modifier) {
progress = index / (total);
// TODO extract these out somehow so you can make custom rounded sides
module shape_slice(progress, thickness_difference, depth_difference) {
// makes the sides bow
extra_side_size = $enable_side_sculpting ? (total - index)/4 : 0;
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 ? pow(progress, 2) : 0;
extra_corner_size = $enable_side_sculpting ? corner_sculpting(progress) : 0;
// width and height differences for this slice
extra_width_difference = ($width_difference - extra_side_size) * progress * modifier;
extra_height_difference = ($height_difference - extra_side_size) * progress * modifier;
// 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;
skew_this_slice = $top_skew * progress;
depth_this_slice = ($total_depth - depth_difference) * progress;
tilt_this_slice = -$top_tilt / $key_height * progress;
translate([
0,
$top_skew * progress,
($total_depth * modifier - depth_difference) * progress
]) rotate([-$top_tilt / $key_height * progress,0,0]){
roundedRect([
total_key_width() - thickness_difference - extra_width_difference,
total_key_height() - thickness_difference - extra_height_difference,
.001
],$corner_radius + extra_corner_size);
translate([0, skew_this_slice, depth_this_slice]) {
rotate([tilt_this_slice,0,0]){
linear_extrude(height = 0.001){
key_shape(
total_key_width(),
total_key_height(),
thickness_difference+extra_width_this_slice,
thickness_difference+extra_height_this_slice,
$corner_radius + extra_corner_size
);
}
}
}
}
@ -244,7 +261,7 @@ module connectors() {
for (connector_pos = $connectors) {
translate([connector_pos[0], connector_pos[1], $stem_inset]) {
rotate([0, 0, $stem_rotation]){
color([1, .6941, .2]) connector($stem_profile, $has_brim, $slop);
color([1, .6941, .2]) connector($stem_profile, $has_brim, $slop, $support_type);
}
}
}
@ -278,7 +295,7 @@ module keytop() {
} else {
shape(0, 0);
}
shape(wall_thickness, keytop_thickness);
translate([0,0,-0.01]) shape(wall_thickness, keytop_thickness);
}
}
@ -319,7 +336,7 @@ module example_key(){
$has_brim = has_brim;
$inverted_dish = inverted_dish;
$connectors = connectors;
$ISOEnter = ISOEnter;
$linear_extrude_shape = linear_extrude_shape;
$rounded_key = rounded_key;
$stem_profile = stem_profile;
$stem_inset = stem_inset;
@ -330,6 +347,9 @@ module example_key(){
$height_slices = height_slices;
$enable_side_sculpting = enable_side_sculpting;
$slop = slop;
$support_type = support_type;
$linear_extrude_height_adjustment = linear_extrude_height_adjustment;
key();
}

View File

@ -1,226 +0,0 @@
solid OpenSCAD_Model
facet normal -1 0 0
outer loop
vertex 50 0 0
vertex 50 53.05 30
vertex 50 53.05 0
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 50 53.05 30
vertex 50 0 0
vertex 50 0 30
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 103.05 53.05 30
vertex 101.05 51.05 30
vertex 103.05 0 30
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 103.05 53.05 30
vertex 52 51.05 30
vertex 101.05 51.05 30
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 52 51.05 30
vertex 50 53.05 30
vertex 52 2 30
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 50 53.05 30
vertex 52 51.05 30
vertex 103.05 53.05 30
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 101.05 2 30
vertex 103.05 0 30
vertex 101.05 51.05 30
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 52 2 30
vertex 103.05 0 30
vertex 101.05 2 30
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 52 2 30
vertex 50 0 30
vertex 103.05 0 30
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 50 0 30
vertex 52 2 30
vertex 50 53.05 30
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 103.05 0 30
vertex 103.05 53.05 0
vertex 103.05 53.05 30
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 103.05 53.05 0
vertex 103.05 0 30
vertex 103.05 0 0
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 103.05 53.05 0
vertex 50 53.05 30
vertex 103.05 53.05 30
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 50 53.05 30
vertex 103.05 53.05 0
vertex 50 53.05 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 103.05 0 0
vertex 101.05 2 0
vertex 103.05 53.05 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 103.05 0 0
vertex 52 2 0
vertex 101.05 2 0
endloop
endfacet
facet normal -0 0 -1
outer loop
vertex 52 2 0
vertex 50 0 0
vertex 52 51.05 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 50 0 0
vertex 52 2 0
vertex 103.05 0 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 101.05 51.05 0
vertex 103.05 53.05 0
vertex 101.05 2 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 52 51.05 0
vertex 103.05 53.05 0
vertex 101.05 51.05 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 52 51.05 0
vertex 50 53.05 0
vertex 103.05 53.05 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 50 53.05 0
vertex 52 51.05 0
vertex 50 0 0
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 50 0 0
vertex 103.05 0 30
vertex 50 0 30
endloop
endfacet
facet normal 0 -1 -0
outer loop
vertex 103.05 0 30
vertex 50 0 0
vertex 103.05 0 0
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 52 2 30
vertex 52 51.05 0
vertex 52 51.05 30
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 52 51.05 0
vertex 52 2 30
vertex 52 2 0
endloop
endfacet
facet normal -1 0 0
outer loop
vertex 101.05 2 0
vertex 101.05 51.05 30
vertex 101.05 51.05 0
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 101.05 51.05 30
vertex 101.05 2 0
vertex 101.05 2 30
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 52 51.05 0
vertex 101.05 51.05 30
vertex 52 51.05 30
endloop
endfacet
facet normal 0 -1 -0
outer loop
vertex 101.05 51.05 30
vertex 52 51.05 0
vertex 101.05 51.05 0
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 101.05 2 0
vertex 52 2 30
vertex 101.05 2 30
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 52 2 30
vertex 101.05 2 0
vertex 52 2 0
endloop
endfacet
endsolid OpenSCAD_Model

View File

@ -35,7 +35,7 @@ $key_height = 1;
$has_brim = false;
$inverted_dish = false;
$connectors = [[0,0]];
$ISOEnter = false;
$linear_extrude_shape = false;
$rounded_key = false;
$stem_profile = 0;
$stem_inset = 0;
@ -45,6 +45,9 @@ $inset_text = false;
$corner_radius = 1;
$height_slices = 1;
$slop = 0.3;
$support_type = "bars";
$key_shape_type = "normal";
$linear_extrude_height_adjustment = 0;
// key profile definitions
@ -206,7 +209,10 @@ module fake_iso_enter() {
$dish_depth = 1;
$dish_skew_x = 0;
$dish_skew_y = 0;
$ISOEnter = true;
$key_shape_type = "iso_enter";
$linear_extrude_shape = true;
$linear_extrude_height_adjustment = 19.05 * 0.5;
stabilized(vertical=true) {
children();
@ -419,4 +425,6 @@ module legend(text, inset=false) {
}
translate_u(1.125, 0.5) fake_iso_enter() cherry() key();
translate_u(0, 0) dcs_row(2) cherry() key();
translate_u(0, 0) sa_row(2) legend("q", inset=true) cherry() {
key();
}

53
shapes.scad Normal file
View File

@ -0,0 +1,53 @@
$fs=.1;
unit = 19.05;
module key_shape(width, height, width_difference, height_difference, corner_size) {
if ($key_shape_type == "iso_enter") {
fakeISOEnter(width_difference/2);
} else if ($key_shape_type == "normal") {
roundedSquare([width - width_difference, height - height_difference], corner_size);
} else if ($key_shape_type == "circle") {
circle(d=width - width_difference);
}
}
// centered
module roundedRect(size, radius, center=true) {
linear_extrude(height = size[2]){
roundedSquare([size[0], size[1]], radius, center=center);
}
}
module roundedSquare(size, radius, center = true) {
offset(r=radius){
square([size[0] - radius * 2, size[1] - radius * 2], center=center);
}
}
// corollary is roundedSquare
// NOT 3D
module fakeISOEnter(thickness_difference = 0){
// t is all modifications to the polygon array
// t used to contain a corner radius adjustment, but due to
// the offset we need that expansion back
t = (thickness_difference - (unit - 18.16));
function unit(length) = unit * length;
pointArray = [
[unit(-.625) + t, unit(-1) + t],
[unit(0.625) - t, unit(-1) + t],
[unit(0.625) - t, unit(1) - t],
[unit(-0.875) + t, unit(1) - t],
[unit(-0.875) + t, unit(0) + t],
[unit(-0.625) + t, unit(0) + t]
];
minkowski(){
circle(r=$corner_radius);
// gives us rounded inner corner
offset(r=-$corner_radius*2) {
polygon(points=pointArray);
}
}
}

View File

@ -1,6 +1,22 @@
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();
}
}
stem_depth = 24;
module brim(has_brim) {
//brim radius. 11 ensconces normal keycap stem in normal keycap
@ -11,10 +27,7 @@ module brim(has_brim) {
if (has_brim) color([0,1,0]) cube([brim_radius, brim_radius, brim_depth]);
}
module cherry_stem(has_brim, slop) {
echo(slop);
module cherry_stem(has_brim, slop, support_type) {
stem_width = 7.2 - slop * 2;
stem_height = 5.5 - slop * 2;
@ -32,20 +45,23 @@ module cherry_stem(has_brim, slop) {
translate([0,0,stem_inset]) {
brim(has_brim);
linear_extrude(height = cross_depth) {
difference(){
linear_extrude(height = stem_depth) {
roundedSquare(stem, 1, center=true);
off = 0;
offset(r = off){
square(vertical_cross + [-off * 2,-off * 2], center=true);
square(horizontal_cross + [-off * 2,-off * 2], center=true);
}
linear_extrude(height = cross_depth) {
square(vertical_cross, center=true);
square(horizontal_cross, center=true);
}
}
// flared support
// 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,cross_depth]) linear_extrude(height=(stem_depth - cross_depth), scale = [6,8]){
roundedSquare([stem_width, stem_height], 1, center=true);
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]);
}
}
}
@ -99,18 +115,3 @@ module filled_stem() {
// so we can't make this work for all keys
cube(100, center=true);
}
//whole connector, alps or cherry, trimmed to fit
module connector(stem_profile, has_brim, slop){
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);
} else if (stem_profile == "filled") {
filled_stem();
}
}

24
supports.scad Normal file
View File

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

View File

@ -1,71 +0,0 @@
$fs=.1;
// centered
module roundedRect(size, radius, center=true) {
linear_extrude(height = size[2]){
roundedSquare([size[0], size[1]], radius, center=center);
}
}
module roundedSquare(size, radius, center = true) {
offset(r=radius){
square([size[0] - radius * 2, size[1] - radius * 2], center=center);
}
}
// corollary is roundedRect
// NOT 3D
module fakeISOEnter(thickness_difference = 0){
// 1u is the space taken upy by a 1u keycap.
// unit is the space taken up by a unit space for a keycap.
// formula is 1u + unit *(length - 1)
// t is all modifications to the polygon array
// t used to contain a corner radius adjustment, but due to
// the offset we need that expansion back
t = (thickness_difference - (19.05 - 18.16));
function unit(length) = 19.05 * length;
pointArray = [
[unit(-.625) + t, unit(-1) + t],
[unit(0.625) - t, unit(-1) + t],
[unit(0.625) - t, unit(1) - t],
[unit(-0.875) + t, unit(1) - t],
[unit(-0.875) + t, unit(0) + t],
[unit(-0.625) + t, unit(0) + t]
];
minkowski(){
circle(r=$corner_radius);
// gives us rounded inner corner
offset(r=-$corner_radius*2) {
polygon(points=pointArray);
}
}
}
module functional_scaled_extrude(height = 10, slices=[]) {
nominal_height = height / (len(slices) - 1);
for (index = [0 : len(slices)-2]){
slice1 = slices[index];
slice2 = slices[index+1];
hull(){
translate([0,0,nominal_height * index]) {
scale(slice1) children();
}
translate([0,0,nominal_height * (index + 1)]) {
scale(slice2) children();
}
}
}
}
module progressive_hull() {
for (i = [0 : $children-2]){
hull(){
children(i);
children(i+1);
}
}
}