1 import cadquery as cq
2
3 # Parameters
4 H = 400
5 W = 200
6 D = 350
7
8 PROFILE = cq.importers.importDXF("vslot-2020_1.dxf").wires()
9
10 SLOT_D = 6
11 PANEL_T = 3
12
13 HANDLE_D = 20
14 HANDLE_L = 50
15 HANDLE_W = 4
16
17
18 def make_vslot(l):
19 return PROFILE.toPending().extrude(l)
20
21
22 def make_connector():
23 rv = (
24 cq.Workplane()
25 .box(20, 20, 20)
26 .faces("<X")
27 .workplane()
28 .cboreHole(6, 15, 18)
29 .faces("<Z")
30 .workplane(centerOption="CenterOfMass")
31 .cboreHole(6, 15, 18)
32 )
33
34 # tag mating faces
35 rv.faces(">X").tag("X").end()
36 rv.faces(">Z").tag("Z").end()
37
38 return rv
39
40
41 def make_panel(w, h, t, cutout):
42 rv = (
43 cq.Workplane("XZ")
44 .rect(w, h)
45 .extrude(t)
46 .faces(">Y")
47 .vertices()
48 .rect(2 * cutout, 2 * cutout)
49 .cutThruAll()
50 .faces("<Y")
51 .workplane()
52 .pushPoints([(-w / 3, HANDLE_L / 2), (-w / 3, -HANDLE_L / 2)])
53 .hole(3)
54 )
55
56 # tag mating edges
57 rv.faces(">Y").edges("%CIRCLE").edges(">Z").tag("hole1")
58 rv.faces(">Y").edges("%CIRCLE").edges("<Z").tag("hole2")
59
60 return rv
61
62
63 def make_handle(w, h, r):
64 pts = ((0, 0), (w, 0), (w, h), (0, h))
65
66 path = cq.Workplane().polyline(pts)
67
68 rv = (
69 cq.Workplane("YZ")
70 .rect(r, r)
71 .sweep(path, transition="round")
72 .tag("solid")
73 .faces("<X")
74 .workplane()
75 .faces("<X", tag="solid")
76 .hole(r / 1.5)
77 )
78
79 # tag mating faces
80 rv.faces("<X").faces(">Y").tag("mate1")
81 rv.faces("<X").faces("<Y").tag("mate2")
82
83 return rv
84
85
86 # define the elements
87 door = (
88 cq.Assembly()
89 .add(make_vslot(H), name="left")
90 .add(make_vslot(H), name="right")
91 .add(make_vslot(W), name="top")
92 .add(make_vslot(W), name="bottom")
93 .add(make_connector(), name="con_tl", color=cq.Color("black"))
94 .add(make_connector(), name="con_tr", color=cq.Color("black"))
95 .add(make_connector(), name="con_bl", color=cq.Color("black"))
96 .add(make_connector(), name="con_br", color=cq.Color("black"))
97 .add(
98 make_panel(W + 2 * SLOT_D, H + 2 * SLOT_D, PANEL_T, SLOT_D),
99 name="panel",
100 color=cq.Color(0, 0, 1, 0.2),
101 )
102 .add(
103 make_handle(HANDLE_D, HANDLE_L, HANDLE_W),
104 name="handle",
105 color=cq.Color("yellow"),
106 )
107 )
108
109 # define the constraints
110 (
111 door
112 # left profile
113 .constrain("left@faces@<Z", "con_bl?Z", "Plane")
114 .constrain("left@faces@<X", "con_bl?X", "Axis")
115 .constrain("left@faces@>Z", "con_tl?Z", "Plane")
116 .constrain("left@faces@<X", "con_tl?X", "Axis")
117 # top
118 .constrain("top@faces@<Z", "con_tl?X", "Plane")
119 .constrain("top@faces@<Y", "con_tl@faces@>Y", "Axis")
120 # bottom
121 .constrain("bottom@faces@<Y", "con_bl@faces@>Y", "Axis")
122 .constrain("bottom@faces@>Z", "con_bl?X", "Plane")
123 # right connectors
124 .constrain("top@faces@>Z", "con_tr@faces@>X", "Plane")
125 .constrain("bottom@faces@<Z", "con_br@faces@>X", "Plane")
126 .constrain("left@faces@>Z", "con_tr?Z", "Axis")
127 .constrain("left@faces@<Z", "con_br?Z", "Axis")
128 # right profile
129 .constrain("right@faces@>Z", "con_tr@faces@>Z", "Plane")
130 .constrain("right@faces@<X", "left@faces@<X", "Axis")
131 # panel
132 .constrain("left@faces@>X[-4]", "panel@faces@<X", "Plane")
133 .constrain("left@faces@>Z", "panel@faces@>Z", "Axis")
134 # handle
135 .constrain("panel?hole1", "handle?mate1", "Plane")
136 .constrain("panel?hole2", "handle?mate2", "Point")
137 )
138
139 # solve
140 door.solve()
141
142 show_object(door, name="door")