This commit is contained in:
Ricardo (XenGi) Band 2023-05-24 23:53:03 +02:00
commit bbad6e3bad
No known key found for this signature in database
30 changed files with 580 additions and 13 deletions

16
.editorconfig Normal file
View file

@ -0,0 +1,16 @@
# EditorConfig is awesome: https://EditorConfig.org
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
[*.scad]
indent_style = space
indent_size = 2
[Makefile]
indent_style = tab

86
.gitignore vendored
View file

@ -1,10 +1,82 @@
.idea/
*.gcode
*.stl
*.3mf
*.amf
*.scad
__pycache__/
*.pyc
.venv
*.gcode
# Created by https://www.toptal.com/developers/gitignore/api/windows,linux,macos
# Edit at https://www.toptal.com/developers/gitignore?templates=windows,linux,macos
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/windows,linux,macos

BIN
OLD/mkbd65.FCStd Normal file

Binary file not shown.

BIN
OLD/mkbd65.FCStd1 Normal file

Binary file not shown.

22622
OLD/mkbd65.dxf Normal file

File diff suppressed because it is too large Load diff

139
OLD/mkbd65.py Executable file
View file

@ -0,0 +1,139 @@
#!/usr/bin/env python3
import sys
from subprocess import run
from configparser import ConfigParser
import click
from solid import scad_render_to_file, translate
from mkbd65.key_mat import key_mat, key
from mkbd65.pcb import pcb
from mkbd65.phone import phone
from mkbd65.lower_case import lower_case
from mkbd65.util import PCB_WIDTH
@click.command()
@click.option("-l", "--layout", "layout", default="ansi", show_default=True, help="Keyboard layout", type=click.Choice(["ansi", "ansi_big_enter", "iso"], case_sensitive=False))
@click.option("-v", "--variant", "variant", default="en", show_default=True, help="Keyboard layout variant", type=click.Choice(["en", "de"], case_sensitive=False))
@click.option("-s", "--stl", "stl", is_flag=True, help="Generate STL files")
@click.option("-3", "--3mf", "emf", is_flag=True, help="Generate 3MF files")
@click.option("-a", "--amf", "amf", is_flag=True, help="Generate AMF files")
@click.option("-d", "--detail", "detail", default=64, show_default=True, help="OpenSCAD detail level", type=click.INT)
@click.argument("config_file")
def cli(layout, variant, stl, emf, amf, detail, config_file):
if layout == "ansi" and variant == "de":
click.echo("There is no german ansi variant. German keyboards need one more key and therefore use the ISO "
"layout.")
sys.exit()
config = ConfigParser()
config.read(config_file)
components = {
"phone": phone(
width=config.getfloat("phone", "width"),
height=config.getfloat("phone", "height"),
thickness=config.getfloat("phone", "thickness"),
corner_radius=config.getfloat("phone", "corner_radius"),
side_radius=config.getfloat("phone", "side_radius")
),
"key": key(
width=config.getfloat("key_mat", "key_width", fallback=9),
height=config.getfloat("key_mat", "key_height", fallback=6),
thickness=config.getfloat("key_mat", "key_thickness", fallback=2),
corner_radius=config.getfloat("key_mat", "key_corner_radius", fallback=1),
label="❤️",
font=config.get("key_mat", "font", fallback="DejaVu Sans:style=Bold")
),
"key_mat": key_mat(
margin=config.getfloat("key_mat", "margin", fallback=1),
padding=config.getfloat("key_mat", "padding", fallback=1),
thickness=config.getfloat("key_mat", "thickness", fallback=0.5),
key_width=config.getfloat("key_mat", "key_width", fallback=9),
key_height=config.getfloat("key_mat", "key_height", fallback=6),
key_radius=config.getfloat("key_mat", "key_corner_radius", fallback=1),
key_thickness=config.getfloat("key_mat", "key_thickness", fallback=2),
layout=layout,
variant=variant,
font=config.get("key_mat", "font", fallback="DejaVu Sans:style=Bold")
),
"pcb": pcb(
key_width=config.getfloat("key_mat", "key_width", fallback=9),
key_height=config.getfloat("key_mat", "key_height", fallback=6),
key_padding=config.getfloat("key_mat", "padding", fallback=1)
),
"lower_case": lower_case(
phone_width=config.getfloat("phone", "width"),
phone_height=config.getfloat("phone", "height"),
phone_radius=config.getfloat("phone", "corner_radius")
),
"test_key_mat": key_mat(
margin=config.getfloat("key_mat", "margin", fallback=1),
padding=config.getfloat("key_mat", "padding", fallback=1),
thickness=config.getfloat("key_mat", "thickness", fallback=0.5),
key_width=config.getfloat("key_mat", "key_width", fallback=9),
key_height=config.getfloat("key_mat", "key_height", fallback=6),
key_radius=config.getfloat("key_mat", "key_corner_radius", fallback=1),
key_thickness=config.getfloat("key_mat", "key_thickness", fallback=2),
layout=layout,
variant=variant,
font=config.get("key_mat", "font", fallback="DejaVu Sans:style=Bold"),
keys_h=5,
keys_v=3
)
}
columns = 13
alps_thickness = 0.78
alps_height = 4
alps_width = 6
pcb_thickness = 1
bottom_cover_thickness = 0.5
pcb_margin_y = 3
pcb_margin_x = (PCB_WIDTH - (columns * config.getfloat("key_mat", "key_width", fallback=9) + (columns - 1) * config.getfloat("key_mat", "padding", fallback=1))) / 2 + (config.getfloat("key_mat", "key_width", fallback=9) - 6) / 2
key_mat_width = 13 * config.getfloat("key_mat", "key_width", fallback=9) + 12 * config.getfloat("key_mat", "padding", fallback=1) + 2 * config.getfloat("key_mat", "margin", fallback=1)
# TODO: fix x of pcb
full_model = components["lower_case"] + translate(v=((config.getfloat("phone", "width") - PCB_WIDTH) / 2, config.getfloat("phone", "corner_radius") / 2, bottom_cover_thickness))(
components["pcb"]
) + translate(v=(
pcb_margin_x + config.getfloat("phone", "corner_radius", fallback=10) / 2 - config.getfloat("key_mat", "margin", fallback=1) - (config.getfloat("key_mat", "key_width", fallback=9) - alps_width) / 2,
pcb_margin_y + config.getfloat("phone", "corner_radius", fallback=10) / 2 - config.getfloat("key_mat", "margin", fallback=1) - (config.getfloat("key_mat", "key_height", fallback=6) - alps_height) / 2,
alps_thickness + pcb_thickness + bottom_cover_thickness))(
components["key_mat"]
)
# config.getfloat("phone", "width") - key_mat_width) / 2,
# 3 + config.getfloat("key_mat", "margin", fallback=1) + (config.getfloat("key_mat", "key_height", fallback=6) - 4) / 2 ,
# 1.78
scad_render_to_file(
full_model,
filepath=f"mkbd65.scad",
file_header=f'$fn = {detail};',
include_orig_code=False
)
for component in components.keys():
print(f"Rendering component {component}...")
scad_render_to_file(
components[component],
filepath=f"mkbd65_{component}.scad",
file_header=f'$fn = {detail};',
include_orig_code=False
)
if stl:
print(f"Generate STL for component {component}...")
run(["openscad", "-o", f"mkbd65_{component}.stl", f"mkbd65_{component}.scad"])
if emf:
print(f"Generate 3MF for component {component}...")
run(["openscad", "-o", f"mkbd65_{component}.3mf", f"mkbd65_{component}.scad"])
if amf:
print(f"Generate AMF for component {component}...")
run(["openscad", "-o", f"mkbd65_{component}.amf", f"mkbd65_{component}.scad"])
if __name__ == "__main__":
cli()

