123 lines
4.0 KiB
Python
123 lines
4.0 KiB
Python
from math import cos, radians, sin, tau
|
|
|
|
from build123d import Align, BuildPart, Cylinder, Location, Locations, Mode
|
|
|
|
from benchmark_common import circular_edges, polar_point, safe_fillet
|
|
|
|
|
|
BARREL_DIAMETER = 36.0
|
|
BARREL_HEIGHT = 70.0
|
|
|
|
FIN_COUNT = 12
|
|
FIN_DIAMETER = 62.0
|
|
FIN_THICKNESS = 2.0
|
|
FIN_Z_VALUES = tuple(10.0 + 5.0 * index for index in range(FIN_COUNT))
|
|
|
|
BASE_FLANGE_DIAMETER = 70.0
|
|
BASE_FLANGE_THICKNESS = 8.0
|
|
MOUNT_HOLE_COUNT = 6
|
|
MOUNT_HOLE_DIAMETER = 5.0
|
|
MOUNT_BOLT_CIRCLE_DIAMETER = 56.0
|
|
|
|
TOP_CAP_DIAMETER = 44.0
|
|
TOP_CAP_BOTTOM_Z = 70.0
|
|
TOP_CAP_HEIGHT = 8.0
|
|
|
|
BOSS_DIAMETER = 12.0
|
|
BOSS_LENGTH = 24.0
|
|
BOSS_ANGLE_DEGREES = 35.0
|
|
BOSS_BORE_DIAMETER = 5.0
|
|
|
|
EDGE_FILLET = 0.95
|
|
|
|
|
|
def _boss_center() -> tuple[float, float, float]:
|
|
angle = radians(BOSS_ANGLE_DEGREES)
|
|
start = (TOP_CAP_DIAMETER / 2.0 - 1.0, 0.0, TOP_CAP_BOTTOM_Z + TOP_CAP_HEIGHT / 2.0)
|
|
direction = (cos(angle), 0.0, sin(angle))
|
|
return (
|
|
start[0] + direction[0] * BOSS_LENGTH / 2.0,
|
|
0.0,
|
|
start[2] + direction[2] * BOSS_LENGTH / 2.0,
|
|
)
|
|
|
|
|
|
def _edge_fillets(part):
|
|
edges = []
|
|
for z_pos in FIN_Z_VALUES:
|
|
edges.extend(circular_edges(part, radius=FIN_DIAMETER / 2.0, axis="z", coordinate=z_pos))
|
|
edges.extend(circular_edges(part, radius=FIN_DIAMETER / 2.0, axis="z", coordinate=z_pos + FIN_THICKNESS))
|
|
edges.extend(circular_edges(part, radius=BASE_FLANGE_DIAMETER / 2.0, axis="z", coordinate=0.0))
|
|
edges.extend(circular_edges(part, radius=BASE_FLANGE_DIAMETER / 2.0, axis="z", coordinate=BASE_FLANGE_THICKNESS))
|
|
return edges
|
|
|
|
|
|
def gen_step():
|
|
"""Return the radial-engine-style cylinder benchmark model in millimeters."""
|
|
boss_rotation_y = 90.0 - BOSS_ANGLE_DEGREES
|
|
boss_center = _boss_center()
|
|
|
|
with BuildPart() as cylinder:
|
|
Cylinder(
|
|
radius=BARREL_DIAMETER / 2.0,
|
|
height=BARREL_HEIGHT,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
)
|
|
|
|
Cylinder(
|
|
radius=BASE_FLANGE_DIAMETER / 2.0,
|
|
height=BASE_FLANGE_THICKNESS,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.ADD,
|
|
)
|
|
|
|
for z_pos in FIN_Z_VALUES:
|
|
with Locations(Location((0.0, 0.0, z_pos))):
|
|
Cylinder(
|
|
radius=FIN_DIAMETER / 2.0,
|
|
height=FIN_THICKNESS,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.ADD,
|
|
)
|
|
|
|
with Locations(Location((0.0, 0.0, TOP_CAP_BOTTOM_Z))):
|
|
Cylinder(
|
|
radius=TOP_CAP_DIAMETER / 2.0,
|
|
height=TOP_CAP_HEIGHT,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.ADD,
|
|
)
|
|
|
|
with Locations(Location(boss_center)):
|
|
Cylinder(
|
|
radius=BOSS_DIAMETER / 2.0,
|
|
height=BOSS_LENGTH,
|
|
rotation=(0.0, boss_rotation_y, 0.0),
|
|
align=(Align.CENTER, Align.CENTER, Align.CENTER),
|
|
mode=Mode.ADD,
|
|
)
|
|
|
|
for index in range(MOUNT_HOLE_COUNT):
|
|
x_pos, y_pos = polar_point(MOUNT_BOLT_CIRCLE_DIAMETER / 2.0, tau * index / MOUNT_HOLE_COUNT)
|
|
with Locations(Location((x_pos, y_pos, -1.0))):
|
|
Cylinder(
|
|
radius=MOUNT_HOLE_DIAMETER / 2.0,
|
|
height=BASE_FLANGE_THICKNESS + 2.0,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.SUBTRACT,
|
|
)
|
|
|
|
with Locations(Location(boss_center)):
|
|
Cylinder(
|
|
radius=BOSS_BORE_DIAMETER / 2.0,
|
|
height=BOSS_LENGTH + 6.0,
|
|
rotation=(0.0, boss_rotation_y, 0.0),
|
|
align=(Align.CENTER, Align.CENTER, Align.CENTER),
|
|
mode=Mode.SUBTRACT,
|
|
)
|
|
|
|
part = cylinder.part
|
|
part = safe_fillet(part, _edge_fillets(part), radius=EDGE_FILLET)
|
|
part.label = "benchmark_07_radial_engine_cylinder_cooling_fins"
|
|
return part
|