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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
from types import SimpleNamespace
from cadquery import ParallelDirSelector, Workplane, Solid
XY = Workplane("XY")
center_xy = (True, True, False)
class V(SimpleNamespace):
def __add__(self, rhs):
assert(set(self.__dict__.keys()) <= set(rhs.__dict__.keys()))
items = [(k, v + rhs.__dict__[k]) for k,v in self.__dict__.items()]
return V(**dict(items))
def __sub__(self, rhs):
assert(set(self.__dict__.keys()) <= set(rhs.__dict__.keys()))
items = [(k, v - rhs.__dict__[k]) for k,v in self.__dict__.items()]
return V(**dict(items))
def __mul__(self, rhs):
assert(isinstance(rhs, int))
items = [(k, v *rhs) for k,v in self.__dict__.items()]
return V(**dict(items))
def xyz(self):
return (self.x, self.y, self.z)
def Ext(part, bounds):
setattr(part, "bounds", bounds)
return part
def V3(x, y, z):
return V(x=x, y=y, z=z)
def V21(v):
return V3(2 * v, 2 * v, v)
def build_bolt(bolt, shaft, tol):
height = shaft + bolt.head_height
part = XY.circle(bolt.head_radius).extrude(bolt.head_height)
part = part.union(XY.circle(bolt.radius).extrude(height))
bounds = XY.circle(bolt.head_radius + 2 * tol).extrude(bolt.head_height + 2 * tol).translate((0, 0, -tol))
bounds = bounds.union(XY.circle(bolt.radius - 0.1 + tol).extrude(height + 10 + 2 * tol).translate((0, 0, - 10 -tol)))
transform = lambda p, h: p.rotate((0, 0, 0), (1, 0, 0), 180).translate((0, 0, h))
return Ext(transform(part, height), transform(bounds, height + tol))
def build_rod(rod, tol):
part = XY.circle(rod.outer).circle(rod.inner).extrude(rod.len)
bounds = XY.circle(rod.outer + tol).extrude(rod.len + 2 * tol).translate((0, 0, -tol))
return Ext(part, bounds)
def build_lid(base, rod, rod_shaft, wall, bolt, bolt_depth, tol, hole_spacing):
outer = base
inner = base - V21(wall + tol)
rod_wall = V(outer = rod.outer + tol + wall, inner = rod.outer + tol, z = rod_shaft.height)
part_bolt = build_bolt(bolt, bolt_depth, tol)
def gen(tol):
outer_padded = outer + V3(tol, tol, tol) * 2
inner_padded = inner - V3(tol, tol, tol) * 2
part = XY.box(*outer_padded.xyz(), centered=center_xy).translate((0, 0, -tol))
part = part.cut(XY.box(*inner_padded.xyz(), centered=center_xy).translate((0, 0, -tol)))
for y in range(-1, 2, 2):
for x in range(-1, 2, 2):
pos = V3(x * hole_spacing.x / 2, y * hole_spacing.y / 2, outer.z)
head_radius = bolt.head_radius + wall + tol
head_height = bolt.head_height + wall + tol
offset_x = (outer.x - 2 * wall - hole_spacing.x) / 2 + tol
offset_y = (outer.y - 2 * wall - hole_spacing.y) / 2 + tol
part = part.union(XY.circle(head_radius).extrude(head_height) \
.translate((pos + V3(0, 0, -head_height)).xyz()))
part = part.union(XY.box(offset_x, offset_y + head_radius, head_height, centered=center_xy) \
.translate((pos + V3(offset_x*x/2, y*(offset_y-(offset_y+head_radius)/2), -head_height)).xyz()))
part = part.union(XY.box(offset_x + head_radius, offset_y, head_height, centered=center_xy) \
.translate((pos + V3(x*(offset_x-(offset_x+head_radius)/2), offset_y*y/2, -head_height)).xyz()))
if tol != 0:
part = part.union(part_bolt.bounds.translate((pos + V3(0, 0, -bolt_depth - bolt.head_height)).xyz()))
else:
part = part.cut(part_bolt.bounds.translate((pos + V3(0, 0, -bolt_depth - bolt.head_height)).xyz()))
return part
part = gen(0)
part_rod_wall = XY.circle(rod_wall.outer).extrude(rod_wall.z)
part = part.union(part_rod_wall.translate((rod_shaft.pos + V3(0, 0, inner.z)).xyz()))
part = part.cut(build_rod(rod, tol).bounds.translate(rod_shaft.pos.xyz()))
part_bounds = gen(tol)
return Ext(part, part_bounds)
def build_base(base, rod, rod_shaft, insert, bolt, wall, tol, lid):
outer = base
inner = outer - V3(2 * wall.x, 2 * wall.y, wall.z) + V21(tol)
floor = wall.z - tol
part = XY.box(*base.xyz(), centered=center_xy)
part = part.cut(XY.box(*inner.xyz(), centered=center_xy).translate((0, 0, floor)))
tower_radius = bolt.radius + wall.x + 1
tower_height = inner.z
for y in range(-1, 2, 2):
for x in range(-1, 2, 2):
pos = V3(x * lid.hole_spacing.x / 2, y * lid.hole_spacing.y / 2, floor)
offset_x = (inner.x - lid.hole_spacing.x) / 2
offset_y = (inner.y - lid.hole_spacing.y) / 2
part = part.union(XY.box(offset_x, offset_y + tower_radius, tower_height, centered=center_xy) \
.translate((pos + V3(offset_x*x/2, y*(offset_y-(offset_y+tower_radius)/2), 0)).xyz()))
part = part.union(XY.box(offset_x + tower_radius, offset_y, tower_height, centered=center_xy) \
.translate((pos + V3(x*(offset_x-(offset_x+tower_radius)/2), offset_y*y/2, 0)).xyz()))
part = part.union(XY.circle(tower_radius).extrude(tower_height).translate(pos.xyz()))
part = part.union(XY.box(wall.x, inner.y, tower_height, centered=center_xy).translate((-20, 0, floor)))
part = part.union(XY.box(wall.x, inner.y, tower_height, centered=center_xy).translate((20, 0, floor)))
rod_pos = (rod_shaft.pos + V3(0, 0, floor)).xyz()
part = part.union(XY.circle(rod.outer + wall.x + 2).extrude(tower_height).translate(rod_pos))
fill_y = inner.y / 2 - rod_shaft.pos.y
part = part.union(XY.box(40, fill_y, tower_height, centered=center_xy).translate(rod_pos)\
.translate((0, -rod_shaft.pos.y+inner.y/2-fill_y/2, 0)))
part = part.cut(XY.circle(rod.outer + tol).extrude(tower_height).translate(rod_pos))
part = part.union(XY.box(40, fill_y, 3, centered=center_xy).translate(rod_pos)\
.translate((0, -rod_shaft.pos.y+inner.y/2-fill_y/2, 0)))
part = part.cut(XY.box(20, 25, 8, centered=center_xy).translate(rod_pos).translate((0, -rod.outer - wall.x/2)))
part = part.cut(build_lid(**lid.__dict__).bounds.translate((0, 0, base.z - lid.base.z)))
return part
def main():
# TEST PRINT
base = V3(80, 80, 15)
rod_shaft = V(pos = V3(0, 0, 0), height = 20)
tol = 0.05
rod = V(outer = 25 / 2, inner = 21 / 2, len = 500)
#base = V3(120, 120, 30)
#rod_shaft = V(pos = V3(0, 30, 0), height = 35)
thin_wall = 2.4
thick_wall = 4
bolt = V(radius = 3 / 2, head_radius = 5.4 / 2, head_height = 3)
bolt_depth = 10 + 1
lid = V3(base.x, base.y, 10)
lid_hole_spacing = V3(lid.x - 15, lid.y - 15, 0)
insert = V(radius=5 / 2, height=5)
base_wall = V3(thick_wall, thick_wall, thin_wall)
#show_object(build_rod(rod).translate((0, 0, 10)))
lid_ctx = V(base=lid, rod=rod, rod_shaft=rod_shaft,
wall=thin_wall, bolt=bolt, bolt_depth=bolt_depth, tol=tol,
hole_spacing=lid_hole_spacing)
show_object(build_lid(**lid_ctx.__dict__).translate((150, 0, 0)))
base_ctx = V(base=base, rod=rod, rod_shaft=rod_shaft, bolt=bolt, wall=base_wall, tol=tol, insert=insert)
show_object(build_base(**base_ctx.__dict__, lid=lid_ctx))
main()
|