390
OLD/mkbd65.svg Normal file
View file

@ -0,0 +1,390 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 607.37007 280.06299"
width="160.7mm"
height="74.099998mm"
version="1.1"
id="svg1033"
sodipodi:docname="mkbd65.svg"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1035"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="2.0014903"
inkscape:cx="284.53798"
inkscape:cy="219.83619"
inkscape:window-width="2560"
inkscape:window-height="1403"
inkscape:window-x="0"
inkscape:window-y="18"
inkscape:window-maximized="1"
inkscape:current-layer="g1031"
units="mm"
inkscape:document-units="mm" />
<desc
id="desc39">mkbd65.dxf - scale = 1.0, origin = (0.0, 0.0), method = manual</desc>
<defs
id="defs53">
<marker
id="DistanceX"
orient="auto"
refX="0"
refY="0"
style="overflow:visible">
<path
d="M 3,-3 -3,3 M 0,-5 V 5"
style="stroke:#000000;stroke-width:0.5"
id="path41" />
</marker>
<pattern
id="Hatch"
patternUnits="userSpaceOnUse"
width="8"
height="8"
x="0"
y="0">
<path
d="M8 4 l-4,4"
stroke="#000000"
stroke-width="0.25"
linecap="square"
id="path44" />
<path
d="M6 2 l-4,4"
stroke="#000000"
stroke-width="0.25"
linecap="square"
id="path46" />
<path
d="M4 0 l-4,4"
stroke="#000000"
stroke-width="0.25"
linecap="square"
id="path48" />
</pattern>
<symbol
id="*Model_Space" />
<symbol
id="*Paper_Space" />
</defs>
<g
inkscape:groupmode="layer"
inkscape:label="0"
id="g1031">
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999985;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 214.8659,257.19763 c -2.08721,-10e-4 -3.77935,-1.69353 -3.77926,-3.77964 v -15.11866 c -9e-5,-2.08761 1.69205,-3.77969 3.77926,-3.77964 h 102.04756 c 2.08715,-5e-5 3.77929,1.69203 3.77927,3.77964 v 15.11866 c 2e-5,2.08611 -1.69212,3.77819 -3.77927,3.77964 z"
id="path305"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 93.921247,132.47374 c -10e-7,-2.08573 -1.692149,-3.77763 -3.779513,-3.77923 H 63.685037 c -2.087363,0.002 -3.779511,1.6935 -3.779514,3.77923 v 15.11696 c 3e-6,2.08748 1.692151,3.77938 3.779514,3.77923 h 26.456697 c 2.087364,1.5e-4 3.779512,-1.69175 3.779513,-3.77923 z"
id="path343"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 93.92126,158.92884 c -10e-7,-2.08573 -1.69215,-3.77763 -3.779516,-3.77923 H 63.685029 c -2.087365,0.002 -3.779514,1.6935 -3.779517,3.77923 v 15.11696 c 3e-6,2.08748 1.692152,3.77938 3.779517,3.77923 h 26.456715 c 2.087366,1.5e-4 3.779515,-1.69175 3.779516,-3.77923 z"
id="path343-3"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 93.921242,185.38553 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 H 63.685037 c -2.087363,0.002 -3.779511,1.6935 -3.779514,3.77923 v 15.11696 c 3e-6,2.08748 1.692151,3.77938 3.779514,3.77924 h 26.456695 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 93.921262,211.84063 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 H 63.685029 c -2.087365,0.002 -3.779514,1.6935 -3.779517,3.77923 v 15.11697 c 3e-6,2.08748 1.692152,3.77938 3.779517,3.77923 h 26.456713 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 93.921262,238.29892 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 H 63.685029 c -2.087365,0.002 -3.779514,1.6935 -3.779517,3.77923 v 15.11697 c 3e-6,2.08748 1.692152,3.77938 3.779517,3.77923 h 26.456713 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-5"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 131.71652,132.47214 c 0,-2.08573 -1.69215,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.087361,0.002 -3.779509,1.6935 -3.779512,3.77923 v 15.11696 c 3e-6,2.08748 1.692151,3.77938 3.779512,3.77923 h 26.4567 c 2.08736,1.5e-4 3.77951,-1.69175 3.77951,-3.77923 z"
id="path343-35"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 131.71654,158.92724 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.087371,0.002 -3.77952,1.6935 -3.779523,3.77923 v 15.11696 c 3e-6,2.08748 1.692152,3.77938 3.779523,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-6"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 131.71652,185.38393 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.087361,0.002 -3.779509,1.6935 -3.779512,3.77923 v 15.11696 c 3e-6,2.08748 1.692151,3.77938 3.779512,3.77924 h 26.4567 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-2"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 131.71654,211.83903 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.087371,0.002 -3.77952,1.6935 -3.779523,3.77923 V 226.956 c 3e-6,2.08748 1.692152,3.77938 3.779523,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-9"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 131.71654,238.29732 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.087371,0.002 -3.77952,1.6935 -3.779523,3.77923 v 15.11697 c 3e-6,2.08748 1.692152,3.77938 3.779523,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-5-1"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 479.43295,151.36993 c -2.08725,1.5e-4 -3.7794,-1.69175 -3.77927,-3.77923 v -15.11696 c -1.3e-4,-2.08573 1.69202,-3.77763 3.77927,-3.77923 h 64.25198 c 2.08747,0.002 3.77962,1.69351 3.77976,3.77923 v 15.11696 c -1.4e-4,2.08747 -1.69229,3.77938 -3.77976,3.77923 z"
id="path389"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 479.43281,204.28172 c -2.08725,1.5e-4 -3.7794,-1.69175 -3.77927,-3.77923 v -15.11696 c -1.3e-4,-2.08573 1.69202,-3.77763 3.77927,-3.77923 h 64.25198 c 2.08747,0.002 3.77962,1.69351 3.77976,3.77923 v 15.11696 c -1.4e-4,2.08747 -1.69229,3.77938 -3.77976,3.77923 z"
id="path389-7"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 479.43281,230.73841 c -2.08725,1.5e-4 -3.7794,-1.69175 -3.77927,-3.77923 v -15.11696 c -1.3e-4,-2.08573 1.69202,-3.77763 3.77927,-3.77923 h 64.25197 c 2.08748,0.002 3.77962,1.69351 3.77976,3.77923 v 15.11696 c -1.4e-4,2.08747 -1.69228,3.77938 -3.77976,3.77923 z"
id="path389-7-6"
sodipodi:nodetypes="ccccccccc" />
<path
d="M 569.5748,0 H 37.795276 C 16.921512,0 -1.3254848e-5,16.921525 0,37.795276 V 242.26772 c -1.3254847e-5,20.87375 16.921512,37.79528 37.795276,37.79527 H 569.5748 c 20.87376,2e-5 37.79529,-16.92151 37.79528,-37.79527 V 37.795276 C 607.37009,16.921522 590.44856,-4.9705675e-6 569.5748,0 Z"
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.01;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
id="path1029"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 169.5118,132.47374 c -1e-5,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45669 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45669 c 2.08737,1.5e-4 3.77951,-1.69175 3.77952,-3.77923 z"
id="path343-2"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 169.51181,158.92884 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-70"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 169.51179,185.38553 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.45669 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77924 h 26.45669 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-9"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 169.51181,211.84063 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-3"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 169.51181,238.29892 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-5-6"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 396.28345,132.47374 c 0,-2.08573 -1.69215,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77951,3.77923 h 26.4567 c 2.08736,1.5e-4 3.77951,-1.69175 3.77951,-3.77923 z"
id="path343-9"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 396.28346,158.92884 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.45672 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77951,3.77923 h 26.45672 c 2.08737,1.5e-4 3.77951,-1.69175 3.77951,-3.77923 z"
id="path343-3-4"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 396.28345,185.38553 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77951,3.77924 h 26.4567 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-7"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 396.28347,211.84063 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45672 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77951,3.77923 h 26.45672 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-8"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 396.28347,238.29892 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45672 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77951,3.77923 h 26.45672 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-5-4"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 434.07872,132.47214 c 0,-2.08573 -1.69215,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.7795,1.6935 -3.77951,3.77923 v 15.11696 c 1e-5,2.08748 1.69215,3.77938 3.77951,3.77923 h 26.4567 c 2.08736,1.5e-4 3.77951,-1.69175 3.77951,-3.77923 z"
id="path343-35-5"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 434.07874,158.92724 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-6-0"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 434.07872,185.38393 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.7795,1.6935 -3.77951,3.77923 v 15.11696 c 1e-5,2.08748 1.69215,3.77938 3.77951,3.77924 h 26.4567 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-2-3"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 434.07874,211.83903 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 V 226.956 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-9-61"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 434.07874,238.29732 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-5-1-0"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 471.874,132.47374 c -1e-5,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45669 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45669 c 2.08737,1.5e-4 3.77951,-1.69175 3.77952,-3.77923 z"
id="path343-2-6"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 471.87401,158.92884 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-70-3"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 509.66929,158.92884 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-6-0-1"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 547.46456,158.93044 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-70-3-5"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 509.66929,238.29892 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-6-0-1-5"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 547.46456,238.30052 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-70-3-5-4"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 471.87399,185.38553 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.45669 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77924 h 26.45669 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-9-2"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 471.87401,211.84063 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-3-0"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 471.87401,238.29892 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-5-6-6"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 207.30707,132.47214 c 0,-2.08573 -1.69215,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77951,3.77923 h 26.4567 c 2.08736,1.5e-4 3.77951,-1.69175 3.77951,-3.77923 z"
id="path343-35-0"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 207.30709,158.92724 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-6-6"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 207.30707,185.38393 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77951,3.77924 h 26.4567 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-2-2"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 207.30709,211.83903 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 V 226.956 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-9-6"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 207.30709,238.29732 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-5-1-1"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 245.10235,132.47214 c -1e-5,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45669 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45669 c 2.08737,1.5e-4 3.77951,-1.69175 3.77952,-3.77923 z"
id="path343-8"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 245.10236,158.92724 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-79"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 245.10234,185.38393 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.45669 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77924 h 26.45669 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-20"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 245.10236,211.83903 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 V 226.956 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-2"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 282.89762,132.47054 c 0,-2.08573 -1.69215,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77951,3.77923 h 26.4567 c 2.08736,1.5e-4 3.77951,-1.69175 3.77951,-3.77923 z"
id="path343-35-7"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 282.89764,158.92564 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-6-5"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 282.89762,185.38233 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77951,3.77924 h 26.4567 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-2-9"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 282.89764,211.83743 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-9-2"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 320.6929,132.47214 c -1e-5,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45669 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45669 c 2.08737,1.5e-4 3.77951,-1.69175 3.77952,-3.77923 z"
id="path343-2-8"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 320.69291,158.92724 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-70-9"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 320.69289,185.38393 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.45669 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77924 h 26.45669 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-9-7"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 320.69291,211.83903 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 V 226.956 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-3-3"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 358.48817,132.47054 c 0,-2.08573 -1.69215,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77951,3.77923 h 26.4567 c 2.08736,1.5e-4 3.77951,-1.69175 3.77951,-3.77923 z"
id="path343-35-0-1"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 358.48819,158.92564 c 0,-2.08573 -1.69215,-3.77763 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-6-6-2"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 358.48817,185.38233 c 0,-2.08573 -1.69214,-3.77763 -3.77951,-3.77923 h -26.4567 c -2.08736,0.002 -3.77951,1.6935 -3.77951,3.77923 v 15.11696 c 0,2.08748 1.69215,3.77938 3.77951,3.77924 h 26.4567 c 2.08737,1.4e-4 3.77951,-1.69176 3.77951,-3.77924 z"
id="path343-6-2-2-9"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 358.48819,211.83743 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-9-6-3"
sodipodi:nodetypes="ccccccccc" />
<path
style="vector-effect:non-scaling-stroke;fill:none;stroke:#ff00ff;stroke-width:0.00999931;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
d="m 358.48819,238.29572 c 0,-2.08573 -1.69215,-3.77762 -3.77952,-3.77923 h -26.45671 c -2.08737,0.002 -3.77952,1.6935 -3.77952,3.77923 v 15.11697 c 0,2.08748 1.69215,3.77938 3.77952,3.77923 h 26.45671 c 2.08737,1.5e-4 3.77952,-1.69175 3.77952,-3.77923 z"
id="path343-3-7-5-1-1-1"
sodipodi:nodetypes="ccccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 35 KiB

