Small Machine Vise
A small benchtop vise for holding parts while drilling, filing or gluing, made of three printed parts: a body with a fixed jaw, a moving jaw that slides on a center rail, and a knob. The lead screw is not printed; an off-the-shelf M8 hex bolt (about 100 mm) and two nuts provide the clamping force. One nut drops into the rear block from above, the bolt head is captured in a pocket in the moving jaw so turning the knob both pushes and pulls, and the second nut is pressed into the knob. The base is 120 x 70 mm, the print layout is 120 x 176 x 40 mm, and the jaws open up to about 65 mm; a vertical V-groove in the fixed jaw helps hold round stock. All parts print as laid out with no supports; PETG is recommended. You can switch between the print layout and an assembled view, and change the base length, jaw width and height, the V-groove and the sliding clearance.
# Small Machine Vise - driven by an M8 bolt and nut
#
# Three parts (multiple solids on purpose):
# 1. Body = base plate + fixed jaw + rear nut block + center rail
# 2. Moving jaw (rail groove underneath, pocket at the back for dropping in the bolt head from above)
# 3. Knob (with a hex hole for a press-fit M8 nut)
# The screw is not printed: use an off-the-shelf M8 hex bolt (about 100 long) and two nuts.
# - Nut 1 drops into the rear block from above (held against rotation)
# - The bolt head is captured in the moving jaw pocket but turns freely -> turning it both pushes and pulls
# - Nut 2 goes into the knob and is tightened onto the end of the bolt
#
# Axes: X = screw axis (+X toward the fixed jaw), base bottom z=0.
@param choices:["print", "assembled"] desc:"Output layout (print layout / assembled)"
layout = "print"
@param 80..200..5 group:"Body" desc:"Base length X (mm)"
base_l = 120
@param 40..80..1 group:"Body" desc:"Jaw width Y (mm)"
jaw_w = 50
@param 20..60..1 group:"Body" desc:"Jaw height (above the base top) (mm)"
jaw_h = 32
@param 1..60..1 group:"Body" desc:"Jaw opening in the assembled view (mm). At 0 the jaws touch and fuse"
opening = 25
@param desc:"Vertical V-groove in the fixed jaw (for round stock)"
v_groove = true
@param 0.2..0.6..0.05 group:"Fit" desc:"Sliding clearance (mm)"
clear = 0.3
# --- Body dimensions ---
base_t = 8
flange = 10 # mounting flange extending beyond the jaws on each side
base_w = jaw_w + 2 * flange
fixed_l = 15 # fixed jaw thickness (X)
rear_l = 18 # nut block thickness (X)
rear_h = jaw_h - 4
slide_l = 22 # moving jaw length (X)
rail_w = 16
rail_h = 5
mount_d = 5.5 # M5 mounting hole
# --- M8 hardware (JIS B 1180 / B 1181) ---
bolt_d = 8.6 # M8 clearance hole
head_af = 13 # hex head across flats
head_k = 5.3 # head height
nut_af = 13
nut_m = 6.5 # nut height
bolt_z = base_t + rail_h + 11 # screw axis height (passes above the rail)
head_r = head_af / sqrt(3) + 0.5 # head circumradius + clearance (turns freely)
x_fixed = base_l / 2 - fixed_l / 2
x_rear = -base_l / 2 + rear_l / 2
jaw_face = base_l / 2 - fixed_l # inner face X of the fixed jaw
# ===== 1. Body =====
plate = box base_l base_w base_t | floor | edges =Z | fillet 4
fixed = box fixed_l jaw_w jaw_h | floor | translate x_fixed 0 base_t
rear = box rear_l jaw_w rear_h | floor | translate x_rear 0 base_t
rail = box (base_l - fixed_l - rear_l + 2) rail_w rail_h | floor
| translate ((rear_l - fixed_l) / 2) 0 base_t
# Rear block: bolt clearance hole + nut slot dropped in from above (across flats keeps it from turning)
bore = cylinder (bolt_d / 2) (rear_l + 2) | rotate 0 90 0 | translate x_rear 0 bolt_z
nut_slot = box (nut_m + clear) (nut_af + clear) (jaw_h) | floor
| translate x_rear 0 (bolt_z - nut_af / sqrt(3) - clear)
# Four mounting holes (flange)
mx = base_l / 2 - 8
my = base_w / 2 - flange / 2
# Loop over the 4 corners with k = 0..3 (k//2 gives the X sign, k%2 the Y sign)
mounts = union [cylinder (mount_d / 2) (base_t + 2)
| translate (((k // 2) * 2 - 1) * mx) (((k % 2) * 2 - 1) * my) (base_t / 2)
for k in range(4)]
# Vertical V-groove in the fixed jaw (90 deg, 3 deep)
vg = box 4.243 4.243 (jaw_h + 2) | rotate 0 0 45 | floor
| translate jaw_face 0 base_t
body0 = plate + fixed + rear + rail - bore - nut_slot - mounts
body = if v_groove then (body0 - vg) else body0
# ===== 2. Moving jaw (built at the origin, placed later) =====
# Bottom at z=0, jaw face on the +X side (x = slide_l/2)
sj_block = box slide_l jaw_w jaw_h | floor
sj_slot = box (slide_l + 2) (rail_w + 2 * clear) (rail_h + clear) | floor | translate 0 0 -0.01
hz = bolt_z - base_t # screw axis height relative to the moving jaw
# Bolt head pocket (dropped in from above) and shank slot
head_pocket = box (head_k + 2 * clear) (2 * head_r) jaw_h | floor
| translate (-slide_l / 2 + 3 + (head_k + 2 * clear) / 2) 0 (hz - head_r)
shank_slot = box 4.5 bolt_d jaw_h | floor | translate (-slide_l / 2 + 1.25) 0 hz
shank_round = cylinder (bolt_d / 2) 6 | rotate 0 90 0 | translate (-slide_l / 2 + 1.5) 0 hz
slide0 = sj_block - sj_slot - head_pocket - shank_slot - shank_round
# ===== 3. Knob =====
knob_r = 18
knob_h = 14
knob0 = cylinder knob_r knob_h | floor | edges [>Z, <Z] | chamfer 1
grips = union [cylinder 3 (knob_h + 2) | floor | translate (knob_r * cos(a)) (knob_r * sin(a)) -1
for a in range(0, 360, 30)]
nut_pocket = polygon 6 ((nut_af + clear) / sqrt(3)) | extrude (nut_m + 0.5) | translate 0 0 (knob_h - nut_m - 0.5)
knob_bore = cylinder (bolt_d / 2) (knob_h + 2) | floor | translate 0 0 -1
knob1 = knob0 - grips - nut_pocket - knob_bore
# ===== Layout =====
# Assembled: moving jaw face set opening away from the fixed jaw inner face, raised clear above the base
slide_asm = slide0 | translate (jaw_face - opening - slide_l / 2) 0 (base_t + clear)
knob_asm = knob1 | rotate 0 90 0 | translate (-base_l / 2 - knob_h - 20) 0 bolt_z
# Print: placed beside the base
slide_prt = slide0 | translate 0 (-(base_w / 2 + jaw_w / 2 + 10)) 0
knob_prt = knob1 | translate 0 (base_w / 2 + knob_r + 10) 0
if layout == "print" then (body + slide_prt + knob_prt) else (body + slide_asm + knob_asm)