10 Commits

Author SHA1 Message Date
Bob
fd68c281c3 Custom stem example
Here's how to implement a custom stem
2020-07-10 01:14:25 -04:00
Bob
24e280fe3c quick stem updates
probably best to pass the stem throw to the stems eh?
2020-07-10 00:46:06 -04:00
Bob
69175f08e4 Merge pull request #53 from rsheldiii/cherry-profile
Add cherry profile
2020-06-18 16:14:40 -04:00
Bob
f4f595c651 Add cherry profile 2020-06-18 16:11:35 -04:00
Bob
fa49ee0c70 Merge pull request #46 from rsheldiii/3d_surface
Add 3d surface beta dish
2020-05-13 00:43:48 -04:00
Bob
9e3f5f4bcd Add 3d surface beta dish 2020-05-12 22:25:51 -04:00
Bob
c7602e2ce9 Merge pull request #45 from rsheldiii/improving-shapes-a-bit
Add rounding facets and more skin shapes
2020-05-12 16:22:38 -04:00
Bob
f98c0d4a4f update link in readme
to point to sha so it's perpetually right, even if I update the code
2020-05-12 14:01:06 -04:00
Bob
18892c02b0 add minkowski facets 2020-05-12 12:02:07 -04:00
Bob
9cb3e12b9b Add rounding facets and more skin shapes 2020-05-12 11:57:40 -04:00
33 changed files with 1086 additions and 799 deletions

View File

@@ -1,13 +0,0 @@
CHANGELOG:
V2.0.0:
* added $fa values for minkowski and shape - so you can customize how much rounding there is
* rejiggered `key.scad` pipeline for more clarity and less shapes
* implemented "3d_surface" dish - still in beta
* super cool though, you can even change the distribution of points on the surface! just make sure you use monotonically increasing functions
* created "hull" folder to house different ways of creating the overall key shape
* promoted "feature" folder to first-class folder with keytext and switch clearance as new residents
* wrote this changelog!
* `flat_keytop_bottom` for less geometry. didn't help render rounded keys though
* still todo: add a magic scaling variable so you can scale the whole world up, see if that fixes degeneracy
* side-printed keycaps are first class! you can use the `sideways()` modifier to set up sideways keycaps that have flat sides to print on.
* it's much easier to make quick artisans now that the inside of the keycap is differenced from any additive features placed on top

View File