0
OLD/mkbd65/__init__.py Normal file
View file

48
OLD/mkbd65/camera_bump.py Normal file
View file

@ -0,0 +1,48 @@
from solid import OpenSCADObject, translate, minkowski, cube, cylinder, linear_extrude, hull, circle, square
def _generic_bump(width: float, height: float, thickness: float, radius: float) -> OpenSCADObject:
"""
A rounded rectangular bump
:return:
"""
return translate(v=(radius, -1 * height + radius, 0))(
minkowski()(
cube([width - 2 * radius, height - 2 * radius, thickness]),
cylinder(r=radius, h=thickness)
)
)
def oneplus_8t() -> OpenSCADObject:
"""
Camera bump of the Oneplus 8T
:return:
"""
return translate(v=(6, 7, 0))(
_generic_bump(width=39, height=25, thickness=1, radius=5)
)
def samsung_s22plus() -> OpenSCADObject:
"""
Camra bump of the Samsung S22+
:return:
"""
return linear_extrude(height=1)(
hull()(
circle(r=10),
translate(v=(20, 40, 0))(
circle(r=10)
),
translate(v=(20, 0, 0))(
square(size=(20, 20), center=True)
),
translate(v=(0, 40, 0))(
square(size=(20, 20), center=True)
)
)
)

