xantronix-z32/case/top.scad

262 lines
8.5 KiB
OpenSCAD
Raw Normal View History

$fn = 72;
2023-11-15 13:03:23 -05:00
include <keyboard.scad>
2023-11-17 15:59:21 -05:00
include <dimensions.scad>
2023-11-14 12:46:52 -05:00
2023-11-17 09:47:43 -05:00
module top_case(key_switch_sizes, pcb_screw_holes) {
2023-11-16 21:55:48 -05:00
keyboard_deck_z_offset = wall_height - keyboard_switch_height;
2023-11-15 17:56:39 -05:00
2023-11-14 12:46:52 -05:00
accent_width = 1.0000;
accent_depth = 0.5;
2023-11-16 20:16:24 -05:00
accent_y_stride = (keyboard_pcb_length - accent_width) / 5.0;
2023-11-14 12:46:52 -05:00
accent_y_bottom = keyboard_y_offset;
2023-11-15 13:09:01 -05:00
vent_width = 2.0000;
vent_length = wall_width;
vent_height = 12.0000;
vent_count = 32;
2023-11-16 20:16:24 -05:00
vent_x_first = keyboard_x_offset + keyboard_pcb_width - vent_count * (vent_width + vent_width);
2023-11-15 13:09:01 -05:00
vent_y_offset = case_length_bottom - vent_length;
2023-11-14 12:46:52 -05:00
2023-11-16 13:51:20 -05:00
eps = 0.01;
2023-11-15 21:18:41 -05:00
2023-11-14 12:46:52 -05:00
module fascia() {
difference() {
2023-11-16 13:51:20 -05:00
cube([case_width_bottom, case_length_bottom, wall_width], false);
translate([keyboard_x_offset, keyboard_y_offset, -eps])
2023-11-16 20:16:24 -05:00
cube([keyboard_pcb_width, keyboard_pcb_length, wall_width + 2*eps], false);
2023-11-14 12:46:52 -05:00
}
2023-11-13 23:19:15 -05:00
}
2023-11-13 21:43:43 -05:00
2023-11-15 13:09:01 -05:00
module vents() {
for (i = [0:vent_count]) {
x = vent_x_first + (i * (vent_width + vent_width));
2023-11-14 12:35:19 -05:00
2023-11-16 13:51:20 -05:00
translate([x, vent_y_offset-eps, wall_height - vent_height])
cube([vent_width, vent_length+2*eps, vent_height+eps], false);
2023-11-14 12:46:52 -05:00
}
}
2023-11-13 21:43:43 -05:00
2023-11-14 12:46:52 -05:00
module accents() {
for (y = [accent_y_bottom: accent_y_stride: case_length_bottom]) {
/* Top */
2023-11-16 13:51:20 -05:00
translate([-eps, y, wall_height - accent_depth])
cube([case_width_bottom+2*eps, accent_width, accent_depth+eps], false);
2023-11-14 12:35:19 -05:00
2023-11-14 12:46:52 -05:00
/* Right */
2023-11-16 13:51:20 -05:00
translate([case_width_bottom - accent_depth, y, -eps])
cube([accent_depth+eps, accent_width+eps, wall_height+2*eps], false);
2023-11-14 12:35:19 -05:00
2023-11-14 12:46:52 -05:00
/* Left */
2023-11-16 13:51:20 -05:00
translate([-eps, y, -eps])
cube([accent_depth+eps, accent_width, wall_height+2*eps], false);
2023-11-14 12:46:52 -05:00
}
}
2023-11-15 17:56:39 -05:00
2023-11-16 19:20:18 -05:00
module screw_posts() {
module screw_post(h) {
difference() {
2023-11-17 13:18:03 -05:00
cylinder(h, d=screw_post_diameter_outer);
2023-11-16 13:51:20 -05:00
2023-11-16 19:20:18 -05:00
translate([0, 0, -eps])
2023-11-17 13:18:03 -05:00
cylinder(h + 2*eps, d=screw_post_diameter_inner);
2023-11-16 19:20:18 -05:00
}
2023-11-16 13:51:20 -05:00
}
2023-11-17 10:06:00 -05:00
for (post = top_case_screw_posts) {
2023-11-16 17:15:15 -05:00
translate([post[0], post[1], wall_height - wall_width - post[2] - eps])
screw_post(post[2] + eps);
2023-11-15 21:18:41 -05:00
}
}
2023-11-16 19:29:26 -05:00
module supports() {
2023-11-16 21:55:48 -05:00
support_width = 1.2500;
support_height = keyboard_switch_height - wall_width;
aspect_ratio = 3.75 / 12.0;
2023-11-16 19:29:26 -05:00
module support(dimensions, width) {
length = dimensions[0];
height = dimensions[1];
2023-11-15 17:56:39 -05:00
2023-11-16 19:29:26 -05:00
module right_triangle(base) {
hypot = sqrt(2*(base^2));
2023-11-15 17:56:39 -05:00
2023-11-16 19:29:26 -05:00
intersection() {
square([base, base]);
2023-11-15 15:11:51 -05:00
2023-11-16 19:29:26 -05:00
translate([-base, 0, 0])
rotate([0, 0, -45])
square([hypot, hypot]);
}
2023-11-15 15:11:51 -05:00
}
2023-11-15 17:56:39 -05:00
2023-11-16 19:29:26 -05:00
module shape() {
/* Height ratio of lower aspect to upper aspect */
aspect_upper_height = height;
aspect_lower_height = aspect_ratio * height;
2023-11-15 17:56:39 -05:00
2023-11-16 19:29:26 -05:00
/* The length of each individual support aspect */
aspect_length = 1/3 * length;
2023-11-15 15:11:51 -05:00
2023-11-16 19:29:26 -05:00
hypotenuse = sqrt(2*(aspect_length^2));
lower_x_offset = aspect_length - (hypotenuse - aspect_length);
2023-11-15 17:56:39 -05:00
2023-11-16 19:29:26 -05:00
right_triangle(height);
2023-11-15 17:56:39 -05:00
2023-11-16 19:29:26 -05:00
square([length, aspect_lower_height], false);
2023-11-15 17:56:39 -05:00
2023-11-16 19:29:26 -05:00
translate([3 * aspect_length, 0, 0])
mirror([1, 0, 0])
right_triangle(height);
}
2023-11-15 17:56:39 -05:00
2023-11-16 19:29:26 -05:00
translate([0, length, 0])
rotate([-90, 0, -90])
linear_extrude(width)
intersection() {
shape();
square([length, height], false);
}
2023-11-15 18:48:50 -05:00
}
2023-11-15 17:56:39 -05:00
2023-11-16 20:16:24 -05:00
support_x_interval = (keyboard_pcb_width + 2 * wall_width - support_width) / 6;
2023-11-15 20:02:49 -05:00
support_x_offset = keyboard_x_offset - wall_width;
2023-11-16 20:16:24 -05:00
support_y_interval = (keyboard_pcb_length + 2 * wall_width - support_width) / 4;
2023-11-15 20:02:49 -05:00
support_y_offset = keyboard_y_offset;
2023-11-15 18:16:58 -05:00
2023-11-15 18:48:50 -05:00
/* Upper vertical supports */
2023-11-15 17:56:39 -05:00
upper_support_length = case_length_bottom
2023-11-16 20:16:24 -05:00
- keyboard_pcb_length
2023-11-15 17:56:39 -05:00
- keyboard_y_offset
- 2 * wall_width;
upper_support_y_offset = keyboard_y_offset
2023-11-16 20:16:24 -05:00
+ keyboard_pcb_length
2023-11-15 17:56:39 -05:00
+ wall_width;
2023-11-15 18:48:50 -05:00
/* Lower vertical supports */
2023-11-15 20:02:49 -05:00
lower_support_length = keyboard_y_offset - 2 * wall_width;
2023-11-15 18:48:50 -05:00
lower_support_y_offset = wall_width;
2023-11-15 20:02:49 -05:00
/* Left horizontal supports */
left_support_length = keyboard_x_offset - 2 * wall_width;
left_support_x_offset = wall_width;
/* Right horizontal supports */
right_support_length = case_width_bottom
2023-11-16 20:16:24 -05:00
- keyboard_pcb_width
2023-11-15 20:02:49 -05:00
- keyboard_x_offset
- 2 * wall_width;
right_support_x_offset = keyboard_x_offset
2023-11-16 20:16:24 -05:00
+ keyboard_pcb_width
2023-11-15 20:02:49 -05:00
+ wall_width;
2023-11-16 20:16:24 -05:00
for (x = [0: support_x_interval: keyboard_pcb_width + 2 * wall_width]) {
2023-11-15 18:48:50 -05:00
translate([support_x_offset + x,
2023-11-16 17:15:15 -05:00
upper_support_y_offset - eps,
2023-11-15 18:16:58 -05:00
wall_height - wall_width])
2023-11-16 21:55:48 -05:00
support([upper_support_length + 2*eps, support_height], support_width);
2023-11-15 18:48:50 -05:00
translate([support_x_offset + x,
2023-11-16 17:15:15 -05:00
lower_support_y_offset - eps,
2023-11-15 18:48:50 -05:00
wall_height - wall_width])
2023-11-16 21:55:48 -05:00
support([lower_support_length + 2*eps, support_height], support_width);
2023-11-15 18:16:58 -05:00
}
2023-11-15 20:02:49 -05:00
2023-11-16 20:16:24 -05:00
for (y = [0: support_y_interval: keyboard_pcb_length + 2 * wall_width]) {
2023-11-16 17:15:15 -05:00
translate([right_support_x_offset - eps,
2023-11-15 20:02:49 -05:00
support_y_offset + y - wall_width + support_width,
wall_height - wall_width])
rotate([0, 0, -90])
2023-11-16 21:55:48 -05:00
support([right_support_length + 2*eps, support_height], support_width);
2023-11-15 21:18:41 -05:00
2023-11-16 14:35:36 -05:00
translate([left_support_x_offset - eps,
2023-11-15 20:02:49 -05:00
support_y_offset + y - wall_width + support_width,
wall_height - wall_width])
rotate([0, 0, -90])
2023-11-16 21:55:48 -05:00
support([left_support_length + 2*eps, support_height], support_width);
2023-11-15 20:02:49 -05:00
}
2023-11-14 12:46:52 -05:00
}
module logotype() {
module logotype_text(size) {
size_ratio = 1/5;
text("XANTRONIX", font="Proxima Nova Semibold", size=size*size_ratio);
2023-11-16 23:57:36 -05:00
translate([16, 0, 0])
text("Z32", font="Proxima Nova Semibold", size=size);
2023-11-16 23:57:36 -05:00
}
size = 10;
2023-11-16 23:57:36 -05:00
translate([keyboard_x_offset,
keyboard_y_offset + keyboard_pcb_length + keyboard_switch_length + accent_width,
wall_height - accent_depth])
linear_extrude(accent_depth + eps)
logotype_text(size);
}
module sextile() {
module shape(width) {
ratio = 33 / 197;
margin = 0.5;
for (angle = [0, -55, 55]) {
rotate([0, 0, angle])
square([width + margin, ratio * width + 2*margin], true);
}
}
width = 16.0;
offset_y = keyboard_y_offset + (keyboard_switch_width + accent_width) / 2;
offset_x = case_width_bottom - width;
translate([offset_x, offset_y, wall_height - accent_depth])
linear_extrude(accent_depth + eps)
shape(width);
2023-11-16 23:57:36 -05:00
}
2023-11-15 19:10:38 -05:00
module body() {
translate([0, 0, wall_height - wall_width])
fascia();
2023-11-15 19:10:38 -05:00
/* Upper */
translate([wall_width, case_length_bottom - wall_width_upper, 0])
cube([case_width_bottom - 2*wall_width, wall_width_upper, wall_lip_upper], false);
translate([0, case_length_bottom - wall_width, wall_lip_upper])
cube([case_width_bottom, wall_width, wall_height - wall_lip_upper], false);
2023-11-15 19:10:38 -05:00
/* Right */
translate([case_width_bottom - wall_width, 0, 0])
2023-11-16 17:15:15 -05:00
cube([wall_width, case_length_bottom, wall_height], false);
2023-11-15 19:10:38 -05:00
/* Lower */
2023-11-16 17:15:15 -05:00
cube([case_width_bottom, wall_width, wall_height], false);
2023-11-15 19:10:38 -05:00
/* Left */
2023-11-16 17:15:15 -05:00
cube([wall_width, case_length_bottom, wall_height], false);
2023-11-15 19:10:38 -05:00
}
2023-11-14 12:46:52 -05:00
difference() {
body();
logotype();
sextile();
2023-11-14 12:46:52 -05:00
accents();
2023-11-15 13:09:01 -05:00
vents();
2023-11-14 12:46:52 -05:00
}
2023-11-14 16:29:51 -05:00
2023-11-15 19:10:38 -05:00
supports();
2023-11-16 13:51:20 -05:00
screw_posts();
2023-11-15 19:10:38 -05:00
2023-11-14 17:33:44 -05:00
translate([keyboard_x_offset, keyboard_y_offset, keyboard_deck_z_offset])
2023-11-16 20:16:24 -05:00
keyboard_deck(wall_width);
2023-11-14 12:35:19 -05:00
}
2023-11-14 12:46:52 -05:00
2023-11-15 17:56:39 -05:00
top_case(keyboard_switch_sizes, keyboard_pcb_screw_holes);