76 Commits

Author SHA1 Message Date
Bob
19f0d2faad quick fix spacebar dishes
hull() was not working properly with such a wide bottom shape - since envelope was using a bottom square that was 6.25uX6.25u. that might spell trouble for 2x2 POS keycaps though... this should be changed to a skin() function down the line
2022-11-27 23:25:03 -05:00
Bob
7a5d2f00ab Merge pull request #173 from bear454/per-legend-fonts
Font can be explicitly set on a legend
2022-10-14 23:52:27 -04:00
Bob
0a29b1bff8 Merge pull request #172 from rsheldiii/fix-iso-sculpting
Add corner and side sculpting to iso_enter
2022-10-14 20:05:02 -04:00
Bob
5be792e270 add corner and side sculpting to iso_enter 2022-10-14 20:01:29 -04:00
Bob
b172788ddd Merge pull request #161 from limitium/master
Align ASA profile with the Akko implementation
2022-10-14 18:30:28 -04:00
Bob
bfed8b8779 Merge pull request #169 from RyuKojiro/hhkb
Add HHKB layout
2022-10-14 18:23:49 -04:00
Bob
46833f9e42 Merge pull request #171 from rsheldiii/hex-style
Hex style
2022-10-14 18:21:12 -04:00
Bob
8b0a6c57f1 don't use 3d surface for DSA even though its cool 2022-10-14 18:16:57 -04:00
Bob
6b444fd5d3 don't modify keys.scad 2022-10-14 18:11:12 -04:00
Bob
e88a398f7a lots of stuff
* added new hex key shape
* moved corner and side sculpting functions into special variables
* fixed negative inset stems sticking out the top
* added corner smoothing functionality to 3d surface dishes
2022-10-07 12:48:07 -04:00
Daniel Loffgren
1907b87dc5 Add HHKB layout 2022-09-21 22:06:23 -07:00
Daniel Loffgren
1935944ec5 key_types.scad uses stabilized() without including key_transformations.scad 2022-09-21 21:08:29 -07:00
Daniel Loffgren
fe960c2f2a key_types.scad uses u functions without including key_sizes.scad 2022-09-21 20:52:14 -07:00
Daniel Loffgren
9665d5d6a0 layout.scad uses thinks like lshift() without including key_types.scad 2022-09-21 20:43:58 -07:00
Daniel Loffgren
7907d2cd4e layout.scad uses u() without including key_sizes.scad 2022-09-20 23:34:30 -07:00
Daniel Loffgren
80c35b04c3 All of the key_profiles use settings without including at least the default settings 2022-09-20 23:33:32 -07:00
Daniel Loffgren
93f883036f functions.scad uses $double_sculpt_radius without including settings.scad 2022-09-20 23:16:28 -07:00
Daniel Loffgren
c4b622efc6 All of the key profiles use use side_tilt() without including functions.scad 2022-09-20 23:12:54 -07:00
Daniel Loffgren
4c6dbc4306 layout.scad uses key_transformations.scad for translate_u(), and key_transformations.scad for key_profile() 2022-09-20 22:30:54 -07:00
James Mason
8fdd3dcb43 Font can be explicitly set on a legend
... instead of using one font for all legends. Super handy for using a
clear text font alongside an icon font.
2022-08-31 19:31:48 -07:00
Sergey Belov
b0eb0d030c Update asa.scad
Remove comments
2022-05-16 13:54:59 +03:00
Sergey Belov
ca3daeec64 Merge pull request #1 from limitium/fix_asa_profile
Asa profile aligned with the Akko implementation
2022-05-16 13:51:55 +03:00
Sergey Belov
9842ce6ff4 Asa profile aligned with the Akko implementation 2022-05-16 13:51:18 +03:00
Bob
ec44ef76de Merge pull request #155 from rsheldiii/typewriter-style
Typewriter style keys
2022-02-28 02:46:50 -05:00
Bob
19de89dc6e typewriter style keys 2022-02-28 02:45:11 -05:00
Bob
2b8a238f8a TODO.md 2022-02-24 17:50:55 -05:00
Bob
ed0c201894 Merge pull request #153 from rsheldiii/3d_surface_upgrades
Use function literals to make surface functions more fun
2022-02-22 21:05:47 -05:00
Bob
703015dc51 use function literals to make surface functions more fun 2022-02-22 21:00:03 -05:00
Bob
f0e339966f tweak corner rounding and size on mt3 2022-02-22 20:58:22 -05:00
Bob
263bd8ebbf Merge pull request #115 from lvisintini/asa-profile
Add new ASA profile (by Akko)
2022-02-22 16:44:52 -05:00
Bob
1c3960aaff Merge pull request #151 from rsheldiii/v2/backside-frontside
add backside() and fontside() helpers
2022-02-22 16:42:05 -05:00
Bob
4bce68dfbb add backside() and fontside() helpers 2022-02-22 13:11:13 -05:00
Bob
dbe5bca1a9 Merge pull request #150 from rsheldiii/v2/resin
Resin settings, some tines support tweaks
2022-02-22 00:39:26 -05:00
Bob
0c9d05e270 Merge pull request #149 from rsheldiii/hipro-and-mt3
Hipro and MT3 profiles
2022-02-22 00:12:26 -05:00
Bob
8ef5bad891 tweaks on mt3/hipro support 2022-02-22 00:04:21 -05:00
Bob
1a8dd314e4 Merge pull request #106 from mrebersv/master
Two new dishes; clone of MT3 profile; second HiPro clone with more accurate dishes
2022-02-21 16:36:24 -05:00
Bob
cc8892364c fix minkowski top_placement and additive artisans 2022-02-21 16:34:06 -05:00
Bob
2429384b51 resin settings, some tines support tweaks 2022-02-21 16:02:37 -05:00
Bob
1a10d1e5bc Merge pull request #124 from Michal-Szczepaniak/patch-1
Fix preonic_default example
2022-02-21 13:30:18 -05:00
Bob
41381ed376 Merge pull request #148 from rsheldiii/v2/propogate-stem-inner-slop
Correctly support $stem_inner_slop
2022-02-21 13:29:28 -05:00
Bob
08f17a4e1f add stem_inner_slop to all places where it is supposed to be 2022-02-21 13:28:36 -05:00
Bob
4766e3eca6 Merge pull request #117 from AberDerBart/master
Fix rounded_cherry stem to properly use $stem_inner_slop
2022-02-21 13:24:19 -05:00
Bob
19cdb2d9ae Merge pull request #145 from rsheldiii/dependabot/npm_and_yarn/copy-props-2.0.5
Bump copy-props from 2.0.4 to 2.0.5
2022-02-21 13:16:38 -05:00
Bob
75cfa2a856 Merge pull request #147 from rsheldiii/v2/offset-stem-support
V2: Make tine support work for offset stems, remove $extra_long_stem_support
2022-02-21 13:12:24 -05:00
Bob
feb9ec6a71 Make tine support work for offset stems
Also remove extra_long_stem_support as it doesn't work with the new
structure
2022-02-21 12:55:52 -05:00
Bob
4ba88df064 Merge pull request #49 from Xuis/InstructionsModification
Added clear instructions for line you should modify
2022-02-21 12:44:24 -05:00
Bob
315bc83039 Merge branch 'master' into InstructionsModification 2022-02-21 12:44:00 -05:00
dependabot[bot]
077de5ac87 Bump copy-props from 2.0.4 to 2.0.5
Bumps [copy-props](https://github.com/gulpjs/copy-props) from 2.0.4 to 2.0.5.
- [Release notes](https://github.com/gulpjs/copy-props/releases)
- [Changelog](https://github.com/gulpjs/copy-props/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gulpjs/copy-props/compare/2.0.4...2.0.5)

---
updated-dependencies:
- dependency-name: copy-props
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 17:27:07 +00:00
Bob
aad8ddc558 Merge pull request #111 from rsheldiii/dependabot/npm_and_yarn/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7
2022-02-21 12:26:10 -05:00
Bob
5ccd4b7f8d Merge pull request #102 from rsheldiii/dependabot/npm_and_yarn/hosted-git-info-2.8.9
Bump hosted-git-info from 2.8.8 to 2.8.9
2022-02-21 12:26:04 -05:00
Bob
e35d5d354a Merge pull request #97 from rsheldiii/dependabot/npm_and_yarn/y18n-3.2.2
Bump y18n from 3.2.1 to 3.2.2
2022-02-21 12:25:57 -05:00
Bob
47f17efcf1 quick iso enter edits 2022-02-20 02:58:45 -05:00
Bob
d3001e7da0 missing $ 2022-02-20 02:11:19 -05:00
Bob
378af54056 Merge pull request #135 from rsheldiii/force-iso-enter-render
Force ISO enter to render as it does not show in preview
2022-02-19 21:05:06 -05:00
Bob
397a3b84fc force ISO enter to render as it does not show in preview 2022-02-19 21:01:19 -05:00
Bob
2c85ea5c07 add todo 2022-02-19 20:41:41 -05:00
Michał Szczepaniak
38bfbfa61c Fix preonic_default example 2022-01-11 20:43:41 +01:00
Luis Visintini
2d03e5dd4b Updates made after review by @limitium 2021-11-06 14:02:02 +00:00
Jonas Grosse-Holz
7ee9e61412 Fix rounded_cherry stem to properly use $stem_inner_slop 2021-09-27 20:45:47 +02:00
Luis Visintini
665698771f Add new ASA profile (by Akko) 2021-08-30 13:59:43 +01:00
dependabot[bot]
f63de1caf2 Bump path-parse from 1.0.6 to 1.0.7
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-12 09:30:58 +00:00
dependabot[bot]
c6bae9460c Bump y18n from 3.2.1 to 3.2.2
Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-25 03:16:47 +00:00
dependabot[bot]
3fb34bc663 Bump hosted-git-info from 2.8.8 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-25 03:16:41 +00:00
Matthew Ebersviller
1f1f6a62d2 Added deep_dish to matty3 profile 2021-07-21 11:52:19 -06:00
Matthew Ebersviller
fdce624cb1 Update squared_spherical.scad 2021-07-21 11:51:22 -06:00
Matthew Ebersviller
762e45ba3d Fixing 60% row offset the correct way 2021-07-21 09:48:08 -06:00
Matthew Ebersviller
d7ea2bf7cc Editing comment for clarity 2021-07-09 12:26:42 -06:00
Matthew Ebersviller
3fca4e26ca Merge branch 'master' of https://github.com/mrebersv/KeyV2 2021-07-09 12:23:37 -06:00
Matthew Ebersviller
cdf75654a6 fixing 60 percent layout
60 percent layout needed array of [0] for row 0 (Function keys).  Without it, every row was getting the wrong depth/angle.
2021-07-09 12:22:33 -06:00
Matthew Ebersviller
e7b92cf52b Update squared_scoop.scad
Fixed some formatting to be easier to read
2021-07-09 10:57:06 -06:00
mebers200
29f5cd2468 Fixing squared_scoop dish to work with keycaps other than 1u sizing 2021-07-09 10:41:34 -06:00
mebers200
d3c26dfaca fixing squared_spherical dish to work with all sizes 2021-07-09 10:22:03 -06:00
mebers200
13520c54e3 Adding new dishes, a profile clone of MT3 (Matty3), and a second HiPro clone with more accurate dishes. 2021-07-08 20:30:12 -06:00
Will Harris
c81889b298 removed more extraneous space for formatting 2020-06-12 16:18:06 -06:00
Will Harris
0a246489ec removed extra space 2020-06-12 16:14:55 -06:00
Will Harris
654874fb5f Added clear instructions to which line you should modify to generate a key
Addition to the README and a slight change in formatting to accommodate
the extra information
2020-06-12 16:07:31 -06:00
44 changed files with 13363 additions and 762 deletions

View File

@@ -25,7 +25,19 @@ If you are technically inclined at all, this is definitely the best way to run t
First, you'll need OpenSCAD: http://www.openscad.org/downloads.html. I highly recommend installing the development snapshot, as they generally support more features and are relatively stable. Development snapshots are listed in their own section on the downloads page.
After you have openSCAD installed, you need to download the code and run it. running `git clone https://github.com/rsheldiii/KeyV2.git` if you have git, or downloading [this zip](https://github.com/rsheldiii/KeyV2/archive/master.zip) and extracting the directory should do it. Then all you need to do is open `keys.scad` with openSCAD and you are set! It is possible to edit this project with an external editor by checking off Design => 'Automatic Reload and Preview' in OpenSCAD.
After you have openSCAD installed, you need to download the code and run it. running `git clone https://github.com/rsheldiii/openSCAD-projects.git` if you have git, or downloading [this zip](https://github.com/rsheldiii/openSCAD-projects/archive/master.zip) and extracting the directory should do it.
To make your own key, all you need to do is open `keys.scad` with openSCAD and modify this line:
```
dcs_row(5) legend("⇪", size=9) key();
```
To be whatever you want. For example, this is for a ctrl key on an OEM keyboard:
```u(1.25) oem_row(3) legend("ctrl", size=4.5) key();```
It is possible to edit this project with an external editor by checking off Design => 'Automatic Reload and Preview' in OpenSCAD.
All examples below assume you are running the library on your computer with OpenSCAD.
@@ -78,7 +90,7 @@ These modifier functions may not cover every use case; in that case, you may hav
new to the library and still in a beta state, layouts allows you to generate an entire layout for a keyboard!
It is recommended to use tined stem support and set `$extra_long_stem_support = true` if you plan on printing these keycaps.
It is recommended to print layouts with a brim that extends to the next key.
```
60_percent_default("dcs") key();
@@ -186,9 +198,7 @@ Prints from this library are still challenging, despite all efforts to the contr
That's it, if you have any questions feel free to open an issue or leave a comment on thingiverse!
## TODO:
* replace linear_extrude_shape_hull with skin_extrude_shape_hull or something, to enable concave extrusions
* replace current ISO enter shape with one that works for `skin()`
* generate dishes via math?
moved to [TODO doc](./TODO.md)
## Contributions welcome

13
TODO.md Normal file
View File

@@ -0,0 +1,13 @@
TODO:
* implement key_shape_at_progress which allows you to query for the exact 2d outline of the keycap at a given height
* this makes certain functions easier - building the envelope for instance
* requires breaking out shape_slice, and creating a polygon of the skin_shape_slice slices
* dishes add / remove height from keycaps, particularly spherical dishes
* a bandaid solution would be to allow you to modify where the keytop is along the progression of the keycap
* you can't just set a new total_depth because of how width_difference and height_difference work
* the true solution would be to rewrite how the dishes work to make them very graduated at the edges
* implement regular polygon for skin extrusions
* switch to skin-shaped extrusions by default
* kailh choc has a non-square key unit; should I get that working for layouts etc?
* move everything over to layouts requiring a child key
* add an "errors" or "warnings" or "suggestions" echo section in key.scad, right when the key is being made, so the errors don't get lost / repeated

File diff suppressed because it is too large Load Diff

View File

@@ -17,4 +17,4 @@ dcs_row(5) legend("⇪", size=9) key();
} */
// example layout
/* preonic_default("dcs"); */
/* preonic_default("dcs") key(); */

View File

@@ -4,6 +4,8 @@ include <dishes/cylindrical.scad>
include <dishes/old_spherical.scad>
include <dishes/sideways_cylindrical.scad>
include <dishes/spherical.scad>
include <dishes/squared_spherical.scad>
include <dishes/squared_scoop.scad>
include <dishes/flat.scad>
include <dishes/3d_surface.scad>
@@ -14,20 +16,22 @@ geodesic=false;
module dish(width, height, depth, inverted) {
if($dish_type == "cylindrical"){
cylindrical_dish(width, height, depth, inverted);
}
else if ($dish_type == "spherical") {
} else if ($dish_type == "spherical") {
spherical_dish(width, height, depth, inverted);
}
else if ($dish_type == "sideways cylindrical"){
} else if ($dish_type == "sideways cylindrical"){
sideways_cylindrical_dish(width, height, depth, inverted);
} else if ($dish_type == "old spherical") {
old_spherical_dish(width, height, depth, inverted);
} else if ($dish_type == "3d_surface") {
} else if ($dish_type == "3d surface") {
3d_surface_dish(width, height, depth, inverted);
} else if ($dish_type == "flat") {
flat_dish(width, height, depth, inverted);
} else if ($dish_type == "disable") {
// else no dish
} else if ($dish_type == "squared spherical") {
squared_spherical_dish(width, height, depth, inverted=inverted);
} else if ($dish_type == "squared scoop") {
squared_scoop_dish(width, height, depth, inverted=inverted);
} else {
echo("WARN: $dish_type unsupported");
}

View File

@@ -6,9 +6,11 @@ module 3d_surface_dish(width, height, depth, inverted) {
// it doesn't have to be dead reckoning for anything but sculpted sides
// we know the angle of the sides from the width difference, height difference,
// skew and tilt of the top. it's a pain to calculate though
scale_factor = 1.1;
scale_factor = 1.05;
// the edges on this behave differently than with the previous dish implementations
scale([width*scale_factor/$3d_surface_size/2,height*scale_factor/$3d_surface_size/2,depth]) rotate([inverted ? 0:180,0,180]) polar_3d_surface(bottom=-10);
scale([width*scale_factor/$3d_surface_size/2,height*scale_factor/$3d_surface_size/2,depth])
rotate([inverted ? 0:180,0,180])
polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-10);
/* %scale([width*scale_factor/$3d_surface_size/2,height*scale_factor/$3d_surface_size/2,depth]) rotate([180,0,0]) polar_3d_surface(bottom=-10); */
}

View File

@@ -1,4 +1,8 @@
module spherical_dish(width, height, depth, inverted){
// these variables take into account corner_radius and corner_sculpting, resulting in a more correct dish
// they don't fix the core issue though (dishes adding / subtracting height on the edges of the keycap), so I've disabled them
// new_width = $key_shape_type == "sculpted_square" ? width - distance_between_circumscribed_and_inscribed($corner_radius + $corner_sculpting(1)) : width;
// new_height = $key_shape_type == "sculpted_square" ? height - distance_between_circumscribed_and_inscribed($corner_radius + $corner_sculpting(1)) : height;
//same thing as the cylindrical dish here, but we need the corners to just touch - so we have to find the hypotenuse of the top
chord = pow((pow(width,2) + pow(height, 2)),0.5); //getting diagonal of the top

View File

@@ -0,0 +1,34 @@
module squared_scoop_dish(height, width, depth, r=0.5, inverted=false, num=4, den=5){
// changable numerator/denoninator on where to place the square's corners
// for example, num=2, den=3 means the dish will happen at 1/3 and 2/3 the
// width and the height. Defaults to 4/5. Customizable when calling
// this module
//
// This was initially intended for the scoop on the HiPro, since that's what
// it uses. Use "hipro_row()" if that's what you'd like. However, I do NOT
// know how close the inner square is for the HiPro keycaps. In fact, it could
// just be a sphere, in which the "squared spherical" scoop is more appropriate.
// If, however, it the "squared scoop" makes sense, you can adjust where the square
// lands with the num (numerator) and den (denominator) variables. For instance,
// "3" and "4" mean 3/4 of the width/height is where the flat part starts.
chord = pow(pow(height/2, 2) + pow(width/2, 2),0.5);
direction = inverted ? -1 : 1;
//This is the set of points to hull around for the scoop
points=[
[height/den - height/2, width/den - width/2, -chord],
[num*height/den - height/2, width/den - width/2, -chord],
[height/den - height/2, num*width/den - width/2, -chord],
[num*height/den - height/2, num*width/den - width/2, -chord]
];
resize([height,width,depth])
hull() {
shape_slice(1,0,0);
for(i=[0:len(points)-1]) {
translate(points[i])
sphere(r=r,$fn=64);
}
}
}

View File

@@ -0,0 +1,22 @@
module squared_spherical_dish(width, height, depth, inverted=false) {
chord = pow(pow(height / 2, 2) + pow(width / 2, 2),0.5);
direction = inverted ? -1 : 1;
r=max(height,width,chord) / 5;
// ^^^^^ Nothing special about this code to figure out r.
// I just modeled up 1u, 1.25u, 1.5u, 2u, 2.25u, and 2.75u
// keys and messed around until I came up with something that
// looked reasonable for all key sizes. This just seems to work
// well for all sizes
translate([-width / 2, -height / 2, 0 * direction]) {
resize([width, height, depth])
hull() {
cube([chord,chord,0.001]);
// Use something larger in this translate than -depth
// (like -chord) if you want more of a defined circle
// in the keywell
translate([chord/2, chord/2, -depth])
sphere(r=r, $fn=128);
}
}
}

View File

@@ -1,9 +1,9 @@
module keytext(text, position, font_size, depth) {
module keytext(text, position, font_size, font_face, depth) {
woffset = (top_total_key_width()/3.5) * position[0];
hoffset = (top_total_key_height()/3.5) * -position[1];
translate([woffset, hoffset, -depth]){
color($tertiary_color) linear_extrude(height=$dish_depth + depth){
text(text=text, font=$font, size=font_size, halign="center", valign="center");
text(text=text, font=font_face, size=font_size, halign="center", valign="center");
}
}
}
@@ -12,14 +12,14 @@ module legends(depth=0) {
if (len($front_legends) > 0) {
front_of_key() {
for (i=[0:len($front_legends)-1]) {
rotate([90,0,0]) keytext($front_legends[i][0], $front_legends[i][1], $front_legends[i][2], depth);
rotate([90,0,0]) keytext($front_legends[i][0], $front_legends[i][1], $front_legends[i][2], $front_legends[i][3], depth);
}
}
}
if (len($legends) > 0) {
top_of_key() {
for (i=[0:len($legends)-1]) {
keytext($legends[i][0], $legends[i][1], $legends[i][2], depth);
keytext($legends[i][0], $legends[i][1], $legends[i][2], $legends[i][3], depth);
}
}
}

View File

@@ -1,10 +1,11 @@
include <constants.scad>
include <settings.scad>
// I use functions when I need to compute special variables off of other special variables
// functions need to be explicitly included, unlike special variables, which
// just need to have been set before they are used. hence this file
function stem_height() = $total_depth - $dish_depth - $stem_inset;
function stem_height() = $total_depth - ($dish_depth * ($inverted_dish ? -1 : 1)) - $stem_inset;
// cherry stem dimensions
function outer_cherry_stem(slop) = [7.2 - slop * 2, 5.5 - slop * 2];
@@ -23,6 +24,10 @@ function cherry_cross(slop, extra_vertical = 0) = [
[1.15 + slop / 3, 4.23 + extra_vertical + slop / 3 + SMALLEST_POSSIBLE],
];
// TODO add side_sculpting
function key_width_at_progress(progress = 0) = $bottom_key_width + ($unit * ($key_length - 1)) - $width_difference;
function key_height_at_progress(progress = 0) = $bottom_key_height + ($unit * ($key_height - 1)) - $height_difference + $side_sculpting(progress);
// actual mm key width and height
function total_key_width(delta = 0) = $bottom_key_width + $unit * ($key_length - 1) - delta;
function total_key_height(delta = 0) = $bottom_key_height + $unit * ($key_height - 1) - delta;
@@ -33,7 +38,7 @@ function top_total_key_height() = $bottom_key_height + ($unit * ($key_height - 1
function side_tilt(column) = asin($unit * column / $double_sculpt_radius);
// tan of 0 is 0, division by 0 is nan, so we have to guard
function extra_side_tilt_height(column) = side_tilt(column) ? ($double_sculpt_radius - (unit * abs(column)) / tan(abs(side_tilt(column)))) : 0;
function extra_side_tilt_height(column) = side_tilt(column) ? ($double_sculpt_radius - ($unit * abs(column)) / tan(abs(side_tilt(column)))) : 0;
// (I think) extra length of the side of the keycap due to the keytop being tilted.
// necessary for calculating flat sided keycaps
@@ -43,30 +48,11 @@ function vertical_inclination_due_to_top_tilt() = sin($top_tilt) * (top_total_ke
// I derived this through a bunch of trig reductions I don't really understand.
function extra_keytop_length_for_flat_sides() = ($width_difference * vertical_inclination_due_to_top_tilt()) / ($total_depth);
// 3d surface functions (still in beta)
// monotonically increasing function that distributes the points of the surface mesh
// only for polar_3d_surface right now
// if it's linear it's a grid. sin(dim) * size concentrates detail around the edges
function surface_distribution_function(dim, size) = sin(dim) * size;
// the function that actually determines what the surface is.
// feel free to override, the last one wins
// debug
function surface_function(x,y) = 1;
// cylindrical
function surface_function(x,y) = (sin(acos(x/$3d_surface_size)));
// spherical
function surface_function(x,y) = (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));
// ripples
/* function surface_function(x,y) = cos(pow(pow(x,2)+pow(y,2),0.5)*10)/4+0.75; */
// Rosenbrock's banana
/* function surface_function(x,y) = (pow(1-(x/100), 2) + 100 * pow((y/100)-pow((x/100),2),2))/200 + 0.1; */
// y=x revolved around the y axis
/* function surface_function(x,y) = 1/(pow(pow(x,2)+pow(y,2),0.5)/100 + .01); */
/* function surface_function(x,y) = sin(rands(0,90,1,x+y)[0]); */
// adds uniform rounding radius for round-anything polyRound
function add_rounding(p, radius)=[for(i=[0:len(p)-1])[p[i].x,p[i].y, radius]];
// computes millimeter length from unit length
function unit_length(length) = $unit * (length - 1) + 18.16;
// if you have a radius of an inscribed circle, this function gives you the extra length for the radius of the circumscribed circle
// and vice versa. used to find the edge of a rounded_square
function distance_between_circumscribed_and_inscribed(radius) = (pow(2, 0.5) - 1) * radius;

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() {
shape_slice(index / $height_slices, thickness_difference, depth_difference);
shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
placed_shape_slice(index / $height_slices, thickness_difference, depth_difference);
placed_shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
}
}
}
module shape_slice(progress, thickness_difference, depth_difference) {
module placed_shape_slice(progress, thickness_difference, depth_difference) {
skew_this_slice = $top_skew * progress;
x_skew_this_slice = $top_skew_x * progress;
@@ -18,16 +18,20 @@ module shape_slice(progress, thickness_difference, depth_difference) {
translate([x_skew_this_slice, skew_this_slice, depth_this_slice]) {
rotate([tilt_this_slice,y_tilt_this_slice,0]){
linear_extrude(height = SMALLEST_POSSIBLE, scale = 1){
key_shape(
[
total_key_width(thickness_difference),
total_key_height(thickness_difference)
],
[$width_difference, $height_difference],
progress
);
}
shape_slice(progress, thickness_difference, depth_difference);
}
}
}
module shape_slice(progress, thickness_difference, depth_difference) {
linear_extrude(height = SMALLEST_POSSIBLE, scale = 1){
key_shape(
[
total_key_width(thickness_difference),
total_key_height(thickness_difference)
],
[$width_difference, $height_difference],
progress
);
}
}

View File

@@ -17,14 +17,13 @@ use <libraries/scad-utils/lists.scad>
use <libraries/scad-utils/shapes.scad>
use <libraries/skin.scad>
// key shape including dish. used as the ouside and inside shape in hollow_key(). allows for itself to be shrunk in depth and width / height
// key shape including dish. used as the outside and inside shape in hollow_key(). allows for itself to be shrunk in depth and width / height
module shape(thickness_difference, depth_difference=0){
dished(depth_difference, $inverted_dish) {
color($primary_color) shape_hull(thickness_difference, depth_difference, $inverted_dish ? 200 : 0);
}
}
// Not currently used due to CGAL errors. Rounds the shape via minkowski
module rounded_shape() {
color($primary_color) minkowski(){
// half minkowski in the z direction
@@ -47,12 +46,13 @@ module minkowski_object() {
}
}
module envelope(depth_difference=0) {
s = 1.5;
module envelope(depth_difference=0, extra_floor_depth=0) {
size = 1.5;
hull(){
cube([total_key_width() * s, total_key_height() * s, 0.01], center = true);
translate([0,0,extra_floor_depth]) cube([key_width_at_progress(extra_floor_depth / $total_depth) * size, key_height_at_progress(extra_floor_depth / $total_depth) * size, 0.01], center = true);
top_placement(SMALLEST_POSSIBLE + depth_difference){
cube([top_total_key_width() * s, top_total_key_height() * s, 0.01], center = true);
cube([top_total_key_width() * size, top_total_key_height() * size, 0.01], center = true);
}
}
}
@@ -65,12 +65,12 @@ module dished(depth_difference = 0, inverted = false) {
children();
difference(){
union() {
// envelope is needed to "fill in" the rest of the keycap
envelope(depth_difference);
// envelope is needed to "fill in" the rest of the keycap. intersections with small objects are much faster than differences with large objects
envelope(depth_difference, $stem_inset);
if (inverted) top_placement(depth_difference) color($secondary_color) _dish(inverted);
}
if (!inverted) top_placement(depth_difference) color($secondary_color) _dish(inverted);
/* %top_placement(depth_difference) _dish(); */
// %top_placement(depth_difference) _dish();
}
}
}
@@ -80,6 +80,7 @@ module dished(depth_difference = 0, inverted = false) {
module _dish(inverted=$inverted_dish) {
translate([$dish_offset_x,0,0]) color($secondary_color)
dish(top_total_key_width() + $dish_overdraw_width, top_total_key_height() + $dish_overdraw_height, $dish_depth, inverted);
// %dish(top_total_key_width() + $dish_overdraw_width, top_total_key_height() + $dish_overdraw_height, $dish_depth, inverted);
}
// puts its children at each keystem position provided
@@ -113,9 +114,9 @@ module top_placement(depth_difference=0) {
top_tilt_by_height = -$top_tilt / $key_height;
top_tilt_y_by_length = $double_sculpted ? (-$top_tilt_y / $key_length) : 0;
minkowski_height = $rounded_key ? $minkowski_radius : 0;
// minkowski_height = $rounded_key ? $minkowski_radius : 0;
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference + minkowski_height/2]){
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference]){
rotate([top_tilt_by_height, top_tilt_y_by_length,0]){
children();
}
@@ -235,10 +236,12 @@ module outer_total_shape(inset=false) {
// takes all the bits and glues them together. requires configuration with special variables.
module key(inset=false) {
difference(){
outer_total_shape(inset);
outer_total_shape(inset) {
children();
};
if ($inner_shape_type != "disable") {
translate([0,0,-SMALLEST_POSSIBLE]) {
translate([0,0,-SMALLEST_POSSIBLE]) { // avoids moire
inner_total_shape();
}
}
@@ -248,10 +251,12 @@ module key(inset=false) {
};
}
// if $stem_inset is less than zero, we add the
// semi-hack to make sure negative inset stems don't poke through the top of the keycap
if ($stem_inset < 0) {
stems_and_stabilizers();
}
dished(0, $inverted_dish) {
stems_and_stabilizers();
}
}
}
// actual full key with space carved out and keystem/stabilizer connectors

View File

@@ -8,10 +8,14 @@ include <key_profiles/dsa.scad>
include <key_profiles/sa.scad>
include <key_profiles/g20.scad>
include <key_profiles/hipro.scad>
include <key_profiles/mt3.scad>
include <key_profiles/grid.scad>
include <key_profiles/regular_polygon.scad>
include <key_profiles/cherry.scad>
include <key_profiles/dss.scad>
include <key_profiles/asa.scad>
include <key_profiles/typewriter.scad>
include <key_profiles/hex.scad>
// man, wouldn't it be so cool if functions were first order
module key_profile(key_profile_type, row, column=0) {
@@ -25,18 +29,26 @@ module key_profile(key_profile_type, row, column=0) {
dss_row(row, column) children();
} else if (key_profile_type == "sa") {
sa_row(row, column) children();
} else if (key_profile_type == "asa") {
asa_row(row, column) children();
} else if (key_profile_type == "g20") {
g20_row(row, column) children();
} else if (key_profile_type == "hipro") {
hipro_row(row, column) children();
} else if (key_profile_type == "grid") {
grid_row(row, column) children();
} else if (key_profile_type == "typewriter") {
typewriter_row(row, column) children();
} else if (key_profile_type == "hex") { // reddit.com/r/MechanicalKeyboards/comments/kza7ji
hex_row(row, column) children();
} else if (key_profile_type == "hexagon") {
hexagonal_row(row, column) children();
} else if (key_profile_type == "octagon") {
octagonal_row(row, column) children();
} else if (key_profile_type == "cherry") {
cherry_row(row, column) children();
} else if (key_profile_type == "mt3") {
mt3_row(row, column) children();
} else if (key_profile_type == "disable") {
children();
} else {

44
src/key_profiles/asa.scad Normal file
View File

@@ -0,0 +1,44 @@
use <../functions.scad>
include <../settings.scad>
module asa_row(row=3, column = 0) {
$key_shape_type = "sculpted_square";
$bottom_key_height = 18.15;
$bottom_key_width = 18.10; // Default (R3)
$total_depth = 10.75; // Default (R3)
$top_tilt = 1.5; // Default (R3)
$width_difference = 6.20;
$height_difference = 6.55;
$dish_type = "spherical";
$dish_depth = 1.3;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 1.75;
$stem_inset = 1.2;
$height_slices = 10;
$corner_radius = 1;
$more_side_sculpting_factor = 0.4;
$side_sculpting = function(progress) (1 - progress) * 4.5;
$corner_sculpting = function(progress) pow(progress, 2);
// this is _incredibly_ intensive
//$rounded_key = true;
if (row == 1){
$total_depth = 10.5;
$top_tilt = 9.33;
children();
} else if (row == 2) {
$total_depth = 9.95;
$top_tilt = 4;
children();
} else if (row == 4){
$total_depth = 12.55;
$top_tilt = 0.43;
children();
}else{
children();
}
}

View File

@@ -1,3 +1,6 @@
use <../functions.scad>
include <../settings.scad>
// based off GMK keycap set
module cherry_row(row=3, column=0) {

View File

@@ -1,3 +1,6 @@
use <../functions.scad>
include <../settings.scad>
module dcs_row(row=3, column=0) {
$bottom_key_width = 18.16;
$bottom_key_height = 18.16;

View File

@@ -1,3 +1,6 @@
use <../functions.scad>
include <../settings.scad>
module dsa_row(row=3, column = 0) {
$key_shape_type = "sculpted_square";
$bottom_key_width = 18.24; // 18.4;
@@ -11,8 +14,12 @@ module dsa_row(row=3, column = 0) {
$dish_skew_x = 0;
$dish_skew_y = 0;
$height_slices = 10;
$enable_side_sculpting = true;
$side_sculpting = function(progress) (1 - progress) * 4.5;
$corner_sculpting = function(progress) pow(progress, 2);
$corner_radius = 1;
$more_side_sculpting_factor = 0.4;
$top_tilt_y = side_tilt(column);
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;

View File

@@ -1,3 +1,6 @@
use <../functions.scad>
include <../settings.scad>
module dss_row(n=3, column=0) {
$key_shape_type = "sculpted_square";
$bottom_key_width = 18.24;
@@ -10,10 +13,13 @@ module dss_row(n=3, column=0) {
$dish_skew_y = 0;
$top_skew = 0;
$height_slices = 10;
$enable_side_sculpting = true;
// might wanna change this if you don't minkowski
// do you even minkowski bro
$corner_radius = 1;
$more_side_sculpting_factor = 0.4;
$side_sculpting = function(progress) (1 - progress) * 4.5;
$corner_sculpting = function(progress) pow(progress, 2);
// this is _incredibly_ intensive
/* $rounded_key = true; */

View File

@@ -1,3 +1,6 @@
use <../functions.scad>
include <../settings.scad>
module g20_row(row=3, column = 0) {
$bottom_key_width = 18.16;
$bottom_key_height = 18.16;

View File

@@ -1,3 +1,6 @@
use <../functions.scad>
include <../settings.scad>
module grid_row(row=3, column = 0) {
$bottom_key_width = 18.16;
$bottom_key_height = 18.16;

62
src/key_profiles/hex.scad Normal file
View File

@@ -0,0 +1,62 @@
include <../constants.scad>
// Regular polygon shapes CIRCUMSCRIBE the sphere of diameter $bottom_key_width
// This is to make tiling them easier, like in the case of hexagonal keycaps etc
// this function doesn't set the key shape, so you can't use it directly without some fiddling
module hex_row(n=3, column=0) {
$bottom_key_width = $unit - 0.5;
$bottom_key_height = $unit - 0.5;
$width_difference = 0;
$height_difference = 0;
$dish_type = "spherical";
$key_shape_type = "hexagon";
$stem_inset = -2.5;
$stem_throw = 3;
// $dish_depth = 1;
$top_skew = 0;
$height_slices = 1;
$stem_support_type = "disable";
$dish_overdraw_width = -8.25;
$dish_overdraw_height = -8.25;
// $corner_radius = 1;
// this is _incredibly_ intensive
/* $rounded_key = true; */
$top_tilt_y = side_tilt(column);
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
base_depth = 4;
if (n <= 1){
$total_depth = base_depth + 2.5 + extra_height;
$top_tilt = -13;
children();
} else if (n == 2) {
$total_depth = base_depth + 0.5 + extra_height;
$top_tilt = -7;
children();
} else if (n == 3) {
$total_depth = base_depth + extra_height;
$top_tilt = 0;
children();
} else if (n == 4){
$total_depth = base_depth + 0.5 + extra_height;
$top_tilt = 7;
children();
} else {
$total_depth = base_depth + extra_height;
$top_tilt = 0;
children();
}
}

View File

@@ -1,4 +1,6 @@
// my own measurements
use <../functions.scad>
include <../settings.scad>
module hipro_row(row=3, column=0) {
$key_shape_type = "sculpted_square";
@@ -7,13 +9,18 @@ module hipro_row(row=3, column=0) {
$width_difference = ($bottom_key_width - 12.3);
$height_difference = ($bottom_key_height - 12.65);
$dish_type = "spherical";
$dish_type = "squared scoop";
$dish_depth = 0.75;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 0;
$height_slices = 10;
$corner_radius = 1;
$more_side_sculpting_factor = 0.4;
$side_sculpting = function(progress) (1 - progress) * 4.5;
$corner_sculpting = function(progress) pow(progress, 2);
$top_tilt_y = side_tilt(column);
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;

58
src/key_profiles/mt3.scad Normal file
View File

@@ -0,0 +1,58 @@
use <../functions.scad>
include <../settings.scad>
// This is an imperfect attempt to clone the MT3 profile
module mt3_row(row=3, column=0, deep_dish=false) {
$key_shape_type = "sculpted_square";
$bottom_key_width = 18.35;
$bottom_key_height = 18.6;
$width_difference = ($bottom_key_width - 13.0);
$height_difference = ($bottom_key_height - 13.0);
$dish_type = "squared spherical";
$dish_depth = deep_dish ? 1.6 : 1.2;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 0;
$height_slices = 10;
$corner_radius = 0.0125;
$more_side_sculpting_factor = 0.75;
$side_sculpting = function(progress) (1 - progress) * 4.5;
$corner_sculpting = function(progress) pow(progress, 2) * 2;
$top_tilt_y = side_tilt(column);
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
if (row == 0){
// TODO I didn't change these yet
$total_depth = 14.7 + extra_height;
$top_tilt = -12.5;
children();
} else if (row == 1) {
$total_depth = 13.1 + extra_height;
$top_tilt = -6;
children();
} else if (row == 2) {
$total_depth = 10.7 + extra_height;
$top_tilt = -6;
children();
} else if (row == 3) {
$total_depth = 10.7 + extra_height;
$top_tilt = 6;
children();
} else if (row == 4){
$total_depth = 11.6 + extra_height;
$top_tilt = 12;
children();
} else if (row >= 5) {
$total_depth = 11.6 + extra_height;
$top_tilt = 0;
children();
} else {
children();
}
}

View File

@@ -1,3 +1,6 @@
use <../functions.scad>
include <../settings.scad>
module oem_row(row=3, column = 0) {
$bottom_key_width = 18.05;
$bottom_key_height = 18.05;

View File

@@ -1,3 +1,5 @@
use <../functions.scad>
include <../settings.scad>
include <../constants.scad>
// Regular polygon shapes CIRCUMSCRIBE the sphere of diameter $bottom_key_width
// This is to make tiling them easier, like in the case of hexagonal keycaps etc

View File

@@ -1,3 +1,6 @@
use <../functions.scad>
include <../settings.scad>
module sa_row(n=3, column=0) {
$key_shape_type = "sculpted_square";
$bottom_key_width = 18.4;
@@ -10,7 +13,12 @@ module sa_row(n=3, column=0) {
$dish_skew_y = 0;
$top_skew = 0;
$height_slices = 10;
$corner_radius = 1;
$more_side_sculpting_factor = 0.4;
$side_sculpting = function(progress) (1 - progress) * 4.5;
$corner_sculpting = function(progress) pow(progress, 2);
// this is _incredibly_ intensive
/* $rounded_key = true; */

View File

@@ -0,0 +1,59 @@
use <../functions.scad>
include <../settings.scad>
include <../constants.scad>
// Regular polygon shapes CIRCUMSCRIBE the sphere of diameter $bottom_key_width
// This is to make tiling them easier, like in the case of hexagonal keycaps etc
// this function doesn't set the key shape, so you can't use it directly without some fiddling
module typewriter_row(n=3, column=0) {
$bottom_key_width = $unit - 0.5;
$bottom_key_height = $unit - 0.5;
$width_difference = 0;
$height_difference = 0;
$dish_type = "spherical";
$key_shape_type = "circular";
$inverted_dish = true;
$stem_inset = -4.5;
$stem_throw = 5;
$dish_depth = 4;
$dish_skew_x = 0;
$dish_skew_y = 0;
$top_skew = 0;
$height_slices = 1;
$stem_support_type = "disable";
// $corner_radius = 1;
// this is _incredibly_ intensive
/* $rounded_key = true; */
$top_tilt_y = side_tilt(column);
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
base_depth = 3.5;
if (n <= 1){
$total_depth = base_depth + 2.5 + extra_height;
$top_tilt = -13;
children();
} else if (n == 2) {
$total_depth = base_depth + 0.5 + extra_height;
$top_tilt = -7;
children();
} else if (n == 3) {
$total_depth = base_depth + extra_height;
$top_tilt = 0;
children();
} else if (n == 4){
$total_depth = base_depth + 0.5 + extra_height;
$top_tilt = 7;
children();
} else {
$total_depth = base_depth + extra_height;
$top_tilt = 0;
children();
}
}

View File

@@ -158,15 +158,17 @@ module flat_support() {
children();
}
module legend(text, position=[0,0], size=undef) {
module legend(text, position=[0,0], size=undef, font=undef) {
font_size = size == undef ? $font_size : size;
$legends = [for(L=[$legends, [[text, position, font_size]]], a=L) a];
font_face = font == undef ? $font : font;
$legends = [for(L=[$legends, [[text, position, font_size, font_face]]], a=L) a];
children();
}
module front_legend(text, position=[0,0], size=undef) {
module front_legend(text, position=[0,0], size=undef, font=undef) {
font_size = size == undef ? $font_size : size;
$front_legends = [for(L=[$front_legends, [[text, position, font_size]]], a=L) a];
font_face = font == undef ? $font : font;
$front_legends = [for(L=[$front_legends, [[text, position, font_size, font_face]]], a=L) a];
children();
}
@@ -193,13 +195,68 @@ module upside_down() {
}
module sideways() {
$stem_support_type = "disable";
$key_shape_type = "flat_sided_square";
$dish_overdraw_width = abs(extra_keytop_length_for_flat_sides());
extra_y_rotation = atan2($width_difference/2,$total_depth);
extra_y_rotation = atan2($width_difference/2,$total_depth); // TODO assumes centered top
translate([0,0,cos(extra_y_rotation) * total_key_width()/2])
rotate([0,90 + extra_y_rotation ,0]) children();
}
/* this is hard to explain. we want the angle of the back of the keycap.
* first we draw a line at the back of the keycap perpendicular to the ground.
* then we extend the line created by the slope of the keytop to that line
* the angle of the latter line off the ground is $top_tilt, and
* you can create a right triangle with the adjacent edge being $bottom_key_height/2
* raised up $total_depth. this gets you x, the component of the extended
* keytop slope line, and y, a component of the first perpendicular line.
* by a very similar triangle you get r and s, where x is the hypotenuse of that
* right triangle and the right angle is again against the first perpendicular line
* s is the opposite line in the right triangle required to find q, the angle
* of the back. if you subtract r from $total_depth plus y you can now use these
* two values in atan to find the angle of interest.
*/
module backside() {
$stem_support_type = "disable";
// $key_shape_type = "flat_sided_square";
a = $bottom_key_height;
b = $total_depth;
c = top_total_key_height();
x = (a / 2 - $top_skew) / cos(-$top_tilt) - c / 2;
y = sin(-$top_tilt) * (x + c/2);
r = sin(-$top_tilt) * x;
s = cos(-$top_tilt) * x;
q = atan2(s, (y + b - r));
translate([0,0,cos(q) * total_key_height()/2])
rotate([-90 - q, 0,0]) children();
}
// this is just backside with a few signs switched
module frontside() {
$stem_support_type = "disable";
// $key_shape_type = "flat_sided_square";
a = $bottom_key_height;
b = $total_depth;
c = top_total_key_height();
x = (a / 2 + $top_skew) / cos($top_tilt) - c / 2;
y = sin($top_tilt) * (x + c/2);
r = sin($top_tilt) * x;
s = cos($top_tilt) * x;
q = atan2(s, (y + b - r));
translate([0,0,cos(q) * total_key_height()/2])
rotate([90 + q, 0,0]) children();
}
// emulating the % modifier.
// since we use custom colors, just using the % modifier doesn't work
module debug() {
@@ -223,3 +280,11 @@ module auto_place() {
translate_u(x,-y) children(child_index);
}
}
// suggested settings for resin prints
module resin() {
$stem_slop = 0;
$stem_inner_slop = 0;
$stem_support_type = "disable";
children();
}

View File

@@ -1,4 +1,6 @@
include <functions.scad>
use <key_sizes.scad>
use <key_transformations.scad>
module spacebar() {
$inverted_dish = $dish_type != "disable";
@@ -50,13 +52,14 @@ module iso_enter() {
/* $top_tilt = 0; */
$stem_support_type = "disable";
$key_shape_type = "iso_enter";
/* $hull_shape_type = "linear extrude"; */
$hull_shape_type = "skin";
$linear_extrude_height_adjustment = 19.05 * 0.5;
// this equals (unit_length(1.5) - unit_length(1.25)) / 2
/* $dish_overdraw_width = 2.38125; */
stabilized(vertical=true) {
children();
render() {
stabilized(vertical=true) {
children();
}
}
}

View File

@@ -17,5 +17,5 @@ include <../layout.scad>
];
module 60_percent_default(profile) {
layout(60_percent_default_layout, profile, 60_percent_legends) children();
layout(60_percent_default_layout, profile, 60_percent_legends, row_sculpting_offset=1) children();
}

View File

@@ -0,0 +1,21 @@
include <../layout.scad>
hhkb_layout = [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1.5,1,1,1,1,1,1,1,1,1,1,1,1,1.5],
[1.75,1,1,1,1,1,1,1,1,1,1,1,2.25],
[2.25,1,1,1,1,1,1,1,1,1,1,1.75,1],
[-1.5,1,1.5,6,1.5,1]
];
hhkb_legends = [
["Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "\\", "`"],
["Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "Delete"],
["Ctrl", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "Return"],
["Shift", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "Shift", "Fn"],
["", "Alt", "Cmd", "", "Cmd", "Alt"],
];
module hhkb_default(profile) {
layout(hhkb_layout, profile, hhkb_legends) children();
}

View File

@@ -1,3 +1,8 @@
use <../key_transformations.scad>
use <../key_profiles.scad>
use <../key_sizes.scad>
use <../key_types.scad>
// sums all values, unless a value is negative, in which case it makes it positive
// dirty hack to allow for large gaps in keysets
function abs_sum(list, x=0) =

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) * $corner_smoothing_surface_function(x,y)) ];
function p0(x, y) = [ x, y, bottom ];
function rev(b, v) = b ? v : [ v[3], v[2], v[1], v[0] ];
function face(x, y) = [ p(x, y + step), p(x + step, y + step), p(x + step, y), p(x + step, y), p(x, y), p(x, y + step) ];
@@ -35,13 +35,13 @@ module 3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST
polyhedron(points, faces, convexity = 8);
}
module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST_POSSIBLE){
module polar_3d_surface(size, step, bottom=-SMALLEST_POSSIBLE){
function to_polar(q, size) = q * (90 / size);
function p(x, y) = [
surface_distribution_function(to_polar(x, size), size),
surface_distribution_function(to_polar(y, size), size),
max(0,surface_function(surface_distribution_function(to_polar(x, size), size), surface_distribution_function(to_polar(y, size), size)))
$surface_distribution_function(to_polar(x, size), size),
$surface_distribution_function(to_polar(y, size), size),
max(0,$surface_function($surface_distribution_function(to_polar(x, size), size), $surface_distribution_function(to_polar(y, size), size)) * $corner_smoothing_surface_function($surface_distribution_function(to_polar(x, size), size), $surface_distribution_function(to_polar(y, size), size)))
];
function p0(x, y) = [ x, y, bottom ];
function rev(b, v) = b ? v : [ v[3], v[2], v[1], v[0] ];
@@ -75,5 +75,5 @@ module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SM
}
// defaults, overridden in functions.scad
function surface_distribution_function(dim, size) = sin(dim) * size;
function surface_function(x,y) = (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));
// $surface_distribution_function = function(dim, size) sin(dim) * size;
// $surface_function = function(x,y) (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));

