from build123d import * from ocp_vscode import show # ========================================== # --- MASTER PARAMETERS --- model_size = 31.0 # Outer diameter of the ring overhang = model_size * (3.0 / model_size) # How many mm the bolt sticks out past the ring # ========================================== # --- Derived Parameters --- outer_diameter = model_size inner_diameter = model_size * (25.4 / model_size) thickness = model_size * (2.3 / model_size) pin_diameter = model_size * (3.1 / model_size) pin_length = model_size * (10.8 / model_size) pin_spacing = model_size * (14.0 / model_size) pin_height_offset = model_size * (1.55 / model_size) fillet_radius = model_size * (0.15 / model_size) # --- Lightning Bolt Proportions --- W = (outer_diameter / 2) + overhang bound = model_size H_outer = model_size * (3.1 / model_size) H_inner = model_size * (0.5 / model_size) X_point = model_size * (5.8 / model_size) X_inner = model_size * (2.7 / model_size) with BuildPart() as opel_pin: # 1. Base Ring with BuildSketch() as ring_sketch: Circle(outer_diameter / 2) Circle(inner_diameter / 2, mode=Mode.SUBTRACT) extrude(amount=thickness) # 2. Lightning Bolt Profile (Aggressive Z-Shape) with BuildSketch() as bolt_sketch: pts = [ (-bound, H_outer), # 1. Top-left outer edge (-bound, -H_inner), # 2. Bottom-left outer edge of upper bar (-X_inner, -H_inner), # 3. Inner bottom corner (cuts right, past center) (-X_point, -H_outer), # 4. Sharp bottom-left point (diagonals back left) (bound, -H_outer), # 5. Bottom-right outer edge (bound, H_inner), # 6. Top-right outer edge of lower bar (X_inner, H_inner), # 7. Inner top corner (cuts left, past center) (X_point, H_outer) # 8. Sharp top-right point (diagonals back right) ] z_shape = Polygon(*pts) # Fillet the 2D corners of the Z shape so the inner zig-zag isn't infinitely sharp fillet(z_shape.vertices(), radius=fillet_radius) # Cleanly slice off the overhangs Circle(W, mode=Mode.INTERSECT) extrude(amount=thickness) # ========================================== # ---> THE FIX: Fillet ALL top edges <--- # 1. Grab the highest face on the Z-axis (the newly merged face of both ring + bolt) top_face = opel_pin.faces().sort_by(Axis.Z)[-1] # 2. Grab ALL edges of that top face (no filtering) all_top_edges = top_face.edges() # 3. Apply the 3D fillet to the entire border fillet(all_top_edges, radius=fillet_radius) # ========================================== # 3. Mounting Pins (on the back face) bottom_face = opel_pin.faces().sort_by(Axis.Z)[0] with BuildSketch(bottom_face) as pin_sketch: with Locations((-pin_spacing, -pin_height_offset), (pin_spacing, pin_height_offset)): Circle(pin_diameter / 2) extrude(amount=pin_length) # --- Export for 3D Printing --- # This saves a STEP file in the same folder as your python script export_step(opel_pin.part, "vintage_opel_pin.step") # --- Send to OCP CAD Viewer --- show(opel_pin)