From 398cb4dc52c99ec2ac4f3104aadb1cf98d4280b6 Mon Sep 17 00:00:00 2001 From: hadware Date: Tue, 12 May 2026 14:45:03 +0200 Subject: [PATCH] =?UTF-8?q?Diff=C3=A9rents=20types=20de=20trous=20pour=20s?= =?UTF-8?q?olidariser=20le=20couvercle=20et=20les=20futures=202=20parties?= =?UTF-8?q?=20du=20bloc=20extrudeur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests.ipynb | 88 +++++++++++++++++++++++++++++++ tractrudeuse_v2.ipynb | 117 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 184 insertions(+), 21 deletions(-) diff --git a/tests.ipynb b/tests.ipynb index 4a4e03a..2022088 100644 --- a/tests.ipynb +++ b/tests.ipynb @@ -40,6 +40,94 @@ } ], "execution_count": 1 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-05-11T13:14:15.239670548Z", + "start_time": "2026-05-11T13:14:14.437899096Z" + } + }, + "cell_type": "code", + "source": [ + "from build123d import *\n", + "from ocp_vscode import *\n", + "\n", + "with BuildPart() as latch:\n", + " # Basic box shape to start with filleted corners\n", + " Box(70, 30, 14)\n", + " end = latch.faces().sort_by(Axis.X)[-1] # save the end with the hole\n", + " fillet(latch.edges().filter_by(Axis.Z), 2)\n", + " fillet(latch.edges().sort_by(Axis.Z)[-1], 1)\n", + " # Make screw tabs\n", + " with BuildSketch(latch.faces().sort_by(Axis.Z)[0]) as l4:\n", + " with Locations((-30, 0), (30, 0)):\n", + " SlotOverall(50, 10, rotation=90)\n", + " Rectangle(50, 30)\n", + " fillet(l4.vertices(Select.LAST), radius=2)\n", + " extrude(amount=-2)\n", + " with GridLocations(60, 40, 2, 2):\n", + " Hole(2)\n", + " # Create the hole from the end saved previously\n", + " with BuildSketch(end) as slide_hole:\n", + " add(end)\n", + " offset(amount=-2)\n", + " fillet(slide_hole.vertices(), 1)\n", + " extrude(amount=-68, mode=Mode.SUBTRACT)\n", + " # Slot for the handle to slide in\n", + " with BuildSketch(latch.faces().sort_by(Axis.Z)[-1]):\n", + " SlotOverall(32, 8)\n", + " extrude(amount=-2, mode=Mode.SUBTRACT)\n", + " # The slider will move align the x axis 12mm in each direction\n", + " LinearJoint(\"latch\", axis=Axis.X, linear_range=(-12, 12))\n", + "\n", + "with BuildPart() as slide:\n", + " # The slide will be a little smaller than the hole\n", + " with BuildSketch() as s1:\n", + " add(slide_hole.sketch)\n", + " offset(amount=-0.25)\n", + " # The extrusions aren't symmetric\n", + " extrude(amount=46)\n", + " extrude(slide.faces().sort_by(Axis.Z)[0], amount=20)\n", + " # Round off the ends\n", + " fillet(slide.edges().group_by(Axis.Z)[0], 1)\n", + " fillet(slide.edges().group_by(Axis.Z)[-1], 1)\n", + " # Create the knob\n", + " with BuildSketch() as s2:\n", + " with Locations((12, 0)):\n", + " SlotOverall(15, 4, rotation=90)\n", + " Rectangle(12, 7, align=(Align.MIN, Align.CENTER))\n", + " fillet(s2.vertices(Select.LAST), 1)\n", + " split(bisect_by=Plane.XZ)\n", + " revolve(axis=Axis.X)\n", + " # Align the joint to Plane.ZY flipped\n", + " RigidJoint(\"slide\", joint_location=Location(-Plane.ZY))\n", + "\n", + "# Position the slide in the latch: -12 >= position <= 12\n", + "latch.part.joints[\"latch\"].connect_to(slide.part.joints[\"slide\"], position=12)\n", + "\n", + "# show(latch.part, render_joints=True)\n", + "# show(slide.part, render_joints=True)\n", + "show(latch.part, slide.part, render_joints=True)" + ], + "id": "cb25c030c8bb89dc", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "++\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "CameraWarning: Object may extend beyond view (287.7% of previous size). Skip warnings with `ignore_camera_warnings()`\n" + ] + } + ], + "execution_count": 2 } ], "metadata": { diff --git a/tractrudeuse_v2.ipynb b/tractrudeuse_v2.ipynb index af3901d..b5cfc1f 100644 --- a/tractrudeuse_v2.ipynb +++ b/tractrudeuse_v2.ipynb @@ -6,11 +6,13 @@ "metadata": { "collapsed": true, "ExecuteTime": { - "end_time": "2026-05-09T14:28:10.474719577Z", - "start_time": "2026-05-09T14:28:05.535127271Z" + "end_time": "2026-05-12T12:43:07.527133896Z", + "start_time": "2026-05-12T12:43:02.563122699Z" } }, "source": [ + "from itertools import product\n", + "\n", "from ocp_vscode import show\n", "\n", "\"\"\"\n", @@ -28,7 +30,7 @@ "# Fente (guide tract) — face droite, centrée en Y\n", "fente_largeur = 152.0 # mm — largeur de la fente -> Y\n", "fente_profondeur = 80.0 # mm — profondeur (longueur de la rainure) -> X\n", - "fente_section = 2.0 # mm — hauteur de la section (épaisseur papier + jeu)\n", + "fente_hauteur = 2.0 # mm — hauteur de la section (épaisseur papier + jeu)\n", "\n", "# Zone à extruder du tract\n", "tract_extrusion_cote = 45 # mm\n", @@ -67,13 +69,26 @@ "emboitement_jeu = 0.3 # mm\n", "\n", "# Couvercle\n", - "couvercle_epaisseur = 3.0 # mm\n", + "couvercle_epaisseur = 5 # mm\n", "couvercle_ouv_largeur = 150 # mm — ouverture X\n", "couvercle_ouv_profondeur = 60 # mm — ouverture Y\n", "\n", "# Bac\n", "bac_hauteur = 100.0 # mm\n", "\n", + "# Fixations couvercle\n", + "vis_diam = 4 + 0.1\n", + "vis_longueur = 40\n", + "vis_profondeur_trou_bloc = vis_longueur - couvercle_epaisseur\n", + "vis_ecrou_diam = 7 + 0.15\n", + "vis_ecrou_hauteur = 3.2 + 0.15\n", + "\n", + "# Fixation couplage des deux sous-parties du bloc extrudeur\n", + "vis_couplage_diam_pas = 2.8\n", + "vis_couplage_diam = 4\n", + "vis_couplage_diam_trou = 8\n", + "vis_couplage_longueur = 20\n", + "\n", "# ─────────────────────────────────────────────────────────────────────────────\n", "# DIMENSIONS DÉRIVÉES\n", "# ─────────────────────────────────────────────────────────────────────────────\n", @@ -83,7 +98,6 @@ "fente_y = fente_largeur / 2 - tracte_extrusion_center_y_offset\n", "fente_z_abs = epaisseur_fond + zone_extrusion_offset_hauteur # hauteur absolue depuis le bas\n", "\n", - "\n", "bloc_extrudeur_int_x = (fente_profondeur - tract_extrusion_center_x_offset\n", " + cav_dim_x - zone_extrusion_offset_avant)\n", "bloc_extrudeur_int_y = max(cav_dim_y, fente_largeur + fente_y)\n", @@ -96,7 +110,6 @@ "cav_x = (bloc_extrudeur_ext_x - cav_dim_x) / 2 # centrée en X\n", "cav_y = 0\n", "\n", - "\n", "# Bac\n", "bac_ext_x = bloc_extrudeur_ext_x + 2 * (epaisseur_paroi + emboitement_jeu)\n", "bac_ext_y = bloc_extrudeur_ext_y + 2 * (epaisseur_paroi + emboitement_jeu)\n", @@ -142,11 +155,16 @@ " # Position relative au centre de la face (origine du sketch)\n", " # with Locations(Location((fente_y, fente_z_abs - bloc_extrudeur_ext_z))):\n", " with Locations(Location((fente_y, fente_z_abs - bloc_extrudeur_ext_z / 2))):\n", - " Rectangle(fente_largeur, fente_section)\n", + " Rectangle(fente_largeur, fente_hauteur)\n", "\n", " extrude(amount=-fente_profondeur, mode=Mode.SUBTRACT)\n", " # ptit coup de chamfrein sur la fente\n", - " chamfer(p.edges(Select.LAST), length=0.5)\n", + " chamfer(\n", + " p.edges(Select.LAST)\n", + " .filter_by(Axis.Y)\n", + " .filter_by_position(Axis.X, bloc_extrudeur_ext_x / 2 - 0.01, bloc_extrudeur_ext_x / 2 + 0.01),\n", + " length=2\n", + " )\n", "\n", " # # 4. Trou d'évacuation (perce le fond depuis en dessous)\n", " cav_floor = faces().filter_by(Axis.Z).sort_by(Axis.Z)[1]\n", @@ -154,12 +172,67 @@ " with BuildSketch(cav_floor) as sk:\n", " with Locations(Location((inner_fente_x\n", " + tract_extrusion_center_x_offset\n", - " - 5, 0))):\n", + " - 5, 0))):\n", " Rectangle(tract_extrusion_cote + 3, tract_extrusion_cote + 3)\n", " extrude(amount=-epaisseur_fond, mode=Mode.SUBTRACT)\n", " # ptit coup de chamfrein sur le trou\n", " chamfer(edges(Select.LAST), length=2)\n", "\n", + " # trous de boulon pour fixer le couvercle\n", + " with Locations(top_face) as sk:\n", + " # Position relative au centre de la face (origine du sketch)\n", + " for side_offset in [bloc_extrudeur_ext_y / 2 - epaisseur_paroi,\n", + " -bloc_extrudeur_ext_y / 2 + epaisseur_paroi]:\n", + " with Locations((0, side_offset)):\n", + " Hole(radius=vis_diam / 2, depth=vis_profondeur_trou_bloc)\n", + " with BuildSketch(Plane(top_face).offset(-10)) as sk:\n", + " for side_offset in [bloc_extrudeur_ext_y / 2 - epaisseur_paroi,\n", + " -bloc_extrudeur_ext_y / 2 + epaisseur_paroi]:\n", + " with Locations((0, side_offset)):\n", + " RegularPolygon(radius=vis_ecrou_diam / 2, side_count=6)\n", + "\n", + " extrude(amount=-vis_ecrou_hauteur, mode=Mode.SUBTRACT)\n", + "\n", + " fente_top_face = (faces()\n", + " .filter_by(Plane.YX)\n", + " .filter_by_position(Axis.Z,\n", + " - bloc_extrudeur_ext_z / 2 + fente_z_abs,\n", + " -bloc_extrudeur_ext_z / 2 + fente_z_abs + fente_hauteur)[0])\n", + "\n", + " # Position relative au centre de la face (origine du sketch)\n", + " y_offsets = (bloc_extrudeur_ext_y / 2 - epaisseur_paroi,\n", + " -(bloc_extrudeur_ext_y / 2) + epaisseur_paroi)\n", + " x_offsets = (bloc_extrudeur_ext_x / 2 - (fente_profondeur + 20),\n", + " - bloc_extrudeur_ext_x / 2 + epaisseur_paroi)\n", + " hole_locations = list(product(x_offsets, y_offsets))\n", + " # Trous de couplage des deux parties du bloc une fois séparées\n", + " with Locations(Plane(\n", + " origin=(0, 0, fente_top_face.center().Z),\n", + " z_dir=(0, 0, 1)\n", + " ).offset(5)) as sk:\n", + " # Trou vers le haut (diamètre 10)\n", + " with Locations(hole_locations):\n", + " Cylinder(\n", + " radius=vis_couplage_diam_trou/2,\n", + " height=50,\n", + " align=(Align.CENTER, Align.CENTER, Align.MIN),\n", + " mode=Mode.SUBTRACT\n", + " )\n", + " Cylinder(\n", + " radius=vis_couplage_diam /2,\n", + " height=5,\n", + " rotation=(180, 0, 0), # inverse le sens\n", + " align=(Align.CENTER, Align.CENTER, Align.MIN),\n", + " mode=Mode.SUBTRACT\n", + " )\n", + " Cylinder(\n", + " radius=vis_couplage_diam_pas /2,\n", + " height=50,\n", + " rotation=(180, 0, 0), # inverse le sens\n", + " align=(Align.CENTER, Align.CENTER, Align.MIN),\n", + " mode=Mode.SUBTRACT\n", + " )\n", + "\n", " # # Trous de boulons pour fixer la trouyoteuse\n", " with Locations(cav_floor):\n", " with GridLocations(50, 60, 2, 2):\n", @@ -240,7 +313,7 @@ " with BuildSketch(bottom_face) as sk:\n", " # Position relative au centre de la face (origine du sketch)\n", " with Locations(Location((0, 0))):\n", - " Rectangle(couv_ext_x - 2 * epaisseur_paroi, couv_ext_y - 2 * epaisseur_paroi,)\n", + " Rectangle(couv_ext_x - 2 * epaisseur_paroi, couv_ext_y - 2 * epaisseur_paroi, )\n", " extrude(amount=-emboitement_profondeur, mode=Mode.SUBTRACT)\n", "\n", " # 3. Ouverture rectangulaire centrée sur la cavité\n", @@ -251,20 +324,22 @@ " Rectangle(couvercle_ouv_largeur, couvercle_ouv_profondeur)\n", " extrude(amount=-epaisseur_paroi, mode=Mode.SUBTRACT)\n", "\n", - " return p.part\n", - "\n", + " with Locations(top_face) as sk:\n", + " # Position relative au centre de la face (origine du sketch)\n", + " for side_offset in [bloc_extrudeur_ext_y / 2 - epaisseur_paroi,\n", + " -bloc_extrudeur_ext_y / 2 + epaisseur_paroi]:\n", + " with Locations((0, side_offset)):\n", + " Hole(radius=vis_diam / 2)\n", "\n", - "def center_xy(part):\n", - " bb = part.bounding_box()\n", - " return part.translate((-bb.center().X, -bb.center().Y, 0))\n", + " return p.part\n", "\n", "\n", "gap = 50\n", "\n", "show(\n", - " center_xy(make_bloc_extrudeur()),\n", - " center_xy(make_bac_recup()).translate((0, 0, -(bloc_extrudeur_ext_z / 2 + 2 * gap))),\n", - " center_xy(make_couvercle()).translate((0, 0, bloc_extrudeur_ext_z / 2 + gap)),\n", + " make_bloc_extrudeur(),\n", + " make_bac_recup().translate((0, 0, -(bloc_extrudeur_ext_z / 2 + 2 * gap))),\n", + " make_couvercle().translate((0, 0, bloc_extrudeur_ext_z / 2 + gap)),\n", " names=[\"superieure\", \"inferieure\", \"couvercle\"],\n", " colors=[\"#ff7800\", \"#000000\", \"#000000\"],\n", ")" @@ -274,11 +349,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "+++\n" + "+cc\n" ] } ], - "execution_count": 110 + "execution_count": 161 }, { "metadata": { @@ -288,7 +363,7 @@ } }, "cell_type": "code", - "source": "bloc_extrudeur_ext_x", + "source": "edges(Select.LAST)[0].is_closed", "id": "810fb3a101c2fccd", "outputs": [ {