@@ -60,7 +60,7 @@ You can chain as many modifier functions as you like!
## Modifier functions
There is a bevy of supporting functions to customize your keycaps. You can add a brim to more easily print the stem with `brimmed_stem_support`, make 2x2 keycaps with `2u() 2uh()`, add legends, rotate stems, and more. All these functions manipulate the settings available to you in [`settings.scad`](https://github.com/rsheldiii/KeyV2/blob/master/src/settings.scad), though [some of them](https://github.com/rsheldiii/KeyV2/blob/master/src/key_transformations.scad#L128) are quite complex.
There is a bevy of supporting functions to customize your keycaps. You can add a brim to more easily print the stem with `brimmed_stem_support`, make 2x2 keycaps with `2u() 2uh()`, add legends, rotate stems, and more. All these functions manipulate the settings available to you in [`settings.scad`](https://github.com/rsheldiii/KeyV2/blob/master/src/settings.scad), though [some of them](https://github.com/rsheldiii/KeyV2/blob/851ececdb297c77bfbcd0a7cb4cdbc5e21970396/src/key_transformations.scad#L128) are quite complex.
These modifier functions can be found in [`key_profiles/`](https://github.com/rsheldiii/KeyV2/blob/master/src/key_profiles) for different keycap profiles, [`key_types.scad`](https://github.com/rsheldiii/KeyV2/blob/master/src/key_types.scad) for predefined settings for common keys (spacebar, left shift, etc), [`key_sizes.scad`](https://github.com/rsheldiii/KeyV2/blob/master/src/key_sizes.scad) for common unit sizes, and [`key_transformations.scad`](https://github.com/rsheldiii/KeyV2/blob/master/src/key_transformations.scad) for everything else. I encourage you to do some sleuthing but for a list of (most) helper functions with explanations, [Check out the wiki!](https://github.com/rsheldiii/KeyV2/wiki/KeyV2-Helper-Documentation)

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,10 @@ include <./includes.scad>
// example key
dcs_row(5) legend("⇪", size=9) key();
/* $stem_throw = 1; */
$stem_type = "custom";
$outset_legends = true;
dcs_row(5) front_legend("j") key();
// example row
/* for (x = [0:1:4]) {
@@ -17,4 +20,4 @@ dcs_row(5) legend("⇪", size=9) key();
} */
// example layout
/* preonic_default("dcs"); */
/* preonic_default("dcs"); */

View File

@@ -5,6 +5,7 @@ include <dishes/old_spherical.scad>
include <dishes/sideways_cylindrical.scad>
include <dishes/spherical.scad>
include <dishes/flat.scad>
include <dishes/3d_surface.scad>
//geodesic looks much better, but runs very slow for anything above a 2u
geodesic=false;
@@ -19,9 +20,10 @@ module dish(width, height, depth, inverted) {
}
else if ($dish_type == "sideways cylindrical"){
sideways_cylindrical_dish(width, height, depth, inverted);
}
else if ($dish_type == "old spherical") {
} else if ($dish_type == "old spherical") {
old_spherical_dish(width, height, depth, inverted);
} 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") {

View File

@@ -1,9 +1,14 @@
include <../libraries/3d_surface.scad>
module 3d_surface_dish(width, height, depth, inverted) {
echo(inverted ? "inverted" : "not inverted");
// scale_factor is dead reckoning
scale_factor = 1.2;
// 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;
// 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,0]) 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,90]) 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,5 +0,0 @@
// features are any premade self-contained objects that go on top or inside
include <features/key_bump.scad>
include <features/clearance_check.scad>
include <features/legends.scad>

View File

@@ -1,24 +0,0 @@
// a fake cherry keyswitch, abstracted out to maybe replace with a better one later
module cherry_keyswitch() {
union() {
hull() {
cube([15.6, 15.6, 0.01], center=true);
translate([0,1,5 - 0.01]) cube([10.5,9.5, 0.01], center=true);
}
hull() {
cube([15.6, 15.6, 0.01], center=true);
translate([0,0,-5.5]) cube([13.5,13.5,0.01], center=true);
}
}
}
//approximate (fully depressed) cherry key to check clearances
module clearance_check() {
if($stem_type == "cherry" || $stem_type == "cherry_rounded"){
color($warning_color){
translate([0,0,3.6 + $stem_inset - 5]) {
cherry_keyswitch();
}
}
}
}

View File

@@ -1,26 +0,0 @@
module keytext(text, position, font_size, 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){
text(text=text, font=$font, size=font_size, halign="center", valign="center");
}
}
}
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);
}
}
}
if (len($legends) > 0) {
top_of_key() {
for (i=[0:len($legends)-1]) {
keytext($legends[i][0], $legends[i][1], $legends[i][2], depth);
}
}
}
}

View File

