# This example is meant to be used from within the CadQuery module of FreeCAD. import cadquery from Helpers import show # Parameter definitions p_outerWidth = 100.0 # Outer width of box enclosure p_outerLength = 150.0 # Outer length of box enclosure p_outerHeight = 50.0 # 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 bo p_topAndBottomRadius = 2.0 # Radius for the curves on the top and bottom edges p_screwpostInset = 12.0 # How far in from the edges the screwposts should be p_screwpostID = 4.0 # Inner diameter of the screwpost holes, should be roughly screw diameter not including threads p_screwpostOD = 10.0 # Outer diameter of the screwposts. Determines 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_lipHeight = 1.0 # Height of lip on the underside of the lid. Sits inside the box body for a snug fit. # Outer shell oshell = cadquery.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.edges("|Z").fillet(p_sideRadius) oshell.edges("#Z").fillet(p_topAndBottomRadius) else: oshell.edges("#Z").fillet(p_topAndBottomRadius) oshell.edges("|Z").fillet(p_sideRadius) # Inner shell ishell = oshell.faces("Z").workplane(-p_thickness)\ .rect(POSTWIDTH, POSTLENGTH, forConstruction=True)\ .vertices() for v in postCenters.all(): v.circle(p_screwpostOD / 2.0).circle(p_screwpostID / 2.0)\ .extrude((-1.0) * ((p_outerHeight + p_lipHeight) - (2.0 * 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() # 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 counterbore/countersink or counterbore topOfLidCenters = cutlip.faces(">Z").workplane().rect(POSTWIDTH, POSTLENGTH, forConstruction=True).vertices() # Add holes of the desired type if p_boreDiameter > 0 and p_boreDepth > 0: topOfLid = topOfLidCenters.cboreHole(p_screwpostID, p_boreDiameter, p_boreDepth, (2.0) * p_thickness) elif p_countersinkDiameter > 0 and p_countersinkAngle > 0: topOfLid = topOfLidCenters.cskHole(p_screwpostID, p_countersinkDiameter, p_countersinkAngle, (2.0) * p_thickness) else: topOfLid= topOfLidCenters.hole(p_screwpostID, 2.0 * p_thickness) # Return the combined result result = topOfLid.combineSolids(bottom) # Render the solid show(result)