View File

@@ -76,12 +76,10 @@ $rounded_cherry_stem_d = 5.5;
// Inset stem requires support but is more accurate in some profiles
// can be negative to make outset stems!
$stem_inset = 0;
// How many degrees to rotate the stems. useful for sideways keycaps, maybe
// How many degrees to rotate the stems. useful for sideways keycaps
$stem_rotation = 0;
// enable to have stem support extend past the keycap bottom, to (hopefully) the next
// keycap. only works on tines right now
$extra_long_stem_support = false;
// How many degrees to rotate the keycap, but _not_ inside features (the stem).
$keycap_rotation = 0;
/* [Shape] */
@@ -194,11 +192,60 @@ $warning_color = [1,0,0, 0.15];
$minkowski_facets = 30;
$shape_facets =30;
// 3d surface settings
// unused for now
$3d_surface_size = 100;
// resolution in each axis. 10 = 10 divisions per x/y = 100 points total
$3d_surface_step = 10;
// "flat" / "dished" / "disable"
$inner_shape_type = "flat";
// default side_sculpting function, linear
$side_sculpting = function(progress) 0;
$corner_sculpting = function(progress) 0;
// you probably shouldn't touch this, it's internal to sculpted_square
// modify side sculpting with the $side_sculpting function in the key profile files
$more_side_sculpting_factor = 0;
// 3d surface functions (still in beta)
// 3d surface settings
// unused for now
$3d_surface_size = 1;
// 3d surface point resolution. $3d_surface_size / $3d_surface_step = steps per x / y
$3d_surface_step = 1/20;
// monotonically increasing function that distributes the points of the surface mesh
// only for polar_3d_surface right now
// if it's linear it's a grid. sin(dim) * size concentrates detail around the edges
sinusoidal_surface_distribution = function(dim,size) sin(dim) * size;
linear_surface_distribution = function(dim,size) dim;
$surface_distribution_function = sinusoidal_surface_distribution;
// the function that actually determines what the surface is.
// feel free to override, the last one wins
// debug
// $surface_function = function(x,y) 1;
cylindrical_surface = function(x,y) (sin(acos(x/$3d_surface_size)));
spherical_surface = function(x,y) (1 - (x/$3d_surface_size)^2)^0.5 * (1 - (y/$3d_surface_size)^2)^0.5;
// looks a lot like mt3
quartic_surface = function(x,y) (1 - (x/$3d_surface_size)^4)^0.5 * (1 - (y/$3d_surface_size)^4)^0.5;
ripple_surface = function(x,y) cos((x^2+y^2)^0.5 * 50)/4 + 0.75;
rosenbrocks_banana_surface = function(x,y) (pow(1-(x/$3d_surface_size))^2 + 100 * pow((y/$3d_surface_size)-(x/$3d_surface_size)^2)^2)/200 + 0.1;
spike_surface = function(x,y) 1/(((x/$3d_surface_size)^2+(y/$3d_surface_size)^2)^0.5) + .01;
random_surface = function(x,y) sin(rands(0,90,1,x+y)[0]);
bumps_surface = function(x,y) sin(20*x)*cos(20*y)/3+1;
$surface_function = bumps_surface; // bumps_surface;
// can be used to smooth the corners of the 3d surface function, to make the dishes add / subtract less height. can really do anything it's just multiplying, but that's what I use it for
$corner_smoothing_surface_function = function(x,y) 1;
// $corner_smoothing_surface_function = function(x,y) (1 - pow(abs(x), 5)/$3d_surface_size) * (1 - pow(abs(y),5)/$3d_surface_size);
// ripples
/*
// Rosenbrock's banana
/* $
// y=x revolved around the y axis
/* $surface_function = */
/* $surface_function = */

