diff --git a/customizer.scad b/customizer.scad index 9e0ac33..61076c4 100644 --- a/customizer.scad +++ b/customizer.scad @@ -162,12 +162,14 @@ $double_sculpted = false; //valign = "top" or "center" or "bottom" // Currently does not work with thingiverse customizer, and actually breaks it $legends = []; +$autolegends = []; //list of front legends to place on a key format: [text, halign, valign, size] //halign = "left" or "center" or "right" //valign = "top" or "center" or "bottom" // Currently does not work with thingiverse customizer, and actually breaks it $front_legends = []; +$front_autolegends = []; // print legends on the front of the key instead of the top $front_print_legends = false; @@ -175,6 +177,9 @@ $front_print_legends = false; // how recessed inset legends / artisans are from the top of the key $inset_legend_depth = 0.2; +// legends are not allowed to print within this many mm of the edge of the key +$legend_margin = 0.8; + // Dimensions of alps stem $alps_stem = [4.45, 2.25]; @@ -1105,6 +1110,18 @@ module front_legend(text, position=[0,0], size=undef) { children(); } +module autolegend(texts) { + // $autolegends = [for(L=[$legends, [[text, position, font_size]]], a=L) a]; + $autolegends = texts; + children(); +} + +module front_autolegend(texts) { + font_size = size == undef ? $font_size : size; + $front_autolegends = [for(L=[$front_legends, [[text, position, font_size]]], a=L) a]; + children(); +} + module bump(depth=undef) { $key_bump = true; $key_bump_depth = depth == undef ? $key_bump_depth : depth; @@ -5034,6 +5051,45 @@ module legends(depth=0) { } } } +module autolegends(depth=0) { + if (len($front_autolegends) > 0) { + front_of_key() { + for (i=[0:len($front_legends)-1]) { + rotate([90,0,0]) keytext($front_legends[i][0], $front_legends[i][1], $front_legends[i][2], depth); + } + } + } + if (len($autolegends) > 0) { + // legends are printed in a square grid - 1, 4, 9 legends, etc + grid_size = len($autolegends)^0.5; + echo("grid_size", grid_size); + max_width = (top_total_key_width() - $legend_margin * (grid_size + 1)) / grid_size; + max_height = (top_total_key_height() - $legend_margin * (grid_size + 1)) / grid_size; + + top_of_key() { + for (column=[0:grid_size-1]) { + for (row=[0:grid_size-1]) { + top_left_corner = [-top_total_key_width()/2, top_total_key_height()/2]; + centering_offset = [max_width / 2, -max_height / 2]; + position_offset = [(max_width + $legend_margin) * column, (-max_height-$legend_margin) * row]; + margin_offset = [$legend_margin, -$legend_margin]; + + translate(top_left_corner + centering_offset + position_offset + margin_offset) { + translate([0,0,-depth]) { + color($tertiary_color) linear_extrude(height=$dish_depth + depth){ + // resize([0, max_height, 0]) { + resize([max_width, 0], auto=true) { + text(text=$autolegends[row * grid_size + column], font=$font, halign="center", valign="center"); + } + // } + } + } + } + } + } + } + } + } // 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 @@ -6242,7 +6298,10 @@ module additive_features(inset) { if($key_bump) keybump($key_bump_depth, $key_bump_edge); if(!inset && $children > 0) color($secondary_color) children(); } - if($outset_legends) legends(0); + if($outset_legends) { + legends(0); + autolegends(0); + } // render the clearance check if it's enabled, but don't have it intersect with anything if ($clearance_check) %clearance_check(); } @@ -6252,7 +6311,10 @@ module subtractive_features(inset) { top_of_key() { if (inset && $children > 0) color($secondary_color) children(); } - if(!$outset_legends) legends($inset_legend_depth); + if(!$outset_legends) { + legends($inset_legend_depth); + autolegends($inset_legend_depth); + } // subtract the clearance check if it's enabled, letting the user see the // parts of the keycap that will hit the cherry switch // this is a little confusing as it eats the stem too @@ -6468,12 +6530,14 @@ $double_sculpted = false; //valign = "top" or "center" or "bottom" // Currently does not work with thingiverse customizer, and actually breaks it $legends = []; +$autolegends = []; //list of front legends to place on a key format: [text, halign, valign, size] //halign = "left" or "center" or "right" //valign = "top" or "center" or "bottom" // Currently does not work with thingiverse customizer, and actually breaks it $front_legends = []; +$front_autolegends = []; // print legends on the front of the key instead of the top $front_print_legends = false; @@ -6481,6 +6545,9 @@ $front_print_legends = false; // how recessed inset legends / artisans are from the top of the key $inset_legend_depth = 0.2; +// legends are not allowed to print within this many mm of the edge of the key +$legend_margin = 0.8; + // Dimensions of alps stem $alps_stem = [4.45, 2.25]; diff --git a/keys.scad b/keys.scad index 74b22ab..602a1ba 100644 --- a/keys.scad +++ b/keys.scad @@ -9,8 +9,11 @@ include <./includes.scad> // example key -dcs_row(5) legend("⇪", size=9) key(); - +$stem_inner_slop = 0; +dcs_row(5) autolegend(["q", "w", "a", "z", "e", "r", "t", "", "hoobastank"]) { + $stem_positions = [[2,2]]; + key(); +} // example row /* for (x = [0:1:4]) { translate_u(0,-x) dcs_row(x) key(); diff --git a/src/features.scad b/src/features.scad index b0ae94a..88c610b 100644 --- a/src/features.scad +++ b/src/features.scad @@ -3,3 +3,4 @@ include include include +include diff --git a/src/features/autolegends.scad b/src/features/autolegends.scad new file mode 100644 index 0000000..24243f4 --- /dev/null +++ b/src/features/autolegends.scad @@ -0,0 +1,39 @@ +module autolegends(depth=0) { + if (len($front_autolegends) > 0) { + front_of_key() { + for (i=[0:len($front_legends)-1]) { + rotate([90,0,0]) keytext($front_legends[i][0], $front_legends[i][1], $front_legends[i][2], depth); + } + } + } + if (len($autolegends) > 0) { + // legends are printed in a square grid - 1, 4, 9 legends, etc + grid_size = len($autolegends)^0.5; + echo("grid_size", grid_size); + max_width = (top_total_key_width() - $legend_margin * (grid_size + 1)) / grid_size; + max_height = (top_total_key_height() - $legend_margin * (grid_size + 1)) / grid_size; + + top_of_key() { + for (column=[0:grid_size-1]) { + for (row=[0:grid_size-1]) { + top_left_corner = [-top_total_key_width()/2, top_total_key_height()/2]; + centering_offset = [max_width / 2, -max_height / 2]; + position_offset = [(max_width + $legend_margin) * column, (-max_height-$legend_margin) * row]; + margin_offset = [$legend_margin, -$legend_margin]; + + translate(top_left_corner + centering_offset + position_offset + margin_offset) { + translate([0,0,-depth]) { + color($tertiary_color) linear_extrude(height=$dish_depth + depth){ + // resize([0, max_height, 0]) { + resize([max_width, 0], auto=true) { + text(text=$autolegends[row * grid_size + column], font=$font, halign="center", valign="center"); + } + // } + } + } + } + } + } + } + } + } diff --git a/src/key.scad b/src/key.scad index 15768ba..2c94372 100644 --- a/src/key.scad +++ b/src/key.scad @@ -180,7 +180,10 @@ module additive_features(inset) { if($key_bump) keybump($key_bump_depth, $key_bump_edge); if(!inset && $children > 0) color($secondary_color) children(); } - if($outset_legends) legends(0); + if($outset_legends) { + legends(0); + autolegends(0); + } // render the clearance check if it's enabled, but don't have it intersect with anything if ($clearance_check) %clearance_check(); } @@ -190,7 +193,10 @@ module subtractive_features(inset) { top_of_key() { if (inset && $children > 0) color($secondary_color) children(); } - if(!$outset_legends) legends($inset_legend_depth); + if(!$outset_legends) { + legends($inset_legend_depth); + autolegends($inset_legend_depth); + } // subtract the clearance check if it's enabled, letting the user see the // parts of the keycap that will hit the cherry switch // this is a little confusing as it eats the stem too diff --git a/src/key_transformations.scad b/src/key_transformations.scad index 4d98cdf..1c5caf7 100644 --- a/src/key_transformations.scad +++ b/src/key_transformations.scad @@ -170,6 +170,18 @@ module front_legend(text, position=[0,0], size=undef) { children(); } +module autolegend(texts) { + // $autolegends = [for(L=[$legends, [[text, position, font_size]]], a=L) a]; + $autolegends = texts; + children(); +} + +module front_autolegend(texts) { + font_size = size == undef ? $font_size : size; + $front_autolegends = [for(L=[$front_legends, [[text, position, font_size]]], a=L) a]; + children(); +} + module bump(depth=undef) { $key_bump = true; $key_bump_depth = depth == undef ? $key_bump_depth : depth; diff --git a/src/settings.scad b/src/settings.scad index 90dbe4d..14ee6d9 100644 --- a/src/settings.scad +++ b/src/settings.scad @@ -147,12 +147,14 @@ $double_sculpted = false; //valign = "top" or "center" or "bottom" // Currently does not work with thingiverse customizer, and actually breaks it $legends = []; +$autolegends = []; //list of front legends to place on a key format: [text, halign, valign, size] //halign = "left" or "center" or "right" //valign = "top" or "center" or "bottom" // Currently does not work with thingiverse customizer, and actually breaks it $front_legends = []; +$front_autolegends = []; // print legends on the front of the key instead of the top $front_print_legends = false; @@ -160,6 +162,9 @@ $front_print_legends = false; // how recessed inset legends / artisans are from the top of the key $inset_legend_depth = 0.2; +// legends are not allowed to print within this many mm of the edge of the key +$legend_margin = 0.8; + // Dimensions of alps stem $alps_stem = [4.45, 2.25];