summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoshua Shreve <j.a.shreve@gmail.com>2022-02-20 15:54:46 -0500
committerJoshua Shreve <j.a.shreve@gmail.com>2022-02-20 15:54:46 -0500
commitc232e1eb4c7ab37bd56b324097e5d14fe4812d1c (patch)
tree370c5038f6afa6930bb042b152be46c906b99e83 /src
parent2960ba0f9c0d5a273818ce007d22cf766f937deb (diff)
parentc636386220cdd709c282b451d50677d8c3e0f93c (diff)
Merge branch 'dev'
Diffstat (limited to 'src')
-rw-r--r--src/dactyl_manuform.py246
-rw-r--r--src/generate_configuration.py7
-rw-r--r--src/generate_configuration_mklasklasd.py506
-rw-r--r--src/run_config.json4
4 files changed, 691 insertions, 72 deletions
diff --git a/src/dactyl_manuform.py b/src/dactyl_manuform.py
index 171a10c..72135e7 100644
--- a/src/dactyl_manuform.py
+++ b/src/dactyl_manuform.py
@@ -94,7 +94,7 @@ if nrows > 5:
centerrow = nrows - centerrow_offset
lastrow = nrows - 1
-if reduced_outer_keys:
+if reduced_outer_cols>0 or reduced_inner_cols>0:
cornerrow = lastrow - 1
else:
cornerrow = lastrow
@@ -330,8 +330,13 @@ def trackball_ball(segments=100, side="right"):
## SA Keycaps ##
################
-
-
+def keycap(*args, **kwargs):
+ if show_caps == 'CHOC':
+ return choc_cap(*args, **kwargs)
+ elif show_caps == 'MX':
+ return sa_cap(*args, **kwargs)
+ else:
+ return sa_cap(*args, **kwargs)
def sa_cap(Usize=1):
# MODIFIED TO NOT HAVE THE ROTATION. NEEDS ROTATION DURING ASSEMBLY
@@ -379,6 +384,40 @@ def sa_cap(Usize=1):
return key_cap
+
+def choc_cap(Usize=1):
+ # MODIFIED TO NOT HAVE THE ROTATION. NEEDS ROTATION DURING ASSEMBLY
+ # sa_length = 18.25
+
+ if Usize == 1:
+ bl2 = 18.0/2
+ bw2 = 17.5/2
+ bt = 2
+ pl2 = 15.0/2
+ pw2 = 14.5/2
+ pt = 1.5
+ gap = 1.5
+
+ k1 = polyline([(bw2, bl2), (bw2, -bl2), (-bw2, -bl2), (-bw2, bl2), (bw2, bl2)])
+ k1 = extrude_poly(outer_poly=k1, height=0.1)
+ k1 = translate(k1, (0, 0, 0.05))
+ k2 = polyline([(bw2, bl2), (bw2, -bl2), (-bw2, -bl2), (-bw2, bl2), (bw2, bl2)])
+ k2 = extrude_poly(outer_poly=k2, height=0.1)
+ k2 = translate(k2, (0, 0, 0.05+bt))
+ k3 = polyline([(pw2, pl2), (pw2, -pl2), (-pw2, -pl2), (-pw2, pl2), (pw2, pl2)])
+ k3 = extrude_poly(outer_poly=k3, height=0.1)
+ k3 = translate(k3, (0, 0, 0.05+bt+pt))
+ key_cap = hull_from_shapes((k1, k2, k3))
+
+ key_cap = translate(key_cap, (0, 0, 2.8 + plate_thickness))
+
+ if show_pcbs:
+ key_cap = add([key_cap, key_pcb()])
+
+ return key_cap
+
+
+
def key_pcb():
shape = box(pcb_width, pcb_height, pcb_thickness)
shape = translate(shape, (0, 0, -pcb_thickness/2))
@@ -510,7 +549,7 @@ def key_holes(side="right"):
holes = []
for column in range(ncols):
for row in range(nrows):
- if (column in [2, 3]) or (not row == lastrow) or (not reduced_outer_keys):
+ if (reduced_inner_cols <= column < (ncols - reduced_outer_cols)) or (not row == lastrow):
holes.append(key_place(single_plate(side=side), column, row))
shape = union(holes)
@@ -523,7 +562,7 @@ def plate_pcb_cutouts(side="right"):
cutouts = []
for column in range(ncols):
for row in range(nrows):
- if (column in [2, 3]) or (not row == lastrow):
+ if (reduced_inner_cols <= column < (ncols - reduced_outer_cols)) or (not row == lastrow):
cutouts.append(key_place(plate_pcb_cutout(side=side), column, row))
# cutouts = union(cutouts)
@@ -531,15 +570,16 @@ def plate_pcb_cutouts(side="right"):
return cutouts
-def caps():
+def caps(cap_type="MX"):
caps = None
+
for column in range(ncols):
for row in range(nrows):
- if (column in [2, 3]) or (not row == lastrow):
+ if (reduced_inner_cols <= column < (ncols - reduced_outer_cols)) or (not row == lastrow):
if caps is None:
- caps = key_place(sa_cap(), column, row)
+ caps = key_place(keycap(), column, row)
else:
- caps = add([caps, key_place(sa_cap(), column, row)])
+ caps = add([caps, key_place(keycap(), column, row)])
return caps
@@ -595,7 +635,7 @@ def connectors():
debugprint('connectors()')
hulls = []
for column in range(ncols - 1):
- if (column in [2]) or (not reduced_outer_keys):
+ if reduced_inner_cols <= column < (ncols - reduced_outer_cols-1):
iterrows = lastrow+1
else:
iterrows = lastrow
@@ -609,7 +649,7 @@ def connectors():
hulls.append(triangle_hulls(places))
for column in range(ncols):
- if (column in [2, 3]) or (not reduced_outer_keys):
+ if reduced_inner_cols <= column < (ncols - reduced_outer_cols):
iterrows = lastrow
else:
iterrows = cornerrow
@@ -622,7 +662,7 @@ def connectors():
hulls.append(triangle_hulls(places))
for column in range(ncols - 1):
- if (column in [2]) or (not reduced_outer_keys):
+ if (reduced_inner_cols <= column < (ncols - reduced_outer_cols-1)):
iterrows = lastrow
else:
iterrows = cornerrow
@@ -634,21 +674,21 @@ def connectors():
places.append(key_place(web_post_tl(), column + 1, row + 1))
hulls.append(triangle_hulls(places))
- if reduced_outer_keys:
- if column == 1:
- places = []
- places.append(key_place(web_post_bl(), column + 1, iterrows))
- places.append(key_place(web_post_br(), column, iterrows))
- places.append(key_place(web_post_tl(), column + 1, iterrows + 1))
- places.append(key_place(web_post_bl(), column + 1, iterrows + 1))
- hulls.append(triangle_hulls(places))
- if column == 3:
- places = []
- places.append(key_place(web_post_br(), column, iterrows))
- places.append(key_place(web_post_bl(), column + 1, iterrows))
- places.append(key_place(web_post_tr(), column, iterrows + 1))
- places.append(key_place(web_post_br(), column, iterrows + 1))
- hulls.append(triangle_hulls(places))
+
+ if column == (reduced_inner_cols-1):
+ places = []
+ places.append(key_place(web_post_bl(), column + 1, iterrows))
+ places.append(key_place(web_post_br(), column, iterrows))
+ places.append(key_place(web_post_tl(), column + 1, iterrows + 1))
+ places.append(key_place(web_post_bl(), column + 1, iterrows + 1))
+ hulls.append(triangle_hulls(places))
+ if column == (ncols - reduced_outer_cols - 1):
+ places = []
+ places.append(key_place(web_post_br(), column, iterrows))
+ places.append(key_place(web_post_bl(), column + 1, iterrows))
+ places.append(key_place(web_post_tr(), column, iterrows + 1))
+ places.append(key_place(web_post_br(), column, iterrows + 1))
+ hulls.append(triangle_hulls(places))
return union(hulls)
@@ -662,7 +702,9 @@ def connectors():
def thumborigin():
# debugprint('thumborigin()')
- origin = key_position([mount_width / 2, -(mount_height / 2), 0], 1, cornerrow)
+
+ corner = cornerrow if reduced_inner_cols > 0 else lastrow
+ origin = key_position([mount_width / 2, -(mount_height / 2), 0], 1, corner)
for i in range(len(origin)):
origin[i] = origin[i] + thumb_offsets[i]
@@ -933,9 +975,9 @@ def thumb_pcb_plate_cutouts(side='right', style_override=None):
return default_thumb_pcb_plate_cutouts(side)
def default_thumbcaps():
- t1 = default_thumb_1x_layout(sa_cap(1), cap=True)
+ t1 = default_thumb_1x_layout(keycap(1), cap=True)
if not default_1U_cluster:
- t1.add(default_thumb_15x_layout(sa_cap(1.5), cap=True))
+ t1.add(default_thumb_15x_layout(keycap(1.5), cap=True))
return t1
@@ -1145,9 +1187,14 @@ def default_thumb_connectors():
def mini_thumb_tr_place(shape):
- shape = rotate(shape, [14, -15, 10])
- shape = translate(shape, thumborigin())
- shape = translate(shape, [-15, -10, 5])
+ if mini_index_key:
+ shape = rotate(shape, [-25, 25, 0])
+ shape = translate(shape, thumborigin())
+ shape = translate(shape, [-12.5, -10, 2])
+ else:
+ shape = rotate(shape, [14, -15, 10])
+ shape = translate(shape, thumborigin())
+ shape = translate(shape, [-15, -10, 5])
return shape
@@ -1195,8 +1242,8 @@ def mini_thumb_15x_layout(shape):
def mini_thumbcaps():
- t1 = mini_thumb_1x_layout(sa_cap(1))
- t15 = mini_thumb_15x_layout(rotate(sa_cap(1), [0, 0, rad2deg(pi / 2)]))
+ t1 = mini_thumb_1x_layout(keycap(1))
+ t15 = mini_thumb_15x_layout(rotate(keycap(1), [0, 0, rad2deg(pi / 2)]))
return t1.add(t15)
@@ -1376,8 +1423,8 @@ def minidox_thumb_fx_layout(shape):
])
def minidox_thumbcaps():
- t1 = minidox_thumb_1x_layout(sa_cap(1))
- # t1.add(minidox_thumb_15x_layout(rotate(sa_cap(1), [0, 0, rad2deg(pi / 2)])))
+ t1 = minidox_thumb_1x_layout(keycap(1))
+ # t1.add(minidox_thumb_15x_layout(rotate(keycap(1), [0, 0, rad2deg(pi / 2)])))
return t1
@@ -1545,8 +1592,8 @@ def carbonfet_thumb_15x_layout(shape, plate=True):
def carbonfet_thumbcaps():
- t1 = carbonfet_thumb_1x_layout(sa_cap(1))
- t15 = carbonfet_thumb_15x_layout(rotate(sa_cap(1.5), [0, 0, rad2deg(pi / 2)]))
+ t1 = carbonfet_thumb_1x_layout(keycap(1))
+ t15 = carbonfet_thumb_15x_layout(rotate(keycap(1.5), [0, 0, rad2deg(pi / 2)]))
return t1.add(t15)
@@ -1806,9 +1853,9 @@ def trackball_layout(shape):
def tbjs_thumbcaps():
- t1 = tbjs_thumb_1x_layout(sa_cap(1))
- # t1 = tbjs_thumb_fx_layout(sa_cap(1))
- # t1.add(tbjs_thumb_15x_layout(rotate(sa_cap(1), [0, 0, rad2deg(pi / 2)])))
+ t1 = tbjs_thumb_1x_layout(keycap(1))
+ # t1 = tbjs_thumb_fx_layout(keycap(1))
+ # t1.add(tbjs_thumb_15x_layout(rotate(keycap(1), [0, 0, rad2deg(pi / 2)])))
return t1
@@ -2087,7 +2134,7 @@ def tbcj_thumb_pcb_plate_cutouts(side="right"):
return t
def tbcj_thumbcaps():
- t = tbcj_thumb_layout(sa_cap(1))
+ t = tbcj_thumb_layout(keycap(1))
return t
@@ -2396,12 +2443,14 @@ def right_wall(skeleton=False):
shape = None
+ corner = cornerrow if reduced_outer_cols > 0 else lastrow
+
shape = union([shape, key_wall_brace(
lastcol, y, 1, 0, web_post_tr(), lastcol, y, 1, 0, web_post_br(),
skeleton=skeleton,
)])
- for i in range(cornerrow):
+ for i in range(corner):
y = i + 1
shape = union([shape, key_wall_brace(
lastcol, y - 1, 1, 0, web_post_br(), lastcol, y, 1, 0, web_post_tr(),
@@ -2417,7 +2466,7 @@ def right_wall(skeleton=False):
shape = union([
shape,
key_wall_brace(
- lastcol, cornerrow, 0, -1, web_post_br(), lastcol, cornerrow, 1, 0, web_post_br(),
+ lastcol, corner, 0, -1, web_post_br(), lastcol, corner, 1, 0, web_post_br(),
skeleton=skeleton
),
])
@@ -2438,14 +2487,15 @@ def left_wall(side='right', skeleton=False):
skeleton=skeleton,
)])
- # for i in range(lastrow):
- for i in range(cornerrow+1):
+ corner = cornerrow if reduced_inner_cols > 0 else lastrow
+
+ for i in range(corner+1):
y = i
- low = (y == (cornerrow))
+ low = (y == (corner))
temp_shape1 = wall_brace(
(lambda sh: left_key_place(sh, y, 1, side=side)), -1, 0, web_post(),
(lambda sh: left_key_place(sh, y, -1, low_corner=low, side=side)), -1, 0, web_post(),
- skeleton=skeleton and (y < (cornerrow)),
+ skeleton=skeleton and (y < (corner)),
)
shape = union([shape, temp_shape1])
@@ -2458,13 +2508,13 @@ def left_wall(side='right', skeleton=False):
shape = union([shape, temp_shape2])
- for i in range(cornerrow):
+ for i in range(corner):
y = i + 1
- low = (y == (cornerrow))
+ low = (y == (corner))
temp_shape1 = wall_brace(
(lambda sh: left_key_place(sh, y - 1, -1, side=side)), -1, 0, web_post(),
(lambda sh: left_key_place(sh, y, 1, side=side)), -1, 0, web_post(),
- skeleton=skeleton and (y < (cornerrow)),
+ skeleton=skeleton and (y < (corner)),
)
shape = union([shape, temp_shape1])
@@ -2484,26 +2534,84 @@ def front_wall(skeleton=False):
print('front_wall()')
shape = None
- shape = union([shape,key_wall_brace(
- 3, lastrow, 0, -1, web_post_bl(), 3, lastrow, 0.5, -1, web_post_br()
- )])
- shape = union([shape,key_wall_brace(
- 3, lastrow, 0.5, -1, web_post_br(), 4, cornerrow, .5, -1, web_post_bl()
- )])
- shape = union([shape,key_wall_brace(
- 4, cornerrow, .5, -1, web_post_bl(), 4, cornerrow, 0, -1, web_post_br()
- )])
+ # shape = union([shape,key_wall_brace(
+ # 3, lastrow, 0, -1, web_post_bl(), 3, lastrow, 0.5, -1, web_post_br()
+ # )])
+ # shape = union([shape,key_wall_brace(
+ # 3, lastrow, 0.5, -1, web_post_br(), 4, cornerrow, .5, -1, web_post_bl()
+ # )])
+ # shape = union([shape,key_wall_brace(
+ # 4, cornerrow, .5, -1, web_post_bl(), 4, cornerrow, 0, -1, web_post_br()
+ # )])
+
+ # for i in range(ncols - 5):
+ # x = i + 5
+ #
+ # shape = union([shape,key_wall_brace(
+ # x, cornerrow, 0, -1, web_post_bl(), x, cornerrow, 0, -1, web_post_br()
+ # )])
+ #
+ # shape = union([shape, key_wall_brace(
+ # x, cornerrow, 0, -1, web_post_bl(), x - 1, cornerrow, 0, -1, web_post_br()
+ # )])
+
+ # corner = lastrow if 4 < (ncols - reduced_outer_cols) else cornerrow
+ corner = cornerrow
+ if reduced_outer_cols>0:
+ offset_col = ncols - reduced_outer_cols
+ else:
+ offset_col = 99
+
+ for i in range(ncols - 3):
+ x = i + 3
+ print("col {}".format(x))
+ if x < (offset_col - 1):
+ print("pre-offset")
+ if x > 3:
+ shape = union([shape, key_wall_brace(
+ x-1, lastrow, 0, -1, web_post_br(), x, lastrow, 0, -1, web_post_bl()
+ )])
+ shape = union([shape, key_wall_brace(
+ x, lastrow, 0, -1, web_post_bl(), x, lastrow, 0, -1, web_post_br()
+ )])
+ elif x < (offset_col):
+ print("offset setup")
+ if x > 3:
+ shape = union([shape, key_wall_brace(
+ x-1, lastrow, 0, -1, web_post_br(), x, lastrow, 0, -1, web_post_bl()
+ )])
+ shape = union([shape, key_wall_brace(
+ x, lastrow, 0, -1, web_post_bl(), x, lastrow, 0.5, -1, web_post_br()
+ )])
+
+ elif x == (offset_col):
+ print("offset")
+ shape = union([shape, key_wall_brace(
+ x - 1, lastrow, 0.5, -1, web_post_br(), x, cornerrow, .5, -1, web_post_bl()
+ )])
+ shape = union([shape, key_wall_brace(
+ x, cornerrow, .5, -1, web_post_bl(), x, cornerrow, 0, -1, web_post_br()
+ )])
+
+ elif x == (offset_col + 1):
+ print("offset completion")
+ shape = union([shape, key_wall_brace(
+ x, cornerrow, 0, -1, web_post_bl(), x - 1, cornerrow, 0, -1, web_post_br()
+ )])
+ shape = union([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 = union([shape,key_wall_brace(
- x, cornerrow, 0, -1, web_post_bl(), x, cornerrow, 0, -1, web_post_br()
- )])
+ else:
+ print("post offset")
+ shape = union([shape, key_wall_brace(
+ x, cornerrow, 0, -1, web_post_bl(), x - 1, corner, 0, -1, web_post_br()
+ )])
+ shape = union([shape, key_wall_brace(
+ x, cornerrow, 0, -1, web_post_bl(), x, corner, 0, -1, web_post_br()
+ )])
- shape = union([shape, key_wall_brace(
- x, cornerrow, 0, -1, web_post_bl(), x - 1, cornerrow, 0, -1, web_post_br()
- )])
return shape
diff --git a/src/generate_configuration.py b/src/generate_configuration.py
index 0d5cd07..c6ed586 100644
--- a/src/generate_configuration.py
+++ b/src/generate_configuration.py
@@ -21,7 +21,7 @@ shape_config = {
'save_dir': '.',
'config_name': "DM",
- 'show_caps': False,
+ 'show_caps': 'MX',
'show_pcbs': False, #only runs if caps are shown, easist place to initially inject geometry
'nrows': 5, #5, # key rows
@@ -38,7 +38,8 @@ shape_config = {
'column_style_gt5': "orthographic",
'column_style': "standard", # options include :standard, :orthographic, and :fixed
- 'reduced_outer_keys': True,
+ 'reduced_inner_cols': 2, #currently supports 0 or 2 due to thumb cluster attachment
+ 'reduced_outer_cols': 0,
'thumb_offsets': [6, -3, 7],
@@ -67,6 +68,8 @@ shape_config = {
'minidox_Usize': 1.6,
# Thumb plate rotations, anything other than 90 degree increments WILL NOT WORK.
+ 'mini_index_key': True,
+
# Screw locations and extra screw locations for separable thumb, all from thumb origin
# Pulled out of hardcoding as drastic changes to the geometry may require fixes to the screw mounts.
# First screw in separable should be similar to the standard location as it will receive the same modifiers.
diff --git a/src/generate_configuration_mklasklasd.py b/src/generate_configuration_mklasklasd.py
new file mode 100644
index 0000000..4263a1f
--- /dev/null
+++ b/src/generate_configuration_mklasklasd.py
@@ -0,0 +1,506 @@
+import sys
+import getopt
+import os
+import json
+
+
+pi = 3.14159
+d2r = pi / 180
+r2d = 180 / pi
+
+shape_config = {
+
+ 'ENGINE': 'solid', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade
+ # 'ENGINE': 'cadquery', # 'solid' = solid python / OpenSCAD, 'cadquery' = cadquery / OpenCascade
+
+
+ ######################
+ ## Shape parameters ##
+ ######################
+
+ 'save_dir': '.',
+ 'config_name': "DM",
+
+ 'show_caps': False,
+ 'show_pcbs': False, #only runs if caps are shown, easist place to initially inject geometry
+
+ 'nrows': 4, #5, # key rows
+ 'ncols': 5, #6, # key columns
+
+ 'alpha': pi / 12.0, # curvature of the columns
+ 'beta': pi / 36.0, # curvature of the rows
+ 'centercol': 3, # controls left_right tilt / tenting (higher number is more tenting)
+ 'centerrow_offset': 3, # rows from max, controls front_back tilt
+ 'tenting_angle': pi / 12.0, # or, change this for more precise tenting control
+
+ # symmetry states if it is a symmetric or asymmetric bui. If asymmetric it doubles the generation time.
+ 'symmetry': "symmetric", # "asymmetric" or "symmetric"
+
+ 'column_style_gt5': "orthographic",
+ 'column_style': "standard", # options include :standard, :orthographic, and :fixed
+ 'reduced_inner_cols': 2, #currently supports 0 or 2 due to thumb cluster attachment
+ 'reduced_outer_cols': 0,
+
+ 'thumb_offsets': [6, -3, 7],
+ 'keyboard_z_offset': (
+ 11 # controls overall height# original=9 with centercol=3# use 16 for centercol=2
+ ),
+
+
+ 'extra_width': 2.5, # extra space between the base of keys# original= 2
+ 'extra_height': 1.0, # original= 0.5
+
+
+ 'web_thickness': 4.0 + 1.1,
+ 'post_size': 0.1,
+ # post_adj': post_size / 2
+ 'post_adj': 0,
+
+ ##############################
+ # THUMB PARAMETERS
+ ##############################
+
+ # 'DEFAULT' 6-key, 'MINI' 5-key, 'CARBONFET' 6-key, 'MINIDOX' 3-key, 'TRACKBALL_ORBYL', 'TRACKBALL_CJ'
+ 'thumb_style': 'MINI',
+ 'default_1U_cluster': True, # only used with default, makes top right thumb cluster key 1U
+ # Thumb key size. May need slight oversizing, check w/ caps. Additional spacing will be automatically added for larger keys.
+ 'minidox_Usize': 1.6,
+ # Thumb plate rotations, anything other than 90 degree increments WILL NOT WORK.
+ 'mini_index_key': True,
+ # Screw locations and extra screw locations for separable thumb, all from thumb origin
+ # Pulled out of hardcoding as drastic changes to the geometry may require fixes to the screw mounts.
+ # First screw in separable should be similar to the standard location as it will receive the same modifiers.
+ 'default_thumb_screw_xy_locations': [[-21, -58]],
+ 'default_separable_thumb_screw_xy_locations': [[-21, -58]],
+ 'mini_thumb_screw_xy_locations': [[-29, -52]],
+ 'mini_separable_thumb_screw_xy_locations': [[-29, -52], [-62, 10], [12, -25]],
+ 'minidox_thumb_screw_xy_locations': [[-37, -34]],
+ 'minidox_separable_thumb_screw_xy_locations': [[-37, -34], [-62, 12], [10, -25]],
+ 'carbonfet_thumb_screw_xy_locations': [[-48, -37]],
+ 'carbonfet_separable_thumb_screw_xy_locations': [[-48, -37], [-52, 10], [12, -35]],
+ 'orbyl_thumb_screw_xy_locations': [[-53, -68]],
+ 'orbyl_separable_thumb_screw_xy_locations': [[-53, -68], [-66, 8], [10, -40]],
+ 'tbcj_thumb_screw_xy_locations': [[-40, -75]],
+ 'tbcj_separable_thumb_screw_xy_locations': [[-40, -75], [-63, 10], [15, -40]],
+
+ 'thumb_plate_tr_rotation': 0.0, # Top right plate rotation tweaks as thumb cluster is crowded for hot swap, etc.
+ 'thumb_plate_tl_rotation': 0.0, # Top left plate rotation tweaks as thumb cluster is crowded for hot swap, etc.
+ 'thumb_plate_mr_rotation': 0.0, # Mid right plate rotation tweaks as thumb cluster is crowded for hot swap, etc.
+ 'thumb_plate_ml_rotation': 0.0, # Mid left plate rotation tweaks as thumb cluster is crowded for hot swap, etc.
+ 'thumb_plate_br_rotation': 0.0, # Bottom right plate rotation tweaks as thumb cluster is crowded for hot swap, etc.
+ 'thumb_plate_bl_rotation': 0.0, # Bottom right plate rotation tweaks as thumb cluster is crowded for hot swap, etc.
+ ##############################
+ # EXPERIMENTAL
+ 'separable_thumb': False, #creates a separable thumb section with additional screws to hold it down. Only attached at base.
+ ##############################
+
+ ###################################
+ ## Trackball in Wall ##
+ ###################################
+ 'trackball_in_wall': False, # Separate trackball option, placing it in the OLED area
+ 'tbiw_ball_center_row': 0.2, # up from cornerrow instead of down from top
+ 'tbiw_translational_offset': (0.0, 0.0, 0.0),
+ 'tbiw_rotation_offset': (0.0, 0.0, 0.0),
+ 'tbiw_left_wall_x_offset_override': 50.0,
+ 'tbiw_left_wall_z_offset_override': 0.0,
+ 'tbiw_left_wall_lower_x_offset': 0.0,
+ 'tbiw_left_wall_lower_y_offset': 0.0,
+ 'tbiw_left_wall_lower_z_offset': 0.0,
+
+ 'tbiw_oled_center_row': .75, # not none, offsets are from this position
+ 'tbiw_oled_translation_offset': (-3.5, 0, 1.5), # Z offset tweaks are expected depending on curvature and OLED mount choice.
+ 'tbiw_oled_rotation_offset': (0, 0, 0),
+
+ ##########################################################################
+ ## Finger Trackball in Wall EXPERIMENTAL WIP!!!! ##
+ ##########################################################################
+ 'finger_trackball_in_wall': False, # Separate trackball option, placing it in the OLED area
+ 'tbiw_ball_center_column': 0.2, # up from cornerrow instead of down from top
+ 'tbiw_translational_offset': (0.0, 0.0, 0.0),
+ 'tbiw_rotation_offset': (0.0, 0.0, 0.0),
+ 'tbiw_top_wall_y_offset_override': 50.0,
+ 'tbiw_top_wall_z_offset_override': 0.0,
+ 'tbiw_top_wall_extension_cols': 4,
+
+
+
+ ###########################################
+ ## Trackball JS / ORBYL Thumb Cluster ##
+ ##########################################
+ 'other_thumb': 'DEFAULT', # cluster used for second thumb except if ball_side == 'both'
+ 'tbjs_key_diameter': 70,
+ 'tbjs_Uwidth': 1.2, # size for inner key near trackball
+ 'tbjs_Uheight': 1.2, # size for inner key near trackball
+
+ # Offsets are per key and are applied before rotating into place around the ball
+ # X and Y act like Tangential and Radial around the ball
+ # 'tbjs_translation_offset': (0, 0, 10), # applied to the whole assy
+ # 'tbjs_rotation_offset': (0, 10, 0), # applied to the whole assy
+ 'tbjs_translation_offset': (0, 0, 2), # applied to the whole assy
+ 'tbjs_rotation_offset': (0, -8, 0), # applied to the whole assy
+ 'tbjs_key_translation_offsets': [
+ (0.0, 0.0, -3.0-5),
+ (0.0, 0.0, -3.0-5),
+ (0.0, 0.0, -3.0-5),
+ (0.0, 0.0, -3.0-5),
+ ],
+ 'tbjs_key_rotation_offsets': [
+ (0.0, 0.0, 0.0),
+ (0.0, 0.0, 0.0),
+ (0.0, 0.0, 0.0),
+ (0.0, 0.0, 0.0),
+ ],
+
+ ###################################
+ ## Trackball CJ Thumb Cluster ##
+ ###################################
+ 'tbcj_inner_diameter': 42,
+ 'tbcj_thickness': 2,
+ 'tbcj_outer_diameter': 53,
+
+
+ ###################################
+ ## Trackball General ##
+ ###################################
+ 'trackball_modular': False, # Added, creates a hole with space for the lip size listed below.
+ 'trackball_modular_lip_width': 3.0, # width of lip cleared out in ring location
+ 'trackball_modular_ball_height': 3.0, # height of ball from ring , used to create identical position to fixed.
+ 'trackball_modular_ring_height': 10.0, # height mount ring down from ball height. Covers gaps on elevated ball.
+ 'trackball_modular_clearance': 0.5, # height of ball from ring, used to create identical position to fixed.
+
+ 'ball_side': 'both', #'left', 'right', or 'both'
+ 'ball_diameter': 34.0,
+ 'ball_wall_thickness': 3, # should not be changed unless the import models are changed.
+ 'ball_gap': 1.0,
+ 'trackball_hole_diameter': 36.5,
+ 'trackball_hole_height': 40,
+ 'trackball_plate_thickness': 2,
+ 'trackball_plate_width': 2,
+ # Removed trackball_rotation, ball_z_offset. and trackball_sensor_rotation and added more flexibility.
+ 'tb_socket_translation_offset': (0, 0, 2.0), # applied to the socket and sensor, large values will cause web/wall issues.
+ 'tb_socket_rotation_offset': (0, 0, 0), # applied to the socket and sensor, large values will cause web/wall issues.
+ 'tb_sensor_translation_offset': (0, 0, 0), #deviation from socket offsets, for fixing generated geometry issues
+ 'tb_sensor_rotation_offset': (0, 0, 0), #deviation from socket offsets, for changing the sensor roll orientation
+
+ ##############################
+ # EXPERIMENTAL PARAMETERS
+ ##############################
+ 'pinky_1_5U': False, # LEAVE AS FALSE, CURRENTLY BROKEN
+ 'first_1_5U_row': 0,
+ 'last_1_5U_row': 5,
+
+ 'skeletal': False,
+ ##############################
+
+
+
+ 'wall_z_offset': 15, # length of the first downward_sloping part of the wall
+ 'wall_x_offset': 5, # offset in the x and/or y direction for the first downward_sloping part of the wall (negative)
+ 'wall_y_offset': 6, # offset in the x and/or y direction for the first downward_sloping part of the wall (negative)
+ 'left_wall_x_offset': 12, # specific values for the left side due to the minimal wall.
+ 'left_wall_z_offset': 3, # specific values for the left side due to the minimal wall.
+ 'left_wall_lower_x_offset': 0, # specific values for the lower left corner.
+ 'left_wall_lower_y_offset': 0, # specific values for the lower left corner.
+ 'left_wall_lower_z_offset': 0,
+ 'wall_thickness': 4.5, # wall thickness parameter used on upper/mid stage of the wall
+ 'wall_base_y_thickness': 4.5, # wall thickness at the lower stage
+ 'wall_base_x_thickness': 4.5, # wall thickness at the lower stage
+
+ 'wall_base_back_thickness': 4.5, # wall thickness at the lower stage in the specifically in back for interface.
+
+ ## Settings for column_style == :fixed
+ ## The defaults roughly match Maltron settings
+ ## http://patentimages.storage.googleapis.com/EP0219944A2/imgf0002.png
+ ## fixed_z overrides the z portion of the column ofsets above.
+ ## NOTE: THIS DOESN'T WORK QUITE LIKE I'D HOPED.
+ 'fixed_angles': [d2r * 10, d2r * 10, 0, 0, 0, d2r * -15, d2r * -15],
+ 'fixed_x': [-41.5, -22.5, 0, 20.3, 41.4, 65.5, 89.6], # relative to the middle finger
+ 'fixed_z': [12.1, 8.3, 0, 5, 10.7, 14.5, 17.5],
+ 'fixed_tenting': d2r * 0,
+
+ #################
+ ## Switch Hole ##
+ #################
+
+ # plate options are
+ # 'HOLE' = a square hole. Also useful for applying custom plate files.
+ # 'NUB' = original side nubs.
+ # 'UNDERCUT' = snap fit undercut. May require CLIP_THICKNESS and possibly CLIP_UNDERCUT tweaking
+ # and/or filing to get proper snap.
+ # 'NOTCH' = snap fit undercut only near switch clip. May require CLIP_THICKNESS and possibly CLIP_UNDERCUT
+ # tweaking and/or filing to get proper snap.
+ # 'HS_NUB' = hot swap underside with nubs.
+ # 'HS_UNDERCUT' = hot swap underside with undercut. Does not generate properly. Hot swap step needs to be modified.
+ # 'HS_NOTCH' = hot swap underside with notch. Does not generate properly. Hot swap step needs to be modified.
+ # 'plate_style': 'NUB',
+ 'plate_style': 'NOTCH',
+
+ 'hole_keyswitch_height': 14.0,
+ 'hole_keyswitch_width': 14.0,
+
+ 'nub_keyswitch_height': 14.4,
+ 'nub_keyswitch_width': 14.4,
+
+ 'undercut_keyswitch_height': 14.0,
+ 'undercut_keyswitch_width': 14.0,
+ 'notch_width': 6.0, # If using notch, it is identical to undecut, but only locally by the switch clip
+
+ 'sa_profile_key_height': 12.7,
+ 'sa_length': 18.5,
+ 'sa_double_length': 37.5,
+ 'plate_thickness': 4 + 1.1,
+
+ 'plate_rim': 1.5 + 0.5,
+ # Undercut style dimensions
+ 'clip_thickness': 1.1,
+ 'clip_undercut': 1.0,
+ 'undercut_transition': .2, # NOT FUNCTIONAL WITH OPENSCAD, ONLY WORKS WITH CADQUERY
+
+ # Custom plate step file
+ 'plate_file': None,
+ 'plate_offset': 0.0,
+
+ ##########################
+ ## OLED Mount Location
+ ##########################
+ # Initial pass will be manual placement. Can be used to create other mounts as well.
+ # Mount type options:
+ # None or 'NONE' = No OLED mount
+ # 'UNDERCUT' = Simple rectangle with undercut for clip in item
+ # 'SLIDING' = Features to slide the OLED in place and use a pin or block to secure from underneath.
+ # 'CLIP' = Features to set the OLED in a frame a snap a bezel down to hold it in place.
+
+ 'oled_mount_type': 'CLIP',
+ 'oled_center_row': 1.25, # if not None, this will override the oled_mount_location_xyz and oled_mount_rotation_xyz settings
+ 'oled_translation_offset': (0, 0, 4), # Z offset tweaks are expected depending on curvature and OLED mount choice.
+ 'oled_rotation_offset': (0, 0, 0),
+
+ 'oled_configurations': {
+ 'UNDERCUT':{
+ # Common parameters
+ 'oled_mount_width': 15.0,
+ 'oled_mount_height': 35.0,
+ 'oled_mount_rim': 3.0,
+ 'oled_mount_depth': 6.0,
+ 'oled_mount_cut_depth': 20.0,
+ 'oled_mount_location_xyz': (-80.0, 20.0, 45.0), # will be overwritten if oled_center_row is not None
+ 'oled_mount_rotation_xyz': (13.0, 0.0, -6.0), # will be overwritten if oled_center_row is not None
+ 'oled_left_wall_x_offset_override': 28.0,
+ 'oled_left_wall_z_offset_override': 0.0,
+ 'oled_left_wall_lower_y_offset': 12.0,
+ 'oled_left_wall_lower_z_offset': 5.0,
+
+ # 'UNDERCUT' Parameters
+ 'oled_mount_undercut': 1.0,
+ 'oled_mount_undercut_thickness': 2.0,
+ },
+ 'SLIDING': {
+ # Common parameters
+ 'oled_mount_width': 12.5, # width of OLED, plus clearance
+ 'oled_mount_height': 25.0, # length of screen
+ 'oled_mount_rim': 2.5,
+ 'oled_mount_depth': 8.0,
+ 'oled_mount_cut_depth': 20.0,
+ 'oled_mount_location_xyz': (-78.0, 10.0, 41.0), # will be overwritten if oled_center_row is not None
+ 'oled_mount_rotation_xyz': (6.0, 0.0, -3.0), # will be overwritten if oled_center_row is not None
+ 'oled_left_wall_x_offset_override': 24.0,
+ 'oled_left_wall_z_offset_override': 0.0,
+ 'oled_left_wall_lower_y_offset': 12.0,
+ 'oled_left_wall_lower_z_offset': 5.0,
+
+ # 'SLIDING' Parameters
+ 'oled_thickness': 4.2, # thickness of OLED, plus clearance. Must include components
+ 'oled_edge_overlap_end': 6.5, # length from end of viewable screen to end of PCB
+ 'oled_edge_overlap_connector': 5.5, # length from end of viewable screen to end of PCB on connection side.
+ 'oled_edge_overlap_thickness': 2.5, # thickness of material over edge of PCB
+ 'oled_edge_overlap_clearance': 2.5, # Clearance to insert PCB before laying down and sliding.
+ 'oled_edge_chamfer': 2.0,
+ },
+ 'CLIP': {
+ # Common parameters
+ 'oled_mount_width': 12.5, # whole OLED width
+ 'oled_mount_height': 39.0, # whole OLED length
+ 'oled_mount_rim': 2.0,
+ 'oled_mount_depth': 7.0,
+ 'oled_mount_cut_depth': 20.0,
+ 'oled_mount_location_xyz': (-78.0, 20.0, 42.0), # will be overwritten if oled_center_row is not None
+ 'oled_mount_rotation_xyz': (12.0, 0.0, -6.0), # will be overwritten if oled_center_row is not None
+ 'oled_left_wall_x_offset_override': 24.0,
+ 'oled_left_wall_z_offset_override': 0.0,
+ 'oled_left_wall_lower_y_offset': 5.0,
+ 'oled_left_wall_lower_z_offset': 5.0,
+
+ # 'CLIP' Parameters
+ 'oled_thickness': 4.2, # thickness of OLED, plus clearance. Must include components
+ 'oled_mount_bezel_thickness': 3.5, # z thickness of clip bezel
+ 'oled_mount_bezel_chamfer': 2.0, # depth of the 45 degree chamfer
+ 'oled_mount_connector_hole': 6.0,
+ 'oled_screen_start_from_conn_end': 6.5,
+ 'oled_screen_length': 24.5,
+ 'oled_screen_width': 10.5,
+ 'oled_clip_thickness': 1.5,
+ 'oled_clip_width': 6.0,
+ 'oled_clip_overhang': 1.0,
+ 'oled_clip_extension': 5.0,
+ 'oled_clip_width_clearance': 0.5,
+ 'oled_clip_undercut': 0.5,
+ 'oled_clip_undercut_thickness': 2.5,
+ 'oled_clip_y_gap': .2,
+ 'oled_clip_z_gap': .2,
+ }
+ },
+
+ 'screws_offset': 'INSIDE', # 'OUTSIDE', 'INSIDE', 'ORIGINAL'
+
+ 'screw_insert_height': 3.8,
+
+ # 'screw_insert_bottom_radius': 5.31 / 2, #Designed for inserts
+ # 'screw_insert_top_radius': 5.1 / 2, #Designed for inserts
+
+ 'screw_insert_bottom_radius': 2.5 / 2, # Designed for self tapping
+ 'screw_insert_top_radius': 2.5 / 2, # Designed for self tapping
+
+ 'screw_insert_outer_radius': 4.25, # Common to keep interface to base
+
+ # Does anyone even use these? I think they just get in the way.
+ 'wire_post_height': 7,
+ 'wire_post_overhang': 3.5,
+ 'wire_post_diameter': 2.6,
+
+
+
+
+ ###################################
+ ## Controller Mount / Connectors ##
+ ###################################
+ # connector options are
+ # 'RJ9_USB_WALL' = Standard internal plate with RJ9 opening and square cutout for connection.
+ # 'USB_WALL' = Standard internal plate with a square cutout for connection, no RJ9.
+ # 'RJ9_USB_TEENSY' = Teensy holder
+ # 'USB_TEENSY' = Teensy holder, no RJ9
+ # 'EXTERNAL' = square cutout for a holder such as the one from lolligagger.
+ # 'NONE' = No openings in the back.
+ 'controller_mount_type': 'EXTERNAL',
+
+ 'external_holder_height': 12.5,
+ 'external_holder_width': 28.75,
+ 'external_holder_xoffset': -5.0,
+ 'external_holder_yoffset': -4.5, #Tweak this value to get the right undercut for the tray engagement.
+
+ # Offset is from the top inner corner of the top inner key.
+
+ ###################################
+ ## PCB Screw Mount ##
+ ###################################
+ "pcb_mount_ref_offset": [0, -5, 0],
+ "pcb_holder_size": [34.6, 7, 4],
+ "pcb_holder_offset": [8.9, 0, 0],
+
+ "pcb_usb_hole_size": [7.5, 10.0, 4],
+ "pcb_usb_hole_offset": [15, 0, 4.5],
+
+ "wall_thinner_size": [34, 7, 10],
+
+ "trrs_hole_size": [3, 20],
+ "trrs_offset": [0, 0, 1.5],
+
+ "pcb_screw_hole_size": [.5, 10],
+ "pcb_screw_x_offsets": [- 5.5, 7.75, 22], # for the screw positions off of reference
+ "pcb_screw_y_offset": -2,
+
+
+ ###################################
+ ## Bottom Plate Dimensions
+ ###################################
+ # COMMON DIMENSION
+ 'screw_hole_diameter': 3,
+ # USED FOR CADQUERY ONLY
+ 'base_thickness': 3.0, # thickness in the middle of the plate
+ 'base_offset': 3.0, # Both start flat/flush on the bottom. This offsets the base up (if positive)
+ 'base_rim_thickness': 5.0, # thickness on the outer frame with screws
+ 'screw_cbore_diameter': 6.0,
+ 'screw_cbore_depth': 2.5,
+
+ # Offset is from the top inner corner of the top inner key.
+
+ ###################################
+ ## HOLES ON PLATE FOR PCB MOUNT
+ ###################################
+ 'plate_holes': True,
+ 'plate_holes_xy_offset': (0.0, 0.0),
+ 'plate_holes_width': 14.3,
+ 'plate_holes_height': 14.3,
+ 'plate_holes_diameter': 1.6,
+ 'plate_holes_depth': 20.0,
+
+ ###################################
+ ## EXPERIMENTAL
+ 'plate_pcb_clear': False,
+ 'plate_pcb_size': (18.5, 18.5, 5),
+ 'plate_pcb_offset': (0, 0, 0),# this is off of the back of the plate size.
+ ###################################
+
+ ###################################
+ ## SHOW PCB FOR FIT CHECK
+ ###################################
+ 'pcb_width': 18.0,
+ 'pcb_height': 18.0,
+ 'pcb_thickness': 1.5,
+ 'pcb_hole_diameter': 2,
+ 'pcb_hole_pattern_width': 14.3,
+ 'pcb_hole_pattern_height': 14.3,
+
+ ###################################
+ ## COLUMN OFFSETS
+ ####################################
+
+ 'column_offsets': [
+ [0, 0, 0],
+ [0, 0, 0],
+ [0, 2.82, -4.5],
+ [0, 0, 0],
+ [0, -6, 5],# REDUCED STAGGER
+ [0, -6, 5],# REDUCED STAGGER
+ [0, -6, 5],# NOT USED IN MOST FORMATS (7th column)
+ ],
+
+}
+
+ ####################################
+ ## END CONFIGURATION SECTION
+ ####################################
+
+def save_config():
+ # Check to see if the user has specified an alternate config
+ opts, args = getopt.getopt(sys.argv[1:], "", ["config=", "update="])
+ got_opts = False
+ for opt, arg in opts:
+ if opt in ('--update'):
+ with open(os.path.join(r"..", "configs", arg + '.json'), mode='r') as fid:
+ data = json.load(fid)
+ shape_config.update(data)
+ got_opts = True
+
+ for opt, arg in opts:
+ if opt in ('--config'):
+ # If a config file was specified, set the config_name and save_dir
+ shape_config['save_dir'] = arg
+ shape_config['config_name'] = arg
+ got_opts = True
+
+ # Write the config to ./configs/<config_name>.json
+ if got_opts:
+ with open(os.path.join(r"..", "configs", shape_config['config_name'] + '.json'), mode='w') as fid:
+ json.dump(shape_config, fid, indent=4)
+
+ else:
+ with open(os.path.join(r".", 'run_config.json'), mode='w') as fid:
+ json.dump(shape_config, fid, indent=4)
+
+
+if __name__ == '__main__':
+ save_config()
+
+ # HERE FOR QUICK TESTING, SHOULD BE COMMENTED ON COMMIT
+ from dactyl_manuform import *
+ run()
diff --git a/src/run_config.json b/src/run_config.json
index 01a8688..8337c8e 100644
--- a/src/run_config.json
+++ b/src/run_config.json
@@ -14,7 +14,8 @@
"symmetry": "symmetric",
"column_style_gt5": "orthographic",
"column_style": "standard",
- "reduced_outer_keys": true,
+ "reduced_inner_cols": 2,
+ "reduced_outer_cols": 0,
"thumb_offsets": [
6,
-3,
@@ -29,6 +30,7 @@
"thumb_style": "DEFAULT",
"default_1U_cluster": true,
"minidox_Usize": 1.6,
+ "mini_index_key": true,
"default_thumb_screw_xy_locations": [
[
-21,