diff --git a/main.py b/main.py index efeaf50..074922e 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,10 @@ # %% # ================== MODELLING (ASSEMBLY) ================== +with BuildPart() as assembly: + add(headset_screw_part) + add(stem_and_handle_bars_part) + if 'ocp_vscode' in locals(): with suppress(Exception): ocp_vscode.show_all() @@ -20,7 +24,7 @@ export = True try: if "show_object" in locals(): - show_object(headset_screw_part, "bike-stem-mount") # type: ignore + show_object(assembly, "bike-stem-mount") # type: ignore export = False elif "ocp_vscode" in locals(): ocp_vscode.reset_show() @@ -31,6 +35,6 @@ if export: print("Exporting to STL") - headset_screw_part.part.export_stl("bike-stem-mount.stl") + assembly.part.export_stl("bike-stem-mount.stl") # %% diff --git a/parts/__pycache__/headset_screw_part.cpython-311.pyc b/parts/__pycache__/headset_screw_part.cpython-311.pyc index bd44ae2..5db4f18 100644 Binary files a/parts/__pycache__/headset_screw_part.cpython-311.pyc and b/parts/__pycache__/headset_screw_part.cpython-311.pyc differ diff --git a/parts/__pycache__/stem_and_handle_bars_part.cpython-311.pyc b/parts/__pycache__/stem_and_handle_bars_part.cpython-311.pyc index cfbaf85..7887109 100644 Binary files a/parts/__pycache__/stem_and_handle_bars_part.cpython-311.pyc and b/parts/__pycache__/stem_and_handle_bars_part.cpython-311.pyc differ diff --git a/parts/headset_screw_part.py b/parts/headset_screw_part.py index 5b14102..79080c0 100644 --- a/parts/headset_screw_part.py +++ b/parts/headset_screw_part.py @@ -63,11 +63,11 @@ def outer_wall(radius: float = stem_circle_radius): # Final filleting to_fillet = headset_screw_part.faces().group_by(Axis.Z)[-1].edges() to_fillet -= to_fillet.group_by(Axis.X)[-1] - fillet(to_fillet, stem_circle_max_height) + fillet(to_fillet, stem_circle_max_height - wall) del to_fillet to_fillet = headset_screw_part.edges().group_by( Axis.Z)[0].group_by(SortBy.LENGTH)[-1] - fillet(to_fillet, wall - eps) + fillet(to_fillet, wall) del to_fillet if __name__ == "__main__": # While developing this single part diff --git a/parts/stem_and_handle_bars_part.py b/parts/stem_and_handle_bars_part.py index b8afdc0..6f1bae6 100644 --- a/parts/stem_and_handle_bars_part.py +++ b/parts/stem_and_handle_bars_part.py @@ -1,18 +1,21 @@ # %% from contextlib import suppress from build123d import * +from copy import copy +import math try: from global_params import * - from headset_screw_part import headset_screw_part + from headset_screw_part import headset_screw_part, stem_circle_max_height, stem_circle_radius except ImportError: # HACK... from parts.global_params import * - from parts.headset_screw_part import headset_screw_part + from parts.headset_screw_part import headset_screw_part, stem_circle_max_height, stem_circle_radius with suppress(ImportError): # Optional import ocp_vscode # ================== PARAMETERS ================== # Measurements... +stem_angle = 20 # Stem angle wrt the headset stem_rect = (35, 35) # Stem "rectangle" (horizontal, vertical) # Where to connect to the stem from the center of the circle stem_range = (20, 45) @@ -22,20 +25,43 @@ # ================== MODELLING ================== -conn_face = headset_screw_part.faces().group_by(Axis.X)[-1] -conn_face_center = conn_face.face().center() -conn_face_bb = conn_face.face().bounding_box() +# Uglily recreate conn_face to support sweeping... +conn_face = headset_screw_part.faces().group_by(Axis.X)[-1].face() +conn_face_bb = conn_face.bounding_box() with BuildSketch() as sweep_obj: - # add(conn_face) - Rectangle(3, 10) - # with BuildLine() as sweep_obj_line: - # Polyline(conn_face_bb.min, (conn_face_bb.min.X, conn_face_bb.max.Y, conn_face_bb.min.Z), - # conn_face_bb.max, (conn_face_bb.min.X, conn_face_bb.min.Y, conn_face_bb.max.Z), close=True) - # make_face() + with BuildLine() as sweep_obj_line: + Polyline((conn_face_bb.min.Z, conn_face_bb.min.Y), (conn_face_bb.max.Z, conn_face_bb.min.Y), + (conn_face_bb.max.Z, conn_face_bb.max.Y), (conn_face_bb.min.Z, conn_face_bb.max.Y), close=True) + make_face() + + to_fillet = sweep_obj_line.vertices().group_by(Axis.X)[-1] + fillet(objects=to_fillet, radius=stem_circle_max_height-wall) + to_fillet = sweep_obj_line.vertices().group_by(Axis.X)[0] + fillet(objects=to_fillet, radius=wall) + + # Validate exact sketch matches... + with BuildSketch() as match: + add(sweep_obj) + add(conn_face, mode=Mode.SUBTRACT) + assert len(match.vertices() + ) == 0, "Rebuilt face sketch doesn't match original" + add(conn_face) + add(sweep_obj, mode=Mode.SUBTRACT) + assert len(match.vertices() + ) == 0, "Rebuilt face sketch doesn't match original" + del match + +stem_dist = stem_range[1] - stem_range[0] +stem_height = stem_dist * math.tan(math.radians(stem_angle)) +print(stem_height) with BuildLine() as sweep_path: - Line((conn_face_center.Z, 0, 0), (conn_face_center.Z, 0, 10)) + Polyline((0, 0, stem_circle_radius), + (0, 0, stem_range[0]), (stem_height, 0, stem_range[1])) stem_and_handle_bars_part = sweep(sections=sweep_obj, path=sweep_path) +conn_face_loc = copy(conn_face.center_location) +stem_and_handle_bars_part = stem_and_handle_bars_part.moved( + Location(conn_face_loc.position - (0, 0, conn_face_bb.size.Z/2), (180, 90, 0))) if __name__ == "__main__": # While developing this single part