mirror of
https://github.com/rsheldiii/KeyV2.git
synced 2026-01-14 14:27:55 -05:00
Compare commits
53 Commits
v2/propoga
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19f0d2faad | ||
|
|
7a5d2f00ab | ||
|
|
0a29b1bff8 | ||
|
|
5be792e270 | ||
|
|
b172788ddd | ||
|
|
bfed8b8779 | ||
|
|
46833f9e42 | ||
|
|
8b0a6c57f1 | ||
|
|
6b444fd5d3 | ||
|
|
e88a398f7a | ||
|
|
1907b87dc5 | ||
|
|
1935944ec5 | ||
|
|
fe960c2f2a | ||
|
|
9665d5d6a0 | ||
|
|
7907d2cd4e | ||
|
|
80c35b04c3 | ||
|
|
93f883036f | ||
|
|
c4b622efc6 | ||
|
|
4c6dbc4306 | ||
|
|
8fdd3dcb43 | ||
|
|
b0eb0d030c | ||
|
|
ca3daeec64 | ||
|
|
9842ce6ff4 | ||
|
|
ec44ef76de | ||
|
|
19de89dc6e | ||
|
|
2b8a238f8a | ||
|
|
ed0c201894 | ||
|
|
703015dc51 | ||
|
|
f0e339966f | ||
|
|
263bd8ebbf | ||
|
|
1c3960aaff | ||
|
|
4bce68dfbb | ||
|
|
dbe5bca1a9 | ||
|
|
0c9d05e270 | ||
|
|
8ef5bad891 | ||
|
|
1a8dd314e4 | ||
|
|
cc8892364c | ||
|
|
2429384b51 | ||
|
|
1a10d1e5bc | ||
|
|
41381ed376 | ||
|
|
38bfbfa61c | ||
|
|
2d03e5dd4b | ||
|
|
665698771f | ||
|
|
1f1f6a62d2 | ||
|
|
fdce624cb1 | ||
|
|
762e45ba3d | ||
|
|
d7ea2bf7cc | ||
|
|
3fca4e26ca | ||
|
|
cdf75654a6 | ||
|
|
e7b92cf52b | ||
|
|
29f5cd2468 | ||
|
|
d3c26dfaca | ||
|
|
13520c54e3 |
@@ -198,9 +198,7 @@ Prints from this library are still challenging, despite all efforts to the contr
|
||||
That's it, if you have any questions feel free to open an issue or leave a comment on thingiverse!
|
||||
|
||||
## TODO:
|
||||
* replace linear_extrude_shape_hull with skin_extrude_shape_hull or something, to enable concave extrusions
|
||||
* replace current ISO enter shape with one that works for `skin()`
|
||||
* generate dishes via math?
|
||||
moved to [TODO doc](./TODO.md)
|
||||
|
||||
## Contributions welcome
|
||||
|
||||
|
||||
10
TODO.md
10
TODO.md
@@ -1,7 +1,11 @@
|
||||
TODO:
|
||||
* Make flat stem support default
|
||||
* make flat inner shape default
|
||||
* support repositioning to print on the back surface of the keycap
|
||||
* implement key_shape_at_progress which allows you to query for the exact 2d outline of the keycap at a given height
|
||||
* this makes certain functions easier - building the envelope for instance
|
||||
* requires breaking out shape_slice, and creating a polygon of the skin_shape_slice slices
|
||||
* dishes add / remove height from keycaps, particularly spherical dishes
|
||||
* a bandaid solution would be to allow you to modify where the keytop is along the progression of the keycap
|
||||
* you can't just set a new total_depth because of how width_difference and height_difference work
|
||||
* the true solution would be to rewrite how the dishes work to make them very graduated at the edges
|
||||
* implement regular polygon for skin extrusions
|
||||
* switch to skin-shaped extrusions by default
|
||||
* kailh choc has a non-square key unit; should I get that working for layouts etc?
|
||||
|
||||
13192
customizer.scad
13192
customizer.scad
File diff suppressed because it is too large
Load Diff
@@ -17,4 +17,4 @@ dcs_row(5) legend("⇪", size=9) key();
|
||||
} */
|
||||
|
||||
// example layout
|
||||
/* preonic_default("dcs"); */
|
||||
/* preonic_default("dcs") key(); */
|
||||
|
||||
@@ -4,6 +4,8 @@ include <dishes/cylindrical.scad>
|
||||
include <dishes/old_spherical.scad>
|
||||
include <dishes/sideways_cylindrical.scad>
|
||||
include <dishes/spherical.scad>
|
||||
include <dishes/squared_spherical.scad>
|
||||
include <dishes/squared_scoop.scad>
|
||||
include <dishes/flat.scad>
|
||||
include <dishes/3d_surface.scad>
|
||||
|
||||
@@ -14,20 +16,22 @@ geodesic=false;
|
||||
module dish(width, height, depth, inverted) {
|
||||
if($dish_type == "cylindrical"){
|
||||
cylindrical_dish(width, height, depth, inverted);
|
||||
}
|
||||
else if ($dish_type == "spherical") {
|
||||
} else if ($dish_type == "spherical") {
|
||||
spherical_dish(width, height, depth, inverted);
|
||||
}
|
||||
else if ($dish_type == "sideways cylindrical"){
|
||||
} else if ($dish_type == "sideways cylindrical"){
|
||||
sideways_cylindrical_dish(width, height, depth, inverted);
|
||||
} else if ($dish_type == "old spherical") {
|
||||
old_spherical_dish(width, height, depth, inverted);
|
||||
} else if ($dish_type == "3d_surface") {
|
||||
} else if ($dish_type == "3d surface") {
|
||||
3d_surface_dish(width, height, depth, inverted);
|
||||
} else if ($dish_type == "flat") {
|
||||
flat_dish(width, height, depth, inverted);
|
||||
} else if ($dish_type == "disable") {
|
||||
// else no dish
|
||||
} else if ($dish_type == "squared spherical") {
|
||||
squared_spherical_dish(width, height, depth, inverted=inverted);
|
||||
} else if ($dish_type == "squared scoop") {
|
||||
squared_scoop_dish(width, height, depth, inverted=inverted);
|
||||
} else {
|
||||
echo("WARN: $dish_type unsupported");
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@ module 3d_surface_dish(width, height, depth, inverted) {
|
||||
// it doesn't have to be dead reckoning for anything but sculpted sides
|
||||
// we know the angle of the sides from the width difference, height difference,
|
||||
// skew and tilt of the top. it's a pain to calculate though
|
||||
scale_factor = 1.1;
|
||||
scale_factor = 1.05;
|
||||
// the edges on this behave differently than with the previous dish implementations
|
||||
scale([width*scale_factor/$3d_surface_size/2,height*scale_factor/$3d_surface_size/2,depth]) rotate([inverted ? 0:180,0,180]) polar_3d_surface(bottom=-10);
|
||||
scale([width*scale_factor/$3d_surface_size/2,height*scale_factor/$3d_surface_size/2,depth])
|
||||
rotate([inverted ? 0:180,0,180])
|
||||
polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-10);
|
||||
/* %scale([width*scale_factor/$3d_surface_size/2,height*scale_factor/$3d_surface_size/2,depth]) rotate([180,0,0]) polar_3d_surface(bottom=-10); */
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
module spherical_dish(width, height, depth, inverted){
|
||||
// these variables take into account corner_radius and corner_sculpting, resulting in a more correct dish
|
||||
// they don't fix the core issue though (dishes adding / subtracting height on the edges of the keycap), so I've disabled them
|
||||
// new_width = $key_shape_type == "sculpted_square" ? width - distance_between_circumscribed_and_inscribed($corner_radius + $corner_sculpting(1)) : width;
|
||||
// new_height = $key_shape_type == "sculpted_square" ? height - distance_between_circumscribed_and_inscribed($corner_radius + $corner_sculpting(1)) : height;
|
||||
|
||||
//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
|
||||
|
||||
34
src/dishes/squared_scoop.scad
Normal file
34
src/dishes/squared_scoop.scad
Normal file
@@ -0,0 +1,34 @@
|
||||
module squared_scoop_dish(height, width, depth, r=0.5, inverted=false, num=4, den=5){
|
||||
// changable numerator/denoninator on where to place the square's corners
|
||||
// for example, num=2, den=3 means the dish will happen at 1/3 and 2/3 the
|
||||
// width and the height. Defaults to 4/5. Customizable when calling
|
||||
// this module
|
||||
//
|
||||
// This was initially intended for the scoop on the HiPro, since that's what
|
||||
// it uses. Use "hipro_row()" if that's what you'd like. However, I do NOT
|
||||
// know how close the inner square is for the HiPro keycaps. In fact, it could
|
||||
// just be a sphere, in which the "squared spherical" scoop is more appropriate.
|
||||
// If, however, it the "squared scoop" makes sense, you can adjust where the square
|
||||
// lands with the num (numerator) and den (denominator) variables. For instance,
|
||||
// "3" and "4" mean 3/4 of the width/height is where the flat part starts.
|
||||
|
||||
chord = pow(pow(height/2, 2) + pow(width/2, 2),0.5);
|
||||
direction = inverted ? -1 : 1;
|
||||
|
||||
//This is the set of points to hull around for the scoop
|
||||
points=[
|
||||
[height/den - height/2, width/den - width/2, -chord],
|
||||
[num*height/den - height/2, width/den - width/2, -chord],
|
||||
[height/den - height/2, num*width/den - width/2, -chord],
|
||||
[num*height/den - height/2, num*width/den - width/2, -chord]
|
||||
];
|
||||
|
||||
resize([height,width,depth])
|
||||
hull() {
|
||||
shape_slice(1,0,0);
|
||||
for(i=[0:len(points)-1]) {
|
||||
translate(points[i])
|
||||
sphere(r=r,$fn=64);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
src/dishes/squared_spherical.scad
Normal file
22
src/dishes/squared_spherical.scad
Normal file
@@ -0,0 +1,22 @@
|
||||
module squared_spherical_dish(width, height, depth, inverted=false) {
|
||||
chord = pow(pow(height / 2, 2) + pow(width / 2, 2),0.5);
|
||||
direction = inverted ? -1 : 1;
|
||||
r=max(height,width,chord) / 5;
|
||||
// ^^^^^ Nothing special about this code to figure out r.
|
||||
// I just modeled up 1u, 1.25u, 1.5u, 2u, 2.25u, and 2.75u
|
||||
// keys and messed around until I came up with something that
|
||||
// looked reasonable for all key sizes. This just seems to work
|
||||
// well for all sizes
|
||||
|
||||
translate([-width / 2, -height / 2, 0 * direction]) {
|
||||
resize([width, height, depth])
|
||||
hull() {
|
||||
cube([chord,chord,0.001]);
|
||||
// Use something larger in this translate than -depth
|
||||
// (like -chord) if you want more of a defined circle
|
||||
// in the keywell
|
||||
translate([chord/2, chord/2, -depth])
|
||||
sphere(r=r, $fn=128);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
module keytext(text, position, font_size, depth) {
|
||||
module keytext(text, position, font_size, font_face, depth) {
|
||||
woffset = (top_total_key_width()/3.5) * position[0];
|
||||
hoffset = (top_total_key_height()/3.5) * -position[1];
|
||||
translate([woffset, hoffset, -depth]){
|
||||
color($tertiary_color) linear_extrude(height=$dish_depth + depth){
|
||||
text(text=text, font=$font, size=font_size, halign="center", valign="center");
|
||||
text(text=text, font=font_face, size=font_size, halign="center", valign="center");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,14 +12,14 @@ module legends(depth=0) {
|
||||
if (len($front_legends) > 0) {
|
||||
front_of_key() {
|
||||
for (i=[0:len($front_legends)-1]) {
|
||||
rotate([90,0,0]) keytext($front_legends[i][0], $front_legends[i][1], $front_legends[i][2], depth);
|
||||
rotate([90,0,0]) keytext($front_legends[i][0], $front_legends[i][1], $front_legends[i][2], $front_legends[i][3], depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (len($legends) > 0) {
|
||||
top_of_key() {
|
||||
for (i=[0:len($legends)-1]) {
|
||||
keytext($legends[i][0], $legends[i][1], $legends[i][2], depth);
|
||||
keytext($legends[i][0], $legends[i][1], $legends[i][2], $legends[i][3], depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
include <constants.scad>
|
||||
include <settings.scad>
|
||||
|
||||
// I use functions when I need to compute special variables off of other special variables
|
||||
// functions need to be explicitly included, unlike special variables, which
|
||||
// just need to have been set before they are used. hence this file
|
||||
|
||||
function stem_height() = $total_depth - $dish_depth - $stem_inset;
|
||||
function stem_height() = $total_depth - ($dish_depth * ($inverted_dish ? -1 : 1)) - $stem_inset;
|
||||
|
||||
// cherry stem dimensions
|
||||
function outer_cherry_stem(slop) = [7.2 - slop * 2, 5.5 - slop * 2];
|
||||
@@ -23,6 +24,10 @@ function cherry_cross(slop, extra_vertical = 0) = [
|
||||
[1.15 + slop / 3, 4.23 + extra_vertical + slop / 3 + SMALLEST_POSSIBLE],
|
||||
];
|
||||
|
||||
// TODO add side_sculpting
|
||||
function key_width_at_progress(progress = 0) = $bottom_key_width + ($unit * ($key_length - 1)) - $width_difference;
|
||||
function key_height_at_progress(progress = 0) = $bottom_key_height + ($unit * ($key_height - 1)) - $height_difference + $side_sculpting(progress);
|
||||
|
||||
// actual mm key width and height
|
||||
function total_key_width(delta = 0) = $bottom_key_width + $unit * ($key_length - 1) - delta;
|
||||
function total_key_height(delta = 0) = $bottom_key_height + $unit * ($key_height - 1) - delta;
|
||||
@@ -43,30 +48,11 @@ function vertical_inclination_due_to_top_tilt() = sin($top_tilt) * (top_total_ke
|
||||
// I derived this through a bunch of trig reductions I don't really understand.
|
||||
function extra_keytop_length_for_flat_sides() = ($width_difference * vertical_inclination_due_to_top_tilt()) / ($total_depth);
|
||||
|
||||
// 3d surface functions (still in beta)
|
||||
|
||||
// monotonically increasing function that distributes the points of the surface mesh
|
||||
// only for polar_3d_surface right now
|
||||
// if it's linear it's a grid. sin(dim) * size concentrates detail around the edges
|
||||
function surface_distribution_function(dim, size) = sin(dim) * size;
|
||||
|
||||
// the function that actually determines what the surface is.
|
||||
// feel free to override, the last one wins
|
||||
|
||||
// debug
|
||||
function surface_function(x,y) = 1;
|
||||
// cylindrical
|
||||
function surface_function(x,y) = (sin(acos(x/$3d_surface_size)));
|
||||
// spherical
|
||||
function surface_function(x,y) = (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));
|
||||
// ripples
|
||||
/* function surface_function(x,y) = cos(pow(pow(x,2)+pow(y,2),0.5)*10)/4+0.75; */
|
||||
// Rosenbrock's banana
|
||||
/* function surface_function(x,y) = (pow(1-(x/100), 2) + 100 * pow((y/100)-pow((x/100),2),2))/200 + 0.1; */
|
||||
// y=x revolved around the y axis
|
||||
/* function surface_function(x,y) = 1/(pow(pow(x,2)+pow(y,2),0.5)/100 + .01); */
|
||||
/* function surface_function(x,y) = sin(rands(0,90,1,x+y)[0]); */
|
||||
// adds uniform rounding radius for round-anything polyRound
|
||||
function add_rounding(p, radius)=[for(i=[0:len(p)-1])[p[i].x,p[i].y, radius]];
|
||||
// computes millimeter length from unit length
|
||||
function unit_length(length) = $unit * (length - 1) + 18.16;
|
||||
|
||||
// if you have a radius of an inscribed circle, this function gives you the extra length for the radius of the circumscribed circle
|
||||
// and vice versa. used to find the edge of a rounded_square
|
||||
function distance_between_circumscribed_and_inscribed(radius) = (pow(2, 0.5) - 1) * radius;
|
||||
@@ -1,13 +1,13 @@
|
||||
module hull_shape_hull(thickness_difference, depth_difference, extra_slices = 0) {
|
||||
for (index = [0:$height_slices - 1 + extra_slices]) {
|
||||
hull() {
|
||||
shape_slice(index / $height_slices, thickness_difference, depth_difference);
|
||||
shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
|
||||
placed_shape_slice(index / $height_slices, thickness_difference, depth_difference);
|
||||
placed_shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module shape_slice(progress, thickness_difference, depth_difference) {
|
||||
module placed_shape_slice(progress, thickness_difference, depth_difference) {
|
||||
skew_this_slice = $top_skew * progress;
|
||||
x_skew_this_slice = $top_skew_x * progress;
|
||||
|
||||
@@ -18,16 +18,20 @@ module shape_slice(progress, thickness_difference, depth_difference) {
|
||||
|
||||
translate([x_skew_this_slice, skew_this_slice, depth_this_slice]) {
|
||||
rotate([tilt_this_slice,y_tilt_this_slice,0]){
|
||||
linear_extrude(height = SMALLEST_POSSIBLE, scale = 1){
|
||||
key_shape(
|
||||
[
|
||||
total_key_width(thickness_difference),
|
||||
total_key_height(thickness_difference)
|
||||
],
|
||||
[$width_difference, $height_difference],
|
||||
progress
|
||||
);
|
||||
}
|
||||
shape_slice(progress, thickness_difference, depth_difference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module shape_slice(progress, thickness_difference, depth_difference) {
|
||||
linear_extrude(height = SMALLEST_POSSIBLE, scale = 1){
|
||||
key_shape(
|
||||
[
|
||||
total_key_width(thickness_difference),
|
||||
total_key_height(thickness_difference)
|
||||
],
|
||||
[$width_difference, $height_difference],
|
||||
progress
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
37
src/key.scad
37
src/key.scad
@@ -17,14 +17,13 @@ use <libraries/scad-utils/lists.scad>
|
||||
use <libraries/scad-utils/shapes.scad>
|
||||
use <libraries/skin.scad>
|
||||
|
||||
// key shape including dish. used as the ouside and inside shape in hollow_key(). allows for itself to be shrunk in depth and width / height
|
||||
// key shape including dish. used as the outside and inside shape in hollow_key(). allows for itself to be shrunk in depth and width / height
|
||||
module shape(thickness_difference, depth_difference=0){
|
||||
dished(depth_difference, $inverted_dish) {
|
||||
color($primary_color) shape_hull(thickness_difference, depth_difference, $inverted_dish ? 200 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Not currently used due to CGAL errors. Rounds the shape via minkowski
|
||||
module rounded_shape() {
|
||||
color($primary_color) minkowski(){
|
||||
// half minkowski in the z direction
|
||||
@@ -47,12 +46,13 @@ module minkowski_object() {
|
||||
}
|
||||
}
|
||||
|
||||
module envelope(depth_difference=0) {
|
||||
s = 1.5;
|
||||
module envelope(depth_difference=0, extra_floor_depth=0) {
|
||||
size = 1.5;
|
||||
|
||||
hull(){
|
||||
cube([total_key_width() * s, total_key_height() * s, 0.01], center = true);
|
||||
translate([0,0,extra_floor_depth]) cube([key_width_at_progress(extra_floor_depth / $total_depth) * size, key_height_at_progress(extra_floor_depth / $total_depth) * size, 0.01], center = true);
|
||||
top_placement(SMALLEST_POSSIBLE + depth_difference){
|
||||
cube([top_total_key_width() * s, top_total_key_height() * s, 0.01], center = true);
|
||||
cube([top_total_key_width() * size, top_total_key_height() * size, 0.01], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,12 +65,12 @@ module dished(depth_difference = 0, inverted = false) {
|
||||
children();
|
||||
difference(){
|
||||
union() {
|
||||
// envelope is needed to "fill in" the rest of the keycap
|
||||
envelope(depth_difference);
|
||||
// envelope is needed to "fill in" the rest of the keycap. intersections with small objects are much faster than differences with large objects
|
||||
envelope(depth_difference, $stem_inset);
|
||||
if (inverted) top_placement(depth_difference) color($secondary_color) _dish(inverted);
|
||||
}
|
||||
if (!inverted) top_placement(depth_difference) color($secondary_color) _dish(inverted);
|
||||
/* %top_placement(depth_difference) _dish(); */
|
||||
// %top_placement(depth_difference) _dish();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,7 @@ module dished(depth_difference = 0, inverted = false) {
|
||||
module _dish(inverted=$inverted_dish) {
|
||||
translate([$dish_offset_x,0,0]) color($secondary_color)
|
||||
dish(top_total_key_width() + $dish_overdraw_width, top_total_key_height() + $dish_overdraw_height, $dish_depth, inverted);
|
||||
// %dish(top_total_key_width() + $dish_overdraw_width, top_total_key_height() + $dish_overdraw_height, $dish_depth, inverted);
|
||||
}
|
||||
|
||||
// puts its children at each keystem position provided
|
||||
@@ -113,9 +114,9 @@ module top_placement(depth_difference=0) {
|
||||
top_tilt_by_height = -$top_tilt / $key_height;
|
||||
top_tilt_y_by_length = $double_sculpted ? (-$top_tilt_y / $key_length) : 0;
|
||||
|
||||
minkowski_height = $rounded_key ? $minkowski_radius : 0;
|
||||
// minkowski_height = $rounded_key ? $minkowski_radius : 0;
|
||||
|
||||
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference + minkowski_height/2]){
|
||||
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference]){
|
||||
rotate([top_tilt_by_height, top_tilt_y_by_length,0]){
|
||||
children();
|
||||
}
|
||||
@@ -235,10 +236,12 @@ module outer_total_shape(inset=false) {
|
||||
// takes all the bits and glues them together. requires configuration with special variables.
|
||||
module key(inset=false) {
|
||||
difference(){
|
||||
outer_total_shape(inset);
|
||||
outer_total_shape(inset) {
|
||||
children();
|
||||
};
|
||||
|
||||
if ($inner_shape_type != "disable") {
|
||||
translate([0,0,-SMALLEST_POSSIBLE]) {
|
||||
translate([0,0,-SMALLEST_POSSIBLE]) { // avoids moire
|
||||
inner_total_shape();
|
||||
}
|
||||
}
|
||||
@@ -248,10 +251,12 @@ module key(inset=false) {
|
||||
};
|
||||
}
|
||||
|
||||
// if $stem_inset is less than zero, we add the
|
||||
// semi-hack to make sure negative inset stems don't poke through the top of the keycap
|
||||
if ($stem_inset < 0) {
|
||||
stems_and_stabilizers();
|
||||
}
|
||||
dished(0, $inverted_dish) {
|
||||
stems_and_stabilizers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// actual full key with space carved out and keystem/stabilizer connectors
|
||||
|
||||
@@ -8,10 +8,14 @@ include <key_profiles/dsa.scad>
|
||||
include <key_profiles/sa.scad>
|
||||
include <key_profiles/g20.scad>
|
||||
include <key_profiles/hipro.scad>
|
||||
include <key_profiles/mt3.scad>
|
||||
include <key_profiles/grid.scad>
|
||||
include <key_profiles/regular_polygon.scad>
|
||||
include <key_profiles/cherry.scad>
|
||||
include <key_profiles/dss.scad>
|
||||
include <key_profiles/asa.scad>
|
||||
include <key_profiles/typewriter.scad>
|
||||
include <key_profiles/hex.scad>
|
||||
|
||||
// man, wouldn't it be so cool if functions were first order
|
||||
module key_profile(key_profile_type, row, column=0) {
|
||||
@@ -25,18 +29,26 @@ module key_profile(key_profile_type, row, column=0) {
|
||||
dss_row(row, column) children();
|
||||
} else if (key_profile_type == "sa") {
|
||||
sa_row(row, column) children();
|
||||
} else if (key_profile_type == "asa") {
|
||||
asa_row(row, column) children();
|
||||
} else if (key_profile_type == "g20") {
|
||||
g20_row(row, column) children();
|
||||
} else if (key_profile_type == "hipro") {
|
||||
hipro_row(row, column) children();
|
||||
} else if (key_profile_type == "grid") {
|
||||
grid_row(row, column) children();
|
||||
} else if (key_profile_type == "typewriter") {
|
||||
typewriter_row(row, column) children();
|
||||
} else if (key_profile_type == "hex") { // reddit.com/r/MechanicalKeyboards/comments/kza7ji
|
||||
hex_row(row, column) children();
|
||||
} else if (key_profile_type == "hexagon") {
|
||||
hexagonal_row(row, column) children();
|
||||
} else if (key_profile_type == "octagon") {
|
||||
octagonal_row(row, column) children();
|
||||
} else if (key_profile_type == "cherry") {
|
||||
cherry_row(row, column) children();
|
||||
} else if (key_profile_type == "mt3") {
|
||||
mt3_row(row, column) children();
|
||||
} else if (key_profile_type == "disable") {
|
||||
children();
|
||||
} else {
|
||||
|
||||
44
src/key_profiles/asa.scad
Normal file
44
src/key_profiles/asa.scad
Normal file
@@ -0,0 +1,44 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
module asa_row(row=3, column = 0) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
$bottom_key_height = 18.15;
|
||||
$bottom_key_width = 18.10; // Default (R3)
|
||||
$total_depth = 10.75; // Default (R3)
|
||||
$top_tilt = 1.5; // Default (R3)
|
||||
$width_difference = 6.20;
|
||||
$height_difference = 6.55;
|
||||
$dish_type = "spherical";
|
||||
$dish_depth = 1.3;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
$top_skew = 1.75;
|
||||
$stem_inset = 1.2;
|
||||
$height_slices = 10;
|
||||
|
||||
$corner_radius = 1;
|
||||
$more_side_sculpting_factor = 0.4;
|
||||
|
||||
$side_sculpting = function(progress) (1 - progress) * 4.5;
|
||||
$corner_sculpting = function(progress) pow(progress, 2);
|
||||
|
||||
// this is _incredibly_ intensive
|
||||
//$rounded_key = true;
|
||||
|
||||
if (row == 1){
|
||||
$total_depth = 10.5;
|
||||
$top_tilt = 9.33;
|
||||
children();
|
||||
} else if (row == 2) {
|
||||
$total_depth = 9.95;
|
||||
$top_tilt = 4;
|
||||
children();
|
||||
} else if (row == 4){
|
||||
$total_depth = 12.55;
|
||||
$top_tilt = 0.43;
|
||||
children();
|
||||
}else{
|
||||
children();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
// based off GMK keycap set
|
||||
|
||||
module cherry_row(row=3, column=0) {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
module dcs_row(row=3, column=0) {
|
||||
$bottom_key_width = 18.16;
|
||||
$bottom_key_height = 18.16;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
module dsa_row(row=3, column = 0) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
$bottom_key_width = 18.24; // 18.4;
|
||||
@@ -11,8 +14,12 @@ module dsa_row(row=3, column = 0) {
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
$height_slices = 10;
|
||||
$enable_side_sculpting = true;
|
||||
|
||||
$side_sculpting = function(progress) (1 - progress) * 4.5;
|
||||
$corner_sculpting = function(progress) pow(progress, 2);
|
||||
|
||||
$corner_radius = 1;
|
||||
$more_side_sculpting_factor = 0.4;
|
||||
|
||||
$top_tilt_y = side_tilt(column);
|
||||
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
module dss_row(n=3, column=0) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
$bottom_key_width = 18.24;
|
||||
@@ -10,10 +13,13 @@ module dss_row(n=3, column=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 = 1;
|
||||
$more_side_sculpting_factor = 0.4;
|
||||
|
||||
$side_sculpting = function(progress) (1 - progress) * 4.5;
|
||||
$corner_sculpting = function(progress) pow(progress, 2);
|
||||
|
||||
// this is _incredibly_ intensive
|
||||
/* $rounded_key = true; */
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
module g20_row(row=3, column = 0) {
|
||||
$bottom_key_width = 18.16;
|
||||
$bottom_key_height = 18.16;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
module grid_row(row=3, column = 0) {
|
||||
$bottom_key_width = 18.16;
|
||||
$bottom_key_height = 18.16;
|
||||
|
||||
62
src/key_profiles/hex.scad
Normal file
62
src/key_profiles/hex.scad
Normal file
@@ -0,0 +1,62 @@
|
||||
include <../constants.scad>
|
||||
// Regular polygon shapes CIRCUMSCRIBE the sphere of diameter $bottom_key_width
|
||||
// This is to make tiling them easier, like in the case of hexagonal keycaps etc
|
||||
|
||||
// this function doesn't set the key shape, so you can't use it directly without some fiddling
|
||||
module hex_row(n=3, column=0) {
|
||||
$bottom_key_width = $unit - 0.5;
|
||||
$bottom_key_height = $unit - 0.5;
|
||||
|
||||
$width_difference = 0;
|
||||
$height_difference = 0;
|
||||
|
||||
$dish_type = "spherical";
|
||||
$key_shape_type = "hexagon";
|
||||
|
||||
$stem_inset = -2.5;
|
||||
$stem_throw = 3;
|
||||
|
||||
// $dish_depth = 1;
|
||||
|
||||
$top_skew = 0;
|
||||
$height_slices = 1;
|
||||
$stem_support_type = "disable";
|
||||
|
||||
$dish_overdraw_width = -8.25;
|
||||
$dish_overdraw_height = -8.25;
|
||||
// $corner_radius = 1;
|
||||
|
||||
// this is _incredibly_ intensive
|
||||
/* $rounded_key = true; */
|
||||
|
||||
$top_tilt_y = side_tilt(column);
|
||||
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
|
||||
|
||||
base_depth = 4;
|
||||
if (n <= 1){
|
||||
$total_depth = base_depth + 2.5 + extra_height;
|
||||
$top_tilt = -13;
|
||||
|
||||
children();
|
||||
} else if (n == 2) {
|
||||
$total_depth = base_depth + 0.5 + extra_height;
|
||||
$top_tilt = -7;
|
||||
|
||||
children();
|
||||
} else if (n == 3) {
|
||||
$total_depth = base_depth + extra_height;
|
||||
$top_tilt = 0;
|
||||
|
||||
children();
|
||||
} else if (n == 4){
|
||||
$total_depth = base_depth + 0.5 + extra_height;
|
||||
$top_tilt = 7;
|
||||
|
||||
children();
|
||||
} else {
|
||||
$total_depth = base_depth + extra_height;
|
||||
$top_tilt = 0;
|
||||
|
||||
children();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
// my own measurements
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
module hipro_row(row=3, column=0) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
|
||||
@@ -7,13 +9,18 @@ module hipro_row(row=3, column=0) {
|
||||
|
||||
$width_difference = ($bottom_key_width - 12.3);
|
||||
$height_difference = ($bottom_key_height - 12.65);
|
||||
$dish_type = "spherical";
|
||||
$dish_type = "squared scoop";
|
||||
$dish_depth = 0.75;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
$top_skew = 0;
|
||||
$height_slices = 10;
|
||||
|
||||
$corner_radius = 1;
|
||||
$more_side_sculpting_factor = 0.4;
|
||||
|
||||
$side_sculpting = function(progress) (1 - progress) * 4.5;
|
||||
$corner_sculpting = function(progress) pow(progress, 2);
|
||||
|
||||
$top_tilt_y = side_tilt(column);
|
||||
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
|
||||
|
||||
58
src/key_profiles/mt3.scad
Normal file
58
src/key_profiles/mt3.scad
Normal file
@@ -0,0 +1,58 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
// This is an imperfect attempt to clone the MT3 profile
|
||||
module mt3_row(row=3, column=0, deep_dish=false) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
|
||||
$bottom_key_width = 18.35;
|
||||
$bottom_key_height = 18.6;
|
||||
|
||||
$width_difference = ($bottom_key_width - 13.0);
|
||||
$height_difference = ($bottom_key_height - 13.0);
|
||||
$dish_type = "squared spherical";
|
||||
$dish_depth = deep_dish ? 1.6 : 1.2;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
$top_skew = 0;
|
||||
$height_slices = 10;
|
||||
|
||||
$corner_radius = 0.0125;
|
||||
$more_side_sculpting_factor = 0.75;
|
||||
|
||||
$side_sculpting = function(progress) (1 - progress) * 4.5;
|
||||
$corner_sculpting = function(progress) pow(progress, 2) * 2;
|
||||
|
||||
|
||||
$top_tilt_y = side_tilt(column);
|
||||
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
|
||||
|
||||
if (row == 0){
|
||||
// TODO I didn't change these yet
|
||||
$total_depth = 14.7 + extra_height;
|
||||
$top_tilt = -12.5;
|
||||
children();
|
||||
} else if (row == 1) {
|
||||
$total_depth = 13.1 + extra_height;
|
||||
$top_tilt = -6;
|
||||
children();
|
||||
} else if (row == 2) {
|
||||
$total_depth = 10.7 + extra_height;
|
||||
$top_tilt = -6;
|
||||
children();
|
||||
} else if (row == 3) {
|
||||
$total_depth = 10.7 + extra_height;
|
||||
$top_tilt = 6;
|
||||
children();
|
||||
} else if (row == 4){
|
||||
$total_depth = 11.6 + extra_height;
|
||||
$top_tilt = 12;
|
||||
children();
|
||||
} else if (row >= 5) {
|
||||
$total_depth = 11.6 + extra_height;
|
||||
$top_tilt = 0;
|
||||
children();
|
||||
} else {
|
||||
children();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
module oem_row(row=3, column = 0) {
|
||||
$bottom_key_width = 18.05;
|
||||
$bottom_key_height = 18.05;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
include <../constants.scad>
|
||||
// Regular polygon shapes CIRCUMSCRIBE the sphere of diameter $bottom_key_width
|
||||
// This is to make tiling them easier, like in the case of hexagonal keycaps etc
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
|
||||
module sa_row(n=3, column=0) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
$bottom_key_width = 18.4;
|
||||
@@ -10,7 +13,12 @@ module sa_row(n=3, column=0) {
|
||||
$dish_skew_y = 0;
|
||||
$top_skew = 0;
|
||||
$height_slices = 10;
|
||||
|
||||
$corner_radius = 1;
|
||||
$more_side_sculpting_factor = 0.4;
|
||||
|
||||
$side_sculpting = function(progress) (1 - progress) * 4.5;
|
||||
$corner_sculpting = function(progress) pow(progress, 2);
|
||||
|
||||
// this is _incredibly_ intensive
|
||||
/* $rounded_key = true; */
|
||||
|
||||
59
src/key_profiles/typewriter.scad
Normal file
59
src/key_profiles/typewriter.scad
Normal file
@@ -0,0 +1,59 @@
|
||||
use <../functions.scad>
|
||||
include <../settings.scad>
|
||||
include <../constants.scad>
|
||||
// Regular polygon shapes CIRCUMSCRIBE the sphere of diameter $bottom_key_width
|
||||
// This is to make tiling them easier, like in the case of hexagonal keycaps etc
|
||||
|
||||
// this function doesn't set the key shape, so you can't use it directly without some fiddling
|
||||
module typewriter_row(n=3, column=0) {
|
||||
$bottom_key_width = $unit - 0.5;
|
||||
$bottom_key_height = $unit - 0.5;
|
||||
$width_difference = 0;
|
||||
$height_difference = 0;
|
||||
$dish_type = "spherical";
|
||||
$key_shape_type = "circular";
|
||||
$inverted_dish = true;
|
||||
$stem_inset = -4.5;
|
||||
$stem_throw = 5;
|
||||
$dish_depth = 4;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
$top_skew = 0;
|
||||
$height_slices = 1;
|
||||
$stem_support_type = "disable";
|
||||
// $corner_radius = 1;
|
||||
|
||||
// this is _incredibly_ intensive
|
||||
/* $rounded_key = true; */
|
||||
|
||||
$top_tilt_y = side_tilt(column);
|
||||
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
|
||||
|
||||
base_depth = 3.5;
|
||||
if (n <= 1){
|
||||
$total_depth = base_depth + 2.5 + extra_height;
|
||||
$top_tilt = -13;
|
||||
|
||||
children();
|
||||
} else if (n == 2) {
|
||||
$total_depth = base_depth + 0.5 + extra_height;
|
||||
$top_tilt = -7;
|
||||
|
||||
children();
|
||||
} else if (n == 3) {
|
||||
$total_depth = base_depth + extra_height;
|
||||
$top_tilt = 0;
|
||||
|
||||
children();
|
||||
} else if (n == 4){
|
||||
$total_depth = base_depth + 0.5 + extra_height;
|
||||
$top_tilt = 7;
|
||||
|
||||
children();
|
||||
} else {
|
||||
$total_depth = base_depth + extra_height;
|
||||
$top_tilt = 0;
|
||||
|
||||
children();
|
||||
}
|
||||
}
|
||||
@@ -158,15 +158,17 @@ module flat_support() {
|
||||
children();
|
||||
}
|
||||
|
||||
module legend(text, position=[0,0], size=undef) {
|
||||
module legend(text, position=[0,0], size=undef, font=undef) {
|
||||
font_size = size == undef ? $font_size : size;
|
||||
$legends = [for(L=[$legends, [[text, position, font_size]]], a=L) a];
|
||||
font_face = font == undef ? $font : font;
|
||||
$legends = [for(L=[$legends, [[text, position, font_size, font_face]]], a=L) a];
|
||||
children();
|
||||
}
|
||||
|
||||
module front_legend(text, position=[0,0], size=undef) {
|
||||
module front_legend(text, position=[0,0], size=undef, font=undef) {
|
||||
font_size = size == undef ? $font_size : size;
|
||||
$front_legends = [for(L=[$front_legends, [[text, position, font_size]]], a=L) a];
|
||||
font_face = font == undef ? $font : font;
|
||||
$front_legends = [for(L=[$front_legends, [[text, position, font_size, font_face]]], a=L) a];
|
||||
children();
|
||||
}
|
||||
|
||||
@@ -193,13 +195,68 @@ module upside_down() {
|
||||
}
|
||||
|
||||
module sideways() {
|
||||
$stem_support_type = "disable";
|
||||
$key_shape_type = "flat_sided_square";
|
||||
$dish_overdraw_width = abs(extra_keytop_length_for_flat_sides());
|
||||
extra_y_rotation = atan2($width_difference/2,$total_depth);
|
||||
extra_y_rotation = atan2($width_difference/2,$total_depth); // TODO assumes centered top
|
||||
translate([0,0,cos(extra_y_rotation) * total_key_width()/2])
|
||||
rotate([0,90 + extra_y_rotation ,0]) children();
|
||||
}
|
||||
|
||||
/* this is hard to explain. we want the angle of the back of the keycap.
|
||||
* first we draw a line at the back of the keycap perpendicular to the ground.
|
||||
* then we extend the line created by the slope of the keytop to that line
|
||||
* the angle of the latter line off the ground is $top_tilt, and
|
||||
* you can create a right triangle with the adjacent edge being $bottom_key_height/2
|
||||
* raised up $total_depth. this gets you x, the component of the extended
|
||||
* keytop slope line, and y, a component of the first perpendicular line.
|
||||
* by a very similar triangle you get r and s, where x is the hypotenuse of that
|
||||
* right triangle and the right angle is again against the first perpendicular line
|
||||
* s is the opposite line in the right triangle required to find q, the angle
|
||||
* of the back. if you subtract r from $total_depth plus y you can now use these
|
||||
* two values in atan to find the angle of interest.
|
||||
*/
|
||||
module backside() {
|
||||
$stem_support_type = "disable";
|
||||
|
||||
// $key_shape_type = "flat_sided_square";
|
||||
|
||||
a = $bottom_key_height;
|
||||
b = $total_depth;
|
||||
c = top_total_key_height();
|
||||
|
||||
x = (a / 2 - $top_skew) / cos(-$top_tilt) - c / 2;
|
||||
y = sin(-$top_tilt) * (x + c/2);
|
||||
r = sin(-$top_tilt) * x;
|
||||
s = cos(-$top_tilt) * x;
|
||||
|
||||
q = atan2(s, (y + b - r));
|
||||
|
||||
translate([0,0,cos(q) * total_key_height()/2])
|
||||
rotate([-90 - q, 0,0]) children();
|
||||
}
|
||||
|
||||
// this is just backside with a few signs switched
|
||||
module frontside() {
|
||||
$stem_support_type = "disable";
|
||||
|
||||
// $key_shape_type = "flat_sided_square";
|
||||
|
||||
a = $bottom_key_height;
|
||||
b = $total_depth;
|
||||
c = top_total_key_height();
|
||||
|
||||
x = (a / 2 + $top_skew) / cos($top_tilt) - c / 2;
|
||||
y = sin($top_tilt) * (x + c/2);
|
||||
r = sin($top_tilt) * x;
|
||||
s = cos($top_tilt) * x;
|
||||
|
||||
q = atan2(s, (y + b - r));
|
||||
|
||||
translate([0,0,cos(q) * total_key_height()/2])
|
||||
rotate([90 + q, 0,0]) children();
|
||||
}
|
||||
|
||||
// emulating the % modifier.
|
||||
// since we use custom colors, just using the % modifier doesn't work
|
||||
module debug() {
|
||||
@@ -223,3 +280,11 @@ module auto_place() {
|
||||
translate_u(x,-y) children(child_index);
|
||||
}
|
||||
}
|
||||
|
||||
// suggested settings for resin prints
|
||||
module resin() {
|
||||
$stem_slop = 0;
|
||||
$stem_inner_slop = 0;
|
||||
$stem_support_type = "disable";
|
||||
children();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
include <functions.scad>
|
||||
use <key_sizes.scad>
|
||||
use <key_transformations.scad>
|
||||
|
||||
module spacebar() {
|
||||
$inverted_dish = $dish_type != "disable";
|
||||
|
||||
@@ -17,5 +17,5 @@ include <../layout.scad>
|
||||
];
|
||||
|
||||
module 60_percent_default(profile) {
|
||||
layout(60_percent_default_layout, profile, 60_percent_legends) children();
|
||||
layout(60_percent_default_layout, profile, 60_percent_legends, row_sculpting_offset=1) children();
|
||||
}
|
||||
|
||||
21
src/layouts/hhkb/default.scad
Normal file
21
src/layouts/hhkb/default.scad
Normal file
@@ -0,0 +1,21 @@
|
||||
include <../layout.scad>
|
||||
|
||||
hhkb_layout = [
|
||||
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
|
||||
[1.5,1,1,1,1,1,1,1,1,1,1,1,1,1.5],
|
||||
[1.75,1,1,1,1,1,1,1,1,1,1,1,2.25],
|
||||
[2.25,1,1,1,1,1,1,1,1,1,1,1.75,1],
|
||||
[-1.5,1,1.5,6,1.5,1]
|
||||
];
|
||||
|
||||
hhkb_legends = [
|
||||
["Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "\\", "`"],
|
||||
["Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "Delete"],
|
||||
["Ctrl", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "Return"],
|
||||
["Shift", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "Shift", "Fn"],
|
||||
["", "Alt", "Cmd", "", "Cmd", "Alt"],
|
||||
];
|
||||
|
||||
module hhkb_default(profile) {
|
||||
layout(hhkb_layout, profile, hhkb_legends) children();
|
||||
}
|
||||
@@ -1,3 +1,8 @@
|
||||
use <../key_transformations.scad>
|
||||
use <../key_profiles.scad>
|
||||
use <../key_sizes.scad>
|
||||
use <../key_types.scad>
|
||||
|
||||
// sums all values, unless a value is negative, in which case it makes it positive
|
||||
// dirty hack to allow for large gaps in keysets
|
||||
function abs_sum(list, x=0) =
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
include <../functions.scad>
|
||||
|
||||
module 3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST_POSSIBLE){
|
||||
function p(x, y) = [ x, y, max(0,surface_function(x, y)) ];
|
||||
function p(x, y) = [ x, y, max(0,$surface_function(x, y) * $corner_smoothing_surface_function(x,y)) ];
|
||||
function p0(x, y) = [ x, y, bottom ];
|
||||
function rev(b, v) = b ? v : [ v[3], v[2], v[1], v[0] ];
|
||||
function face(x, y) = [ p(x, y + step), p(x + step, y + step), p(x + step, y), p(x + step, y), p(x, y), p(x, y + step) ];
|
||||
@@ -35,13 +35,13 @@ module 3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST
|
||||
polyhedron(points, faces, convexity = 8);
|
||||
}
|
||||
|
||||
module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST_POSSIBLE){
|
||||
module polar_3d_surface(size, step, bottom=-SMALLEST_POSSIBLE){
|
||||
function to_polar(q, size) = q * (90 / size);
|
||||
|
||||
function p(x, y) = [
|
||||
surface_distribution_function(to_polar(x, size), size),
|
||||
surface_distribution_function(to_polar(y, size), size),
|
||||
max(0,surface_function(surface_distribution_function(to_polar(x, size), size), surface_distribution_function(to_polar(y, size), size)))
|
||||
$surface_distribution_function(to_polar(x, size), size),
|
||||
$surface_distribution_function(to_polar(y, size), size),
|
||||
max(0,$surface_function($surface_distribution_function(to_polar(x, size), size), $surface_distribution_function(to_polar(y, size), size)) * $corner_smoothing_surface_function($surface_distribution_function(to_polar(x, size), size), $surface_distribution_function(to_polar(y, size), size)))
|
||||
];
|
||||
function p0(x, y) = [ x, y, bottom ];
|
||||
function rev(b, v) = b ? v : [ v[3], v[2], v[1], v[0] ];
|
||||
@@ -75,5 +75,5 @@ module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SM
|
||||
}
|
||||
|
||||
// defaults, overridden in functions.scad
|
||||
function surface_distribution_function(dim, size) = sin(dim) * size;
|
||||
function surface_function(x,y) = (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));
|
||||
// $surface_distribution_function = function(dim, size) sin(dim) * size;
|
||||
// $surface_function = function(x,y) (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));
|
||||
|
||||
@@ -76,8 +76,10 @@ $rounded_cherry_stem_d = 5.5;
|
||||
// Inset stem requires support but is more accurate in some profiles
|
||||
// can be negative to make outset stems!
|
||||
$stem_inset = 0;
|
||||
// How many degrees to rotate the stems. useful for sideways keycaps, maybe
|
||||
// How many degrees to rotate the stems. useful for sideways keycaps
|
||||
$stem_rotation = 0;
|
||||
// How many degrees to rotate the keycap, but _not_ inside features (the stem).
|
||||
$keycap_rotation = 0;
|
||||
|
||||
/* [Shape] */
|
||||
|
||||
@@ -190,11 +192,60 @@ $warning_color = [1,0,0, 0.15];
|
||||
$minkowski_facets = 30;
|
||||
$shape_facets =30;
|
||||
|
||||
// 3d surface settings
|
||||
// unused for now
|
||||
$3d_surface_size = 100;
|
||||
// resolution in each axis. 10 = 10 divisions per x/y = 100 points total
|
||||
$3d_surface_step = 10;
|
||||
|
||||
|
||||
// "flat" / "dished" / "disable"
|
||||
$inner_shape_type = "flat";
|
||||
|
||||
// default side_sculpting function, linear
|
||||
$side_sculpting = function(progress) 0;
|
||||
$corner_sculpting = function(progress) 0;
|
||||
|
||||
// you probably shouldn't touch this, it's internal to sculpted_square
|
||||
// modify side sculpting with the $side_sculpting function in the key profile files
|
||||
$more_side_sculpting_factor = 0;
|
||||
|
||||
// 3d surface functions (still in beta)
|
||||
|
||||
// 3d surface settings
|
||||
// unused for now
|
||||
$3d_surface_size = 1;
|
||||
// 3d surface point resolution. $3d_surface_size / $3d_surface_step = steps per x / y
|
||||
$3d_surface_step = 1/20;
|
||||
|
||||
// monotonically increasing function that distributes the points of the surface mesh
|
||||
// only for polar_3d_surface right now
|
||||
// if it's linear it's a grid. sin(dim) * size concentrates detail around the edges
|
||||
sinusoidal_surface_distribution = function(dim,size) sin(dim) * size;
|
||||
linear_surface_distribution = function(dim,size) dim;
|
||||
|
||||
$surface_distribution_function = sinusoidal_surface_distribution;
|
||||
|
||||
// the function that actually determines what the surface is.
|
||||
// feel free to override, the last one wins
|
||||
|
||||
// debug
|
||||
// $surface_function = function(x,y) 1;
|
||||
cylindrical_surface = function(x,y) (sin(acos(x/$3d_surface_size)));
|
||||
spherical_surface = function(x,y) (1 - (x/$3d_surface_size)^2)^0.5 * (1 - (y/$3d_surface_size)^2)^0.5;
|
||||
// looks a lot like mt3
|
||||
quartic_surface = function(x,y) (1 - (x/$3d_surface_size)^4)^0.5 * (1 - (y/$3d_surface_size)^4)^0.5;
|
||||
ripple_surface = function(x,y) cos((x^2+y^2)^0.5 * 50)/4 + 0.75;
|
||||
rosenbrocks_banana_surface = function(x,y) (pow(1-(x/$3d_surface_size))^2 + 100 * pow((y/$3d_surface_size)-(x/$3d_surface_size)^2)^2)/200 + 0.1;
|
||||
spike_surface = function(x,y) 1/(((x/$3d_surface_size)^2+(y/$3d_surface_size)^2)^0.5) + .01;
|
||||
random_surface = function(x,y) sin(rands(0,90,1,x+y)[0]);
|
||||
bumps_surface = function(x,y) sin(20*x)*cos(20*y)/3+1;
|
||||
|
||||
$surface_function = bumps_surface; // bumps_surface;
|
||||
|
||||
// can be used to smooth the corners of the 3d surface function, to make the dishes add / subtract less height. can really do anything it's just multiplying, but that's what I use it for
|
||||
$corner_smoothing_surface_function = function(x,y) 1;
|
||||
// $corner_smoothing_surface_function = function(x,y) (1 - pow(abs(x), 5)/$3d_surface_size) * (1 - pow(abs(y),5)/$3d_surface_size);
|
||||
|
||||
// ripples
|
||||
/*
|
||||
// Rosenbrock's banana
|
||||
/* $
|
||||
// y=x revolved around the y axis
|
||||
/* $surface_function = */
|
||||
/* $surface_function = */
|
||||
@@ -28,6 +28,8 @@ module key_shape(size, delta, progress = 0) {
|
||||
regular_polygon_shape(size, delta, progress);
|
||||
} else if ($key_shape_type == "octagon") {
|
||||
regular_polygon_shape(size, delta, progress, sides=8);
|
||||
} else if ($key_shape_type == "circular") {
|
||||
regular_polygon_shape(size, delta, progress, sides=36);
|
||||
} else {
|
||||
echo("Warning: unsupported $key_shape_type");
|
||||
}
|
||||
|
||||
@@ -59,11 +59,11 @@ function skin_iso_enter_shape(size, delta, progress, thickness_difference) =
|
||||
add_rounding(
|
||||
iso_enter_vertices(
|
||||
size,
|
||||
delta,
|
||||
[delta.x - $side_sculpting(progress), delta.y - $side_sculpting(progress)],
|
||||
progress,
|
||||
thickness_difference
|
||||
),
|
||||
$corner_radius
|
||||
$corner_radius + $corner_sculpting(progress)
|
||||
),
|
||||
$shape_facets
|
||||
);
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
// rounded square shape with additional sculpting functions to better approximate
|
||||
|
||||
// When sculpting sides, how much in should the tops come
|
||||
side_sculpting_factor = 4.5;
|
||||
// When sculpting corners, how much extra radius should be added
|
||||
corner_sculpting_factor = 1;
|
||||
// When doing more side sculpting corners, how much extra radius should be added
|
||||
more_side_sculpting_factor = 0.4;
|
||||
|
||||
|
||||
// side sculpting functions
|
||||
// bows the sides out on stuff like SA and DSA keycaps
|
||||
function side_sculpting(progress) = (1 - progress) * side_sculpting_factor;
|
||||
function side_sculpting(progress) = (1 - progress) * $side_sculpting_factor;
|
||||
// makes the rounded corners of the keycap grow larger as they move upwards
|
||||
function corner_sculpting(progress) = pow(progress, 2) * corner_sculpting_factor;
|
||||
function corner_sculpting(progress) = pow(progress, 2) * $corner_sculpting_factor;
|
||||
|
||||
module sculpted_square_shape(size, delta, progress) {
|
||||
width = size[0];
|
||||
@@ -21,9 +13,9 @@ module sculpted_square_shape(size, delta, progress) {
|
||||
width_difference = delta[0];
|
||||
height_difference = delta[1];
|
||||
// makes the sides bow
|
||||
extra_side_size = side_sculpting(progress);
|
||||
extra_side_size = $side_sculpting(progress);
|
||||
// makes the rounded corners of the keycap grow larger as they move upwards
|
||||
extra_corner_size = corner_sculpting(progress);
|
||||
extra_corner_size = $corner_sculpting(progress);
|
||||
|
||||
// computed values for this slice
|
||||
extra_width_this_slice = (width_difference - extra_side_size) * progress;
|
||||
@@ -37,7 +29,7 @@ module sculpted_square_shape(size, delta, progress) {
|
||||
|
||||
offset(r = extra_corner_radius_this_slice, $fa=360/$shape_facets) {
|
||||
offset(r = -extra_corner_radius_this_slice) {
|
||||
side_rounded_square(square_size, r = more_side_sculpting_factor * progress);
|
||||
side_rounded_square(square_size, r = $more_side_sculpting_factor * progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,9 +71,9 @@ function skin_sculpted_square_shape(size, delta, progress, thickness_difference)
|
||||
width_difference = delta[0],
|
||||
height_difference = delta[1],
|
||||
// makes the sides bow
|
||||
extra_side_size = side_sculpting(progress),
|
||||
extra_side_size = $side_sculpting(progress),
|
||||
// makes the rounded corners of the keycap grow larger as they move upwards
|
||||
extra_corner_size = corner_sculpting(progress),
|
||||
extra_corner_size = $corner_sculpting(progress),
|
||||
|
||||
// computed values for this slice
|
||||
extra_width_this_slice = (width_difference - extra_side_size) * progress,
|
||||
@@ -92,7 +84,7 @@ function skin_sculpted_square_shape(size, delta, progress, thickness_difference)
|
||||
width - extra_width_this_slice - thickness_difference,
|
||||
height - extra_height_this_slice - thickness_difference
|
||||
]
|
||||
) new_side_rounded_square(square_size, more_side_sculpting_factor * progress, extra_corner_radius_this_slice);
|
||||
) new_side_rounded_square(square_size, $more_side_sculpting_factor * progress, extra_corner_radius_this_slice);
|
||||
|
||||
|
||||
module side_rounded_square(size, r) {
|
||||
|
||||
@@ -36,7 +36,7 @@ module tines_support(stem_type, stem_support_height, slop) {
|
||||
}
|
||||
|
||||
// 2 vertical tines holding either side of the cruciform
|
||||
for (x = [1.15, -1.15]) {
|
||||
for (x = [2, -2]) {
|
||||
translate([x,0,$stem_support_height / 2]) {
|
||||
cube([
|
||||
0.5,
|
||||
|
||||
@@ -2,7 +2,7 @@ include <../functions.scad>
|
||||
|
||||
// extra length to the vertical tine of the inside cherry cross
|
||||
// splits the stem into halves - allows easier fitment
|
||||
extra_vertical = 0.6;
|
||||
extra_vertical = 100;
|
||||
|
||||
module inside_cherry_cross(slop) {
|
||||
// inside cross
|
||||
|
||||
Reference in New Issue
Block a user