@@ -40,3 +40,22 @@ function vertical_inclination_due_to_top_tilt() = sin($top_tilt) * (top_total_ke
// of the keycap a flat plane. 1 = front, -1 = back
// 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));
// (statically) random!
/* function surface_function(x,y) = sin(rands(0,90,1,x+y)[0]); */

View File

@@ -1,19 +0,0 @@
include <hulls/skin.scad>
include <hulls/linear_extrude.scad>
include <hulls/hull.scad>
// basic key shape, no dish, no inside
// which is only used for dishing to cut the dish off correctly
// $height_difference used for keytop thickness
// extra_slices is a hack to make inverted dishes still work
module shape_hull(thickness_difference, depth_difference, extra_slices = 0){
render() {
if ($skin_extrude_shape) {
skin_extrude_shape_hull(thickness_difference, depth_difference, extra_slices);
} else if ($linear_extrude_shape) {
linear_extrude_shape_hull(thickness_difference, depth_difference, extra_slices);
} else {
hull_shape_hull(thickness_difference, depth_difference, extra_slices);
}
}
}

View File

@@ -1,33 +0,0 @@
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);
}
}
}
module shape_slice(progress, thickness_difference, depth_difference) {
skew_this_slice = $top_skew * progress;
x_skew_this_slice = $top_skew_x * progress;
depth_this_slice = ($total_depth - depth_difference) * progress;
tilt_this_slice = -$top_tilt / $key_height * progress;
y_tilt_this_slice = $double_sculpted ? (-$top_tilt_y / $key_length * progress) : 0;
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 + $minkowski_radius, scale = 0.1){
key_shape(
[
total_key_width(thickness_difference),
total_key_height(thickness_difference)
],
[$width_difference, $height_difference],
progress
);
}
}
}
}

View File

@@ -1,18 +0,0 @@
// corollary is hull_shape_hull
// extra_slices unused, only to match argument signatures
module linear_extrude_shape_hull(thickness_difference, depth_difference, extra_slices = 0){
height = $total_depth - depth_difference;
width_scale = top_total_key_width() / total_key_width();
height_scale = top_total_key_height() / total_key_height();
translate([0,$linear_extrude_height_adjustment,0]){
linear_extrude(height = height, scale = [width_scale, height_scale]) {
translate([0,-$linear_extrude_height_adjustment,0]){
key_shape(
[total_key_width(thickness_difference), total_key_height(thickness_difference)],
[$width_difference, $height_difference]
);
}
}
}
}

View File

@@ -1,34 +0,0 @@
// 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
// a lot more difficult to use
module skin_extrude_shape_hull(thickness_difference, depth_difference, extra_slices = 0 ) {
skin([
for (index = [0:$height_slices + extra_slices])
let(
progress = (index / $height_slices),
skew_this_slice = $top_skew * progress,
x_skew_this_slice = $top_skew_x * progress,
depth_this_slice = ($total_depth - depth_difference) * progress,
tilt_this_slice = -$top_tilt / $key_height * progress,
y_tilt_this_slice = $double_sculpted ? (-$top_tilt_y / $key_length * progress) : 0
)
skin_shape_slice(progress, thickness_difference, skew_this_slice, x_skew_this_slice, depth_this_slice, tilt_this_slice, y_tilt_this_slice)
]);
}
function skin_shape_slice(progress, thickness_difference, skew_this_slice, x_skew_this_slice, depth_this_slice, tilt_this_slice, y_tilt_this_slice) =
transform(
translation([x_skew_this_slice,skew_this_slice,depth_this_slice]),
transform(
rotation([tilt_this_slice,y_tilt_this_slice,0]),
skin_key_shape([
total_key_width(0),
total_key_height(0),
],
[$width_difference, $height_difference],
progress,
thickness_difference
)
)
);

View File

