diff options
-rw-r--r-- | src/dactyl_manuform.py | 177 | ||||
-rw-r--r-- | src/generate_configuration.py | 44 | ||||
-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/run_config.json | 50 |
6 files changed, 277 insertions, 59 deletions
diff --git a/src/dactyl_manuform.py b/src/dactyl_manuform.py index a04a291..9913086 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 @@ -273,30 +274,37 @@ def single_plate(cylinder_segments=100, side="right"): return plate 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 @@ -3233,8 +3241,130 @@ 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 + pcb_usb_hole_z_offset + 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)) + holes.append(translate(hole, (pcb_screw_x_offsets[0], 0, 0))) + holes.append(translate(hole, (pcb_screw_x_offsets[1], 0, 0))) + holes.append(translate(hole, (pcb_screw_x_offsets[2], 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) @@ -3883,7 +4013,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))]) @@ -3922,7 +4059,7 @@ 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'): + if ('TRACKBALL' in thumb_style) and (side == ball_side or ball_side == 'both'): tbprecut, tb, tbcutout, sensor, ball = generate_trackball_in_cluster() shape = difference(shape, [tbprecut]) diff --git a/src/generate_configuration.py b/src/generate_configuration.py index f5fa716..1fb89bf 100644 --- a/src/generate_configuration.py +++ b/src/generate_configuration.py @@ -21,7 +21,7 @@ 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 @@ -44,11 +44,16 @@ shape_config = { 11 # controls overall height# original=9 with centercol=3# use 16 for centercol=2 ), + 'web_thickness': 4.0, + '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', + 'thumb_style': 'CARBONFET', '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, @@ -109,9 +114,11 @@ 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' @@ -294,10 +301,7 @@ 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' 'screw_insert_height': 3.8, @@ -322,7 +326,7 @@ shape_config = { # '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', + 'controller_mount_type': 'PCB_MOUNT', 'external_holder_height': 12.5, 'external_holder_width': 28.75, @@ -332,6 +336,26 @@ 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 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/run_config.json b/src/run_config.json index 48bde38..3b1da65 100644 --- a/src/run_config.json +++ b/src/run_config.json @@ -2,7 +2,7 @@ "ENGINE": "solid", "save_dir": ".", "config_name": "DM", - "show_caps": true, + "show_caps": false, "show_pcbs": false, "nrows": 5, "ncols": 6, @@ -20,7 +20,10 @@ 7 ], "keyboard_z_offset": 11, - "thumb_style": "TRACKBALL_ORBYL", + "web_thickness": 4.0, + "post_size": 0.1, + "post_adj": 0, + "thumb_style": "CARBONFET", "default_1U_cluster": true, "minidox_Usize": 1.6, "thumb_plate_tr_rotation": 0.0, @@ -116,6 +119,10 @@ "tbcj_thickness": 2, "tbcj_outer_diameter": 53, "trackball_modular": false, + "trackball_modular_lip_width": 3.0, + "trackball_modular_ball_height": 3.0, + "trackball_modular_ring_height": 10.0, + "trackball_modular_clearance": 0.5, "trackball_Usize": 1.5, "ball_side": "right", "ball_diameter": 34.0, @@ -308,9 +315,6 @@ "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, @@ -318,11 +322,45 @@ "wire_post_height": 7, "wire_post_overhang": 3.5, "wire_post_diameter": 2.6, - "controller_mount_type": "EXTERNAL", + "controller_mount_type": "PCB_MOUNT", "external_holder_height": 12.5, "external_holder_width": 28.75, "external_holder_xoffset": -5.0, "external_holder_yoffset": -4.5, + "pcb_mount_ref_y_offset": -5, + "pcb_holder_size": [ + 34.6, + 7, + 4 + ], + "pcb_holder_x_offset": 8.9, + "pcb_usb_hole_x_offset": 15, + "pcb_usb_hole_z_offset": 4.5, + "pcb_usb_hole_size": [ + 7.5, + 10.0, + 4 + ], + "wall_thinner_size": [ + 34, + 7, + 10 + ], + "trrs_hole_size": [ + 3, + 20 + ], + "trrs_z_offset": 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": 2, "base_thickness": 3.0, "base_offset": 3.0, |