diff --git a/tractrudeuse_v2.ipynb b/tractrudeuse_v2.ipynb index b4db2a9..51fd568 100644 --- a/tractrudeuse_v2.ipynb +++ b/tractrudeuse_v2.ipynb @@ -6,8 +6,8 @@ "metadata": { "collapsed": true, "ExecuteTime": { - "end_time": "2026-05-14T02:35:48.111465748Z", - "start_time": "2026-05-14T02:35:34.544312989Z" + "end_time": "2026-05-15T00:06:41.549639954Z", + "start_time": "2026-05-15T00:06:27.739048425Z" } }, "source": [ @@ -29,7 +29,6 @@ "\n", "# 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_hauteur = 2.0 # mm — hauteur de la section (épaisseur papier + jeu)\n", "\n", "# Zone à extruder du tract\n", @@ -50,6 +49,10 @@ "zone_extrusion_offset_avant = 50 # mm\n", "# offset par rapport au bas de l'extrudeuse\n", "zone_extrusion_offset_hauteur = 12 # mm\n", + "# distance sur X entre l'avant de l'extrudeuse et les trous\n", + "extrudeuse_dist_trous_avant_x = 105 # mm\n", + "trous_fixation_extrudeuse_ecart = 40 # mm\n", + "trous_fixation_extrudeuse_diam = 5 # mm\n", "\n", "# Cavité perforatrice\n", "jeu_cavite = 2 # mm\n", @@ -67,7 +70,7 @@ "evac_taille = 48.0 # mm — côté du carré (45 + jeu)\n", "\n", "# Parois\n", - "epaisseur_paroi_fond = 20 # mm\n", + "epaisseur_paroi_fond = 15 # mm\n", "epaisseur_paroi = 10 # mm\n", "epaisseur_fond = 10.0 # mm\n", "\n", @@ -93,7 +96,7 @@ "# 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_diam_trou = 10\n", "vis_couplage_longueur = 20\n", "\n", "# Encoches d'emboitages\n", @@ -105,13 +108,14 @@ "# DIMENSIONS DÉRIVÉES\n", "# ─────────────────────────────────────────────────────────────────────────────\n", "\n", + "# TODO: vérifier les offset relatifs fente/zone d'extrusion\n", "# Fente\n", "# léger offset pour centrer la zone à extruder dans l'axe de l'extrudeuse\n", "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", + "fente_profondeur = tract_extrusion_center_x_offset + zone_extrusion_offset_avant + epaisseur_paroi\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_x = cav_dim_x\n", "bloc_extrudeur_int_y = max(cav_dim_y, fente_largeur + fente_y)\n", "\n", "bloc_extrudeur_ext_x = bloc_extrudeur_int_x + 2 * epaisseur_paroi\n", @@ -142,21 +146,43 @@ "\n", "def make_bloc_extrudeur():\n", " with BuildPart() as p:\n", - " # 1. Corps principal\n", + " # Corps principal\n", " Box(bloc_extrudeur_ext_x, bloc_extrudeur_ext_y, bloc_extrudeur_ext_z)\n", " chamfer(edges().filter_by(Axis.Z), length=2)\n", "\n", - " # 2. Cavité perforatrice (ouverte vers le haut)\n", + " # Cavité perforatrice (ouverte vers le haut)\n", " # On se met sur le haut du bloc, puis on extrude de la honteur\n", " top_face = faces().sort_by(Axis.Z)[-1]\n", " with BuildSketch(top_face) as sk:\n", " # Position relative au centre de la face (origine du sketch)\n", - " with Locations(Location((cav_x + cav_dim_x / 2 - bloc_extrudeur_ext_x / 2, 0))):\n", + " with Locations((cav_x + cav_dim_x / 2 - bloc_extrudeur_ext_x / 2, 0)):\n", " Rectangle(cav_dim_x, cav_dim_y)\n", "\n", " extrude(amount=-cav_hauteur, mode=Mode.SUBTRACT)\n", "\n", - " # # 3. Fente latérale (débouche sur la face droite, X max)\n", + " # évidage de la matière sur les cotés de la cavité\n", + " with BuildSketch(top_face) as sk:\n", + " # Position relative au centre de la face (origine du sketch)\n", + " with Locations((-bloc_extrudeur_int_x / 2, 0)):\n", + " Rectangle(cav_dim_x - fente_profondeur,\n", + " bloc_extrudeur_ext_y - 4 * epaisseur_paroi,\n", + " align=(Align.MIN, Align.CENTER))\n", + " extrude(amount=-cav_hauteur, mode=Mode.SUBTRACT)\n", + "\n", + " with BuildSketch(top_face) as sk:\n", + " # Position relative au centre de la face (origine du sketch)\n", + " with Locations((bloc_extrudeur_int_x / 2, 0)):\n", + " Rectangle(cav_dim_x - 10,\n", + " bloc_extrudeur_ext_y - 4 * epaisseur_paroi,\n", + " align=(Align.MAX, Align.CENTER))\n", + " extrude(amount=-cav_hauteur / 2, mode=Mode.SUBTRACT)\n", + " e = (edges(Select.LAST)\n", + " .filter_by(Plane.top)\n", + " .filter_by(lambda x: not x.is_interior)\n", + " .filter_by_position(Axis.Z, minimum=0, maximum=bloc_extrudeur_ext_z / 2 - 0.1))\n", + " chamfer(e, length=6)\n", + "\n", + " # Fente latérale (débouche sur la face droite, X max)\n", " front_face = faces().sort_by(Axis.X)[-1]\n", " front_plane = Plane(\n", " origin=front_face.center(),\n", @@ -170,13 +196,20 @@ " Rectangle(fente_largeur, fente_hauteur)\n", "\n", " extrude(amount=-fente_profondeur, mode=Mode.SUBTRACT)\n", + " edges_stop = (edges(Select.LAST)\n", + " .filter_by(Axis.Y)\n", + " .filter_by(lambda x: x.is_interior)\n", + " .sort_by(Axis.Z)[-2:])\n", + "\n", " # ptit coup de chamfrein sur la fente\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", + " length=5\n", " )\n", + " # ptit coup de chamfrein le bord intérieur haut du butoir de la fente\n", + " chamfer(edges_stop,length=1)\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", @@ -247,8 +280,9 @@ "\n", " # # Trous de boulons pour fixer la trouyoteuse\n", " with Locations(cav_floor):\n", - " with GridLocations(50, 60, 2, 2):\n", - " Hole(radius=3)\n", + " with Locations((cav_dim_x / 2 - extrudeuse_dist_trous_avant_x, 0)):\n", + " with GridLocations(0, trous_fixation_extrudeuse_ecart, 1, 2):\n", + " Hole(radius=trous_fixation_extrudeuse_diam / 2 + 0.2)\n", "\n", " # Affichage du logo sur la face de la fente\n", " # centré, au dessus de la fente\n", @@ -258,8 +292,8 @@ " cx = (min_x + max_x) / 2\n", "\n", " with BuildSketch(front_plane) as sk:\n", - " add([s.translate((-cx, -5, 0)) for s in logo_shapes])\n", - " scale(by=0.8)\n", + " add([s.translate((-cx, 0, 0)) for s in logo_shapes])\n", + " scale(by=0.7)\n", "\n", " extrude(amount=-1, mode=Mode.SUBTRACT) # 1.5 mm de profondeur\n", "\n", @@ -323,7 +357,6 @@ " top_edges = (edges(Select.LAST).filter_by(Axis.X).sort_by(Axis.Z)[-4:])\n", " chamfer(top_edges, length=0.5)\n", "\n", - "\n", " with BuildPart() as p_bottom:\n", " add(bottom)\n", " top_face = faces().filter_by(Plane.XY).sort_by(Axis.Z)[-1]\n", @@ -434,7 +467,107 @@ ] } ], - "execution_count": 19 + "execution_count": 108 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-05-14T23:44:03.217747593Z", + "start_time": "2026-05-14T23:44:03.171779231Z" + } + }, + "cell_type": "code", + "source": "fente_profondeur", + "id": "a3d65d64eb54186b", + "outputs": [ + { + "data": { + "text/plain": [ + "92.5" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 106 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-05-14T17:02:55.525552748Z", + "start_time": "2026-05-14T17:02:53.826129466Z" + } + }, + "cell_type": "code", + "source": [ + "pattes_largueur = 5\n", + "pattes_profondeur = 5\n", + "bras_patte_dist = 8\n", + "bloc_hauteur_totale = 10\n", + "bloc_hauteur = 6\n", + "pourtour_hauteur = bloc_hauteur_totale - bloc_hauteur\n", + "raiser_dim_x = 30\n", + "raiser_dim_y = 18\n", + "raiser_dim_z = 15\n", + "cav_bloc_dim_x = 24\n", + "cav_bloc_dim_y = 14\n", + "\n", + "with BuildPart() as bp:\n", + " raiser = Box(raiser_dim_x, raiser_dim_y, raiser_dim_z)\n", + " raiser_faces = raiser.faces()\n", + " bottom_face = faces().filter_by(Plane.top).sort_by(Axis.Z)[0]\n", + " with BuildSketch(Plane(bottom_face).reverse()):\n", + " Rectangle(cav_bloc_dim_x, cav_bloc_dim_y)\n", + " extrude(amount=(bloc_hauteur + 1), mode=Mode.SUBTRACT)\n", + "\n", + " for face in raiser_faces.filter_by(lambda f: abs(f.normal_at().Z) < 0.01):\n", + " plane = Plane(face)\n", + " offset_plane = plane.offset(bras_patte_dist)\n", + " with BuildSketch(offset_plane):\n", + " with Locations((bottom_face.center().Z,)):\n", + " Rectangle(2,5, align=(Align.MIN, Align.CENTER))\n", + " with BuildSketch(face):\n", + " add(face.rotate(Axis.Y, 90)) # ← utilise directement la face comme sketch\n", + " loft()\n", + "\n", + " patte_plane = Plane(\n", + " origin=offset_plane.origin,\n", + " x_dir=-offset_plane.y_dir,\n", + " z_dir=(0,0,1)\n", + " ).offset(bottom_face.center().Z)\n", + " with BuildSketch(patte_plane):\n", + " Rectangle(5,bras_patte_dist - 1, align=(Align.CENTER, Align.MIN))\n", + " with BuildSketch(patte_plane.offset(-pourtour_hauteur)):\n", + " Rectangle(5,5, align=(Align.CENTER, Align.MIN))\n", + "\n", + " loft()\n", + "\n", + "show(bp.part)\n", + "export_step(bp.part, \"/tmp/raiser.step\")" + ], + "id": "ff26d94e85b6c380", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 103, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 103 }, { "metadata": {