"""Captive panel screw envelope, M3 to M5, any length, as step.parts' published models draw it: a shank (drawn at the thread's nominal diameter) and a round knob, two bodies. The shank (diameter d, length `length`) runs along +Z from z = 0; the knob (diameter 2d, height d) is centred on the shank's top end, so it overlaps the shank by d / 2 (two bodies, as in the models: the knob is a separate part of a captive screw). No thread, retainer, spring or knurl. """ from steve import Model thread = "M3" # Thread length = 20 # mm Shank length material = "unspecified" # Material # mm, measured on step.parts' models captive_panel_screw_m_l (the cylinders of their two solids): shank # diameter = the thread's nominal d; knob diameter 2d and height d, centred on the shank's top end (every model) THREADS = {"M3": 3.0, "M4": 4.0, "M5": 5.0} KNOB_DIAMETER = 2.0 # x d KNOB_HEIGHT = 1.0 # x d MATERIALS = {"unspecified": (None, None), "steel": ("steel-generic", "#9da2a8"), "stainless-304": ("stainless-304", "#c9ccd0")} d = THREADS[thread] material_id, colour = MATERIALS[material] model = Model() model.cylinder("shank", d / 2, length, name="Shank") model.cylinder("knob", KNOB_DIAMETER * d / 2, KNOB_HEIGHT * d, at=(0, 0, length - KNOB_HEIGHT * d / 2), op="new", name="Knob") if material_id: model.material(material_id, color=colour) result = model.result()