@@ -5,7 +5,7 @@ include <stems.scad>
include <stem_supports.scad>
include <dishes.scad>
include <supports.scad>
include <features.scad>
include <key_features.scad>
include <libraries/geodesic_sphere.scad>
@@ -37,7 +37,7 @@ module rounded_shape() {
// half minkowski in the z direction
color($primary_color) shape_hull($minkowski_radius * 2, $minkowski_radius/2, $inverted_dish ? 2 : 0);
/* cube($minkowski_radius); */
sphere(r=$minkowski_radius, $fn=48);
sphere(r=$minkowski_radius, $fn=$minkowski_facets);
}
}
/* %envelope(); */
@@ -271,6 +271,16 @@ module top_of_key(){
}
}
module keytext(text, position, font_size, 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){
text(text=text, font=$font, size=font_size, halign="center", valign="center");
}
}
}
module keystem_positions(positions) {
for (connector_pos = positions) {
translate(connector_pos) {
@@ -289,23 +299,56 @@ module support_for(positions, stem_type) {
module stems_for(positions, stem_type) {
keystem_positions(positions) {
color($tertiary_color) stem(stem_type, $total_depth, $stem_slop);
color($tertiary_color) stem(stem_type, $total_depth, $stem_slop, $stem_throw);
if ($stem_support_type != "disable") {
color($quaternary_color) stem_support($stem_support_type, stem_type, $stem_support_height, $stem_slop);
}
}
}
// a fake cherry keyswitch, abstracted out to maybe replace with a better one later
module cherry_keyswitch() {
union() {
hull() {
cube([15.6, 15.6, 0.01], center=true);
translate([0,1,5 - 0.01]) cube([10.5,9.5, 0.01], center=true);
}
hull() {
cube([15.6, 15.6, 0.01], center=true);
translate([0,0,-5.5]) cube([13.5,13.5,0.01], center=true);
}
}
}
//approximate (fully depressed) cherry key to check clearances
module clearance_check() {
if($stem_type == "cherry" || $stem_type == "cherry_rounded"){
color($warning_color){
translate([0,0,3.6 + $stem_inset - 5]) {
cherry_keyswitch();
}
}
}
}
module legends(depth=0) {
if (len($front_legends) > 0) {
front_placement() {
if (len($front_legends) > 0) {
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($legends) > 0) {
top_of_key() {
// outset legend
if (len($legends) > 0) {
for (i=[0:len($legends)-1]) {
keytext($legends[i][0], $legends[i][1], $legends[i][2], depth);
}
}
}
}
}

1
src/key_features.scad Normal file
View File

@@ -0,0 +1 @@
include <features/key_bump.scad>

View File

@@ -9,6 +9,7 @@ include <key_profiles/sa.scad>
include <key_profiles/g20.scad>
include <key_profiles/hipro.scad>
include <key_profiles/grid.scad>
include <key_profiles/cherry.scad>
// man, wouldn't it be so cool if functions were first order
module key_profile(key_profile_type, row, column=0) {
@@ -26,6 +27,8 @@ module key_profile(key_profile_type, row, column=0) {
hipro_row(row, column) children();
} else if (key_profile_type == "grid") {
grid_row(row, column) children();
} else if (key_profile_type == "cherry") {
cherry_row(row, column) children();
} else if (key_profile_type == "disable") {
children();
} else {

View File

@@ -0,0 +1,48 @@
// based off GMK keycap set
module cherry_row(row=3, column=0) {
$bottom_key_width = 18.16;
$bottom_key_height = 18.16;
$width_difference = $bottom_key_width - 11.85;
$height_difference = $bottom_key_height - 14.64;
$dish_type = "cylindrical";
$dish_depth = 0.65;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 2;
$top_tilt_y = side_tilt(column);
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
// NOTE: cherry keycaps have this stem inset, but I'm reticent to turn it on
// since it'll be surprising to folks. the height has been adjusted accordingly
// $stem_inset = 0.6;
extra_stem_inset_height = max(0.6 - $stem_inset, 0);
// <= is a hack so you can do these in a for loop. function row = 0
if (row <= 1) {
$total_depth = 9.8 - extra_stem_inset_height + extra_height;
$top_tilt = 0;
children();
} else if (row == 2) {
$total_depth = 7.45 - extra_stem_inset_height + extra_height;
$top_tilt = 2.5;
children();
} else if (row == 3) {
$total_depth = 6.55 - extra_stem_inset_height + extra_height;
$top_tilt = 5;
children();
} else if (row == 3) {
$total_depth = 6.7 + 0.65 - extra_stem_inset_height + extra_height;
$top_tilt = 11.5;
children();
} else if (row >= 4) {
$total_depth = 6.7 + 0.65 - extra_stem_inset_height + extra_height;
$top_tilt = 11.5;
children();
} else {
children();
}
}

View File

@@ -1,7 +1,9 @@
// thanks Paul https://github.com/openscad/list-comprehension-demos/
include <../functions.scad>
module 3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST_POSSIBLE){
function p(x, y) = [ x, y, 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) ];
@@ -34,12 +36,12 @@ module 3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST
}
module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST_POSSIBLE){
function to_polar(q) = q * (90 / size);
function to_polar(q, size) = q * (90 / size);
function p(x, y) = [
surface_distribution_function(to_polar(x)),
surface_distribution_function(to_polar(y)),
surface_function(surface_distribution_function(to_polar(x)), surface_distribution_function(to_polar(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)))
];
function p0(x, y) = [ x, y, bottom ];
function rev(b, v) = b ? v : [ v[3], v[2], v[1], v[0] ];
@@ -72,5 +74,6 @@ module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SM
polyhedron(points, faces, convexity = 8);
}
function surface_distribution_function(dim) = sin(dim) * $3d_surface_size;
// 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));

View File

@@ -1,17 +1,35 @@
function rounded_rectangle_profile(size=[1,1],r=1,fn=32) = [
for (index = [0:fn-1])
let(a = index/fn*360)
r * [cos(a), sin(a)]
+ sign_x(index, fn) * [size[0]/2-r,0]
+ sign_y(index, fn) * [0,size[1]/2-r]
];
function sign_x(i,n) =
i < n/4 || i > n-n/4 ? 1 :
i > n/4 && i < n-n/4 ? -1 :
i < n/4 || i > n*3/4 ? 1 :
i > n/4 && i < n*3/4 ? -1 :
0;
function sign_y(i,n) =
i > 0 && i < n/2 ? 1 :
i > n/2 ? -1 :
0;
function rectangle_profile(size=[1,1],fn=32) = [
for (index = [0:fn-1])
let(a = index/fn*360)
sign_x(index, fn) * [size[0]/2,0]
+ sign_y(index, fn) * [0,size[1]/2]
];
function rounded_rectangle_profile(size=[1,1],r=1,fn=32) = [
let(max_fn = max(fn,8))
for (index = [0:max_fn-1])
let(a = index/max_fn*360)
r * [cos(a), sin(a)]
+ sign_x(index, max_fn) * [size[0]/2-r,0]
+ sign_y(index, max_fn) * [0,size[1]/2-r]
];
function double_rounded_rectangle_profile(size=[1,1], r=1, fn=32) = [
let(max_fn = max(fn,8))
for (index = [0:max_fn-1])
let(a = index/max_fn*360)
r * [cos(a), sin(a)]
+ sign_x(index, max_fn) * [size[0]/2-r,0]
+ sign_y(index, max_fn) * [0,size[1]/2-r]
];

View File

@@ -86,7 +86,7 @@ $extra_long_stem_support = false;
// Key shape type, determines the shape of the key. default is 'rounded square'
$key_shape_type = "rounded_square";
// ISO enter needs to be linear extruded NOT from the center. this tells the program how far up 'not from the center' is
// ISO enter needs to be linear extruded NOT from the center when not using skin. this tells the program how far up 'not from the center' is
$linear_extrude_height_adjustment = 0;
// How many slices will be made, to approximate curves on corners. Leave at 1 if you are not curving corners
// If you're doing fancy bowed keycap sides, this controls how many slices you take
@@ -183,3 +183,13 @@ $secondary_color = [.4412, .7, .3784];
$tertiary_color = [1, .6941, .2];
$quaternary_color = [.4078, .3569, .749];
$warning_color = [1,0,0, 0.15];
// how many facets circles will have when used in these features
$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;

View File

@@ -32,9 +32,11 @@ module key_shape(size, delta, progress = 0) {
function skin_key_shape(size, delta, progress = 0, thickness_difference) =
$key_shape_type == "rounded_square" ?
skin_rounded_square(size, delta, progress) :
skin_rounded_square(size, delta, progress, thickness_difference) :
$key_shape_type == "sculpted_square" ?
skin_sculpted_square_shape(size, delta, progress) :
skin_sculpted_square_shape(size, delta, progress, thickness_difference) :
$key_shape_type == "square" ?
skin_square_shape(size, delta, progress, thickness_difference) :
$key_shape_type == "iso_enter" ?
skin_iso_enter_shape(size, delta, progress, thickness_difference) :
echo("Warning: unsupported $key_shape_type for skin shape. disable skin_extrude_shape or pick a new shape");

View File

@@ -1,12 +1,12 @@
include <../libraries/rounded_rectangle_profile.scad>
module rounded_square_shape(size, delta, progress, center = true) {
offset(r=$corner_radius){
offset(r=$corner_radius, $fa=360/$shape_facets){
square_shape([size.x - $corner_radius*2, size.y - $corner_radius*2], delta, progress);
}
}
// for skin
function skin_rounded_square(size, delta, progress) =
rounded_rectangle_profile(size - (delta * progress), fn=36, r=$corner_radius);
function skin_rounded_square(size, delta, progress, thickness_difference) =
rounded_rectangle_profile(size - (delta * progress), fn=$shape_facets, r=$corner_radius);

View File

@@ -37,7 +37,7 @@ module sculpted_square_shape(size, delta, progress) {
height - extra_height_this_slice
];
offset(r = extra_corner_radius_this_slice) {
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);
}
@@ -46,7 +46,7 @@ module sculpted_square_shape(size, delta, progress) {
// fudging the hell out of this, I don't remember what the negative-offset-positive-offset was doing in the module above
// also no 'bowed' square shape for now
function skin_sculpted_square_shape(size, delta, progress) =
function skin_sculpted_square_shape(size, delta, progress, thickness_difference) =
let(
width = size[0],
height = size[1],
@@ -64,10 +64,10 @@ function skin_sculpted_square_shape(size, delta, progress) =
extra_corner_radius_this_slice = ($corner_radius + extra_corner_size),
square_size = [
width - extra_width_this_slice,
height - extra_height_this_slice
width - extra_width_this_slice - thickness_difference,
height - extra_height_this_slice - thickness_difference
]
) rounded_rectangle_profile(square_size - [extra_corner_radius_this_slice, extra_corner_radius_this_slice]/4, fn=36, r=extra_corner_radius_this_slice/1.5 + $more_side_sculpting_factor * progress);
) double_rounded_rectangle_profile(square_size - [extra_corner_radius_this_slice, extra_corner_radius_this_slice]/4, fn=$shape_facets, r=extra_corner_radius_this_slice/1.5 + $more_side_sculpting_factor * progress);
/* offset(r = extra_corner_radius_this_slice) {
offset(r = -extra_corner_radius_this_slice) {
@@ -85,10 +85,10 @@ module side_rounded_square(size, r) {
sw = iw / resolution;
union() {
if (sr > 0) {
translate([-iw/2, 0]) scale([sr, sh]) circle(d = resolution);
translate([iw/2, 0]) scale([sr, sh]) circle(d = resolution);
translate([0, -ih/2]) scale([sw, sr]) circle(d = resolution);
translate([0, ih/2]) scale([sw, sr]) circle(d = resolution);
translate([-iw/2, 0]) scale([sr, sh]) circle(d = resolution, $fa=360/$shape_facets);
translate([iw/2, 0]) scale([sr, sh]) circle(d = resolution, $fa=360/$shape_facets);
translate([0, -ih/2]) scale([sw, sr]) circle(d = resolution, $fa=360/$shape_facets);
translate([0, ih/2]) scale([sw, sr]) circle(d = resolution, $fa=360/$shape_facets);
}
square([iw, ih], center=true);
}

View File

@@ -1,4 +1,6 @@
use <../functions.scad>
include <../libraries/rounded_rectangle_profile.scad>
// we do this weird key_shape_type check here because rounded_square uses
// square_shape, and we want flat sides to work for that too.
@@ -28,3 +30,17 @@ module flat_sided_square_shape(size, delta, progress) {
[(-size.x + (delta.x - extra_keytop_length_for_flat_sides()) * progress)/2, (size.y - delta.y * progress)/2]
]);
}
function skin_square_shape(size, delta, progress, thickness_difference) =
let(
width = size[0],
height = size[1],
width_difference = delta[0] * progress,
height_difference = delta[1] * progress,
square_size = [
width - width_difference - thickness_difference,
height - height_difference - thickness_difference
]
) rectangle_profile(square_size, fn=36);

View File

@@ -4,22 +4,25 @@ include <stems/box_cherry.scad>
include <stems/alps.scad>
include <stems/filled.scad>
include <stems/cherry_stabilizer.scad>
include <stems/custom.scad>
//whole stem, alps or cherry, trimmed to fit
module stem(stem_type, depth, slop){
module stem(stem_type, depth, slop, throw){
if (stem_type == "alps") {
alps_stem(depth, slop);
alps_stem(depth, slop, throw);
} else if (stem_type == "cherry" || stem_type == "costar_stabilizer") {
cherry_stem(depth, slop);
cherry_stem(depth, slop, throw);
} else if (stem_type == "rounded_cherry") {
rounded_cherry_stem(depth, slop);
rounded_cherry_stem(depth, slop, throw);
} else if (stem_type == "box_cherry") {
box_cherry_stem(depth, slop);
box_cherry_stem(depth, slop, throw);
} else if (stem_type == "filled") {
filled_stem();
} else if (stem_type == "cherry_stabilizer") {
cherry_stabilizer_stem(depth, slop);
cherry_stabilizer_stem(depth, slop, throw);
} else if (stem_type == "custom") {
custom_stem(depth, slop, throw);
} else if (stem_type == "disable") {
children();
} else {

View File

@@ -1,4 +1,4 @@
module alps_stem(depth, has_brim, slop){
module alps_stem(depth, slop, throw){
linear_extrude(height=depth) {
square($alps_stem, center = true);
}

View File

@@ -1,7 +1,7 @@
include <../functions.scad>
include <cherry.scad>
module box_cherry_stem(depth, slop) {
module box_cherry_stem(depth, slop, throw) {
difference(){
// outside shape
linear_extrude(height = depth) {

View File

@@ -23,7 +23,7 @@ module inside_cherry_cross(slop) {
}
}
module cherry_stem(depth, slop) {
module cherry_stem(depth, slop, throw) {
difference(){
// outside shape
linear_extrude(height = depth) {

View File

@@ -15,7 +15,7 @@ module inside_cherry_stabilizer_cross(slop) {
}
}
module cherry_stabilizer_stem(depth, slop) {
module cherry_stabilizer_stem(depth, slop, throw) {
difference(){
// outside shape
linear_extrude(height = depth) {

12
src/stems/custom.scad Normal file
View File

@@ -0,0 +1,12 @@
thickness = .84;
inner_stem_size = [6,4];
outer_stem_size = inner_stem_size + [thickness, thickness];
module custom_stem(depth, slop, throw){
linear_extrude(height=depth) {
difference() {
square(outer_stem_size + [slop,slop], center = true);
square(inner_stem_size + [slop,slop], center = true);
}
}
}

View File

@@ -1,4 +1,4 @@
module filled_stem() {
module filled_stem(_depth, _slop, _throw) {
// I broke the crap out of this stem type due to the changes I made around how stems are differenced
// now that we just take the dish out of stems in order to support stuff like
// bare stem keycaps (and buckling spring eventually) we can't just make a

View File

@@ -1,7 +1,7 @@
include <../functions.scad>
include <cherry.scad>
module rounded_cherry_stem(depth, slop) {
module rounded_cherry_stem(depth, slop, throw) {
difference(){
cylinder(d=$rounded_cherry_stem_d, h=depth);