Files
pirouette/camera_mount.py
Arnaud Morin 9e10071e1a Increase a little bit camera lens hole size
Signed-off-by: Arnaud Morin <arnaud.gfpv@mailops.fr>
2026-09-05 14:59:19 +02:00

139 lines
3.7 KiB
Python

# @author Arnaud Morin <arnaud.gfpv@mailops.fr>
# SPDX-License-Identifier: Apache-2.0
#
import cadquery as cq
from math import sqrt
def camera_mount():
cam = (cq.Workplane("XZ")
.box(17, 17, 10, centered=(True, True, False))
.faces(">Y")
.workplane()
.rect(17, 17)
.workplane(offset=8)
.rect(14, 14)
.loft(combine=True))
# Round the loft's four corners.
corners = cq.selectors.BoxSelector((-10, 1, -10), (10, 8, 10))
cam = cam.edges(corners).fillet(6.0)
# Lens hole
cam = cam.faces(">Y").workplane().hole(13.5)
# Camera pocket
cam = cam.faces("<Y").workplane().rect(14, 14).cutBlind(-9)
# Position camera correctly
cam = (cam.rotate((0, 0, 0), (1, 0, 0), 45)
.translate((0, 9, 17)))
# Base plate
base = (cq.Workplane("XY")
.box(55,55,1, centered=(True,True,False)))
# Skirt (jupe)
bottom_pts = [
(12, -22), (12, -7.5), (12, 0), (12, 7.5),
(12, 17), (6, 17), (0, 17), (-6, 17),
(-12, 17), (-12, 7.5), (-12, 0), (-12, -7.5),
(-12, -22), (-6, -22), (0, -22), (6, -22),
]
bottom = cq.Wire.makePolygon(
[cq.Vector(x, y, 0.0) for x, y in bottom_pts], close=True)
top_pts = [
(8.5, 8.5), (8.5, 4.25), (8.5, 0), (8.5, -4.25),
(8.5, -8.5), (4.25, -8.5), (0, -8.5), (-4.25, -8.5),
(-8.5, -8.5), (-8.5, -4.25), (-8.5, 0), (-8.5, 4.25),
(-8.5, 8.5), (-4.25, 8.5), (0, 8.5), (4.25, 8.5),
]
top = (cq.Wire.makePolygon(
[cq.Vector(x, -5.0, z) for x, z in top_pts], close=True)
.rotate((0, 0, 0), (1, 0, 0), 45)
.translate((0, 9, 17)))
skirt = cq.Workplane("XY").add(cq.Solid.makeLoft([bottom, top], True))
p = base.union(skirt)
# Filet between the union using a box to select the edges.
box = cq.selectors.BoxSelector((-13, -23, 0), (13, 18, 3), boundingbox=True)
p = p.faces("+Z").edges(box).fillet(9)
# Skirt pocket for camera
normal_45 = cq.Vector(0, 1 / sqrt(2), 1 / sqrt(2))
p = (p.faces(cq.DirectionSelector(normal_45))
.workplane(centerOption="CenterOfBoundBox")
.rect(14, 14)
.cutThruAll())
# Filet below base, on three sides of the pocket's exit hole.
box = cq.selectors.BoxSelector((-14, -16, 0), (14, 10, 1))
p = p.faces("-Z").edges(box).fillet(4.5)
# Camera support
p = p.union(cam)
# Cut extra plate
quadrant = [
(21, 0),
(15, 7),
(20, 23.7),
(14, 23.7),
(7.5, 20.5),
(0, 20.5),
(0, 40),
(40, 40),
(40, 0),
]
cut = (
cq.Workplane("XY")
.polyline(quadrant)
.close()
.extrude(10)
)
cut = cut.union(cut.mirror("XZ"))
cut = cut.union(cut.mirror("YZ"))
cut = cut.edges("|Z").fillet(3)
p = p.cut(cut)
# Add holes for 25.5x25.5 FC.
bolts = (cq.Workplane("XY")
.pushPoints([(18.03, 0), (-18.03, 0), (0, -18.03), (0, 18.03)])
.circle(2.2 / 2.0)
.extrude(10, both=True))
p = p.cut(bolts)
# Add holes for standoff
x, y = (14, 20)
bolts = (cq.Workplane("XY")
.pushPoints([(sx * x, sy * y) for sx in (-1.0, 1.0) for sy in (-1.0, 1.0)])
.circle(2.2 / 2.0)
.extrude(10, both=True))
p = p.cut(bolts)
return p
result = camera_mount()
assert result.solids().size() == 1, "camera_mount is not one solid"
if "show_object" not in globals(): # running outside CQ-editor
def show_object(*args, **kwargs):
pass
show_object(result)
if __name__ == "__main__":
TPU_DENSITY = 1.21e-3 # g/mm3
solid = result.val()
print("camera_mount %.2f g in TPU"
% (solid.Volume() * TPU_DENSITY))