235
OLD/mkbd65/key_mat.py Normal file
View file

@ -0,0 +1,235 @@
from typing import Tuple
from solid import OpenSCADObject, cube, linear_extrude, text, translate, scale, rotate, cylinder, union, color, square, offset
from solid.utils import up
from mkbd65.util import get_label_size, FILAMENT_LAYER, LAYOUTS
def key(
width: float,
height: float,
corner_radius: float,
thickness: float,
font: str,
label: str = ""
) -> OpenSCADObject:
"""
Generates a single key
key:
+-----+
| | height
+-----+
width \\ thickness
:param width: Width in mm
:param height: Height in mm
:param corner_radius: Radius of corners in mm
:param thickness: Thickness in mm
:param label: Text label
:param font: Font to use
:return:
"""
dome_height = 2
return union()(
translate(v=(0, height / 2, 2))(
scale(v=(1, 1, dome_height / height))(
rotate((0, 90, 0))(
cylinder(h=width, d=height)
)
) * translate(v=(width / 2, height / 2, 0))(
scale((1, 1, dome_height / width))(
rotate((90, 0, 0))(
cylinder(h=height, d=width)
)
)
)
) * up(z=2)(
linear_extrude(height=dome_height / 2)(
translate(v=(corner_radius, corner_radius, 0))(
offset(r=corner_radius)(
square(size=(width - 2 * corner_radius, height - 2 * corner_radius))
)
)
)
),
linear_extrude(height=2)(
# round_rect(width=width, height=height, radius=corner_radius)
translate(v=(corner_radius, corner_radius, 0))(
offset(r=corner_radius)(
square(size=(width - 2 * corner_radius, height - 2 * corner_radius))
)
)
)
) - translate(v=(width / 2, height / 2, thickness + dome_height / 2 - dome_height * 3 * FILAMENT_LAYER))(
linear_extrude(height=dome_height * 3 * FILAMENT_LAYER)(
text(text=label, size=get_label_size(label), font=font, halign='center', valign='center')
)
)
def key_mat(
margin: float | Tuple[float, float, float, float],
padding: float | Tuple[float, float],
thickness: float,
key_width: float,
key_height: float,
key_radius: float,
key_thickness: float,
layout: str,
variant: str,
font: str,
keys_h: int = 13,
keys_v: int = 5
) -> OpenSCADObject:
"""
Generates elastic mat with fixed layout but variable sizes
mat:
+---------------------------------------------+
| margin |
| +-----+ +-----+ +-----+ |
|margin| |padding| | ... | |margin|
| +-----+ +-----+ +-----+ |
| padding |
| +-----+ +-----+ +-----+ |
| | | | | ... | | |
| +-----+ +-----+ +-----+ |
| ... ... ... |
| +-----+ +-----+ +-----+ |
| | | | | ... | | |
| +-----+ +-----+ +-----+ |
| margin |
+---------------------------------------------+
\\ thickness
:param keys_v:
:param keys_h:
:param variant:
:param margin: left, right, top and bottom margin, can be single number to set all at once.
:param padding: Horizontal and vertical padding, can be single number to set both at once.
:param thickness: Thickness of matt.
:param key_width: Width of keys.
:param key_height: Height of keys.
:param key_radius: Radius of key corners.
:param key_thickness: Thickness of keys without matt.
:param layout: ansi or iso layout.
:param font:
:return:
"""
spacebar_start = 4 # horizontal start key of space bar (0 index)
spacebar_width = 3 # space bar length in keys
margin_l = margin[0] if isinstance(margin, Tuple) else margin
margin_r = margin[1] if isinstance(margin, Tuple) else margin
margin_t = margin[2] if isinstance(margin, Tuple) else margin
margin_b = margin[3] if isinstance(margin, Tuple) else margin
padding_h = padding[0] if isinstance(padding, Tuple) else padding
padding_v = padding[1] if isinstance(padding, Tuple) else padding
mat = cube([
keys_h * key_width + (keys_h - 1) * padding_h + margin_l + margin_r,
keys_v * key_height + (keys_v - 1) * padding_v + margin_t + margin_b,
thickness
])
# add keys to mat
for x in range(keys_h):
for y in range(keys_v):
if (x == keys_h - 1 and (y in [0, 2, 3] and layout.startswith("ansi") or y in [0, 2] and layout == "iso")) \
or (spacebar_start < x < spacebar_start + spacebar_width and y == keys_v - 1):
# skip for wide keys (backspace, enter, shift and space bar)
continue
elif x == keys_h - 1 and y == 1 and layout in ["ansi_big_enter", "iso"]:
# big enter
mat += translate(v=(padding_h + x * (key_width + padding_h), padding_v + (keys_v - y - 2) * (key_height + padding_v), thickness))(key(
width=key_width,
height=2 * key_height + padding_v,
corner_radius=key_radius,
thickness=key_thickness,
font=font,
label=LAYOUTS[f"{layout}_{variant}"][y][x]
))
elif x == keys_h - 2 and (y == 0 or (y == 2 and layout == "ansi") or (y == 3 and layout != "iso")):
# wide key
mat += translate(v=(padding_h + x * (key_width + padding_h), padding_v + (keys_v - y - 1) * (key_height + padding_v), thickness))(key(
width=2 * key_width + padding_h,
height=key_height,
corner_radius=key_radius,
thickness=key_thickness,
font=font,
label=LAYOUTS[f"{layout}_{variant}"][y][x]
))
elif x == spacebar_start and y == keys_v - 1:
# space bar
mat += translate(v=(padding_h + x * (key_width + padding_h), padding_v + (keys_v - y - 1) * (key_height + padding_v), thickness))(key(
width=spacebar_width * key_width + (spacebar_width - 1) * padding_h,
height=key_height,
corner_radius=key_radius,
thickness=key_thickness,
font=font,
label=LAYOUTS[f"{layout}_{variant}"][y][x]
))
else:
# normal key
mat += translate(v=(padding_h + x * (key_width + padding_h), padding_v + (keys_v - y - 1) * (key_height + padding_v), thickness))(key(
width=key_width,
height=key_height,
corner_radius=key_radius,
thickness=key_thickness,
font=font,
label=LAYOUTS[f"{layout}_{variant}"][y][x]
))
# add holes to keys for better "pressability"
for x in range(keys_h):
for y in range(keys_v):
if (x == keys_h - 1 and (y in [0, 2, 3] and layout.startswith("ansi") or y in [0, 2] and layout == "iso")) \
or (spacebar_start < x < spacebar_start + spacebar_width and y == keys_v - 1):
# skip for wide keys (backspace, enter, shift and space bar)
continue
elif x == keys_h - 1 and y == 1 and layout in ["ansi_big_enter", "iso"]:
# big enter
mat -= translate(v=(padding_h + x * (key_width + padding_h) + 1, padding_v + (keys_v - y - 2) * (key_height + padding_v) + 1, 0))(
cube((key_width - 2, 2 * key_height + padding_v - 2, key_thickness + thickness - 2 * FILAMENT_LAYER)) - translate(v=(key_width / 2 - 1, key_height / 2 - 1, 0))(
cylinder(d=2, h=key_thickness + thickness - 2 * FILAMENT_LAYER)
) - translate(v=(key_width / 2 - 1, key_height + padding_v + key_height / 2 - 1, 0))(
cylinder(d=2, h=key_thickness + thickness - 2 * FILAMENT_LAYER)
) - translate(v=(key_width / 2 - 2, key_height / 2 - 1, 0))(
cube((2, padding_v + key_height, key_thickness + thickness - 2 * FILAMENT_LAYER))
)
)
elif x == keys_h - 2 and (y == 0 or (y == 2 and layout == "ansi") or (y == 3 and layout != "iso")):
# wide key
mat -= translate(v=(padding_h + x * (key_width + padding_h) + 1, padding_v + (keys_v - y - 1) * (key_height + padding_v) + 1, 0))(
cube((2 * key_width + padding_h - 2, key_height - 2, key_thickness + thickness - 2 * FILAMENT_LAYER)) - translate(v=(key_width / 2 - 1, key_height / 2 - 1, 0))(
cylinder(d=2, h=key_thickness + thickness - 2 * FILAMENT_LAYER)
) - translate(v=(key_width + padding_h + key_width / 2 - 1, key_height / 2 - 1, 0))(
cylinder(d=2, h=key_thickness + thickness - 2 * FILAMENT_LAYER)
) - translate(v=(key_width / 2 - 1, key_height / 2 - 2, 0))(
cube((padding_h + key_width, 2, key_thickness + thickness - 2 * FILAMENT_LAYER))
)
)
elif x == spacebar_start and y == keys_v - 1:
# space bar
mat -= translate(v=(padding_h + x * (key_width + padding_h) + 1, padding_v + (keys_v - y - 1) * (key_height + padding_v) + 1, 0))(
cube((spacebar_width * key_width + (spacebar_width - 1) * padding_h - 2, key_height - 2, key_thickness + thickness - 2 * FILAMENT_LAYER)) - translate(v=(key_width / 2 - 1, key_height / 2 - 1, 0))(
cylinder(d=2, h=key_thickness + thickness - 2 * FILAMENT_LAYER)
) - translate(v=((spacebar_width - 1) * key_width + (spacebar_width - 1) * padding_h + key_width / 2 - 1, key_height / 2 - 1, 0))(
cylinder(d=2, h=key_thickness + thickness - 2 * FILAMENT_LAYER)
) - translate(v=(key_width / 2 - 1, key_height / 2 - 2, 0))(
cube(((spacebar_width - 1) * padding_h + (spacebar_width - 1) * key_width, 2, key_thickness + thickness - 2 * FILAMENT_LAYER))
)
)
else:
# normal key
mat -= translate(v=(padding_h + x * (key_width + padding_h) + 1, padding_v + (keys_v - y - 1) * (key_height + padding_v) + 1, 0))(
cube((key_width - 2, key_height - 2, key_thickness + thickness - 2 * FILAMENT_LAYER)) - translate(v=(key_width / 2 - 1, key_height / 2 - 1, 0))(
cylinder(d=2, h=key_thickness + thickness - 2 * FILAMENT_LAYER)
)
)
return color("DarkSlateGray")(mat)

