From 8b4b9ae6878597f0090b749322396738eb415db8 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 18 Jun 2020 17:22:29 -0400 Subject: [PATCH] hull_shape_type --- CHANGELOG.md | 1 + TIPS_AND_TRICKS.md | 2 +- customizer.scad | 96 +++++++++++++++----------------------- src/hulls.scad | 4 +- src/key.scad | 72 +++++++++++----------------- src/key_profiles/grid.scad | 2 +- src/key_types.scad | 2 +- src/settings.scad | 8 ++-- 8 files changed, 75 insertions(+), 112 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8197d44..6857f25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ CHANGELOG: * implemented `$inner_shape_type`, use "flat" for less geometry or "disable" to make a completely solid key easily. didn't help render rounded keys though * side-printed keycaps are first class! you can use the `sideways()` modifier to set up sideways keycaps that have flat sides to print on. * it's much easier to make quick artisans now that the inside of the keycap is differenced from any additive features placed on top + * `$linear_extrude_shape` and `$skin_extrude_shape` retired in favor of `$hull_shape_type` * still todo: add a magic scaling variable so you can scale the whole world up, see if that fixes degeneracy * still todo: rejigger supports * still todo: rejigger inner shape. maybe just always make it flat diff --git a/TIPS_AND_TRICKS.md b/TIPS_AND_TRICKS.md index ee0761d..49f96ad 100644 --- a/TIPS_AND_TRICKS.md +++ b/TIPS_AND_TRICKS.md @@ -14,7 +14,7 @@ At the end of the day though, all the columnular sculpting is doing is adding ex ## skin mode -SA, HiPro and DSA keycaps take _forever_ to render. This is a multifaceted issue that I don't want to get into here, but suffice to say _one_ of the reasons it takes so long is how the keycap is constructed from multiple, smaller slices. OpenSCAD takes more time to render the more objects you have, regardless of how they interact. Enter `$skin_extrude_shape = true`. +SA, HiPro and DSA keycaps take _forever_ to render. This is a multifaceted issue that I don't want to get into here, but suffice to say _one_ of the reasons it takes so long is how the keycap is constructed from multiple, smaller slices. OpenSCAD takes more time to render the more objects you have, regardless of how they interact. Enter `$hull_shape_type = "skin"`. `skin()` is a list comprehension function available [here](https://github.com/openscad/list-comprehension-demos/blob/master/skin.scad). The gist of it is that instead of having x number of keycap slices unioned together, we give `skin()` a set of profiles and it makes a single object out of it for us. This reduces the number of objects per keycap, which makes it easier to render them. diff --git a/customizer.scad b/customizer.scad index 40bc3d4..8712e37 100644 --- a/customizer.scad +++ b/customizer.scad @@ -133,12 +133,10 @@ $font="DejaVu Sans Mono:style=Book"; // Whether or not to render fake keyswitches to check clearances $clearance_check = false; // Should be faster, also required for concave shapes -// Use linear_extrude instead of hull slices to make the shape of the key -$linear_extrude_shape = false; -// warns in trajectory.scad but it looks benign -// brand new, more correct, hopefully faster, lots more work -$skin_extrude_shape = false; +// what kind of extrusion we use to create the keycap. "hull" is standard, "linear extrude" is legacy, "skin" is new and not well supported. +$hull_shape_type = "hull"; // ["hull", "linear extrude", "skin"] + // This doesn't work very well, but you can try $rounded_key = false; //minkowski radius. radius of sphere used in minkowski sum for minkowski_key function. 1.75 for G20 @@ -557,7 +555,7 @@ module grid_row(row=3, column = 0) { $dish_skew_x = 0; $dish_skew_y = 0; - $linear_extrude_shape = true; + $hull_shape_type = "linear extrude"; $dish_overdraw_width = -8; @@ -662,7 +660,7 @@ module iso_enter() { $top_tilt = 0; $stem_support_type = "disable"; $key_shape_type = "iso_enter"; - /* $linear_extrude_shape = true; */ + /* $hull_shape_type = "linear extrude"; */ $linear_extrude_height_adjustment = 19.05 * 0.5; // this equals (unit_length(1.5) - unit_length(1.25)) / 2 $dish_overdraw_width = 2.38125; @@ -2962,9 +2960,9 @@ module shape_slice(progress, thickness_difference, depth_difference) { // 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) { + if ($hull_shape_type == "skin") { skin_extrude_shape_hull(thickness_difference, depth_difference, extra_slices); - } else if ($linear_extrude_shape) { + } else if ($hull_shape_type == "linear extrude") { linear_extrude_shape_hull(thickness_difference, depth_difference, extra_slices); } else { hull_shape_hull(thickness_difference, depth_difference, extra_slices); @@ -3928,9 +3926,7 @@ module shape(thickness_difference, depth_difference=0){ } } -// this function is more correct, but takes _forever_ -// the main difference is minkowski happens after dishing, meaning the dish is -// also minkowski'd +// 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 @@ -3953,7 +3949,6 @@ module minkowski_object() { } } - module envelope(depth_difference=0) { s = 1.5; hull(){ @@ -3986,19 +3981,6 @@ 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 - dish_depth = ($dish_type == "disable") ? 0 : $dish_depth; - // if the dish is inverted, we need to account for that too. in this case we do half, otherwise the children would be floating on top of the dish - corrected_dish_depth = ($inverted_dish) ? -dish_depth / 2 : dish_depth; - - top_placement(corrected_dish_depth) { - children(); - } -} - // puts its children at each keystem position provided module keystem_positions(positions) { for (connector_pos = positions) { @@ -4039,6 +4021,19 @@ module top_placement(depth_difference=0) { } } +// 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 + dish_depth = ($dish_type == "disable") ? 0 : $dish_depth; + // if the dish is inverted, we need to account for that too. in this case we do half, otherwise the children would be floating on top of the dish + corrected_dish_depth = ($inverted_dish) ? -dish_depth / 2 : dish_depth; + + top_placement(corrected_dish_depth) { + children(); + } +} + 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 @@ -4063,14 +4058,12 @@ module outer_shape() { } module inner_shape(extra_wall_thickness = 0, extra_keytop_thickness = 0) { - translate([0,0,-SMALLEST_POSSIBLE]) { - if ($inner_shape_type == "flat") { - /* $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($wall_thickness + extra_wall_thickness, $keytop_thickness + extra_keytop_thickness); - } + if ($inner_shape_type == "flat") { + /* $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($wall_thickness + extra_wall_thickness, $keytop_thickness + extra_keytop_thickness); } } @@ -4096,15 +4089,11 @@ module subtractive_features(inset) { if ($clearance_check) %clearance_check(); } +// features inside the key itself (stem, supports, etc) 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 if ($support_type != "disable") support_for($stem_positions, $stem_type); } } @@ -4120,9 +4109,13 @@ module key(inset=false) { }; } - if ($inner_shape_type != "disable") difference() { - inner_shape(); - inside_features(); + if ($inner_shape_type != "disable") { + translate([0,0,-SMALLEST_POSSIBLE]) { + difference() { + inner_shape(); + inside_features(); + } + } } subtractive_features(inset) { @@ -4131,17 +4124,6 @@ module key(inset=false) { } } -module display_key(inset=false) { - minkowski() { - outer_shape(); - minkowski_object(); - // minkowski doesn't work with difference - additive_features(false) { - children(); - }; - } -} - // actual full key with space carved out and keystem/stabilizer connectors // this is an example key with all the fixins from settings.scad module example_key(){ @@ -4265,12 +4247,10 @@ $font="DejaVu Sans Mono:style=Book"; // Whether or not to render fake keyswitches to check clearances $clearance_check = false; // Should be faster, also required for concave shapes -// Use linear_extrude instead of hull slices to make the shape of the key -$linear_extrude_shape = false; -// warns in trajectory.scad but it looks benign -// brand new, more correct, hopefully faster, lots more work -$skin_extrude_shape = false; +// what kind of extrusion we use to create the keycap. "hull" is standard, "linear extrude" is legacy, "skin" is new and not well supported. +$hull_shape_type = "hull"; // ["hull", "linear extrude", "skin"] + // This doesn't work very well, but you can try $rounded_key = false; //minkowski radius. radius of sphere used in minkowski sum for minkowski_key function. 1.75 for G20 diff --git a/src/hulls.scad b/src/hulls.scad index 2fb7218..2698011 100644 --- a/src/hulls.scad +++ b/src/hulls.scad @@ -8,9 +8,9 @@ include // 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) { + if ($hull_shape_type == "skin") { skin_extrude_shape_hull(thickness_difference, depth_difference, extra_slices); - } else if ($linear_extrude_shape) { + } else if ($hull_shape_type == "linear extrude") { linear_extrude_shape_hull(thickness_difference, depth_difference, extra_slices); } else { hull_shape_hull(thickness_difference, depth_difference, extra_slices); diff --git a/src/key.scad b/src/key.scad index 06197ff..388625f 100644 --- a/src/key.scad +++ b/src/key.scad @@ -29,9 +29,7 @@ module shape(thickness_difference, depth_difference=0){ } } -// this function is more correct, but takes _forever_ -// the main difference is minkowski happens after dishing, meaning the dish is -// also minkowski'd +// 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 @@ -54,7 +52,6 @@ module minkowski_object() { } } - module envelope(depth_difference=0) { s = 1.5; hull(){ @@ -87,19 +84,6 @@ 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 - dish_depth = ($dish_type == "disable") ? 0 : $dish_depth; - // if the dish is inverted, we need to account for that too. in this case we do half, otherwise the children would be floating on top of the dish - corrected_dish_depth = ($inverted_dish) ? -dish_depth / 2 : dish_depth; - - top_placement(corrected_dish_depth) { - children(); - } -} - // puts its children at each keystem position provided module keystem_positions(positions) { for (connector_pos = positions) { @@ -140,6 +124,19 @@ module top_placement(depth_difference=0) { } } +// 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 + dish_depth = ($dish_type == "disable") ? 0 : $dish_depth; + // if the dish is inverted, we need to account for that too. in this case we do half, otherwise the children would be floating on top of the dish + corrected_dish_depth = ($inverted_dish) ? -dish_depth / 2 : dish_depth; + + top_placement(corrected_dish_depth) { + children(); + } +} + 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 @@ -164,14 +161,12 @@ module outer_shape() { } module inner_shape(extra_wall_thickness = 0, extra_keytop_thickness = 0) { - translate([0,0,-SMALLEST_POSSIBLE]) { - if ($inner_shape_type == "flat") { - /* $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($wall_thickness + extra_wall_thickness, $keytop_thickness + extra_keytop_thickness); - } + if ($inner_shape_type == "flat") { + /* $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($wall_thickness + extra_wall_thickness, $keytop_thickness + extra_keytop_thickness); } } @@ -197,15 +192,11 @@ module subtractive_features(inset) { if ($clearance_check) %clearance_check(); } +// features inside the key itself (stem, supports, etc) 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 if ($support_type != "disable") support_for($stem_positions, $stem_type); } } @@ -221,9 +212,13 @@ module key(inset=false) { }; } - if ($inner_shape_type != "disable") difference() { - inner_shape(); - inside_features(); + if ($inner_shape_type != "disable") { + translate([0,0,-SMALLEST_POSSIBLE]) { + difference() { + inner_shape(); + inside_features(); + } + } } subtractive_features(inset) { @@ -232,17 +227,6 @@ module key(inset=false) { } } -module display_key(inset=false) { - minkowski() { - outer_shape(); - minkowski_object(); - // minkowski doesn't work with difference - additive_features(false) { - children(); - }; - } -} - // actual full key with space carved out and keystem/stabilizer connectors // this is an example key with all the fixins from settings.scad module example_key(){ diff --git a/src/key_profiles/grid.scad b/src/key_profiles/grid.scad index 2528e11..94f4906 100644 --- a/src/key_profiles/grid.scad +++ b/src/key_profiles/grid.scad @@ -11,7 +11,7 @@ module grid_row(row=3, column = 0) { $dish_skew_x = 0; $dish_skew_y = 0; - $linear_extrude_shape = true; + $hull_shape_type = "linear extrude"; $dish_overdraw_width = -8; diff --git a/src/key_types.scad b/src/key_types.scad index 1b821a1..b867895 100644 --- a/src/key_types.scad +++ b/src/key_types.scad @@ -46,7 +46,7 @@ module iso_enter() { $top_tilt = 0; $stem_support_type = "disable"; $key_shape_type = "iso_enter"; - /* $linear_extrude_shape = true; */ + /* $hull_shape_type = "linear extrude"; */ $linear_extrude_height_adjustment = 19.05 * 0.5; // this equals (unit_length(1.5) - unit_length(1.25)) / 2 $dish_overdraw_width = 2.38125; diff --git a/src/settings.scad b/src/settings.scad index 0869c1e..186a395 100644 --- a/src/settings.scad +++ b/src/settings.scad @@ -118,12 +118,10 @@ $font="DejaVu Sans Mono:style=Book"; // Whether or not to render fake keyswitches to check clearances $clearance_check = false; // Should be faster, also required for concave shapes -// Use linear_extrude instead of hull slices to make the shape of the key -$linear_extrude_shape = false; -// warns in trajectory.scad but it looks benign -// brand new, more correct, hopefully faster, lots more work -$skin_extrude_shape = false; +// what kind of extrusion we use to create the keycap. "hull" is standard, "linear extrude" is legacy, "skin" is new and not well supported. +$hull_shape_type = "hull"; // ["hull", "linear extrude", "skin"] + // This doesn't work very well, but you can try $rounded_key = false; //minkowski radius. radius of sphere used in minkowski sum for minkowski_key function. 1.75 for G20