diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..30cf57e
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Ignored default folder with query files
+/queries/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..09d1715
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..0f62618
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..e7bbb22
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/tractrudeuse.iml b/.idea/tractrudeuse.iml
new file mode 100644
index 0000000..1d22da1
--- /dev/null
+++ b/.idea/tractrudeuse.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests.ipynb b/tests.ipynb
index 2022088..3e90067 100644
--- a/tests.ipynb
+++ b/tests.ipynb
@@ -41,6 +41,52 @@
],
"execution_count": 1
},
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2026-05-12T15:43:51.244991561Z",
+ "start_time": "2026-05-12T15:43:51.223161624Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "from build123d import *\n",
+ "\n",
+ "# Créer une face plate (exemple : un carré dans le plan XY)\n",
+ "box = Box(10, 10, 10)\n",
+ "face = box.faces().filter_by(Plane.YX).sort_by(Axis.Z)[0]\n",
+ "print(face.center())\n",
+ "print(\"Normal avant inversion :\", face.orientation) # Affiche le vecteur normal (ex: (0, 0, 1))\n",
+ "\n",
+ "# Inverser le vecteur normal\n",
+ "face_reversed = -face\n",
+ "print(\"Normal après inversion :\", face_reversed.orientation) # Affiche le vecteur normal inversé\n",
+ "\n",
+ "print(Plane(face))\n",
+ "print(Plane(face).reverse())\n",
+ "print(Plane.XY)\n",
+ "print(Plane.XY.reverse())\n",
+ "print(Plane.YX)"
+ ],
+ "id": "7450390859017a41",
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Vector(0, 0, -5)\n",
+ "Normal avant inversion : Vector(0, 0, 0)\n",
+ "Normal après inversion : Vector(0, 0, 0)\n",
+ "Plane(o=(0.00, 0.00, -5.00), x=(1.00, 0.00, 0.00), z=(-0.00, -0.00, -1.00))\n",
+ "Plane(o=(0.00, 0.00, -5.00), x=(1.00, 0.00, 0.00), z=(0.00, 0.00, 1.00))\n",
+ "Plane(o=(0.00, 0.00, 0.00), x=(1.00, 0.00, 0.00), z=(0.00, 0.00, 1.00))\n",
+ "Plane(o=(0.00, 0.00, 0.00), x=(1.00, 0.00, 0.00), z=(-0.00, -0.00, -1.00))\n",
+ "Plane(o=(0.00, 0.00, 0.00), x=(0.00, 1.00, 0.00), z=(0.00, 0.00, -1.00))\n"
+ ]
+ }
+ ],
+ "execution_count": 13
+ },
{
"metadata": {
"ExecuteTime": {
diff --git a/tractrudeuse_v2.ipynb b/tractrudeuse_v2.ipynb
index f9af629..8a9cf7e 100644
--- a/tractrudeuse_v2.ipynb
+++ b/tractrudeuse_v2.ipynb
@@ -6,8 +6,8 @@
"metadata": {
"collapsed": true,
"ExecuteTime": {
- "end_time": "2026-05-12T12:54:56.813417603Z",
- "start_time": "2026-05-12T12:54:51.653355189Z"
+ "end_time": "2026-05-12T16:07:33.781803143Z",
+ "start_time": "2026-05-12T16:07:26.817563805Z"
}
},
"source": [
@@ -89,6 +89,11 @@
"vis_couplage_diam_trou = 8\n",
"vis_couplage_longueur = 20\n",
"\n",
+ "# Encoches d'emboitages\n",
+ "encoche_profondeur = 4\n",
+ "encoche_longueur = 20\n",
+ "encoche_largueur = epaisseur_paroi / 3\n",
+ "\n",
"# ─────────────────────────────────────────────────────────────────────────────\n",
"# DIMENSIONS DÉRIVÉES\n",
"# ─────────────────────────────────────────────────────────────────────────────\n",
@@ -210,28 +215,28 @@
" 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",
+ " # 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",
@@ -264,7 +269,50 @@
" rotation=-90)\n",
" extrude(amount=-1, mode=Mode.SUBTRACT)\n",
"\n",
- " return p.part\n",
+ " # Couper au niveau de la fente\n",
+ " top, bottom = split(\n",
+ " p.part,\n",
+ " bisect_by=Plane(\n",
+ " origin=(0, 0, fente_top_face.center().Z),\n",
+ " z_dir=(0, 0, 1)\n",
+ " ),\n",
+ " keep=Keep.BOTH\n",
+ " )\n",
+ "\n",
+ " # Rajouter des encoches tenon/mortaises pour verrouiller les deux pièces\n",
+ " # l'une dans l'autre\n",
+ " y_offsets = (bloc_extrudeur_ext_y / 2 - epaisseur_paroi / 2,\n",
+ " -(bloc_extrudeur_ext_y / 2) + epaisseur_paroi / 2)\n",
+ " x_offsets = (bloc_extrudeur_ext_x / 2 - epaisseur_paroi * 2,\n",
+ " - bloc_extrudeur_ext_x / 2 + epaisseur_paroi * 2)\n",
+ " sockets_offsets = list(product(x_offsets, y_offsets))\n",
+ " with BuildPart() as p_top:\n",
+ " add(top)\n",
+ " bottom_face = faces().filter_by(Plane.XY).sort_by(Axis.Z)[0]\n",
+ " bottom_plane = Plane(\n",
+ " origin=(0, 0, bottom_face.center().Z),\n",
+ " z_dir=(0, 0, 1)\n",
+ " )\n",
+ " with BuildSketch(bottom_plane):\n",
+ " with Locations(sockets_offsets):\n",
+ " Rectangle(encoche_longueur, encoche_largueur)\n",
+ " extrude(amount=encoche_profondeur, mode=Mode.SUBTRACT)\n",
+ "\n",
+ " with BuildPart() as p_bottom:\n",
+ " add(bottom)\n",
+ " top_face = faces().filter_by(Plane.XY).sort_by(Axis.Z)[-1]\n",
+ " top_plane = Plane(\n",
+ " origin=(0, 0, top_face.center().Z),\n",
+ " z_dir=(0, 0, 1)\n",
+ " )\n",
+ " with BuildSketch(top_plane):\n",
+ " with Locations(sockets_offsets):\n",
+ " Rectangle(encoche_longueur - 0.4, encoche_largueur - 0.4)\n",
+ " extrude(amount=encoche_profondeur - 0.2, mode=Mode.ADD)\n",
+ " top_edges = edges(Select.LAST).filter_by_position(Axis.Z, minimum=top_plane.origin.Z + encoche_profondeur / 2, maximum= top_plane.origin.Z + encoche_profondeur * 2)\n",
+ " chamfer(top_edges, length=1)\n",
+ "\n",
+ " return Compound(children=[p_top.part, p_bottom.part])\n",
"\n",
"\n",
"# ─────────────────────────────────────────────────────────────────────────────\n",
@@ -323,7 +371,10 @@
" with Locations(Location((0, 0))):\n",
" Rectangle(couvercle_ouv_largeur, couvercle_ouv_profondeur)\n",
" extrude(amount=-epaisseur_paroi, mode=Mode.SUBTRACT)\n",
+ " # petit coup de chamfrein\n",
+ " chamfer(edges(Select.LAST), length=2)\n",
"\n",
+ " # trous de vis\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",
@@ -349,11 +400,11 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "+cc\n"
+ "c+c+\n"
]
}
],
- "execution_count": 162
+ "execution_count": 14
},
{
"metadata": {
@@ -363,7 +414,7 @@
}
},
"cell_type": "code",
- "source": "edges(Select.LAST)[0].is_closed",
+ "source": "make_brake_formed",
"id": "810fb3a101c2fccd",
"outputs": [
{