Compare commits

...

1 Commits

Author SHA1 Message Date
Bob 15d87a8f95 github desktop completely screwed me 2020-05-12 11:33:33 -04:00
8 changed files with 278 additions and 327 deletions

View File

@ -5,11 +5,88 @@
// without having to rely on this file. Unfortunately that means setting tons of
// special variables, but that's a limitation of SCAD we have to work around
echo($fa);
echo("WHERES THE BEEF");
include <./includes.scad>
dsa_row(3) {
union() {
$key_shape_type="sculpted_square";
$dish_type="disabled";
$skin_extrude_shape = true;
key();
}
}
/* $inverted_dish = true; */
/* $rounded_key = true; */
/* $linear_extrude_shape=true; */
/* $rounded_key=true; */
/* $outset_legends = true; */
/* $inverted_dish =true; */
/* $dish_type = "pyramid"; */
/* legend("q") key(); */
/* $outset_legends = true; */
dcs_row(3) {
/* iso_enter() */
union() {
union() {
/* $minkowski_radius = 10; */
/* $minkowski_radius = 0.12; */
/* $key_shape_type = "iso_enter"; */
$key_shape_type="sculpted_square";
/* $dish_type ="disable"; */
/* $inverted_dish = true; */
/* $stem_type = "disable"; */
/* $dish_type="3d_surface"; */
/* $support_type = "disable"; */
/* $stabilizer_type = "disable"; */
/* rounded_shape(); */
/* minkowski() { */
/* rounded_key(); */
/* translate([0,0,-200]) cube(10); */
// example key
dcs_row(5) legend("⇪", size=9) key();
/* difference(){ */
/* key(); */
/* cube(100); */
/* } */
/* minkowski_shape(); */
/* } */
}
}
}
/* translate_u(1,0) {
oem_row(3) {
cherry() legend("q")
union() {
key();
}
}
} */
/* difference() {
translate([0,0,-.1]) cube(1.1);
translate([0.5,0.5,-0.5]) polar_3d_surface(step=0.1);
} */
// Written in 2015 by Torsten Paul <Torsten.Paul@gmx.de>
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to the
// public domain worldwide. This software is distributed without any
// warranty.
//
// For details of the CC0 Public Domain Dedication see
// <http://creativecommons.org/publicdomain/zero/1.0/>.
// example row
/* for (x = [0:1:4]) {
@ -17,4 +94,4 @@ dcs_row(5) legend("⇪", size=9) key();
} */
// example layout
/* preonic_default("dcs"); */
/* preonic_default("dcs"); */

View File

