"""Keystone colour-keyed through-hole test point: a wire-form loop on a nylon base, miniature (5000 to 5004, 5115 to 5119), compact (5005 to 5009, 5120 to 5124) or multipurpose (5010 to 5014, 5125 to 5129). The base stands on the board (the XY plane) centred on the origin; the loop is in the XZ plane above it, and the terminal's legs run down through the board. The terminal is one solid, the base another. Dimensions from Keystone's catalogue page; see the README.""" from steve import Model style = "compact" # miniature, compact or multipurpose colour = "red" # red, black, white, orange, yellow, brown, green, blue, grey or purple # style: (base diameter, loop inside diameter, base height, height above the board, overall length, terminal thickness, terminal width, # board hole), mm. Keystone Electronics catalogue, "(THM) THRU HOLE MOUNT TEST POINTS - COLOR KEYED", page 62 (copy hosted by # static.chipdip.ru): the dimensions in inches [mm] and the SPECIFICATIONS' "Terminal: thickness x width Phosphor Bronze, Silver Plate", # "Base: Nylon 46" and "Mtg. Hole". STYLES = { "miniature": (2.5, 1.25, 3.0, 4.6, 7.6, 0.25, 0.51, 1.0), "compact": (3.2, 1.80, 3.0, 5.6, 8.9, 0.38, 0.81, 1.6), "multipurpose": (3.2, 1.80, 3.0, 8.1, 11.3, 0.38, 0.81, 1.6), } # The same page's catalogue numbers, by base colour, and the colours for looks. NUMBERS = { "miniature": {"red": 5000, "black": 5001, "white": 5002, "orange": 5003, "yellow": 5004, "brown": 5115, "green": 5116, "blue": 5117, "grey": 5118, "purple": 5119}, "compact": {"red": 5005, "black": 5006, "white": 5007, "orange": 5008, "yellow": 5009, "brown": 5120, "green": 5121, "blue": 5122, "grey": 5123, "purple": 5124}, "multipurpose": {"red": 5010, "black": 5011, "white": 5012, "orange": 5013, "yellow": 5014, "brown": 5125, "green": 5126, "blue": 5127, "grey": 5128, "purple": 5129}, } COLOURS = {"red": "#c8302c", "black": "#1d1d1f", "white": "#f2f2ee", "orange": "#e8792b", "yellow": "#f2d22e", "brown": "#7a4a26", "green": "#3f8f3f", "blue": "#2f5fb3", "grey": "#8a8a8a", "purple": "#7d4fa8"} # Proportion, for looks (the page draws it but doesn't dimension it): below the loop the terminal's two ends run down side by side as one # post, two thicknesses wide, through the base to the overall length's end below the board (the drawn snap-fit splay isn't modelled). if style not in STYLES: raise ValueError(f"no style {style!r}: {', '.join(STYLES)}") if colour not in COLOURS: raise ValueError(f"no colour {colour!r}: {', '.join(COLOURS)}") base_d, loop_id, base_h, above, overall, t, w, hole = STYLES[style] loop_r = loop_id / 2 + t loop_z = above - loop_r below = overall - above model = Model() # The loop: a ring of the terminal's section, in the XZ plane (normal -Y: offset -w / 2 and the extrusion runs across to -Y). model.plane("loop_plane", on="XZ", offset=-w / 2, name="Terminal") with model.sketch("loop_outer", on="loop_plane", name="Terminal") as sk: sk.circle("outer", (0, loop_z), loop_r) model.extrude("loop", "loop_outer", distance=w, op="new", body="terminal_body", name="Terminal") with model.sketch("loop_inner", on="loop_plane", name="Terminal") as sk: sk.circle("inner", (0, loop_z), loop_id / 2) model.extrude("loop_eye", "loop_inner", distance=w, op="cut", body="terminal_body", name="Terminal") post_top = loop_z - loop_id / 2 model.box("post", 2 * t, w, post_top + below, at=(0, 0, (post_top - below) / 2), op="join", body="terminal_body", name="Terminal") model.cylinder("base", base_d / 2, base_h, op="new", body="base_body", name="Base") # The terminal passes through the base: cut its room out of the base, so that no solids overlap. model.combine("base_room", "base_body", ["terminal_body"], op="cut", keep_tools=True, name="Room for the terminal") # Materials (the page: "Phosphor Bronze, Silver Plate"; "Base: Nylon 46"): the terminal phosphor bronze C51000, the base nylon, pa6 the # nearest in the material list (PA46's density about 1.18, PA6's 1.14). model.material("copper-c51000", bodies=["terminal_body"], color="#d8d8dc") model.material("pa6", bodies=["base_body"], color=COLOURS[colour]) result = model.result()