Import CAD projects and cad-router v1
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
from math import cos, radians, sin
|
||||
|
||||
from build123d import (
|
||||
Align,
|
||||
BuildLine,
|
||||
BuildPart,
|
||||
BuildSketch,
|
||||
CenterArc,
|
||||
Circle,
|
||||
Color,
|
||||
Compound,
|
||||
Cylinder,
|
||||
Edge,
|
||||
Line,
|
||||
Location,
|
||||
Plane,
|
||||
extrude,
|
||||
make_face,
|
||||
sweep,
|
||||
)
|
||||
|
||||
|
||||
# Units: millimeters.
|
||||
# Origin: centered on the staircase axis; base/column bottom starts at Z=0.
|
||||
# XY: plan view. +Z: staircase rise direction.
|
||||
|
||||
BASE_DIAMETER = 90.0
|
||||
BASE_THICKNESS = 5.0
|
||||
|
||||
COLUMN_DIAMETER = 14.0
|
||||
COLUMN_HEIGHT = 140.0
|
||||
|
||||
TREAD_COUNT = 20
|
||||
TREAD_THICKNESS = 4.0
|
||||
TREAD_INNER_RADIUS = 10.0
|
||||
TREAD_OUTER_RADIUS = 62.0
|
||||
TREAD_SWEEP_DEGREES = 24.0
|
||||
TREAD_FIRST_BOTTOM_Z = 4.0
|
||||
TREAD_RISE = 6.0
|
||||
TREAD_ROTATION_DEGREES = 18.0
|
||||
|
||||
HANDRAIL_RADIUS = 66.0
|
||||
HANDRAIL_TUBE_DIAMETER = 5.0
|
||||
HANDRAIL_START_Z = 14.0
|
||||
HANDRAIL_END_Z = 130.0
|
||||
|
||||
BALUSTER_DIAMETER = 3.0
|
||||
|
||||
def _polar_point(radius: float, angle_degrees: float) -> tuple[float, float]:
|
||||
angle_radians = radians(angle_degrees)
|
||||
return (radius * cos(angle_radians), radius * sin(angle_radians))
|
||||
|
||||
|
||||
def _make_base():
|
||||
with BuildPart() as base:
|
||||
Cylinder(
|
||||
radius=BASE_DIAMETER / 2.0,
|
||||
height=BASE_THICKNESS,
|
||||
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
||||
)
|
||||
|
||||
part = base.part
|
||||
part.label = "circular_base_disk_diameter_90mm_thickness_5mm"
|
||||
part.color = Color(0.42, 0.43, 0.45, 1.0)
|
||||
return part
|
||||
|
||||
|
||||
def _make_column():
|
||||
with BuildPart() as column:
|
||||
Cylinder(
|
||||
radius=COLUMN_DIAMETER / 2.0,
|
||||
height=COLUMN_HEIGHT,
|
||||
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
||||
)
|
||||
|
||||
part = column.part
|
||||
part.label = "central_column_diameter_14mm_height_140mm"
|
||||
part.color = Color(0.70, 0.72, 0.74, 1.0)
|
||||
return part
|
||||
|
||||
|
||||
def _make_tread_profile():
|
||||
half_sweep = TREAD_SWEEP_DEGREES / 2.0
|
||||
start_angle = -half_sweep
|
||||
end_angle = half_sweep
|
||||
|
||||
with BuildPart() as tread:
|
||||
with BuildSketch(Plane.XY):
|
||||
with BuildLine():
|
||||
CenterArc((0.0, 0.0), TREAD_OUTER_RADIUS, start_angle, TREAD_SWEEP_DEGREES)
|
||||
Line(
|
||||
_polar_point(TREAD_OUTER_RADIUS, end_angle),
|
||||
_polar_point(TREAD_INNER_RADIUS, end_angle),
|
||||
)
|
||||
CenterArc((0.0, 0.0), TREAD_INNER_RADIUS, end_angle, -TREAD_SWEEP_DEGREES)
|
||||
Line(
|
||||
_polar_point(TREAD_INNER_RADIUS, start_angle),
|
||||
_polar_point(TREAD_OUTER_RADIUS, start_angle),
|
||||
)
|
||||
make_face()
|
||||
extrude(amount=TREAD_THICKNESS)
|
||||
|
||||
part = tread.part
|
||||
part.label = "tread_profile_inner_10mm_outer_62mm_sweep_24deg"
|
||||
part.color = Color(0.78, 0.58, 0.35, 1.0)
|
||||
return part
|
||||
|
||||
|
||||
def _make_tread(index: int):
|
||||
angle_degrees = index * TREAD_ROTATION_DEGREES
|
||||
bottom_z = TREAD_FIRST_BOTTOM_Z + index * TREAD_RISE
|
||||
tread_profile = _make_tread_profile()
|
||||
tread = tread_profile.moved(Location((0.0, 0.0, bottom_z), (0.0, 0.0, angle_degrees)))
|
||||
tread.label = f"tread_{index + 1:02d}_bottom_z_{bottom_z:.0f}mm_angle_{angle_degrees:.0f}deg"
|
||||
return tread
|
||||
|
||||
|
||||
def _handrail_center_z(angle_degrees: float) -> float:
|
||||
rail_rise = HANDRAIL_END_Z - HANDRAIL_START_Z
|
||||
return HANDRAIL_START_Z + rail_rise * angle_degrees / 360.0
|
||||
|
||||
|
||||
def _make_handrail():
|
||||
rail_height = HANDRAIL_END_Z - HANDRAIL_START_Z
|
||||
path = Edge.make_helix(
|
||||
pitch=rail_height,
|
||||
height=rail_height,
|
||||
radius=HANDRAIL_RADIUS,
|
||||
center=(0.0, 0.0, HANDRAIL_START_Z),
|
||||
)
|
||||
start_tangent = path.tangent_at(0.0)
|
||||
profile_plane = Plane(
|
||||
origin=(HANDRAIL_RADIUS, 0.0, HANDRAIL_START_Z),
|
||||
x_dir=(1.0, 0.0, 0.0),
|
||||
z_dir=start_tangent,
|
||||
)
|
||||
|
||||
with BuildPart() as rail:
|
||||
with BuildSketch(profile_plane):
|
||||
Circle(HANDRAIL_TUBE_DIAMETER / 2.0)
|
||||
sweep(path=path, is_frenet=True)
|
||||
|
||||
part = rail.part
|
||||
part.label = "helical_outer_handrail_radius_66mm_diameter_5mm"
|
||||
part.color = Color(0.22, 0.28, 0.34, 1.0)
|
||||
return part
|
||||
|
||||
|
||||
def _make_baluster(index: int):
|
||||
angle_degrees = index * TREAD_ROTATION_DEGREES
|
||||
tread_top_z = TREAD_FIRST_BOTTOM_Z + index * TREAD_RISE + TREAD_THICKNESS
|
||||
rail_center_z = _handrail_center_z(angle_degrees)
|
||||
x_pos, y_pos = _polar_point(TREAD_OUTER_RADIUS, angle_degrees)
|
||||
height = rail_center_z - tread_top_z
|
||||
|
||||
with BuildPart() as baluster:
|
||||
Cylinder(
|
||||
radius=BALUSTER_DIAMETER / 2.0,
|
||||
height=height,
|
||||
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
||||
)
|
||||
|
||||
part = baluster.part.moved(Location((x_pos, y_pos, tread_top_z)))
|
||||
part.label = f"baluster_{index + 1:02d}_diameter_3mm"
|
||||
part.color = Color(0.30, 0.33, 0.36, 1.0)
|
||||
return part
|
||||
|
||||
|
||||
def gen_step():
|
||||
"""Return a labeled miniature spiral staircase STEP compound in millimeters."""
|
||||
parts = [
|
||||
_make_base(),
|
||||
_make_column(),
|
||||
]
|
||||
|
||||
for index in range(TREAD_COUNT):
|
||||
parts.append(_make_tread(index))
|
||||
|
||||
parts.append(_make_handrail())
|
||||
|
||||
for index in range(TREAD_COUNT):
|
||||
parts.append(_make_baluster(index))
|
||||
|
||||
assembly = Compound(
|
||||
obj=parts,
|
||||
children=parts,
|
||||
label="miniature_spiral_staircase",
|
||||
)
|
||||
return assembly
|
||||
Reference in New Issue
Block a user