diff --git a/src/features/legends.scad b/src/features/legends.scad index 83641cb..c38c696 100644 --- a/src/features/legends.scad +++ b/src/features/legends.scad @@ -2,8 +2,9 @@ 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_face, size=font_size, halign="center", valign="center"); + height = $dish_depth + depth + ($rounded_key ? $minkowski_radius : 0); + color($tertiary_color) linear_extrude(height=height){ + text(text=text, font=font_face, size=font_size, halign=$label_valign, valign=$label_halign); } } } diff --git a/src/key.scad b/src/key.scad index d1278b0..a0e8a16 100644 --- a/src/key.scad +++ b/src/key.scad @@ -213,7 +213,7 @@ module inside_features() { module stems_and_stabilizers() { translate([0, 0, $stem_inset]) { if ($stabilizer_type != "disable") stems_for($stabilizers, $stabilizer_type); - if ($stem_type != "disable") stems_for($stem_positions, $stem_type); + if ($stem_type != "disable" && $stem_type != "scissors_clip") stems_for($stem_positions, $stem_type); } } @@ -235,20 +235,23 @@ module outer_total_shape(inset=false) { // The final, penultimate key generation function. // takes all the bits and glues them together. requires configuration with special variables. module key(inset=false) { - difference(){ - outer_total_shape(inset) { - children(); - }; + union() { + difference() { + outer_total_shape(inset) { + children(); + }; - if ($inner_shape_type != "disable") { - translate([0,0,-SMALLEST_POSSIBLE]) { // avoids moire - inner_total_shape(); + if ($inner_shape_type != "disable") { + translate([0,0,-SMALLEST_POSSIBLE]) { // avoids moire + inner_total_shape(); + } } - } - subtractive_features(inset) { - children(); - }; + subtractive_features(inset) { + children(); + }; + } + if ($stem_type == "scissors_clip") stems_for($stem_positions, $stem_type); } // semi-hack to make sure negative inset stems don't poke through the top of the keycap diff --git a/src/settings.scad b/src/settings.scad index c636fee..6029940 100644 --- a/src/settings.scad +++ b/src/settings.scad @@ -4,7 +4,7 @@ $key_length = 1.0; // Range not working in thingiverse customizer atm [1:0.25:16] // What type of stem you want. Most people want Cherry. -$stem_type = "cherry"; // [cherry, alps, rounded_cherry, box_cherry, filled, disable] +$stem_type = "cherry"; // [cherry, alps, rounded_cherry, box_cherry, filled, scissors_clip, disable] // The stem is the hardest part to print, so this variable controls how much 'slop' there is in the stem // if your keycaps stick in the switch raise this value @@ -84,7 +84,7 @@ $keycap_rotation = 0; /* [Shape] */ // Key shape type, determines the shape of the key. default is 'rounded square' -$key_shape_type = "rounded_square"; +$key_shape_type = "rounded_square"; // [rounded_square, iso_enter, sculpted_square, flat_sided_square, square, oblong, hexagon, octagon, circular, rounded_bottom_square, rounded_bottom_rouned_square] // 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 @@ -248,4 +248,40 @@ $corner_smoothing_surface_function = function(x,y) 1; /* $ // y=x revolved around the y axis /* $surface_function = */ -/* $surface_function = */ \ No newline at end of file +/* $surface_function = */ + +/* [Label alignment] */ + +// label text vertical alignment +$label_valign = "center"; +// label text horizontal allignment +$label_halign = "center"; + +/* [Bottom radius shape] */ + +// bottom arc height for rounded_bottom_rouned_square and rounded_bottom_square $key_shape +$bottom_radius_heght = 1; +// disables rounding at right of the button +$rounded_square_sharp_right = false; + +/* [Scissors clip] */ + +$clip_width = 0.8; +$clip_height = 2.1; +$clip_depth = 1.4; +// distance between center of clips +$clip_horizontal_distance = 7; +$clip_hole_diameter = 0.9; +$clip_hole_click_diameter = 0.6; + +// distance between clips and pockets center +$clip_to_pocket = 11; + +// inner distance between clip pockets +$clip_pocket_inner_distance = 11.5; +$clip_pocket_width = 1.7; +$clip_pocket_height= 2; +$clip_pocket_depth = 1.7; + +// Offset of the clip +$clip_offset = [0,0,0]; \ No newline at end of file diff --git a/src/shapes.scad b/src/shapes.scad index 7a4ccb4..2581bfc 100644 --- a/src/shapes.scad +++ b/src/shapes.scad @@ -5,6 +5,7 @@ include include include include +include // size: at progress 0, the shape is supposed to be this size // delta: at progress 1, the keycap is supposed to be size - delta @@ -30,6 +31,10 @@ module key_shape(size, delta, progress = 0) { regular_polygon_shape(size, delta, progress, sides=8); } else if ($key_shape_type == "circular") { regular_polygon_shape(size, delta, progress, sides=36); + } else if ($key_shape_type == "rounded_bottom_square"){ + rounded_bottom_square_shape(size, delta, progress); + } else if ($key_shape_type == "rounded_bottom_rouned_square"){ + rounded_bottom_rouned_square_shape(size, delta, progress); } else { echo("Warning: unsupported $key_shape_type"); } diff --git a/src/shapes/rounded_bottom.scad b/src/shapes/rounded_bottom.scad new file mode 100644 index 0000000..295c7a5 --- /dev/null +++ b/src/shapes/rounded_bottom.scad @@ -0,0 +1,22 @@ +use <../functions.scad> + +module rounded_bottom_square_shape_by_radius(section_size, bottom_radius) { + intersection() { + square(section_size, center = true); + translate(v = [0, -section_size.y/2+ bottom_radius]) circle(r = bottom_radius, $fn=120); + } +} + +module rounded_bottom_square_shape(size, delta, progress) { + section_size = size-delta * progress; + bottom_radius = $bottom_radius_heght/2 + section_size[1]^2/8/$bottom_radius_heght; + rounded_bottom_square_shape_by_radius(section_size, bottom_radius); +} + +module rounded_bottom_rouned_square_shape(size, delta, progress) { + offset(r=$corner_radius, $fa=360/$shape_facets) { + section_size = size-delta * progress - [1,1]*$corner_radius*2; + bottom_radius = $bottom_radius_heght/2 + section_size.y^2/8/$bottom_radius_heght; + rounded_bottom_square_shape_by_radius(section_size, bottom_radius); + } +} \ No newline at end of file diff --git a/src/shapes/rounded_square.scad b/src/shapes/rounded_square.scad index bef7faa..f353ec9 100644 --- a/src/shapes/rounded_square.scad +++ b/src/shapes/rounded_square.scad @@ -5,6 +5,9 @@ module rounded_square_shape(size, delta, progress, center = true) { offset(r=$corner_radius, $fa=360/$shape_facets){ square_shape([size.x - $corner_radius*2, size.y - $corner_radius*2], delta, progress); } + if($rounded_square_sharp_right) { + translate(v = [size.x/4, 0]) square_shape([size.x/2, size.y], delta, progress); + } } // for skin diff --git a/src/stems.scad b/src/stems.scad index 5f68c95..5d0295c 100644 --- a/src/stems.scad +++ b/src/stems.scad @@ -5,6 +5,7 @@ include include include include +include //whole stem, alps or cherry, trimmed to fit @@ -25,6 +26,8 @@ module stem(stem_type, depth, slop, throw){ choc_stem(depth, slop, throw); } else if (stem_type == "disable") { children(); + } else if(stem_type == "scissors_clip") { + scissors_clip_steam(); } else { echo("Warning: unsupported $stem_type: "); echo(stem_type); diff --git a/src/stems/scissors_clip.scad b/src/stems/scissors_clip.scad new file mode 100644 index 0000000..be93282 --- /dev/null +++ b/src/stems/scissors_clip.scad @@ -0,0 +1,34 @@ +module scissors_clip_steam() { + translate(v = [0, ($bottom_key_height-$clip_height-0.7)/2, $total_depth-$keytop_thickness-$dish_depth]+$clip_offset) { + translate(v = [0, 0, -$clip_depth/2]) { + translate(v = [$clip_horizontal_distance/2, 0]) scissors_clip(); + translate(v = [-$clip_horizontal_distance/2, 0]) scissors_clip(); + } + + translate(v = [0, -$clip_to_pocket, -$clip_pocket_depth/2]) { + translate(v = [$clip_pocket_inner_distance/2+$clip_pocket_width/2,0,0]) scissors_clip_pocket(); + translate(v = [-$clip_pocket_inner_distance/2-$clip_pocket_width/2,0,0]) mirror(v = [1,0,0]) scissors_clip_pocket(); + } + } +} + +module scissors_clip() { + eps = 0.1; + rotate(a = [0,90,0]) + linear_extrude(height=$clip_width, center=true) + difference() { + translate(v = [-eps/2, 0]) square(size = [$clip_depth+eps, $clip_height], center=true); + translate(v = [($clip_hole_diameter-$clip_depth)/2+0.1, 0]) circle(r = $clip_hole_diameter/2); + //translate(v = [$clip_depth/2, 0]) circle(r = $clip_hole_diameter/2); + square(size = [$clip_depth, $clip_hole_click_diameter], center=true); + } +} + +module scissors_clip_pocket() { + size = [$clip_pocket_width, $clip_pocket_height, $clip_pocket_depth]; + difference() { + cube(size = size, center=true); + translate([-0.5, -0.5, 0.6]) cube(size = size, center=true); + translate(-size/2) rotate(a = 45, v = [0,0,1]) cube(size=[1,1,1]*1.5, center=true); + } +} \ No newline at end of file