summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Shreve <j.a.shreve@gmail.com>2021-07-08 22:05:34 -0400
committerJoshua Shreve <j.a.shreve@gmail.com>2021-07-08 22:05:34 -0400
commite3bf24d17cdbda9ace5dbcae257c5c856ef984d9 (patch)
tree6bcfbc6741f47feac4faad63a59011001fc3da82
parent7746b122ed99c5e31e8334d26817e4c00ac76560 (diff)
Added helper files to remove the cadquery / solid python helpers from the main file. Improved notch and added holes around key plate for mounting. Still WIP, but should be functional.
-rw-r--r--src/dactyl_manuform.py296
-rw-r--r--src/dactyl_manuform_solid.py2373
-rw-r--r--src/generate_configuration.py4
-rw-r--r--src/helpers_cadquery.py184
-rw-r--r--src/helpers_solid.py126
-rw-r--r--src/model_builder.py16
-rw-r--r--src/run_config.json12
7 files changed, 324 insertions, 2687 deletions
diff --git a/src/dactyl_manuform.py b/src/dactyl_manuform.py
index 2753064..1265d5b 100644
--- a/src/dactyl_manuform.py
+++ b/src/dactyl_manuform.py
@@ -118,301 +118,9 @@ def column_offset(column: int) -> list:
####################################################
if ENGINE == 'cadquery':
- import cadquery as cq
- def box(width, height, depth):
- return cq.Workplane("XY").box(width, height, depth)
-
- def cylinder(radius, height, segments=100):
- return cq.Workplane("XY").union(cq.Solid.makeCylinder(radius=radius, height=height))
-
- def sphere(radius):
- return cq.Workplane('XY').union(cq.Solid.makeSphere(radius))
-
- def cone(r1, r2, height):
- return cq.Workplane('XY').union(
- cq.Solid.makeCone(radius1=r1, radius2=r2, height=height))
-
- 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 add(shapes):
- print('union()')
- shape = None
- for item in shapes:
- if shape is None:
- shape = item
- else:
- shape = shape.add(item)
- return shape
-
-
- def difference(shape, shapes):
- print('difference()')
- for item in shapes:
- shape = shape.cut(item)
- return shape
-
-
- def intersect(shape1, shape2):
- return shape1.intersect(shape2)
-
-
- 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 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 polyline(point_list):
- return cq.Workplane('XY').polyline(point_list)
-
- # def project_to_plate():
- # square = cq.Workplane('XY').rect(1000, 1000)
- # for wire in square.wires().objects:
- # plane = cq.Workplane('XY').add(cq.Face.makeFromWires(wire))
-
-
- def extrude_poly(outer_poly, inner_polys=None, height=1):#vector=(0,0,1)):
- outer_wires = cq.Wire.assembleEdges(outer_poly.edges().objects)
- inner_wires = []
- if inner_polys is not None:
- for item in inner_polys:
- inner_wires.append(cq.Wire.assembleEdges(item.edges().objects))
-
- return cq.Workplane('XY').add(cq.Solid.extrudeLinear(outerWire=outer_wires, innerWires=inner_wires, vecNormal=cq.Vector(0, 0, height)))
-
-
- def import_file(filename):
- return cq.Workplane('XY').add(cq.importers.importShape(
- cq.exporters.ExportTypes.STEP,
- filename+".step"))
-
-
- def export_file(shape, fname):
- cq.exporters.export(w=shape, fname=fname+".step",
- exportType='STEP')
-
- def export_dxf(shape, fname):
- cq.exporters.export(w=shape, fname=fname+".dxf",
- exportType='DXF')
-
+ from src.helpers_cadquery import *
else:
- import solid as sl
-
-
- def box(width, height, depth):
- return sl.cube([width, height, depth], center=True)
-
-
- def cylinder(radius, height, segments=100):
- return sl.cylinder(r=radius, h=height, segments=segments, center=True)
-
-
- def sphere(radius):
- return sl.sphere(radius)
-
-
- def cone(r1, r2, height):
- return sl.cylinder(r1=r1, r2=r2, h=height)#, center=True)
-
-
- def rotate(shape, angle):
- return sl.rotate(angle)(shape)
-
-
- def translate(shape, vector):
- return sl.translate(tuple(vector))(shape)
-
-
- def mirror(shape, plane=None):
- print('mirror()')
- planes={
- 'XY': [0, 0, 1],
- 'YX': [0, 0, -1],
- 'XZ': [0, 1, 0],
- 'ZX': [0, -1, 0],
- 'YZ': [1, 0, 0],
- 'ZY': [-1, 0, 0],
- }
- return sl.mirror(planes[plane])(shape)
-
-
- def union(shapes):
- print('union()')
- shape = None
- for item in shapes:
- if shape is None:
- shape = item
- else:
- shape += item
- return shape
-
-
- def add(shapes):
- print('union()')
- shape = None
- for item in shapes:
- if shape is None:
- shape = item
- else:
- shape += item
- return shape
-
-
- def difference(shape, shapes):
- print('difference()')
- for item in shapes:
- shape -= item
- return shape
-
-
- def intersect(shape1, shape2):
- return sl.intersect()(shape1, shape2)
-
- def hull_from_points(points):
- return sl.hull()(*points)
-
- def hull_from_shapes(shapes, points=None):
- hs = []
- if points is not None:
- hs.extend(points)
- if shapes is not None:
- hs.extend(shapes)
- return sl.hull()(*hs)
-
- def tess_hull(shapes, sl_tol=.5, sl_angTol=1):
- return sl.hull()(*shapes)
-
- def triangle_hulls(shapes):
- print('triangle_hulls()')
- hulls = []
- for i in range(len(shapes) - 2):
- hulls.append(hull_from_shapes(shapes[i: (i + 3)]))
-
- return union(hulls)
-
-
- def polyline(point_list):
- return sl.polygon(point_list)
-
-
- # def project_to_plate():
- # square = cq.Workplane('XY').rect(1000, 1000)
- # for wire in square.wires().objects:
- # plane = cq.Workplane('XY').add(cq.Face.makeFromWires(wire))
-
- def extrude_poly(outer_poly, inner_polys=None, height=1):
- if inner_polys is not None:
- return sl.linear_extrude(height=height, twist=0, convexity=0, center=True)(outer_poly, *inner_polys)
- else:
- return sl.linear_extrude(height=height, twist=0, convexity=0, center=True)(outer_poly)
-
-
- def import_file(fname):
- return sl.import_(fname+".stl")
-
-
- def export_file(shape, fname):
- print("EXPORTING TO {}".format(fname+".scad"))
- sl.scad_render_to_file(shape, fname+".scad")
-
-
- def export_dxf(shape, fname):
- pass
+ from src.helpers_solid import *
####################################################
# END HELPER FUNCTIONS
diff --git a/src/dactyl_manuform_solid.py b/src/dactyl_manuform_solid.py
deleted file mode 100644
index 07e2450..0000000
--- a/src/dactyl_manuform_solid.py
+++ /dev/null
@@ -1,2373 +0,0 @@
-import solid as sl
-import numpy as np
-from numpy import pi
-import os.path as path
-import os
-import json
-
-def deg2rad(degrees: float) -> float:
- return degrees * pi / 180
-
-
-def rad2deg(rad: float) -> float:
- return rad * 180 / pi
-
-
-
-## 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.stl")
- 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]
-
-
-def single_plate(cylinder_segments=100, side="right"):
- if plate_style in ['NUB', 'HS_NUB']:
- top_wall = sl.cube([mount_width, 1.5, plate_thickness], center=True)
- top_wall = sl.translate(
- (0, (1.5 / 2) + (keyswitch_height / 2), plate_thickness / 2)
- )(top_wall)
-
- left_wall = sl.cube([1.5, mount_height, plate_thickness], center=True)
- left_wall = sl.translate(
- ((1.5 / 2) + (keyswitch_width / 2), 0, plate_thickness / 2)
- )(left_wall)
-
- side_nub = sl.cylinder(1, 2.75, segments=cylinder_segments, center=True)
- side_nub = sl.rotate(rad2deg(pi / 2), [1, 0, 0])(side_nub)
- side_nub = sl.translate((keyswitch_width / 2, 0, 1))(side_nub)
- nub_cube = sl.cube([1.5, 2.75, plate_thickness], center=True)
- nub_cube = sl.translate(
- ((1.5 / 2) + (keyswitch_width / 2), 0, plate_thickness / 2)
- )(nub_cube)
-
- side_nub = sl.hull()(side_nub, nub_cube)
-
- plate_half1 = top_wall + left_wall + side_nub
- plate_half2 = plate_half1
- plate_half2 = sl.mirror([0, 1, 0])(plate_half2)
- plate_half2 = sl.mirror([1, 0, 0])(plate_half2)
-
- plate = plate_half1 + plate_half2
-
-
- else: # 'HOLE' or default, square cutout for non-nub designs.
- plate = sl.cube([mount_width, mount_height, mount_thickness], center=True)
- plate = sl.translate((0.0, 0.0, mount_thickness / 2.0))(plate)
- shape_cut = sl.cube([keyswitch_width, keyswitch_height, mount_thickness * 2], center=True)
- shape_cut = sl.translate((0.0, 0.0, mount_thickness))(shape_cut)
- plate = sl.difference()(plate, shape_cut)
-
- if plate_style in ['UNDERCUT', 'HS_UNDERCUT']:
- undercut = sl.cube([
- keyswitch_width + 2 * clip_undercut,
- keyswitch_height + 2 * clip_undercut,
- mount_thickness
- ], center=True)
-
- undercut = sl.translate((0.0, 0.0, -clip_thickness + mount_thickness / 2.0))(undercut)
-
- plate = sl.difference()(plate, undercut)
-
- if plate_file is not None:
- socket = sl.import_(plate_file)
- socket = sl.translate([0.0, 0.0, plate_thickness + plate_offset])(socket)
-
- plate = sl.union()(plate, socket)
-
- if side == "left":
- plate = sl.mirror([-1, 0, 0])(plate)
-
- 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 = sl.polygon([[bw2, bl2], [bw2, -bl2], [-bw2, -bl2], [-bw2, bl2]])
- k1 = sl.linear_extrude(height=0.1, twist=0, convexity=0, center=True)(k1)
- k1 = sl.translate([0, 0, 0.05])(k1)
- k2 = sl.polygon([[pw2, pl2], [pw2, -pl2], [-pw2, -pl2], [-pw2, pl2]])
- k2 = sl.linear_extrude(height=0.1, twist=0, convexity=0, center=True)(k2)
- k2 = sl.translate([0, 0, 12.0])(k2)
- if m > 0:
- m1 = sl.polygon([[m, m], [m, -m], [-m, -m], [-m, m]])
- m1 = sl.linear_extrude(height=0.1, twist=0, convexity=0, center=True)(m1)
- m1 = sl.translate([0, 0, 6.0])(m1)
- key_cap = sl.hull()(k1, k2, m1)
- else:
- key_cap = sl.hull()(k1, k2)
-
- # key_cap = sl.translate([0, 0, 5 + plate_thickness])(key_cap)
- key_cap = sl.color([220 / 255, 163 / 255, 163 / 255, 1])(key_cap)
-
- return key_cap
-
-
-#########################
-## Placement Functions ##
-#########################
-
-
-def rotate_around_x(position, angle):
- # print((position, angle))
- 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((position, angle))
- 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 offset_for_column(col, row):
- if pinky_1_5U and (
- col == lastcol and row <= last_1_5U and row >= first_1_5U
- ):
- return 4.7625
- else:
- return 0
-
-def apply_key_geometry(
- shape,
- translate_fn,
- rotate_x_fn,
- rotate_y_fn,
- column,
- row,
- column_style=column_style,
-):
- 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, [offset_for_column(column, row), 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 translate(shape, xyz):
- return sl.translate(xyz)(shape)
-
-
-def x_rot(shape, angle):
- return sl.rotate(rad2deg(angle), [1, 0, 0])(shape)
-
-
-def y_rot(shape, angle):
- return sl.rotate(rad2deg(angle), [0, 1, 0])(shape)
-
-
-def key_place(shape, column, row):
- return apply_key_geometry(shape, translate, x_rot, y_rot, column, row)
-
-
-def add_translate(shape, xyz):
- vals = []
- for i in range(len(shape)):
- vals.append(shape[i] + xyz[i])
- return vals
-
-
-def key_position(position, column, row):
- return apply_key_geometry(
- position, add_translate, rotate_around_x, rotate_around_y, column, row
- )
-
-
-def key_holes(side="right"):
- hole = single_plate(side=side)
- holes = []
- for column in range(ncols):
- for row in range(nrows):
- if (column in [2, 3]) or (not row == lastrow):
- holes.append(key_place(hole, column, row))
-
- return sl.union()(*holes)
-
-
-def caps():
- caps = []
- for column in range(ncols):
- for row in range(nrows):
- if (column in [2, 3]) or (not row == lastrow):
- caps.append(key_place(sa_cap(), column, row))
-
- return sl.union()(*caps)
-
-
-####################
-## Web Connectors ##
-####################
-
-
-def web_post():
- post = sl.cube([post_size, post_size, web_thickness], center=True)
- post = sl.translate([0, 0, plate_thickness - (web_thickness / 2)])(post)
- return post
-
-
-post_adj = post_size / 2
-
-
-def web_post_tr(wide=False):
- if wide:
- w_divide = 1.2
- else:
- w_divide = 2.0
- return sl.translate(
- [(mount_width / w_divide) - post_adj, (mount_height / 2) - post_adj, 0]
- )(web_post())
-
-def web_post_tl(wide=False):
- if wide:
- w_divide = 1.2
- else:
- w_divide = 2.0
- return sl.translate(
- [-(mount_width / w_divide) + post_adj, (mount_height / 2) - post_adj, 0]
- )(web_post())
-
-
-def web_post_bl(wide=False):
- if wide:
- w_divide = 1.2
- else:
- w_divide = 2.0
- return sl.translate(
- [-(mount_width / w_divide) + post_adj, -(mount_height / 2) + post_adj, 0]
- )(web_post())
-
-
-def web_post_br(wide=False):
- if wide:
- w_divide = 1.2
- else:
- w_divide = 2.0
- return sl.translate(
- [(mount_width / w_divide) - post_adj, -(mount_height / 2) + post_adj, 0]
- )(web_post())
-
-
-
-
-def triangle_hulls(shapes):
- hulls = []
- for i in range(len(shapes) - 2):
- hulls.append(sl.hull()(*shapes[i: (i + 3)]))
-
- return sl.union()(*hulls)
-
-
-def 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 sl.union()(*hulls)
-
-
-############
-## Thumbs ##
-############
-
-
-def 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):
- shape = sl.rotate(10, [1, 0, 0])(shape)
- shape = sl.rotate(-23, [0, 1, 0])(shape)
- shape = sl.rotate(10, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-12, -16, 3])(shape)
- return shape
-
-
-def thumb_tl_place(shape):
- shape = sl.rotate(10, [1, 0, 0])(shape)
- shape = sl.rotate(-23, [0, 1, 0])(shape)
- shape = sl.rotate(10, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-32, -15, -2])(shape)
- return shape
-
-
-def thumb_mr_place(shape):
- shape = sl.rotate(-6, [1, 0, 0])(shape)
- shape = sl.rotate(-34, [0, 1, 0])(shape)
- shape = sl.rotate(48, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-29, -40, -13])(shape)
- return shape
-
-
-def thumb_ml_place(shape):
- shape = sl.rotate(6, [1, 0, 0])(shape)
- shape = sl.rotate(-34, [0, 1, 0])(shape)
- shape = sl.rotate(40, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-51, -25, -12])(shape)
- return shape
-
-
-def thumb_br_place(shape):
- shape = sl.rotate(-16, [1, 0, 0])(shape)
- shape = sl.rotate(-33, [0, 1, 0])(shape)
- shape = sl.rotate(54, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-37.8, -55.3, -25.3])(shape)
- return shape
-
-
-def thumb_bl_place(shape):
- shape = sl.rotate(-4, [1, 0, 0])(shape)
- shape = sl.rotate(-35, [0, 1, 0])(shape)
- shape = sl.rotate(52, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-56.3, -43.3, -23.5])(shape)
- return shape
-
-
-def thumb_1x_layout(shape):
- return sl.union()(
- thumb_mr_place(shape),
- thumb_ml_place(shape),
- thumb_br_place(shape),
- thumb_bl_place(shape),
- )
-
-
-def thumb_15x_layout(shape):
- return sl.union()(thumb_tr_place(shape), thumb_tl_place(shape))
-
-
-def double_plate_half():
- plate_height = (sa_double_length - mount_height) / 3
- top_plate = sl.cube([mount_width, plate_height, web_thickness], center=True)
- top_plate = sl.translate(
- [0, (plate_height + mount_height) / 2, plate_thickness - (web_thickness / 2)]
- )(top_plate)
- return top_plate
-
-
-def double_plate():
- top_plate = double_plate_half()
- return sl.union()(top_plate, sl.mirror([0, 1, 0])(top_plate))
-
-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))
- t15 = thumb_15x_layout(sl.rotate(pi / 2, [0, 0, 1])(sa_cap(1.5)))
- return t1 + t15
-
-
-
-def default_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 += thumb_15x_layout(double_plate())
-
- return shape
-
-
-def thumb_post_tr():
- return sl.translate(
- [(mount_width / 2) - post_adj, (mount_height / 1.15) - post_adj, 0]
- )(web_post())
-
-
-def thumb_post_tl():
- return sl.translate(
- [-(mount_width / 2) + post_adj, (mount_height / 1.15) - post_adj, 0]
- )(web_post())
-
-
-def thumb_post_bl():
- return sl.translate(
- [-(mount_width / 2) + post_adj, -(mount_height / 1.15) + post_adj, 0]
- )(web_post())
-
-
-def thumb_post_br():
- return sl.translate(
- [(mount_width / 2) - post_adj, -(mount_height / 1.15) + post_adj, 0]
- )(web_post())
-
-
-def default_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 sl.union()(*hulls)
-
-
-############################
-# MINI THUMB CLUSTER
-############################
-
-
-def mini_thumb_tr_place(shape):
- shape = sl.rotate(14, [1, 0, 0])(shape)
- shape = sl.rotate(-15, [0, 1, 0])(shape)
- shape = sl.rotate(10, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-15, -10, 5])(shape)
- return shape
-
-
-def mini_thumb_tl_place(shape):
- shape = sl.rotate(10, [1, 0, 0])(shape)
- shape = sl.rotate(-23, [0, 1, 0])(shape)
- shape = sl.rotate(25, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-35, -16, -2])(shape)
- return shape
-
-
-def mini_thumb_mr_place(shape):
- shape = sl.rotate(10, [1, 0, 0])(shape)
- shape = sl.rotate(-23, [0, 1, 0])(shape)
- shape = sl.rotate(25, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-23, -34, -6])(shape)
- return shape
-
-
-def mini_thumb_br_place(shape):
- shape = sl.rotate(6, [1, 0, 0])(shape)
- shape = sl.rotate(-34, [0, 1, 0])(shape)
- shape = sl.rotate(35, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-39, -43, -16])(shape)
- return shape
-
-
-def mini_thumb_bl_place(shape):
- shape = sl.rotate(6, [1, 0, 0])(shape)
- shape = sl.rotate(-32, [0, 1, 0])(shape)
- shape = sl.rotate(35, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-51, -25, -11.5])(shape)
- return shape
-
-
-def mini_thumb_1x_layout(shape):
- return sl.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 sl.union()(mini_thumb_tr_place(shape))
-
-
-def mini_thumbcaps():
- t1 = mini_thumb_1x_layout(sa_cap(1))
- t15 = mini_thumb_15x_layout(sl.rotate(pi / 2, [0, 0, 1])(sa_cap(1)))
- return t1 + 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 += mini_thumb_15x_layout(single_plate(side=side))
-
- return shape
-
-
-def mini_thumb_post_tr():
- return sl.translate(
- [(mount_width / 2) - post_adj, (mount_height / 2) - post_adj, 0]
- )(web_post())
-
-
-def mini_thumb_post_tl():
- return sl.translate(
- [-(mount_width / 2) + post_adj, (mount_height / 2) - post_adj, 0]
- )(web_post())
-
-
-def mini_thumb_post_bl():
- return sl.translate(
- [-(mount_width / 2) + post_adj, -(mount_height / 2) + post_adj, 0]
- )(web_post())
-
-
-def mini_thumb_post_br():
- return sl.translate(
- [(mount_width / 2) - post_adj, -(mount_height / 2) + post_adj, 0]
- )(web_post())
-
-
-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),
- ]
- )
- )
-
- # 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 sl.union()(*hulls)
-
-
-############################
-# Carbonfet THUMB CLUSTER
-############################
-
-
-def carbonfet_thumb_tl_place(shape):
- shape = sl.rotate(10, [1, 0, 0])(shape)
- shape = sl.rotate(-24, [0, 1, 0])(shape)
- shape = sl.rotate(10, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-13, -9.8, 4])(shape)
-
- return shape
-
-def carbonfet_thumb_tr_place(shape):
- shape = sl.rotate(6, [1, 0, 0])(shape)
- shape = sl.rotate(-24, [0, 1, 0])(shape)
- shape = sl.rotate(10, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-7.5, -29.5, 0])(shape)
- return shape
-
-def carbonfet_thumb_ml_place(shape):
- shape = sl.rotate(8, [1, 0, 0])(shape)
- shape = sl.rotate(-31, [0, 1, 0])(shape)
- shape = sl.rotate(14, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-30.5, -17, -6])(shape)
- return shape
-
-def carbonfet_thumb_mr_place(shape):
- shape = sl.rotate(4, [1, 0, 0])(shape)
- shape = sl.rotate(-31, [0, 1, 0])(shape)
- shape = sl.rotate(14, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-22.2, -41, -10.3])(shape)
- return shape
-
-def carbonfet_thumb_br_place(shape):
- shape = sl.rotate(2, [1, 0, 0])(shape)
- shape = sl.rotate(-37, [0, 1, 0])(shape)
- shape = sl.rotate(18, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-37, -46.4, -22])(shape)
- return shape
-
-def carbonfet_thumb_bl_place(shape):
- shape = sl.rotate(6, [1, 0, 0])(shape)
- shape = sl.rotate(-37, [0, 1, 0])(shape)
- shape = sl.rotate(18, [0, 0, 1])(shape)
- shape = sl.translate(thumborigin())(shape)
- shape = sl.translate([-47, -23, -19])(shape)
- return shape
-
-
-def carbonfet_thumb_1x_layout(shape):
- return sl.union()(
- # carbonfet_thumb_tr_place(sl.rotate(pi / 2, [0, 0, 1])(shape)),
- carbonfet_thumb_tr_place(shape),
- carbonfet_thumb_mr_place(shape),
- carbonfet_thumb_br_place(shape),
- # carbonfet_thumb_tl_place(sl.rotate(pi / 2, [0, 0, 1])(shape)),
- carbonfet_thumb_tl_place(shape),
- )
-
-
-def carbonfet_thumb_15x_layout(shape):
- return sl.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(sl.rotate(pi / 2, [0, 0, 1])(sa_cap(1.5)))
- return t1 + 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 += carbonfet_thumb_15x_layout(double_plate_half())
- shape += carbonfet_thumb_15x_layout(single_plate(side=side))
-
- return shape
-
-def carbonfet_thumb_post_tr():
- return sl.translate(
- [(mount_width / 2) - post_adj, (mount_height / 1.15) - post_adj, 0]
- )(web_post())
-
-
-def carbonfet_thumb_post_tl():
- return sl.translate(
- [-(mount_width / 2) + post_adj, (mount_height / 1.15) - post_adj, 0]
- )(web_post())
-
-
-def carbonfet_thumb_post_bl():
- return sl.translate(
- [-(mount_width / 2) + post_adj, -(mount_height / 1.15) + post_adj, 0]
- )(web_post())
-
-
-def carbonfet_thumb_post_br():
- return sl.translate(
- [(mount_width / 2) - post_adj, -(mount_height / 2) + post_adj, 0]
- )(web_post())
-
-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 sl.union()(*hulls)
-
-##########
-## Case ##
-##########
-
-
-def bottom_hull(p, height=0.001):
- shape = None
- for item in p:
- proj = sl.projection()(p)
- t_shape = sl.linear_extrude(height=height, twist=0, convexity=0, center=True)(
- proj
- )
- t_shape = sl.translate([0, 0, height / 2 - 10])(t_shape)
- if shape is None:
- shape = t_shape
- shape = sl.hull()(p, shape, t_shape)
- return shape
-
-
-def left_key_position(row, direction):
- 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):
- pos = left_key_position(row, direction)
- return sl.translate(pos)(shape)
-
-
-def wall_locate1(dx, dy):
- return [dx * wall_thickness, dy * wall_thickness, -1]
-
-
-def wall_locate2(dx, dy):
- return [dx * wall_x_offset, dy * wall_y_offset, -wall_z_offset]
-
-
-def wall_locate3(dx, dy, back=False):
- 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,
- ]
-
-
-def wall_brace(place1, dx1, dy1, post1, place2, dx2, dy2, post2, back=False):
- hulls = []
-
- hulls.append(place1(post1))
- hulls.append(place1(sl.translate(wall_locate1(dx1, dy1))(post1)))
- hulls.append(place1(sl.translate(wall_locate2(dx1, dy1))(post1)))
- hulls.append(place1(sl.translate(wall_locate3(dx1, dy1, back))(post1)))
-
- hulls.append(place2(post2))
- hulls.append(place2(sl.translate(wall_locate1(dx2, dy2))(post2)))
- hulls.append(place2(sl.translate(wall_locate2(dx2, dy2))(post2)))
- hulls.append(place2(sl.translate(wall_locate3(dx2, dy2, back))(post2)))
- shape1 = sl.hull()(*hulls)
-
- hulls = []
- hulls.append(place1(sl.translate(wall_locate2(dx1, dy1))(post1)))
- hulls.append(place1(sl.translate(wall_locate3(dx1, dy1, back))(post1)))
- hulls.append(place2(sl.translate(wall_locate2(dx2, dy2))(post2)))
- hulls.append(place2(sl.translate(wall_locate3(dx2, dy2, back))(post2)))
- shape2 = bottom_hull(hulls)
-
- return shape1 + shape2
-
-
-def key_wall_brace(x1, y1, dx1, dy1, post1, x2, y2, dx2, dy2, post2, back=False):
- 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():
- x = 0
- 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 += key_wall_brace(x, 0, 0, 1, web_post_tl(), x, 0, 0, 1, web_post_tr(), back=True)
- shape += key_wall_brace(
- x, 0, 0, 1, web_post_tl(), x - 1, 0, 0, 1, web_post_tr(), back=True
- )
- shape += key_wall_brace(
- lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr(), back=True
- )
- return shape
-
-
-def right_wall():
- if pinky_1_5U:
- if first_1_5U_row > 0:
- shape = key_wall_brace(
- lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr())
- else:
- shape = key_wall_brace(
- lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 0, 1, web_post_tr(wide=True))
- shape += key_wall_brace(
- lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr(wide=True))
-
- shape += key_wall_brace(
- lastcol, 0, 0, -1, web_post_br(), lastcol, 0, 1, 0, web_post_br())
-
- if first_1_5U_row >= 2:
- for y in range(first_1_5U_row - 1):
- shape += key_wall_brace(
- lastcol, y, 1, 0, web_post_tr(), lastcol, y, 1, 0, web_post_br())
- shape += key_wall_brace(
- lastcol, y, 1, 0, web_post_br(), lastcol, y-1, 1, 0, web_post_tr())
-
- if first_1_5U_row >= 1:
- for i in range(2):
- y = first_1_5U_row - 1 + i
- shape += key_wall_brace(
- lastcol, y, 1, 0, web_post_tr(), lastcol, y-1, 1, 0, web_post_tr(wide=True))
-
- for i in range(2):
- y = first_1_5U_row + i
- shape += key_wall_brace(
- lastcol, y, 1, 0, web_post_tr(wide=True), lastcol, y, 1, 0, web_post_br(wide=True))
-
- for i in range(first_1_5U_row - last_1_5U_row):
- y = first_1_5U_row + i
- shape += key_wall_brace(
- lastcol, y+1, 1, 0, web_post_tr(wide=True), lastcol, y, 1, 0, web_post_br(wide=True))
-
- if first_1_5U_row >= 1:
- for i in range(2):
- y = first_1_5U_row - 1 + i
- shape += key_wall_brace(
- lastcol, y, 1, 0, web_post_tr(), lastcol, y-1, 1, 0, web_post_tr(wide=True))
-
- else:
- y = 0
- shape = 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 += key_wall_brace(
- lastcol, y - 1, 1, 0, web_post_br(), lastcol, y, 1, 0, web_post_tr())
-
- shape += key_wall_brace(
- lastcol, y, 1, 0, web_post_tr(), lastcol, y, 1, 0, web_post_br())
-
- shape += key_wall_brace(
- lastcol, cornerrow, 0, -1, web_post_br(), lastcol, cornerrow, 1, 0, web_post_br())
-
- return shape
-
-
-def left_wall():
- shape = 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 += 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 = sl.hull()(
- 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 += temp_shape1 + 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 = sl.hull()(
- 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 += temp_shape1 + temp_shape2
-
- return shape
-
-
-def front_wall():
- shape = key_wall_brace(
- lastcol, 0, 0, 1, web_post_tr(), lastcol, 0, 1, 0, web_post_tr()
- )
- shape += key_wall_brace(
- 3, lastrow, 0, -1, web_post_bl(), 3, lastrow, 0.5, -1, web_post_br()
- )
- shape += 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 += 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 += 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():
- # thumb, walls
- shape = wall_brace(thumb_mr_place, 0, -1, web_post_br(), thumb_tr_place, 0, -1, thumb_post_br())
- shape += wall_brace(thumb_mr_place, 0, -1, web_post_br(), thumb_mr_place, 0, -1, web_post_bl())
- shape += wall_brace(thumb_br_place, 0, -1, web_post_br(), thumb_br_place, 0, -1, web_post_bl())
- shape += wall_brace(thumb_ml_place, -0.3, 1, web_post_tr(), thumb_ml_place, 0, 1, web_post_tl())
- shape += wall_brace(thumb_bl_place, 0, 1, web_post_tr(), thumb_bl_place, 0, 1, web_post_tl())
- shape += wall_brace(thumb_br_place, -1, 0, web_post_tl(), thumb_br_place, -1, 0, web_post_bl())
- shape += wall_brace(thumb_bl_place, -1, 0, web_post_tl(), thumb_bl_place, -1, 0, web_post_bl())
- # thumb, corners
- shape += wall_brace(thumb_br_place, -1, 0, web_post_bl(), thumb_br_place, 0, -1, web_post_bl())
- shape += wall_brace(thumb_bl_place, -1, 0, web_post_tl(), thumb_bl_place, 0, 1, web_post_tl())
- # thumb, tweeners
- shape += wall_brace(thumb_mr_place, 0, -1, web_post_bl(), thumb_br_place, 0, -1, web_post_br())
- shape += wall_brace(thumb_ml_place, 0, 1, web_post_tl(), thumb_bl_place, 0, 1, web_post_tr())
- shape += wall_brace(thumb_bl_place, -1, 0, web_post_bl(), thumb_br_place, -1, 0, web_post_tl())
- shape += 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():
- # clunky bit on the top left thumb connection (normal connectors don't work well)
- shape = bottom_hull(
- [
- left_key_place(sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1),
- thumb_ml_place(sl.translate(wall_locate2(-0.3, 1))(web_post_tr())),
- thumb_ml_place(sl.translate(wall_locate3(-0.3, 1))(web_post_tr())),
- ]
- )
-
- shape += sl.hull()(
- [
- left_key_place(sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1),
- thumb_ml_place(sl.translate(wall_locate2(-0.3, 1))(web_post_tr())),
- thumb_ml_place(sl.translate(wall_locate3(-0.3, 1))(web_post_tr())),
- thumb_tl_place(thumb_post_tl()),
- ]
- )
-
- shape += sl.hull()(
- [
- left_key_place(web_post(), cornerrow, -1),
- left_key_place(sl.translate(wall_locate1(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1),
- thumb_tl_place(thumb_post_tl()),
- ]
- )
-
- shape += sl.hull()(
- [
- left_key_place(web_post(), cornerrow, -1),
- left_key_place(sl.translate(wall_locate1(-1, 0))(web_post()), cornerrow, -1),
- key_place(web_post_bl(), 0, cornerrow),
- # key_place(sl.translate(wall_locate1(-1, 0))(web_post_bl()), 0, cornerrow),
- key_place(sl.translate(wall_locate1(0, 0))(web_post_bl()), 0, cornerrow),
- thumb_tl_place(thumb_post_tl()),
- ]
- )
-
- shape += sl.hull()(
- [
- thumb_ml_place(web_post_tr()),
- thumb_ml_place(sl.translate(wall_locate1(-0.3, 1))(web_post_tr())),
- thumb_ml_place(sl.translate(wall_locate2(-0.3, 1))(web_post_tr())),
- thumb_ml_place(sl.translate(wall_locate3(-0.3, 1))(web_post_tr())),
- thumb_tl_place(thumb_post_tl()),
- ]
- )
-
- return shape
-
-
-def mini_thumb_walls():
- # thumb, walls
- shape = wall_brace(mini_thumb_mr_place, 0, -1, web_post_br(), mini_thumb_tr_place, 0, -1, mini_thumb_post_br())
- shape += wall_brace(mini_thumb_mr_place, 0, -1, web_post_br(), mini_thumb_mr_place, 0, -1, web_post_bl())
- shape += wall_brace(mini_thumb_br_place, 0, -1, web_post_br(), mini_thumb_br_place, 0, -1, web_post_bl())
- shape += wall_brace(mini_thumb_bl_place, 0, 1, web_post_tr(), mini_thumb_bl_place, 0, 1, web_post_tl())
- shape += wall_brace(mini_thumb_br_place, -1, 0, web_post_tl(), mini_thumb_br_place, -1, 0, web_post_bl())
- shape += wall_brace(mini_thumb_bl_place, -1, 0, web_post_tl(), mini_thumb_bl_place, -1, 0, web_post_bl())
- # thumb, corners
- shape += wall_brace(mini_thumb_br_place, -1, 0, web_post_bl(), mini_thumb_br_place, 0, -1, web_post_bl())
- shape += wall_brace(mini_thumb_bl_place, -1, 0, web_post_tl(), mini_thumb_bl_place, 0, 1, web_post_tl())
- # thumb, tweeners
- shape += wall_brace(mini_thumb_mr_place, 0, -1, web_post_bl(), mini_thumb_br_place, 0, -1, web_post_br())
- shape += wall_brace(mini_thumb_bl_place, -1, 0, web_post_bl(), mini_thumb_br_place, -1, 0, web_post_tl())
- shape += 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():
- # clunky bit on the top left thumb connection (normal connectors don't work well)
- shape = bottom_hull(
- [
- left_key_place(sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1),
- mini_thumb_bl_place(sl.translate(wall_locate2(-0.3, 1))(web_post_tr())),
- mini_thumb_bl_place(sl.translate(wall_locate3(-0.3, 1))(web_post_tr())),
- ]
- )
-
- shape += sl.hull()(
- [
- left_key_place(sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1),
- mini_thumb_bl_place(sl.translate(wall_locate2(-0.3, 1))(web_post_tr())),
- mini_thumb_bl_place(sl.translate(wall_locate3(-0.3, 1))(web_post_tr())),
- mini_thumb_tl_place(web_post_tl()),
- ]
- )
-
- shape += sl.hull()(
- [
- left_key_place(web_post(), cornerrow, -1),
- left_key_place(sl.translate(wall_locate1(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1),
- mini_thumb_tl_place(web_post_tl()),
- ]
- )
-
- shape += sl.hull()(
- [
- left_key_place(web_post(), cornerrow, -1),
- left_key_place(sl.translate(wall_locate1(-1, 0))(web_post()), cornerrow, -1),
- key_place(web_post_bl(), 0, cornerrow),
- # key_place(sl.translate(wall_locate1(-1, 0))(web_post_bl()), 0, cornerrow),
- mini_thumb_tl_place(web_post_tl()),
- ]
- )
-
- shape += sl.hull()(
- [
- mini_thumb_bl_place(web_post_tr()),
- mini_thumb_bl_place(sl.translate(wall_locate1(-0.3, 1))(web_post_tr())),
- mini_thumb_bl_place(sl.translate(wall_locate2(-0.3, 1))(web_post_tr())),
- mini_thumb_bl_place(sl.translate(wall_locate3(-0.3, 1))(web_post_tr())),
- mini_thumb_tl_place(web_post_tl()),
- ]
- )
-
- return shape
-
-
-
-def carbonfet_thumb_walls():
- # thumb, walls
- shape = wall_brace(carbonfet_thumb_mr_place, 0, -1, web_post_br(), carbonfet_thumb_tr_place, 0, -1, web_post_br())
- shape += wall_brace(carbonfet_thumb_mr_place, 0, -1, web_post_br(), carbonfet_thumb_mr_place, 0, -1.15, web_post_bl())
- shape += wall_brace(carbonfet_thumb_br_place, 0, -1, web_post_br(), carbonfet_thumb_br_place, 0, -1, web_post_bl())
- shape += wall_brace(carbonfet_thumb_bl_place, -.3, 1, thumb_post_tr(), carbonfet_thumb_bl_place, 0, 1, thumb_post_tl())
- shape += wall_brace(carbonfet_thumb_br_place, -1, 0, web_post_tl(), carbonfet_thumb_br_place, -1, 0, web_post_bl())
- shape += wall_brace(carbonfet_thumb_bl_place, -1, 0, thumb_post_tl(), carbonfet_thumb_bl_place, -1, 0, web_post_bl())
- # thumb, corners
- shape += wall_brace(carbonfet_thumb_br_place, -1, 0, web_post_bl(), carbonfet_thumb_br_place, 0, -1, web_post_bl())
- shape += wall_brace(carbonfet_thumb_bl_place, -1, 0, thumb_post_tl(), carbonfet_thumb_bl_place, 0, 1, thumb_post_tl())
- # thumb, tweeners
- shape += wall_brace(carbonfet_thumb_mr_place, 0, -1.15, web_post_bl(), carbonfet_thumb_br_place, 0, -1, web_post_br())
- # shape += wall_brace(thumb_ml_place, 0, 1, web_post_tl(), carbonfet_thumb_bl_place, 0, 1, web_post_tr())
- shape += wall_brace(carbonfet_thumb_bl_place, -1, 0, web_post_bl(), carbonfet_thumb_br_place, -1, 0, web_post_tl())
- 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():
- # clunky bit on the top left thumb connection (normal connectors don't work well)
- shape = bottom_hull(
- [
- left_key_place(sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1),
- carbonfet_thumb_bl_place(sl.translate(wall_locate2(-0.3, 1))(thumb_post_tr())),
- carbonfet_thumb_bl_place(sl.translate(wall_locate3(-0.3, 1))(thumb_post_tr())),
- ]
- )
-
- shape += sl.hull()(
- [
- left_key_place(sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1),
- carbonfet_thumb_bl_place(sl.translate(wall_locate2(-0.3, 1))(thumb_post_tr())),
- carbonfet_thumb_bl_place(sl.translate(wall_locate3(-0.3, 1))(thumb_post_tr())),
- carbonfet_thumb_ml_place(thumb_post_tl()),
- ]
- )
-
- shape += sl.hull()(
- [
- left_key_place(web_post(), cornerrow, -1),
- left_key_place(sl.translate(wall_locate1(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1),
- left_key_place(sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1),
- carbonfet_thumb_ml_place(thumb_post_tl()),
- ]
- )
-
- shape += sl.hull()(
- [
- left_key_place(web_post(), cornerrow, -1),
- left_key_place(sl.translate(wall_locate1(-1, 0))(web_post()), cornerrow, -1),
- key_place(web_post_bl(), 0, cornerrow),
- # key_place(sl.translate(wall_locate1(-1, 0))(web_post_bl()), 0, cornerrow),
- carbonfet_thumb_ml_place(thumb_post_tl()),
- ]
- )
-
- shape += sl.hull()(
- [
- carbonfet_thumb_bl_place(thumb_post_tr()),
- carbonfet_thumb_bl_place(sl.translate(wall_locate1(-0.3, 1))(thumb_post_tr())),
- carbonfet_thumb_bl_place(sl.translate(wall_locate2(-0.3, 1))(thumb_post_tr())),
- carbonfet_thumb_bl_place(sl.translate(wall_locate3(-0.3, 1))(thumb_post_tr())),
- carbonfet_thumb_ml_place(thumb_post_tl()),
- ]
- )
-
- return shape
-
-
-
-def case_walls():
- return (
- 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():
- return sl.cube([14.78, 13, 22.38], center=True)
-
-
-def rj9_space():
- return sl.translate(rj9_position)(rj9_cube())
-
-
-def rj9_holder():
- shape = sl.union()(
- sl.translate([0, 2, 0])(sl.cube([10.78, 9, 18.38], center=True)),
- sl.translate([0, 0, 5])(sl.cube([10.78, 13, 5], center=True)),
- )
- shape = sl.difference()(rj9_cube(), shape)
- shape = sl.translate(rj9_position)(shape)
- 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():
- shape = sl.cube(
- [
- usb_holder_size[0] + usb_holder_thickness,
- usb_holder_size[1],
- usb_holder_size[2] + usb_holder_thickness,
- ],
- center=True,
- )
- shape = sl.translate(
- [
- usb_holder_position[0],
- usb_holder_position[1],
- (usb_holder_size[2] + usb_holder_thickness) / 2,
- ]
- )(shape)
- return shape
-
-
-def usb_holder_hole():
- shape = sl.cube(usb_holder_size, center=True)
- shape = sl.translate(
- [
- usb_holder_position[0],
- usb_holder_position[1],
- (usb_holder_size[2] + usb_holder_thickness) / 2,
- ]
- )(shape)
- return shape
-
-
-external_start = list(
- 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 = sl.cube((external_holder_width, 20.0, external_holder_height), center=True)
- shape = sl.translate(
- (
- external_start[0] + external_holder_xoffset,
- external_start[1],
- external_holder_height / 2
- )
- )(shape)
- 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 = sl.cube([mount_ext_width, mount_ext_up_height, oled_mount_cut_depth + .01], center=True)
- hole = sl.translate([0., top_hole_start + top_hole_length / 2, 0.])(hole)
- hole_down = sl.cube([mount_ext_width, mount_ext_height, oled_mount_depth + oled_mount_cut_depth / 2],
- center=True)
- hole_down = sl.translate([0., 0., -oled_mount_cut_depth / 4])(hole_down)
- hole += hole_down
-
- shape = sl.cube([mount_ext_width, mount_ext_height, oled_mount_depth], center=True)
-
- 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 = sl.cube([oled_mount_width, conn_hole_length + .01, oled_mount_depth], center=True)
- conn_hole = sl.translate([
- 0,
- conn_hole_start + conn_hole_length / 2,
- -oled_edge_overlap_thickness
- ])(conn_hole)
-
- 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 = sl.cube([oled_mount_width, end_hole_length + .01, oled_mount_depth], center=True)
- end_hole = sl.translate([
- 0,
- end_hole_start + end_hole_length / 2,
- -oled_edge_overlap_thickness
- ])(end_hole)
-
- 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 = sl.cube(
- [oled_mount_width, top_hole_length, oled_edge_overlap_thickness + oled_thickness - oled_edge_chamfer],
- center=True)
- top_hole = sl.translate([
- 0,
- top_hole_start + top_hole_length / 2,
- (oled_mount_depth - oled_edge_overlap_thickness - oled_thickness - oled_edge_chamfer) / 2.0
- ])(top_hole)
-
- top_chamfer_1 = sl.cube([
- oled_mount_width,
- top_hole_length,
- 0.01
- ], center=True)
- top_chamfer_2 = sl.cube([
- oled_mount_width + 2 * oled_edge_chamfer,
- top_hole_length + 2 * oled_edge_chamfer,
- 0.01
- ], center=True)
- top_chamfer_1 = sl.translate([
- 0,
- 0,
- -oled_edge_chamfer - .05
- ])(top_chamfer_1)
- top_chamfer_1 = sl.hull()(top_chamfer_1, top_chamfer_2)
-
- top_chamfer_1 = sl.translate([
- 0,
- top_hole_start + top_hole_length / 2,
- oled_mount_depth / 2.0 + .05
- ])(top_chamfer_1)
- top_hole += top_chamfer_1
-
- shape = sl.difference()(shape, conn_hole, top_hole, end_hole)
-
- shape = sl.rotate(oled_mount_rotation_xyz)(shape)
- shape = sl.translate(
- (
- oled_mount_location_xyz[0],
- oled_mount_location_xyz[1],
- oled_mount_location_xyz[2],
- )
- )(shape)
-
- hole = sl.rotate(oled_mount_rotation_xyz)(hole)
- hole = sl.translate(
- (
- oled_mount_location_xyz[0],
- oled_mount_location_xyz[1],
- oled_mount_location_xyz[2],
- )
- )(hole)
- 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 = sl.cube([mount_ext_width, mount_ext_height, oled_mount_cut_depth + .01], center=True)
-
- shape = sl.cube([mount_ext_width, mount_ext_height, oled_mount_depth], center=True)
- shape -= sl.cube([oled_mount_width, oled_mount_height, oled_mount_depth + .1], center=True)
-
- clip_slot = sl.cube([
- oled_clip_width + 2 * oled_clip_width_clearance,
- oled_mount_height + 2 * oled_clip_thickness + 2 * oled_clip_overhang,
- oled_mount_depth + .1], center=True)
-
- shape -= clip_slot
-
- clip_undercut = sl.cube([
- 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], center=True)
-
- clip_undercut = sl.translate((0., 0., oled_clip_undercut_thickness))(clip_undercut)
- shape -= clip_undercut
-
- plate = sl.cube([
- oled_mount_width + .1,
- oled_mount_height - 2 * oled_mount_connector_hole,
- oled_mount_depth - oled_thickness], center=True)
- plate = sl.translate((0., 0., -oled_thickness / 2.0))(plate)
- shape += plate
-
- shape = sl.rotate(oled_mount_rotation_xyz)(shape)
- shape = sl.translate(
- (
- oled_mount_location_xyz[0],
- oled_mount_location_xyz[1],
- oled_mount_location_xyz[2],
- )
- )(shape)
-
- hole = sl.rotate(oled_mount_rotation_xyz)(hole)
- hole = sl.translate(
- (
- oled_mount_location_xyz[0],
- oled_mount_location_xyz[1],
- oled_mount_location_xyz[2],
- )
- )(hole)
-
- 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 = sl.cube([mount_ext_width - .1, mount_ext_height - .1, oled_mount_bezel_thickness], center=True)
- shape = sl.translate((0., 0., oled_mount_bezel_thickness / 2.))(shape)
-
- hole_1 = sl.cube([
- oled_screen_width + 2 * oled_mount_bezel_chamfer,
- oled_screen_length + 2 * oled_mount_bezel_chamfer,
- .01
- ], center=True)
- hole_2 = sl.cube([oled_screen_width, oled_screen_length, 2.05 * oled_mount_bezel_thickness], center=True)
- hole = sl.hull()(hole_1, hole_2)
-
- shape -= sl.translate((0., 0., oled_mount_bezel_thickness))(hole)
-
- clip_leg = sl.cube([oled_clip_width, oled_clip_thickness, oled_leg_depth], center=True)
- clip_leg = sl.translate((
- 0.,
- 0.,
- # (oled_mount_height+2*oled_clip_overhang+oled_clip_thickness)/2,
- -oled_leg_depth / 2.
- ))(clip_leg)
-
- latch_1 = sl.cube([
- oled_clip_width,
- oled_clip_overhang + oled_clip_thickness,
- .01
- ], center=True)
- latch_2 = sl.cube([
- oled_clip_width,
- oled_clip_thickness / 2,
- oled_clip_extension
- ], center=True)
- latch_2 = sl.translate((
- 0.,
- -(-oled_clip_thickness / 2 + oled_clip_thickness + oled_clip_overhang) / 2,
- -oled_clip_extension / 2
- ))(latch_2)
- latch = sl.hull()(latch_1, latch_2)
- latch = sl.translate((
- 0.,
- oled_clip_overhang / 2,
- -oled_leg_depth
- ))(latch)
-
- clip_leg += latch
-
- clip_leg = sl.translate((
- 0.,
- (oled_mount_height + 2 * oled_clip_overhang + oled_clip_thickness) / 2 - oled_clip_y_gap,
- 0.
- ))(clip_leg)
-
- shape += clip_leg
- shape += sl.mirror((0., 1., 0.))(clip_leg)
-
- 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 = sl.cube([mount_ext_width, mount_ext_height, oled_mount_cut_depth + .01], center=True)
-
- shape = sl.cube([mount_ext_width, mount_ext_height, oled_mount_depth], center=True)
- shape = sl.difference()(
- shape,
- sl.cube([oled_mount_width, oled_mount_height, oled_mount_depth + .1], center=True)
- )
- undercut = sl.cube([
- oled_mount_width + 2 * oled_mount_undercut,
- oled_mount_height + 2 * oled_mount_undercut,
- oled_mount_depth], center=True)
- undercut = sl.translate((0., 0., -oled_mount_undercut_thickness))(undercut)
- shape = sl.difference()(shape, undercut)
-
- shape = sl.rotate(oled_mount_rotation_xyz)(shape)
- shape = sl.translate(
- (
- oled_mount_location_xyz[0],
- oled_mount_location_xyz[1],
- oled_mount_location_xyz[2],
- )
- )(shape)
-
- hole = sl.rotate(oled_mount_rotation_xyz)(hole)
- hole = sl.translate(
- (
- oled_mount_location_xyz[0],
- oled_mount_location_xyz[1],
- oled_mount_location_xyz[2],
- )
- )(hole)
-
- 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():
- s1 = sl.cube([3, teensy_holder_length, 6 + teensy_width], center=True)
- s1 = sl.translate([1.5, teensy_holder_offset, 0])(s1)
-
- s2 = sl.cube([teensy_pcb_thickness, teensy_holder_length, 3], center=True)
- s2 = sl.translate(
- [
- (teensy_pcb_thickness / 2) + 3,
- teensy_holder_offset,
- -1.5 - (teensy_width / 2),
- ]
- )(s2)
-
- s3 = sl.cube([teensy_pcb_thickness, teensy_holder_top_length, 3], center=True)
- s3 = sl.translate(
- [
- (teensy_pcb_thickness / 2) + 3,
- teensy_holder_top_offset,
- 1.5 + (teensy_width / 2),
- ]
- )(s3)
-
- s4 = sl.cube([4, teensy_holder_top_length, 4], center=True)
- s4 = sl.translate(
- [teensy_pcb_thickness + 5, teensy_holder_top_offset, 1 + (teensy_width / 2)]
- )(s4)
-
- shape = sl.union()(s1, s2, s3, s4)
-
- shape = sl.translate([-teensy_holder_width, 0, 0])(shape)
- shape = sl.translate([-1.4, 0, 0])(shape)
- shape = sl.translate(
- [teensy_top_xy[0], teensy_top_xy[1] - 1, (6 + teensy_width) / 2]
- )(shape)
-
- return shape
-
-
-def screw_insert_shape(bottom_radius, top_radius, height):
- shape = sl.union()(
- sl.cylinder(r1=bottom_radius, r2=top_radius, h=height, center=True),
- sl.translate([0, 0, (height / 2)])(sl.sphere(top_radius)),
- )
- return shape
-
-
-def screw_insert(column, row, bottom_radius, top_radius, height):
- 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,
- )
-
- # add z height below 0 due to 0 thickness skin covering the hole.
- shape = screw_insert_shape(bottom_radius, top_radius, height + 5)
- shape = sl.translate((position[0], position[1], height / 2 - 2.5))(shape)
-
- return shape
-
-
-def screw_insert_all_shapes(bottom_radius, top_radius, height):
- shape = sl.union()(
- 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):
- s1 = sl.cube(
- [wire_post_diameter, wire_post_diameter, wire_post_height], center=True
- )
- s1 = sl.translate([0, -wire_post_diameter * 0.5 * direction, 0])(s1)
-
- s2 = sl.cube(
- [wire_post_diameter, wire_post_overhang, wire_post_diameter], center=True
- )
- s2 = sl.translate(
- [0, -wire_post_overhang * 0.5 * direction, -wire_post_height / 2]
- )(s2)
-
- shape = sl.union()(s1, s2)
- shape = sl.translate([0, -offset, (-wire_post_height / 2) + 3])(shape)
- shape = sl.rotate(-alpha / 2, [1, 0, 0])(shape)
- shape = sl.translate([3, -mount_height / 2, 0])(shape)
-
- return shape
-
-
-def wire_posts():
- shape = thumb_ml_place(sl.translate([-5, 0, -2])(wire_post(1, 0)))
- shape += thumb_ml_place(sl.translate([0, 0, -2.5])(wire_post(-1, 6)))
- shape += thumb_ml_place(sl.translate([5, 0, -2])(wire_post(1, 0)))
-
- for column in range(lastcol):
- for row in range(lastrow - 1):
- shape += sl.union()(
- key_place(sl.translate([-5, 0, 0])(wire_post(1, 0)), column, row),
- key_place(sl.translate([0, 0, 0])(wire_post(-1, 6)), column, row),
- key_place(sl.translate([5, 0, 0])(wire_post(1, 0)), column, row),
- )
- return shape
-
-
-def model_side(side="right"):
- shape = sl.union()(key_holes(side=side), connectors(), thumb(side=side), thumb_connectors(), )
- pre_sub = []
- adders = []
- post_sub = [screw_insert_holes()]
-
- if controller_mount_type in ['RJ9_USB_TEENSY']:
- adders.append(teensy_holder())
-
- if controller_mount_type in ['RJ9_USB_TEENSY', 'RJ9_USB_WALL']:
- adders.append(usb_holder())
- post_sub.append(usb_holder_hole())
-
- if controller_mount_type in ['RJ9_USB_TEENSY', 'RJ9_USB_WALL']:
- pre_sub.append(rj9_space())
- adders.append(rj9_holder())
-
- if controller_mount_type in ['EXTERNAL']:
- post_sub.append(external_mount_hole())
-
- s2 = sl.union()(case_walls(), screw_insert_outers())
- s2 = sl.difference()(s2, *pre_sub)
- s2 = sl.union()(s2, *adders)
- shape = sl.union()(shape, s2)
-
- shape -= sl.translate([0, 0, -20])(sl.cube([350, 350, 40], center=True))
-
- shape = sl.difference()(shape, *post_sub)
-
- if oled_mount_type == "UNDERCUT":
- hole, frame = oled_undercut_mount_frame()
- shape -= hole
- shape += frame
-
- elif oled_mount_type == "SLIDING":
- hole, frame = oled_sliding_mount_frame()
- shape -= hole
- shape += frame
-
- elif oled_mount_type == "CLIP":
- hole, frame = oled_clip_mount_frame()
- shape -= hole
- shape += frame
-
- if side == "left":
- shape = sl.mirror([-1, 0, 0])(shape)
-
- return shape
-
-
-mod_r = model_side(side="right")
-
-sl.scad_render_to_file(mod_r, path.join(r"..", "things", save_dir, config_name + r"_right.scad"))
-
-if symmetry == "asymmetric":
- mod_l = model_side(side="left")
- sl.scad_render_to_file(
- mod_l, path.join(r"..", "things", save_dir, config_name + r"_left.scad")
- )
-else:
- sl.scad_render_to_file(
- sl.mirror([-1, 0, 0])(mod_r), path.join(r"..", "things", save_dir, config_name + r"_left.scad")
- )
-
-
-def baseplate():
- shape = sl.union()(
- case_walls(),
- screw_insert_outers(),
- )
-
- tool = sl.translate([0, 0, -10])(screw_insert_screw_holes())
-
- shape = shape - tool
-
- shape = sl.translate([0, 0, -0.01])(shape)
-
- return sl.projection(cut=True)(shape)
-
-
-sl.scad_render_to_file(baseplate(), path.join(r"..", "things", save_dir, config_name + r"_plate.scad"))
-
-if oled_mount_type == 'UNDERCUT':
- sl.scad_render_to_file(oled_undercut_mount_frame()[1], path.join(r"..", "things", save_dir, config_name + r"_oled_undercut_test.scad"))
-
-if oled_mount_type == 'SLIDING':
- sl.scad_render_to_file(oled_sliding_mount_frame()[1], path.join(r"..", "things", save_dir, config_name + r"_oled_sliding_test.scad"))
-
-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)
- sl.scad_render_to_file(oled_clip(), path.join(r"..", "things", save_dir, config_name + r"_oled_clip.scad"))
- sl.scad_render_to_file(oled_clip_mount_frame()[1], path.join(r"..", "things", save_dir, config_name + r"_oled_clip_test.scad"))
- sl.scad_render_to_file(oled_clip_mount_frame()[1] + oled_clip(),
- path.join(r"..", "things", save_dir, config_name + r"_oled_clip_assy_test.scad"))
diff --git a/src/generate_configuration.py b/src/generate_configuration.py
index 3340214..e5dd966 100644
--- a/src/generate_configuration.py
+++ b/src/generate_configuration.py
@@ -40,6 +40,7 @@ shape_config = {
9 # controls overall height# original=9 with centercol=3# use 16 for centercol=2
),
+ 'thumb_style': 'DEFAULT', # 'DEFAULT', 'MINI', 'CARBONFET'
##############################
# NEW TEST PARAMETERS
@@ -47,7 +48,6 @@ shape_config = {
'pinky_1_5U': False, # LEAVE AS FALSE, CURRENTLY BROKEN
'first_1_5U_row': 0,
'last_1_5U_row': 5,
- 'thumb_style': 'DEFAULT', #'DEFAULT', 'MINI', 'CARBONFET'
##############################
@@ -235,7 +235,7 @@ shape_config = {
###################################
## EXPERIMENTAL
###################################
- 'plate_holes': True,
+ 'plate_holes': False,
'plate_holes_xy_offset': (0.0, 0.0),
'plate_holes_width': 14.3,
'plate_holes_height': 14.3,
diff --git a/src/helpers_cadquery.py b/src/helpers_cadquery.py
new file mode 100644
index 0000000..108e2ac
--- /dev/null
+++ b/src/helpers_cadquery.py
@@ -0,0 +1,184 @@
+import cadquery as cq
+from scipy.spatial import ConvexHull as sphull
+import numpy as np
+
+def box(width, height, depth):
+ return cq.Workplane("XY").box(width, height, depth)
+
+
+def cylinder(radius, height, segments=100):
+ return cq.Workplane("XY").union(cq.Solid.makeCylinder(radius=radius, height=height))
+
+
+def sphere(radius):
+ return cq.Workplane('XY').union(cq.Solid.makeSphere(radius))
+
+
+def cone(r1, r2, height):
+ return cq.Workplane('XY').union(
+ cq.Solid.makeCone(radius1=r1, radius2=r2, height=height))
+
+
+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 add(shapes):
+ print('union()')
+ shape = None
+ for item in shapes:
+ if shape is None:
+ shape = item
+ else:
+ shape = shape.add(item)
+ return shape
+
+
+def difference(shape, shapes):
+ print('difference()')
+ for item in shapes:
+ shape = shape.cut(item)
+ return shape
+
+
+def intersect(shape1, shape2):
+ return shape1.intersect(shape2)
+
+
+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 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 polyline(point_list):
+ return cq.Workplane('XY').polyline(point_list)
+
+
+# def project_to_plate():
+# square = cq.Workplane('XY').rect(1000, 1000)
+# for wire in square.wires().objects:
+# plane = cq.Workplane('XY').add(cq.Face.makeFromWires(wire))
+
+
+def extrude_poly(outer_poly, inner_polys=None, height=1): # vector=(0,0,1)):
+ outer_wires = cq.Wire.assembleEdges(outer_poly.edges().objects)
+ inner_wires = []
+ if inner_polys is not None:
+ for item in inner_polys:
+ inner_wires.append(cq.Wire.assembleEdges(item.edges().objects))
+
+ return cq.Workplane('XY').add(
+ cq.Solid.extrudeLinear(outerWire=outer_wires, innerWires=inner_wires, vecNormal=cq.Vector(0, 0, height)))
+
+
+def import_file(filename):
+ return cq.Workplane('XY').add(cq.importers.importShape(
+ cq.exporters.ExportTypes.STEP,
+ filename + ".step"))
+
+
+def export_file(shape, fname):
+ cq.exporters.export(w=shape, fname=fname + ".step",
+ exportType='STEP')
+
+
+def export_dxf(shape, fname):
+ cq.exporters.export(w=shape, fname=fname + ".dxf",
+ exportType='DXF') \ No newline at end of file
diff --git a/src/helpers_solid.py b/src/helpers_solid.py
new file mode 100644
index 0000000..918f7a3
--- /dev/null
+++ b/src/helpers_solid.py
@@ -0,0 +1,126 @@
+import solid as sl
+
+
+def box(width, height, depth):
+ return sl.cube([width, height, depth], center=True)
+
+
+def cylinder(radius, height, segments=100):
+ return sl.cylinder(r=radius, h=height, segments=segments, center=True)
+
+
+def sphere(radius):
+ return sl.sphere(radius)
+
+
+def cone(r1, r2, height):
+ return sl.cylinder(r1=r1, r2=r2, h=height) # , center=True)
+
+
+def rotate(shape, angle):
+ return sl.rotate(angle)(shape)
+
+
+def translate(shape, vector):
+ return sl.translate(tuple(vector))(shape)
+
+
+def mirror(shape, plane=None):
+ print('mirror()')
+ planes = {
+ 'XY': [0, 0, 1],
+ 'YX': [0, 0, -1],
+ 'XZ': [0, 1, 0],
+ 'ZX': [0, -1, 0],
+ 'YZ': [1, 0, 0],
+ 'ZY': [-1, 0, 0],
+ }
+ return sl.mirror(planes[plane])(shape)
+
+
+def union(shapes):
+ print('union()')
+ shape = None
+ for item in shapes:
+ if shape is None:
+ shape = item
+ else:
+ shape += item
+ return shape
+
+
+def add(shapes):
+ print('union()')
+ shape = None
+ for item in shapes:
+ if shape is None:
+ shape = item
+ else:
+ shape += item
+ return shape
+
+
+def difference(shape, shapes):
+ print('difference()')
+ for item in shapes:
+ shape -= item
+ return shape
+
+
+def intersect(shape1, shape2):
+ return sl.intersect()(shape1, shape2)
+
+
+def hull_from_points(points):
+ return sl.hull()(*points)
+
+
+def hull_from_shapes(shapes, points=None):
+ hs = []
+ if points is not None:
+ hs.extend(points)
+ if shapes is not None:
+ hs.extend(shapes)
+ return sl.hull()(*hs)
+
+
+def tess_hull(shapes, sl_tol=.5, sl_angTol=1):
+ return sl.hull()(*shapes)
+
+
+def triangle_hulls(shapes):
+ print('triangle_hulls()')
+ hulls = []
+ for i in range(len(shapes) - 2):
+ hulls.append(hull_from_shapes(shapes[i: (i + 3)]))
+
+ return union(hulls)
+
+
+def polyline(point_list):
+ return sl.polygon(point_list)
+
+
+# def project_to_plate():
+# square = cq.Workplane('XY').rect(1000, 1000)
+# for wire in square.wires().objects:
+# plane = cq.Workplane('XY').add(cq.Face.makeFromWires(wire))
+
+def extrude_poly(outer_poly, inner_polys=None, height=1):
+ if inner_polys is not None:
+ return sl.linear_extrude(height=height, twist=0, convexity=0, center=True)(outer_poly, *inner_polys)
+ else:
+ return sl.linear_extrude(height=height, twist=0, convexity=0, center=True)(outer_poly)
+
+
+def import_file(fname):
+ return sl.import_(fname + ".stl")
+
+
+def export_file(shape, fname):
+ print("EXPORTING TO {}".format(fname + ".scad"))
+ sl.scad_render_to_file(shape, fname + ".scad")
+
+
+def export_dxf(shape, fname):
+ pass \ No newline at end of file
diff --git a/src/model_builder.py b/src/model_builder.py
index 21bb325..f181655 100644
--- a/src/model_builder.py
+++ b/src/model_builder.py
@@ -118,17 +118,9 @@ for config in configurations:
with open('run_config.json', mode='w') as fid:
json.dump(shape_config, fid, indent=4)
- for ENGINE in ['solid', 'cadquery']:
- if ENGINE == 'solid':
- if init:
- import src.dactyl_manuform_solid as dactyl_manuform
- else:
- importlib.reload(dactyl_manuform)
-
- if ENGINE == 'cadquery':
- if init:
- import src.dactyl_manuform as dactyl_manuform_cadquery
- else:
- importlib.reload(dactyl_manuform_cadquery)
+ if init:
+ import src.dactyl_manuform as dactyl_manuform
+ else:
+ importlib.reload(dactyl_manuform)
init = False
diff --git a/src/run_config.json b/src/run_config.json
index e1d3337..f87eaa1 100644
--- a/src/run_config.json
+++ b/src/run_config.json
@@ -1,8 +1,8 @@
{
- "save_dir": ".",
- "config_name": "DM",
+ "save_dir": "6x6_Basic",
+ "config_name": "6x6_Basic",
"show_caps": false,
- "nrows": 5,
+ "nrows": 6,
"ncols": 6,
"alpha": 0.26179916666666664,
"beta": 0.08726638888888888,
@@ -18,10 +18,10 @@
7
],
"keyboard_z_offset": 9,
+ "thumb_style": "DEFAULT",
"pinky_1_5U": false,
"first_1_5U_row": 0,
"last_1_5U_row": 5,
- "thumb_style": "DEFAULT",
"extra_width": 2.5,
"extra_height": 1.0,
"wall_z_offset": 15,
@@ -77,7 +77,7 @@
"undercut_transition": 0.2,
"plate_file": null,
"plate_offset": 0.0,
- "oled_mount_type": "CLIP",
+ "oled_mount_type": null,
"oled_configurations": {
"UNDERCUT": {
"oled_mount_width": 15.0,
@@ -165,7 +165,7 @@
"post_size": 0.1,
"post_adj": 0,
"screws_offset": "INSIDE",
- "controller_mount_type": "EXTERNAL",
+ "controller_mount_type": "RJ9_USB_WALL",
"external_holder_height": 12.5,
"external_holder_width": 28.75,
"external_holder_xoffset": -5.0,