Files
cadSet/text-to-cad/models/cad-router-v1/connecting_rod.py
T
2026-07-27 16:01:32 +08:00

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