@ -5,7 +5,8 @@ include <stems.scad>
include <stem_supports.scad>
include <dishes.scad>
include <supports.scad>
include <key_features.scad>
include <features.scad>
include <hulls.scad>
include <libraries/geodesic_sphere.scad>
@ -15,10 +16,10 @@ use <libraries/scad-utils/lists.scad>
use <libraries/scad-utils/shapes.scad>
use <libraries/skin.scad>
/* [Hidden] */
SMALLEST_POSSIBLE = 1/128;
$fs = .1;
// basically disable $fs - though it might be useful for these CGAL problems
$fs = .01;
$unit = 19.05;
// 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
@ -28,197 +29,31 @@ module shape(thickness_difference, depth_difference=0){
}
}
// shape of the key but with soft, rounded edges. no longer includes dish
// randomly doesnt work sometimes
// the dish doesn't _quite_ reach as far as it should
module rounded_shape() {
dished(-$minkowski_radius, $inverted_dish) {
color($primary_color) minkowski(){
// 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);
}
}
/* %envelope(); */
}
// this function is more correct, but takes _forever_
// the main difference is minkowski happens after dishing, meaning the dish is
// also minkowski'd
/* module rounded_shape() {
module rounded_shape() {
color($primary_color) minkowski(){
// half minkowski in the z direction
shape($minkowski_radius * 2, $minkowski_radius/2);
difference(){
sphere(r=$minkowski_radius, $fn=20);
translate([0,0,-$minkowski_radius]){
cube($minkowski_radius * 2, center=true);
}
}
minkowski_object();
}
} */
}
// minkowski places this object at every vertex of the other object then mashes
// it all together
module minkowski_object() {
// alternative minkowski shape that needs the bottom of the keycap to be trimmed
/* sphere(1); */
// 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);
difference(){
sphere(r=$minkowski_radius, $fa=360/$minkowski_facets);
translate([0,0,-$minkowski_radius]){
cube($minkowski_radius * 2, center=true);
}
}
}
// 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
)
)
);
// 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]
);
}
}
}
}
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){
key_shape(
[
total_key_width(thickness_difference),
total_key_height(thickness_difference)
],
[$width_difference, $height_difference],
progress
);
}
}
}
}
// for when you want something to only exist inside the keycap.
// used for the support structure
module inside() {
intersection() {
shape($wall_thickness, $keytop_thickness);
children();
}
}
// for when you want something to only exist outside the keycap
module outside() {
difference() {
children();
shape($wall_thickness, $keytop_thickness);
}
}
// put something at the top of the key, with no adjustments for dishing
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;
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference + minkowski_height/2]){
rotate([top_tilt_by_height, top_tilt_y_by_length,0]){
children();
}
}
}
module front_placement() {
// all this math is to take top skew and tilt into account
// we need to find the new effective height and depth of the top, front lip
// of the keycap to find the angle so we can rotate things correctly into place
total_depth_difference = sin(-$top_tilt) * (top_total_key_height()/2);
total_height_difference = $top_skew + (1 - cos(-$top_tilt)) * (top_total_key_height()/2);
angle = atan2(($total_depth - total_depth_difference), ($height_difference/2 + total_height_difference));
hypotenuse = ($total_depth -total_depth_difference) / sin(angle);
translate([0,-total_key_height()/2,0]) {
rotate([-(90-angle), 0, 0]) {
translate([0,0,hypotenuse/2]){
children();
}
}
}
}
// just to DRY up the code
module _dish() {
color($secondary_color) dish(top_total_key_width() + $dish_overdraw_width, top_total_key_height() + $dish_overdraw_height, $dish_depth, $inverted_dish);
}
module envelope(depth_difference=0) {
s = 1.5;
@ -230,18 +65,6 @@ module envelope(depth_difference=0) {
}
}
// I think this is unused
module dished_for_show() {
difference(){
union() {
envelope();
if ($inverted_dish) top_placement(0) _dish();
}
if (!$inverted_dish) top_placement(0) _dish();
}
}
// for when you want to take the dish out of things
// used for adding the dish to the key shape and making sure stems don't stick out the top
// creates a bounding box 1.5 times larger in width and height than the keycap.
@ -250,15 +73,21 @@ module dished(depth_difference = 0, inverted = false) {
children();
difference(){
union() {
// envelope is needed to "fill in" the rest of the keycap
envelope(depth_difference);
if (inverted) top_placement(depth_difference) _dish();
if (inverted) top_placement(depth_difference) _dish(inverted);
}
if (!inverted) top_placement(depth_difference) _dish();
if (!inverted) top_placement(depth_difference) _dish(inverted);
}
}
}
// puts it's children at the center of the dishing on the key, including dish height
// just to DRY up the code
module _dish(inverted=$inverted_dish) {
color($secondary_color) dish(top_total_key_width() + $dish_overdraw_width, top_total_key_height() + $dish_overdraw_height, $dish_depth, inverted);
}
// puts its children at the center of the dishing on the key, including dish height
// more user-friendly than top_placement
module top_of_key(){
// if there is a dish, we need to account for how much it digs into the top
@ -271,16 +100,7 @@ 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");
}
}
}
// puts its children at each keystem position provided
module keystem_positions(positions) {
for (connector_pos = positions) {
translate(connector_pos) {
@ -306,125 +126,132 @@ module stems_for(positions, stem_type) {
}
}
// 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);
// put something at the top of the key, with no adjustments for dishing
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;
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference + minkowski_height/2]){
rotate([top_tilt_by_height, top_tilt_y_by_length,0]){
children();
}
}
}
//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 front_of_key() {
// all this math is to take top skew and tilt into account
// we need to find the new effective height and depth of the top, front lip
// of the keycap to find the angle so we can rotate things correctly into place
total_depth_difference = sin(-$top_tilt) * (top_total_key_height()/2);
total_height_difference = $top_skew + (1 - cos(-$top_tilt)) * (top_total_key_height()/2);
angle = atan2(($total_depth - total_depth_difference), ($height_difference/2 + total_height_difference));
hypotenuse = ($total_depth -total_depth_difference) / sin(angle);
translate([0,-total_key_height()/2,0]) {
rotate([-(90-angle), 0, 0]) {
translate([0,0,hypotenuse/2]){
children();
}
}
}
}
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);
}
}
}
module outer_shape() {
if ($rounded_key) {
rounded_shape();
} else {
shape(0, 0);
}
}
// legends / artisan support
module artisan(depth) {
top_of_key() {
// artisan objects / outset shape legends
color($secondary_color) children();
}
}
// key with hollowed inside but no stem
module hollow_key() {
difference(){
if ($rounded_key) {
rounded_shape();
module inner_shape(extra_wall_thickness = 0, extra_keytop_thickness = 0) {
translate([0,0,-SMALLEST_POSSIBLE]) {
if ($flat_keytop_bottom) {
/* $key_shape_type="square"; */
$height_slices = 1;
color($primary_color) shape_hull($wall_thickness + extra_wall_thickness, $keytop_thickness + extra_keytop_thickness, 0);
} else {
shape(0, 0);
}
// translation purely for aesthetic purposes, to get rid of that awful lattice
translate([0,0,-SMALLEST_POSSIBLE]) {
shape($wall_thickness, $keytop_thickness);
shape($wall_thickness + extra_wall_thickness, $keytop_thickness + extra_keytop_thickness);
}
}
}
// additive objects at the top of the key
module additive_features(inset) {
top_of_key() {
if($key_bump) keybump($key_bump_depth, $key_bump_edge);
if(!inset && $children > 0) color($secondary_color) children();
}
if($outset_legends) legends(0);
// render the clearance check if it's enabled, but don't have it intersect with anything
if ($clearance_check) %clearance_check();
}
// subtractive objects at the top of the key
module subtractive_features(inset) {
top_of_key() {
if (inset && $children > 0) color($secondary_color) children();
}
if(!$outset_legends) legends($inset_legend_depth);
// subtract the clearance check if it's enabled, letting the user see the
// parts of the keycap that will hit the cherry switch
if ($clearance_check) %clearance_check();
}
module inside_features() {
translate([0, 0, $stem_inset]) {
// both stem and support are optional
if ($stabilizer_type != "disable") stems_for($stabilizers, $stabilizer_type);
if ($stem_type != "disable") stems_for($stem_positions, $stem_type);
if ($stabilizer_type != "disable") support_for($stabilizers, $stabilizer_type);
// always render stem support even if there isn't a stem.
// rendering flat support w/no stem is much more common than a hollow keycap
// so if you want a hollow keycap you'll have to turn support off entirely
support_for($stem_positions, $stem_type);
}
}
// The final, penultimate key generation function.
// takes all the bits and glues them together. requires configuration with special variables.
module key(inset = false) {
module key(inset=false) {
difference(){
union() {
outer_shape();
additive_features(inset);
}
difference() {
inner_shape();
inside_features();
}
subtractive_features(inset);
}
}
module rounded_key(inset=false) {
difference() {
union(){
// the shape of the key, inside and out
hollow_key();
if($key_bump) top_of_key() keybump($key_bump_depth, $key_bump_edge);
// additive objects at the top of the key
// outside() makes them stay out of the inside. it's a bad name
if(!inset && $children > 0) outside() artisan(0) children();
if($outset_legends) legends(0);
// render the clearance check if it's enabled, but don't have it intersect with anything
if ($clearance_check) %clearance_check();
}
// subtractive objects at the top of the key
// no outside() - I can't think of a use for it. will save render time
if (inset && $children > 0) artisan($inset_legend_depth) children();
if(!$outset_legends) legends($inset_legend_depth);
// subtract the clearance check if it's enabled, letting the user see the
// parts of the keycap that will hit the cherry switch
if ($clearance_check) %clearance_check();
}
// both stem and support are optional
if ($stem_type != "disable" || ($stabilizers != [] && $stabilizer_type != "disable")) {
dished($keytop_thickness, $inverted_dish) {
translate([0, 0, $stem_inset]) {
if ($stabilizer_type != "disable") stems_for($stabilizers, $stabilizer_type);
if ($stem_type != "disable") stems_for($stem_positions, $stem_type);
minkowski() {
difference() {
outer_shape();
inner_shape();
}
minkowski_object();
}
subtractive_features(inset);
}
if ($support_type != "disable"){
inside() {
translate([0, 0, $stem_inset]) {
if ($stabilizer_type != "disable") support_for($stabilizers, $stabilizer_type);
/* additive_features(inset); */
// always render stem support even if there isn't a stem.
// rendering flat support w/no stem is much more common than a hollow keycap
// so if you want a hollow keycap you'll have to turn support off entirely
support_for($stem_positions, $stem_type);
}
}
}
/* intersection() {
inner_shape($wall_thickness, $keytop_thickness);
inside_features();
} */
}
// actual full key with space carved out and keystem/stabilizer connectors

View File

@ -1,3 +1,21 @@
function sign_x(i,n) =
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) = [
for (index = [0:fn-1])
let(a = index/fn*360)
@ -6,12 +24,10 @@ function rounded_rectangle_profile(size=[1,1],r=1,fn=32) = [
+ 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 :
0;
function sign_y(i,n) =
i > 0 && i < n/2 ? 1 :
i > n/2 ? -1 :
0;
function double_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]
];

View File

@ -37,7 +37,7 @@ $outset_legends = false;
// Height in units of key. should remain 1 for most uses
$key_height = 1.0;
// Keytop thickness, aka how many millimeters between the inside and outside of the top surface of the key
$keytop_thickness = 1;
$keytop_thickness = 2;
// Wall thickness, aka the thickness of the sides of the keycap. note this is the total thickness, aka 3 = 1.5mm walls
$wall_thickness = 3;
// Radius of corners of keycap
@ -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,16 @@ $secondary_color = [.4412, .7, .3784];
$tertiary_color = [1, .6941, .2];
$quaternary_color = [.4078, .3569, .749];
$warning_color = [1,0,0, 0.15];
// 3d surface variables
// see functions.scad for the surface function
$3d_surface_size = 10;
$3d_surface_step = 1;
// normally the bottom of the keytop looks like the top - curved, at least
// underneath the support structure. This ensures there's a minimum thickness for the
// underside of the keycap, but it's a fair bit of geometry
$flat_keytop_bottom = true;
// how many facets circles will have when used in these features
$minkowski_facets = 30;
$shape_facets = 30;

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) - [thickness_difference, thickness_difference]*2, 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=36, 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);