106
OLD/mkbd65/lower_case.py Normal file
View file

@ -0,0 +1,106 @@
from solid import OpenSCADObject, hull, translate, sphere, cube, scale, offset, square, color
from solid.utils import up, right, down, forward
from mkbd65.util import PCB_WIDTH, PCB_HEIGHT, PCB_RADIUS
def lower_case(phone_width: float, phone_height: float, phone_radius: float) -> OpenSCADObject:
"""
Rounded bottom part of the case
:param phone_width:
:param phone_height:
:param phone_radius:
:return:
"""
thickness = 2
window_thickness = 0.5
# TODO: make a difference between phone_radius and thickness of side walls
return color("DarkSlateGray")(up(z=thickness)(
(scale(v=(1, 1, thickness / phone_radius))(
hull()(
translate(v=(phone_radius, phone_radius, 0))(
sphere(r=phone_radius),
forward(y=phone_height - 2 * phone_radius)(
sphere(r=phone_radius)
),
right(x=phone_width - 2 * phone_radius)(
sphere(r=phone_radius)
),
translate(v=(phone_width - 2 * phone_radius, phone_height - 2 * phone_radius, 0))(
sphere(r=phone_radius)
)
)
)
) * down(z=thickness)(
cube([phone_width, phone_height, thickness])
)) - translate(v=(2 * phone_radius, 2 * phone_radius, -1 * thickness / 2))(
scale(v=(1, 1, thickness))(
offset(r=phone_radius)(
square([phone_width - 4 * phone_radius, phone_height - 4 * phone_radius])
)
)
) - translate(v=(phone_width - PCB_WIDTH, phone_radius, -1 * thickness / 2 + window_thickness))(
scale(v=(1, 1, thickness))(
offset(r=PCB_RADIUS)(
square([PCB_WIDTH - 2 * PCB_RADIUS, PCB_HEIGHT - 2 * PCB_RADIUS])
)
)
)
))
# width = 160.7;
# height = 74.1;
# radius = 10;
# thickness = 2;
# pcb_radius = 5;
# pcb_width = 150;
# pcb_height = 64;
# window_thickness = 0.5;
#
#
# translate([0, 0, thickness]) {
# difference() {
# intersection() {
# scale([1, 1, thickness / radius]) {
# hull() {
# translate([radius, radius, 0]) {
# sphere(r=radius);
# translate([0, height-2*radius, 0]) {
# sphere(r=radius);
# }
# translate([width-2*radius, 0, 0]) {
# sphere(r=radius);
# }
# translate([width-2*radius, height-2*radius, 0]) {
# sphere(r=radius);
# }
# }
# }
# }
# translate([0, 0, -thickness]) {
# cube([width, height, thickness]);
# }
# }
#
# translate([2*radius, 2*radius, -thickness/2]) {
# scale([1, 1, thickness]) {
# offset(r=radius) {
# square([width - 4 * radius, height - 4 * radius]);
# }
# }
# }
# translate([width - pcb_width, radius, -1*thickness/2+window_thickness]) {
# scale([1,1,thickness]) {
# offset(r=pcb_radius) {
# square([pcb_width - 2 * pcb_radius, pcb_height - 2 * pcb_radius]);
# }
# }
# }
# }
# }

View file

@ -0,0 +1,99 @@
"""
All sizes are in millimeters.
"""
from solid import OpenSCADObject, hull, translate, cylinder, intersection, sphere, scale
def lower_case(width: float, height: float) -> OpenSCADObject:
"""
Generates lower half of the case
:param width: length from top to bottom (landscape)
:param height: length from left to right (landscape)
:return:
"""
length = 160.7
width = 74.1
height = 5
radius = 5
corners = [(-1, -1), (-1, 1), (1, -1), (1, 1)]
for x, y in corners:
hull()(
[scale(v=(sx, sy, 1))(
# upper cylindrical part
translate(v=(length / 2 - radius, width / 2 - radius, 0))(
cylinder(r=radius, h=height - radius)
) if height > radius else None,
translate(v=(length / 2 - radius, width / 2 - radius, height - radius))(
sphere(r=radius)
) * translate(v=(length / 2 - radius, width / 2 - radius, 0))(
cylinder(r=radius, h=height)
) if height < 2 * radius else None
) for sx in [-1, 1]]
)
for sx in [-1, 1]:
for sy in [-1, 1]:
scale(v=(sx, sy, 1))(
# upper cylindrical part
if height > radius:
translate(v=(length / 2 - radius, width / 2 - radius, 0))(
cylinder(r=radius, h=height - radius)
)
# upper spheric part
intersection()(
# sphere
translate(v=(length / 2 - radius, width / 2 - radius, height - radius))(
sphere(r=radius)
),
# clip sphere at bottom plane
translate(v=(length / 2 - radius, width / 2 - radius, 0))(
cylinder(r=radius, h=height)
) if height < 2 * radius else None
)
)
return hull()(
)
return linear_extrude(height=thickness)(
round_rect(width=width, height=height, radius=corner_radius)
)
//hull() {
// for(sx=[-1,1]) {
// for(sy=[-1,1]) {
// scale([sx,sy,1]) {
// // lower cylindric part
// /*if(height>radius) {
// translate([length/2-radius,width/2-radius,0]) {
// cylinder(r=radius,h=height-radius);
// }
// }*/
// // upper spheric part
// intersection() {
// // sphere
// translate([length/2-radius,width/2-radius,height-radius]) {
// sphere(r=radius);
// }
// // clip sphere at bottom plane
// if(height<2*radius) {
// translate([length/2-radius,width/2-radius,0]) {
// cylinder(r=radius,h=height);
// }
// }
// }
// }
// }
// }
//}

