169 lines
5.1 KiB
Python
169 lines
5.1 KiB
Python
"""Parametric V1 connecting-rod sample routed to the build123d backend."""
|
|
|
|
from math import atan2, degrees, hypot
|
|
|
|
from build123d import (
|
|
Align,
|
|
Box,
|
|
BuildPart,
|
|
BuildSketch,
|
|
Cylinder,
|
|
Location,
|
|
Locations,
|
|
Mode,
|
|
Plane,
|
|
SlotOverall,
|
|
extrude,
|
|
fillet,
|
|
)
|
|
|
|
|
|
CENTER_DISTANCE = 120.0
|
|
THICKNESS = 14.0
|
|
|
|
BIG_END_OUTER_DIAMETER = 56.0
|
|
BIG_END_BORE_DIAMETER = 36.0
|
|
SMALL_END_OUTER_DIAMETER = 36.0
|
|
SMALL_END_BORE_DIAMETER = 20.0
|
|
|
|
WEB_WIDTH = 24.0
|
|
POCKET_LENGTH = 72.0
|
|
POCKET_WIDTH = 12.0
|
|
POCKET_DEPTH = 3.0
|
|
|
|
VIEWER_SLOT_START = (-28.73179347578467, -0.3844822039559189)
|
|
VIEWER_SLOT_END = (24.36043904920138, -0.24367243243227724)
|
|
VIEWER_SLOT_SURFACE_Z = THICKNESS - POCKET_DEPTH
|
|
VIEWER_SLOT_WIDTH = 2.0
|
|
VIEWER_SLOT_BLIND_DEPTH = 2.0
|
|
VIEWER_EDGE_E14_FILLET_RADIUS = 1.0
|
|
VIEWER_HOLE_CENTER = (-22.122781376227962, -9.435525387895417)
|
|
VIEWER_HOLE_DIAMETER = 6.0
|
|
VIEWER_HOLE_BLIND_DEPTH = 6.0
|
|
VIEWER_HOLE_SURFACE_Z = THICKNESS
|
|
VIEWER_HOLE_BOOLEAN_OVERTRAVEL = 0.2
|
|
|
|
VIEWER_SLOT_CENTER = (
|
|
(VIEWER_SLOT_START[0] + VIEWER_SLOT_END[0]) / 2.0,
|
|
(VIEWER_SLOT_START[1] + VIEWER_SLOT_END[1]) / 2.0,
|
|
)
|
|
VIEWER_SLOT_LENGTH = hypot(
|
|
VIEWER_SLOT_END[0] - VIEWER_SLOT_START[0],
|
|
VIEWER_SLOT_END[1] - VIEWER_SLOT_START[1],
|
|
)
|
|
VIEWER_SLOT_ROTATION = degrees(
|
|
atan2(
|
|
VIEWER_SLOT_END[1] - VIEWER_SLOT_START[1],
|
|
VIEWER_SLOT_END[0] - VIEWER_SLOT_START[0],
|
|
)
|
|
)
|
|
|
|
|
|
def _viewer_edge_e14(part):
|
|
"""Select the big-end top outer edge selected in CAD Viewer as e14."""
|
|
selected_edges = []
|
|
for edge in part.edges():
|
|
try:
|
|
edge_radius = edge.radius
|
|
edge_center = edge.arc_center
|
|
edge_normal = edge.normal()
|
|
except Exception:
|
|
continue
|
|
|
|
if abs(edge_radius - BIG_END_OUTER_DIAMETER / 2.0) > 0.05:
|
|
continue
|
|
if abs(edge_center.X + CENTER_DISTANCE / 2.0) > 0.05:
|
|
continue
|
|
if abs(edge_center.Y) > 0.05:
|
|
continue
|
|
if abs(edge_center.Z - THICKNESS) > 0.05:
|
|
continue
|
|
if abs(edge_normal.Z) < 1.0 - 1e-4:
|
|
continue
|
|
selected_edges.append(edge)
|
|
|
|
if len(selected_edges) != 1:
|
|
raise RuntimeError(f"Expected one viewer-selected e14 edge, found {len(selected_edges)}")
|
|
return selected_edges
|
|
|
|
|
|
def gen_step():
|
|
"""Return a closed, STEP-ready connecting-rod solid in millimeters."""
|
|
half_distance = CENTER_DISTANCE / 2.0
|
|
|
|
with BuildPart() as rod:
|
|
with Locations(Location((-half_distance, 0.0, 0.0))):
|
|
Cylinder(
|
|
radius=BIG_END_OUTER_DIAMETER / 2.0,
|
|
height=THICKNESS,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
)
|
|
|
|
with Locations(Location((half_distance, 0.0, 0.0))):
|
|
Cylinder(
|
|
radius=SMALL_END_OUTER_DIAMETER / 2.0,
|
|
height=THICKNESS,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
)
|
|
|
|
Box(
|
|
CENTER_DISTANCE,
|
|
WEB_WIDTH,
|
|
THICKNESS,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
)
|
|
|
|
with Locations(Location((-half_distance, 0.0, -1.0))):
|
|
Cylinder(
|
|
radius=BIG_END_BORE_DIAMETER / 2.0,
|
|
height=THICKNESS + 2.0,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.SUBTRACT,
|
|
)
|
|
|
|
with Locations(Location((half_distance, 0.0, -1.0))):
|
|
Cylinder(
|
|
radius=SMALL_END_BORE_DIAMETER / 2.0,
|
|
height=THICKNESS + 2.0,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.SUBTRACT,
|
|
)
|
|
|
|
with BuildSketch(Plane.XY):
|
|
SlotOverall(width=POCKET_LENGTH, height=POCKET_WIDTH)
|
|
extrude(amount=POCKET_DEPTH, mode=Mode.SUBTRACT)
|
|
|
|
with BuildSketch(Plane.XY.offset(THICKNESS - POCKET_DEPTH)):
|
|
SlotOverall(width=POCKET_LENGTH, height=POCKET_WIDTH)
|
|
extrude(amount=POCKET_DEPTH, mode=Mode.SUBTRACT)
|
|
|
|
with BuildSketch(Plane.XY.offset(VIEWER_SLOT_SURFACE_Z - VIEWER_SLOT_BLIND_DEPTH)):
|
|
with Locations(Location((VIEWER_SLOT_CENTER[0], VIEWER_SLOT_CENTER[1], 0.0))):
|
|
SlotOverall(
|
|
width=VIEWER_SLOT_LENGTH,
|
|
height=VIEWER_SLOT_WIDTH,
|
|
rotation=VIEWER_SLOT_ROTATION,
|
|
)
|
|
extrude(amount=VIEWER_SLOT_BLIND_DEPTH, mode=Mode.SUBTRACT)
|
|
|
|
with Locations(
|
|
Location(
|
|
(
|
|
VIEWER_HOLE_CENTER[0],
|
|
VIEWER_HOLE_CENTER[1],
|
|
VIEWER_HOLE_SURFACE_Z - VIEWER_HOLE_BLIND_DEPTH,
|
|
)
|
|
)
|
|
):
|
|
Cylinder(
|
|
radius=VIEWER_HOLE_DIAMETER / 2.0,
|
|
height=VIEWER_HOLE_BLIND_DEPTH + VIEWER_HOLE_BOOLEAN_OVERTRAVEL,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.SUBTRACT,
|
|
)
|
|
|
|
result = rod.part
|
|
result = fillet(_viewer_edge_e14(result), radius=VIEWER_EDGE_E14_FILLET_RADIUS)
|
|
result.label = "cad_router_v1_connecting_rod"
|
|
return result
|