Initial Commit
This commit is contained in:
commit
6f62c24f9b
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.stl
|
||||||
|
/__pycache__/
|
||||||
|
/*.svg
|
31
key_bittings.py
Normal file
31
key_bittings.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
MM_PER_IN = 25.4
|
||||||
|
|
||||||
|
|
||||||
|
# A progression of root depths, decreasing by a constant amount each step.
|
||||||
|
def linear_depths(start, end, base, increment):
|
||||||
|
return {str(depth): base - (depth - start) * increment
|
||||||
|
for depth in range(start, end + 1)}
|
||||||
|
|
||||||
|
|
||||||
|
def depths_in_to_mm(depths):
|
||||||
|
return {name: depth * MM_PER_IN for name, depth in depths.items()}
|
||||||
|
|
||||||
|
|
||||||
|
# https://www.lockreference.com/wp-content/uploads/2019/03/Yale-Disc-Tumbler.pdf
|
||||||
|
yale_disc = depths_in_to_mm({
|
||||||
|
"1": .250,
|
||||||
|
"2": .230,
|
||||||
|
"X": .220, # also called "7"
|
||||||
|
"3": .210,
|
||||||
|
"4": .190,
|
||||||
|
"5": .170,
|
||||||
|
})
|
||||||
|
|
||||||
|
# https://www.lockreference.com/wp-content/uploads/2018/01/Yale-.019.pdf
|
||||||
|
yale_019 = depths_in_to_mm(linear_depths(0, 9, .320, .019))
|
||||||
|
|
||||||
|
# https://www.lockreference.com/wp-content/uploads/2018/01/Yale-.025.pdf
|
||||||
|
yale_025 = depths_in_to_mm(linear_depths(0, 7, .320, .025))
|
||||||
|
|
||||||
|
# https://www.lockreference.com/wp-content/uploads/2018/09/National-Disc-Tumbler-Single-Sided.pdf
|
||||||
|
national_disc_tumbler = depths_in_to_mm(linear_depths(1, 4, .250, .025))
|
88
snap_on_templates.py
Normal file
88
snap_on_templates.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import cadquery as cq
|
||||||
|
from cadquery import exporters
|
||||||
|
|
||||||
|
import key_bittings
|
||||||
|
|
||||||
|
MM_PER_IN = 25.4
|
||||||
|
|
||||||
|
key_thickness = 2 + .2
|
||||||
|
|
||||||
|
text_size = 4
|
||||||
|
text_depth = 0.5
|
||||||
|
text_margin = 2
|
||||||
|
|
||||||
|
lishi_width = 18 - 0.3
|
||||||
|
lishi_depth = 5
|
||||||
|
lishi_height = 9.98
|
||||||
|
lishi_overhang_height = 2.25
|
||||||
|
lishi_overhang_width = 1
|
||||||
|
lishi_overhang_radius = 1 - .000000001 # workaround to fillet a part with the same thickness
|
||||||
|
corner_radius = 0.5
|
||||||
|
side_thickness = 1
|
||||||
|
bottom_thickness = 2
|
||||||
|
back_thickness = 1.5
|
||||||
|
# this number is somewhat estimated, but quite important
|
||||||
|
# it is the offset from the end of the pliers to the point of the cutter
|
||||||
|
lishi_cutter_offset = .54 * MM_PER_IN
|
||||||
|
key_guide_width = 15
|
||||||
|
key_guide_height = 12.5
|
||||||
|
|
||||||
|
notch_width = 1
|
||||||
|
notch_height = 1.32
|
||||||
|
notch_depth = 0.5
|
||||||
|
|
||||||
|
|
||||||
|
def lishi_template(name, depth):
|
||||||
|
result = (
|
||||||
|
cq
|
||||||
|
.Workplane("front")
|
||||||
|
.box(lishi_width + side_thickness * 2, lishi_depth + lishi_overhang_width, lishi_height + bottom_thickness)
|
||||||
|
.tag("lishi_interface")
|
||||||
|
.edges("not >Y").fillet(corner_radius)
|
||||||
|
)
|
||||||
|
|
||||||
|
# TODO: positioning could be better
|
||||||
|
result = (
|
||||||
|
result
|
||||||
|
.faces("<Y").workplane().move(0, bottom_thickness/2)
|
||||||
|
.rect(lishi_width, lishi_height).cutBlind(-lishi_depth)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = (
|
||||||
|
result
|
||||||
|
.faces("<X", tag="lishi_interface").vertices(">Y and >Z")
|
||||||
|
.workplane(offset=-side_thickness, centerOption="CenterOfMass")
|
||||||
|
.rect(lishi_overhang_width, lishi_overhang_height, centered=False).extrude(-lishi_width)
|
||||||
|
.edges(">Z").edges("<Y").fillet(lishi_overhang_radius)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = (
|
||||||
|
result
|
||||||
|
.faces(">Y", tag="lishi_interface").vertices(">X and <Z")
|
||||||
|
.workplane(centerOption="CenterOfMass")
|
||||||
|
.rect(key_guide_width, key_guide_height, centered=False).extrude(key_thickness + back_thickness, combine=False)
|
||||||
|
.tag("key_guide")
|
||||||
|
.edges("not <Y").fillet(corner_radius)
|
||||||
|
.faces(">X", tag="key_guide").vertices("<Z and <Y").workplane(centerOption="CenterOfMass").center(0, bottom_thickness + lishi_cutter_offset - depth)
|
||||||
|
# ideally, the key profile would be passed in as an argument
|
||||||
|
.rect(key_thickness, depth, centered=False).cutThruAll()
|
||||||
|
.union(result) # this seems like a fairly bad way to do this, but it does work
|
||||||
|
)
|
||||||
|
|
||||||
|
result = (
|
||||||
|
result
|
||||||
|
.add(result.objects[0].Edges())
|
||||||
|
.faces(">Y", tag="key_guide").vertices(">XZ").workplane(centerOption="CenterOfMass")
|
||||||
|
# TODO: better positioning
|
||||||
|
.moveTo(lishi_width / 2 + side_thickness, -notch_height/2)
|
||||||
|
.rect(notch_width, notch_height).cutBlind(-notch_depth)
|
||||||
|
.faces(">Y").workplane(centerOption="CenterOfMass").text(name, text_size, -text_depth)
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
for name, depth in key_bittings.national_disc_tumbler.items():
|
||||||
|
#log(f"{name}, {depth}")
|
||||||
|
result = lishi_template(name, depth)
|
||||||
|
exporters.export(result, f'national_disc_tumbler_{name}.stl')
|
Loading…
Reference in New Issue
Block a user