Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from dataclasses import dataclass
- from build123d import *
- @dataclass(frozen = True)
- class PhoneHolderParams():
- phone_length: float # Or rather "how much length of the phone to hold"
- phone_width: float
- phone_thickness: float
- glass_thickness: float
- holder_lip: float = 3 *MM
- clip_length: float = 50 *MM
- clip_thickness: float = 4 *MM
- wall_thickness: float = 3 *MM
- phone_gap: float = 0.5 *MM # Space around phone
- glass_gap: float = 0.3 *MM # Space around glass
- bottom_fillet_radius = 12 *MM
- overall_chamfer: float = 1 *MM
- hole_chamfer: float = 0.6 *MM
- def build_phone_holder(params: PhoneHolderParams):
- # Convenience variables to help keep track of the different distances
- outer_width = params.wall_thickness + params.phone_width + params.phone_gap + params.wall_thickness
- outer_holder_x = params.wall_thickness + params.phone_thickness + params.phone_gap + params.wall_thickness
- outer_holder_y = params.phone_length + params.wall_thickness
- outer_clip_x = outer_holder_x + params.glass_thickness + params.glass_gap + params.clip_thickness
- cutout_thickness = params.phone_thickness + params.phone_gap
- with BuildPart() as holder_part:
- # Main holder piece with clip
- with BuildSketch():
- with BuildLine():
- Polyline([
- (0, 0),
- (outer_clip_x, 0), # Across to clip
- (outer_clip_x - params.glass_gap * 2, params.clip_length), # Up to top of clip. Slight tilt so the clip flexes slightly and grips the glass
- (outer_clip_x - params.glass_gap * 2 - params.clip_thickness, params.clip_length), # Across top of clip
- (outer_clip_x - params.clip_thickness, params.clip_thickness), # Down to glass gap
- (outer_holder_x, params.clip_thickness), # Across glass gap
- (outer_holder_x, outer_holder_y), # Up to top of holder
- (0, outer_holder_y), # Across top of holder
- ], close = True)
- make_face()
- extrude(amount = outer_width)
- # Round the bottom to match the look of a curved phone
- fillet(holder_part.edges().filter_by(Plane.XZ).filter_by(Plane.XY).sort_by(Axis.Y)[-2:], radius = params.bottom_fillet_radius)
- # Cutout where the phone slides in
- offset_top = Plane(holder_part.faces().sort_by(Axis.X)[0]).offset(-params.wall_thickness)
- with BuildSketch(offset_top):
- RectangleRounded(params.phone_length, params.phone_width + params.phone_gap, params.bottom_fillet_radius - params.wall_thickness)
- extrude(amount=-cutout_thickness, mode=Mode.SUBTRACT)
- # Cut out the front so you can see the phone screen
- offset_side = Plane(holder_part.faces().sort_by(Axis.X)[0])
- offset_side = offset_side.shift_origin(offset_side.origin + (0, -params.holder_lip, 0))
- with BuildSketch(offset_side):
- RectangleRounded(params.phone_length - params.holder_lip, params.phone_width - (params.holder_lip * 2), params.bottom_fillet_radius - params.holder_lip)
- extrude(amount = -params.wall_thickness, mode = Mode.SUBTRACT)
- # Cut out the sides so that you can access buttons and more easily slide the phone out
- offset_side = Plane(holder_part.faces().sort_by(Axis.Z)[0]).shift_origin((0, 0, 0))
- with BuildSketch(offset_side):
- Rectangle((cutout_thickness + params.wall_thickness) * 2, 5)
- with Locations((0, -params.phone_length * 0.4)):
- Circle(cutout_thickness + params.wall_thickness)
- make_hull()
- extrude(amount = -outer_width, mode = Mode.SUBTRACT)
- # Make it easy to handle in the hand. Arguably should exclude the edges inside of the cutouts, but that's a pain
- chamfer(holder_part.edges().filter_by(GeomType.LINE), length = params.overall_chamfer)
- # Drainage/speaker hole in the bottom
- with BuildSketch(holder_part.faces().sort_by(Axis.Y)[-1]):
- with Locations((0, params.phone_width / 2 - params.phone_thickness * 0.8), (0, -(params.phone_width / 2 - params.phone_thickness * 0.8))):
- RegularPolygon(radius = params.phone_thickness * 0.4, side_count = 6, rotation = 30)
- make_hull()
- extrude(amount = -params.wall_thickness * 2, mode = Mode.SUBTRACT)
- chamfer(holder_part.edges(Select.LAST).filter_by(lambda e: e.edge().length > params.wall_thickness), length = params.hole_chamfer)
- return holder_part.part
- # %%
- import importlib
- import ShowerPhoneHolder
- importlib.reload(ShowerPhoneHolder)
- from ShowerPhoneHolder import *
- from ocp_vscode import *
- set_port(3939)
- phone_holder_params = PhoneHolderParams(
- phone_length = 140 *MM,
- phone_width = 79 *MM,
- phone_thickness = 10.0 *MM,
- glass_thickness = 4.7 *MM,
- )
- phone_holder = build_phone_holder(phone_holder_params)
- export_stl(phone_holder, "ShowerPhoneHolder.stl")
- show_all()
- # %%
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement