From b5326dae82e30cd784ffb37428907ade48465ff2 Mon Sep 17 00:00:00 2001 From: Yeicor <4929005+Yeicor@users.noreply.github.com> Date: Thu, 4 Jan 2024 21:23:58 +0100 Subject: [PATCH] Continue the multipart design --- main.py | 8 ++- .../headset_screw_part.cpython-311.pyc | Bin 5244 -> 5222 bytes .../stem_and_handle_bars_part.cpython-311.pyc | Bin 2163 -> 3806 bytes parts/headset_screw_part.py | 4 +- parts/stem_and_handle_bars_part.py | 50 +++++++++++++----- 5 files changed, 46 insertions(+), 16 deletions(-) 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 bd44ae21d96465699d5a48ef40c2dc0b19bea299..5db4f186310d9b08799614fabe295153a734b789 100644 GIT binary patch delta 318 zcmeyP@l1nnIWI340}yx$O;7#9HIYw(@xVs)J=kT`mpA|9Wo2YE+WenyHq+!zA)(E?1#KDmR+L;6Grq`Ta)rg@0*lFHM&W?ii!9Pt zSfnqoNZ;TP{E*6M#3=NE0Y-cTvA)2$2njUSj~_qKL?GOZ$(w}zYW!@N59+BoDX<x{L2M0EAp5W^ud^BJVJ(oF!)7ebR-A{eKxz)#GJ@E4@<8?x sS#4Jl)}tICHAh8QTqQV@x(^;J8I1i~XgV^ef zAhw1nkbPK|*V&Bquog(oVKWwIE6&4KAT@_=89{72c_90UthTEN>roDnnxi5tt`eL_ cB|vJ9N;87kGM*AZ&UpqFe-`%h?2JGX04j`QR{#J2 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 cfbaf8505ac253c9067a92cd20ed509c579acc62..78871099ad930a9c5fc86fa119d381a922096711 100644 GIT binary patch literal 3806 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 Hi$VVl!d4z- 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