diff options
author | Joshua Shreve <j.a.shreve@gmail.com> | 2021-07-07 21:11:14 -0400 |
---|---|---|
committer | Joshua Shreve <j.a.shreve@gmail.com> | 2021-07-07 21:11:14 -0400 |
commit | 7f9e6386a5b7c0c30cacb1c963fdd676645f0637 (patch) | |
tree | 0c873c623407162680b340256160150db9a4b94f /src/dactyl_manuform_cadquery.py | |
parent | ddc52e6dce23404fc6a4a76417cf6bf92ef4d5e7 (diff) |
Temporary version as the cadquery and solid python versions are merged by use of helper functions. Added a screw to the thumb cluster. Cadquery baseplate now has counterbores and actual solid geometry that is autogenerated, which is not possible in solid/OpenSCAD by the current methodology as it requires finding and extruding edges.
Diffstat (limited to 'src/dactyl_manuform_cadquery.py')
-rw-r--r-- | src/dactyl_manuform_cadquery.py | 2574 |
1 files changed, 0 insertions, 2574 deletions
diff --git a/src/dactyl_manuform_cadquery.py b/src/dactyl_manuform_cadquery.py deleted file mode 100644 index f1c29be..0000000 --- a/src/dactyl_manuform_cadquery.py +++ /dev/null @@ -1,2574 +0,0 @@ -import cadquery as cq - -import numpy as np -from numpy import pi -import os.path as path -import json -import os - -from scipy.spatial import ConvexHull as sphull - - -def deg2rad(degrees: float) -> float: - return degrees * pi / 180 - - -def rad2deg(rad: float) -> float: - return rad * 180 / pi - -debug_exports = False - -## IMPORT DEFAULT CONFIG IN CASE NEW PARAMETERS EXIST -import src.generate_configuration as cfg -for item in cfg.shape_config: - locals()[item] = cfg.shape_config[item] - -## LOAD RUN CONFIGURATION FILE -with open('run_config.json', mode='r') as fid: - data = json.load(fid) -for item in data: - locals()[item] = data[item] - -if oled_mount_type is not None: - for item in oled_configurations[oled_mount_type]: - locals()[item] = oled_configurations[oled_mount_type][item] - -if nrows > 5: - column_style = column_style_gt5 - -centerrow = nrows - centerrow_offset - -lastrow = nrows - 1 -cornerrow = lastrow - 1 -lastcol = ncols - 1 - - -# Derived values -if plate_style in ['NUB', 'HS_NUB']: - keyswitch_height = nub_keyswitch_height - keyswitch_width = nub_keyswitch_width -elif plate_style in ['UNDERCUT', 'HS_UNDERCUT']: - keyswitch_height = undercut_keyswitch_height - keyswitch_width = undercut_keyswitch_width -else: - keyswitch_height = hole_keyswitch_height - keyswitch_width = hole_keyswitch_width - -if plate_style in ['HS_UNDERCUT', 'HS_NUB', 'HS_HOLE']: - symmetry = "asymmetric" - plate_file = path.join("..", "src", r"hot_swap_plate.step") - plate_offset = 0.0 - -mount_width = keyswitch_width + 3 -mount_height = keyswitch_height + 3 -mount_thickness = plate_thickness - -if oled_mount_type is not None: - left_wall_x_offset = oled_left_wall_x_offset_override - left_wall_z_offset = oled_left_wall_z_offset_override - - - -spath = path.join("..", "things", save_dir) -if not path.isdir(spath): - os.mkdir(spath) - - -def column_offset(column: int) -> list: - return column_offsets[column] - -# column_style='fixed' - -def rotate(shape, angle): - 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]) - shape = shape.rotate(axisStartPoint=origin, axisEndPoint=(0, 0, 1), angleDegrees=angle[2]) - return shape - - -def translate(shape, vector): - return shape.translate(tuple(vector)) - - -def mirror(shape, plane=None): - print('mirror()') - return shape.mirror(mirrorPlane=plane) - - -def union(shapes): - print('union()') - shape = None - for item in shapes: - if shape is None: - shape = item - else: - shape = shape.union(item) - return shape - - -def face_from_points(points): - # print('face_from_points()') - edges = [] - num_pnts = len(points) - for i in range(len(points)): - p1 = points[i] - p2 = points[(i + 1) % num_pnts] - edges.append( - cq.Edge.makeLine( - cq.Vector(p1[0], p1[1], p1[2]), - cq.Vector(p2[0], p2[1], p2[2]), - ) - ) - - face = cq.Face.makeFromWires(cq.Wire.assembleEdges(edges)) - - return face - - -def hull_from_points(points): - # print('hull_from_points()') - hull_calc = sphull(points) - n_faces = len(hull_calc.simplices) - - faces = [] - for i in range(n_faces): - face_items = hull_calc.simplices[i] - fpnts = [] - for item in face_items: - fpnts.append(points[item]) - faces.append(face_from_points(fpnts)) - - shape = cq.Solid.makeSolid(cq.Shell.makeShell(faces)) - shape = cq.Workplane('XY').union(shape) - return shape - - -def hull_from_shapes(shapes, points=None): - # print('hull_from_shapes()') - vertices = [] - for shape in shapes: - verts = shape.vertices() - for vert in verts.objects: - vertices.append(np.array(vert.toTuple())) - if points is not None: - for point in points: - vertices.append(np.array(point)) - - shape = hull_from_points(vertices) - return shape - - -def tess_hull(shapes, sl_tol=.5, sl_angTol=1): - # print('hull_from_shapes()') - vertices = [] - solids = [] - for wp in shapes: - for item in wp.solids().objects: - solids.append(item) - - for shape in solids: - verts = shape.tessellate(sl_tol, sl_angTol)[0] - for vert in verts: - vertices.append(np.array(vert.toTuple())) - - shape = hull_from_points(vertices) - return shape - - - - -def single_plate(cylinder_segments=100, side="right"): - - if plate_style in ['NUB', 'HS_NUB']: - top_wall = cq.Workplane("XY").box(mount_width, 1.5, plate_thickness) - top_wall = top_wall.translate((0, (1.5 / 2) + (keyswitch_height / 2), plate_thickness / 2)) - - left_wall = cq.Workplane("XY").box(1.5, mount_height, plate_thickness) - left_wall = left_wall.translate(((1.5 / 2) + (keyswitch_width / 2), 0, plate_thickness / 2)) - - side_nub = cq.Workplane("XY").union(cq.Solid.makeCylinder(radius=1, height=2.75)) - side_nub = side_nub.translate((0, 0, -2.75 / 2.0)) - side_nub = rotate(side_nub, (90, 0, 0)) - side_nub = side_nub.translate((keyswitch_width / 2, 0, 1)) - nub_cube = cq.Workplane("XY").box(1.5, 2.75, plate_thickness) - nub_cube = nub_cube.translate(((1.5 / 2) + (keyswitch_width / 2), 0, plate_thickness / 2)) - - side_nub2 = tess_hull(shapes=(side_nub, nub_cube)) - side_nub2 = side_nub2.union(side_nub).union(nub_cube) - - plate_half1 = top_wall.union(left_wall).union(side_nub2) - plate_half2 = plate_half1 - plate_half2 = mirror(plate_half2, 'XZ') - plate_half2 = mirror(plate_half2, 'YZ') - - plate = plate_half1.union(plate_half2) - - else: # 'HOLE' or default, square cutout for non-nub designs. - plate = cq.Workplane("XY").box(mount_width, mount_height, mount_thickness) - plate = plate.translate((0.0, 0.0, mount_thickness / 2.0)) - - shape_cut = cq.Workplane("XY").box(keyswitch_width, keyswitch_height, mount_thickness * 2) - shape_cut = shape_cut.translate((0.0, 0.0, mount_thickness)) - - plate = plate.cut(shape_cut) - - if plate_style in ['UNDERCUT', 'HS_UNDERCUT']: - undercut = cq.Workplane("XY").box( - keyswitch_width + 2 * clip_undercut, - keyswitch_height + 2 * clip_undercut, - mount_thickness - ) - - undercut = undercut.translate((0.0, 0.0, -clip_thickness + mount_thickness / 2.0)) - if undercut_transition > 0: - undercut = undercut.faces("+Z").chamfer(undercut_transition, clip_undercut) - - plate = plate.cut(undercut) - - if plate_file is not None: - socket = cq.Workplane('XY').add(cq.importers.importShape( - cq.exporters.ExportTypes.STEP, - plate_file)) - socket = socket.translate([0, 0, plate_thickness + plate_offset]) - plate = plate.union(socket) - - if side == "left": - plate = plate.mirror('YZ') - - return plate - - -################ -## SA Keycaps ## -################ - -sa_length = 18.25 -sa_double_length = 37.5 - - -def sa_cap(Usize=1): - # MODIFIED TO NOT HAVE THE ROTATION. NEEDS ROTATION DURING ASSEMBLY - sa_length = 18.25 - - if Usize == 1: - bl2 = 18.5/2 - bw2 = 18.5/2 - m = 17 / 2 - pl2 = 6 - pw2 = 6 - - elif Usize == 2: - bl2 = sa_length - bw2 = sa_length / 2 - m = 0 - pl2 = 16 - pw2 = 6 - - elif Usize == 1.5: - bl2 = sa_length / 2 - bw2 = 27.94 / 2 - m = 0 - pl2 = 6 - pw2 = 11 - - k1 = cq.Workplane('XY').polyline([(bw2, bl2), (bw2, -bl2), (-bw2, -bl2), (-bw2, bl2), (bw2, bl2)]) - k1 = cq.Wire.assembleEdges(k1.edges().objects) - k1 = cq.Workplane('XY').add(cq.Solid.extrudeLinear(outerWire=k1, innerWires=[], vecNormal=cq.Vector(0, 0, 0.1))) - k1 = k1.translate((0, 0, 0.05)) - k2 = cq.Workplane('XY').polyline([(pw2, pl2), (pw2, -pl2), (-pw2, -pl2), (-pw2, pl2), (pw2, pl2)]) - k2 = cq.Wire.assembleEdges(k2.edges().objects) - k2 = cq.Workplane('XY').add(cq.Solid.extrudeLinear(outerWire=k2, innerWires=[], vecNormal=cq.Vector(0, 0, 0.1))) - k2 = k2.translate((0, 0, 12.0)) - if m > 0: - m1 = cq.Workplane('XY').polyline([(m, m), (m, -m), (-m, -m), (-m, m), (m, m)]) - m1 = cq.Wire.assembleEdges(m1.edges().objects) - m1 = cq.Workplane('XY').add(cq.Solid.extrudeLinear(outerWire=m1, innerWires=[], vecNormal=cq.Vector(0, 0, 0.1))) - m1 = m1.translate((0, 0, 6.0)) - key_cap = hull_from_shapes((k1, k2, m1)) - else: - key_cap = hull_from_shapes((k1, k2)) - - key_cap = key_cap.translate((0, 0, 5 + plate_thickness)) - # key_cap = key_cap.color((220 / 255, 163 / 255, 163 / 255, 1)) - - return key_cap - - -######################### -## Placement Functions ## -######################### - - -def rotate_around_x(position, angle): - # print('rotate_around_x()') - t_matrix = np.array( - [ - [1, 0, 0], - [0, np.cos(angle), -np.sin(angle)], - [0, np.sin(angle), np.cos(angle)], - ] - ) - return np.matmul(t_matrix, position) - - -def rotate_around_y(position, angle): - # print('rotate_around_y()') - t_matrix = np.array( - [ - [np.cos(angle), 0, np.sin(angle)], - [0, 1, 0], - [-np.sin(angle), 0, np.cos(angle)], - ] - ) - return np.matmul(t_matrix, position) - - -cap_top_height = plate_thickness + sa_profile_key_height -row_radius = ((mount_height + extra_height) / 2) / (np.sin(alpha / 2)) + cap_top_height -column_radius = ( - ((mount_width + extra_width) / 2) / (np.sin(beta / 2)) - ) + cap_top_height -column_x_delta = -1 - column_radius * np.sin(beta) -column_base_angle = beta * (centercol - 2) - - -def apply_key_geometry( - shape, - translate_fn, - rotate_x_fn, - rotate_y_fn, - column, - row, - column_style=column_style, -): - print('apply_key_geometry()') - - column_angle = beta * (centercol - column) - - if column_style == "orthographic": - column_z_delta = column_radius * (1 - np.cos(column_angle)) - shape = translate_fn(shape, [0, 0, -row_radius]) - shape = rotate_x_fn(shape, alpha * (centerrow - row)) - shape = translate_fn(shape, [0, 0, row_radius]) - shape = rotate_y_fn(shape, column_angle) - shape = translate_fn( - shape, [-(column - centercol) * column_x_delta, 0, column_z_delta] - ) - shape = translate_fn(shape, column_offset(column)) - - elif column_style == "fixed": - shape = rotate_y_fn(shape, fixed_angles[column]) - shape = translate_fn(shape, [fixed_x[column], 0, fixed_z[column]]) - shape = translate_fn(shape, [0, 0, -(row_radius + fixed_z[column])]) - shape = rotate_x_fn(shape, alpha * (centerrow - row)) - shape = translate_fn(shape, [0, 0, row_radius + fixed_z[column]]) - shape = rotate_y_fn(shape, fixed_tenting) - shape = translate_fn(shape, [0, column_offset(column)[1], 0]) - - else: - shape = translate_fn(shape, [0, 0, -row_radius]) - shape = rotate_x_fn(shape, alpha * (centerrow - row)) - shape = translate_fn(shape, [0, 0, row_radius]) - shape = translate_fn(shape, [0, 0, -column_radius]) - shape = rotate_y_fn(shape, column_angle) - shape = translate_fn(shape, [0, 0, column_radius]) - shape = translate_fn(shape, column_offset(column)) - - shape = rotate_y_fn(shape, tenting_angle) - shape = translate_fn(shape, [0, 0, keyboard_z_offset]) - - return shape - - -def x_rot(shape, angle): - # print('x_rot()') - return rotate(shape, [rad2deg(angle), 0, 0]) - - -def y_rot(shape, angle): - # print('y_rot()') - return rotate(shape, [0, rad2deg(angle), 0]) - - -def key_place(shape, column, row): - print('key_place()') - return apply_key_geometry(shape, translate, x_rot, y_rot, column, row) - - -def add_translate(shape, xyz): - print('add_translate()') - vals = [] - for i in range(len(shape)): - vals.append(shape[i] + xyz[i]) - return vals - - -def key_position(position, column, row): - print('key_position()') - return apply_key_geometry( - position, add_translate, rotate_around_x, rotate_around_y, column, row - ) - - -def key_holes(side="right"): - print('key_holes()') - # hole = single_plate() - holes = [] - for column in range(ncols): - for row in range(nrows): - if (column in [2, 3]) or (not row == lastrow): - holes.append(key_place(single_plate(side=side), column, row)) - - shape = union(holes) - - return shape - - -def caps(): - caps = None - for column in range(ncols): - for row in range(nrows): - if (column in [2, 3]) or (not row == lastrow): - if caps is None: - caps = key_place(sa_cap(), column, row) - else: - caps = caps.add(key_place(sa_cap(), column, row)) - - return caps - - -#################### -## Web Connectors ## -#################### - - - -def web_post(): - print('web_post()') - post = cq.Workplane("XY").box(post_size, post_size, web_thickness) - post = post.translate((0, 0, plate_thickness - (web_thickness / 2))) - return post - - -def web_post_tr(wide=False): - if wide: - w_divide = 1.2 - else: - w_divide = 2.0 - - return web_post().translate(((mount_width / w_divide) - post_adj, (mount_height / 2) - post_adj, 0)) - - -def web_post_tl(wide=False): - if wide: - w_divide = 1.2 - else: - w_divide = 2.0 - return web_post().translate((-(mount_width / w_divide) + post_adj, (mount_height / 2) - post_adj, 0)) - - -def web_post_bl(wide=False): - if wide: - w_divide = 1.2 - else: - w_divide = 2.0 - return web_post().translate((-(mount_width / w_divide) + post_adj, -(mount_height / 2) + post_adj, 0)) - - -def web_post_br(wide=False): - if wide: - w_divide = 1.2 - else: - w_divide = 2.0 - return web_post().translate(((mount_width / w_divide) - post_adj, -(mount_height / 2) + post_adj, 0)) - - -def triangle_hulls(shapes): - print('triangle_hulls()') - hulls = [cq.Workplane('XY')] - for i in range(len(shapes) - 2): - hulls.append(hull_from_shapes(shapes[i: (i + 3)])) - - return union(hulls) - - -def connectors(): - print('connectors()') - hulls = [] - for column in range(ncols - 1): - for row in range(lastrow): # 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)) - places.append(key_place(web_post_tr(), column, row)) - places.append(key_place(web_post_bl(), column + 1, row)) - places.append(key_place(web_post_br(), column, row)) - hulls.append(triangle_hulls(places)) - - for column in range(ncols): - # for row in range(nrows-1): - for row in range(cornerrow): - places = [] - places.append(key_place(web_post_bl(), column, row)) - places.append(key_place(web_post_br(), column, row)) - places.append(key_place(web_post_tl(), column, row + 1)) - places.append(key_place(web_post_tr(), column, row + 1)) - 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? - places = [] - places.append(key_place(web_post_br(), column, row)) - places.append(key_place(web_post_tr(), column, row + 1)) - places.append(key_place(web_post_bl(), column + 1, row)) - places.append(key_place(web_post_tl(), column + 1, row + 1)) - hulls.append(triangle_hulls(places)) - - return union(hulls) - - -############ -## Thumbs ## -############ - - -def thumborigin(): - # print('thumborigin()') - origin = key_position([mount_width / 2, -(mount_height / 2), 0], 1, cornerrow) - for i in range(len(origin)): - origin[i] = origin[i] + thumb_offsets[i] - return origin - - -def thumb_tr_place(shape): - print('thumb_tr_place()') - shape = rotate(shape, [10, -23, 10]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-12, -16, 3]) - return shape - - -def thumb_tl_place(shape): - print('thumb_tl_place()') - shape = rotate(shape, [10, -23, 10]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-32, -15, -2]) - return shape - - -def thumb_mr_place(shape): - print('thumb_mr_place()') - shape = rotate(shape, [-6, -34, 48]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-29, -40, -13]) - return shape - - -def thumb_ml_place(shape): - print('thumb_ml_place()') - shape = rotate(shape, [6, -34, 40]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-51, -25, -12]) - return shape - - -def thumb_br_place(shape): - print('thumb_br_place()') - shape = rotate(shape, [-16, -33, 54]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-37.8, -55.3, -25.3]) - return shape - - -def thumb_bl_place(shape): - print('thumb_bl_place()') - shape = rotate(shape, [-4, -35, 52]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-56.3, -43.3, -23.5]) - return shape - - -def thumb_1x_layout(shape, cap=False): - print('thumb_1x_layout()') - if cap: - shapes = thumb_mr_place(shape) - shapes = shapes.add(thumb_ml_place(shape)) - shapes = shapes.add(thumb_br_place(shape)) - shapes = shapes.add(thumb_bl_place(shape)) - else: - shapes = union( - [ - thumb_mr_place(shape), - thumb_ml_place(shape), - thumb_br_place(shape), - thumb_bl_place(shape), - ] - ) - return shapes - - -def thumb_15x_layout(shape, cap=False): - print('thumb_15x_layout()') - if cap: - shape = rotate(shape, (0, 0, 90)) - return thumb_tr_place(shape).add(thumb_tl_place(shape).solids().objects[0]) - else: - return thumb_tr_place(shape).union(thumb_tl_place(shape)) - -def double_plate_half(): - print('double_plate()') - plate_height = (sa_double_length - mount_height) / 3 - top_plate = cq.Workplane("XY").box(mount_width, plate_height, web_thickness) - top_plate = translate(top_plate, - [0, (plate_height + mount_height) / 2, plate_thickness - (web_thickness / 2)] - ) - return top_plate - -def double_plate(): - print('double_plate()') - top_plate = double_plate_half() - return union((top_plate, mirror(top_plate, 'XZ'))) - - -def thumbcaps(): - if thumb_style == "MINI": - return mini_thumbcaps() - elif thumb_style == "CARBONFET": - return carbonfet_thumbcaps() - else: - return default_thumbcaps() - - -def thumb(side="right"): - if thumb_style == "MINI": - return mini_thumb(side) - elif thumb_style == "CARBONFET": - return carbonfet_thumb(side) - else: - return default_thumb(side) - - -def thumb_connectors(): - if thumb_style == "MINI": - return mini_thumb_connectors() - elif thumb_style == "CARBONFET": - return carbonfet_thumb_connectors() - else: - return default_thumb_connectors() - - -def default_thumbcaps(): - t1 = thumb_1x_layout(sa_cap(1), cap=True) - t15 = thumb_15x_layout(sa_cap(1.5), cap=True) - return t1.add(t15) - - -def default_thumb(side="right"): - print('thumb()') - shape = thumb_1x_layout(rotate(single_plate(side=side), (0, 0, -90))) - shape = shape.union(thumb_15x_layout(rotate(single_plate(side=side), (0, 0, -90)))) - shape = shape.union(thumb_15x_layout(double_plate())) - return shape - - -def thumb_post_tr(): - print('thumb_post_tr()') - return translate(web_post(), - [(mount_width / 2) - post_adj, (mount_height / 1.15) - post_adj, 0] - ) - - -def thumb_post_tl(): - print('thumb_post_tl()') - return translate(web_post(), - [-(mount_width / 2) + post_adj, (mount_height / 1.15) - post_adj, 0] - ) - - -def thumb_post_bl(): - print('thumb_post_bl()') - return translate(web_post(), - [-(mount_width / 2) + post_adj, -(mount_height / 1.15) + post_adj, 0] - ) - - -def thumb_post_br(): - print('thumb_post_br()') - return translate(web_post(), - [(mount_width / 2) - post_adj, -(mount_height / 1.15) + post_adj, 0] - ) - - -def default_thumb_connectors(): - print('thumb_connectors()') - hulls = [] - - # Top two - hulls.append( - triangle_hulls( - [ - thumb_tl_place(thumb_post_tr()), - thumb_tl_place(thumb_post_br()), - thumb_tr_place(thumb_post_tl()), - thumb_tr_place(thumb_post_bl()), - ] - ) - ) - - # bottom two on the right - hulls.append( - triangle_hulls( - [ - thumb_br_place(web_post_tr()), - thumb_br_place(web_post_br()), - thumb_mr_place(web_post_tl()), - thumb_mr_place(web_post_bl()), - ] - ) - ) - - # bottom two on the left - hulls.append( - triangle_hulls( - [ - thumb_br_place(web_post_tr()), - thumb_br_place(web_post_br()), - thumb_mr_place(web_post_tl()), - thumb_mr_place(web_post_bl()), - ] - ) - ) - # centers of the bottom four - hulls.append( - triangle_hulls( - [ - thumb_bl_place(web_post_tr()), - thumb_bl_place(web_post_br()), - thumb_ml_place(web_post_tl()), - thumb_ml_place(web_post_bl()), - ] - ) - ) - - # top two to the middle two, starting on the left - hulls.append( - triangle_hulls( - [ - thumb_br_place(web_post_tl()), - thumb_bl_place(web_post_bl()), - thumb_br_place(web_post_tr()), - thumb_bl_place(web_post_br()), - thumb_mr_place(web_post_tl()), - thumb_ml_place(web_post_bl()), - thumb_mr_place(web_post_tr()), - thumb_ml_place(web_post_br()), - ] - ) - ) - - # top two to the main keyboard, starting on the left - hulls.append( - triangle_hulls( - [ - thumb_tl_place(thumb_post_tl()), - thumb_ml_place(web_post_tr()), - thumb_tl_place(thumb_post_bl()), - thumb_ml_place(web_post_br()), - thumb_tl_place(thumb_post_br()), - thumb_mr_place(web_post_tr()), - thumb_tr_place(thumb_post_bl()), - thumb_mr_place(web_post_br()), - thumb_tr_place(thumb_post_br()), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - thumb_tl_place(thumb_post_tl()), - key_place(web_post_bl(), 0, cornerrow), - thumb_tl_place(thumb_post_tr()), - key_place(web_post_br(), 0, cornerrow), - thumb_tr_place(thumb_post_tl()), - key_place(web_post_bl(), 1, cornerrow), - thumb_tr_place(thumb_post_tr()), - key_place(web_post_br(), 1, cornerrow), - key_place(web_post_tl(), 2, lastrow), - key_place(web_post_bl(), 2, lastrow), - thumb_tr_place(thumb_post_tr()), - key_place(web_post_bl(), 2, lastrow), - 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) - -############################ -# MINI THUMB CLUSTER -############################ - - -def mini_thumb_tr_place(shape): - shape = rotate(shape, [14, -15, 10]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-15, -10, 5]) - return shape - - -def mini_thumb_tl_place(shape): - shape = rotate(shape, [10, -23, 25]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-35, -16, -2]) - return shape - - -def mini_thumb_mr_place(shape): - shape = rotate(shape, [10, -23, 25]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-23, -34, -6]) - return shape - - -def mini_thumb_br_place(shape): - shape = rotate(shape, [6, -34, 35]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-39, -43, -16]) - return shape - - -def mini_thumb_bl_place(shape): - shape = rotate(shape, [6, -32, 35]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-51, -25, -11.5]) - return shape - - -def mini_thumb_1x_layout(shape): - return union([ - mini_thumb_mr_place(shape), - mini_thumb_br_place(shape), - mini_thumb_tl_place(shape), - mini_thumb_bl_place(shape), - ]) - - -def mini_thumb_15x_layout(shape): - return union([mini_thumb_tr_place(shape)] ) - - -def mini_thumbcaps(): - t1 = mini_thumb_1x_layout(sa_cap(1)) - t15 = mini_thumb_15x_layout(rotate(sa_cap(1) , pi / 2, [0, 0, 1])) - return t1.add(t15) - - -def mini_thumb(side="right"): - - # shape = thumb_1x_layout(sl.rotate([0.0, 0.0, -90])(single_plate(side=side))) - # shape += thumb_15x_layout(sl.rotate([0.0, 0.0, -90])(single_plate(side=side))) - shape = mini_thumb_1x_layout(single_plate(side=side)) - shape = union([shape, mini_thumb_15x_layout(single_plate(side=side))]) - - return shape - - -def mini_thumb_post_tr(): - return translate(web_post(), - [(mount_width / 2) - post_adj, (mount_height / 2) - post_adj, 0] - ) - - -def mini_thumb_post_tl(): - return translate(web_post(), - [-(mount_width / 2) + post_adj, (mount_height / 2) - post_adj, 0] - ) - - -def mini_thumb_post_bl(): - return translate(web_post(), - [-(mount_width / 2) + post_adj, -(mount_height / 2) + post_adj, 0] - ) - - -def mini_thumb_post_br(): - return translate(web_post(), - [(mount_width / 2) - post_adj, -(mount_height / 2) + post_adj, 0] - ) - - -def mini_thumb_connectors(): - hulls = [] - - # Top two - hulls.append( - triangle_hulls( - [ - mini_thumb_tl_place(web_post_tr()), - mini_thumb_tl_place(web_post_br()), - mini_thumb_tr_place(mini_thumb_post_tl()), - mini_thumb_tr_place(mini_thumb_post_bl()), - ] - ) - ) - - # bottom two on the right - hulls.append( - triangle_hulls( - [ - mini_thumb_br_place(web_post_tr()), - mini_thumb_br_place(web_post_br()), - mini_thumb_mr_place(web_post_tl()), - mini_thumb_mr_place(web_post_bl()), - ] - ) - ) - - # bottom two on the left - hulls.append( - triangle_hulls( - [ - mini_thumb_mr_place(web_post_tr()), - mini_thumb_mr_place(web_post_br()), - mini_thumb_tr_place(mini_thumb_post_br()), - ] - ) - ) - - # between top and bottom row - hulls.append( - triangle_hulls( - [ - mini_thumb_br_place(web_post_tl()), - mini_thumb_bl_place(web_post_bl()), - mini_thumb_br_place(web_post_tr()), - mini_thumb_bl_place(web_post_br()), - mini_thumb_mr_place(web_post_tl()), - mini_thumb_tl_place(web_post_bl()), - mini_thumb_mr_place(web_post_tr()), - mini_thumb_tl_place(web_post_br()), - mini_thumb_tr_place(web_post_bl()), - mini_thumb_mr_place(web_post_tr()), - mini_thumb_tr_place(web_post_br()), - ] - ) - ) - # top two to the main keyboard, starting on the left - hulls.append( - triangle_hulls( - [ - mini_thumb_tl_place(web_post_tl()), - mini_thumb_bl_place(web_post_tr()), - mini_thumb_tl_place(web_post_bl()), - mini_thumb_bl_place(web_post_br()), - mini_thumb_mr_place(web_post_tr()), - mini_thumb_tl_place(web_post_bl()), - mini_thumb_tl_place(web_post_br()), - mini_thumb_mr_place(web_post_tr()), - ] - ) - ) - # top two to the main keyboard, starting on the left - hulls.append( - triangle_hulls( - [ - mini_thumb_tl_place(web_post_tl()), - key_place(web_post_bl(), 0, cornerrow), - mini_thumb_tl_place(web_post_tr()), - key_place(web_post_br(), 0, cornerrow), - mini_thumb_tr_place(mini_thumb_post_tl()), - 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_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_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) - - -############################ -# Carbonfet THUMB CLUSTER -############################ - - -def carbonfet_thumb_tl_place(shape): - shape = rotate(shape, [10, -24, 10]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-13, -9.8, 4]) - return shape - -def carbonfet_thumb_tr_place(shape): - shape = rotate(shape, [6, -25, 10]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-7.5, -29.5, 0]) - return shape - -def carbonfet_thumb_ml_place(shape): - shape = rotate(shape, [8, -31, 14]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-30.5, -17, -6]) - return shape - -def carbonfet_thumb_mr_place(shape): - shape = rotate(shape, [4, -31, 14]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-22.2, -41, -10.3]) - return shape - -def carbonfet_thumb_br_place(shape): - shape = rotate(shape, [2, -37, 18]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-37, -46.4, -22]) - return shape - -def carbonfet_thumb_bl_place(shape): - shape = rotate(shape, [6, -37, 18]) - shape = shape.translate(thumborigin()) - shape = shape.translate([-47, -23, -19]) - return shape - - -def carbonfet_thumb_1x_layout(shape): - return union([ - carbonfet_thumb_tr_place(shape), - carbonfet_thumb_mr_place(shape), - carbonfet_thumb_br_place(shape), - carbonfet_thumb_tl_place(shape), - ]) - - -def carbonfet_thumb_15x_layout(shape): - return union([ - carbonfet_thumb_bl_place(shape), - carbonfet_thumb_ml_place(shape) - ]) - - -def carbonfet_thumbcaps(): - t1 = carbonfet_thumb_1x_layout(sa_cap(1)) - t15 = carbonfet_thumb_15x_layout(rotate(sa_cap(1.5), pi / 2, [0, 0, 1])) - return t1.add(t15) - - -def carbonfet_thumb(side="right"): - # shape = thumb_1x_layout(sl.rotate([0.0, 0.0, -90])(single_plate(side=side))) - # shape += thumb_15x_layout(sl.rotate([0.0, 0.0, -90])(single_plate(side=side))) - shape = carbonfet_thumb_1x_layout(single_plate(side=side)) - shape = union([shape, carbonfet_thumb_15x_layout(double_plate_half())]) - shape = union([shape, carbonfet_thumb_15x_layout(single_plate(side=side))]) - - return shape - -def carbonfet_thumb_post_tr(): - return translate(web_post(), - [(mount_width / 2) - post_adj, (mount_height / 1.15) - post_adj, 0] - ) - - -def carbonfet_thumb_post_tl(): - return translate(web_post(), - [-(mount_width / 2) + post_adj, (mount_height / 1.15) - post_adj, 0] - ) - - -def carbonfet_thumb_post_bl(): - return translate(web_post(), - [-(mount_width / 2) + post_adj, -(mount_height / 1.15) + post_adj, 0] - ) - - -def carbonfet_thumb_post_br(): - return translate(web_post(), - [(mount_width / 2) - post_adj, -(mount_height / 2) + post_adj, 0] - ) - -def carbonfet_thumb_connectors(): - hulls = [] - - # Top two - hulls.append( - triangle_hulls( - [ - carbonfet_thumb_tl_place(web_post_tl()), - carbonfet_thumb_tl_place(web_post_bl()), - carbonfet_thumb_ml_place(carbonfet_thumb_post_tr()), - carbonfet_thumb_ml_place(web_post_br()), - ] - ) - ) - - hulls.append( - triangle_hulls( - [ - carbonfet_thumb_ml_place(carbonfet_thumb_post_tl()), - carbonfet_thumb_ml_place(web_post_bl()), - carbonfet_thumb_bl_place(carbonfet_thumb_post_tr()), - carbonfet_thumb_bl_place(web_post_br()), - ] - ) - ) - - # bottom two on the right - hulls.append( - triangle_hulls( - [ - carbonfet_thumb_br_place(web_post_tr()), - carbonfet_thumb_br_place(web_post_br()), - carbonfet_thumb_mr_place(web_post_tl()), - carbonfet_thumb_mr_place(web_post_bl()), - ] - ) - ) - - # bottom two on the left - hulls.append( - triangle_hulls( - [ - carbonfet_thumb_mr_place(web_post_tr()), - carbonfet_thumb_mr_place(web_post_br()), - carbonfet_thumb_tr_place(web_post_tl()), - carbonfet_thumb_tr_place(web_post_bl()), - ] - ) - ) - hulls.append( - triangle_hulls( - [ - carbonfet_thumb_tr_place(web_post_br()), - carbonfet_thumb_tr_place(web_post_bl()), - carbonfet_thumb_mr_place(web_post_br()), - ] - ) - ) - - # between top and bottom row - hulls.append( - triangle_hulls( - [ - carbonfet_thumb_br_place(web_post_tl()), - carbonfet_thumb_bl_place(web_post_bl()), - carbonfet_thumb_br_place(web_post_tr()), - carbonfet_thumb_bl_place(web_post_br()), - carbonfet_thumb_mr_place(web_post_tl()), - carbonfet_thumb_ml_place(web_post_bl()), - carbonfet_thumb_mr_place(web_post_tr()), - carbonfet_thumb_ml_place(web_post_br()), - carbonfet_thumb_tr_place(web_post_tl()), - carbonfet_thumb_tl_place(web_post_bl()), - carbonfet_thumb_tr_place(web_post_tr()), - carbonfet_thumb_tl_place(web_post_br()), - ] - ) - ) - # top two to the main keyboard, starting on the left - hulls.append( - triangle_hulls( - [ - carbonfet_thumb_ml_place(carbonfet_thumb_post_tl()), - key_place(web_post_bl(), 0, cornerrow), - carbonfet_thumb_ml_place(carbonfet_thumb_post_tr()), - key_place(web_post_br(), 0, cornerrow), - carbonfet_thumb_tl_place(web_post_tl()), - 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), - carbonfet_thumb_tl_place(web_post_br()), - key_place(web_post_br(), 2, lastrow), - key_place(web_post_bl(), 3, lastrow), - carbonfet_thumb_tl_place(web_post_br()), - carbonfet_thumb_tr_place(web_post_tr()), - ] - ) - ) - - 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), - ] - ) - ) - - 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) - - -########## -## Case ## -########## - - -def bottom_hull(p, height=0.001): - print("bottom_hull()") - shape = None - for item in p: - # proj = sl.projection()(p) - # t_shape = sl.linear_extrude(height=height, twist=0, convexity=0, center=True)( - # proj - # ) - vertices = [] - verts = item.faces('<Z').vertices() - for vert in verts.objects: - v0 = vert.toTuple() - v1 = [v0[0], v0[1], -10] - vertices.append(np.array(v0)) - vertices.append(np.array(v1)) - - t_shape = hull_from_points(vertices) - - # t_shape = translate(t_shape, [0, 0, height / 2 - 10]) - - if shape is None: - shape = t_shape - - for shp in (*p, shape, t_shape): - try: - shp.vertices() - except: - 0 - # shape = shape.union(hull_from_shapes((item, shape, t_shape))) - shape = shape.union(hull_from_shapes((shape, t_shape))) - # shape = shape.union(t_shape) - - return shape - - - -def left_key_position(row, direction): - print("left_key_position()") - pos = np.array( - key_position([-mount_width * 0.5, direction * mount_height * 0.5, 0], 0, row) - ) - return list(pos - np.array([left_wall_x_offset, 0, left_wall_z_offset])) - - -def left_key_place(shape, row, direction): - print("left_key_place()") - pos = left_key_position(row, direction) - return shape.translate(pos) - - -def wall_locate1(dx, dy): - print("wall_locate1()") - return [dx * wall_thickness, dy * wall_thickness, -1] - - -def wall_locate2(dx, dy): - print("wall_locate2()") - return [dx * wall_x_offset, dy * wall_y_offset, -wall_z_offset] - - -def wall_locate3(dx, dy, back=False): - print("wall_locate3()") - if back: - return [ - dx * (wall_x_offset + wall_base_x_thickness), - dy * (wall_y_offset + wall_base_back_thickness), - -wall_z_offset, - ] - else: - return [ - dx * (wall_x_offset + wall_base_x_thickness), - 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): - print("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)))) - - 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)))) - 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) - - return shape1.union(shape2) - # return shape1 - - -def key_wall_brace(x1, y1, dx1, dy1, post1, x2, y2, dx2, dy2, post2, back=False): - print("key_wall_brace()") - return wall_brace( - (lambda shape: key_place(shape, x1, y1)), - dx1, - dy1, - post1, - (lambda shape: key_place(shape, x2, y2)), - dx2, - dy2, - post2, - back - ) - - -def back_wall(): - print("back_wall()") - x = 0 - shape = cq.Workplane('XY') - shape = shape.union(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 = shape.union(key_wall_brace(x, 0, 0, 1, web_post_tl(), x, 0, 0, 1, web_post_tr(), back=True)) - shape = shape.union(key_wall_brace( - x, 0, 0, 1, web_post_tl(), x - 1, 0, 0, 1, web_post_tr(), back=True - )) - shape = shape.union(key_wall_brace( - lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr(), back=True - )) - return shape - - -def right_wall(): - print("right_wall()") - y = 0 - shape = cq.Workplane('XY') - shape = shape.union( - key_wall_brace( - lastcol, y, 1, 0, web_post_tr(), lastcol, y, 1, 0, web_post_br() - ) - ) - - for i in range(lastrow - 1): - y = i + 1 - shape = shape.union(key_wall_brace( - lastcol, y - 1, 1, 0, web_post_br(), lastcol, y, 1, 0, web_post_tr() - )) - - shape = shape.union(key_wall_brace( - lastcol, y, 1, 0, web_post_tr(), lastcol, y, 1, 0, web_post_br() - )) - #STRANGE PARTIAL OFFSET - - shape = shape.union(key_wall_brace( - lastcol, - cornerrow, - 0, - -1, - web_post_br(), - lastcol, - cornerrow, - 1, - 0, - web_post_br(), - )) - return shape - - -def left_wall(): - print('left_wall()') - shape = cq.Workplane('XY') - shape = shape.union(wall_brace( - (lambda sh: key_place(sh, 0, 0)), - 0, - 1, - web_post_tl(), - (lambda sh: left_key_place(sh, 0, 1)), - 0, - 1, - web_post(), - )) - - shape = shape.union(wall_brace( - (lambda sh: left_key_place(sh, 0, 1)), - 0, - 1, - web_post(), - (lambda sh: left_key_place(sh, 0, 1)), - -1, - 0, - web_post(), - )) - - for i in range(lastrow): - y = i - temp_shape1 = wall_brace( - (lambda sh: left_key_place(sh, y, 1)), - -1, - 0, - web_post(), - (lambda sh: left_key_place(sh, y, -1)), - -1, - 0, - web_post(), - ) - 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), - left_key_place(web_post(), y, -1), - )) - shape = shape.union(temp_shape1) - shape = shape.union(temp_shape2) - - for i in range(lastrow - 1): - y = i + 1 - temp_shape1 = wall_brace( - (lambda sh: left_key_place(sh, y - 1, -1)), - -1, - 0, - web_post(), - (lambda sh: left_key_place(sh, y, 1)), - -1, - 0, - web_post(), - ) - 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), - left_key_place(web_post(), y - 1, -1), - )) - shape = shape.union(temp_shape1) - shape = shape.union(temp_shape2) - - return shape - - -def front_wall(): - print('front_wall()') - shape = cq.Workplane('XY') - shape = shape.union( - key_wall_brace( - lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr() - ) - ) - shape = shape.union(key_wall_brace( - 3, lastrow, 0, -1, web_post_bl(), 3, lastrow, 0.5, -1, web_post_br() - )) - shape = shape.union(key_wall_brace( - 3, lastrow, 0.5, -1, web_post_br(), 4, cornerrow, 1, -1, web_post_bl() - )) - for i in range(ncols - 4): - x = i + 4 - shape = shape.union(key_wall_brace( - x, cornerrow, 0, -1, web_post_bl(), x, cornerrow, 0, -1, web_post_br() - )) - for i in range(ncols - 5): - x = i + 5 - shape = shape.union(key_wall_brace( - x, cornerrow, 0, -1, web_post_bl(), x - 1, cornerrow, 0, -1, web_post_br() - )) - - return shape - -def thumb_walls(): - if thumb_style == "MINI": - return mini_thumb_walls() - elif thumb_style == "CARBONFET": - return carbonfet_thumb_walls() - else: - return default_thumb_walls() - -def thumb_connection(): - if thumb_style == "MINI": - return mini_thumb_connection() - elif thumb_style == "CARBONFET": - return carbonfet_thumb_connection() - else: - return default_thumb_connection() - -def default_thumb_walls(): - print('thumb_walls()') - # thumb, walls - shape = cq.Workplane('XY') - shape = shape.union(wall_brace(thumb_mr_place, 0, -1, web_post_br(), thumb_tr_place, 0, -1, thumb_post_br())) - shape = shape.union(wall_brace(thumb_mr_place, 0, -1, web_post_br(), thumb_mr_place, 0, -1, web_post_bl())) - shape = shape.union(wall_brace(thumb_br_place, 0, -1, web_post_br(), thumb_br_place, 0, -1, web_post_bl())) - shape = shape.union(wall_brace(thumb_ml_place, -0.3, 1, web_post_tr(), thumb_ml_place, 0, 1, web_post_tl())) - shape = shape.union(wall_brace(thumb_bl_place, 0, 1, web_post_tr(), thumb_bl_place, 0, 1, web_post_tl())) - shape = shape.union(wall_brace(thumb_br_place, -1, 0, web_post_tl(), thumb_br_place, -1, 0, web_post_bl())) - shape = shape.union(wall_brace(thumb_bl_place, -1, 0, web_post_tl(), thumb_bl_place, -1, 0, web_post_bl())) - # thumb, corners - shape = shape.union(wall_brace(thumb_br_place, -1, 0, web_post_bl(), thumb_br_place, 0, -1, web_post_bl())) - shape = shape.union(wall_brace(thumb_bl_place, -1, 0, web_post_tl(), thumb_bl_place, 0, 1, web_post_tl())) - # thumb, tweeners - shape = shape.union(wall_brace(thumb_mr_place, 0, -1, web_post_bl(), thumb_br_place, 0, -1, web_post_br())) - shape = shape.union(wall_brace(thumb_ml_place, 0, 1, web_post_tl(), thumb_bl_place, 0, 1, web_post_tr())) - shape = shape.union(wall_brace(thumb_bl_place, -1, 0, web_post_bl(), thumb_br_place, -1, 0, web_post_tl())) - shape = shape.union(wall_brace(thumb_tr_place, 0, -1, thumb_post_br(), (lambda sh: key_place(sh, 3, lastrow)), 0, -1, web_post_bl())) - - return shape - - -def default_thumb_connection(): - print('thumb_connection()') - shape = cq.Workplane('XY') - # clunky bit on the top left thumb connection (normal connectors don't work well) - shape = shape.union(bottom_hull( - [ - left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1), - thumb_ml_place(translate(web_post_tr(), wall_locate2(-0.3, 1))), - thumb_ml_place(translate(web_post_tr(), wall_locate3(-0.3, 1))), - ] - )) - - # shape = shape.union(hull_from_shapes( - - shape = shape.union( - hull_from_shapes( - [ - left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1), - thumb_ml_place(translate(web_post_tr(), wall_locate2(-0.3, 1))), - thumb_ml_place(translate(web_post_tr(), wall_locate3(-0.3, 1))), - thumb_tl_place(thumb_post_tl()), - ] - ) - ) # ) - - shape = shape.union(hull_from_shapes( - [ - left_key_place(web_post(), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate1(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1), - thumb_tl_place(thumb_post_tl()), - ] - )) - - shape = shape.union(hull_from_shapes( - [ - left_key_place(web_post(), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate1(-1, 0)), cornerrow, -1), - key_place(web_post_bl(), 0, cornerrow), - key_place(translate(web_post_bl(), wall_locate1(-1, 0)), 0, cornerrow), - thumb_tl_place(thumb_post_tl()), - ] - )) - - shape = shape.union(hull_from_shapes( - [ - thumb_ml_place(web_post_tr()), - thumb_ml_place(translate(web_post_tr(), wall_locate1(-0.3, 1))), - thumb_ml_place(translate(web_post_tr(), wall_locate2(-0.3, 1))), - thumb_ml_place(translate(web_post_tr(), wall_locate3(-0.3, 1))), - thumb_tl_place(thumb_post_tl()), - ] - )) - - return shape - -def mini_thumb_walls(): - # thumb, walls - shape = cq.Workplane('XY') - shape = shape.union(wall_brace(mini_thumb_mr_place, 0, -1, web_post_br(), mini_thumb_tr_place, 0, -1, mini_thumb_post_br())) - shape = shape.union(wall_brace(mini_thumb_mr_place, 0, -1, web_post_br(), mini_thumb_mr_place, 0, -1, web_post_bl())) - shape = shape.union(wall_brace(mini_thumb_br_place, 0, -1, web_post_br(), mini_thumb_br_place, 0, -1, web_post_bl())) - shape = shape.union(wall_brace(mini_thumb_bl_place, 0, 1, web_post_tr(), mini_thumb_bl_place, 0, 1, web_post_tl())) - shape = shape.union(wall_brace(mini_thumb_br_place, -1, 0, web_post_tl(), mini_thumb_br_place, -1, 0, web_post_bl())) - shape = shape.union(wall_brace(mini_thumb_bl_place, -1, 0, web_post_tl(), mini_thumb_bl_place, -1, 0, web_post_bl())) - # thumb, corners - shape = shape.union(wall_brace(mini_thumb_br_place, -1, 0, web_post_bl(), mini_thumb_br_place, 0, -1, web_post_bl())) - shape = shape.union(wall_brace(mini_thumb_bl_place, -1, 0, web_post_tl(), mini_thumb_bl_place, 0, 1, web_post_tl())) - # thumb, tweeners - shape = shape.union(wall_brace(mini_thumb_mr_place, 0, -1, web_post_bl(), mini_thumb_br_place, 0, -1, web_post_br())) - shape = shape.union(wall_brace(mini_thumb_bl_place, -1, 0, web_post_bl(), mini_thumb_br_place, -1, 0, web_post_tl())) - shape = shape.union(wall_brace(mini_thumb_tr_place, 0, -1, mini_thumb_post_br(), (lambda sh: key_place(sh, 3, lastrow)), 0, -1, web_post_bl())) - - return shape - -def mini_thumb_connection(): - shape = cq.Workplane('XY') - # clunky bit on the top left thumb connection (normal connectors don't work well) - shape = shape.union(bottom_hull( - [ - left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1), - mini_thumb_bl_place(translate(web_post_tr(), wall_locate2(-0.3, 1))), - mini_thumb_bl_place(translate(web_post_tr(), wall_locate3(-0.3, 1))), - ] - )) - - shape = shape.union( - hull_from_shapes( - [ - left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1), - mini_thumb_bl_place(translate(web_post_tr(), wall_locate2(-0.3, 1))), - mini_thumb_bl_place(translate(web_post_tr(), wall_locate3(-0.3, 1))), - mini_thumb_tl_place(web_post_tl()), - ] - )) - - shape = shape.union( - hull_from_shapes( - [ - left_key_place(web_post(), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate1(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1), - mini_thumb_tl_place(web_post_tl()), - ] - )) - - shape = shape.union( - hull_from_shapes( - [ - left_key_place(web_post(), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate1(-1, 0)), cornerrow, -1), - key_place(web_post_bl(), 0, cornerrow), - mini_thumb_tl_place(web_post_tl()), - ] - )) - - shape = shape.union( - hull_from_shapes( - [ - mini_thumb_bl_place(web_post_tr()), - mini_thumb_bl_place(translate(web_post_tr(), wall_locate1(-0.3, 1))), - mini_thumb_bl_place(translate(web_post_tr(), wall_locate2(-0.3, 1))), - mini_thumb_bl_place(translate(web_post_tr(), wall_locate3(-0.3, 1))), - mini_thumb_tl_place(web_post_tl()), - ] - )) - - return shape - - - -def carbonfet_thumb_walls(): - # thumb, walls - shape = cq.Workplane('XY') - shape = shape.union(wall_brace(carbonfet_thumb_mr_place, 0, -1, web_post_br(), carbonfet_thumb_tr_place, 0, -1, web_post_br())) - shape = shape.union(wall_brace(carbonfet_thumb_mr_place, 0, -1, web_post_br(), carbonfet_thumb_mr_place, 0, -1.15, web_post_bl())) - shape = shape.union(wall_brace(carbonfet_thumb_br_place, 0, -1, web_post_br(), carbonfet_thumb_br_place, 0, -1, web_post_bl())) - shape = shape.union(wall_brace(carbonfet_thumb_bl_place, -.3, 1, thumb_post_tr(), carbonfet_thumb_bl_place, 0, 1, thumb_post_tl())) - shape = shape.union(wall_brace(carbonfet_thumb_br_place, -1, 0, web_post_tl(), carbonfet_thumb_br_place, -1, 0, web_post_bl())) - shape = shape.union(wall_brace(carbonfet_thumb_bl_place, -1, 0, thumb_post_tl(), carbonfet_thumb_bl_place, -1, 0, web_post_bl())) - # thumb, corners - shape = shape.union(wall_brace(carbonfet_thumb_br_place, -1, 0, web_post_bl(), carbonfet_thumb_br_place, 0, -1, web_post_bl())) - shape = shape.union(wall_brace(carbonfet_thumb_bl_place, -1, 0, thumb_post_tl(), carbonfet_thumb_bl_place, 0, 1, thumb_post_tl())) - # thumb, tweeners - shape = shape.union(wall_brace(carbonfet_thumb_mr_place, 0, -1.15, web_post_bl(), carbonfet_thumb_br_place, 0, -1, web_post_br())) - shape = shape.union(wall_brace(carbonfet_thumb_bl_place, -1, 0, web_post_bl(), carbonfet_thumb_br_place, -1, 0, web_post_tl())) - shape = shape.union(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(): - # clunky bit on the top left thumb connection (normal connectors don't work well) - shape = bottom_hull( - [ - left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1), - carbonfet_thumb_bl_place(translate(thumb_post_tr(), wall_locate2(-0.3, 1))), - carbonfet_thumb_bl_place(translate(thumb_post_tr(), wall_locate3(-0.3, 1))), - ] - ) - - shape = shape.union( - hull_from_shapes( - [ - left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1), - carbonfet_thumb_bl_place(translate(thumb_post_tr(), wall_locate2(-0.3, 1))), - carbonfet_thumb_bl_place(translate(thumb_post_tr(), wall_locate3(-0.3, 1))), - carbonfet_thumb_ml_place(thumb_post_tl()), - ] - )) - - shape = shape.union( - hull_from_shapes( - [ - left_key_place(web_post(), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate1(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate2(-1, 0)), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate3(-1, 0)), cornerrow, -1), - carbonfet_thumb_ml_place(thumb_post_tl()), - ] - )) - - shape = shape.union( - hull_from_shapes( - [ - left_key_place(web_post(), cornerrow, -1), - left_key_place(translate(web_post(), wall_locate1(-1, 0)), cornerrow, -1), - key_place(web_post_bl(), 0, cornerrow), - carbonfet_thumb_ml_place(thumb_post_tl()), - ] - )) - - shape = shape.union( - hull_from_shapes( - [ - carbonfet_thumb_bl_place(thumb_post_tr()), - carbonfet_thumb_bl_place(translate(thumb_post_tr(), wall_locate1(-0.3, 1))), - carbonfet_thumb_bl_place(translate(thumb_post_tr(), wall_locate2(-0.3, 1))), - carbonfet_thumb_bl_place(translate(thumb_post_tr(), wall_locate3(-0.3, 1))), - carbonfet_thumb_ml_place(thumb_post_tl()), - ] - )) - - return shape - -def case_walls(): - print('case_walls()') - shape = cq.Workplane('XY') - return ( - union([ - shape, - back_wall(), - left_wall(), - right_wall(), - front_wall(), - thumb_walls(), - thumb_connection(), - ]) - ) - - -rj9_start = list( - np.array([0, -3, 0]) - + np.array( - key_position( - list(np.array(wall_locate3(0, 1)) + np.array([0, (mount_height / 2), 0])), - 0, - 0, - ) - ) -) - -rj9_position = (rj9_start[0], rj9_start[1], 11) - - -def rj9_cube(): - print('rj9_cube()') - shape = cq.Workplane("XY").box(14.78, 13, 22.38) - - return shape - - -def rj9_space(): - print('rj9_space()') - return rj9_cube().translate(rj9_position) - - -def rj9_holder(): - print('rj9_holder()') - shape = cq.Workplane("XY").box(10.78, 9, 18.38).translate((0, 2, 0)) - shape = shape.union(cq.Workplane("XY").box(10.78, 13, 5).translate((0, 0, 5))) - shape = rj9_cube().cut(shape) - shape = shape.translate(rj9_position) - - return shape - - -usb_holder_position = key_position( - list(np.array(wall_locate2(0, 1)) + np.array([0, (mount_height / 2), 0])), 1, 0 -) -usb_holder_size = [6.5, 10.0, 13.6] -usb_holder_thickness = 4 - - -def usb_holder(): - print('usb_holder()') - shape = cq.Workplane("XY").box( - usb_holder_size[0] + usb_holder_thickness, - usb_holder_size[1], - usb_holder_size[2] + usb_holder_thickness, - ) - shape = shape.translate( - ( - usb_holder_position[0], - usb_holder_position[1], - (usb_holder_size[2] + usb_holder_thickness) / 2, - ) - ) - return shape - - -def usb_holder_hole(): - print('usb_holder_hole()') - shape = cq.Workplane("XY").box(*usb_holder_size) - shape = shape.translate( - ( - usb_holder_position[0], - usb_holder_position[1], - (usb_holder_size[2] + usb_holder_thickness) / 2, - ) - ) - return shape - - -external_start = list( - # np.array([0, -3, 0]) - np.array([external_holder_width / 2, 0, 0]) - + np.array( - key_position( - list(np.array(wall_locate3(0, 1)) + np.array([0, (mount_height / 2), 0])), - 0, - 0, - ) - ) -) - -def external_mount_hole(): - print('external_mount_hole()') - shape = cq.Workplane("XY").box(external_holder_width, 20.0, external_holder_height) - shape = shape.translate( - ( - external_start[0] + external_holder_xoffset, - external_start[1], - external_holder_height / 2, - ) - ) - return shape - - - -def oled_sliding_mount_frame(): - mount_ext_width = oled_mount_width + 2 * oled_mount_rim - mount_ext_height = ( - oled_mount_height + 2 * oled_edge_overlap_end - + oled_edge_overlap_connector + oled_edge_overlap_clearance - + 2 * oled_mount_rim - ) - mount_ext_up_height = oled_mount_height + 2 * oled_mount_rim - top_hole_start = -mount_ext_height / 2.0 + oled_mount_rim + oled_edge_overlap_end + oled_edge_overlap_connector - top_hole_length = oled_mount_height - - hole = cq.Workplane("XY").box(mount_ext_width, mount_ext_up_height, oled_mount_cut_depth + .01) - hole = hole.translate((0., top_hole_start + top_hole_length / 2, 0.)) - - hole_down = cq.Workplane("XY").box(mount_ext_width, mount_ext_height, oled_mount_depth + oled_mount_cut_depth / 2) - hole_down = hole_down.translate((0., 0., -oled_mount_cut_depth / 4)) - hole = hole.union(hole_down) - - shape = cq.Workplane("XY").box(mount_ext_width, mount_ext_height, oled_mount_depth) - - conn_hole_start = -mount_ext_height / 2.0 + oled_mount_rim - conn_hole_length = ( - oled_edge_overlap_end + oled_edge_overlap_connector - + oled_edge_overlap_clearance + oled_thickness - ) - conn_hole = cq.Workplane("XY").box(oled_mount_width, conn_hole_length + .01, oled_mount_depth) - conn_hole = conn_hole.translate(( - 0, - conn_hole_start + conn_hole_length / 2, - -oled_edge_overlap_thickness - )) - - end_hole_length = ( - oled_edge_overlap_end + oled_edge_overlap_clearance - ) - end_hole_start = mount_ext_height / 2.0 - oled_mount_rim - end_hole_length - end_hole = cq.Workplane("XY").box(oled_mount_width, end_hole_length + .01, oled_mount_depth) - end_hole = end_hole.translate(( - 0, - end_hole_start + end_hole_length / 2, - -oled_edge_overlap_thickness - )) - - top_hole_start = -mount_ext_height / 2.0 + oled_mount_rim + oled_edge_overlap_end + oled_edge_overlap_connector - top_hole_length = oled_mount_height - top_hole = cq.Workplane("XY").box(oled_mount_width, top_hole_length, oled_edge_overlap_thickness + oled_thickness - oled_edge_chamfer) - top_hole = top_hole.translate(( - 0, - top_hole_start + top_hole_length / 2, - (oled_mount_depth - oled_edge_overlap_thickness - oled_thickness - oled_edge_chamfer) / 2.0 - )) - - top_chamfer_1 = cq.Workplane("XY").box( - oled_mount_width, - top_hole_length, - 0.01 - ) - top_chamfer_2 = cq.Workplane("XY").box( - oled_mount_width + 2 * oled_edge_chamfer, - top_hole_length + 2 * oled_edge_chamfer, - 0.01 - ) - top_chamfer_1 = top_chamfer_1.translate((0, 0, -oled_edge_chamfer - .05)) - - # top_chamfer_1 = sl.hull()(top_chamfer_1, top_chamfer_2) - top_chamfer_1 = hull_from_shapes([top_chamfer_1, top_chamfer_2]) - - top_chamfer_1 = top_chamfer_1.translate(( - 0, - top_hole_start + top_hole_length / 2, - oled_mount_depth / 2.0 + .05 - )) - - top_hole = top_hole.union(top_chamfer_1) - - shape = shape.cut(conn_hole) - shape = shape.cut(top_hole) - shape = shape.cut(end_hole) - - shape = rotate(shape, oled_mount_rotation_xyz) - shape = translate(shape, - ( - oled_mount_location_xyz[0], - oled_mount_location_xyz[1], - oled_mount_location_xyz[2], - ) - ) - - hole = rotate(hole, oled_mount_rotation_xyz) - hole = translate(hole, - ( - oled_mount_location_xyz[0], - oled_mount_location_xyz[1], - oled_mount_location_xyz[2], - ) - ) - return hole, shape - - -def oled_clip_mount_frame(): - mount_ext_width = oled_mount_width + 2 * oled_mount_rim - mount_ext_height = ( - oled_mount_height + 2 * oled_clip_thickness - + 2 * oled_clip_undercut + 2 * oled_clip_overhang + 2 * oled_mount_rim - ) - hole = cq.Workplane("XY").box(mount_ext_width, mount_ext_height, oled_mount_cut_depth + .01) - - shape = cq.Workplane("XY").box(mount_ext_width, mount_ext_height, oled_mount_depth) - shape = shape.cut(cq.Workplane("XY").box(oled_mount_width, oled_mount_height, oled_mount_depth + .1)) - - clip_slot = cq.Workplane("XY").box( - oled_clip_width + 2 * oled_clip_width_clearance, - oled_mount_height + 2 * oled_clip_thickness + 2 * oled_clip_overhang, - oled_mount_depth + .1 - ) - - shape = shape.cut(clip_slot) - - clip_undercut = cq.Workplane("XY").box( - oled_clip_width + 2 * oled_clip_width_clearance, - oled_mount_height + 2 * oled_clip_thickness + 2 * oled_clip_overhang + 2 * oled_clip_undercut, - oled_mount_depth + .1 - ) - - clip_undercut = clip_undercut.translate((0., 0., oled_clip_undercut_thickness)) - shape = shape.cut(clip_undercut) - - plate = cq.Workplane("XY").box( - oled_mount_width + .1, - oled_mount_height - 2 * oled_mount_connector_hole, - oled_mount_depth - oled_thickness - ) - plate = plate.translate((0., 0., -oled_thickness / 2.0)) - shape = shape.union(plate) - - shape = rotate(shape, oled_mount_rotation_xyz) - shape = translate(shape, - ( - oled_mount_location_xyz[0], - oled_mount_location_xyz[1], - oled_mount_location_xyz[2], - ) - ) - - hole = rotate(hole, oled_mount_rotation_xyz) - hole = translate(hole, - ( - oled_mount_location_xyz[0], - oled_mount_location_xyz[1], - oled_mount_location_xyz[2], - ) - ) - - return hole, shape - - -def oled_clip(): - mount_ext_width = oled_mount_width + 2 * oled_mount_rim - mount_ext_height = ( - oled_mount_height + 2 * oled_clip_thickness + 2 * oled_clip_overhang - + 2 * oled_clip_undercut + 2 * oled_mount_rim - ) - - oled_leg_depth = oled_mount_depth + oled_clip_z_gap - - shape = cq.Workplane("XY").box(mount_ext_width - .1, mount_ext_height - .1, oled_mount_bezel_thickness) - shape = translate(shape, (0., 0., oled_mount_bezel_thickness / 2.)) - - hole_1 = cq.Workplane("XY").box( - oled_screen_width + 2 * oled_mount_bezel_chamfer, - oled_screen_length + 2 * oled_mount_bezel_chamfer, - .01 - ) - hole_2 = cq.Workplane("XY").box(oled_screen_width, oled_screen_length, 2.05 * oled_mount_bezel_thickness) - hole = hull_from_shapes([hole_1, hole_2]) - - shape = shape.cut(translate(hole, (0., 0., oled_mount_bezel_thickness))) - - clip_leg = cq.Workplane("XY").box(oled_clip_width, oled_clip_thickness, oled_leg_depth) - clip_leg = translate(clip_leg, ( - 0., - 0., - # (oled_mount_height+2*oled_clip_overhang+oled_clip_thickness)/2, - -oled_leg_depth / 2. - )) - - latch_1 = cq.Workplane("XY").box( - oled_clip_width, - oled_clip_overhang + oled_clip_thickness, - .01 - ) - latch_2 = cq.Workplane("XY").box( - oled_clip_width, - oled_clip_thickness / 2, - oled_clip_extension - ) - latch_2 = translate(latch_2, ( - 0., - -(-oled_clip_thickness / 2 + oled_clip_thickness + oled_clip_overhang) / 2, - -oled_clip_extension / 2 - )) - latch = hull_from_shapes([latch_1, latch_2]) - latch = translate(latch, ( - 0., - oled_clip_overhang / 2, - -oled_leg_depth - )) - - clip_leg = union([clip_leg, latch]) - - clip_leg = translate(clip_leg, ( - 0., - (oled_mount_height + 2 * oled_clip_overhang + oled_clip_thickness) / 2 - oled_clip_y_gap, - 0. - )) - - shape = union([shape, clip_leg, mirror(clip_leg, 'XZ')]) - - return shape - - -def oled_undercut_mount_frame(): - mount_ext_width = oled_mount_width + 2 * oled_mount_rim - mount_ext_height = oled_mount_height + 2 * oled_mount_rim - hole = cq.Workplane("XY").box(mount_ext_width, mount_ext_height, oled_mount_cut_depth + .01) - - shape = cq.Workplane("XY").box(mount_ext_width, mount_ext_height, oled_mount_depth) - shape = shape.cut(cq.Workplane("XY").box(oled_mount_width, oled_mount_height, oled_mount_depth + .1)) - undercut = cq.Workplane("XY").box( - oled_mount_width + 2 * oled_mount_undercut, - oled_mount_height + 2 * oled_mount_undercut, - oled_mount_depth) - undercut = translate(undercut, (0., 0., -oled_mount_undercut_thickness)) - shape = shape.cut(undercut) - - shape = rotate(shape, oled_mount_rotation_xyz) - shape = translate(shape, ( - oled_mount_location_xyz[0], - oled_mount_location_xyz[1], - oled_mount_location_xyz[2], - ) - ) - - hole = rotate(hole, oled_mount_rotation_xyz) - hole = translate(hole, ( - oled_mount_location_xyz[0], - oled_mount_location_xyz[1], - oled_mount_location_xyz[2], - ) - ) - - return hole, shape - - -teensy_width = 20 -teensy_height = 12 -teensy_length = 33 -teensy2_length = 53 -teensy_pcb_thickness = 2 -teensy_holder_width = 7 + teensy_pcb_thickness -teensy_holder_height = 6 + teensy_width -teensy_offset_height = 5 -teensy_holder_top_length = 18 -teensy_top_xy = key_position(wall_locate3(-1, 0), 0, centerrow - 1) -teensy_bot_xy = key_position(wall_locate3(-1, 0), 0, centerrow + 1) -teensy_holder_length = teensy_top_xy[1] - teensy_bot_xy[1] -teensy_holder_offset = -teensy_holder_length / 2 -teensy_holder_top_offset = (teensy_holder_top_length / 2) - teensy_holder_length - - -def teensy_holder(): - print('teensy_holder()') - s1 = cq.Workplane("XY").box(3, teensy_holder_length, 6 + teensy_width) - s1 = translate(s1, [1.5, teensy_holder_offset, 0]) - - s2 = cq.Workplane("XY").box(teensy_pcb_thickness, teensy_holder_length, 3) - s2 = translate(s2, - ( - (teensy_pcb_thickness / 2) + 3, - teensy_holder_offset, - -1.5 - (teensy_width / 2), - ) - ) - - s3 = cq.Workplane("XY").box(teensy_pcb_thickness, teensy_holder_top_length, 3) - s3 = translate(s3, - [ - (teensy_pcb_thickness / 2) + 3, - teensy_holder_top_offset, - 1.5 + (teensy_width / 2), - ] - ) - - s4 = cq.Workplane("XY").box(4, teensy_holder_top_length, 4) - s4 = translate(s4, - [teensy_pcb_thickness + 5, teensy_holder_top_offset, 1 + (teensy_width / 2)] - ) - - shape = union((s1, s2, s3, s4)) - - shape = shape.translate([-teensy_holder_width, 0, 0]) - shape = shape.translate([-1.4, 0, 0]) - shape = translate(shape, - [teensy_top_xy[0], teensy_top_xy[1] - 1, (6 + teensy_width) / 2] - ) - - return shape - - -def screw_insert_shape(bottom_radius, top_radius, height): - print('screw_insert_shape()') - if bottom_radius == top_radius: - base = cq.Workplane('XY').union(cq.Solid.makeCylinder(radius=bottom_radius, height=height)).translate( - (0, 0, -height / 2) - ) - else: - base = cq.Workplane('XY').union( - cq.Solid.makeCone(radius1=bottom_radius, radius2=top_radius, height=height)).translate((0, 0, -height / 2)) - - shape = union(( - base, - cq.Workplane('XY').union(cq.Solid.makeSphere(top_radius)).translate((0, 0, (height / 2))), - )) - return shape - - -def screw_insert(column, row, bottom_radius, top_radius, height): - print('screw_insert()') - shift_right = column == lastcol - shift_left = column == 0 - shift_up = (not (shift_right or shift_left)) and (row == 0) - shift_down = (not (shift_right or shift_left)) and (row >= lastrow) - - if screws_offset == 'INSIDE': - # print('Shift Inside') - shift_left_adjust = wall_base_x_thickness - shift_right_adjust = -wall_base_x_thickness/2 - shift_down_adjust = -wall_base_y_thickness/2 - shift_up_adjust = -wall_base_y_thickness/3 - - elif screws_offset == 'OUTSIDE': - print('Shift Outside') - shift_left_adjust = 0 - shift_right_adjust = wall_base_x_thickness/2 - shift_down_adjust = wall_base_y_thickness*2/3 - shift_up_adjust = wall_base_y_thickness*2/3 - - else: - # print('Shift Origin') - shift_left_adjust = 0 - shift_right_adjust = 0 - shift_down_adjust = 0 - shift_up_adjust = 0 - - if shift_up: - position = key_position( - list(np.array(wall_locate2(0, 1)) + np.array([0, (mount_height / 2) + shift_up_adjust, 0])), - column, - row, - ) - elif shift_down: - position = key_position( - list(np.array(wall_locate2(0, -1)) - np.array([0, (mount_height / 2) + shift_down_adjust, 0])), - column, - row, - ) - elif shift_left: - position = list( - np.array(left_key_position(row, 0)) + np.array(wall_locate3(-1, 0)) + np.array((shift_left_adjust,0,0)) - ) - else: - position = key_position( - list(np.array(wall_locate2(1, 0)) + np.array([(mount_height / 2), 0, 0]) + np.array((shift_right_adjust,0,0)) - ), - column, - row, - ) - - - shape = screw_insert_shape(bottom_radius, top_radius, height) - shape = shape.translate([position[0], position[1], height / 2]) - - return shape - - -def screw_insert_all_shapes(bottom_radius, top_radius, height): - print('screw_insert_all_shapes()') - shape = ( - screw_insert(0, 0, bottom_radius, top_radius, height), - screw_insert(0, lastrow-1, bottom_radius, top_radius, height), - screw_insert(3, lastrow, bottom_radius, top_radius, height), - screw_insert(3, 0, bottom_radius, top_radius, height), - screw_insert(lastcol, 0, bottom_radius, top_radius, height), - screw_insert(lastcol, lastrow-1, bottom_radius, top_radius, height), - ) - - return shape - - -screw_insert_height = 3.8 -screw_insert_bottom_radius = 5.31 / 2 -screw_insert_top_radius = 5.1 / 2 -screw_insert_holes = screw_insert_all_shapes( - screw_insert_bottom_radius, screw_insert_top_radius, screw_insert_height -) -screw_insert_outers = screw_insert_all_shapes( - screw_insert_bottom_radius + 1.6, - screw_insert_top_radius + 1.6, - screw_insert_height + 1.5, -) -screw_insert_screw_holes = screw_insert_all_shapes(1.7, 1.7, 350) - -wire_post_height = 7 -wire_post_overhang = 3.5 -wire_post_diameter = 2.6 - - -def wire_post(direction, offset): - print('wire_post()') - s1 = cq.Workplane("XY").box( - wire_post_diameter, wire_post_diameter, wire_post_height - ) - s1 = translate(s1, [0, -wire_post_diameter * 0.5 * direction, 0]) - - s2 = cq.Workplane("XY").box( - wire_post_diameter, wire_post_overhang, wire_post_diameter - ) - s2 = translate(s2, - [0, -wire_post_overhang * 0.5 * direction, -wire_post_height / 2] - ) - - shape = union((s1, s2)) - shape = shape.translate([0, -offset, (-wire_post_height / 2) + 3]) - shape = rotate(shape, [-alpha / 2, 0, 0]) - shape = shape.translate((3, -mount_height / 2, 0)) - - return shape - - -def wire_posts(): - print('wire_posts()') - shape = thumb_ml_place(wire_post(1, 0).translate([-5, 0, -2])) - shape = shape.union(thumb_ml_place(wire_post(-1, 6).translate([0, 0, -2.5]))) - shape = shape.union(thumb_ml_place(wire_post(1, 0).translate([5, 0, -2]))) - - for column in range(lastcol): - for row in range(lastrow - 1): - shape = union([ - shape, - key_place(wire_post(1, 0).translate([-5, 0, 0]), column, row), - key_place(wire_post(-1, 6).translate([0, 0, 0]), column, row), - key_place(wire_post(1, 0).translate([5, 0, 0]), column, row), - ]) - return shape - - -def model_side(side="right"): - print('model_right()') - shape = cq.Workplane('XY').union(key_holes(side=side)) - if debug_exports: - cq.exporters.export(w=shape, fname=path.join(r"..", "things", r"debug_key_plates.step"), exportType='STEP') - connector_shape = connectors() - shape = shape.union(connector_shape) - if debug_exports: - cq.exporters.export(w=shape, fname=path.join(r"..", "things", r"debug_connector_shape.step"), exportType='STEP') - thumb_shape = thumb(side=side) - if debug_exports: - cq.exporters.export(w=thumb_shape, fname=path.join(r"..", "things", r"debug_thumb_shape.step"), exportType='STEP') - shape = shape.union(thumb_shape) - thumb_connector_shape = thumb_connectors() - shape = shape.union(thumb_connector_shape) - if debug_exports: - cq.exporters.export(w=shape, fname=path.join(r"..", "things", r"debug_thumb_connector_shape.step"), exportType='STEP') - walls_shape = case_walls() - if debug_exports: - cq.exporters.export(w=walls_shape, fname=path.join(r"..", "things", r"debug_walls_shape.step"), exportType='STEP') - s2 = cq.Workplane('XY').union(walls_shape) - s2 = union([s2, *screw_insert_outers]) - - if controller_mount_type in ['RJ9_USB_TEENSY']: - s2 = s2.union(teensy_holder()) - - if controller_mount_type in ['RJ9_USB_TEENSY', 'RJ9_USB_WALL']: - s2 = s2.union(usb_holder()) - s2 = s2.cut(usb_holder_hole()) - - if controller_mount_type in ['RJ9_USB_TEENSY', 'RJ9_USB_WALL']: - s2 = s2.cut(rj9_space()) - - if controller_mount_type in ['EXTERNAL']: - s2 = s2.cut(external_mount_hole()) - - s2 = s2.cut(union(screw_insert_holes)) - shape = shape.union(s2) - # shape = shape.union(s2, tol=.01) - - if controller_mount_type in ['RJ9_USB_TEENSY', 'RJ9_USB_WALL']: - shape = shape.union(rj9_holder()) - - if oled_mount_type == "UNDERCUT": - hole, frame = oled_undercut_mount_frame() - shape = shape.cut(hole) - shape = union([shape, frame]) - - elif oled_mount_type == "SLIDING": - hole, frame = oled_sliding_mount_frame() - shape = shape.cut(hole) - shape = union([shape, frame]) - - elif oled_mount_type == "CLIP": - hole, frame = oled_clip_mount_frame() - shape = shape.cut(hole) - shape = union([shape, frame]) - - block = cq.Workplane("XY").box(350, 350, 40) - block = block.translate((0, 0, -20)) - shape = shape.cut(block) - - if show_caps: - shape = shape.add(thumbcaps()) - shape = shape.add(caps()) - - if side == "left": - shape = shape.mirror('YZ') - - return shape - - -def baseplate(): - # shape = mod_r - shape = union([case_walls(), *screw_insert_outers]) - # tool = translate(screw_insert_screw_holes(), [0, 0, -10]) - tool = screw_insert_screw_holes - for item in tool: - item = translate(item, [0, 0, -10]) - shape = shape.cut(item) - - shape = shape.translate((0, 0, -0.01)) - - square = cq.Workplane('XY').rect(1000, 1000) - for wire in square.wires().objects: - plane = cq.Workplane('XY').add(cq.Face.makeFromWires(wire)) - - shape = shape.intersect(plane) - - outside = shape.vertices(cq.DirectionMinMaxSelector(cq.Vector(1, 0, 0), True)).objects[0] - - sizes = [] - max_val = 0 - inner_index = 0 - base_wires = shape.wires().objects - for i_wire, wire in enumerate(base_wires): - is_outside = False - for vert in wire.Vertices(): - if vert.toTuple() == outside.toTuple(): - outer_wire = wire - outer_index = i_wire - is_outside = True - sizes.append(0) - if not is_outside: - sizes.append(len(wire.Vertices())) - if sizes[-1]>max_val: - inner_index = i_wire - max_val = sizes[-1] - print(sizes) - inner_wire = base_wires[inner_index] - - inner_plate = cq.Workplane('XY').add(cq.Face.makeFromWires(inner_wire)) - shape.add(inner_plate) - - holes = [] - for i in range(len(base_wires)): - if i not in [inner_index, outer_index]: - holes.append(base_wires[i]) - - shape = cq.Workplane('XY').add(cq.Solid.extrudeLinear(outer_wire, holes, cq.Vector(0, 0, -5))) - - return shape - - - -# base = baseplate() -# cq.exporters.export(w=base, fname=path.join(r"..", "things", save_dir, config_name + r"_plate.step"), exportType='STEP') -# cq.exporters.export(w=base, fname=path.join(r"..", "things", save_dir, config_name + r"_plate.dxf"), exportType='DXF') - -mod_r = model_side(side="right") -cq.exporters.export(w=mod_r, fname=path.join(r"..", "things", save_dir, config_name + r"_right.step"), exportType='STEP') - -if symmetry == "asymmetric": - mod_l = model_side(side="left") - cq.exporters.export(w=mod_l, fname=path.join(r"..", "things", save_dir, config_name + r"_left.step"), exportType='STEP') - -else: - cq.exporters.export(w=mod_r.mirror('YZ'), fname=path.join(r"..", "things", save_dir, config_name + r"_left.step"), exportType='STEP') - - -base = baseplate() -cq.exporters.export(w=base, fname=path.join(r"..", "things", save_dir, config_name + r"_plate.step"), exportType='STEP') -cq.exporters.export(w=base, fname=path.join(r"..", "things", save_dir, config_name + r"_plate.dxf"), exportType='DXF') - - -if oled_mount_type == 'UNDERCUT': - cq.exporters.export(w=oled_undercut_mount_frame()[1], fname=path.join(r"..", "things", save_dir, config_name + r"_oled_undercut_test.step"), exportType='STEP') - -if oled_mount_type == 'SLIDING': - cq.exporters.export(w=oled_sliding_mount_frame()[1], fname=path.join(r"..", "things", save_dir, config_name + r"_oled_sliding_test.step"), exportType='STEP') - -if oled_mount_type == 'CLIP': - oled_mount_location_xyz = (0.0, 0.0, -oled_mount_depth / 2) - oled_mount_rotation_xyz = (0.0, 0.0, 0.0) - cq.exporters.export(w=oled_clip(), fname=path.join(r"..", "things", save_dir, config_name + r"_oled_clip.step"), exportType='STEP') - cq.exporters.export(w=oled_clip_mount_frame()[1], - fname=path.join(r"..", "things", save_dir, config_name + r"_oled_clip_test.step"), exportType='STEP') - cq.exporters.export(w=union((oled_clip_mount_frame()[1], oled_clip())), - fname=path.join(r"..", "things", save_dir, config_name + r"_oled_clip_assy_test.step"), exportType='STEP') |