You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
5.6 KiB
189 lines
5.6 KiB
import cadquery as cq
|
|
|
|
usb_h = 10.5
|
|
usb_v = 5.2
|
|
|
|
socket_distance_x = 10.8
|
|
socket_distance_y = 36.55
|
|
socket_width = 28
|
|
|
|
# the width of the bezel on the side of the inner relay
|
|
side_bezel_width = 3.14
|
|
|
|
# how far the plug in the middle is from the side
|
|
# where the socket that powers the relay coil is
|
|
distance_from_socket_to_end = 46
|
|
|
|
relay_x_size = 120.2
|
|
relay_y_size = 168
|
|
|
|
# dimensions of the socket for coil power on the side
|
|
end_socket_width = 30.4
|
|
end_socket_height = 22.6
|
|
|
|
# the distance from the side of the socket to the edge of the box
|
|
# for the socket that powers the relay coil
|
|
end_socket_distance_from_side = 3.47 + 3 # add 3mm for tape
|
|
|
|
reset_button_dist_from_socket = 5.27
|
|
reset_width = 18.7
|
|
reset_height = 35.04
|
|
reset_lip_height = 3.37 # probably not needed
|
|
|
|
# parameter definitions
|
|
p_outerWidth = relay_x_size + 15 # Outer width of box enclosure
|
|
p_outerLength = relay_y_size # Outer length of box enclosure
|
|
p_outerHeight = 33.6 + 30 # Outer height of box enclosure
|
|
|
|
p_thickness = 3.0 # Thickness of the box walls
|
|
p_sideRadius = 10.0 # Radius for the curves around the sides of the box
|
|
p_topAndBottomRadius = (
|
|
2.0 # Radius for the curves on the top and bottom edges of the box
|
|
)
|
|
|
|
p_screwpostInset = 12.0 # How far in from the edges the screw posts should be place.
|
|
p_screwpostID = 4.0 # Inner Diameter of the screw post holes, should be roughly screw diameter not including threads
|
|
p_screwpostOD = 10.0 # Outer Diameter of the screw posts.\nDetermines overall thickness of the posts
|
|
|
|
p_boreDiameter = 8.0 # Diameter of the counterbore hole, if any
|
|
p_boreDepth = 1.0 # Depth of the counterbore hole, if
|
|
p_countersinkDiameter = 0.0 # Outer diameter of countersink. Should roughly match the outer diameter of the screw head
|
|
p_countersinkAngle = 90.0 # Countersink angle (complete angle between opposite sides, not from center to one side)
|
|
p_flipLid = True # Whether to place the lid with the top facing down or not.
|
|
p_lipHeight = 1.0 # Height of lip on the underside of the lid.\nSits inside the box body for a snug fit.
|
|
|
|
# outer shell
|
|
oshell = (
|
|
cq.Workplane("XY")
|
|
.rect(p_outerWidth, p_outerLength)
|
|
.extrude(p_outerHeight + p_lipHeight)
|
|
)
|
|
|
|
# weird geometry happens if we make the fillets in the wrong order
|
|
if p_sideRadius > p_topAndBottomRadius:
|
|
oshell = oshell.edges("|Z").fillet(p_sideRadius)
|
|
oshell = oshell.edges("#Z").fillet(p_topAndBottomRadius)
|
|
else:
|
|
oshell = oshell.edges("#Z").fillet(p_topAndBottomRadius)
|
|
oshell = oshell.edges("|Z").fillet(p_sideRadius)
|
|
|
|
# inner shell
|
|
ishell = (
|
|
oshell.faces("<Z")
|
|
.workplane(p_thickness, True)
|
|
.rect((p_outerWidth - 2.0 * p_thickness), (p_outerLength - 2.0 * p_thickness))
|
|
.extrude(
|
|
(p_outerHeight - 2.0 * p_thickness), False
|
|
) # set combine false to produce just the new boss
|
|
)
|
|
ishell = ishell.edges("|Z").fillet(p_sideRadius - p_thickness)
|
|
|
|
# make the box outer box
|
|
box = oshell.cut(ishell)
|
|
|
|
# make the screw posts
|
|
POSTWIDTH = p_outerWidth - 2.0 * p_screwpostInset
|
|
POSTLENGTH = p_outerLength - 2.0 * p_screwpostInset
|
|
|
|
box = (
|
|
box.faces(">Z")
|
|
.workplane(-p_thickness)
|
|
.rect(POSTWIDTH, POSTLENGTH, forConstruction=True)
|
|
.vertices()
|
|
.circle(p_screwpostOD / 2.0)
|
|
.circle(p_screwpostID / 2.0)
|
|
.extrude(-1.0 * (p_outerHeight + p_lipHeight - p_thickness), True)
|
|
)
|
|
|
|
# split lid into top and bottom parts
|
|
(lid, bottom) = (
|
|
box.faces(">Z")
|
|
.workplane(-p_thickness - p_lipHeight)
|
|
.split(keepTop=True, keepBottom=True)
|
|
.all()
|
|
) # splits into two solids
|
|
|
|
lid = (
|
|
lid.workplane()
|
|
.rect(
|
|
socket_width + socket_distance_x,
|
|
socket_distance_y + (socket_width),
|
|
forConstruction=True,
|
|
)
|
|
.tag("sockets")
|
|
.vertices()
|
|
.rect(socket_width, socket_width)
|
|
.cutThruAll()
|
|
)
|
|
|
|
bottom = (
|
|
bottom.faces(">Y")
|
|
.workplane()
|
|
.center(0, -end_socket_height + 8)
|
|
.rect(end_socket_width, end_socket_height)
|
|
.cutBlind("next")
|
|
)
|
|
|
|
holes = (
|
|
cq.Workplane("XY")
|
|
.rect((p_outerWidth - 20.0 * p_thickness), (p_outerLength - 20.0 * p_thickness))
|
|
.vertices()
|
|
.cylinder(10, 3.1 / 2)
|
|
)
|
|
|
|
bottom = bottom.cut(holes)
|
|
|
|
bottom = (
|
|
bottom.faces(">Y[0]")
|
|
.workplane(offset=0)
|
|
.move(0, -(p_outerHeight / 2) - usb_v - 3.3)
|
|
.box(usb_h, usb_v, 10, combine="cut")
|
|
)
|
|
|
|
# lid = (lid.center(socket_width-8, socket_distance_y+(socket_width)-3)
|
|
# .rect(reset_height, reset_width)
|
|
# .cutThruAll())
|
|
|
|
# translate the lid, and subtract the bottom from it to produce the lid inset
|
|
lowerLid = lid.translate((0, 0, -p_lipHeight))
|
|
cutlip = lowerLid.cut(bottom).translate(
|
|
(p_outerWidth + p_thickness, 0, p_thickness - p_outerHeight + p_lipHeight)
|
|
)
|
|
|
|
# compute centers for screw holes
|
|
topOfLidCenters = (
|
|
cutlip.faces(">Z")
|
|
.workplane(centerOption="CenterOfMass")
|
|
.rect(POSTWIDTH, POSTLENGTH, forConstruction=True)
|
|
.vertices()
|
|
)
|
|
|
|
# add holes of the desired type
|
|
if p_boreDiameter > 0 and p_boreDepth > 0:
|
|
print("first")
|
|
topOfLid = topOfLidCenters.cboreHole(
|
|
p_screwpostID, p_boreDiameter, p_boreDepth, 2.0 * p_thickness
|
|
)
|
|
elif p_countersinkDiameter > 0 and p_countersinkAngle > 0:
|
|
print("second")
|
|
topOfLid = topOfLidCenters.cskHole(
|
|
p_screwpostID, p_countersinkDiameter, p_countersinkAngle, 2.0 * p_thickness
|
|
)
|
|
else:
|
|
print("third")
|
|
topOfLid = topOfLidCenters.hole(p_screwpostID, 2.0 * p_thickness)
|
|
|
|
# flip lid upside down if desired
|
|
if p_flipLid:
|
|
topOfLid = topOfLid.rotateAboutCenter((1, 0, 0), 180)
|
|
|
|
# return the combined result
|
|
result = topOfLid.union(bottom)
|
|
|
|
cq.exporters.export(bottom, "/home/deck/model_files/enclosure_bottom.step")
|
|
cq.exporters.export(topOfLid, "/home/deck/model_files/enclosure_lid.step")
|
|
|
|
try:
|
|
show_object(bottom)
|
|
except NameError:
|
|
pass
|
|
|