88
OLD/mkbd65/pcb.py Normal file
View file

@ -0,0 +1,88 @@
from solid import OpenSCADObject, color, linear_extrude, polygon, translate, scale, offset, square, union, cylinder
from mkbd65.util import PCB_WIDTH, PCB_HEIGHT, PCB_RADIUS
def switch() -> OpenSCADObject:
"""
Alps SKTKABE010
6 +----+ 5
/ \
7 + + 4 | 2mm
8 + + 3 |
\ 4mm /
1 +----+ 2
:return:
"""
thickness = 0.78
return color("Silver")(
linear_extrude(height=0.5)(
polygon(points=[(1, 0), (5, 0), (6, 1), (6, 3), (5, 4), (1, 4), (0, 3), (0, 1)]),
)
) + color("Black")(
translate(v=(3, 2, 0))(
cylinder(r=0.5, h=thickness)
)
)
def pcb(key_width: float, key_height: float, key_padding: float) -> OpenSCADObject:
"""
:return:
"""
pcb_thickness = 1
rows = 5
columns = 13
board = color(c="Purple")(
translate(v=(PCB_RADIUS, PCB_RADIUS, pcb_thickness/2))(
scale(v=(1, 1, pcb_thickness))(
offset(r=PCB_RADIUS)(
square([PCB_WIDTH - 2 * PCB_RADIUS, PCB_HEIGHT - 2 * PCB_RADIUS])
)
)
)
)
switches = []
margin_x = (PCB_WIDTH - (columns * key_width + (columns - 1) * key_padding)) / 2 + (key_width - 6) / 2
margin_y = 3
for x in range(columns):
for y in range(rows):
switches.append(
translate(v=(margin_x + x * (key_width + key_padding), margin_y + y * (key_height + key_padding), pcb_thickness))(
switch()
)
)
return union()(
board,
*switches
)
# TODO: Add ATMEGA and flat cable connector
# rows = 5
# columns = 12
# hspacing = 4
# vspacing = 3
# width = 6
# height = 4
#
# board = color("Green")(cube([123, 49, 0.6])) + translate((13, 36, 0.6))(
# color("BlackPaint")(cube([7, 7, 1]))
# ) + translate((23, 35.75, 0.6))(
# color("BlackPaint")(cube([2.5, 2, 0.55]))
# )
#
# for row in range(rows):
# for col in range(columns):
# board += translate((3.5 + (hspacing + width) * col, 2 + (vspacing + height) * row, 0.6))(
# switch()
# )
#
# return board

41
OLD/mkbd65/phone.py Normal file
View file

