mirror of
https://github.com/rsheldiii/KeyV2.git
synced 2026-01-14 22:37:56 -05:00
Compare commits
1 Commits
v2.2.0
...
v2/autoleg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e955331e8d |
1
TODO.md
1
TODO.md
@@ -1,5 +1,6 @@
|
||||
TODO:
|
||||
* Make flat stem support default
|
||||
* make flat inner shape default
|
||||
* support repositioning to print on the back surface of the keycap
|
||||
* implement regular polygon for skin extrusions
|
||||
* switch to skin-shaped extrusions by default
|
||||
|
||||
262
customizer.scad
262
customizer.scad
@@ -162,12 +162,14 @@ $double_sculpted = false;
|
||||
//valign = "top" or "center" or "bottom"
|
||||
// Currently does not work with thingiverse customizer, and actually breaks it
|
||||
$legends = [];
|
||||
$autolegends = [];
|
||||
|
||||
//list of front legends to place on a key format: [text, halign, valign, size]
|
||||
//halign = "left" or "center" or "right"
|
||||
//valign = "top" or "center" or "bottom"
|
||||
// Currently does not work with thingiverse customizer, and actually breaks it
|
||||
$front_legends = [];
|
||||
$front_autolegends = [];
|
||||
|
||||
// print legends on the front of the key instead of the top
|
||||
$front_print_legends = false;
|
||||
@@ -175,6 +177,9 @@ $front_print_legends = false;
|
||||
// how recessed inset legends / artisans are from the top of the key
|
||||
$inset_legend_depth = 0.2;
|
||||
|
||||
// legends are not allowed to print within this many mm of the edge of the key
|
||||
$legend_margin = 0.8;
|
||||
|
||||
// Dimensions of alps stem
|
||||
$alps_stem = [4.45, 2.25];
|
||||
|
||||
@@ -214,12 +219,6 @@ $3d_surface_step = 10;
|
||||
// "flat" / "dished" / "disable"
|
||||
$inner_shape_type = "flat";
|
||||
|
||||
// When sculpting sides using sculpted_square, 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;
|
||||
// key width functions
|
||||
|
||||
module u(u=1) {
|
||||
@@ -515,6 +514,7 @@ module g20_row(row=3, column = 0) {
|
||||
children();
|
||||
}
|
||||
}
|
||||
// my own measurements
|
||||
module hipro_row(row=3, column=0) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
|
||||
@@ -523,7 +523,7 @@ module hipro_row(row=3, column=0) {
|
||||
|
||||
$width_difference = ($bottom_key_width - 12.3);
|
||||
$height_difference = ($bottom_key_height - 12.65);
|
||||
$dish_type = "squared scoop";
|
||||
$dish_type = "spherical";
|
||||
$dish_depth = 0.75;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
@@ -555,57 +555,6 @@ module hipro_row(row=3, column=0) {
|
||||
children();
|
||||
}
|
||||
}
|
||||
// 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 = 1;
|
||||
|
||||
$more_side_sculpting_factor = 0.75;
|
||||
|
||||
$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();
|
||||
}
|
||||
}
|
||||
module grid_row(row=3, column = 0) {
|
||||
$bottom_key_width = 18.16;
|
||||
$bottom_key_height = 18.16;
|
||||
@@ -843,8 +792,6 @@ module key_profile(key_profile_type, row, column=0) {
|
||||
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 {
|
||||
@@ -1163,6 +1110,18 @@ module front_legend(text, position=[0,0], size=undef) {
|
||||
children();
|
||||
}
|
||||
|
||||
module autolegend(texts) {
|
||||
// $autolegends = [for(L=[$legends, [[text, position, font_size]]], a=L) a];
|
||||
$autolegends = texts;
|
||||
children();
|
||||
}
|
||||
|
||||
module front_autolegend(texts) {
|
||||
font_size = size == undef ? $font_size : size;
|
||||
$front_autolegends = [for(L=[$front_legends, [[text, position, font_size]]], a=L) a];
|
||||
children();
|
||||
}
|
||||
|
||||
module bump(depth=undef) {
|
||||
$key_bump = true;
|
||||
$key_bump_depth = depth == undef ? $key_bump_depth : depth;
|
||||
@@ -2162,11 +2121,19 @@ function skin_iso_enter_shape(size, delta, progress, thickness_difference) =
|
||||
);
|
||||
// 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];
|
||||
@@ -2191,7 +2158,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2246,7 +2213,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) {
|
||||
@@ -4665,62 +4632,6 @@ module spherical_dish(width, height, depth, inverted){
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
module flat_dish(width, height, depth, inverted){
|
||||
cube([width + 100,height + 100, depth], center=true);
|
||||
}
|
||||
@@ -4898,9 +4809,11 @@ 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);
|
||||
@@ -4910,10 +4823,6 @@ module dish(width, height, depth, inverted) {
|
||||
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");
|
||||
}
|
||||
@@ -5142,6 +5051,45 @@ module legends(depth=0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
module autolegends(depth=0) {
|
||||
if (len($front_autolegends) > 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (len($autolegends) > 0) {
|
||||
// legends are printed in a square grid - 1, 4, 9 legends, etc
|
||||
grid_size = len($autolegends)^0.5;
|
||||
echo("grid_size", grid_size);
|
||||
max_width = (top_total_key_width() - $legend_margin * (grid_size + 1)) / grid_size;
|
||||
max_height = (top_total_key_height() - $legend_margin * (grid_size + 1)) / grid_size;
|
||||
|
||||
top_of_key() {
|
||||
for (column=[0:grid_size-1]) {
|
||||
for (row=[0:grid_size-1]) {
|
||||
top_left_corner = [-top_total_key_width()/2, top_total_key_height()/2];
|
||||
centering_offset = [max_width / 2, -max_height / 2];
|
||||
position_offset = [(max_width + $legend_margin) * column, (-max_height-$legend_margin) * row];
|
||||
margin_offset = [$legend_margin, -$legend_margin];
|
||||
|
||||
translate(top_left_corner + centering_offset + position_offset + margin_offset) {
|
||||
translate([0,0,-depth]) {
|
||||
color($tertiary_color) linear_extrude(height=$dish_depth + depth){
|
||||
// resize([0, max_height, 0]) {
|
||||
resize([max_width, 0], auto=true) {
|
||||
text(text=$autolegends[row * grid_size + column], font=$font, halign="center", valign="center");
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// use skin() instead of successive hulls. much more correct, and looks faster
|
||||
// too, in most cases. successive hull relies on overlapping faces which are
|
||||
// not good. But, skin works on vertex sets instead of shapes, which makes it
|
||||
@@ -5197,13 +5145,13 @@ module linear_extrude_shape_hull(thickness_difference, depth_difference, extra_s
|
||||
module hull_shape_hull(thickness_difference, depth_difference, extra_slices = 0) {
|
||||
for (index = [0:$height_slices - 1 + extra_slices]) {
|
||||
hull() {
|
||||
placed_shape_slice(index / $height_slices, thickness_difference, depth_difference);
|
||||
placed_shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
|
||||
shape_slice(index / $height_slices, thickness_difference, depth_difference);
|
||||
shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module placed_shape_slice(progress, thickness_difference, depth_difference) {
|
||||
module shape_slice(progress, thickness_difference, depth_difference) {
|
||||
skew_this_slice = $top_skew * progress;
|
||||
x_skew_this_slice = $top_skew_x * progress;
|
||||
|
||||
@@ -5214,24 +5162,20 @@ module placed_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]){
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -6198,6 +6142,7 @@ module shape(thickness_difference, depth_difference=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
|
||||
@@ -6286,9 +6231,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]){
|
||||
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference + minkowski_height/2]){
|
||||
rotate([top_tilt_by_height, top_tilt_y_by_length,0]){
|
||||
children();
|
||||
}
|
||||
@@ -6353,7 +6298,10 @@ module additive_features(inset) {
|
||||
if($key_bump) keybump($key_bump_depth, $key_bump_edge);
|
||||
if(!inset && $children > 0) color($secondary_color) children();
|
||||
}
|
||||
if($outset_legends) legends(0);
|
||||
if($outset_legends) {
|
||||
legends(0);
|
||||
autolegends(0);
|
||||
}
|
||||
// render the clearance check if it's enabled, but don't have it intersect with anything
|
||||
if ($clearance_check) %clearance_check();
|
||||
}
|
||||
@@ -6363,7 +6311,10 @@ module subtractive_features(inset) {
|
||||
top_of_key() {
|
||||
if (inset && $children > 0) color($secondary_color) children();
|
||||
}
|
||||
if(!$outset_legends) legends($inset_legend_depth);
|
||||
if(!$outset_legends) {
|
||||
legends($inset_legend_depth);
|
||||
autolegends($inset_legend_depth);
|
||||
}
|
||||
// subtract the clearance check if it's enabled, letting the user see the
|
||||
// parts of the keycap that will hit the cherry switch
|
||||
// this is a little confusing as it eats the stem too
|
||||
@@ -6408,9 +6359,7 @@ 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) {
|
||||
children();
|
||||
};
|
||||
outer_total_shape(inset);
|
||||
|
||||
if ($inner_shape_type != "disable") {
|
||||
translate([0,0,-SMALLEST_POSSIBLE]) {
|
||||
@@ -6581,12 +6530,14 @@ $double_sculpted = false;
|
||||
//valign = "top" or "center" or "bottom"
|
||||
// Currently does not work with thingiverse customizer, and actually breaks it
|
||||
$legends = [];
|
||||
$autolegends = [];
|
||||
|
||||
//list of front legends to place on a key format: [text, halign, valign, size]
|
||||
//halign = "left" or "center" or "right"
|
||||
//valign = "top" or "center" or "bottom"
|
||||
// Currently does not work with thingiverse customizer, and actually breaks it
|
||||
$front_legends = [];
|
||||
$front_autolegends = [];
|
||||
|
||||
// print legends on the front of the key instead of the top
|
||||
$front_print_legends = false;
|
||||
@@ -6594,6 +6545,9 @@ $front_print_legends = false;
|
||||
// how recessed inset legends / artisans are from the top of the key
|
||||
$inset_legend_depth = 0.2;
|
||||
|
||||
// legends are not allowed to print within this many mm of the edge of the key
|
||||
$legend_margin = 0.8;
|
||||
|
||||
// Dimensions of alps stem
|
||||
$alps_stem = [4.45, 2.25];
|
||||
|
||||
@@ -6632,13 +6586,7 @@ $3d_surface_step = 10;
|
||||
|
||||
// "flat" / "dished" / "disable"
|
||||
$inner_shape_type = "flat";
|
||||
|
||||
// When sculpting sides using sculpted_square, 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; key();
|
||||
key();
|
||||
}
|
||||
|
||||
if (!$using_customizer) {
|
||||
|
||||
@@ -9,8 +9,11 @@ include <./includes.scad>
|
||||
|
||||
|
||||
// example key
|
||||
dcs_row(5) legend("⇪", size=9) key();
|
||||
|
||||
$stem_inner_slop = 0;
|
||||
dcs_row(5) autolegend(["q", "w", "a", "z", "e", "r", "t", "", "hoobastank"]) {
|
||||
$stem_positions = [[2,2]];
|
||||
key();
|
||||
}
|
||||
// example row
|
||||
/* for (x = [0:1:4]) {
|
||||
translate_u(0,-x) dcs_row(x) key();
|
||||
|
||||
@@ -4,8 +4,6 @@ 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>
|
||||
|
||||
@@ -16,9 +14,11 @@ 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);
|
||||
@@ -28,10 +28,6 @@ module dish(width, height, depth, inverted) {
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,3 +3,4 @@
|
||||
include <features/key_bump.scad>
|
||||
include <features/clearance_check.scad>
|
||||
include <features/legends.scad>
|
||||
include <features/autolegends.scad>
|
||||
|
||||
39
src/features/autolegends.scad
Normal file
39
src/features/autolegends.scad
Normal file
@@ -0,0 +1,39 @@
|
||||
module autolegends(depth=0) {
|
||||
if (len($front_autolegends) > 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (len($autolegends) > 0) {
|
||||
// legends are printed in a square grid - 1, 4, 9 legends, etc
|
||||
grid_size = len($autolegends)^0.5;
|
||||
echo("grid_size", grid_size);
|
||||
max_width = (top_total_key_width() - $legend_margin * (grid_size + 1)) / grid_size;
|
||||
max_height = (top_total_key_height() - $legend_margin * (grid_size + 1)) / grid_size;
|
||||
|
||||
top_of_key() {
|
||||
for (column=[0:grid_size-1]) {
|
||||
for (row=[0:grid_size-1]) {
|
||||
top_left_corner = [-top_total_key_width()/2, top_total_key_height()/2];
|
||||
centering_offset = [max_width / 2, -max_height / 2];
|
||||
position_offset = [(max_width + $legend_margin) * column, (-max_height-$legend_margin) * row];
|
||||
margin_offset = [$legend_margin, -$legend_margin];
|
||||
|
||||
translate(top_left_corner + centering_offset + position_offset + margin_offset) {
|
||||
translate([0,0,-depth]) {
|
||||
color($tertiary_color) linear_extrude(height=$dish_depth + depth){
|
||||
// resize([0, max_height, 0]) {
|
||||
resize([max_width, 0], auto=true) {
|
||||
text(text=$autolegends[row * grid_size + column], font=$font, halign="center", valign="center");
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
module hull_shape_hull(thickness_difference, depth_difference, extra_slices = 0) {
|
||||
for (index = [0:$height_slices - 1 + extra_slices]) {
|
||||
hull() {
|
||||
placed_shape_slice(index / $height_slices, thickness_difference, depth_difference);
|
||||
placed_shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
|
||||
shape_slice(index / $height_slices, thickness_difference, depth_difference);
|
||||
shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module placed_shape_slice(progress, thickness_difference, depth_difference) {
|
||||
module shape_slice(progress, thickness_difference, depth_difference) {
|
||||
skew_this_slice = $top_skew * progress;
|
||||
x_skew_this_slice = $top_skew_x * progress;
|
||||
|
||||
@@ -18,20 +18,16 @@ module placed_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]){
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
19
src/key.scad
19
src/key.scad
@@ -24,6 +24,7 @@ module shape(thickness_difference, depth_difference=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
|
||||
@@ -112,9 +113,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]){
|
||||
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference + minkowski_height/2]){
|
||||
rotate([top_tilt_by_height, top_tilt_y_by_length,0]){
|
||||
children();
|
||||
}
|
||||
@@ -179,7 +180,10 @@ module additive_features(inset) {
|
||||
if($key_bump) keybump($key_bump_depth, $key_bump_edge);
|
||||
if(!inset && $children > 0) color($secondary_color) children();
|
||||
}
|
||||
if($outset_legends) legends(0);
|
||||
if($outset_legends) {
|
||||
legends(0);
|
||||
autolegends(0);
|
||||
}
|
||||
// render the clearance check if it's enabled, but don't have it intersect with anything
|
||||
if ($clearance_check) %clearance_check();
|
||||
}
|
||||
@@ -189,7 +193,10 @@ module subtractive_features(inset) {
|
||||
top_of_key() {
|
||||
if (inset && $children > 0) color($secondary_color) children();
|
||||
}
|
||||
if(!$outset_legends) legends($inset_legend_depth);
|
||||
if(!$outset_legends) {
|
||||
legends($inset_legend_depth);
|
||||
autolegends($inset_legend_depth);
|
||||
}
|
||||
// subtract the clearance check if it's enabled, letting the user see the
|
||||
// parts of the keycap that will hit the cherry switch
|
||||
// this is a little confusing as it eats the stem too
|
||||
@@ -234,9 +241,7 @@ 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) {
|
||||
children();
|
||||
};
|
||||
outer_total_shape(inset);
|
||||
|
||||
if ($inner_shape_type != "disable") {
|
||||
translate([0,0,-SMALLEST_POSSIBLE]) {
|
||||
|
||||
@@ -8,7 +8,6 @@ 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>
|
||||
@@ -38,8 +37,6 @@ module key_profile(key_profile_type, row, column=0) {
|
||||
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 {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// my own measurements
|
||||
module hipro_row(row=3, column=0) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
|
||||
@@ -6,7 +7,7 @@ module hipro_row(row=3, column=0) {
|
||||
|
||||
$width_difference = ($bottom_key_width - 12.3);
|
||||
$height_difference = ($bottom_key_height - 12.65);
|
||||
$dish_type = "squared scoop";
|
||||
$dish_type = "spherical";
|
||||
$dish_depth = 0.75;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// 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 = 1;
|
||||
|
||||
$more_side_sculpting_factor = 0.75;
|
||||
|
||||
$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();
|
||||
}
|
||||
}
|
||||
@@ -170,6 +170,18 @@ module front_legend(text, position=[0,0], size=undef) {
|
||||
children();
|
||||
}
|
||||
|
||||
module autolegend(texts) {
|
||||
// $autolegends = [for(L=[$legends, [[text, position, font_size]]], a=L) a];
|
||||
$autolegends = texts;
|
||||
children();
|
||||
}
|
||||
|
||||
module front_autolegend(texts) {
|
||||
font_size = size == undef ? $font_size : size;
|
||||
$front_autolegends = [for(L=[$front_legends, [[text, position, font_size]]], a=L) a];
|
||||
children();
|
||||
}
|
||||
|
||||
module bump(depth=undef) {
|
||||
$key_bump = true;
|
||||
$key_bump_depth = depth == undef ? $key_bump_depth : depth;
|
||||
|
||||
@@ -17,5 +17,5 @@ include <../layout.scad>
|
||||
];
|
||||
|
||||
module 60_percent_default(profile) {
|
||||
layout(60_percent_default_layout, profile, 60_percent_legends, row_sculpting_offset=1) children();
|
||||
layout(60_percent_default_layout, profile, 60_percent_legends) children();
|
||||
}
|
||||
|
||||
@@ -147,12 +147,14 @@ $double_sculpted = false;
|
||||
//valign = "top" or "center" or "bottom"
|
||||
// Currently does not work with thingiverse customizer, and actually breaks it
|
||||
$legends = [];
|
||||
$autolegends = [];
|
||||
|
||||
//list of front legends to place on a key format: [text, halign, valign, size]
|
||||
//halign = "left" or "center" or "right"
|
||||
//valign = "top" or "center" or "bottom"
|
||||
// Currently does not work with thingiverse customizer, and actually breaks it
|
||||
$front_legends = [];
|
||||
$front_autolegends = [];
|
||||
|
||||
// print legends on the front of the key instead of the top
|
||||
$front_print_legends = false;
|
||||
@@ -160,6 +162,9 @@ $front_print_legends = false;
|
||||
// how recessed inset legends / artisans are from the top of the key
|
||||
$inset_legend_depth = 0.2;
|
||||
|
||||
// legends are not allowed to print within this many mm of the edge of the key
|
||||
$legend_margin = 0.8;
|
||||
|
||||
// Dimensions of alps stem
|
||||
$alps_stem = [4.45, 2.25];
|
||||
|
||||
@@ -198,10 +203,3 @@ $3d_surface_step = 10;
|
||||
|
||||
// "flat" / "dished" / "disable"
|
||||
$inner_shape_type = "flat";
|
||||
|
||||
// When sculpting sides using sculpted_square, 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;
|
||||
@@ -1,10 +1,18 @@
|
||||
// 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];
|
||||
@@ -29,7 +37,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,7 +92,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) {
|
||||
|
||||
Reference in New Issue
Block a user