165 lines
5.0 KiB
Python
165 lines
5.0 KiB
Python
from math import cos, radians, sin
|
|
|
|
from build123d import (
|
|
Align,
|
|
Box,
|
|
BuildPart,
|
|
BuildSketch,
|
|
Cylinder,
|
|
Location,
|
|
Locations,
|
|
Mode,
|
|
Plane,
|
|
Polygon,
|
|
add,
|
|
extrude,
|
|
)
|
|
|
|
from benchmark_common import rounded_triangle_points, safe_fillet
|
|
|
|
|
|
BASE_LENGTH = 120.0
|
|
BASE_WIDTH = 60.0
|
|
BASE_THICKNESS = 10.0
|
|
BASE_FILLET = 3.0
|
|
|
|
LUG_X_EXTENT = 36.0
|
|
LUG_RADIUS = 18.0
|
|
LUG_HEIGHT_ABOVE_BASE = 42.0
|
|
LUG_THICKNESS_Y = 18.0
|
|
LUG_GAP_Y = 16.0
|
|
LUG_FILLET = 2.0
|
|
|
|
CLEVIS_HOLE_DIAMETER = 14.0
|
|
CLEVIS_HOLE_CENTER_Z = 34.0
|
|
|
|
BASE_HOLE_DIAMETER = 7.0
|
|
BASE_HOLE_LOCATIONS = ((-45.0, -20.0), (-45.0, 20.0), (45.0, -20.0), (45.0, 20.0))
|
|
|
|
CUTOUT_CORNER_RADIUS = 3.0
|
|
RIB_THICKNESS_X = 6.0
|
|
|
|
|
|
def _lug_profile_points() -> list[tuple[float, float]]:
|
|
half_x = LUG_X_EXTENT / 2.0
|
|
arc_center_z = BASE_THICKNESS + LUG_HEIGHT_ABOVE_BASE - LUG_RADIUS
|
|
points = [(-half_x, BASE_THICKNESS), (half_x, BASE_THICKNESS), (half_x, arc_center_z)]
|
|
|
|
for step in range(1, 12):
|
|
angle = radians(180.0 * step / 12.0)
|
|
points.append((LUG_RADIUS * cos(angle), arc_center_z + LUG_RADIUS * sin(angle)))
|
|
|
|
points.append((-half_x, arc_center_z))
|
|
return points
|
|
|
|
|
|
def _make_lug(y_min: float, label: str):
|
|
with BuildPart() as lug:
|
|
with BuildSketch(Plane.XZ):
|
|
Polygon(_lug_profile_points(), align=None)
|
|
extrude(amount=LUG_THICKNESS_Y)
|
|
|
|
part = lug.part.moved(Location((0.0, y_min, 0.0)))
|
|
part.label = label
|
|
return part
|
|
|
|
|
|
def _make_rib(sign: float):
|
|
outer_y = sign * (LUG_GAP_Y / 2.0 + LUG_THICKNESS_Y)
|
|
foot_y = sign * (BASE_WIDTH / 2.0)
|
|
top_z = BASE_THICKNESS + 28.0
|
|
|
|
with BuildPart() as rib:
|
|
with BuildSketch(Plane.YZ):
|
|
Polygon(
|
|
[
|
|
(outer_y, BASE_THICKNESS),
|
|
(foot_y, BASE_THICKNESS),
|
|
(outer_y, top_z),
|
|
],
|
|
align=None,
|
|
)
|
|
extrude(amount=RIB_THICKNESS_X)
|
|
|
|
part = rib.part.moved(Location((-RIB_THICKNESS_X / 2.0, 0.0, 0.0)))
|
|
part.label = "positive_y_diagonal_rib" if sign > 0.0 else "negative_y_diagonal_rib"
|
|
return part
|
|
|
|
|
|
def _outer_base_edges(part):
|
|
edges = []
|
|
for edge in part.edges():
|
|
bbox = edge.bounding_box()
|
|
center = bbox.center()
|
|
on_outer_x = abs(abs(center.X) - BASE_LENGTH / 2.0) < 0.05
|
|
on_outer_y = abs(abs(center.Y) - BASE_WIDTH / 2.0) < 0.05
|
|
on_top_or_bottom = abs(center.Z - 0.0) < 0.05 or abs(center.Z - BASE_THICKNESS) < 0.05
|
|
if (on_outer_x or on_outer_y) and on_top_or_bottom:
|
|
edges.append(edge)
|
|
return edges
|
|
|
|
|
|
def _lug_base_edges(part):
|
|
edges = []
|
|
for edge in part.edges():
|
|
bbox = edge.bounding_box()
|
|
center = bbox.center()
|
|
if abs(center.Z - BASE_THICKNESS) > 0.05:
|
|
continue
|
|
if abs(abs(center.Y) - LUG_GAP_Y / 2.0) < 0.05 and bbox.size.X > LUG_X_EXTENT - 1.0:
|
|
edges.append(edge)
|
|
return edges
|
|
|
|
|
|
def _subtract_rounded_triangle(vertices: list[tuple[float, float]]):
|
|
with BuildSketch(Plane.XY) as cutout:
|
|
Polygon(
|
|
rounded_triangle_points(vertices, radius=CUTOUT_CORNER_RADIUS, segments=5),
|
|
align=None,
|
|
)
|
|
extrude(cutout.sketch, amount=BASE_THICKNESS + 2.0, mode=Mode.SUBTRACT)
|
|
|
|
|
|
def gen_step():
|
|
"""Return the clevis bracket benchmark model in millimeters."""
|
|
positive_lug_y_min = LUG_GAP_Y / 2.0 + LUG_THICKNESS_Y
|
|
negative_lug_y_min = -LUG_GAP_Y / 2.0
|
|
|
|
with BuildPart() as bracket:
|
|
Box(BASE_LENGTH, BASE_WIDTH, BASE_THICKNESS, align=(Align.CENTER, Align.CENTER, Align.MIN))
|
|
|
|
base = safe_fillet(bracket.part, _outer_base_edges(bracket.part), radius=BASE_FILLET)
|
|
|
|
with BuildPart() as bracket:
|
|
add(base, mode=Mode.ADD)
|
|
add(_make_lug(positive_lug_y_min, "positive_y_clevis_lug"), mode=Mode.ADD)
|
|
add(_make_lug(negative_lug_y_min, "negative_y_clevis_lug"), mode=Mode.ADD)
|
|
add(_make_rib(1.0), mode=Mode.ADD)
|
|
add(_make_rib(-1.0), mode=Mode.ADD)
|
|
|
|
with Locations(Location((0.0, 0.0, CLEVIS_HOLE_CENTER_Z))):
|
|
Cylinder(
|
|
radius=CLEVIS_HOLE_DIAMETER / 2.0,
|
|
height=BASE_WIDTH + 8.0,
|
|
rotation=(90.0, 0.0, 0.0),
|
|
align=(Align.CENTER, Align.CENTER, Align.CENTER),
|
|
mode=Mode.SUBTRACT,
|
|
)
|
|
|
|
for x_pos, y_pos in BASE_HOLE_LOCATIONS:
|
|
with Locations(Location((x_pos, y_pos, -1.0))):
|
|
Cylinder(
|
|
radius=BASE_HOLE_DIAMETER / 2.0,
|
|
height=BASE_THICKNESS + 2.0,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.SUBTRACT,
|
|
)
|
|
|
|
_subtract_rounded_triangle([(-54.0, -13.0), (-25.0, 0.0), (-54.0, 13.0)])
|
|
_subtract_rounded_triangle([(54.0, -13.0), (25.0, 0.0), (54.0, 13.0)])
|
|
|
|
part = bracket.part
|
|
part = safe_fillet(part, _lug_base_edges(part), radius=LUG_FILLET)
|
|
part.label = "benchmark_06_aerospace_clevis_bracket_lightening_cutouts"
|
|
return part
|