"""Bellows shaft coupling, clamping type: two hubs and a bellows. Axis along Z, the first hub's end face on the XY plane, bore d1 in the first hub, bore d2 in the second. Fit dimensions from MISUMI's table; see the README.""" import cadquery as cq from steve import Model size = 16 # mm Outside diameter D d1 = 5 # mm Bore 1 (d1 <= d2) d2 = 6 # mm Bore 2 detail = "full" # full: hubs, bellows, slits and clamp screw holes; simple: one solid with the bores # D: (L, hub length l, screw from the end F, screw offset G, clamp screw M, bores offered). # MISUMI Couplings catalogue, Bellows Couplings, Clamping, CPBC table, https://de.misumi-ec.com/files/images/products/docs/flexibleshaftcouplings.pdf, PDF p. 24. SIZES = {12: (23.5, 7.5, 2.3, 4, 2, (4, 5)), 16: (26.5, 9, 3, 5, 2.5, (5, 6)), 20: (33, 10, 3.5, 6.5, 2.5, (6, 8)), 25: (36.5, 12, 4.5, 9, 3, (8, 10)), 32: (42, 13.5, 5, 11, 4, (8, 10, 12, 14))} L, hub, F, G, screw, bores = SIZES[size] if d1 not in bores or d2 not in bores or d1 > d2: raise ValueError(f"The {size} mm bellows coupling offers bores {bores}, with d1 <= d2.") R = size / 2 SLIT = 0.05 * size # the slit's width and the bellows' folds are proportions, for looks; the table doesn't dimension them FOLDS = 8 def half(z0, bore, slit_z0): shape = cq.Workplane("XY").workplane(offset=z0).circle(R).extrude(hub) shape = shape.cut(cq.Workplane("XY").workplane(offset=z0 - 1).circle(bore / 2).extrude(hub + 2)) return shape.cut(cq.Workplane("XY").workplane(offset=slit_z0).center(R / 2 + 0.5, 0).rect(R + 1, SLIT).extrude(hub + 1)) model = Model() if detail == "simple": body = cq.Workplane("XY").circle(R).extrude(L) body = body.cut(cq.Workplane("XY").workplane(offset=-1).circle(d1 / 2).extrude(L / 2 + 1)) body = body.cut(cq.Workplane("XY").workplane(offset=L / 2).circle(d2 / 2).extrude(L / 2 + 1)) model.add("body", body, name="Bellows coupling") model.material("aluminum-generic", color="#c9ccd1") else: first, second = half(0, d1, -1), half(L - hub, d2, L - hub) for z in (F, L - F): cross = cq.Workplane("YZ").center(G, z).circle(screw / 2).extrude(R + 1, both=True) first, second = first.cut(cross), second.cut(cross) inner, outer = max(d2 / 2 + 0.3, 0.62 * R), 0.96 * R step = (L - 2 * hub) / (2 * FOLDS) points = [(inner * 0.92, hub), (inner, hub)] for k in range(FOLDS): points += [(outer, hub + (2 * k + 1) * step), (inner, hub + (2 * k + 2) * step)] points.append((inner * 0.92, L - hub)) folds = cq.Workplane("XZ").polyline(points).close().revolve(360, (0, 0, 0), (0, 1, 0)) model.add("hub_1", first, op="new", body="hub_1_body", name="Hub, d1") model.add("hub_2", second, op="new", body="hub_2_body", name="Hub, d2") model.add("bellows", folds, op="new", body="bellows_body", name="Bellows") model.material("aluminum-generic", bodies=["hub_1_body", "hub_2_body"], color="#c9ccd1") model.material("bronze", bodies=["bellows_body"], color="#b08d57") result = model.result()