90 lines
3.2 KiB
Python
90 lines
3.2 KiB
Python
# This example is meant to be used from within the CadQuery module of FreeCAD.
|
|
import cadquery as cq
|
|
from Helpers import show
|
|
|
|
exploded = False # when true, moves the base away from the top so we see
|
|
showTop = True # When true, the top is rendered.
|
|
showCover = True # When true, the cover is rendered
|
|
|
|
width = 2.2 # Nominal x dimension of the part
|
|
height = 0.5 # Height from bottom top to the top of the top :P
|
|
length = 1.5 # Nominal y dimension of the part
|
|
trapezoidFudge = 0.7 # ratio of trapezoid bases. set to 1.0 for cube
|
|
xHoleOffset = 0.500 # Holes are distributed symetrically about each axis
|
|
yHoleOffset = 0.500
|
|
zFilletRadius = 0.50 # Fillet radius of corners perp. to Z axis.
|
|
yFilletRadius = 0.250 # Fillet readius of the top edge of the case
|
|
lipHeight = 0.1 # The height of the lip on the inside of the cover
|
|
wallThickness = 0.06 # Wall thickness for the case
|
|
coverThickness = 0.2 # Thickness of the cover plate
|
|
holeRadius = 0.30 # Button hole radius
|
|
counterSyncAngle = 100 # Countersink angle.
|
|
|
|
xyplane = cq.Workplane("XY")
|
|
yzplane = cq.Workplane("YZ")
|
|
|
|
|
|
def trapezoid(b1, b2, h):
|
|
"Defines a symetrical trapezoid in the XY plane."
|
|
|
|
y = h / 2
|
|
x1 = b1 / 2
|
|
x2 = b2 / 2
|
|
return (xyplane
|
|
.polyline([(-x1, y),
|
|
(x1, y),
|
|
(x2, -y),
|
|
(-x2, -y),
|
|
(-x1, y)]))
|
|
|
|
|
|
# Defines our base shape: a box with fillets around the vertical edges.
|
|
# This has to be a function because we need to create multiple copies of
|
|
# the shape.
|
|
def base(h):
|
|
return (trapezoid(width, width * trapezoidFudge, length)
|
|
.extrude(h)
|
|
.translate((0, 0, height / 2))
|
|
.edges("Z")
|
|
.fillet(zFilletRadius))
|
|
|
|
# start with the base shape
|
|
top = (base(height)
|
|
# then fillet the top edge
|
|
.edges(">Z")
|
|
.fillet(yFilletRadius)
|
|
# shell the solid from the bottom face, with a .060" wall thickness
|
|
.faces("-Z")
|
|
.shell(-wallThickness)
|
|
# cut five button holes into the top face in a cross pattern.
|
|
.faces("+Z")
|
|
.workplane()
|
|
.pushPoints([(0, 0),
|
|
(-xHoleOffset, 0),
|
|
(0, -yHoleOffset),
|
|
(xHoleOffset, 0),
|
|
(0, yHoleOffset)])
|
|
.cskHole(diameter=holeRadius,
|
|
cskDiameter=holeRadius * 1.5,
|
|
cskAngle=counterSyncAngle))
|
|
|
|
# the bottom cover begins with the same basic shape as the top
|
|
cover = (base(coverThickness)
|
|
# we need to move it upwards into the parent solid slightly.
|
|
.translate((0, 0, -coverThickness + lipHeight))
|
|
# now we subtract the top from the cover. This produces a lip on the
|
|
# solid NOTE: that this does not account for mechanical tolerances.
|
|
# But it looks cool.
|
|
.cut(top)
|
|
# try to fillet the inner edge of the cover lip. Technically this
|
|
# fillets every edge perpendicular to the Z axis.
|
|
.edges("#Z")
|
|
.fillet(.020)
|
|
.translate((0, 0, -0.5 if exploded else 0)))
|
|
|
|
# Conditionally render the parts
|
|
if showTop:
|
|
show(top)
|
|
if showCover:
|
|
show(cover)
|