/
covers.py
127 lines (104 loc) · 5.13 KB
/
covers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
from re import X
import cadquery as cq
import gridfinity
#The height of the label lip on divider bins.
label_lip_height = 11.75 - 2#mm
#How deep we want our covers to be.
depth = 3.5#mm
extra_depth = gridfinity.block_mating_depth - depth
def giant_block_lip(w, h):
"""Generate a block lip *without* the usual divisions between grid units.
e.g. for a 3x2 block, it will generate one large solid shape that mates
with it, rather than six arranged in a grid.
This block lip will not mate to a baseplate but it will mate to a stacking
lip."""
x = -(w * gridfinity.grid_unit / 2) + gridfinity.block_mating_inset
y = -(h * gridfinity.grid_unit / 2) + gridfinity.block_mating_inset
return cq.Workplane("XY")\
.gridfinity_block(w, h, 1)\
.faces("<Z")\
.placeSketch(gridfinity.inset_profile(w, h, gridfinity.block_mating_inset))\
.extrude(gridfinity.block_mating_depth * -1)\
.edges("<Z")\
.chamfer(gridfinity.block_mating_chamfer)\
.edges(cq.NearestToPointSelector([x, y, 0]))\
.chamfer(gridfinity.block_mating_inset - gridfinity.block_spacing * 0.5 - 0.01)
def cover(w, h):
return giant_block_lip(w, h)\
.faces(">Y")\
.workplane()\
.transformed((0,0,0), (0, -extra_depth, 0))\
.rect(gridfinity.grid_unit * w, gridfinity.block_extrusion(1) + extra_depth, centered = [True, False])\
.cutBlind(-100 * w)\
.faces(">Z")\
.workplane(centerOption='CenterOfBoundBox')\
.transformed((0,0,0), (0, -gridfinity.top_surface_length(h) / 2 - 20, 0))\
.rect(gridfinity.grid_unit * w, label_lip_height + 20, centered = [True, False])\
.cutBlind(-100 * w)\
.faces("<Y")\
.edges("<Z")\
.chamfer(2.5)\
.faces("<Y")\
.edges(">Z")\
.fillet(0.25)
def topplate(w, h):
"""Generate a top cover for a set of height-leveled Gridfinity blocks.
This is basically the inverse of a baseplate."""
with_cutouts = cq.Workplane("XY")\
.gridfinity_block(w, h, 0.5)\
.gridfinity_block_lip(w, h, holes=False)\
.faces(">Z")\
.edges(cq.NearestToPointSelector([(w * gridfinity.grid_unit / 2), (h * gridfinity.grid_unit / 2), gridfinity.block_extrusion(1)]))\
.fillet(gridfinity.block_stacking_lip / 2)
return with_cutouts
def midplate(w, h):
"""Generate a vertical divider, which is essentially a thin baseplate that
can be stacked on top of other storage blocks.
The purpose of vertical dividers are to prevent blocks with magnets from
magnetizing parts in divider bins stacked below them. They're sort of like
weighted baseplates, except they are sized to stack as if they were 1x tall
blocks."""
with_cutouts = cq.Workplane("XY")\
.gridfinity_block(w, h, 1)\
.gridfinity_block_lip(w, h, holes=False)\
.faces(">Z")\
.rarray(gridfinity.grid_unit, gridfinity.grid_unit, w, h)\
.eachpoint(lambda c: cq.Workplane("XY")\
.placeSketch(gridfinity.inset_profile(1, 1, gridfinity.block_mating_inset))\
.extrude(gridfinity.stacking_mating_depth * -1)\
.val()\
.moved(c)\
.moved(cq.Location(cq.Vector(0, 0, gridfinity.block_extrusion(1)))),
combine="cut",
clean=True)
filleted = with_cutouts
for i in range(0, w):
for j in range(0, h):
x = (i * gridfinity.grid_unit) - (w * gridfinity.grid_unit / 2) + gridfinity.block_mating_inset
y = (j * gridfinity.grid_unit) - (h * gridfinity.grid_unit / 2) + gridfinity.block_mating_inset
z = gridfinity.block_extrusion(1)
try:
filleted = filleted\
.edges(cq.NearestToPointSelector([x + gridfinity.grid_unit / 2, y + gridfinity.grid_unit / 2, z]))\
.chamfer(gridfinity.block_mating_inset - gridfinity.block_spacing * 0.5 - gridfinity.block_stacking_lip)\
.edges(cq.NearestToPointSelector([x + gridfinity.grid_unit / 2, y + gridfinity.grid_unit / 2, z - gridfinity.block_mating_depth]))\
.chamfer(gridfinity.block_stacking_chamfer)\
.faces(">Z")\
.edges(cq.NearestToPointSelector([x, y, z]))\
.fillet(gridfinity.block_stacking_lip / 2)
except:
continue
return filleted\
.faces(">Z")\
.edges(cq.NearestToPointSelector([(w * gridfinity.grid_unit / 2), (h * gridfinity.grid_unit / 2), gridfinity.block_extrusion(1)]))\
.fillet(gridfinity.block_stacking_lip / 2)
for i in range(1,7):
for j in range(1,7):
if j > i:
continue
x = (i * (i + 1) / 2) * gridfinity.grid_unit
y = (j * (j + 1) / 2) * gridfinity.grid_unit
if j == 1 and i <= 5:
locals()["cover" + str(i) + "_" + str(j)] = cover(i, j).translate((x, y, -10))
locals()["midplate" + str(i) + "_" + str(j)] = midplate(i, j).translate((x, y, 0))
locals()["topplate" + str(i) + "_" + str(j)] = topplate(i, j).translate((x, y, 20))