@ -0,0 +1,41 @@
from solid import OpenSCADObject, linear_extrude, translate, offset, square, cylinder, rotate, hull, cube
def phone(
width: float,
height: float,
thickness: float,
corner_radius: float,
side_radius: float
) -> OpenSCADObject:
"""
Generates rough estimate of the phones shape (basically an oneplus 8t)
:param width: length from top to bottom (landscape)
:param height: length from left to right (landscape)
:param thickness: How thicc is it?
:param corner_radius: Assuming all phones have round corners
:param side_radius: Assuming all phones have rounded side rails
:return:
"""
return linear_extrude(height=thickness)(
translate(v=(corner_radius, corner_radius, 0))(
offset(r=corner_radius)(
square(size=(width - 2 * corner_radius, height - 2 * corner_radius))
)
)
) * hull()(
translate(v=(0, side_radius, side_radius))(
rotate(a=(0, 90, 0))(
cylinder(r=side_radius, h=width)
)
),
translate(v=(0, height - side_radius, side_radius))(
rotate(a=(0, 90, 0))(
cylinder(r=side_radius, h=width)
)
),
translate(v=(0, 0, thickness / 2))(
cube(size=[width, height, thickness / 2])
)
)

53
OLD/mkbd65/util.py Normal file
View file

@ -0,0 +1,53 @@
PCB_RADIUS = 5
PCB_WIDTH = 150
PCB_HEIGHT = 64
FILAMENT_LAYER = 0.1
# TODO: Add iso_fr (AZERTY) just for Slim :P
LAYOUTS = {
"ansi_en": [
["Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "⌫", None],
["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\\\"],
["A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "↵", None],
["Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "▲", "⬆", None],
["Ctrl", "Fn", "⬆", "Alt", "———", None, None, "-", "=", "◀", "▼", "▶", "Ctrl"]
],
"ansi_big_enter_en": [
["Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "⌫", None],
["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "↵"],
["A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "\\\\", None],
["Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "▲", "⬆", None],
["Ctrl", "Fn", "⬆", "Alt", "———", None, None, "-", "=", "◀", "▼", "▶", "Ctrl"]
],
"iso_en": [
["Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "⌫", None],
["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "↵"],
["A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "#", None],
["Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "▲", "\\\\", "⬆"],
["Ctrl", "Fn", "⬆", "Alt", "———", None, None, "-", "=", "◀", "▼", "▶", "Ctrl"]
],
"iso_de": [
["Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "⌫", None],
["Q", "W", "E", "R", "T", "Z", "U", "I", "O", "P", "Ü", "+", "↵"],
["A", "S", "D", "F", "G", "H", "J", "K", "L", "Ö", "Ä", "#", None],
["Y", "X", "C", "V", "B", "N", "M", ",", ".", "/", "▲", "<", "⬆"],
["Ctrl", "Fn", "⬆", "Alt", "———", None, None, "ẞ", "´", "◀", "▼", "▶", "Ctrl"]
]
}
def get_label_size(label: str) -> float:
"""
Get font size depending on label.
:param label:
:return:
"""
if label == "↵":
return 4
elif label in ["Esc", "Alt", "Fn", "Ä", "Ü", "Ö"]:
return 3
elif label == "Ctrl":
return 2.5
else:
return 3.5

18
OLD/motorola_g100.ini Normal file
View file

@ -0,0 +1,18 @@
# Motorola moto g100
[phone]
width = 74.2
height = 168.4
thickness = 9.7
corner_radius = 10
side_radius = 5
[key_mat]
margin = 1
padding = 1
thickness = 0.5
key_width = 9
key_height = 6
key_corner_radius = 1
key_thickness = 2
font = DejaVu Sans:style=Bold

18
OLD/oneplus_8t.ini Normal file
View file

@ -0,0 +1,18 @@
# Oneplus 8t
[phone]
width = 160.7
height = 74.1
thickness = 8.4
corner_radius = 10
side_radius = 5
[key_mat]
margin = 1
padding = 1
thickness = 0.5
key_width = 9
key_height = 6
key_corner_radius = 1
key_thickness = 2
font = DejaVu Sans:style=Bold

1
OLD/phones/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
!*.scad

View file

@ -0,0 +1,43 @@
// Samsung Galaxy S22+
$fn = 64;
module SamsungGalaxyS22Plus() {
depth = 7.6;
width = 75.8;
height = 157.4;
corner_radius = 10;
bump_depth = 1.5;
bump_width = 22;
bump_height = 50;
flash_radius = 3;
flash_top = 11;
flash_left = 27;
translate([corner_radius, corner_radius, 0]) {
// phone body
hull() {
cylinder(h=depth, r=corner_radius);
translate([width - 2*corner_radius, 0, 0]) cylinder(h=depth, r=corner_radius);
translate([0, height - 2*corner_radius, 0]) cylinder(h=depth, r=corner_radius);
translate([width - 2*corner_radius, height - 2*corner_radius, 0]) cylinder(h=depth, r=corner_radius);
};
translate([0, height - 2*corner_radius, depth]) {
// camera bump
hull() {
cylinder(h=bump_depth, r1=corner_radius, r2=corner_radius-1);
translate([bump_width - 2*corner_radius + corner_radius-2, corner_radius-2, 0]) cylinder(h=bump_depth, r1=2, r2=1);
translate([bump_width - 2*corner_radius, -1 * (bump_height - 2*corner_radius), 0]) cylinder(h=bump_depth, r1=corner_radius, r2=corner_radius-1);
translate([-1* (corner_radius-2), -1* (bump_height - 2*corner_radius + corner_radius-2), 0]) cylinder(h=bump_depth, r1=2, r2=1);
};
// flashlight
translate([flash_left - corner_radius, -1* (flash_top - corner_radius), 0]) cylinder(h=10, r1=flash_radius, r2=10+flash_radius);
};
};
};
SamsungGalaxyS22Plus();

BIN
OLD/poc/mechanism.skp Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more