summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dactyl_manuform.py177
-rw-r--r--src/generate_configuration.py44
-rw-r--r--src/helpers_blender.py3
-rw-r--r--src/helpers_cadquery.py31
-rw-r--r--src/helpers_solid.py31
-rw-r--r--src/run_config.json50
6 files changed, 277 insertions, 59 deletions
diff --git a/src/dactyl_manuform.py b/src/dactyl_manuform.py
index a04a291..9913086 100644
--- a/src/dactyl_manuform.py
+++ b/src/dactyl_manuform.py
@@ -4,6 +4,7 @@ import os.path as path
import getopt, sys
import json
import os
+import copy
from scipy.spatial import ConvexHull as sphull
@@ -273,30 +274,37 @@ def single_plate(cylinder_segments=100, side="right"):
return plate
def trackball_cutout(segments=100, side="right"):
- shape = cylinder(trackball_hole_diameter / 2, trackball_hole_height)
+ if trackball_modular:
+ hole_diameter = ball_diameter + 2 * (ball_gap + ball_wall_thickness + trackball_modular_clearance+trackball_modular_lip_width)-.1
+ shape = cylinder(hole_diameter / 2, trackball_hole_height)
+ else:
+ shape = cylinder(trackball_hole_diameter / 2, trackball_hole_height)
return shape
def trackball_socket(segments=100, side="right"):
- # shape = sphere(ball_diameter / 2)
- # cyl = cylinder(ball_diameter / 2 + 4, 20)
- # cyl = translate(cyl, (0, 0, -8))
- # shape = union([shape, cyl])
+ if trackball_modular:
+ hole_diameter = ball_diameter + 2 * (ball_gap + ball_wall_thickness + trackball_modular_clearance)
+ ring_diameter = hole_diameter + 2 * trackball_modular_lip_width
+ ring_height = trackball_modular_ring_height
+ ring_z_offset = mount_thickness - trackball_modular_ball_height
+ shape = cylinder(ring_diameter / 2, ring_height)
+ shape = translate(shape, (0, 0, -ring_height / 2 + ring_z_offset))
- tb_file = path.join(parts_path, r"trackball_socket_body_34mm")
- tbcut_file = path.join(parts_path, r"trackball_socket_cutter_34mm")
- sens_file = path.join(parts_path, r"trackball_sensor_mount")
- senscut_file = path.join(parts_path, r"trackball_sensor_cutter")
+ cutter = cylinder(hole_diameter / 2, ring_height + .2)
+ cutter = translate(cutter, (0, 0, -ring_height / 2 + ring_z_offset))
+ sensor = None
- # shape = import_file(tb_file)
- # # shape = difference(shape, [import_file(senscut_file)])
- # # shape = union([shape, import_file(sens_file)])
- # cutter = import_file(tbcut_file)
+ else:
+ tb_file = path.join(parts_path, r"trackball_socket_body_34mm")
+ tbcut_file = path.join(parts_path, r"trackball_socket_cutter_34mm")
+ sens_file = path.join(parts_path, r"trackball_sensor_mount")
+ senscut_file = path.join(parts_path, r"trackball_sensor_cutter")
- shape = import_file(tb_file)
- sensor = import_file(sens_file)
- cutter = import_file(tbcut_file)
- cutter = union([cutter, import_file(senscut_file)])
+ shape = import_file(tb_file)
+ sensor = import_file(sens_file)
+ cutter = import_file(tbcut_file)
+ cutter = union([cutter, import_file(senscut_file)])
# return shape, cutter
return shape, cutter, sensor
@@ -3233,8 +3241,130 @@ def external_mount_hole():
)
return shape
-def generate_trackball(pos, rot):
+
+pcb_mount_ref_position = key_position(
+ #TRRS POSITION IS REFERENCE BY CONVENIENCE
+ list(np.array(wall_locate3(0, 1)) + np.array([0, (mount_height / 2), 0])), 0, 0
+)
+
+pcb_mount_ref_position[0] = pcb_mount_ref_position[0] + pcb_mount_ref_offset[0]
+pcb_mount_ref_position[1] = pcb_mount_ref_position[1] + pcb_mount_ref_offset[1]
+pcb_mount_ref_position[2] = 0.0 + pcb_mount_ref_offset[2]
+
+def pcb_usb_hole():
+ debugprint('pcb_holder()')
+ pcb_usb_position = copy.deepcopy(pcb_mount_ref_position)
+ pcb_usb_position[0] = pcb_usb_position[0] + pcb_usb_hole_offset[0]
+ pcb_usb_position[1] = pcb_usb_position[1] + pcb_usb_hole_offset[1]
+ pcb_usb_position[2] = pcb_usb_position[2] + pcb_usb_hole_offset[2]
+
+ shape = box(*pcb_usb_hole_size)
+ shape = translate(shape,
+ (
+ pcb_usb_position[0],
+ pcb_usb_position[1],
+ pcb_usb_hole_size[2] / 2 + pcb_usb_hole_z_offset + usb_holder_thickness,
+ )
+ )
+ return shape
+
+
+
+pcb_holder_position = copy.deepcopy(pcb_mount_ref_position)
+pcb_holder_position[0] = pcb_holder_position[0] + pcb_holder_offset[0]
+pcb_holder_position[1] = pcb_holder_position[1] + pcb_holder_offset[1]
+pcb_holder_position[2] = pcb_holder_position[2] + pcb_holder_offset[2]
+pcb_holder_thickness = pcb_holder_size[2]
+
+def pcb_holder():
+ debugprint('pcb_holder()')
+ shape = box(*pcb_holder_size)
+ shape = translate(shape,
+ (
+ pcb_holder_position[0],
+ pcb_holder_position[1] - pcb_holder_size[1] / 2,
+ pcb_holder_thickness / 2,
+ )
+ )
+ return shape
+
+
+def wall_thinner():
+ debugprint('wall_thinner()')
+ shape = box(*wall_thinner_size)
+ shape = translate(shape,
+ (
+ pcb_holder_position[0],
+ pcb_holder_position[1] - wall_thinner_size[1]/2,
+ wall_thinner_size[2]/2 + pcb_holder_thickness,
+ )
+ )
+ return shape
+
+
+
+
+def trrs_hole():
+ debugprint('trrs_hole()')
+ trrs_position = copy.deepcopy(pcb_mount_ref_position)
+ trrs_position[0] = trrs_position[0] + trrs_offset[0]
+ trrs_position[1] = trrs_position[1] + trrs_offset[1]
+ trrs_position[2] = trrs_position[2] + trrs_offset[2]
+
+ trrs_hole_size = [3, 20]
+
+
+ shape = cylinder(*trrs_hole_size)
+ shape = rotate(shape, [0, 90, 90])
+ shape = translate(shape,
+ (
+ trrs_position[0],
+ trrs_position[1],
+ trrs_hole_size[0] + pcb_holder_thickness,
+ )
+ )
+ return shape
+
+pcb_screw_position = copy.deepcopy(pcb_mount_ref_position)
+pcb_screw_position[1] = pcb_screw_position[1] + pcb_screw_y_offset
+
+def pcb_screw_hole():
+ debugprint('pcb_screw_hole()')
+ holes = []
+ hole = cylinder(*pcb_screw_hole_size)
+ hole = translate(hole, pcb_screw_position)
+ hole = translate(hole, (0, 0, pcb_screw_hole_size[1]/2-.1))
+ holes.append(translate(hole, (pcb_screw_x_offsets[0], 0, 0)))
+ holes.append(translate(hole, (pcb_screw_x_offsets[1], 0, 0)))
+ holes.append(translate(hole, (pcb_screw_x_offsets[2], 0, 0)))
+
+ return holes
+
+
+if oled_center_row is not None:
+ base_pt1 = key_position(
+ list(np.array([-mount_width/2, 0, 0]) + np.array([0, (mount_height / 2), 0])), 0, oled_center_row-1
+ )
+ base_pt2 = key_position(
+ list(np.array([-mount_width/2, 0, 0]) + np.array([0, (mount_height / 2), 0])), 0, oled_center_row+1
+ )
+ base_pt0 = key_position(
+ list(np.array([-mount_width / 2, 0, 0]) + np.array([0, (mount_height / 2), 0])), 0, oled_center_row
+ )
+
+ oled_mount_location_xyz = (np.array(base_pt1)+np.array(base_pt2))/2. + np.array(((-left_wall_x_offset/2), 0, 0)) + np.array(oled_translation_offset)
+ oled_mount_location_xyz[2] = (oled_mount_location_xyz[2] + base_pt0[2])/2
+
+ angle_x = np.arctan2(base_pt1[2] - base_pt2[2], base_pt1[1] - base_pt2[1])
+ angle_z = np.arctan2(base_pt1[0] - base_pt2[0], base_pt1[1] - base_pt2[1])
+
+ oled_mount_rotation_xyz = (rad2deg(angle_x), 0, -rad2deg(angle_z)) + np.array(oled_rotation_offset)
+
+
+
+
+def generate_trackball(pos, rot):
precut = trackball_cutout()
precut = rotate(precut, tb_socket_rotation_offset)
precut = translate(precut, tb_socket_translation_offset)
@@ -3883,7 +4013,14 @@ def model_side(side="right"):
if controller_mount_type in ['EXTERNAL']:
s2 = difference(s2, [external_mount_hole()])
- if controller_mount_type in ['None']:
+ if controller_mount_type in ['PCB_MOUNT']:
+ s2 = difference(s2, [pcb_usb_hole()])
+ s2 = difference(s2, [trrs_hole()])
+ s2 = union([s2, pcb_holder()])
+ s2 = difference(s2, [wall_thinner()])
+ s2 = difference(s2, pcb_screw_hole())
+
+ if controller_mount_type in [None, 'None']:
0 # do nothing, only here to expressly state inaction.
s2 = difference(s2, [union(screw_insert_holes(side=side))])
@@ -3922,7 +4059,7 @@ def model_side(side="right"):
if show_caps:
shape = add([shape, ball])
- if (trackball_in_wall or ('TRACKBALL' in thumb_style)) and (side == ball_side or ball_side == 'both'):
+ if ('TRACKBALL' in thumb_style) and (side == ball_side or ball_side == 'both'):
tbprecut, tb, tbcutout, sensor, ball = generate_trackball_in_cluster()
shape = difference(shape, [tbprecut])
diff --git a/src/generate_configuration.py b/src/generate_configuration.py
index f5fa716..1fb89bf 100644
--- a/src/generate_configuration.py
+++ b/src/generate_configuration.py
@@ -21,7 +21,7 @@ shape_config = {
'save_dir': '.',
'config_name': "DM",
- 'show_caps': True,
+ 'show_caps': False,
'show_pcbs': False, #only runs if caps are shown, easist place to initially inject geometry
'nrows': 5, #5, # key rows
@@ -44,11 +44,16 @@ shape_config = {
11 # controls overall height# original=9 with centercol=3# use 16 for centercol=2
),
+ 'web_thickness': 4.0,
+ 'post_size': 0.1,
+ # post_adj': post_size / 2
+ 'post_adj': 0,
+
##############################
# THUMB PARAMETERS
##############################
# 'DEFAULT' 6-key, 'MINI' 5-key, 'CARBONFET' 6-key, 'MINIDOX' 3-key, 'TRACKBALL_ORBYL', 'TRACKBALL_CJ'
- 'thumb_style': 'TRACKBALL_ORBYL',
+ 'thumb_style': 'CARBONFET',
'default_1U_cluster': True, # only used with default, makes top right thumb cluster key 1U
# Thumb key size. May need slight oversizing, check w/ caps. Additional spacing will be automatically added for larger keys.
'minidox_Usize': 1.6,
@@ -109,9 +114,11 @@ shape_config = {
###################################
## Trackball General ##
###################################
- # EXPERIMENTAL
- 'trackball_modular': False, # May add removable trackball in subsequent releases, no current use.
- # END EXPERIMENTAL
+ 'trackball_modular': False, # Added, creates a hole with space for the lip size listed below.
+ 'trackball_modular_lip_width': 3.0, # width of lip cleared out in ring location
+ 'trackball_modular_ball_height': 3.0, # height of ball from ring , used to create identical position to fixed.
+ 'trackball_modular_ring_height': 10.0, # height mount ring down from ball height. Covers gaps on elevated ball.
+ 'trackball_modular_clearance': 0.5, # height of ball from ring, used to create identical position to fixed.
'trackball_Usize': 1.5, # size for inner key near trackball
'ball_side': 'right', #'left', 'right', or 'both'
@@ -294,10 +301,7 @@ shape_config = {
'oled_clip_z_gap': .2,
}
},
- 'web_thickness': 4.0,
- 'post_size': 0.1,
- # post_adj': post_size / 2
- 'post_adj': 0,
+
'screws_offset': 'INSIDE', #'OUTSIDE', 'INSIDE', 'ORIGINAL'
'screw_insert_height': 3.8,
@@ -322,7 +326,7 @@ shape_config = {
# 'USB_TEENSY' = Teensy holder, no RJ9
# 'EXTERNAL' = square cutout for a holder such as the one from lolligagger.
# 'NONE' = No openings in the back.
- 'controller_mount_type': 'EXTERNAL',
+ 'controller_mount_type': 'PCB_MOUNT',
'external_holder_height': 12.5,
'external_holder_width': 28.75,
@@ -332,6 +336,26 @@ shape_config = {
# Offset is from the top inner corner of the top inner key.
###################################
+ ## PCB Screw Mount ##
+ ###################################
+ "pcb_mount_ref_offset": [0, -5, 0],
+ "pcb_holder_size": [34.6, 7, 4],
+ "pcb_holder_offset": [8.9, 0, 0],
+
+ "pcb_usb_hole_size": [7.5, 10.0, 4],
+ "pcb_usb_hole_offset": [15, 0, 4.5],
+
+ "wall_thinner_size": [34, 7, 10],
+
+ "trrs_hole_size": [3, 20],
+ "trrs_offset": [0, 0, 1.5],
+
+ "pcb_screw_hole_size": [.5, 10],
+ "pcb_screw_x_offsets": [- 5.5, 7.75, 22], # for the screw positions off of reference
+ "pcb_screw_y_offset": -2,
+
+
+ ###################################
## Bottom Plate Dimensions
###################################
# COMMON DIMENSION
diff --git a/src/helpers_blender.py b/src/helpers_blender.py
index 9213488..00da8e5 100644
--- a/src/helpers_blender.py
+++ b/src/helpers_blender.py
@@ -82,7 +82,8 @@ def add(shapes):
def difference(shape, shapes):
debugprint('difference()')
for item in shapes:
- shape -= item
+ if item is not None:
+ shape -= item
return shape
diff --git a/src/helpers_cadquery.py b/src/helpers_cadquery.py
index 5dc78d1..58a876a 100644
--- a/src/helpers_cadquery.py
+++ b/src/helpers_cadquery.py
@@ -30,6 +30,8 @@ def cone(r1, r2, height):
def rotate(shape, angle):
+ if shape is None:
+ return None
origin = (0, 0, 0)
shape = shape.rotate(axisStartPoint=origin, axisEndPoint=(1, 0, 0), angleDegrees=angle[0])
shape = shape.rotate(axisStartPoint=origin, axisEndPoint=(0, 1, 0), angleDegrees=angle[1])
@@ -38,6 +40,8 @@ def rotate(shape, angle):
def translate(shape, vector):
+ if shape is None:
+ return None
return shape.translate(tuple(vector))
@@ -50,10 +54,11 @@ def union(shapes):
debugprint('union()')
shape = None
for item in shapes:
- if shape is None:
- shape = item
- else:
- shape = shape.union(item)
+ if item is not None:
+ if shape is None:
+ shape = item
+ else:
+ shape = shape.union(item)
return shape
@@ -61,23 +66,27 @@ def add(shapes):
debugprint('union()')
shape = None
for item in shapes:
- if shape is None:
- shape = item
- else:
- shape = shape.add(item)
+ if item is not None:
+ if shape is None:
+ shape = item
+ else:
+ shape = shape.add(item)
return shape
def difference(shape, shapes):
debugprint('difference()')
for item in shapes:
- shape = shape.cut(item)
+ if item is not None:
+ shape = shape.cut(item)
return shape
def intersect(shape1, shape2):
- return shape1.intersect(shape2)
-
+ if shape2 is not None:
+ return shape1.intersect(shape2)
+ else:
+ return shape1
def face_from_points(points):
# debugprint('face_from_points()')
diff --git a/src/helpers_solid.py b/src/helpers_solid.py
index 174d65a..2557e01 100644
--- a/src/helpers_solid.py
+++ b/src/helpers_solid.py
@@ -23,10 +23,14 @@ def cone(r1, r2, height):
def rotate(shape, angle):
+ if shape is None:
+ return None
return sl.rotate(angle)(shape)
def translate(shape, vector):
+ if shape is None:
+ return None
return sl.translate(tuple(vector))(shape)
@@ -47,10 +51,11 @@ def union(shapes):
debugprint('union()')
shape = None
for item in shapes:
- if shape is None:
- shape = item
- else:
- shape += item
+ if item is not None:
+ if shape is None:
+ shape = item
+ else:
+ shape += item
return shape
@@ -58,23 +63,27 @@ def add(shapes):
debugprint('union()')
shape = None
for item in shapes:
- if shape is None:
- shape = item
- else:
- shape += item
+ if item is not None:
+ if shape is None:
+ shape = item
+ else:
+ shape += item
return shape
def difference(shape, shapes):
debugprint('difference()')
for item in shapes:
- shape -= item
+ if item is not None:
+ shape -= item
return shape
def intersect(shape1, shape2):
- return sl.intersection()(shape1, shape2)
-
+ if shape2 is not None:
+ return sl.intersection()(shape1, shape2)
+ else:
+ return shape1
def hull_from_points(points):
return sl.hull()(*points)
diff --git a/src/run_config.json b/src/run_config.json
index 48bde38..3b1da65 100644
--- a/src/run_config.json
+++ b/src/run_config.json
@@ -2,7 +2,7 @@
"ENGINE": "solid",
"save_dir": ".",
"config_name": "DM",
- "show_caps": true,
+ "show_caps": false,
"show_pcbs": false,
"nrows": 5,
"ncols": 6,
@@ -20,7 +20,10 @@
7
],
"keyboard_z_offset": 11,
- "thumb_style": "TRACKBALL_ORBYL",
+ "web_thickness": 4.0,
+ "post_size": 0.1,
+ "post_adj": 0,
+ "thumb_style": "CARBONFET",
"default_1U_cluster": true,
"minidox_Usize": 1.6,
"thumb_plate_tr_rotation": 0.0,
@@ -116,6 +119,10 @@
"tbcj_thickness": 2,
"tbcj_outer_diameter": 53,
"trackball_modular": false,
+ "trackball_modular_lip_width": 3.0,
+ "trackball_modular_ball_height": 3.0,
+ "trackball_modular_ring_height": 10.0,
+ "trackball_modular_clearance": 0.5,
"trackball_Usize": 1.5,
"ball_side": "right",
"ball_diameter": 34.0,
@@ -308,9 +315,6 @@
"oled_clip_z_gap": 0.2
}
},
- "web_thickness": 4.0,
- "post_size": 0.1,
- "post_adj": 0,
"screws_offset": "INSIDE",
"screw_insert_height": 3.8,
"screw_insert_bottom_radius": 2.655,
@@ -318,11 +322,45 @@
"wire_post_height": 7,
"wire_post_overhang": 3.5,
"wire_post_diameter": 2.6,
- "controller_mount_type": "EXTERNAL",
+ "controller_mount_type": "PCB_MOUNT",
"external_holder_height": 12.5,
"external_holder_width": 28.75,
"external_holder_xoffset": -5.0,
"external_holder_yoffset": -4.5,
+ "pcb_mount_ref_y_offset": -5,
+ "pcb_holder_size": [
+ 34.6,
+ 7,
+ 4
+ ],
+ "pcb_holder_x_offset": 8.9,
+ "pcb_usb_hole_x_offset": 15,
+ "pcb_usb_hole_z_offset": 4.5,
+ "pcb_usb_hole_size": [
+ 7.5,
+ 10.0,
+ 4
+ ],
+ "wall_thinner_size": [
+ 34,
+ 7,
+ 10
+ ],
+ "trrs_hole_size": [
+ 3,
+ 20
+ ],
+ "trrs_z_offset": 1.5,
+ "pcb_screw_hole_size": [
+ 0.5,
+ 10
+ ],
+ "pcb_screw_x_offsets": [
+ -5.5,
+ 7.75,
+ 22
+ ],
+ "pcb_screw_y_offset": -2,
"screw_hole_diameter": 2,
"base_thickness": 3.0,
"base_offset": 3.0,