Programmatic generation of an openUC2 cube insert and component cutouts using CadQuery.
Python-generated generic insert that can e.g. host a lens or something
Goal:
- Create a reusable insert “blank” (outer geometry + optional tabs/wings + threaded holes).
- Create separate component STEP cutters (lens pockets, motor clearances, etc.).
- Import any STEP cutter, apply an affine transform, and subtract it from the insert to produce a printable/custom holder.
Coordinate system:
- Optical axis = Z-axis
- Optical axis passes through (0, 0) in the XY-plane
- All shapes are built around the origin by default
Creates a negative volume (“cutter”) as a STEP file.
Typical use:
- Generate a lens pocket as a cylinder + optional seat + optional set-screw holes.
- Export as
component_cut.step(and optionallycomponent_cut.stl).
You can create multiple cutters, e.g.:
lens_25mm_cut.stepmotor_clearance_cut.steplaser_mount_cut.step
These STEP cutters are then consumed by the insert builder.
Creates the insert body and subtracts one or more imported STEP cutters.
What it generates:
- Outer insert outline (octagon-like profile from the technical drawing)
- Optional side tabs (or “wings” depending on the version you use)
- Optional center bore (or you do center bore via cutter STEP)
- Optional threaded/tapping holes
- Subtraction of imported cutters after applying affine transforms
- Exports
uc2_insert.stepanduc2_insert.stl
Create an environment and install CadQuery:
pip install cadqueryIf your Python environment is already set up (e.g. mambaforge), install into that environment.
python uc2_component_cut_step.pyThis writes:
component_cut.stepcomponent_cut.stl(optional)
Edit uc2_insert_builder.py and add the cutter to CUTTERS, then run:
python uc2_insert_builder.pyThis writes:
uc2_insert.stepuc2_insert.stl
A cutter is any solid STEP you want to subtract from the insert.
Typical workflow:
- Generate a cutter STEP in a dedicated script (preferred, reproducible)
- Add it to
CUTTERSlist inuc2_insert_builder.py - Assign an affine transform for positioning/orientation
- Boolean subtract (
insert.cut(cutter))
This supports:
- Lens holders (coaxial to optical axis)
- Motor pockets (offset + rotated)
- LED/laser holders
- Cable channels / clearance volumes
- Any imported CAD STEP solid
Each cutter can be positioned and rotated with:
- Translation:
tx, ty, tz(mm) - Rotation:
rx, ry, rz(degrees, applied about origin, in order X → Y → Z)
Example: shift 2 mm in X, rotate 15° around optical axis:
CUTTERS = [
("component_cut.step", Affine(tx=2.0, ty=0.0, tz=0.0, rx=0.0, ry=0.0, rz=15.0)),
]Tip:
- If you want a lens centered on the optical axis, keep
(tx, ty) = (0, 0).
In uc2_insert_builder.py:
OUTER_HALF,SHOULDER_HALF: insert outlineINSERT_THICKNESS: extrusion thicknessADD_SIDE_TABS, tab dimensionsADD_THREAD_HOLESand hole geometryCUTTERSlist and each cutter transform
In uc2_component_cut_step.py:
- Lens diameter + clearance
- Seat diameter + depth
- Set screw count, diameter, radius
This approach is meant to support openUC2’s open insert ecosystem:
- Generate inserts reproducibly
- Share scripts + parameters
- Allow others to remix and extend
If you create a useful cutter for a common component (lens size, motor, LED), publish it with:
- source script
- generated STEP
- a short usage snippet (recommended transform and parameters)