View File

@@ -28,6 +28,8 @@ module key_shape(size, delta, progress = 0) {
regular_polygon_shape(size, delta, progress);
} else if ($key_shape_type == "octagon") {
regular_polygon_shape(size, delta, progress, sides=8);
} else if ($key_shape_type == "circular") {
regular_polygon_shape(size, delta, progress, sides=36);
} else {
echo("Warning: unsupported $key_shape_type");
}

View File

@@ -38,12 +38,12 @@ module ISO_enter_shape(size, delta, progress){
}
function iso_enter_vertices(size, delta, progress, thickness_difference) = [
[ 0-delta.x/2 * progress - thickness_difference/2, 0 - delta.y / 2 * progress - thickness_difference/2], // top right
[ 0-delta.x/2 * progress - thickness_difference/2, -size[1] + delta.y / 2 * progress + thickness_difference/2], // bottom right
[-size[0] * width_ratio + delta.x/2 * progress + thickness_difference/2, -size[1] + delta.y / 2 * progress + thickness_difference/2], // bottom left
[-size[0] * width_ratio + delta.x/2 * progress + thickness_difference/2,-size[1] * height_ratio + delta.y / 2 * progress + thickness_difference/2], // inner middle point
[ -size[0] + delta.x/2 * progress + thickness_difference/2,-size[1] * height_ratio + delta.y / 2 * progress + thickness_difference/2], // outer middle point
[ -size[0] + delta.x/2 * progress + thickness_difference/2, 0 - delta.y / 2 * progress - thickness_difference/2] // top left
[ 0-delta.x/2 * progress - thickness_difference/8, 0 - delta.y / 2 * progress - thickness_difference/8], // top right
[ 0-delta.x/2 * progress - thickness_difference/8, -size[1] + delta.y / 2 * progress + thickness_difference/8], // bottom right
[-size[0] * width_ratio + delta.x/2 * progress + thickness_difference/8, -size[1] + delta.y / 2 * progress + thickness_difference/8], // bottom left
[-size[0] * width_ratio + delta.x/2 * progress + thickness_difference/8,-size[1] * height_ratio + delta.y / 2 * progress + thickness_difference/2], // inner middle point
[ -size[0] + delta.x/2 * progress + thickness_difference/8,-size[1] * height_ratio + delta.y / 2 * progress + thickness_difference/2], // outer middle point
[ -size[0] + delta.x/2 * progress + thickness_difference/8, 0 - delta.y / 2 * progress - thickness_difference/8] // top left
] + [
[(size[0] * width_ratio)/2, size[1]/2 ],
[(size[0] * width_ratio)/2, size[1]/2 ],
@@ -59,11 +59,11 @@ function skin_iso_enter_shape(size, delta, progress, thickness_difference) =
add_rounding(
iso_enter_vertices(
size,
delta,
[delta.x - $side_sculpting(progress), delta.y - $side_sculpting(progress)],
progress,
thickness_difference
),
$corner_radius
$corner_radius + $corner_sculpting(progress)
),
$shape_facets
);

