114 lines
3.3 KiB
Python
114 lines
3.3 KiB
Python
from build123d import (
|
|
Align,
|
|
Box,
|
|
BuildPart,
|
|
BuildSketch,
|
|
Cylinder,
|
|
Location,
|
|
Locations,
|
|
Mode,
|
|
Plane,
|
|
Polygon,
|
|
add,
|
|
extrude,
|
|
)
|
|
|
|
from benchmark_common import safe_fillet
|
|
|
|
|
|
BASE_LENGTH = 80.0
|
|
BASE_WIDTH = 50.0
|
|
BASE_THICKNESS = 8.0
|
|
|
|
BACK_LENGTH = 80.0
|
|
BACK_THICKNESS = 8.0
|
|
BACK_HEIGHT = 50.0
|
|
BACK_CENTER_Y = BASE_WIDTH / 2.0 - BACK_THICKNESS / 2.0
|
|
|
|
HOLE_DIAMETER = 6.0
|
|
BASE_HOLE_LOCATIONS = ((-25.0, -10.0), (25.0, -10.0))
|
|
BACK_HOLE_LOCATIONS = ((-25.0, 30.0), (25.0, 30.0))
|
|
|
|
GUSSET_X_THICKNESS = 8.0
|
|
GUSSET_X_LOCATIONS = (-20.0, 20.0)
|
|
GUSSET_DEPTH = 30.0
|
|
GUSSET_HEIGHT = 30.0
|
|
TRANSITION_FILLET = 2.0
|
|
|
|
|
|
def _make_gusset(x_center: float):
|
|
back_front_y = BACK_CENTER_Y - BACK_THICKNESS / 2.0
|
|
front_y = back_front_y - GUSSET_DEPTH
|
|
top_z = BASE_THICKNESS + GUSSET_HEIGHT
|
|
|
|
with BuildPart() as gusset:
|
|
with BuildSketch(Plane.YZ):
|
|
Polygon(
|
|
[
|
|
(back_front_y, BASE_THICKNESS),
|
|
(front_y, BASE_THICKNESS),
|
|
(back_front_y, top_z),
|
|
],
|
|
align=None,
|
|
)
|
|
extrude(amount=GUSSET_X_THICKNESS)
|
|
|
|
part = gusset.part.moved(Location((x_center - GUSSET_X_THICKNESS / 2.0, 0.0, 0.0)))
|
|
part.label = f"gusset_x_{x_center:.0f}"
|
|
return part
|
|
|
|
|
|
def _transition_edges(part):
|
|
edges = []
|
|
for edge in part.edges():
|
|
bbox = edge.bounding_box()
|
|
if str(edge.geom_type).endswith("LINE"):
|
|
if abs(bbox.min.Z - BASE_THICKNESS) < 0.05 and abs(bbox.max.Z - BASE_THICKNESS) < 0.05:
|
|
center_y = bbox.center().Y
|
|
if BACK_CENTER_Y - BACK_THICKNESS / 2.0 - 0.05 <= center_y <= BASE_WIDTH / 2.0 + 0.05:
|
|
if bbox.size.X > 20.0:
|
|
edges.append(edge)
|
|
return edges
|
|
|
|
|
|
def gen_step():
|
|
"""Return the L-bracket benchmark model in millimeters."""
|
|
with BuildPart() as bracket:
|
|
Box(BASE_LENGTH, BASE_WIDTH, BASE_THICKNESS, align=(Align.CENTER, Align.CENTER, Align.MIN))
|
|
|
|
with Locations(Location((0.0, BACK_CENTER_Y, BASE_THICKNESS))):
|
|
Box(
|
|
BACK_LENGTH,
|
|
BACK_THICKNESS,
|
|
BACK_HEIGHT,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.ADD,
|
|
)
|
|
|
|
for x_pos, y_pos in BASE_HOLE_LOCATIONS:
|
|
with Locations(Location((x_pos, y_pos, -1.0))):
|
|
Cylinder(
|
|
radius=HOLE_DIAMETER / 2.0,
|
|
height=BASE_THICKNESS + 2.0,
|
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
|
mode=Mode.SUBTRACT,
|
|
)
|
|
|
|
for x_pos, z_pos in BACK_HOLE_LOCATIONS:
|
|
with Locations(Location((x_pos, BACK_CENTER_Y, z_pos))):
|
|
Cylinder(
|
|
radius=HOLE_DIAMETER / 2.0,
|
|
height=BACK_THICKNESS + 2.0,
|
|
rotation=(90.0, 0.0, 0.0),
|
|
align=(Align.CENTER, Align.CENTER, Align.CENTER),
|
|
mode=Mode.SUBTRACT,
|
|
)
|
|
|
|
for x_center in GUSSET_X_LOCATIONS:
|
|
add(_make_gusset(x_center), mode=Mode.ADD)
|
|
|
|
part = bracket.part
|
|
part = safe_fillet(part, _transition_edges(part), radius=TRANSITION_FILLET)
|
|
part.label = "benchmark_03_l_bracket_gussets_two_hole_directions"
|
|
return part
|