1 Commits

Author SHA1 Message Date
Bob
e955331e8d autolegends
doesn't work yet, because you can't fit an arbitrary object into a
bounding box while maintaining aspect ratio
2022-02-21 15:52:51 -05:00
26 changed files with 676 additions and 822 deletions

View File

@@ -198,7 +198,9 @@ 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:
moved to [TODO doc](./TODO.md)
* 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?
## Contributions welcome

View File

@@ -1,5 +1,7 @@
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
* kailh choc has a non-square key unit; should I get that working for layouts etc?

File diff suppressed because it is too large Load Diff

View File

@@ -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();

View File

@@ -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,22 +14,20 @@ 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");
}

View File

@@ -6,11 +6,9 @@ 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.11;
scale_factor = 1.1;
// 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(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([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([180,0,0]) polar_3d_surface(bottom=-10); */
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -3,3 +3,4 @@
include <features/key_bump.scad>
include <features/clearance_check.scad>
include <features/legends.scad>
include <features/autolegends.scad>

View 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");
}
// }
}
}
}
}
}
}
}
}

View File

@@ -43,6 +43,29 @@ 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

View File

@@ -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
);
}
}

View File

@@ -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]) {

View File

@@ -8,13 +8,10 @@ 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>
// man, wouldn't it be so cool if functions were first order
module key_profile(key_profile_type, row, column=0) {
@@ -28,24 +25,18 @@ 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 == "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 {

View File

@@ -1,42 +0,0 @@
module asa_row(row=3, column = 0) {
$key_shape_type = "sculpted_square";
$bottom_key_height = 18.06;
$bottom_key_width = 18.05; // Default (R3)
$total_depth = 10.35; // Default (R3)
$top_tilt = 1.5; // Default (R3)
$width_difference = 5.05;
$height_difference = 5.56;
$dish_type = "spherical";
$dish_depth = 1.2;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 1.75;
$stem_inset = 1.2;
$height_slices = 10;
$corner_radius = 1;
// this is _incredibly_ intensive
//$rounded_key = true;
if (row == 1){
$bottom_key_width = 17.95;
$width_difference = 4.95;
$total_depth = 10.65;
$top_tilt = 7;
children();
} else if (row == 2) {
$bottom_key_width = 18.17;
$width_difference = 5.17;
$total_depth = 9.65;
$top_tilt = 3.25;
children();
} else if (row == 4){
$bottom_key_width = 18.02;
$width_difference = 5.02;
$total_depth = 11.9;
$top_tilt = 0.43;
children();
} else {
children();
}
}

View File

@@ -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;

View File

@@ -1,53 +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_sculpting_factor = 2;
$corner_radius = 0.0125;
$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();
}
}

View File

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

View File

@@ -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;
@@ -193,68 +205,13 @@ 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); // TODO assumes centered top
extra_y_rotation = atan2($width_difference/2,$total_depth);
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() {
@@ -278,11 +235,3 @@ 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();
}

View File

@@ -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();
}

View File

@@ -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)) ];
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, step, bottom=-SMALLEST_POSSIBLE){
module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_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)))
];
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, step, bottom=-SMALLEST_POSSIBLE){
}
// defaults, overridden in functions.scad
// $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));
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));

View File

@@ -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];
@@ -190,56 +195,11 @@ $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";
// 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;
// 3d surface functions (still in beta)
// 3d surface settings
// unused for now
$3d_surface_size = 20;
// resolution in each axis. 10 = 10 divisions per x/y = 100 points total.
// 5 = 20 divisions per x/y
$3d_surface_step = 1;
// 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) sin(dim) * size;
$surface_distribution_function = linear_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;
// ripples
/*
// Rosenbrock's banana
/* $
// y=x revolved around the y axis
/* $surface_function = */
/* $surface_function = */

View File

@@ -28,8 +28,6 @@ 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");
}

View File

@@ -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) {

View File

@@ -36,7 +36,7 @@ module tines_support(stem_type, stem_support_height, slop) {
}
// 2 vertical tines holding either side of the cruciform
for (x = [2, -2]) {
for (x = [1.15, -1.15]) {
translate([x,0,$stem_support_height / 2]) {
cube([
0.5,

View File

@@ -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 = 100;
extra_vertical = 0.6;
module inside_cherry_cross(slop) {
// inside cross