View File

@@ -1,18 +1,10 @@
// rounded square shape with additional sculpting functions to better approximate
// When sculpting sides, how much in should the tops come
side_sculpting_factor = 4.5;
// When sculpting corners, how much extra radius should be added
corner_sculpting_factor = 1;
// When doing more side sculpting corners, how much extra radius should be added
more_side_sculpting_factor = 0.4;
// side sculpting functions
// bows the sides out on stuff like SA and DSA keycaps
function side_sculpting(progress) = (1 - progress) * side_sculpting_factor;
function side_sculpting(progress) = (1 - progress) * $side_sculpting_factor;
// makes the rounded corners of the keycap grow larger as they move upwards
function corner_sculpting(progress) = pow(progress, 2) * corner_sculpting_factor;
function corner_sculpting(progress) = pow(progress, 2) * $corner_sculpting_factor;
module sculpted_square_shape(size, delta, progress) {
width = size[0];
@@ -21,9 +13,9 @@ module sculpted_square_shape(size, delta, progress) {
width_difference = delta[0];
height_difference = delta[1];
// makes the sides bow
extra_side_size = side_sculpting(progress);
extra_side_size = $side_sculpting(progress);
// makes the rounded corners of the keycap grow larger as they move upwards
extra_corner_size = corner_sculpting(progress);
extra_corner_size = $corner_sculpting(progress);
// computed values for this slice
extra_width_this_slice = (width_difference - extra_side_size) * progress;
@@ -37,7 +29,7 @@ module sculpted_square_shape(size, delta, progress) {
offset(r = extra_corner_radius_this_slice, $fa=360/$shape_facets) {
offset(r = -extra_corner_radius_this_slice) {
side_rounded_square(square_size, r = more_side_sculpting_factor * progress);
side_rounded_square(square_size, r = $more_side_sculpting_factor * progress);
}
}
}
@@ -79,9 +71,9 @@ function skin_sculpted_square_shape(size, delta, progress, thickness_difference)
width_difference = delta[0],
height_difference = delta[1],
// makes the sides bow
extra_side_size = side_sculpting(progress),
extra_side_size = $side_sculpting(progress),
// makes the rounded corners of the keycap grow larger as they move upwards
extra_corner_size = corner_sculpting(progress),
extra_corner_size = $corner_sculpting(progress),
// computed values for this slice
extra_width_this_slice = (width_difference - extra_side_size) * progress,
@@ -92,7 +84,7 @@ function skin_sculpted_square_shape(size, delta, progress, thickness_difference)
width - extra_width_this_slice - thickness_difference,
height - extra_height_this_slice - thickness_difference
]
) new_side_rounded_square(square_size, more_side_sculpting_factor * progress, extra_corner_radius_this_slice);
) new_side_rounded_square(square_size, $more_side_sculpting_factor * progress, extra_corner_radius_this_slice);
module side_rounded_square(size, r) {

View File

@@ -16,12 +16,12 @@ module brim_support(stem_type, stem_support_height, slop) {
}
}
inside_cherry_cross(slop);
inside_cherry_cross($stem_inner_slop);
}
} else if (stem_type == "rounded_cherry") {
difference() {
cylinder(d=$rounded_cherry_stem_d * 2, h=stem_support_height);
inside_cherry_cross(slop);
inside_cherry_cross($stem_inner_slop);
}
} else if (stem_type == "box_cherry") {
difference() {
@@ -31,7 +31,7 @@ module brim_support(stem_type, stem_support_height, slop) {
}
}
inside_cherry_cross(slop);
inside_cherry_cross($stem_inner_slop);
}
} else if (stem_type == "cherry_stabilizer") {
difference() {
@@ -41,7 +41,7 @@ module brim_support(stem_type, stem_support_height, slop) {
}
}
inside_cherry_cross(slop);
inside_cherry_cross($stem_inner_slop);
}
} else if(stem_type == "choc") {
translate([-5.7/2,0,0]) linear_extrude(height=stem_support_height) {

View File

@@ -1,17 +1,20 @@
include <../functions.scad>
include <../stems/cherry.scad>
/* NOTE: every reference to total_key_width and total_key_height
* is multiplied by two in order to account for offset stems
*/
module centered_tines(stem_support_height) {
if ($key_length < 2) {
translate([0,0,$stem_support_height / 2]) {
cube([total_key_width(), 0.5, $stem_support_height], center = true);
cube([total_key_width()*2, 0.5, $stem_support_height], center = true);
}
}
translate([0,0,$stem_support_height / 2]) {
cube([
1,
total_key_height(),
total_key_height()*2,
$stem_support_height
],
center = true);
@@ -19,16 +22,13 @@ module centered_tines(stem_support_height) {
}
module tines_support(stem_type, stem_support_height, slop) {
extra_height = $extra_long_stem_support ? ($unit - total_key_height()) + 0.1 : -$wall_thickness/4; // fudge
extra_width = $extra_long_stem_support ? ($unit - total_key_width()) + 0.1 : -$wall_thickness/4;
if (stem_type == "cherry" || stem_type == "costar_stabilizer") {
difference () {
union() {
if ($key_length < 2) {
translate([0,0,$stem_support_height / 2]) {
cube([
total_key_width() + extra_width*2,
total_key_width()*2,
0.5,
$stem_support_height
], center = true);
@@ -36,18 +36,18 @@ module tines_support(stem_type, stem_support_height, slop) {
}
// 2 vertical tines holding either side of the cruciform
for (x = [1.15, -1.15]) {
for (x = [2, -2]) {
translate([x,0,$stem_support_height / 2]) {
cube([
0.5,
total_key_height() + extra_height*2, // this is to extend past
total_key_height()*2, // this is to extend past
$stem_support_height
], center = true);
}
}
}
inside_cherry_cross(slop);
inside_cherry_cross($stem_inner_slop);
}
} else if (stem_type == "cherry_stabilizer") {
difference () {
@@ -55,7 +55,7 @@ module tines_support(stem_type, stem_support_height, slop) {
translate([x,0,$stem_support_height / 2]) {
cube([
1,
total_key_height($wall_thickness),
total_key_height()*2,
$stem_support_height
], center = true);
}
@@ -67,19 +67,19 @@ module tines_support(stem_type, stem_support_height, slop) {
difference () {
centered_tines(stem_support_height);
inside_cherry_cross(slop);
inside_cherry_cross($stem_inner_slop);
}
} else if (stem_type == "rounded_cherry") {
difference () {
centered_tines(stem_support_height);
inside_cherry_cross(slop);
inside_cherry_cross($stem_inner_slop);
}
} else if (stem_type == "alps"){
centered_tines(stem_support_height);
} else if (stem_type == "choc"){
if ($key_length < 2) translate([0,0,$stem_support_height / 2]) cube([total_key_width($wall_thickness)+$wall_thickness/4, 0.42, $stem_support_height], center = true);
/* translate([-5.7/2,0,$stem_support_height / 2]) cube([0.5, total_key_height($wall_thickness), $stem_support_height], center = true); */
/* translate([5.7/2,0,$stem_support_height / 2]) cube([0.5, total_key_height($wall_thickness), $stem_support_height], center = true); */
if ($key_length < 2) translate([0,0,$stem_support_height / 2]) cube([total_key_width(), 0.42, $stem_support_height], center = true);
/* translate([-5.7/2,0,$stem_support_height / 2]) cube([0.5, total_key_height(), $stem_support_height], center = true); */
/* translate([5.7/2,0,$stem_support_height / 2]) cube([0.5, total_key_height(), $stem_support_height], center = true); */
}
}

View File

@@ -11,6 +11,6 @@ module box_cherry_stem(depth, slop, throw) {
}
// inside cross
inside_cherry_cross(slop);
inside_cherry_cross($stem_inner_slop);
}
}

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

View File

@@ -7,6 +7,6 @@ module rounded_cherry_stem(depth, slop, throw) {
// inside cross
// translation purely for aesthetic purposes, to get rid of that awful lattice
inside_cherry_cross(slop);
inside_cherry_cross($stem_inner_slop);
}
}

View File

@@ -445,12 +445,12 @@ copy-descriptor@^0.1.0:
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
copy-props@^2.0.1:
version "2.0.4"
resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.4.tgz#93bb1cadfafd31da5bb8a9d4b41f471ec3a72dfe"
integrity sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==
version "2.0.5"
resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.5.tgz#03cf9ae328d4ebb36f8f1d804448a6af9ee3f2d2"
integrity sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==
dependencies:
each-props "^1.3.0"
is-plain-object "^2.0.1"
each-props "^1.3.2"
is-plain-object "^5.0.0"
core-util-is@~1.0.0:
version "1.0.2"
@@ -538,7 +538,7 @@ duplexify@^3.6.0:
readable-stream "^2.0.0"
stream-shift "^1.0.0"
each-props@^1.3.0:
each-props@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333"
integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==
@@ -1013,9 +1013,9 @@ homedir-polyfill@^1.0.1:
parse-passwd "^1.0.0"
hosted-git-info@^2.1.4:
version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
inflight@^1.0.4:
version "1.0.6"
@@ -1178,6 +1178,11 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
is-plain-object@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
is-relative@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
@@ -1624,9 +1629,9 @@ path-is-absolute@^1.0.0:
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
path-parse@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-root-regex@^0.1.0:
version "0.1.2"
@@ -2348,9 +2353,9 @@ xtend@~4.0.0, xtend@~4.0.1:
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
version "3.2.2"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696"
integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==
yargs-parser@^5.0.0:
version "5.0.1"