diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | resources/multithumb_test.PNG | bin | 0 -> 73978 bytes | |||
-rw-r--r-- | resources/separable_thumb1.PNG | bin | 0 -> 794001 bytes | |||
-rw-r--r-- | resources/separable_thumb2.PNG | bin | 0 -> 800252 bytes | |||
-rw-r--r-- | resources/trackball_test.PNG | bin | 0 -> 742543 bytes | |||
-rw-r--r-- | src/dactyl_manuform.py | 1209 | ||||
-rw-r--r-- | src/generate_configuration.py | 145 | ||||
-rw-r--r-- | src/generate_configuration_orbyl_test.py | 501 | ||||
-rw-r--r-- | src/generate_configuration_test.py | 501 | ||||
-rw-r--r-- | src/helpers_blender.py | 3 | ||||
-rw-r--r-- | src/helpers_cadquery.py | 31 | ||||
-rw-r--r-- | src/helpers_solid.py | 31 | ||||
-rw-r--r-- | src/parts/trackball_sensor_mount.stl | bin | 307684 -> 307684 bytes | |||
-rw-r--r-- | src/run_config.json | 229 |
14 files changed, 2050 insertions, 602 deletions
@@ -19,3 +19,5 @@ things/ things/*.scad things/*.step things/*.stl +*.3mf +*.dxf diff --git a/resources/multithumb_test.PNG b/resources/multithumb_test.PNG Binary files differnew file mode 100644 index 0000000..7371b2c --- /dev/null +++ b/resources/multithumb_test.PNG diff --git a/resources/separable_thumb1.PNG b/resources/separable_thumb1.PNG Binary files differnew file mode 100644 index 0000000..6435d05 --- /dev/null +++ b/resources/separable_thumb1.PNG diff --git a/resources/separable_thumb2.PNG b/resources/separable_thumb2.PNG Binary files differnew file mode 100644 index 0000000..736ff1a --- /dev/null +++ b/resources/separable_thumb2.PNG diff --git a/resources/trackball_test.PNG b/resources/trackball_test.PNG Binary files differnew file mode 100644 index 0000000..3d8deba --- /dev/null +++ b/resources/trackball_test.PNG diff --git a/src/dactyl_manuform.py b/src/dactyl_manuform.py index a04a291..8dc44b5 100644 --- a/src/dactyl_manuform.py +++ b/src/dactyl_manuform.py @@ -4,6 +4,7 @@ import os.path as path import getopt, sys import json import os +import copy from scipy.spatial import ConvexHull as sphull @@ -272,31 +273,48 @@ def single_plate(cylinder_segments=100, side="right"): return plate +def plate_pcb_cutout(side="right"): + shape = box(*plate_pcb_size) + shape = translate(shape, (0, 0, -plate_pcb_size[2]/2)) + shape = translate(shape, plate_pcb_offset) + + if side == "left": + shape = mirror(shape, 'YZ') + + return shape + def trackball_cutout(segments=100, side="right"): - shape = cylinder(trackball_hole_diameter / 2, trackball_hole_height) + if trackball_modular: + hole_diameter = ball_diameter + 2 * (ball_gap + ball_wall_thickness + trackball_modular_clearance+trackball_modular_lip_width)-.1 + shape = cylinder(hole_diameter / 2, trackball_hole_height) + else: + shape = cylinder(trackball_hole_diameter / 2, trackball_hole_height) return shape def trackball_socket(segments=100, side="right"): - # shape = sphere(ball_diameter / 2) - # cyl = cylinder(ball_diameter / 2 + 4, 20) - # cyl = translate(cyl, (0, 0, -8)) - # shape = union([shape, cyl]) + if trackball_modular: + hole_diameter = ball_diameter + 2 * (ball_gap + ball_wall_thickness + trackball_modular_clearance) + ring_diameter = hole_diameter + 2 * trackball_modular_lip_width + ring_height = trackball_modular_ring_height + ring_z_offset = mount_thickness - trackball_modular_ball_height + shape = cylinder(ring_diameter / 2, ring_height) + shape = translate(shape, (0, 0, -ring_height / 2 + ring_z_offset)) - tb_file = path.join(parts_path, r"trackball_socket_body_34mm") - tbcut_file = path.join(parts_path, r"trackball_socket_cutter_34mm") - sens_file = path.join(parts_path, r"trackball_sensor_mount") - senscut_file = path.join(parts_path, r"trackball_sensor_cutter") + cutter = cylinder(hole_diameter / 2, ring_height + .2) + cutter = translate(cutter, (0, 0, -ring_height / 2 + ring_z_offset)) + sensor = None - # shape = import_file(tb_file) - # # shape = difference(shape, [import_file(senscut_file)]) - # # shape = union([shape, import_file(sens_file)]) - # cutter = import_file(tbcut_file) + else: + tb_file = path.join(parts_path, r"trackball_socket_body_34mm") + tbcut_file = path.join(parts_path, r"trackball_socket_cutter_34mm") + sens_file = path.join(parts_path, r"trackball_sensor_mount") + senscut_file = path.join(parts_path, r"trackball_sensor_cutter") - shape = import_file(tb_file) - sensor = import_file(sens_file) - cutter = import_file(tbcut_file) - cutter = union([cutter, import_file(senscut_file)]) + shape = import_file(tb_file) + sensor = import_file(sens_file) + cutter = import_file(tbcut_file) + cutter = union([cutter, import_file(senscut_file)]) # return shape, cutter return shape, cutter, sensor @@ -496,6 +514,19 @@ def key_holes(side="right"): return shape +def plate_pcb_cutouts(side="right"): + debugprint('plate_pcb_cutouts()') + # hole = single_plate() + cutouts = [] + for column in range(ncols): + for row in range(nrows): + if (column in [2, 3]) or (not row == lastrow): + cutouts.append(key_place(plate_pcb_cutout(side=side), column, row)) + + # cutouts = union(cutouts) + + return cutouts + def caps(): caps = None @@ -561,7 +592,11 @@ def connectors(): debugprint('connectors()') hulls = [] for column in range(ncols - 1): - for row in range(lastrow): # need to consider last_row? + if (column in [2]): + iterrows = lastrow+1 + else: + iterrows = lastrow + for row in range(iterrows): # need to consider last_row? # for row in range(nrows): # need to consider last_row? places = [] places.append(key_place(web_post_tl(), column + 1, row)) @@ -571,8 +606,11 @@ def connectors(): hulls.append(triangle_hulls(places)) for column in range(ncols): - # for row in range(nrows-1): - for row in range(cornerrow): + if (column in [2, 3]): + iterrows = lastrow + else: + iterrows = cornerrow + for row in range(iterrows): places = [] places.append(key_place(web_post_bl(), column, row)) places.append(key_place(web_post_br(), column, row)) @@ -581,8 +619,11 @@ def connectors(): hulls.append(triangle_hulls(places)) for column in range(ncols - 1): - # for row in range(nrows-1): # need to consider last_row? - for row in range(cornerrow): # need to consider last_row? + if (column in [2]): + iterrows = lastrow + else: + iterrows = cornerrow + for row in range(iterrows): places = [] places.append(key_place(web_post_br(), column, row)) places.append(key_place(web_post_tr(), column, row + 1)) @@ -590,7 +631,24 @@ def connectors(): places.append(key_place(web_post_tl(), column + 1, row + 1)) hulls.append(triangle_hulls(places)) - return union(hulls) + if column == 1: + places = [] + places.append(key_place(web_post_bl(), column + 1, iterrows)) + places.append(key_place(web_post_br(), column, iterrows)) + places.append(key_place(web_post_tl(), column + 1, iterrows + 1)) + places.append(key_place(web_post_bl(), column + 1, iterrows + 1)) + hulls.append(triangle_hulls(places)) + if column == 3: + places = [] + places.append(key_place(web_post_br(), column, iterrows)) + places.append(key_place(web_post_bl(), column + 1, iterrows)) + places.append(key_place(web_post_tr(), column, iterrows + 1)) + places.append(key_place(web_post_br(), column, iterrows + 1)) + hulls.append(triangle_hulls(places)) + + + # return union(hulls) + return add(hulls) ############ @@ -606,7 +664,7 @@ def thumborigin(): origin[i] = origin[i] + thumb_offsets[i] if thumb_style == 'MINIDOX': - origin[1] = origin[1] - .4*(trackball_Usize-1)*sa_length + origin[1] = origin[1] - .4*(minidox_Usize-1)*sa_length return origin @@ -686,6 +744,10 @@ def default_thumb_1x_layout(shape, cap=False): shapes = union(shape_list) return shapes +def default_thumb_pcb_plate_cutouts(side="right"): + shape = default_thumb_1x_layout(plate_pcb_cutout(side=side)) + shape = union([shape, default_thumb_15x_layout(plate_pcb_cutout(side=side))]) + return shape def default_thumb_15x_layout(shape, cap=False, plate=True): debugprint('thumb_15x_layout()') @@ -722,6 +784,9 @@ def default_thumb_15x_layout(shape, cap=False, plate=True): def adjustable_plate_size(Usize=1.5): return (Usize * sa_length - mount_height) / 2 +def usize_dimention(Usize=1.5): + return Usize * sa_length + def adjustable_plate_half(Usize=1.5): debugprint('double_plate()') @@ -737,6 +802,14 @@ def adjustable_plate(Usize=1.5): top_plate = adjustable_plate_half(Usize) return union((top_plate, mirror(top_plate, 'XZ'))) +def adjustable_square_plate(Uwidth=1.5, Uheight=1.5): + width = usize_dimention(Usize=Uwidth) + height = usize_dimention(Usize=Uheight) + print("width: {}, height: {}, thickness:{}".format(width, height, web_thickness)) + shape = box(width, height, web_thickness) + shape = difference(shape, [box(mount_width-.01, mount_height-.01, 2*web_thickness)]) + shape = translate(shape, (0, 0, web_thickness/2)) + return shape def double_plate_half(): debugprint('double_plate()') @@ -830,6 +903,31 @@ def thumb_connectors(side='right', style_override=None): return default_thumb_connectors() +def thumb_pcb_plate_cutouts(side='right', style_override=None): + if style_override is None: + _thumb_style = thumb_style + else: + _thumb_style = style_override + + if _thumb_style == "MINI": + return mini_thumb_pcb_plate_cutouts(side) + elif _thumb_style == "MINIDOX": + return minidox_thumb_pcb_plate_cutouts(side) + elif _thumb_style == "CARBONFET": + return carbonfet_thumb_pcb_plate_cutouts(side) + + elif "TRACKBALL" in _thumb_style: + if (side == ball_side or ball_side == 'both'): + if _thumb_style == "TRACKBALL_ORBYL": + return tbjs_thumb_pcb_plate_cutouts(side) + elif _thumb_style == "TRACKBALL_CJ": + return tbcj_thumb_pcb_plate_cutouts(side) + else: + return thumb_pcb_plate_cutouts(side, style_override=other_thumb) + + else: + return default_thumb_pcb_plate_cutouts(side) + def default_thumbcaps(): t1 = default_thumb_1x_layout(sa_cap(1), cap=True) if not default_1U_cluster: @@ -840,8 +938,11 @@ def default_thumbcaps(): def default_thumb(side="right"): print('thumb()') shape = default_thumb_1x_layout(rotate(single_plate(side=side), (0, 0, -90))) - shape = union([shape, default_thumb_15x_layout(rotate(single_plate(side=side), (0, 0, -90)))]) - shape = union([shape, default_thumb_15x_layout(double_plate(), plate=False)]) + # shape = union([shape, default_thumb_15x_layout(rotate(single_plate(side=side), (0, 0, -90)))]) + # shape = union([shape, default_thumb_15x_layout(double_plate(), plate=False)]) + shape = add([shape, default_thumb_15x_layout(rotate(single_plate(side=side), (0, 0, -90)))]) + shape = add([shape, default_thumb_15x_layout(double_plate(), plate=False)]) + shape = difference(shape, [default_thumb_pcb_plate_cutouts()]) return shape @@ -998,19 +1099,12 @@ def default_thumb_connectors(): key_place(web_post_bl(), 1, cornerrow), default_thumb_tr_place(web_post_tr()), key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), key_place(web_post_bl(), 2, lastrow), default_thumb_tr_place(web_post_tr()), key_place(web_post_bl(), 2, lastrow), default_thumb_tr_place(web_post_br()), key_place(web_post_br(), 2, lastrow), key_place(web_post_bl(), 3, lastrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_tl(), 3, lastrow), - key_place(web_post_bl(), 3, cornerrow), - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - key_place(web_post_bl(), 4, cornerrow), ] ) ) @@ -1032,42 +1126,12 @@ def default_thumb_connectors(): key_place(web_post_bl(), 2, lastrow), default_thumb_tr_place(thumb_post_br()), key_place(web_post_br(), 2, lastrow), - key_place(web_post_bl(), 3, lastrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_tl(), 3, lastrow), - key_place(web_post_bl(), 3, cornerrow), - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - key_place(web_post_bl(), 4, cornerrow), ] ) ) - hulls.append( - triangle_hulls( - [ - key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), - key_place(web_post_bl(), 2, cornerrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_br(), 2, cornerrow), - key_place(web_post_bl(), 3, cornerrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, lastrow), - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_bl(), 4, cornerrow), - ] - ) - ) - - return union(hulls) + return add(hulls) + # return union(hulls) ############################ # MINI THUMB CLUSTER @@ -1110,7 +1174,8 @@ def mini_thumb_bl_place(shape): def mini_thumb_1x_layout(shape): - return union([ + # return union([ + return add([ mini_thumb_mr_place(rotate(shape, [0, 0, thumb_plate_mr_rotation])), mini_thumb_br_place(rotate(shape, [0, 0, thumb_plate_br_rotation])), mini_thumb_tl_place(rotate(shape, [0, 0, thumb_plate_tl_rotation])), @@ -1119,7 +1184,8 @@ def mini_thumb_1x_layout(shape): def mini_thumb_15x_layout(shape): - return union([mini_thumb_tr_place(rotate(shape, [0, 0, thumb_plate_tr_rotation]))]) + # return union([mini_thumb_tr_place(rotate(shape, [0, 0, thumb_plate_tr_rotation]))]) + return add([mini_thumb_tr_place(rotate(shape, [0, 0, thumb_plate_tr_rotation]))]) def mini_thumbcaps(): @@ -1130,8 +1196,15 @@ def mini_thumbcaps(): def mini_thumb(side="right"): shape = mini_thumb_1x_layout(single_plate(side=side)) - shape = union([shape, mini_thumb_15x_layout(single_plate(side=side))]) + # shape = union([shape, mini_thumb_15x_layout(single_plate(side=side))]) + shape = add([shape, mini_thumb_15x_layout(single_plate(side=side))]) + + return shape +def mini_thumb_pcb_plate_cutouts(side="right"): + shape = mini_thumb_1x_layout(plate_pcb_cutout(side=side)) + # shape = union([shape, mini_thumb_15x_layout(plate_pcb_cutout(side=side))]) + shape = add([shape, mini_thumb_15x_layout(plate_pcb_cutout(side=side))]) return shape @@ -1242,54 +1315,19 @@ def mini_thumb_connectors(): key_place(web_post_bl(), 1, cornerrow), mini_thumb_tr_place(mini_thumb_post_tr()), key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), + # key_place(web_post_tl(), 2, lastrow), key_place(web_post_bl(), 2, lastrow), mini_thumb_tr_place(mini_thumb_post_tr()), key_place(web_post_bl(), 2, lastrow), mini_thumb_tr_place(mini_thumb_post_br()), key_place(web_post_br(), 2, lastrow), key_place(web_post_bl(), 3, lastrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_tl(), 3, lastrow), - key_place(web_post_bl(), 3, cornerrow), - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - ] - ) - ) - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, lastrow), - key_place(web_post_bl(), 4, cornerrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - key_place(web_post_bl(), 4, cornerrow), - ] - ) - ) - hulls.append( - triangle_hulls( - [ - key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), - key_place(web_post_bl(), 2, cornerrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_br(), 2, cornerrow), - key_place(web_post_bl(), 3, cornerrow), ] ) ) - return union(hulls) + # return union(hulls) + return add(hulls) ############################ @@ -1336,7 +1374,8 @@ def minidox_thumb_br_place(shape): def minidox_thumb_1x_layout(shape): - return union([ + # return union([ + return add([ minidox_thumb_tr_place(rotate(shape, [0, 0, thumb_plate_tr_rotation])), minidox_thumb_tl_place(rotate(shape, [0, 0, thumb_plate_tl_rotation])), minidox_thumb_ml_place(rotate(shape, [0, 0, thumb_plate_ml_rotation])), @@ -1344,7 +1383,8 @@ def minidox_thumb_1x_layout(shape): def minidox_thumb_fx_layout(shape): - return union([ + # return union([ + return add([ minidox_thumb_tr_place(rotate(shape, [0, 0, thumb_plate_tr_rotation])), minidox_thumb_tl_place(rotate(shape, [0, 0, thumb_plate_tl_rotation])), minidox_thumb_ml_place(rotate(shape, [0, 0, thumb_plate_ml_rotation])), @@ -1359,11 +1399,15 @@ def minidox_thumbcaps(): def minidox_thumb(side="right"): shape = minidox_thumb_fx_layout(rotate(single_plate(side=side), [0.0, 0.0, -90])) - shape = union([shape, minidox_thumb_fx_layout(adjustable_plate(minidox_Usize))]) + # shape = union([shape, minidox_thumb_fx_layout(adjustable_plate(minidox_Usize))]) + shape = add([shape, minidox_thumb_fx_layout(adjustable_plate(minidox_Usize))]) # shape = minidox_thumb_1x_layout(single_plate(side=side)) + return shape - - +def minidox_thumb_pcb_plate_cutouts(side="right"): + shape = minidox_thumb_fx_layout(plate_pcb_cutout(side=side)) + # shape = union([shape, minidox_thumb_fx_layout(plate_pcb_cutout())]) + shape = add([shape, minidox_thumb_fx_layout(plate_pcb_cutout())]) return shape def minidox_thumb_post_tr(): @@ -1434,54 +1478,18 @@ def minidox_thumb_connectors(): key_place(web_post_bl(), 1, cornerrow), minidox_thumb_tr_place(minidox_thumb_post_tr()), key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), key_place(web_post_bl(), 2, lastrow), minidox_thumb_tr_place(minidox_thumb_post_tr()), key_place(web_post_bl(), 2, lastrow), minidox_thumb_tr_place(minidox_thumb_post_br()), key_place(web_post_br(), 2, lastrow), key_place(web_post_bl(), 3, lastrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_tl(), 3, lastrow), - key_place(web_post_bl(), 3, cornerrow), - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - ] - ) - ) - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, lastrow), - key_place(web_post_bl(), 4, cornerrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - key_place(web_post_bl(), 4, cornerrow), - ] - ) - ) - hulls.append( - triangle_hulls( - [ - key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), - key_place(web_post_bl(), 2, cornerrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_br(), 2, cornerrow), - key_place(web_post_bl(), 3, cornerrow), ] ) ) - return union(hulls) + # return union(hulls) + return add(hulls) ############################ @@ -1527,7 +1535,8 @@ def carbonfet_thumb_bl_place(shape): def carbonfet_thumb_1x_layout(shape): - return union([ + # return union([ + return add([ carbonfet_thumb_tr_place(rotate(shape, [0, 0, thumb_plate_tr_rotation])), carbonfet_thumb_mr_place(rotate(shape, [0, 0, thumb_plate_mr_rotation])), carbonfet_thumb_br_place(rotate(shape, [0, 0, thumb_plate_br_rotation])), @@ -1537,12 +1546,14 @@ def carbonfet_thumb_1x_layout(shape): def carbonfet_thumb_15x_layout(shape, plate=True): if plate: - return union([ + # return union([ + return add([ carbonfet_thumb_bl_place(rotate(shape, [0, 0, thumb_plate_bl_rotation])), carbonfet_thumb_ml_place(rotate(shape, [0, 0, thumb_plate_ml_rotation])) ]) else: - return union([ + # return union([ + return add([ carbonfet_thumb_bl_place(shape), carbonfet_thumb_ml_place(shape) ]) @@ -1556,9 +1567,17 @@ def carbonfet_thumbcaps(): def carbonfet_thumb(side="right"): shape = carbonfet_thumb_1x_layout(single_plate(side=side)) - shape = union([shape, carbonfet_thumb_15x_layout(double_plate_half(), plate=False)]) - shape = union([shape, carbonfet_thumb_15x_layout(single_plate(side=side))]) + # shape = union([shape, carbonfet_thumb_15x_layout(double_plate_half(), plate=False)]) + # shape = union([shape, carbonfet_thumb_15x_layout(single_plate(side=side))]) + shape = add([shape, carbonfet_thumb_15x_layout(double_plate_half(), plate=False)]) + shape = add([shape, carbonfet_thumb_15x_layout(single_plate(side=side))]) + + return shape +def carbonfet_thumb_pcb_plate_cutouts(side="right"): + shape = carbonfet_thumb_1x_layout(plate_pcb_cutout(side=side)) + # shape = union([shape, carbonfet_thumb_15x_layout(plate_pcb_cutout())]) + shape = add([shape, carbonfet_thumb_15x_layout(plate_pcb_cutout())]) return shape def carbonfet_thumb_post_tr(): @@ -1674,7 +1693,6 @@ def carbonfet_thumb_connectors(): key_place(web_post_bl(), 1, cornerrow), carbonfet_thumb_tl_place(web_post_tr()), key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), key_place(web_post_bl(), 2, lastrow), carbonfet_thumb_tl_place(web_post_tr()), key_place(web_post_bl(), 2, lastrow), @@ -1690,28 +1708,6 @@ def carbonfet_thumb_connectors(): hulls.append( triangle_hulls( [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - key_place(web_post_tl(), 3, lastrow), - key_place(web_post_bl(), 3, cornerrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_br(), 2, lastrow), - key_place(web_post_tl(), 3, lastrow), - key_place(web_post_bl(), 3, lastrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ carbonfet_thumb_tr_place(web_post_br()), carbonfet_thumb_tr_place(web_post_tr()), key_place(web_post_bl(), 3, lastrow), @@ -1719,41 +1715,8 @@ def carbonfet_thumb_connectors(): ) ) - hulls.append( - triangle_hulls( - [ - key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), - key_place(web_post_bl(), 2, cornerrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_br(), 2, cornerrow), - key_place(web_post_tl(), 3, lastrow), - key_place(web_post_bl(), 3, cornerrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, lastrow), - key_place(web_post_bl(), 4, cornerrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - key_place(web_post_bl(), 4, cornerrow), - ] - ) - ) - - return union(hulls) + # return union(hulls) + return add(hulls) ############################ @@ -1764,7 +1727,7 @@ def tbjs_thumb_position_rotation(): rot = [10, -15, 5] pos = thumborigin() # Changes size based on key diameter around ball, shifting off of the top left cluster key. - shift = [-.9*tbjs_key_diameter/2+27-42, -.1*tbjs_key_diameter/2+3-20, -5] + shift = [-.9*tbjs_key_diameter/2+27-42, -.1*tbjs_key_diameter/2+3-25, -5] for i in range(len(pos)): pos[i] = pos[i] + shift[i] + tbjs_translation_offset[i] @@ -1790,9 +1753,7 @@ def tbjs_thumb_tl_place(shape): shape = translate(shape, (t_off[0], t_off[1]+tbjs_key_diameter/2, t_off[2])) shape = rotate(shape, [0,0,-80]) shape = tbjs_place(shape) - # shape = rotate(shape, [5, 10, -65]) - # shape = translate(shape, thumborigin()) - # shape = translate(shape, [-14, -9, 0]) + return shape def tbjs_thumb_mr_place(shape): @@ -1804,9 +1765,6 @@ def tbjs_thumb_mr_place(shape): shape = rotate(shape, [0,0,-130]) shape = tbjs_place(shape) - # shape = rotate(shape, [7, 20, -105]) - # shape = translate(shape, thumborigin()) - # shape = translate(shape, [-12, -32, -5]) return shape def tbjs_thumb_br_place(shape): @@ -1819,9 +1777,6 @@ def tbjs_thumb_br_place(shape): shape = rotate(shape, [0,0,-180]) shape = tbjs_place(shape) - # shape = rotate(shape, [25, -11, 0]) - # shape = translate(shape, thumborigin()) - # shape = translate(shape, [-40, -50, -16]) return shape @@ -1834,67 +1789,50 @@ def tbjs_thumb_bl_place(shape): shape = rotate(shape, [0,0,-230]) shape = tbjs_place(shape) - # shape = rotate(shape, [25, 0, -45]) - # shape = translate(shape, thumborigin()) - # shape = translate(shape, [-63, -41, -18]) return shape -# def tbjs_thumb_tlold_place(shape): -# debugprint('thumb_tl_place()') -# shape = rotate(shape, [7.5, -10, 10]) -# shape = translate(shape, thumborigin()) -# shape = translate(shape, [-32.5, -14.5, -4]) -# return shape -# -# -# def tbjs_thumb_mlold_place(shape): -# debugprint('thumb_ml_place()') -# shape = rotate(shape, [6, -34, 40]) -# shape = translate(shape, thumborigin()) -# shape = translate(shape, [-51, -25, -12]) -# return shape - - def tbjs_thumb_1x_layout(shape): - return union([ + # return union([ + return add([ tbjs_thumb_tl_place(rotate(shape, [0, 0, thumb_plate_tr_rotation])), - # tbjs_thumb_tlold_place(rotate(shape, [0, 0, thumb_plate_tl_rotation])), - # tbjs_thumb_mlold_place(rotate(shape, [0, 0, thumb_plate_ml_rotation])), tbjs_thumb_mr_place(rotate(shape, [0, 0, thumb_plate_mr_rotation])), tbjs_thumb_bl_place(rotate(shape, [0, 0, thumb_plate_bl_rotation])), tbjs_thumb_br_place(rotate(shape, [0, 0, thumb_plate_br_rotation])), ]) +def tbjs_thumb_pcb_plate_cutouts(side="right"): + return tbjs_thumb_1x_layout(plate_pcb_cutout(side=side)) + def tbjs_thumb_fx_layout(shape): - return union([ - # tbjs_thumb_tl_place(rotate(shape, [0, 0, thumb_plate_tr_rotation])), - # tbjs_thumb_tlold_place(rotate(shape, [0, 0, thumb_plate_tl_rotation])), - # tbjs_thumb_mlold_place(rotate(shape, [0, 0, thumb_plate_ml_rotation])), - # tbjs_thumb_mr_place(rotate(shape, [0, 0, thumb_plate_mr_rotation])), - # tbjs_thumb_bl_place(rotate(shape, [0, 0, thumb_plate_bl_rotation])), - # tbjs_thumb_br_place(rotate(shape, [0, 0, thumb_plate_br_rotation])), - ]) + return [ + tbjs_thumb_tl_place(rotate(shape, [0, 0, thumb_plate_tr_rotation])), + tbjs_thumb_mr_place(rotate(shape, [0, 0, thumb_plate_mr_rotation])), + tbjs_thumb_bl_place(rotate(shape, [0, 0, thumb_plate_bl_rotation])), + tbjs_thumb_br_place(rotate(shape, [0, 0, thumb_plate_br_rotation])), + ] def trackball_layout(shape): - return union([ - # Relocating positioning to individual parts due to complexity. - # tbjs_place(rotate(shape, [0, 0, trackball_rotation])), + # return union([ + return add([ tbjs_place(shape), ]) def tbjs_thumbcaps(): t1 = tbjs_thumb_1x_layout(sa_cap(1)) + # t1 = tbjs_thumb_fx_layout(sa_cap(1)) # t1.add(tbjs_thumb_15x_layout(rotate(sa_cap(1), [0, 0, rad2deg(pi / 2)]))) return t1 def tbjs_thumb(side="right"): - shape = tbjs_thumb_fx_layout(rotate(single_plate(side=side), [0.0, 0.0, -90])) - shape = union([shape, tbjs_thumb_fx_layout(double_plate())]) - shape = union([shape, tbjs_thumb_1x_layout(single_plate(side=side))]) + # shape = tbjs_thumb_fx_layout(rotate(single_plate(side=side), [0.0, 0.0, -90])) + shape = tbjs_thumb_1x_layout(single_plate(side=side)) + # shape = tbjs_thumb_fx_layout(adjustable_square_plate(Uwidth=tbjs_Uwidth, Uheight=tbjs_Uheight)) + # shape = union([shape, *tbjs_thumb_fx_layout(adjustable_square_plate(Uwidth=tbjs_Uwidth, Uheight=tbjs_Uheight))]) + shape = add([shape, *tbjs_thumb_fx_layout(adjustable_square_plate(Uwidth=tbjs_Uwidth, Uheight=tbjs_Uheight))]) # shape = union([shape, trackball_layout(trackball_socket())]) # shape = tbjs_thumb_1x_layout(single_plate(side=side)) @@ -1904,28 +1842,28 @@ def tbjs_thumb(side="right"): def tbjs_thumb_post_tr(): debugprint('thumb_post_tr()') return translate(web_post(), - [(mount_width / 2) - post_adj, ((mount_height/2) + adjustable_plate_size(trackball_Usize)) - post_adj, 0] + [(mount_width / 2) + adjustable_plate_size(tbjs_Uwidth) - post_adj, ((mount_height/2) + adjustable_plate_size(tbjs_Uheight)) - post_adj, 0] ) def tbjs_thumb_post_tl(): debugprint('thumb_post_tl()') return translate(web_post(), - [-(mount_width / 2) + post_adj, ((mount_height/2) + adjustable_plate_size(trackball_Usize)) - post_adj, 0] + [-(mount_width / 2) - adjustable_plate_size(tbjs_Uwidth) + post_adj, ((mount_height/2) + adjustable_plate_size(tbjs_Uheight)) - post_adj, 0] ) def tbjs_thumb_post_bl(): debugprint('thumb_post_bl()') return translate(web_post(), - [-(mount_width / 2) + post_adj, -((mount_height/2) + adjustable_plate_size(trackball_Usize)) + post_adj, 0] + [-(mount_width / 2) - adjustable_plate_size(tbjs_Uwidth) + post_adj, -((mount_height/2) + adjustable_plate_size(tbjs_Uheight)) + post_adj, 0] ) def tbjs_thumb_post_br(): debugprint('thumb_post_br()') return translate(web_post(), - [(mount_width / 2) - post_adj, -((mount_height/2) + adjustable_plate_size(trackball_Usize)) + post_adj, 0] + [(mount_width / 2) + adjustable_plate_size(tbjs_Uwidth) - post_adj, - ((mount_height/2) + adjustable_plate_size(tbjs_Uheight)) + post_adj, 0] ) @@ -1986,21 +1924,21 @@ def tbjs_thumb_connectors(): triangle_hulls( [ tbjs_place(tbjs_post_l()), - tbjs_thumb_bl_place(web_post_tl()), + tbjs_thumb_bl_place(tbjs_thumb_post_tl()), tbjs_place(tbjs_post_bl()), - tbjs_thumb_bl_place(web_post_tr()), - tbjs_thumb_br_place(web_post_tl()), + tbjs_thumb_bl_place(tbjs_thumb_post_tr()), + tbjs_thumb_br_place(tbjs_thumb_post_tl()), tbjs_place(tbjs_post_bl()), - tbjs_thumb_br_place(web_post_tr()), + tbjs_thumb_br_place(tbjs_thumb_post_tr()), tbjs_place(tbjs_post_br()), - tbjs_thumb_br_place(web_post_tr()), + tbjs_thumb_br_place(tbjs_thumb_post_tr()), tbjs_place(tbjs_post_br()), - tbjs_thumb_mr_place(web_post_br()), + tbjs_thumb_mr_place(tbjs_thumb_post_br()), tbjs_place(tbjs_post_r()), - tbjs_thumb_mr_place(web_post_bl()), - tbjs_thumb_tl_place(web_post_br()), + tbjs_thumb_mr_place(tbjs_thumb_post_bl()), + tbjs_thumb_tl_place(tbjs_thumb_post_br()), tbjs_place(tbjs_post_r()), - tbjs_thumb_tl_place(web_post_bl()), + tbjs_thumb_tl_place(tbjs_thumb_post_bl()), tbjs_place(tbjs_post_tr()), key_place(web_post_bl(), 0, cornerrow), tbjs_place(tbjs_post_tl()), @@ -2012,10 +1950,10 @@ def tbjs_thumb_connectors(): hulls.append( triangle_hulls( [ - tbjs_thumb_bl_place(web_post_tr()), - tbjs_thumb_br_place(web_post_tl()), - tbjs_thumb_bl_place(web_post_br()), - tbjs_thumb_br_place(web_post_bl()), + tbjs_thumb_bl_place(tbjs_thumb_post_tr()), + tbjs_thumb_br_place(tbjs_thumb_post_tl()), + tbjs_thumb_bl_place(tbjs_thumb_post_br()), + tbjs_thumb_br_place(tbjs_thumb_post_bl()), ] ) ) @@ -2024,10 +1962,10 @@ def tbjs_thumb_connectors(): hulls.append( triangle_hulls( [ - tbjs_thumb_br_place(web_post_tr()), - tbjs_thumb_mr_place(web_post_br()), - tbjs_thumb_br_place(web_post_br()), - tbjs_thumb_mr_place(web_post_tr()), + tbjs_thumb_br_place(tbjs_thumb_post_tr()), + tbjs_thumb_mr_place(tbjs_thumb_post_br()), + tbjs_thumb_br_place(tbjs_thumb_post_br()), + tbjs_thumb_mr_place(tbjs_thumb_post_tr()), ] ) ) @@ -2035,39 +1973,16 @@ def tbjs_thumb_connectors(): hulls.append( triangle_hulls( [ - tbjs_thumb_mr_place(web_post_bl()), - tbjs_thumb_tl_place(web_post_br()), - tbjs_thumb_mr_place(web_post_tl()), - tbjs_thumb_tl_place(web_post_tr()), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), - key_place(web_post_bl(), 2, cornerrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_br(), 2, cornerrow), - key_place(web_post_bl(), 3, cornerrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, lastrow), - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_bl(), 4, cornerrow), + tbjs_thumb_mr_place(tbjs_thumb_post_bl()), + tbjs_thumb_tl_place(tbjs_thumb_post_br()), + tbjs_thumb_mr_place(tbjs_thumb_post_tl()), + tbjs_thumb_tl_place(tbjs_thumb_post_tr()), ] ) ) - return union(hulls) + # return union(hulls) + return add(hulls) @@ -2104,7 +2019,8 @@ def tbcj_thumb_bl_place(shape): return shape def tbcj_thumb_layout(shape): - return union([ + # return union([ + return add([ tbcj_thumb_tr_place(rotate(shape, [0, 0, thumb_plate_tr_rotation])), tbcj_thumb_tl_place(rotate(shape, [0, 0, thumb_plate_tl_rotation])), tbcj_thumb_ml_place(rotate(shape, [0, 0, thumb_plate_ml_rotation])), @@ -2164,24 +2080,26 @@ def tbcj_holder(): return shape def tbcj_thumb_position_rotation(): - # loc = np.array([-15, -60, -12]) + thumborigin() - # shape = translate(shape, loc) - # shape = rotate(shape, (0,0,0)) pos = np.array([-15, -60, -12]) + thumborigin() - rot = (0,0,0) + rot = (0, 0, 0) return pos, rot def tbcj_place(shape): loc = np.array([-15, -60, -12]) + thumborigin() shape = translate(shape, loc) - shape = rotate(shape, (0,0,0)) + shape = rotate(shape, (0, 0, 0)) return shape def tbcj_thumb(side="right"): t = tbcj_thumb_layout(single_plate(side=side)) tb = tbcj_place(tbcj_holder()) - return union([t, tb]) + # return union([t, tb]) + return add([t, tb]) + +def tbcj_thumb_pcb_plate_cutouts(side="right"): + t = tbcj_thumb_layout(plate_pcb_cutout(side=side)) + return t def tbcj_thumbcaps(): t = tbcj_thumb_layout(sa_cap(1)) @@ -2266,43 +2184,12 @@ def tbcj_thumb_connectors(): key_place(web_post_bl(), 1, cornerrow), tbcj_thumb_tr_place(web_post_tr()), key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), key_place(web_post_bl(), 2, lastrow), tbcj_thumb_tr_place(web_post_tr()), key_place(web_post_bl(), 2, lastrow), tbcj_thumb_tr_place(web_post_br()), key_place(web_post_br(), 2, lastrow), key_place(web_post_bl(), 3, lastrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_tl(), 3, lastrow), - key_place(web_post_bl(), 3, cornerrow), - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - key_place(web_post_bl(), 4, cornerrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), - key_place(web_post_bl(), 2, cornerrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_br(), 2, cornerrow), - key_place(web_post_bl(), 3, cornerrow), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, lastrow), - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_bl(), 4, cornerrow), ] ) ) @@ -2354,7 +2241,8 @@ def tbcj_thumb_connectors(): ) ) - return union(hulls) + # return union(hulls) + return add(hulls) @@ -2370,27 +2258,31 @@ def left_key_position(row, direction, low_corner=False, side='right'): if trackball_in_wall and (side == ball_side or ball_side == 'both'): if low_corner: + x_offset = tbiw_left_wall_lower_x_offset y_offset = tbiw_left_wall_lower_y_offset z_offset = tbiw_left_wall_lower_z_offset else: + x_offset = 0.0 y_offset = 0.0 z_offset = 0.0 return list(pos - np.array([ - tbiw_left_wall_x_offset_override, + tbiw_left_wall_x_offset_override - x_offset, -y_offset, tbiw_left_wall_z_offset_override + z_offset ])) if low_corner: + x_offset = left_wall_lower_x_offset y_offset = left_wall_lower_y_offset z_offset = left_wall_lower_z_offset else: + x_offset = 0.0 y_offset = 0.0 z_offset = 0.0 - return list(pos - np.array([left_wall_x_offset, -y_offset, left_wall_z_offset + z_offset])) + return list(pos - np.array([left_wall_x_offset - x_offset, -y_offset, left_wall_z_offset + z_offset])) def left_key_place(shape, row, direction, low_corner=False, side='right'): @@ -2423,40 +2315,46 @@ def wall_locate3(dx, dy, back=False): dy * (wall_y_offset + wall_base_y_thickness), -wall_z_offset, ] - # return [ - # dx * (wall_xy_offset + wall_thickness), - # dy * (wall_xy_offset + wall_thickness), - # -wall_z_offset, - # ] -def wall_brace(place1, dx1, dy1, post1, place2, dx2, dy2, post2, back=False): +def wall_brace(place1, dx1, dy1, post1, place2, dx2, dy2, post2, back=False, skeleton=False, skel_bottom=False): debugprint("wall_brace()") hulls = [] hulls.append(place1(post1)) - hulls.append(place1(translate(post1, wall_locate1(dx1, dy1)))) - hulls.append(place1(translate(post1, wall_locate2(dx1, dy1)))) - hulls.append(place1(translate(post1, wall_locate3(dx1, dy1, back)))) + if not skeleton: + hulls.append(place1(translate(post1, wall_locate1(dx1, dy1)))) + hulls.append(place1(translate(post1, wall_locate2(dx1, dy1)))) + if not skeleton or skel_bottom: + hulls.append(place1(translate(post1, wall_locate3(dx1, dy1, back)))) hulls.append(place2(post2)) - hulls.append(place2(translate(post2, wall_locate1(dx2, dy2)))) - hulls.append(place2(translate(post2, wall_locate2(dx2, dy2)))) - hulls.append(place2(translate(post2, wall_locate3(dx2, dy2, back)))) + if not skeleton: + hulls.append(place2(translate(post2, wall_locate1(dx2, dy2)))) + hulls.append(place2(translate(post2, wall_locate2(dx2, dy2)))) + + if not skeleton or skel_bottom: + hulls.append(place2(translate(post2, wall_locate3(dx2, dy2, back)))) + shape1 = hull_from_shapes(hulls) hulls = [] - hulls.append(place1(translate(post1, wall_locate2(dx1, dy1)))) - hulls.append(place1(translate(post1, wall_locate3(dx1, dy1, back)))) - hulls.append(place2(translate(post2, wall_locate2(dx2, dy2)))) - hulls.append(place2(translate(post2, wall_locate3(dx2, dy2, back)))) - shape2 = bottom_hull(hulls) + if not skeleton: + hulls.append(place1(translate(post1, wall_locate2(dx1, dy1)))) + hulls.append(place2(translate(post2, wall_locate2(dx2, dy2)))) + if not skeleton or skel_bottom: + hulls.append(place1(translate(post1, wall_locate3(dx1, dy1, back)))) + hulls.append(place2(translate(post2, wall_locate3(dx2, dy2, back)))) - return union([shape1, shape2]) - # return shape1 + if len(hulls)>0: + shape2 = bottom_hull(hulls) + # shape1 = union([shape1, shape2]) + shape1 = add([shape1, shape2]) + return shape1 -def key_wall_brace(x1, y1, dx1, dy1, post1, x2, y2, dx2, dy2, post2, back=False): + +def key_wall_brace(x1, y1, dx1, dy1, post1, x2, y2, dx2, dy2, post2, back=False, skeleton=False, skel_bottom=False): debugprint("key_wall_brace()") return wall_brace( (lambda shape: key_place(shape, x1, y1)), @@ -2467,54 +2365,80 @@ def key_wall_brace(x1, y1, dx1, dy1, post1, x2, y2, dx2, dy2, post2, back=False) dx2, dy2, post2, - back + back, + skeleton=skeleton, + skel_bottom=False, ) -def back_wall(): +def back_wall(skeleton=False): print("back_wall()") x = 0 - shape = union([key_wall_brace(x, 0, 0, 1, web_post_tl(), x, 0, 0, 1, web_post_tr(), back=True)]) + shape = None + shape = union([shape, key_wall_brace( + x, 0, 0, 1, web_post_tl(), x, 0, 0, 1, web_post_tr(), back=True, + )]) for i in range(ncols - 1): x = i + 1 - shape = union([shape, key_wall_brace(x, 0, 0, 1, web_post_tl(), x, 0, 0, 1, web_post_tr(), back=True)]) shape = union([shape, key_wall_brace( - x, 0, 0, 1, web_post_tl(), x - 1, 0, 0, 1, web_post_tr(), back=True + x, 0, 0, 1, web_post_tl(), x, 0, 0, 1, web_post_tr(), back=True, + )]) + + skelly = skeleton and not x==1 + shape = union([shape, key_wall_brace( + x, 0, 0, 1, web_post_tl(), x - 1, 0, 0, 1, web_post_tr(), back=True, + skeleton=skelly, skel_bottom=True, )]) + shape = union([shape, key_wall_brace( - lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr(), back=True + lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr(), back=True, + skeleton=skeleton, skel_bottom=True, )]) + if not skeleton: + shape = union([shape, + key_wall_brace( + lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr() + ) + ]) return shape -def right_wall(): +def right_wall(skeleton=False): print("right_wall()") y = 0 - shape = union([ - key_wall_brace( - lastcol, y, 1, 0, web_post_tr(), lastcol, y, 1, 0, web_post_br() - ) - ]) + + shape = None + + shape = union([shape, key_wall_brace( + lastcol, y, 1, 0, web_post_tr(), lastcol, y, 1, 0, web_post_br(), + skeleton=skeleton, + )]) for i in range(lastrow - 1): y = i + 1 shape = union([shape, key_wall_brace( - lastcol, y - 1, 1, 0, web_post_br(), lastcol, y, 1, 0, web_post_tr() + lastcol, y - 1, 1, 0, web_post_br(), lastcol, y, 1, 0, web_post_tr(), + skeleton=skeleton, )]) shape = union([shape, key_wall_brace( - lastcol, y, 1, 0, web_post_tr(), lastcol, y, 1, 0, web_post_br() + lastcol, y, 1, 0, web_post_tr(), lastcol, y, 1, 0, web_post_br(), + skeleton=skeleton, )]) #STRANGE PARTIAL OFFSET shape = union([ shape, - key_wall_brace(lastcol, cornerrow, 0, -1, web_post_br(), lastcol, cornerrow, 1, 0, web_post_br()) + key_wall_brace( + lastcol, cornerrow, 0, -1, web_post_br(), lastcol, cornerrow, 1, 0, web_post_br(), + skeleton=skeleton + ), ]) + return shape -def left_wall(side='right'): +def left_wall(side='right', skeleton=False): print('left_wall()') shape = union([wall_brace( (lambda sh: key_place(sh, 0, 0)), 0, 1, web_post_tl(), @@ -2524,6 +2448,7 @@ def left_wall(side='right'): shape = union([shape, wall_brace( (lambda sh: left_key_place(sh, 0, 1, side=side)), 0, 1, web_post(), (lambda sh: left_key_place(sh, 0, 1, side=side)), -1, 0, web_post(), + skeleton=skeleton, )]) for i in range(lastrow): @@ -2532,14 +2457,17 @@ def left_wall(side='right'): temp_shape1 = wall_brace( (lambda sh: left_key_place(sh, y, 1, side=side)), -1, 0, web_post(), (lambda sh: left_key_place(sh, y, -1, low_corner=low, side=side)), -1, 0, web_post(), + skeleton=skeleton and (y < (lastrow-1)), ) + shape = union([shape, temp_shape1]) + temp_shape2 = hull_from_shapes(( key_place(web_post_tl(), 0, y), key_place(web_post_bl(), 0, y), left_key_place(web_post(), y, 1, side=side), left_key_place(web_post(), y, -1, low_corner=low, side=side), )) - shape = union([shape, temp_shape1]) + shape = union([shape, temp_shape2]) for i in range(lastrow - 1): @@ -2548,26 +2476,26 @@ def left_wall(side='right'): temp_shape1 = wall_brace( (lambda sh: left_key_place(sh, y - 1, -1, side=side)), -1, 0, web_post(), (lambda sh: left_key_place(sh, y, 1, side=side)), -1, 0, web_post(), + skeleton=skeleton and (y < (lastrow - 1)), ) + shape = union([shape, temp_shape1]) + temp_shape2 = hull_from_shapes(( key_place(web_post_tl(), 0, y), key_place(web_post_bl(), 0, y - 1), left_key_place(web_post(), y, 1, side=side), left_key_place(web_post(), y - 1, -1, side=side), )) - shape = union([shape, temp_shape1]) + shape = union([shape, temp_shape2]) return shape -def front_wall(): +def front_wall(skeleton=False): print('front_wall()') - shape = union([ - key_wall_brace( - lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr() - ) - ]) + shape = None + shape = union([shape,key_wall_brace( 3, lastrow, 0, -1, web_post_bl(), 3, lastrow, 0.5, -1, web_post_br() )]) @@ -2588,57 +2516,57 @@ def front_wall(): return shape -def thumb_walls(side='right', style_override=None): +def thumb_walls(side='right', style_override=None, skeleton=False): if style_override is None: _thumb_style = thumb_style else: _thumb_style = style_override if _thumb_style == "MINI": - return mini_thumb_walls() + return mini_thumb_walls(skeleton=skeleton) elif _thumb_style == "MINIDOX": - return minidox_thumb_walls() + return minidox_thumb_walls(skeleton=skeleton) elif _thumb_style == "CARBONFET": - return carbonfet_thumb_walls() + return carbonfet_thumb_walls(skeleton=skeleton) elif "TRACKBALL" in _thumb_style: if (side == ball_side or ball_side == 'both'): if _thumb_style == "TRACKBALL_ORBYL": - return tbjs_thumb_walls() + return tbjs_thumb_walls(skeleton=skeleton) elif thumb_style == "TRACKBALL_CJ": - return tbcj_thumb_walls() + return tbcj_thumb_walls(skeleton=skeleton) else: - return thumb_walls(side, style_override=other_thumb) + return thumb_walls(side, style_override=other_thumb, skeleton=skeleton) else: - return default_thumb_walls() + return default_thumb_walls(skeleton=skeleton) -def thumb_connection(side='right', style_override=None): +def thumb_connection(side='right', style_override=None, skeleton=False): if style_override is None: _thumb_style = thumb_style else: _thumb_style = style_override if _thumb_style == "MINI": - return mini_thumb_connection(side=side) + return mini_thumb_connection(side=side, skeleton=skeleton) elif _thumb_style == "MINIDOX": - return minidox_thumb_connection(side=side) + return minidox_thumb_connection(side=side, skeleton=skeleton) elif _thumb_style == "CARBONFET": - return carbonfet_thumb_connection(side=side) + return carbonfet_thumb_connection(side=side, skeleton=skeleton) elif "TRACKBALL" in _thumb_style: if (side == ball_side or ball_side == 'both'): if _thumb_style == "TRACKBALL_ORBYL": - return tbjs_thumb_connection(side=side) + return tbjs_thumb_connection(side=side, skeleton=skeleton) elif thumb_style == "TRACKBALL_CJ": - return tbcj_thumb_connection(side=side) + return tbcj_thumb_connection(side=side, skeleton=skeleton) else: - return thumb_connection(side, style_override=other_thumb) + return thumb_connection(side, style_override=other_thumb, skeleton=skeleton) else: - return default_thumb_connection(side=side) + return default_thumb_connection(side=side, skeleton=skeleton) -def default_thumb_walls(): +def default_thumb_walls(skeleton=False): print('thumb_walls()') # thumb, walls if default_1U_cluster: @@ -2666,10 +2594,11 @@ def default_thumb_walls(): return shape -def default_thumb_connection(side='right'): +def default_thumb_connection(side='right', skeleton=False): print('thumb_connection()') # clunky bit on the top left thumb connection (normal connectors don't work well) - shape = union([bottom_hull( + shape = None + shape = union([shape, bottom_hull( [ left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1, low_corner=True, side=side), left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1, low_corner=True, side=side), @@ -2721,7 +2650,7 @@ def default_thumb_connection(side='right'): return shape -def tbjs_thumb_connection(side='right'): +def tbjs_thumb_connection(side='right', skeleton=False): print('thumb_connection()') # clunky bit on the top left thumb connection (normal connectors don't work well) hulls = [] @@ -2729,7 +2658,8 @@ def tbjs_thumb_connection(side='right'): triangle_hulls( [ key_place(web_post_bl(), 0, cornerrow), - left_key_place(web_post(), lastrow - 1, -1, side=side, low_corner=True), # left_key_place(translate(web_post(), wall_locate1(-1, 0)), cornerrow, -1, low_corner=True), + left_key_place(web_post(), lastrow - 1, -1, side=side, low_corner=True), + # left_key_place(translate(web_post(), wall_locate1(-1, 0)), cornerrow, -1, low_corner=True), tbjs_place(tbjs_post_tl()), ] ) @@ -2739,31 +2669,23 @@ def tbjs_thumb_connection(side='right'): triangle_hulls( [ key_place(web_post_bl(), 0, cornerrow), - tbjs_thumb_tl_place(web_post_bl()), + tbjs_thumb_tl_place(tbjs_thumb_post_bl()), key_place(web_post_br(), 0, cornerrow), - tbjs_thumb_tl_place(web_post_tl()), + tbjs_thumb_tl_place(tbjs_thumb_post_tl()), key_place(web_post_bl(), 1, cornerrow), - tbjs_thumb_tl_place(web_post_tl()), + tbjs_thumb_tl_place(tbjs_thumb_post_tl()), key_place(web_post_br(), 1, cornerrow), - tbjs_thumb_tl_place(web_post_tr()), - key_place(web_post_tl(), 2, lastrow), + tbjs_thumb_tl_place(tbjs_thumb_post_tr()), key_place(web_post_bl(), 2, lastrow), - tbjs_thumb_tl_place(web_post_tr()), + tbjs_thumb_tl_place(tbjs_thumb_post_tr()), key_place(web_post_bl(), 2, lastrow), - tbjs_thumb_mr_place(web_post_tl()), + tbjs_thumb_mr_place(tbjs_thumb_post_tl()), key_place(web_post_br(), 2, lastrow), key_place(web_post_bl(), 3, lastrow), - tbjs_thumb_mr_place(web_post_tr()), - tbjs_thumb_mr_place(web_post_tl()), + tbjs_thumb_mr_place(tbjs_thumb_post_tr()), + tbjs_thumb_mr_place(tbjs_thumb_post_tl()), key_place(web_post_br(), 2, lastrow), - key_place(web_post_bl(), 3, lastrow), - key_place(web_post_tr(), 2, lastrow), - key_place(web_post_tl(), 3, lastrow), - key_place(web_post_bl(), 3, cornerrow), - key_place(web_post_tr(), 3, lastrow), - key_place(web_post_br(), 3, cornerrow), - key_place(web_post_bl(), 4, cornerrow), ] ) ) @@ -2771,28 +2693,28 @@ def tbjs_thumb_connection(side='right'): return shape -def tbjs_thumb_walls(): +def tbjs_thumb_walls(skeleton=False): print('thumb_walls()') # thumb, walls shape = wall_brace( - tbjs_thumb_mr_place, .5, 1, web_post_tr(), + tbjs_thumb_mr_place, .5, 1, tbjs_thumb_post_tr(), (lambda sh: key_place(sh, 3, lastrow)), 0, -1, web_post_bl(), ) shape = union([shape, wall_brace( - tbjs_thumb_mr_place, .5, 1, web_post_tr(), - tbjs_thumb_br_place, 0, -1, web_post_br(), + tbjs_thumb_mr_place, .5, 1, tbjs_thumb_post_tr(), + tbjs_thumb_br_place, 0, -1, tbjs_thumb_post_br(), )]) shape = union([shape, wall_brace( - tbjs_thumb_br_place, 0, -1, web_post_br(), - tbjs_thumb_br_place, 0, -1, web_post_bl(), + tbjs_thumb_br_place, 0, -1, tbjs_thumb_post_br(), + tbjs_thumb_br_place, 0, -1, tbjs_thumb_post_bl(), )]) shape = union([shape, wall_brace( - tbjs_thumb_br_place, 0, -1, web_post_bl(), - tbjs_thumb_bl_place, 0, -1, web_post_br(), + tbjs_thumb_br_place, 0, -1, tbjs_thumb_post_bl(), + tbjs_thumb_bl_place, 0, -1, tbjs_thumb_post_br(), )]) shape = union([shape, wall_brace( - tbjs_thumb_bl_place, 0, -1, web_post_br(), - tbjs_thumb_bl_place, -1, -1, web_post_bl(), + tbjs_thumb_bl_place, 0, -1, tbjs_thumb_post_br(), + tbjs_thumb_bl_place, -1, -1, tbjs_thumb_post_bl(), )]) shape = union([shape, wall_brace( @@ -2805,17 +2727,17 @@ def tbjs_thumb_walls(): )]) shape = union([shape, wall_brace( tbjs_place, -1, 0, tbjs_post_l(), - tbjs_thumb_bl_place, -1, 0, web_post_tl(), + tbjs_thumb_bl_place, -1, 0, tbjs_thumb_post_tl(), )]) shape = union([shape, wall_brace( - tbjs_thumb_bl_place, -1, 0, web_post_tl(), - tbjs_thumb_bl_place, -1, -1, web_post_bl(), + tbjs_thumb_bl_place, -1, 0, tbjs_thumb_post_tl(), + tbjs_thumb_bl_place, -1, -1, tbjs_thumb_post_bl(), )]) return shape -def tbcj_thumb_connection(side='right'): +def tbcj_thumb_connection(side='right', skeleton=False): # clunky bit on the top left thumb connection (normal connectors don't work well) shape = union([bottom_hull( [ @@ -2868,7 +2790,7 @@ def tbcj_thumb_connection(side='right'): return shape -def tbcj_thumb_walls(): +def tbcj_thumb_walls(skeleton=False): shape = union([wall_brace(tbcj_thumb_ml_place, -0.3, 1, web_post_tr(), tbcj_thumb_ml_place, 0, 1, web_post_tl())]) shape = union([shape, wall_brace(tbcj_thumb_bl_place, 0, 1, web_post_tr(), tbcj_thumb_bl_place, 0, 1, web_post_tl())]) shape = union([shape, wall_brace(tbcj_thumb_bl_place, -1, 0, web_post_tl(), tbcj_thumb_bl_place, -1, 0, web_post_bl())]) @@ -2895,7 +2817,7 @@ def tbcj_thumb_walls(): return shape -def mini_thumb_walls(): +def mini_thumb_walls(skeleton=False): # thumb, walls shape = union([wall_brace(mini_thumb_mr_place, 0, -1, web_post_br(), mini_thumb_tr_place, 0, -1, mini_thumb_post_br())]) shape = union([shape, wall_brace(mini_thumb_mr_place, 0, -1, web_post_br(), mini_thumb_mr_place, 0, -1, web_post_bl())]) @@ -2913,7 +2835,7 @@ def mini_thumb_walls(): return shape -def mini_thumb_connection(side='right'): +def mini_thumb_connection(side='right', skeleton=False): # clunky bit on the top left thumb connection (normal connectors don't work well) shape = union([bottom_hull( [ @@ -2969,7 +2891,7 @@ def mini_thumb_connection(side='right'): return shape -def minidox_thumb_walls(): +def minidox_thumb_walls(skeleton=False): # thumb, walls shape = union([wall_brace(minidox_thumb_tr_place, 0, -1, minidox_thumb_post_br(), minidox_thumb_tr_place, 0, -1, minidox_thumb_post_bl())]) @@ -2988,7 +2910,7 @@ def minidox_thumb_walls(): return shape -def minidox_thumb_connection(side='right'): +def minidox_thumb_connection(side='right', skeleton=False): # clunky bit on the top left thumb connection (normal connectors don't work well) shape = union([bottom_hull( [ @@ -3027,7 +2949,6 @@ def minidox_thumb_connection(side='right'): left_key_place(web_post(), cornerrow, -1, low_corner=True, side=side), left_key_place(translate(web_post(), wall_locate1(-1, 0)), cornerrow, -1, low_corner=True, side=side), key_place(web_post_bl(), 0, cornerrow), - # key_place(translate(web_post_bl(), wall_locate1(-1, 0)), cornerrow, -1, low_corner=True), minidox_thumb_tl_place(minidox_thumb_post_tl()), ] )]) @@ -3047,7 +2968,7 @@ def minidox_thumb_connection(side='right'): -def carbonfet_thumb_walls(): +def carbonfet_thumb_walls(skeleton=False): # thumb, walls shape = union([wall_brace(carbonfet_thumb_mr_place, 0, -1, web_post_br(), carbonfet_thumb_tr_place, 0, -1, web_post_br())]) shape = union([shape, wall_brace(carbonfet_thumb_mr_place, 0, -1, web_post_br(), carbonfet_thumb_mr_place, 0, -1.15, web_post_bl())]) @@ -3064,7 +2985,7 @@ def carbonfet_thumb_walls(): shape = union([shape, wall_brace(carbonfet_thumb_tr_place, 0, -1, web_post_br(), (lambda sh: key_place(sh, 3, lastrow)), 0, -1, web_post_bl())]) return shape -def carbonfet_thumb_connection(side='right'): +def carbonfet_thumb_connection(side='right', skeleton=False): # clunky bit on the top left thumb connection (normal connectors don't work well) shape = bottom_hull( [ @@ -3120,16 +3041,16 @@ def carbonfet_thumb_connection(side='right'): return shape -def case_walls(side='right'): +def case_walls(side='right', skeleton=False): print('case_walls()') return ( union([ - back_wall(), - left_wall(side=side), - right_wall(), - front_wall(), - thumb_walls(side=side), - thumb_connection(side=side), + back_wall(skeleton=skeleton), + left_wall(side=side, skeleton=skeleton), + right_wall(skeleton=skeleton), + front_wall(skeleton=skeleton), + # thumb_walls(side=side), + # thumb_connection(side=side), ]) ) @@ -3233,8 +3154,129 @@ def external_mount_hole(): ) return shape -def generate_trackball(pos, rot): + +pcb_mount_ref_position = key_position( + #TRRS POSITION IS REFERENCE BY CONVENIENCE + list(np.array(wall_locate3(0, 1)) + np.array([0, (mount_height / 2), 0])), 0, 0 +) + +pcb_mount_ref_position[0] = pcb_mount_ref_position[0] + pcb_mount_ref_offset[0] +pcb_mount_ref_position[1] = pcb_mount_ref_position[1] + pcb_mount_ref_offset[1] +pcb_mount_ref_position[2] = 0.0 + pcb_mount_ref_offset[2] + +def pcb_usb_hole(): + debugprint('pcb_holder()') + pcb_usb_position = copy.deepcopy(pcb_mount_ref_position) + pcb_usb_position[0] = pcb_usb_position[0] + pcb_usb_hole_offset[0] + pcb_usb_position[1] = pcb_usb_position[1] + pcb_usb_hole_offset[1] + pcb_usb_position[2] = pcb_usb_position[2] + pcb_usb_hole_offset[2] + + shape = box(*pcb_usb_hole_size) + shape = translate(shape, + ( + pcb_usb_position[0], + pcb_usb_position[1], + pcb_usb_hole_size[2] / 2 + usb_holder_thickness, + ) + ) + return shape + + + +pcb_holder_position = copy.deepcopy(pcb_mount_ref_position) +pcb_holder_position[0] = pcb_holder_position[0] + pcb_holder_offset[0] +pcb_holder_position[1] = pcb_holder_position[1] + pcb_holder_offset[1] +pcb_holder_position[2] = pcb_holder_position[2] + pcb_holder_offset[2] +pcb_holder_thickness = pcb_holder_size[2] + +def pcb_holder(): + debugprint('pcb_holder()') + shape = box(*pcb_holder_size) + shape = translate(shape, + ( + pcb_holder_position[0], + pcb_holder_position[1] - pcb_holder_size[1] / 2, + pcb_holder_thickness / 2, + ) + ) + return shape + + +def wall_thinner(): + debugprint('wall_thinner()') + shape = box(*wall_thinner_size) + shape = translate(shape, + ( + pcb_holder_position[0], + pcb_holder_position[1] - wall_thinner_size[1]/2, + wall_thinner_size[2]/2 + pcb_holder_thickness, + ) + ) + return shape + + + + +def trrs_hole(): + debugprint('trrs_hole()') + trrs_position = copy.deepcopy(pcb_mount_ref_position) + trrs_position[0] = trrs_position[0] + trrs_offset[0] + trrs_position[1] = trrs_position[1] + trrs_offset[1] + trrs_position[2] = trrs_position[2] + trrs_offset[2] + + trrs_hole_size = [3, 20] + + + shape = cylinder(*trrs_hole_size) + shape = rotate(shape, [0, 90, 90]) + shape = translate(shape, + ( + trrs_position[0], + trrs_position[1], + trrs_hole_size[0] + pcb_holder_thickness, + ) + ) + return shape + +pcb_screw_position = copy.deepcopy(pcb_mount_ref_position) +pcb_screw_position[1] = pcb_screw_position[1] + pcb_screw_y_offset + +def pcb_screw_hole(): + debugprint('pcb_screw_hole()') + holes = [] + hole = cylinder(*pcb_screw_hole_size) + hole = translate(hole, pcb_screw_position) + hole = translate(hole, (0, 0, pcb_screw_hole_size[1]/2-.1)) + for offset in pcb_screw_x_offsets: + holes.append(translate(hole, (offset, 0, 0))) + + return holes + + +if oled_center_row is not None: + base_pt1 = key_position( + list(np.array([-mount_width/2, 0, 0]) + np.array([0, (mount_height / 2), 0])), 0, oled_center_row-1 + ) + base_pt2 = key_position( + list(np.array([-mount_width/2, 0, 0]) + np.array([0, (mount_height / 2), 0])), 0, oled_center_row+1 + ) + base_pt0 = key_position( + list(np.array([-mount_width / 2, 0, 0]) + np.array([0, (mount_height / 2), 0])), 0, oled_center_row + ) + + oled_mount_location_xyz = (np.array(base_pt1)+np.array(base_pt2))/2. + np.array(((-left_wall_x_offset/2), 0, 0)) + np.array(oled_translation_offset) + oled_mount_location_xyz[2] = (oled_mount_location_xyz[2] + base_pt0[2])/2 + + angle_x = np.arctan2(base_pt1[2] - base_pt2[2], base_pt1[1] - base_pt2[1]) + angle_z = np.arctan2(base_pt1[0] - base_pt2[0], base_pt1[1] - base_pt2[1]) + + oled_mount_rotation_xyz = (rad2deg(angle_x), 0, -rad2deg(angle_z)) + np.array(oled_rotation_offset) + + + + +def generate_trackball(pos, rot): precut = trackball_cutout() precut = rotate(precut, tb_socket_rotation_offset) precut = translate(precut, tb_socket_translation_offset) @@ -3671,9 +3713,7 @@ def teensy_holder(): def screw_insert_shape(bottom_radius, top_radius, height): debugprint('screw_insert_shape()') if bottom_radius == top_radius: - base = translate(cylinder(radius=bottom_radius, height=height), - (0, 0, -height / 2) - ) + base = cylinder(radius=bottom_radius, height=height) else: base = translate(cone(r1=bottom_radius, r2=top_radius, height=height), (0, 0, -height / 2)) @@ -3742,35 +3782,61 @@ def screw_insert(column, row, bottom_radius, top_radius, height, side='right'): return shape -def screw_insert_thumb(bottom_radius, top_radius, height): - if thumb_style == 'MINI': - position = thumborigin() - position = list(np.array(position) + np.array([-29, -51, -16])) - position[2] = 0 +def thumb_screw_insert(bottom_radius, top_radius, height, offset=None, side='right'): + shape = screw_insert_shape(bottom_radius, top_radius, height) + shapes = [] + if offset is None: + offset = 0.0 + + origin = thumborigin() - elif thumb_style == 'MINIDOX': - position = thumborigin() - position = list(np.array(position) + np.array([-37, -32, -16])) - position[1] = position[1] - .4 * (minidox_Usize - 1) * sa_length - position[2] = 0 + if ('TRACKBALL' in thumb_style) and not (side == ball_side or ball_side == 'both'): + _thumb_style = other_thumb + else: + _thumb_style = thumb_style + + if _thumb_style == 'MINI': + if separable_thumb: + xypositions = copy.deepcopy(mini_separable_thumb_screw_xy_locations) + else: + xypositions = copy.deepcopy(mini_thumb_screw_xy_locations) + + elif _thumb_style == 'MINIDOX': + if separable_thumb: + xypositions = copy.deepcopy(minidox_separable_thumb_screw_xy_locations) + else: + xypositions = copy.deepcopy(minidox_thumb_screw_xy_locations) + xypositions[0][1] = xypositions[0][1] - .4 * (minidox_Usize - 1) * sa_length - elif thumb_style == 'CARBONFET': - position = thumborigin() - position = list(np.array(position) + np.array([-48, -37, 0])) - position[2] = 0 - elif thumb_style == 'TRACKBALL': - position = thumborigin() - position = list(np.array(position) + np.array([-72, -40, -16])) - position[2] = 0 + elif _thumb_style == 'CARBONFET': + if separable_thumb: + xypositions = copy.deepcopy(carbonfet_separable_thumb_screw_xy_locations) + else: + xypositions = copy.deepcopy(carbonfet_thumb_screw_xy_locations) + + elif _thumb_style == 'TRACKBALL_ORBYL': + if separable_thumb: + xypositions = copy.deepcopy(orbyl_separable_thumb_screw_xy_locations) + else: + xypositions = copy.deepcopy(orbyl_thumb_screw_xy_locations) + + elif _thumb_style == 'TRACKBALL_CJ': + if separable_thumb: + xypositions = copy.deepcopy(tbcj_separable_thumb_screw_xy_locations) + else: + xypositions = copy.deepcopy(tbcj_thumb_screw_xy_locations) else: - position = thumborigin() - position = list(np.array(position) + np.array([-21, -58, 0])) - position[2] = 0 + if separable_thumb: + xypositions = copy.deepcopy(default_separable_thumb_screw_xy_locations) + else: + xypositions = copy.deepcopy(default_thumb_screw_xy_locations) - shape = screw_insert_shape(bottom_radius, top_radius, height) - shape = translate(shape, [position[0], position[1], height / 2]) - return shape + for xyposition in xypositions: + position = list(np.array(origin) + np.array([*xyposition, -origin[2]])) + shapes.append(translate(shape, [position[0], position[1], height / 2 + offset])) + + return shapes def screw_insert_all_shapes(bottom_radius, top_radius, height, offset=0, side='right'): print('screw_insert_all_shapes()') @@ -3781,26 +3847,36 @@ def screw_insert_all_shapes(bottom_radius, top_radius, height, offset=0, side='r translate(screw_insert(3, 0, bottom_radius, top_radius, height, side=side), (0,0, offset)), translate(screw_insert(lastcol, 0, bottom_radius, top_radius, height, side=side), (0, 0, offset)), translate(screw_insert(lastcol, lastrow-1, bottom_radius, top_radius, height, side=side), (0, 0, offset)), - translate(screw_insert_thumb(bottom_radius, top_radius, height), (0, 0, offset)), + # translate(screw_insert_thumb(bottom_radius, top_radius, height), (0, 0, offset)), ) return shape +def thumb_screw_insert_holes(side='right'): + return thumb_screw_insert( + screw_insert_bottom_radius, screw_insert_top_radius, screw_insert_height+.02, offset=-.01, side=side + ) - +def thumb_screw_insert_outers(offset=0.0, side='right'): + # screw_insert_bottom_radius + screw_insert_wall + # screw_insert_top_radius + screw_insert_wall + bottom_radius = screw_insert_outer_radius + top_radius = screw_insert_outer_radius + height = screw_insert_height + 1.5 + return thumb_screw_insert(bottom_radius, top_radius, height, offset=offset, side=side) def screw_insert_holes(side='right'): return screw_insert_all_shapes( screw_insert_bottom_radius, screw_insert_top_radius, screw_insert_height+.02, offset=-.01, side=side ) -def screw_insert_outers(side='right'): - return screw_insert_all_shapes( - screw_insert_bottom_radius + 1.6, - screw_insert_top_radius + 1.6, - screw_insert_height + 1.5, - side=side - ) +def screw_insert_outers(offset=0.0, side='right'): + # screw_insert_bottom_radius + screw_insert_wall + # screw_insert_top_radius + screw_insert_wall + bottom_radius = screw_insert_outer_radius + top_radius = screw_insert_outer_radius + height = screw_insert_height + 1.5 + return screw_insert_all_shapes(bottom_radius, top_radius, height, offset=offset, side=side) def screw_insert_screw_holes(side='right'): return screw_insert_all_shapes(1.7, 1.7, 350, side=side) @@ -3849,24 +3925,18 @@ def wire_posts(): def model_side(side="right"): print('model_right()') - shape = union([key_holes(side=side)]) + shape = add([key_holes(side=side)]) + # shape = union([key_holes(side=side)]) if debug_exports: export_file(shape=shape, fname=path.join(r"..", "things", r"debug_key_plates")) connector_shape = connectors() shape = union([shape, connector_shape]) if debug_exports: export_file(shape=shape, fname=path.join(r"..", "things", r"debug_connector_shape")) - thumb_shape = thumb(side=side) - if debug_exports: - export_file(shape=thumb_shape, fname=path.join(r"..", "things", r"debug_thumb_shape")) - shape = union([shape, thumb_shape]) - thumb_connector_shape = thumb_connectors(side=side) - shape = union([shape, thumb_connector_shape]) - if debug_exports: - export_file(shape=shape, fname=path.join(r"..", "things", r"debug_thumb_connector_shape")) - walls_shape = case_walls(side=side) + walls_shape = case_walls(side=side, skeleton=skeletal) if debug_exports: export_file(shape=walls_shape, fname=path.join(r"..", "things", r"debug_walls_shape")) + s2 = union([walls_shape]) s2 = union([s2, *screw_insert_outers(side=side)]) @@ -3883,7 +3953,14 @@ def model_side(side="right"): if controller_mount_type in ['EXTERNAL']: s2 = difference(s2, [external_mount_hole()]) - if controller_mount_type in ['None']: + if controller_mount_type in ['PCB_MOUNT']: + s2 = difference(s2, [pcb_usb_hole()]) + s2 = difference(s2, [trrs_hole()]) + s2 = union([s2, pcb_holder()]) + s2 = difference(s2, [wall_thinner()]) + s2 = difference(s2, pcb_screw_hole()) + + if controller_mount_type in [None, 'None']: 0 # do nothing, only here to expressly state inaction. s2 = difference(s2, [union(screw_insert_holes(side=side))]) @@ -3907,7 +3984,7 @@ def model_side(side="right"): shape = difference(shape, [hole]) shape = union([shape, frame]) - if trackball_in_wall and (side == ball_side or ball_side == 'both'): + if trackball_in_wall and (side == ball_side or ball_side == 'both') and separable_thumb: tbprecut, tb, tbcutout, sensor, ball = generate_trackball_in_wall() shape = difference(shape, [tbprecut]) @@ -3922,46 +3999,116 @@ def model_side(side="right"): if show_caps: shape = add([shape, ball]) - if (trackball_in_wall or ('TRACKBALL' in thumb_style)) and (side == ball_side or ball_side == 'both'): - tbprecut, tb, tbcutout, sensor, ball = generate_trackball_in_cluster() + if plate_pcb_clear: + shape = difference(shape, [plate_pcb_cutouts(side=side)]) - shape = difference(shape, [tbprecut]) - # export_file(shape=shape, fname=path.join(save_path, config_name + r"_test_1")) - shape = union([shape, tb]) - # export_file(shape=shape, fname=path.join(save_path, config_name + r"_test_2")) - shape = difference(shape, [tbcutout]) - # export_file(shape=shape, fname=path.join(save_path, config_name + r"_test_3a")) - # export_file(shape=add([shape, sensor]), fname=path.join(save_path, config_name + r"_test_3b")) - shape = union([shape, sensor]) + main_shape = shape - if show_caps: - shape = add([shape, ball]) + #BUILD THUMB + + thumb_shape = thumb(side=side) + if debug_exports: + export_file(shape=thumb_shape, fname=path.join(r"..", "things", r"debug_thumb_shape")) + thumb_connector_shape = thumb_connectors(side=side) + if debug_exports: + export_file(shape=thumb_connector_shape, fname=path.join(r"..", "things", r"debug_thumb_connector_shape")) + + thumb_wall_shape = thumb_walls(side=side, skeleton=skeletal) + thumb_wall_shape = union([thumb_wall_shape, *thumb_screw_insert_outers(side=side)]) + thumb_connection_shape = thumb_connection(side=side, skeleton=skeletal) + + + if debug_exports: + thumb_test = union([thumb_shape, thumb_connector_shape, thumb_wall_shape, thumb_connection_shape]) + export_file(shape=thumb_test, fname=path.join(r"..", "things", r"debug_thumb_test_{}_shape".format(side))) + + thumb_section = union([thumb_shape, thumb_connector_shape, thumb_wall_shape, thumb_connection_shape]) + thumb_section = difference(thumb_section, [union(thumb_screw_insert_holes(side=side))]) + + has_trackball = False + if ('TRACKBALL' in thumb_style) and (side == ball_side or ball_side == 'both'): + tbprecut, tb, tbcutout, sensor, ball = generate_trackball_in_cluster() + has_trackball = True + thumb_section = difference(thumb_section, [tbprecut]) + thumb_section = union([thumb_section, tb]) + thumb_section = difference(thumb_section, [tbcutout]) + thumb_section = union([thumb_section, sensor]) + + if plate_pcb_clear: + thumb_section = difference(thumb_section, [thumb_pcb_plate_cutouts(side=side)]) block = box(350, 350, 40) block = translate(block, (0, 0, -20)) - shape = difference(shape, [block]) + main_shape = difference(main_shape, [block]) + thumb_section = difference(thumb_section, [block]) + + + + if separable_thumb: + thumb_section = difference(thumb_section, [main_shape]) + if show_caps: + thumb_section = add([thumb_section, thumbcaps(side=side)]) + if has_trackball: + thumb_section = add([thumb_section, ball]) + else: + main_shape = union([main_shape, thumb_section]) + if show_caps: + main_shape = add([main_shape, thumbcaps(side=side)]) + if has_trackball: + main_shape = add([main_shape, ball]) + + if trackball_in_wall and (side == ball_side or ball_side == 'both') and not separable_thumb: + tbprecut, tb, tbcutout, sensor, ball = generate_trackball_in_wall() + + main_shape = difference(main_shape, [tbprecut]) + # export_file(shape=shape, fname=path.join(save_path, config_name + r"_test_1")) + main_shape = union([main_shape, tb]) + # export_file(shape=shape, fname=path.join(save_path, config_name + r"_test_2")) + main_shape = difference(main_shape, [tbcutout]) + # export_file(shape=shape, fname=path.join(save_path, config_name + r"_test_3a")) + # export_file(shape=add([shape, sensor]), fname=path.join(save_path, config_name + r"_test_3b")) + main_shape = union([main_shape, sensor]) + + if show_caps: + main_shape = add([main_shape, ball]) + + + + if show_caps: - shape = add([shape, thumbcaps(side=side)]) - shape = add([shape, caps()]) + main_shape = add([main_shape, caps()]) if side == "left": - shape = mirror(shape, 'YZ') + main_shape = mirror(main_shape, 'YZ') + thumb_section = mirror(thumb_section, 'YZ') - return shape + return main_shape, thumb_section # NEEDS TO BE SPECIAL FOR CADQUERY def baseplate(wedge_angle=None, side='right'): if ENGINE == 'cadquery': # shape = mod_r - shape = union([case_walls(side=side), *screw_insert_outers(side=side)]) + shape = union([ + case_walls(side=side), + *screw_insert_outers(side=side), + thumb_walls(side=side), + *thumb_screw_insert_outers(side=side), + ]) # tool = translate(screw_insert_screw_holes(side=side), [0, 0, -10]) tool = screw_insert_all_shapes(screw_hole_diameter/2., screw_hole_diameter/2., 350, side=side) for item in tool: item = translate(item, [0, 0, -10]) shape = difference(shape, [item]) + tool = thumb_screw_insert(screw_hole_diameter/2., screw_hole_diameter/2., 350, side=side) + for item in tool: + item = translate(item, [0, 0, -10]) + shape = difference(shape, [item]) + + + shape = translate(shape, (0, 0, -0.0001)) square = cq.Workplane('XY').rect(1000, 1000) @@ -4024,7 +4171,9 @@ def baseplate(wedge_angle=None, side='right'): shape = union([ case_walls(side=side), - *screw_insert_outers(side=side) + *screw_insert_outers(side=side), + thumb_walls(side=side), + *thumb_screw_insert_outers(side=side), ]) tool = translate(union(screw_insert_screw_holes(side=side)), [0, 0, -10]) @@ -4038,16 +4187,18 @@ def baseplate(wedge_angle=None, side='right'): def run(): - mod_r = model_side(side="right") + mod_r, tmb_r = model_side(side="right") export_file(shape=mod_r, fname=path.join(save_path, config_name + r"_right")) + export_file(shape=tmb_r, fname=path.join(save_path, config_name + r"_thumb_right")) base = baseplate(side='right') export_file(shape=base, fname=path.join(save_path, config_name + r"_right_plate")) export_dxf(shape=base, fname=path.join(save_path, config_name + r"_right_plate")) if symmetry == "asymmetric": - mod_l = model_side(side="left") + mod_l, tmb_l = model_side(side="left") export_file(shape=mod_l, fname=path.join(save_path, config_name + r"_left")) + export_file(shape=tmb_l, fname=path.join(save_path, config_name + r"_thumb_left")) base_l = mirror(baseplate(side='left'), 'YZ') export_file(shape=base_l, fname=path.join(save_path, config_name + r"_left_plate")) diff --git a/src/generate_configuration.py b/src/generate_configuration.py index f5fa716..d6a377d 100644 --- a/src/generate_configuration.py +++ b/src/generate_configuration.py @@ -10,8 +10,8 @@ r2d = 180 / pi shape_config = { - 'ENGINE': 'solid', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade - # 'ENGINE': 'cadquery', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade + # 'ENGINE': 'solid', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade + 'ENGINE': 'cadquery', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade ###################### @@ -21,10 +21,10 @@ shape_config = { 'save_dir': '.', 'config_name': "DM", - 'show_caps': True, + 'show_caps': False, 'show_pcbs': False, #only runs if caps are shown, easist place to initially inject geometry - 'nrows': 5, #5, # key rows + 'nrows': 6, #5, # key rows 'ncols': 6, #6, # key columns 'alpha': pi / 12.0, # curvature of the columns @@ -44,21 +44,53 @@ shape_config = { 11 # controls overall height# original=9 with centercol=3# use 16 for centercol=2 ), + + 'extra_width': 2.5, # extra space between the base of keys# original= 2 + 'extra_height': 1.0, # original= 0.5 + + + 'web_thickness': 4.0 + 1.1, + 'post_size': 0.1, + # post_adj': post_size / 2 + 'post_adj': 0, + ############################## # THUMB PARAMETERS ############################## + # 'DEFAULT' 6-key, 'MINI' 5-key, 'CARBONFET' 6-key, 'MINIDOX' 3-key, 'TRACKBALL_ORBYL', 'TRACKBALL_CJ' 'thumb_style': 'TRACKBALL_ORBYL', 'default_1U_cluster': True, # only used with default, makes top right thumb cluster key 1U # Thumb key size. May need slight oversizing, check w/ caps. Additional spacing will be automatically added for larger keys. 'minidox_Usize': 1.6, # Thumb plate rotations, anything other than 90 degree increments WILL NOT WORK. + + # Screw locations and extra screw locations for separable thumb, all from thumb origin + # Pulled out of hardcoding as drastic changes to the geometry may require fixes to the screw mounts. + # First screw in separable should be similar to the standard location as it will receive the same modifiers. + 'default_thumb_screw_xy_locations': [[-21, -58]], + 'default_separable_thumb_screw_xy_locations': [[-21, -58]], + 'mini_thumb_screw_xy_locations': [[-29, -52]], + 'mini_separable_thumb_screw_xy_locations': [[-29, -52], [-62, 10], [12, -25]], + 'minidox_thumb_screw_xy_locations': [[-37, -34]], + 'minidox_separable_thumb_screw_xy_locations': [[-37, -34], [-62, 12], [10, -25]], + 'carbonfet_thumb_screw_xy_locations': [[-48, -37]], + 'carbonfet_separable_thumb_screw_xy_locations': [[-48, -37], [-52, 10], [12, -35]], + 'orbyl_thumb_screw_xy_locations': [[-53, -68]], + 'orbyl_separable_thumb_screw_xy_locations': [[-53, -68], [-66, 8], [10, -40]], + 'tbcj_thumb_screw_xy_locations': [[-40, -75]], + 'tbcj_separable_thumb_screw_xy_locations': [[-40, -75], [-63, 10], [15, -40]], + 'thumb_plate_tr_rotation': 0.0, # Top right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. 'thumb_plate_tl_rotation': 0.0, # Top left plate rotation tweaks as thumb cluster is crowded for hot swap, etc. 'thumb_plate_mr_rotation': 0.0, # Mid right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. 'thumb_plate_ml_rotation': 0.0, # Mid left plate rotation tweaks as thumb cluster is crowded for hot swap, etc. 'thumb_plate_br_rotation': 0.0, # Bottom right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. 'thumb_plate_bl_rotation': 0.0, # Bottom right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + ############################## + # EXPERIMENTAL + 'separable_thumb': False, #creates a separable thumb section with additional screws to hold it down. Only attached at base. + ############################## ################################### ## Trackball in Wall ## @@ -69,6 +101,7 @@ shape_config = { 'tbiw_rotation_offset': (0.0, 0.0, 0.0), 'tbiw_left_wall_x_offset_override': 50.0, 'tbiw_left_wall_z_offset_override': 0.0, + 'tbiw_left_wall_lower_x_offset': 0.0, 'tbiw_left_wall_lower_y_offset': 0.0, 'tbiw_left_wall_lower_z_offset': 0.0, @@ -76,15 +109,33 @@ shape_config = { 'tbiw_oled_translation_offset': (-3.5, 0, 1.5), # Z offset tweaks are expected depending on curvature and OLED mount choice. 'tbiw_oled_rotation_offset': (0, 0, 0), + ########################################################################## + ## Finger Trackball in Wall EXPERIMENTAL WIP!!!! ## + ########################################################################## + 'finger_trackball_in_wall': False, # Separate trackball option, placing it in the OLED area + 'tbiw_ball_center_column': 0.2, # up from cornerrow instead of down from top + 'tbiw_translational_offset': (0.0, 0.0, 0.0), + 'tbiw_rotation_offset': (0.0, 0.0, 0.0), + 'tbiw_top_wall_y_offset_override': 50.0, + 'tbiw_top_wall_z_offset_override': 0.0, + 'tbiw_top_wall_extension_cols': 4, + + + ########################################### ## Trackball JS / ORBYL Thumb Cluster ## ########################################## 'other_thumb': 'DEFAULT', # cluster used for second thumb except if ball_side == 'both' 'tbjs_key_diameter': 70, + 'tbjs_Uwidth': 1.2, # size for inner key near trackball + 'tbjs_Uheight': 1.2, # size for inner key near trackball + # Offsets are per key and are applied before rotating into place around the ball # X and Y act like Tangential and Radial around the ball - 'tbjs_translation_offset': (0, 0, 10), # applied to the whole assy - 'tbjs_rotation_offset': (0, 0, 0), # applied to the whole assy + # 'tbjs_translation_offset': (0, 0, 10), # applied to the whole assy + # 'tbjs_rotation_offset': (0, 10, 0), # applied to the whole assy + 'tbjs_translation_offset': (0, 0, 2), # applied to the whole assy + 'tbjs_rotation_offset': (0, -8, 0), # applied to the whole assy 'tbjs_key_translation_offsets': [ (0.0, 0.0, -3.0-5), (0.0, 0.0, -3.0-5), @@ -109,12 +160,13 @@ shape_config = { ################################### ## Trackball General ## ################################### - # EXPERIMENTAL - 'trackball_modular': False, # May add removable trackball in subsequent releases, no current use. - # END EXPERIMENTAL + 'trackball_modular': False, # Added, creates a hole with space for the lip size listed below. + 'trackball_modular_lip_width': 3.0, # width of lip cleared out in ring location + 'trackball_modular_ball_height': 3.0, # height of ball from ring , used to create identical position to fixed. + 'trackball_modular_ring_height': 10.0, # height mount ring down from ball height. Covers gaps on elevated ball. + 'trackball_modular_clearance': 0.5, # height of ball from ring, used to create identical position to fixed. - 'trackball_Usize': 1.5, # size for inner key near trackball - 'ball_side': 'right', #'left', 'right', or 'both' + 'ball_side': 'both', #'left', 'right', or 'both' 'ball_diameter': 34.0, 'ball_wall_thickness': 3, # should not be changed unless the import models are changed. 'ball_gap': 1.0, @@ -134,17 +186,18 @@ shape_config = { 'pinky_1_5U': False, # LEAVE AS FALSE, CURRENTLY BROKEN 'first_1_5U_row': 0, 'last_1_5U_row': 5, + + 'skeletal': False, ############################## - 'extra_width': 2.5, # extra space between the base of keys# original= 2 - 'extra_height': 1.0, # original= 0.5 'wall_z_offset': 15, # length of the first downward_sloping part of the wall 'wall_x_offset': 5, # offset in the x and/or y direction for the first downward_sloping part of the wall (negative) 'wall_y_offset': 6, # offset in the x and/or y direction for the first downward_sloping part of the wall (negative) 'left_wall_x_offset': 12, # specific values for the left side due to the minimal wall. 'left_wall_z_offset': 3, # specific values for the left side due to the minimal wall. + 'left_wall_lower_x_offset': 0, # specific values for the lower left corner. 'left_wall_lower_y_offset': 0, # specific values for the lower left corner. 'left_wall_lower_z_offset': 0, 'wall_thickness': 4.5, # wall thickness parameter used on upper/mid stage of the wall @@ -188,16 +241,16 @@ shape_config = { 'undercut_keyswitch_height': 14.0, 'undercut_keyswitch_width': 14.0, - 'notch_width': 5.0, # If using notch, it is identical to undecut, but only locally by the switch clip + 'notch_width': 6.0, # If using notch, it is identical to undecut, but only locally by the switch clip 'sa_profile_key_height': 12.7, 'sa_length': 18.5, 'sa_double_length': 37.5, - 'plate_thickness': 4+1.1, + 'plate_thickness': 4 + 1.1, 'plate_rim': 1.5 + 0.5, # Undercut style dimensions - 'clip_thickness': 1.4, + 'clip_thickness': 1.1, 'clip_undercut': 1.0, 'undercut_transition': .2, # NOT FUNCTIONAL WITH OPENSCAD, ONLY WORKS WITH CADQUERY @@ -294,15 +347,18 @@ shape_config = { 'oled_clip_z_gap': .2, } }, - 'web_thickness': 4.0, - 'post_size': 0.1, - # post_adj': post_size / 2 - 'post_adj': 0, - 'screws_offset': 'INSIDE', #'OUTSIDE', 'INSIDE', 'ORIGINAL' + + 'screws_offset': 'INSIDE', # 'OUTSIDE', 'INSIDE', 'ORIGINAL' 'screw_insert_height': 3.8, - 'screw_insert_bottom_radius': 5.31 / 2, - 'screw_insert_top_radius': 5.1 / 2, + + # 'screw_insert_bottom_radius': 5.31 / 2, #Designed for inserts + # 'screw_insert_top_radius': 5.1 / 2, #Designed for inserts + + 'screw_insert_bottom_radius': 2.5 / 2, # Designed for self tapping + 'screw_insert_top_radius': 2.5 / 2, # Designed for self tapping + + 'screw_insert_outer_radius': 4.25, # Common to keep interface to base # Does anyone even use these? I think they just get in the way. 'wire_post_height': 7, @@ -332,30 +388,57 @@ shape_config = { # Offset is from the top inner corner of the top inner key. ################################### + ## PCB Screw Mount ## + ################################### + "pcb_mount_ref_offset": [0, -5, 0], + "pcb_holder_size": [34.6, 7, 4], + "pcb_holder_offset": [8.9, 0, 0], + + "pcb_usb_hole_size": [7.5, 10.0, 4], + "pcb_usb_hole_offset": [15, 0, 4.5], + + "wall_thinner_size": [34, 7, 10], + + "trrs_hole_size": [3, 20], + "trrs_offset": [0, 0, 1.5], + + "pcb_screw_hole_size": [.5, 10], + "pcb_screw_x_offsets": [- 5.5, 7.75, 22], # for the screw positions off of reference + "pcb_screw_y_offset": -2, + + + ################################### ## Bottom Plate Dimensions ################################### # COMMON DIMENSION - 'screw_hole_diameter': 2, + 'screw_hole_diameter': 3, # USED FOR CADQUERY ONLY 'base_thickness': 3.0, # thickness in the middle of the plate 'base_offset': 3.0, # Both start flat/flush on the bottom. This offsets the base up (if positive) 'base_rim_thickness': 5.0, # thickness on the outer frame with screws - 'screw_cbore_diameter': 4.0, - 'screw_cbore_depth': 2.0, + 'screw_cbore_diameter': 6.0, + 'screw_cbore_depth': 2.5, # Offset is from the top inner corner of the top inner key. ################################### ## HOLES ON PLATE FOR PCB MOUNT ################################### - 'plate_holes': False, + 'plate_holes': True, 'plate_holes_xy_offset': (0.0, 0.0), 'plate_holes_width': 14.3, 'plate_holes_height': 14.3, - 'plate_holes_diameter': 1.7, + 'plate_holes_diameter': 1.6, 'plate_holes_depth': 20.0, ################################### + ## EXPERIMENTAL + 'plate_pcb_clear': False, + 'plate_pcb_size': (18.5, 18.5, 5), + 'plate_pcb_offset': (0, 0, 0),# this is off of the back of the plate size. + ################################### + + ################################### ## SHOW PCB FOR FIT CHECK ################################### 'pcb_width': 18.0, @@ -414,4 +497,8 @@ def save_config(): if __name__ == '__main__': - save_config()
\ No newline at end of file + save_config() + + ## HERE FOR QUICK TESTING, SHOULD BE COMMENTED ON COMMIT + # from dactyl_manuform import * + # run()
\ No newline at end of file diff --git a/src/generate_configuration_orbyl_test.py b/src/generate_configuration_orbyl_test.py new file mode 100644 index 0000000..383b8cf --- /dev/null +++ b/src/generate_configuration_orbyl_test.py @@ -0,0 +1,501 @@ +import sys +import getopt +import os +import json + + +pi = 3.14159 +d2r = pi / 180 +r2d = 180 / pi + +shape_config = { + + 'ENGINE': 'solid', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade + # 'ENGINE': 'cadquery', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade + + + ###################### + ## Shape parameters ## + ###################### + + 'save_dir': '.', + 'config_name': "DM", + + 'show_caps': False, + 'show_pcbs': False, #only runs if caps are shown, easist place to initially inject geometry + + 'nrows': 5, #5, # key rows + 'ncols': 6, #6, # key columns + + 'alpha': pi / 12.0, # curvature of the columns + 'beta': pi / 36.0, # curvature of the rows + 'centercol': 3, # controls left_right tilt / tenting (higher number is more tenting) + 'centerrow_offset': 3, # rows from max, controls front_back tilt + 'tenting_angle': pi / 12.0, # or, change this for more precise tenting control + + # symmetry states if it is a symmetric or asymmetric bui. If asymmetric it doubles the generation time. + 'symmetry': "symmetric", # "asymmetric" or "symmetric" + + 'column_style_gt5': "orthographic", + 'column_style': "standard", # options include :standard, :orthographic, and :fixed + + 'thumb_offsets': [6, -3, 7], + 'keyboard_z_offset': ( + 11 # controls overall height# original=9 with centercol=3# use 16 for centercol=2 + ), + + + 'extra_width': 2.5, # extra space between the base of keys# original= 2 + 'extra_height': 1.0, # original= 0.5 + + + 'web_thickness': 4.0 + 1.1, + 'post_size': 0.1, + # post_adj': post_size / 2 + 'post_adj': 0, + + ############################## + # THUMB PARAMETERS + ############################## + + # 'DEFAULT' 6-key, 'MINI' 5-key, 'CARBONFET' 6-key, 'MINIDOX' 3-key, 'TRACKBALL_ORBYL', 'TRACKBALL_CJ' + 'thumb_style': 'TRACKBALL_ORBYL', + 'default_1U_cluster': True, # only used with default, makes top right thumb cluster key 1U + # Thumb key size. May need slight oversizing, check w/ caps. Additional spacing will be automatically added for larger keys. + 'minidox_Usize': 1.6, + # Thumb plate rotations, anything other than 90 degree increments WILL NOT WORK. + + # Screw locations and extra screw locations for separable thumb, all from thumb origin + # Pulled out of hardcoding as drastic changes to the geometry may require fixes to the screw mounts. + # First screw in separable should be similar to the standard location as it will receive the same modifiers. + 'default_thumb_screw_xy_locations': [[-21, -58]], + 'default_separable_thumb_screw_xy_locations': [[-21, -58]], + 'mini_thumb_screw_xy_locations': [[-29, -52]], + 'mini_separable_thumb_screw_xy_locations': [[-29, -52], [-62, 10], [12, -25]], + 'minidox_thumb_screw_xy_locations': [[-37, -34]], + 'minidox_separable_thumb_screw_xy_locations': [[-37, -34], [-62, 12], [10, -25]], + 'carbonfet_thumb_screw_xy_locations': [[-48, -37]], + 'carbonfet_separable_thumb_screw_xy_locations': [[-48, -37], [-52, 10], [12, -35]], + 'orbyl_thumb_screw_xy_locations': [[-53, -68]], + 'orbyl_separable_thumb_screw_xy_locations': [[-53, -68], [-66, 8], [10, -40]], + 'tbcj_thumb_screw_xy_locations': [[-40, -75]], + 'tbcj_separable_thumb_screw_xy_locations': [[-40, -75], [-63, 10], [15, -40]], + + 'thumb_plate_tr_rotation': 0.0, # Top right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_tl_rotation': 0.0, # Top left plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_mr_rotation': 0.0, # Mid right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_ml_rotation': 0.0, # Mid left plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_br_rotation': 0.0, # Bottom right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_bl_rotation': 0.0, # Bottom right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + ############################## + # EXPERIMENTAL + 'separable_thumb': True, #creates a separable thumb section with additional screws to hold it down. Only attached at base. + ############################## + + ################################### + ## Trackball in Wall ## + ################################### + 'trackball_in_wall': False, # Separate trackball option, placing it in the OLED area + 'tbiw_ball_center_row': 0.2, # up from cornerrow instead of down from top + 'tbiw_translational_offset': (0.0, 0.0, 0.0), + 'tbiw_rotation_offset': (0.0, 0.0, 0.0), + 'tbiw_left_wall_x_offset_override': 50.0, + 'tbiw_left_wall_z_offset_override': 0.0, + 'tbiw_left_wall_lower_x_offset': 0.0, + 'tbiw_left_wall_lower_y_offset': -10.0, + 'tbiw_left_wall_lower_z_offset': -10.0, + + 'tbiw_oled_center_row': .75, # not none, offsets are from this position + 'tbiw_oled_translation_offset': (-3.5, 0, 1.5), # Z offset tweaks are expected depending on curvature and OLED mount choice. + 'tbiw_oled_rotation_offset': (0, 0, 0), + + ########################################################################## + ## Finger Trackball in Wall EXPERIMENTAL WIP!!!! ## + ########################################################################## + 'finger_trackball_in_wall': False, # Separate trackball option, placing it in the OLED area + 'tbiw_ball_center_column': 0.2, # up from cornerrow instead of down from top + 'tbiw_translational_offset': (0.0, 0.0, 0.0), + 'tbiw_rotation_offset': (0.0, 0.0, 0.0), + 'tbiw_top_wall_y_offset_override': 50.0, + 'tbiw_top_wall_z_offset_override': 0.0, + 'tbiw_top_wall_extension_cols': 4, + + + + ########################################### + ## Trackball JS / ORBYL Thumb Cluster ## + ########################################## + 'other_thumb': 'DEFAULT', # cluster used for second thumb except if ball_side == 'both' + 'tbjs_key_diameter': 70, + 'tbjs_Uwidth': 1.2, # size for inner key near trackball + 'tbjs_Uheight': 1.2, # size for inner key near trackball + + # Offsets are per key and are applied before rotating into place around the ball + # X and Y act like Tangential and Radial around the ball + # 'tbjs_translation_offset': (0, 0, 10), # applied to the whole assy + # 'tbjs_rotation_offset': (0, 10, 0), # applied to the whole assy + 'tbjs_translation_offset': (0, 0, 2), # applied to the whole assy + 'tbjs_rotation_offset': (0, -8, 0), # applied to the whole assy + 'tbjs_key_translation_offsets': [ + (0.0, 0.0, -3.0-5), + (0.0, 0.0, -3.0-5), + (0.0, 0.0, -3.0-5), + (0.0, 0.0, -3.0-5), + ], + 'tbjs_key_rotation_offsets': [ + (0.0, 0.0, 0.0), + (0.0, 0.0, 0.0), + (0.0, 0.0, 0.0), + (0.0, 0.0, 0.0), + ], + + ################################### + ## Trackball CJ Thumb Cluster ## + ################################### + 'tbcj_inner_diameter': 42, + 'tbcj_thickness': 2, + 'tbcj_outer_diameter': 53, + + + ################################### + ## Trackball General ## + ################################### + 'trackball_modular': False, # Added, creates a hole with space for the lip size listed below. + 'trackball_modular_lip_width': 3.0, # width of lip cleared out in ring location + 'trackball_modular_ball_height': 3.0, # height of ball from ring , used to create identical position to fixed. + 'trackball_modular_ring_height': 10.0, # height mount ring down from ball height. Covers gaps on elevated ball. + 'trackball_modular_clearance': 0.5, # height of ball from ring, used to create identical position to fixed. + + 'ball_side': 'both', #'left', 'right', or 'both' + 'ball_diameter': 34.0, + 'ball_wall_thickness': 3, # should not be changed unless the import models are changed. + 'ball_gap': 1.0, + 'trackball_hole_diameter': 36.5, + 'trackball_hole_height': 40, + 'trackball_plate_thickness': 2, + 'trackball_plate_width': 2, + # Removed trackball_rotation, ball_z_offset. and trackball_sensor_rotation and added more flexibility. + 'tb_socket_translation_offset': (0, 0, 2.0), # applied to the socket and sensor, large values will cause web/wall issues. + 'tb_socket_rotation_offset': (0, 0, 0), # applied to the socket and sensor, large values will cause web/wall issues. + 'tb_sensor_translation_offset': (0, 0, 0), #deviation from socket offsets, for fixing generated geometry issues + 'tb_sensor_rotation_offset': (0, 0, 0), #deviation from socket offsets, for changing the sensor roll orientation + + ############################## + # EXPERIMENTAL PARAMETERS + ############################## + 'pinky_1_5U': False, # LEAVE AS FALSE, CURRENTLY BROKEN + 'first_1_5U_row': 0, + 'last_1_5U_row': 5, + ############################## + + + 'wall_z_offset': 15, # length of the first downward_sloping part of the wall + 'wall_x_offset': 5, # offset in the x and/or y direction for the first downward_sloping part of the wall (negative) + 'wall_y_offset': 6, # offset in the x and/or y direction for the first downward_sloping part of the wall (negative) + 'left_wall_x_offset': 12, # specific values for the left side due to the minimal wall. + 'left_wall_z_offset': -3, # specific values for the left side due to the minimal wall. + 'left_wall_lower_x_offset': 0, # specific values for the lower left corner. + 'left_wall_lower_y_offset': 0, # specific values for the lower left corner. + 'left_wall_lower_z_offset': 0, + 'wall_thickness': 4.5, # wall thickness parameter used on upper/mid stage of the wall + 'wall_base_y_thickness': 4.5, # wall thickness at the lower stage + 'wall_base_x_thickness': 4.5, # wall thickness at the lower stage + + 'wall_base_back_thickness': 4.5, # wall thickness at the lower stage in the specifically in back for interface. + + ## Settings for column_style == :fixed + ## The defaults roughly match Maltron settings + ## http://patentimages.storage.googleapis.com/EP0219944A2/imgf0002.png + ## fixed_z overrides the z portion of the column ofsets above. + ## NOTE: THIS DOESN'T WORK QUITE LIKE I'D HOPED. + 'fixed_angles': [d2r * 10, d2r * 10, 0, 0, 0, d2r * -15, d2r * -15], + 'fixed_x': [-41.5, -22.5, 0, 20.3, 41.4, 65.5, 89.6], # relative to the middle finger + 'fixed_z': [12.1, 8.3, 0, 5, 10.7, 14.5, 17.5], + 'fixed_tenting': d2r * 0, + + ################# + ## Switch Hole ## + ################# + + # plate options are + # 'HOLE' = a square hole. Also useful for applying custom plate files. + # 'NUB' = original side nubs. + # 'UNDERCUT' = snap fit undercut. May require CLIP_THICKNESS and possibly CLIP_UNDERCUT tweaking + # and/or filing to get proper snap. + # 'NOTCH' = snap fit undercut only near switch clip. May require CLIP_THICKNESS and possibly CLIP_UNDERCUT + # tweaking and/or filing to get proper snap. + # 'HS_NUB' = hot swap underside with nubs. + # 'HS_UNDERCUT' = hot swap underside with undercut. Does not generate properly. Hot swap step needs to be modified. + # 'HS_NOTCH' = hot swap underside with notch. Does not generate properly. Hot swap step needs to be modified. + # 'plate_style': 'NUB', + 'plate_style': 'NOTCH', + + 'hole_keyswitch_height': 14.0, + 'hole_keyswitch_width': 14.0, + + 'nub_keyswitch_height': 14.4, + 'nub_keyswitch_width': 14.4, + + 'undercut_keyswitch_height': 14.0, + 'undercut_keyswitch_width': 14.0, + 'notch_width': 5.0, # If using notch, it is identical to undecut, but only locally by the switch clip + + 'sa_profile_key_height': 12.7, + 'sa_length': 18.5, + 'sa_double_length': 37.5, + 'plate_thickness': 4 + 1.1, + + 'plate_rim': 1.5 + 0.5, + # Undercut style dimensions + 'clip_thickness': 1.3, + 'clip_undercut': 1.0, + 'undercut_transition': .2, # NOT FUNCTIONAL WITH OPENSCAD, ONLY WORKS WITH CADQUERY + + # Custom plate step file + 'plate_file': None, + 'plate_offset': 0.0, + + ########################## + ## OLED Mount Location + ########################## + # Initial pass will be manual placement. Can be used to create other mounts as well. + # Mount type options: + # None or 'NONE' = No OLED mount + # 'UNDERCUT' = Simple rectangle with undercut for clip in item + # 'SLIDING' = Features to slide the OLED in place and use a pin or block to secure from underneath. + # 'CLIP' = Features to set the OLED in a frame a snap a bezel down to hold it in place. + + 'oled_mount_type': 'CLIP', + 'oled_center_row': 1.25, # if not None, this will override the oled_mount_location_xyz and oled_mount_rotation_xyz settings + 'oled_translation_offset': (0, 0, 4), # Z offset tweaks are expected depending on curvature and OLED mount choice. + 'oled_rotation_offset': (0, 0, 0), + + 'oled_configurations': { + 'UNDERCUT':{ + # Common parameters + 'oled_mount_width': 15.0, + 'oled_mount_height': 35.0, + 'oled_mount_rim': 3.0, + 'oled_mount_depth': 6.0, + 'oled_mount_cut_depth': 20.0, + 'oled_mount_location_xyz': (-80.0, 20.0, 45.0), # will be overwritten if oled_center_row is not None + 'oled_mount_rotation_xyz': (13.0, 0.0, -6.0), # will be overwritten if oled_center_row is not None + 'oled_left_wall_x_offset_override': 28.0, + 'oled_left_wall_z_offset_override': 0.0, + 'oled_left_wall_lower_y_offset': 12.0, + 'oled_left_wall_lower_z_offset': 5.0, + + # 'UNDERCUT' Parameters + 'oled_mount_undercut': 1.0, + 'oled_mount_undercut_thickness': 2.0, + }, + 'SLIDING': { + # Common parameters + 'oled_mount_width': 12.5, # width of OLED, plus clearance + 'oled_mount_height': 25.0, # length of screen + 'oled_mount_rim': 2.5, + 'oled_mount_depth': 8.0, + 'oled_mount_cut_depth': 20.0, + 'oled_mount_location_xyz': (-78.0, 10.0, 41.0), # will be overwritten if oled_center_row is not None + 'oled_mount_rotation_xyz': (6.0, 0.0, -3.0), # will be overwritten if oled_center_row is not None + 'oled_left_wall_x_offset_override': 24.0, + 'oled_left_wall_z_offset_override': 0.0, + 'oled_left_wall_lower_y_offset': 12.0, + 'oled_left_wall_lower_z_offset': 5.0, + + # 'SLIDING' Parameters + 'oled_thickness': 4.2, # thickness of OLED, plus clearance. Must include components + 'oled_edge_overlap_end': 6.5, # length from end of viewable screen to end of PCB + 'oled_edge_overlap_connector': 5.5, # length from end of viewable screen to end of PCB on connection side. + 'oled_edge_overlap_thickness': 2.5, # thickness of material over edge of PCB + 'oled_edge_overlap_clearance': 2.5, # Clearance to insert PCB before laying down and sliding. + 'oled_edge_chamfer': 2.0, + }, + 'CLIP': { + # Common parameters + 'oled_mount_width': 12.5, # whole OLED width + 'oled_mount_height': 39.0, # whole OLED length + 'oled_mount_rim': 2.0, + 'oled_mount_depth': 7.0, + 'oled_mount_cut_depth': 20.0, + 'oled_mount_location_xyz': (-78.0, 20.0, 42.0), # will be overwritten if oled_center_row is not None + 'oled_mount_rotation_xyz': (12.0, 0.0, -6.0), # will be overwritten if oled_center_row is not None + 'oled_left_wall_x_offset_override': 24.0, + 'oled_left_wall_z_offset_override': 0.0, + 'oled_left_wall_lower_y_offset': 12.0, + 'oled_left_wall_lower_z_offset': 5.0, + + # 'CLIP' Parameters + 'oled_thickness': 4.2, # thickness of OLED, plus clearance. Must include components + 'oled_mount_bezel_thickness': 3.5, # z thickness of clip bezel + 'oled_mount_bezel_chamfer': 2.0, # depth of the 45 degree chamfer + 'oled_mount_connector_hole': 6.0, + 'oled_screen_start_from_conn_end': 6.5, + 'oled_screen_length': 24.5, + 'oled_screen_width': 10.5, + 'oled_clip_thickness': 1.5, + 'oled_clip_width': 6.0, + 'oled_clip_overhang': 1.0, + 'oled_clip_extension': 5.0, + 'oled_clip_width_clearance': 0.5, + 'oled_clip_undercut': 0.5, + 'oled_clip_undercut_thickness': 2.5, + 'oled_clip_y_gap': .2, + 'oled_clip_z_gap': .2, + } + }, + + 'screws_offset': 'INSIDE', # 'OUTSIDE', 'INSIDE', 'ORIGINAL' + + 'screw_insert_height': 3.8, + + # 'screw_insert_bottom_radius': 5.31 / 2, #Designed for inserts + # 'screw_insert_top_radius': 5.1 / 2, #Designed for inserts + + 'screw_insert_bottom_radius': 2.5 / 2, # Designed for self tapping + 'screw_insert_top_radius': 2.5 / 2, # Designed for self tapping + + 'screw_insert_outer_radius': 4.25, # Common to keep interface to base + + # Does anyone even use these? I think they just get in the way. + 'wire_post_height': 7, + 'wire_post_overhang': 3.5, + 'wire_post_diameter': 2.6, + + + + + ################################### + ## Controller Mount / Connectors ## + ################################### + # connector options are + # 'RJ9_USB_WALL' = Standard internal plate with RJ9 opening and square cutout for connection. + # 'USB_WALL' = Standard internal plate with a square cutout for connection, no RJ9. + # 'RJ9_USB_TEENSY' = Teensy holder + # 'USB_TEENSY' = Teensy holder, no RJ9 + # 'EXTERNAL' = square cutout for a holder such as the one from lolligagger. + # 'NONE' = No openings in the back. + 'controller_mount_type': 'EXTERNAL', + + 'external_holder_height': 12.5, + 'external_holder_width': 28.75, + 'external_holder_xoffset': -5.0, + 'external_holder_yoffset': -4.5, #Tweak this value to get the right undercut for the tray engagement. + + # Offset is from the top inner corner of the top inner key. + + ################################### + ## PCB Screw Mount ## + ################################### + "pcb_mount_ref_offset": [0, -5, 0], + "pcb_holder_size": [34.6, 7, 4], + "pcb_holder_offset": [8.9, 0, 0], + + "pcb_usb_hole_size": [7.5, 10.0, 4], + "pcb_usb_hole_offset": [15, 0, 4.5], + + "wall_thinner_size": [34, 7, 10], + + "trrs_hole_size": [3, 20], + "trrs_offset": [0, 0, 1.5], + + "pcb_screw_hole_size": [.5, 10], + "pcb_screw_x_offsets": [- 5.5, 7.75, 22], # for the screw positions off of reference + "pcb_screw_y_offset": -2, + + + ################################### + ## Bottom Plate Dimensions + ################################### + # COMMON DIMENSION + 'screw_hole_diameter': 3, + # USED FOR CADQUERY ONLY + 'base_thickness': 3.0, # thickness in the middle of the plate + 'base_offset': 3.0, # Both start flat/flush on the bottom. This offsets the base up (if positive) + 'base_rim_thickness': 5.0, # thickness on the outer frame with screws + 'screw_cbore_diameter': 6.0, + 'screw_cbore_depth': 2.5, + + # Offset is from the top inner corner of the top inner key. + + ################################### + ## HOLES ON PLATE FOR PCB MOUNT + ################################### + 'plate_holes': True, + 'plate_holes_xy_offset': (0.0, 0.0), + 'plate_holes_width': 14.3, + 'plate_holes_height': 14.3, + 'plate_holes_diameter': 1.6, + 'plate_holes_depth': 20.0, + + ################################### + ## EXPERIMENTAL + 'plate_pcb_clear': False, + 'plate_pcb_size': (18.5, 18.5, 5), + 'plate_pcb_offset': (0, 0, 0),# this is off of the back of the plate size. + ################################### + + ################################### + ## SHOW PCB FOR FIT CHECK + ################################### + 'pcb_width': 18.0, + 'pcb_height': 18.0, + 'pcb_thickness': 1.5, + 'pcb_hole_diameter': 2, + 'pcb_hole_pattern_width': 14.3, + 'pcb_hole_pattern_height': 14.3, + + ################################### + ## COLUMN OFFSETS + #################################### + + 'column_offsets': [ + [0, 0, 0], + [0, 0, 0], + [0, 2.82, -4.5], + [0, 0, 0], + [0, -6, 5],# REDUCED STAGGER + [0, -6, 5],# REDUCED STAGGER + [0, -6, 5],# NOT USED IN MOST FORMATS (7th column) + ], + +} + + #################################### + ## END CONFIGURATION SECTION + #################################### + +def save_config(): + # Check to see if the user has specified an alternate config + opts, args = getopt.getopt(sys.argv[1:], "", ["config=", "update="]) + got_opts = False + for opt, arg in opts: + if opt in ('--update'): + with open(os.path.join(r"..", "configs", arg + '.json'), mode='r') as fid: + data = json.load(fid) + shape_config.update(data) + got_opts = True + + for opt, arg in opts: + if opt in ('--config'): + # If a config file was specified, set the config_name and save_dir + shape_config['save_dir'] = arg + shape_config['config_name'] = arg + got_opts = True + + # Write the config to ./configs/<config_name>.json + if got_opts: + with open(os.path.join(r"..", "configs", shape_config['config_name'] + '.json'), mode='w') as fid: + json.dump(shape_config, fid, indent=4) + + else: + with open(os.path.join(r".", 'run_config.json'), mode='w') as fid: + json.dump(shape_config, fid, indent=4) + + +if __name__ == '__main__': + save_config() + + ## HERE FOR QUICK TESTING, SHOULD BE COMMENTED ON COMMIT + from dactyl_manuform import * + run()
\ No newline at end of file diff --git a/src/generate_configuration_test.py b/src/generate_configuration_test.py new file mode 100644 index 0000000..c40849b --- /dev/null +++ b/src/generate_configuration_test.py @@ -0,0 +1,501 @@ +import sys +import getopt +import os +import json + + +pi = 3.14159 +d2r = pi / 180 +r2d = 180 / pi + +shape_config = { + + # 'ENGINE': 'solid', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade + 'ENGINE': 'cadquery', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade + + + ###################### + ## Shape parameters ## + ###################### + + 'save_dir': '.', + 'config_name': "DM", + + 'show_caps': False, + 'show_pcbs': False, #only runs if caps are shown, easist place to initially inject geometry + + 'nrows': 6, #5, # key rows + 'ncols': 6, #6, # key columns + + 'alpha': pi / 12.0, # curvature of the columns + 'beta': pi / 36.0, # curvature of the rows + 'centercol': 3, # controls left_right tilt / tenting (higher number is more tenting) + 'centerrow_offset': 3, # rows from max, controls front_back tilt + 'tenting_angle': pi / 12.0, # or, change this for more precise tenting control + + # symmetry states if it is a symmetric or asymmetric bui. If asymmetric it doubles the generation time. + 'symmetry': "symmetric", # "asymmetric" or "symmetric" + + 'column_style_gt5': "orthographic", + 'column_style': "standard", # options include :standard, :orthographic, and :fixed + + 'thumb_offsets': [6, -3, 7], + 'keyboard_z_offset': ( + 11 # controls overall height# original=9 with centercol=3# use 16 for centercol=2 + ), + + + 'extra_width': 2.5, # extra space between the base of keys# original= 2 + 'extra_height': 1.0, # original= 0.5 + + + 'web_thickness': 4.0 + 1.1, + 'post_size': 0.1, + # post_adj': post_size / 2 + 'post_adj': 0, + + ############################## + # THUMB PARAMETERS + ############################## + + # 'DEFAULT' 6-key, 'MINI' 5-key, 'CARBONFET' 6-key, 'MINIDOX' 3-key, 'TRACKBALL_ORBYL', 'TRACKBALL_CJ' + 'thumb_style': 'DEFAULT', + 'default_1U_cluster': True, # only used with default, makes top right thumb cluster key 1U + # Thumb key size. May need slight oversizing, check w/ caps. Additional spacing will be automatically added for larger keys. + 'minidox_Usize': 1.6, + # Thumb plate rotations, anything other than 90 degree increments WILL NOT WORK. + + # Screw locations and extra screw locations for separable thumb, all from thumb origin + # Pulled out of hardcoding as drastic changes to the geometry may require fixes to the screw mounts. + # First screw in separable should be similar to the standard location as it will receive the same modifiers. + 'default_thumb_screw_xy_locations': [[-21, -58]], + 'default_separable_thumb_screw_xy_locations': [[-21, -58]], + 'mini_thumb_screw_xy_locations': [[-29, -52]], + 'mini_separable_thumb_screw_xy_locations': [[-29, -52], [-62, 10], [12, -25]], + 'minidox_thumb_screw_xy_locations': [[-37, -34]], + 'minidox_separable_thumb_screw_xy_locations': [[-37, -34], [-62, 12], [10, -25]], + 'carbonfet_thumb_screw_xy_locations': [[-48, -37]], + 'carbonfet_separable_thumb_screw_xy_locations': [[-48, -37], [-52, 10], [12, -35]], + 'orbyl_thumb_screw_xy_locations': [[-53, -68]], + 'orbyl_separable_thumb_screw_xy_locations': [[-53, -68], [-66, 8], [10, -40]], + 'tbcj_thumb_screw_xy_locations': [[-40, -75]], + 'tbcj_separable_thumb_screw_xy_locations': [[-40, -75], [-63, 10], [15, -40]], + + 'thumb_plate_tr_rotation': 0.0, # Top right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_tl_rotation': 0.0, # Top left plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_mr_rotation': 0.0, # Mid right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_ml_rotation': 0.0, # Mid left plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_br_rotation': 0.0, # Bottom right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + 'thumb_plate_bl_rotation': 0.0, # Bottom right plate rotation tweaks as thumb cluster is crowded for hot swap, etc. + ############################## + # EXPERIMENTAL + 'separable_thumb': False, #creates a separable thumb section with additional screws to hold it down. Only attached at base. + ############################## + + ################################### + ## Trackball in Wall ## + ################################### + 'trackball_in_wall': False, # Separate trackball option, placing it in the OLED area + 'tbiw_ball_center_row': 0, # up from cornerrow instead of down from top + 'tbiw_translational_offset': (2.0, -12.0, -10.0), + 'tbiw_rotation_offset': (30.0, -10.0, 0.0), + 'tbiw_left_wall_x_offset_override': 50.0, + 'tbiw_left_wall_z_offset_override': 0.0, + 'tbiw_left_wall_lower_x_offset': 15.0, + 'tbiw_left_wall_lower_y_offset': -15.0, + 'tbiw_left_wall_lower_z_offset': -25.0, + + 'tbiw_oled_center_row': .75, # not none, offsets are from this position + 'tbiw_oled_translation_offset': (-3.5, 0, 1.5), # Z offset tweaks are expected depending on curvature and OLED mount choice. + 'tbiw_oled_rotation_offset': (0, 0, 0), + + ########################################################################## + ## Finger Trackball in Wall EXPERIMENTAL WIP!!!! ## + ########################################################################## + # 'finger_trackball_in_wall': False, # Separate trackball option, placing it in the OLED area + # 'tbiw_ball_center_column': 0.2, # up from cornerrow instead of down from top + # 'tbiw_translational_offset': (0.0, 0.0, 0.0), + # 'tbiw_rotation_offset': (0.0, 0.0, 0.0), + # 'tbiw_top_wall_y_offset_override': 50.0, + # 'tbiw_top_wall_z_offset_override': 0.0, + # 'tbiw_top_wall_extension_cols': 4, + + + + ########################################### + ## Trackball JS / ORBYL Thumb Cluster ## + ########################################## + 'other_thumb': 'DEFAULT', # cluster used for second thumb except if ball_side == 'both' + 'tbjs_key_diameter': 70, + 'tbjs_Uwidth': 1.2, # size for inner key near trackball + 'tbjs_Uheight': 1.2, # size for inner key near trackball + + # Offsets are per key and are applied before rotating into place around the ball + # X and Y act like Tangential and Radial around the ball + # 'tbjs_translation_offset': (0, 0, 10), # applied to the whole assy + # 'tbjs_rotation_offset': (0, 10, 0), # applied to the whole assy + 'tbjs_translation_offset': (0, 0, 2), # applied to the whole assy + 'tbjs_rotation_offset': (0, -8, 0), # applied to the whole assy + 'tbjs_key_translation_offsets': [ + (0.0, 0.0, -3.0-5), + (0.0, 0.0, -3.0-5), + (0.0, 0.0, -3.0-5), + (0.0, 0.0, -3.0-5), + ], + 'tbjs_key_rotation_offsets': [ + (0.0, 0.0, 0.0), + (0.0, 0.0, 0.0), + (0.0, 0.0, 0.0), + (0.0, 0.0, 0.0), + ], + + ################################### + ## Trackball CJ Thumb Cluster ## + ################################### + 'tbcj_inner_diameter': 42, + 'tbcj_thickness': 2, + 'tbcj_outer_diameter': 53, + + + ################################### + ## Trackball General ## + ################################### + 'trackball_modular': False, # Added, creates a hole with space for the lip size listed below. + 'trackball_modular_lip_width': 3.0, # width of lip cleared out in ring location + 'trackball_modular_ball_height': 3.0, # height of ball from ring , used to create identical position to fixed. + 'trackball_modular_ring_height': 10.0, # height mount ring down from ball height. Covers gaps on elevated ball. + 'trackball_modular_clearance': 0.5, # height of ball from ring, used to create identical position to fixed. + + 'ball_side': 'both', #'left', 'right', or 'both' + 'ball_diameter': 34.0, + 'ball_wall_thickness': 3, # should not be changed unless the import models are changed. + 'ball_gap': 1.0, + 'trackball_hole_diameter': 36.5, + 'trackball_hole_height': 40, + 'trackball_plate_thickness': 2, + 'trackball_plate_width': 2, + # Removed trackball_rotation, ball_z_offset. and trackball_sensor_rotation and added more flexibility. + 'tb_socket_translation_offset': (0, 0, 2.0), # applied to the socket and sensor, large values will cause web/wall issues. + 'tb_socket_rotation_offset': (0, 0, 0), # applied to the socket and sensor, large values will cause web/wall issues. + 'tb_sensor_translation_offset': (0, 0, 0), #deviation from socket offsets, for fixing generated geometry issues + 'tb_sensor_rotation_offset': (0, 0, 0), #deviation from socket offsets, for changing the sensor roll orientation + + ############################## + # EXPERIMENTAL PARAMETERS + ############################## + 'pinky_1_5U': False, # LEAVE AS FALSE, CURRENTLY BROKEN + 'first_1_5U_row': 0, + 'last_1_5U_row': 5, + ############################## + + + 'wall_z_offset': 15, # length of the first downward_sloping part of the wall + 'wall_x_offset': 5, # offset in the x and/or y direction for the first downward_sloping part of the wall (negative) + 'wall_y_offset': 6, # offset in the x and/or y direction for the first downward_sloping part of the wall (negative) + 'left_wall_x_offset': 12, # specific values for the left side due to the minimal wall. + 'left_wall_z_offset': 3, # specific values for the left side due to the minimal wall. + 'left_wall_lower_x_offset': 0, # specific values for the lower left corner. + 'left_wall_lower_y_offset': 0, # specific values for the lower left corner. + 'left_wall_lower_z_offset': 0, + 'wall_thickness': 4.5, # wall thickness parameter used on upper/mid stage of the wall + 'wall_base_y_thickness': 4.5, # wall thickness at the lower stage + 'wall_base_x_thickness': 4.5, # wall thickness at the lower stage + + 'wall_base_back_thickness': 4.5, # wall thickness at the lower stage in the specifically in back for interface. + + ## Settings for column_style == :fixed + ## The defaults roughly match Maltron settings + ## http://patentimages.storage.googleapis.com/EP0219944A2/imgf0002.png + ## fixed_z overrides the z portion of the column ofsets above. + ## NOTE: THIS DOESN'T WORK QUITE LIKE I'D HOPED. + 'fixed_angles': [d2r * 10, d2r * 10, 0, 0, 0, d2r * -15, d2r * -15], + 'fixed_x': [-41.5, -22.5, 0, 20.3, 41.4, 65.5, 89.6], # relative to the middle finger + 'fixed_z': [12.1, 8.3, 0, 5, 10.7, 14.5, 17.5], + 'fixed_tenting': d2r * 0, + + ################# + ## Switch Hole ## + ################# + + # plate options are + # 'HOLE' = a square hole. Also useful for applying custom plate files. + # 'NUB' = original side nubs. + # 'UNDERCUT' = snap fit undercut. May require CLIP_THICKNESS and possibly CLIP_UNDERCUT tweaking + # and/or filing to get proper snap. + # 'NOTCH' = snap fit undercut only near switch clip. May require CLIP_THICKNESS and possibly CLIP_UNDERCUT + # tweaking and/or filing to get proper snap. + # 'HS_NUB' = hot swap underside with nubs. + # 'HS_UNDERCUT' = hot swap underside with undercut. Does not generate properly. Hot swap step needs to be modified. + # 'HS_NOTCH' = hot swap underside with notch. Does not generate properly. Hot swap step needs to be modified. + # 'plate_style': 'NUB', + 'plate_style': 'NOTCH', + + 'hole_keyswitch_height': 14.0, + 'hole_keyswitch_width': 14.0, + + 'nub_keyswitch_height': 14.4, + 'nub_keyswitch_width': 14.4, + + 'undercut_keyswitch_height': 14.0, + 'undercut_keyswitch_width': 14.0, + 'notch_width': 5.0, # If using notch, it is identical to undecut, but only locally by the switch clip + + 'sa_profile_key_height': 12.7, + 'sa_length': 18.5, + 'sa_double_length': 37.5, + 'plate_thickness': 4 + 1.1, + + 'plate_rim': 1.5 + 0.5, + # Undercut style dimensions + 'clip_thickness': 1.3, + 'clip_undercut': 1.0, + 'undercut_transition': .2, # NOT FUNCTIONAL WITH OPENSCAD, ONLY WORKS WITH CADQUERY + + # Custom plate step file + 'plate_file': None, + 'plate_offset': 0.0, + + ########################## + ## OLED Mount Location + ########################## + # Initial pass will be manual placement. Can be used to create other mounts as well. + # Mount type options: + # None or 'NONE' = No OLED mount + # 'UNDERCUT' = Simple rectangle with undercut for clip in item + # 'SLIDING' = Features to slide the OLED in place and use a pin or block to secure from underneath. + # 'CLIP' = Features to set the OLED in a frame a snap a bezel down to hold it in place. + + 'oled_mount_type': 'CLIP', + 'oled_center_row': 1.25, # if not None, this will override the oled_mount_location_xyz and oled_mount_rotation_xyz settings + 'oled_translation_offset': (0, 0, 4), # Z offset tweaks are expected depending on curvature and OLED mount choice. + 'oled_rotation_offset': (0, 0, 0), + + 'oled_configurations': { + 'UNDERCUT':{ + # Common parameters + 'oled_mount_width': 15.0, + 'oled_mount_height': 35.0, + 'oled_mount_rim': 3.0, + 'oled_mount_depth': 6.0, + 'oled_mount_cut_depth': 20.0, + 'oled_mount_location_xyz': (-80.0, 20.0, 45.0), # will be overwritten if oled_center_row is not None + 'oled_mount_rotation_xyz': (13.0, 0.0, -6.0), # will be overwritten if oled_center_row is not None + 'oled_left_wall_x_offset_override': 28.0, + 'oled_left_wall_z_offset_override': 0.0, + 'oled_left_wall_lower_y_offset': 12.0, + 'oled_left_wall_lower_z_offset': 5.0, + + # 'UNDERCUT' Parameters + 'oled_mount_undercut': 1.0, + 'oled_mount_undercut_thickness': 2.0, + }, + 'SLIDING': { + # Common parameters + 'oled_mount_width': 12.5, # width of OLED, plus clearance + 'oled_mount_height': 25.0, # length of screen + 'oled_mount_rim': 2.5, + 'oled_mount_depth': 8.0, + 'oled_mount_cut_depth': 20.0, + 'oled_mount_location_xyz': (-78.0, 10.0, 41.0), # will be overwritten if oled_center_row is not None + 'oled_mount_rotation_xyz': (6.0, 0.0, -3.0), # will be overwritten if oled_center_row is not None + 'oled_left_wall_x_offset_override': 24.0, + 'oled_left_wall_z_offset_override': 0.0, + 'oled_left_wall_lower_y_offset': 12.0, + 'oled_left_wall_lower_z_offset': 5.0, + + # 'SLIDING' Parameters + 'oled_thickness': 4.2, # thickness of OLED, plus clearance. Must include components + 'oled_edge_overlap_end': 6.5, # length from end of viewable screen to end of PCB + 'oled_edge_overlap_connector': 5.5, # length from end of viewable screen to end of PCB on connection side. + 'oled_edge_overlap_thickness': 2.5, # thickness of material over edge of PCB + 'oled_edge_overlap_clearance': 2.5, # Clearance to insert PCB before laying down and sliding. + 'oled_edge_chamfer': 2.0, + }, + 'CLIP': { + # Common parameters + 'oled_mount_width': 12.5, # whole OLED width + 'oled_mount_height': 39.0, # whole OLED length + 'oled_mount_rim': 2.0, + 'oled_mount_depth': 7.0, + 'oled_mount_cut_depth': 20.0, + 'oled_mount_location_xyz': (-78.0, 20.0, 42.0), # will be overwritten if oled_center_row is not None + 'oled_mount_rotation_xyz': (12.0, 0.0, -6.0), # will be overwritten if oled_center_row is not None + 'oled_left_wall_x_offset_override': 24.0, + 'oled_left_wall_z_offset_override': 0.0, + 'oled_left_wall_lower_y_offset': 12.0, + 'oled_left_wall_lower_z_offset': 5.0, + + # 'CLIP' Parameters + 'oled_thickness': 4.2, # thickness of OLED, plus clearance. Must include components + 'oled_mount_bezel_thickness': 3.5, # z thickness of clip bezel + 'oled_mount_bezel_chamfer': 2.0, # depth of the 45 degree chamfer + 'oled_mount_connector_hole': 6.0, + 'oled_screen_start_from_conn_end': 6.5, + 'oled_screen_length': 24.5, + 'oled_screen_width': 10.5, + 'oled_clip_thickness': 1.5, + 'oled_clip_width': 6.0, + 'oled_clip_overhang': 1.0, + 'oled_clip_extension': 5.0, + 'oled_clip_width_clearance': 0.5, + 'oled_clip_undercut': 0.5, + 'oled_clip_undercut_thickness': 2.5, + 'oled_clip_y_gap': .2, + 'oled_clip_z_gap': .2, + } + }, + + 'screws_offset': 'INSIDE', # 'OUTSIDE', 'INSIDE', 'ORIGINAL' + + 'screw_insert_height': 3.8, + + # 'screw_insert_bottom_radius': 5.31 / 2, #Designed for inserts + # 'screw_insert_top_radius': 5.1 / 2, #Designed for inserts + + 'screw_insert_bottom_radius': 2.5 / 2, # Designed for self tapping + 'screw_insert_top_radius': 2.5 / 2, # Designed for self tapping + + 'screw_insert_outer_radius': 4.25, # Common to keep interface to base + + # Does anyone even use these? I think they just get in the way. + 'wire_post_height': 7, + 'wire_post_overhang': 3.5, + 'wire_post_diameter': 2.6, + + + + + ################################### + ## Controller Mount / Connectors ## + ################################### + # connector options are + # 'RJ9_USB_WALL' = Standard internal plate with RJ9 opening and square cutout for connection. + # 'USB_WALL' = Standard internal plate with a square cutout for connection, no RJ9. + # 'RJ9_USB_TEENSY' = Teensy holder + # 'USB_TEENSY' = Teensy holder, no RJ9 + # 'EXTERNAL' = square cutout for a holder such as the one from lolligagger. + # 'NONE' = No openings in the back. + 'controller_mount_type': 'EXTERNAL', + + 'external_holder_height': 12.5, + 'external_holder_width': 28.75, + 'external_holder_xoffset': -5.0, + 'external_holder_yoffset': -4.5, #Tweak this value to get the right undercut for the tray engagement. + + # Offset is from the top inner corner of the top inner key. + + ################################### + ## PCB Screw Mount ## + ################################### + "pcb_mount_ref_offset": [0, -5, 0], + "pcb_holder_size": [34.6, 7, 4], + "pcb_holder_offset": [8.9, 0, 0], + + "pcb_usb_hole_size": [7.5, 10.0, 4], + "pcb_usb_hole_offset": [15, 0, 4.5], + + "wall_thinner_size": [34, 7, 10], + + "trrs_hole_size": [3, 20], + "trrs_offset": [0, 0, 1.5], + + "pcb_screw_hole_size": [.5, 10], + "pcb_screw_x_offsets": [- 5.5, 7.75, 22], # for the screw positions off of reference + "pcb_screw_y_offset": -2, + + + ################################### + ## Bottom Plate Dimensions + ################################### + # COMMON DIMENSION + 'screw_hole_diameter': 3, + # USED FOR CADQUERY ONLY + 'base_thickness': 3.0, # thickness in the middle of the plate + 'base_offset': 3.0, # Both start flat/flush on the bottom. This offsets the base up (if positive) + 'base_rim_thickness': 5.0, # thickness on the outer frame with screws + 'screw_cbore_diameter': 6.0, + 'screw_cbore_depth': 2.5, + + # Offset is from the top inner corner of the top inner key. + + ################################### + ## HOLES ON PLATE FOR PCB MOUNT + ################################### + 'plate_holes': True, + 'plate_holes_xy_offset': (0.0, 0.0), + 'plate_holes_width': 14.3, + 'plate_holes_height': 14.3, + 'plate_holes_diameter': 1.6, + 'plate_holes_depth': 20.0, + + ################################### + ## EXPERIMENTAL + 'plate_pcb_clear': False, + 'plate_pcb_size': (18.5, 18.5, 5), + 'plate_pcb_offset': (0, 0, 0),# this is off of the back of the plate size. + ################################### + + ################################### + ## SHOW PCB FOR FIT CHECK + ################################### + 'pcb_width': 18.0, + 'pcb_height': 18.0, + 'pcb_thickness': 1.5, + 'pcb_hole_diameter': 2, + 'pcb_hole_pattern_width': 14.3, + 'pcb_hole_pattern_height': 14.3, + + ################################### + ## COLUMN OFFSETS + #################################### + + 'column_offsets': [ + [0, 0, 0], + [0, 0, 0], + [0, 2.82, -4.5], + [0, 0, 0], + [0, -6, 5],# REDUCED STAGGER + [0, -6, 5],# REDUCED STAGGER + [0, -6, 5],# NOT USED IN MOST FORMATS (7th column) + ], + +} + + #################################### + ## END CONFIGURATION SECTION + #################################### + +def save_config(): + # Check to see if the user has specified an alternate config + opts, args = getopt.getopt(sys.argv[1:], "", ["config=", "update="]) + got_opts = False + for opt, arg in opts: + if opt in ('--update'): + with open(os.path.join(r"..", "configs", arg + '.json'), mode='r') as fid: + data = json.load(fid) + shape_config.update(data) + got_opts = True + + for opt, arg in opts: + if opt in ('--config'): + # If a config file was specified, set the config_name and save_dir + shape_config['save_dir'] = arg + shape_config['config_name'] = arg + got_opts = True + + # Write the config to ./configs/<config_name>.json + if got_opts: + with open(os.path.join(r"..", "configs", shape_config['config_name'] + '.json'), mode='w') as fid: + json.dump(shape_config, fid, indent=4) + + else: + with open(os.path.join(r".", 'run_config.json'), mode='w') as fid: + json.dump(shape_config, fid, indent=4) + + +if __name__ == '__main__': + save_config() + + ## HERE FOR QUICK TESTING, SHOULD BE COMMENTED ON COMMIT + from dactyl_manuform import * + run()
\ No newline at end of file diff --git a/src/helpers_blender.py b/src/helpers_blender.py index 9213488..00da8e5 100644 --- a/src/helpers_blender.py +++ b/src/helpers_blender.py @@ -82,7 +82,8 @@ def add(shapes): def difference(shape, shapes): debugprint('difference()') for item in shapes: - shape -= item + if item is not None: + shape -= item return shape diff --git a/src/helpers_cadquery.py b/src/helpers_cadquery.py index 5dc78d1..58a876a 100644 --- a/src/helpers_cadquery.py +++ b/src/helpers_cadquery.py @@ -30,6 +30,8 @@ def cone(r1, r2, height): def rotate(shape, angle): + if shape is None: + return None origin = (0, 0, 0) shape = shape.rotate(axisStartPoint=origin, axisEndPoint=(1, 0, 0), angleDegrees=angle[0]) shape = shape.rotate(axisStartPoint=origin, axisEndPoint=(0, 1, 0), angleDegrees=angle[1]) @@ -38,6 +40,8 @@ def rotate(shape, angle): def translate(shape, vector): + if shape is None: + return None return shape.translate(tuple(vector)) @@ -50,10 +54,11 @@ def union(shapes): debugprint('union()') shape = None for item in shapes: - if shape is None: - shape = item - else: - shape = shape.union(item) + if item is not None: + if shape is None: + shape = item + else: + shape = shape.union(item) return shape @@ -61,23 +66,27 @@ def add(shapes): debugprint('union()') shape = None for item in shapes: - if shape is None: - shape = item - else: - shape = shape.add(item) + if item is not None: + if shape is None: + shape = item + else: + shape = shape.add(item) return shape def difference(shape, shapes): debugprint('difference()') for item in shapes: - shape = shape.cut(item) + if item is not None: + shape = shape.cut(item) return shape def intersect(shape1, shape2): - return shape1.intersect(shape2) - + if shape2 is not None: + return shape1.intersect(shape2) + else: + return shape1 def face_from_points(points): # debugprint('face_from_points()') diff --git a/src/helpers_solid.py b/src/helpers_solid.py index 174d65a..2557e01 100644 --- a/src/helpers_solid.py +++ b/src/helpers_solid.py @@ -23,10 +23,14 @@ def cone(r1, r2, height): def rotate(shape, angle): + if shape is None: + return None return sl.rotate(angle)(shape) def translate(shape, vector): + if shape is None: + return None return sl.translate(tuple(vector))(shape) @@ -47,10 +51,11 @@ def union(shapes): debugprint('union()') shape = None for item in shapes: - if shape is None: - shape = item - else: - shape += item + if item is not None: + if shape is None: + shape = item + else: + shape += item return shape @@ -58,23 +63,27 @@ def add(shapes): debugprint('union()') shape = None for item in shapes: - if shape is None: - shape = item - else: - shape += item + if item is not None: + if shape is None: + shape = item + else: + shape += item return shape def difference(shape, shapes): debugprint('difference()') for item in shapes: - shape -= item + if item is not None: + shape -= item return shape def intersect(shape1, shape2): - return sl.intersection()(shape1, shape2) - + if shape2 is not None: + return sl.intersection()(shape1, shape2) + else: + return shape1 def hull_from_points(points): return sl.hull()(*points) diff --git a/src/parts/trackball_sensor_mount.stl b/src/parts/trackball_sensor_mount.stl Binary files differindex b3e1afa..4bbcfa5 100644 --- a/src/parts/trackball_sensor_mount.stl +++ b/src/parts/trackball_sensor_mount.stl diff --git a/src/run_config.json b/src/run_config.json index 48bde38..153a75c 100644 --- a/src/run_config.json +++ b/src/run_config.json @@ -1,10 +1,10 @@ { - "ENGINE": "solid", + "ENGINE": "cadquery", "save_dir": ".", "config_name": "DM", - "show_caps": true, + "show_caps": false, "show_pcbs": false, - "nrows": 5, + "nrows": 6, "ncols": 6, "alpha": 0.26179916666666664, "beta": 0.08726638888888888, @@ -20,15 +20,133 @@ 7 ], "keyboard_z_offset": 11, + "extra_width": 2.5, + "extra_height": 1.0, + "web_thickness": 5.1, + "post_size": 0.1, + "post_adj": 0, "thumb_style": "TRACKBALL_ORBYL", "default_1U_cluster": true, "minidox_Usize": 1.6, + "default_thumb_screw_xy_locations": [ + [ + -21, + -58 + ] + ], + "default_separable_thumb_screw_xy_locations": [ + [ + -21, + -58 + ] + ], + "mini_thumb_screw_xy_locations": [ + [ + -29, + -52 + ] + ], + "mini_separable_thumb_screw_xy_locations": [ + [ + -29, + -52 + ], + [ + -62, + 10 + ], + [ + 12, + -25 + ] + ], + "minidox_thumb_screw_xy_locations": [ + [ + -37, + -34 + ] + ], + "minidox_separable_thumb_screw_xy_locations": [ + [ + -37, + -34 + ], + [ + -62, + 12 + ], + [ + 10, + -25 + ] + ], + "carbonfet_thumb_screw_xy_locations": [ + [ + -48, + -37 + ] + ], + "carbonfet_separable_thumb_screw_xy_locations": [ + [ + -48, + -37 + ], + [ + -52, + 10 + ], + [ + 12, + -35 + ] + ], + "orbyl_thumb_screw_xy_locations": [ + [ + -53, + -68 + ] + ], + "orbyl_separable_thumb_screw_xy_locations": [ + [ + -53, + -68 + ], + [ + -66, + 8 + ], + [ + 10, + -40 + ] + ], + "tbcj_thumb_screw_xy_locations": [ + [ + -40, + -75 + ] + ], + "tbcj_separable_thumb_screw_xy_locations": [ + [ + -40, + -75 + ], + [ + -63, + 10 + ], + [ + 15, + -40 + ] + ], "thumb_plate_tr_rotation": 0.0, "thumb_plate_tl_rotation": 0.0, "thumb_plate_mr_rotation": 0.0, "thumb_plate_ml_rotation": 0.0, "thumb_plate_br_rotation": 0.0, "thumb_plate_bl_rotation": 0.0, + "separable_thumb": false, "trackball_in_wall": false, "tbiw_ball_center_row": 0.2, "tbiw_translational_offset": [ @@ -43,6 +161,7 @@ ], "tbiw_left_wall_x_offset_override": 50.0, "tbiw_left_wall_z_offset_override": 0.0, + "tbiw_left_wall_lower_x_offset": 0.0, "tbiw_left_wall_lower_y_offset": 0.0, "tbiw_left_wall_lower_z_offset": 0.0, "tbiw_oled_center_row": 0.75, @@ -56,16 +175,23 @@ 0, 0 ], + "finger_trackball_in_wall": false, + "tbiw_ball_center_column": 0.2, + "tbiw_top_wall_y_offset_override": 50.0, + "tbiw_top_wall_z_offset_override": 0.0, + "tbiw_top_wall_extension_cols": 4, "other_thumb": "DEFAULT", "tbjs_key_diameter": 70, + "tbjs_Uwidth": 1.2, + "tbjs_Uheight": 1.2, "tbjs_translation_offset": [ 0, 0, - 10 + 2 ], "tbjs_rotation_offset": [ 0, - 0, + -8, 0 ], "tbjs_key_translation_offsets": [ @@ -116,8 +242,11 @@ "tbcj_thickness": 2, "tbcj_outer_diameter": 53, "trackball_modular": false, - "trackball_Usize": 1.5, - "ball_side": "right", + "trackball_modular_lip_width": 3.0, + "trackball_modular_ball_height": 3.0, + "trackball_modular_ring_height": 10.0, + "trackball_modular_clearance": 0.5, + "ball_side": "both", "ball_diameter": 34.0, "ball_wall_thickness": 3, "ball_gap": 1.0, @@ -148,13 +277,13 @@ "pinky_1_5U": false, "first_1_5U_row": 0, "last_1_5U_row": 5, - "extra_width": 2.5, - "extra_height": 1.0, + "skeletal": false, "wall_z_offset": 15, "wall_x_offset": 5, "wall_y_offset": 6, "left_wall_x_offset": 12, "left_wall_z_offset": 3, + "left_wall_lower_x_offset": 0, "left_wall_lower_y_offset": 0, "left_wall_lower_z_offset": 0, "wall_thickness": 4.5, @@ -196,13 +325,13 @@ "nub_keyswitch_width": 14.4, "undercut_keyswitch_height": 14.0, "undercut_keyswitch_width": 14.0, - "notch_width": 5.0, + "notch_width": 6.0, "sa_profile_key_height": 12.7, "sa_length": 18.5, "sa_double_length": 37.5, "plate_thickness": 5.1, "plate_rim": 2.0, - "clip_thickness": 1.4, + "clip_thickness": 1.1, "clip_undercut": 1.0, "undercut_transition": 0.2, "plate_file": null, @@ -308,13 +437,11 @@ "oled_clip_z_gap": 0.2 } }, - "web_thickness": 4.0, - "post_size": 0.1, - "post_adj": 0, "screws_offset": "INSIDE", "screw_insert_height": 3.8, - "screw_insert_bottom_radius": 2.655, - "screw_insert_top_radius": 2.55, + "screw_insert_bottom_radius": 1.25, + "screw_insert_top_radius": 1.25, + "screw_insert_outer_radius": 4.25, "wire_post_height": 7, "wire_post_overhang": 3.5, "wire_post_diameter": 2.6, @@ -323,21 +450,81 @@ "external_holder_width": 28.75, "external_holder_xoffset": -5.0, "external_holder_yoffset": -4.5, - "screw_hole_diameter": 2, + "pcb_mount_ref_offset": [ + 0, + -5, + 0 + ], + "pcb_holder_size": [ + 34.6, + 7, + 4 + ], + "pcb_holder_offset": [ + 8.9, + 0, + 0 + ], + "pcb_usb_hole_size": [ + 7.5, + 10.0, + 4 + ], + "pcb_usb_hole_offset": [ + 15, + 0, + 4.5 + ], + "wall_thinner_size": [ + 34, + 7, + 10 + ], + "trrs_hole_size": [ + 3, + 20 + ], + "trrs_offset": [ + 0, + 0, + 1.5 + ], + "pcb_screw_hole_size": [ + 0.5, + 10 + ], + "pcb_screw_x_offsets": [ + -5.5, + 7.75, + 22 + ], + "pcb_screw_y_offset": -2, + "screw_hole_diameter": 3, "base_thickness": 3.0, "base_offset": 3.0, "base_rim_thickness": 5.0, - "screw_cbore_diameter": 4.0, - "screw_cbore_depth": 2.0, - "plate_holes": false, + "screw_cbore_diameter": 6.0, + "screw_cbore_depth": 2.5, + "plate_holes": true, "plate_holes_xy_offset": [ 0.0, 0.0 ], "plate_holes_width": 14.3, "plate_holes_height": 14.3, - "plate_holes_diameter": 1.7, + "plate_holes_diameter": 1.6, "plate_holes_depth": 20.0, + "plate_pcb_clear": false, + "plate_pcb_size": [ + 18.5, + 18.5, + 5 + ], + "plate_pcb_offset": [ + 0, + 0, + 0 + ], "pcb_width": 18.0, "pcb_height": 18.0, "pcb_thickness": 1.5, |