trenchfoot 0.1.0__tar.gz → 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of trenchfoot might be problematic. Click here for more details.

Files changed (79) hide show
  1. trenchfoot-0.1.1/.env +1 -0
  2. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/.github/workflows/ci.yml +17 -0
  3. trenchfoot-0.1.1/PKG-INFO +113 -0
  4. trenchfoot-0.1.1/README.md +95 -0
  5. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/gmsh_sloped_trench_mesher.py +8 -3
  6. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/pyproject.toml +1 -1
  7. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/tests/test_trenchfoot_generation.py +36 -3
  8. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/uv.lock +1 -1
  9. trenchfoot-0.1.0/.env +0 -1
  10. trenchfoot-0.1.0/PKG-INFO +0 -104
  11. trenchfoot-0.1.0/README.md +0 -86
  12. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/.github_token.env +0 -0
  13. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/LICENSE +0 -0
  14. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/STATUS.md +0 -0
  15. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/docs/scenario_gallery.md +0 -0
  16. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/__init__.py +0 -0
  17. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/Dockerfile +0 -0
  18. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/README.md +0 -0
  19. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/__init__.py +0 -0
  20. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/generate_scenarios.py +0 -0
  21. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/plot_mesh.py +0 -0
  22. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/render_colors.py +0 -0
  23. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/meshes/trench_scene_culled.obj +0 -0
  24. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/metrics.json +0 -0
  25. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/point_clouds/culled/resolution0p050.pth +0 -0
  26. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/point_clouds/full/resolution0p050.pth +0 -0
  27. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/preview.png +0 -0
  28. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/preview_oblique.png +0 -0
  29. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/preview_side.png +0 -0
  30. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/preview_top.png +0 -0
  31. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/scene.json +0 -0
  32. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/trench_scene.obj +0 -0
  33. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S01_straight_vwalls/volumetric/trench_volume.msh +0 -0
  34. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/meshes/trench_scene_culled.obj +0 -0
  35. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/metrics.json +0 -0
  36. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/point_clouds/culled/resolution0p050.pth +0 -0
  37. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/point_clouds/full/resolution0p050.pth +0 -0
  38. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview.png +0 -0
  39. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_oblique.png +0 -0
  40. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_side.png +0 -0
  41. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_top.png +0 -0
  42. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/scene.json +0 -0
  43. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/trench_scene.obj +0 -0
  44. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S02_straight_slope_pipe/volumetric/trench_volume.msh +0 -0
  45. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/meshes/trench_scene_culled.obj +0 -0
  46. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/metrics.json +0 -0
  47. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/point_clouds/culled/resolution0p050.pth +0 -0
  48. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/point_clouds/full/resolution0p050.pth +0 -0
  49. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview.png +0 -0
  50. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_oblique.png +0 -0
  51. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_side.png +0 -0
  52. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_top.png +0 -0
  53. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/scene.json +0 -0
  54. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/trench_scene.obj +0 -0
  55. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/volumetric/trench_volume.msh +0 -0
  56. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S04_U_slope_multi_noise/meshes/trench_scene_culled.obj +0 -0
  57. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S04_U_slope_multi_noise/metrics.json +0 -0
  58. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview.png +0 -0
  59. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_oblique.png +0 -0
  60. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_side.png +0 -0
  61. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_top.png +0 -0
  62. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S04_U_slope_multi_noise/scene.json +0 -0
  63. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S04_U_slope_multi_noise/trench_scene.obj +0 -0
  64. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S04_U_slope_multi_noise/volumetric/trench_volume.msh +0 -0
  65. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S05_wide_slope_pair/metrics.json +0 -0
  66. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_oblique.png +0 -0
  67. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_side.png +0 -0
  68. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_top.png +0 -0
  69. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S05_wide_slope_pair/scene.json +0 -0
  70. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S05_wide_slope_pair/trench_scene.obj +0 -0
  71. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S06_bumpy_wide_loop/metrics.json +0 -0
  72. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_oblique.png +0 -0
  73. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_side.png +0 -0
  74. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_top.png +0 -0
  75. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S06_bumpy_wide_loop/scene.json +0 -0
  76. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/S06_bumpy_wide_loop/trench_scene.obj +0 -0
  77. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scenarios/SUMMARY.json +0 -0
  78. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/scene_spec_example.json +0 -0
  79. {trenchfoot-0.1.0 → trenchfoot-0.1.1}/packages/trenchfoot/trench_scene_generator_v3.py +0 -0
trenchfoot-0.1.1/.env ADDED
@@ -0,0 +1 @@
1
+ PYPI_API_TOKEN=pypi-AgEIcHlwaS5vcmcCJDhjMzk2NDI3LTA0ZTYtNDI4Yy04N2ViLTc2NjdhMmYzZmQ2YgACElsxLFsidHJlbmNoZm9vdCJdXQACLFsyLFsiN2U3YWRkYjItYWI3OC00N2IyLTk4ZGYtYjY4MDMyZTNhYjhiIl1dAAAGICYdxdeBd_-nMpV2e7LHisX3JmN7fIG-CunPvNMHZWav
@@ -15,6 +15,9 @@ jobs:
15
15
  steps:
16
16
  - uses: actions/checkout@v4
17
17
 
18
+ - name: Install system dependencies
19
+ run: sudo apt-get update && sudo apt-get install -y libglu1-mesa
20
+
18
21
  - name: Set up uv
19
22
  uses: astral-sh/setup-uv@v3
20
23
  with:
@@ -38,9 +41,13 @@ jobs:
38
41
  env:
39
42
  UV_PROJECT_ENVIRONMENT: .venv
40
43
  PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
44
+ PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
41
45
  steps:
42
46
  - uses: actions/checkout@v4
43
47
 
48
+ - name: Install system dependencies
49
+ run: sudo apt-get update && sudo apt-get install -y libglu1-mesa
50
+
44
51
  - name: Set up uv
45
52
  uses: astral-sh/setup-uv@v3
46
53
  with:
@@ -49,6 +56,16 @@ jobs:
49
56
  - name: Create virtual environment
50
57
  run: uv venv --python 3.12
51
58
 
59
+ - name: Ensure PyPI token
60
+ shell: bash
61
+ run: |
62
+ TOKEN="${PYPI_API_TOKEN:-${PYPI_TOKEN:-}}"
63
+ if [ -z "$TOKEN" ]; then
64
+ echo "PYPI_API_TOKEN or PYPI_TOKEN secret not provided" >&2
65
+ exit 1
66
+ fi
67
+ echo "PYPI_API_TOKEN=$TOKEN" >> "$GITHUB_ENV"
68
+
52
69
  - name: Load .env if present
53
70
  if: hashFiles('.env') != ''
54
71
  shell: bash
@@ -0,0 +1,113 @@
1
+ Metadata-Version: 2.4
2
+ Name: trenchfoot
3
+ Version: 0.1.1
4
+ Summary: Synthetic trench scenario generator bundle (surfaces + volumetrics).
5
+ Author: Liam Moore
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: numpy>=1.26
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest>=8.3; extra == 'dev'
11
+ Provides-Extra: mesher
12
+ Requires-Dist: gmsh>=4.11; extra == 'mesher'
13
+ Provides-Extra: preview
14
+ Requires-Dist: matplotlib>=3.8; extra == 'preview'
15
+ Provides-Extra: viz
16
+ Requires-Dist: plotly>=5.24; extra == 'viz'
17
+ Description-Content-Type: text/markdown
18
+
19
+ # Trenchfoot
20
+
21
+ Surface and volumetric trench mesh generator with shipped presets, Plotly previews, and a lightweight Python SDK.
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ pip install trenchfoot
27
+ ```
28
+
29
+ Want volumetrics or visualisations? Install extras as needed:
30
+ - `pip install "trenchfoot[mesher]"` for gmsh-powered volume meshes.
31
+ - `pip install "trenchfoot[preview]"` for matplotlib snapshot renders.
32
+ - `pip install "trenchfoot[viz]"` for Plotly HTML viewers.
33
+
34
+ ## Scenario Gallery
35
+
36
+ Color key: trench surfaces use warm soil tones; embedded geometry is colour-coded per group.
37
+
38
+ | Scenario | Top | Side | Oblique |
39
+ | --- | --- | --- | --- |
40
+ | S01_straight_vwalls | ![S01 top](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_top.png) | ![S01 side](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_side.png) | ![S01 oblique](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_oblique.png) |
41
+ | S02_straight_slope_pipe | ![S02 top](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_top.png) | ![S02 side](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_side.png) | ![S02 oblique](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_oblique.png) |
42
+ | S03_L_slope_two_pipes_box | ![S03 top](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_top.png) | ![S03 side](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_side.png) | ![S03 oblique](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_oblique.png) |
43
+ | S04_U_slope_multi_noise | ![S04 top](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_top.png) | ![S04 side](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_side.png) | ![S04 oblique](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_oblique.png) |
44
+ | S05_wide_slope_pair | ![S05 top](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_top.png) | ![S05 side](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_side.png) | ![S05 oblique](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_oblique.png) |
45
+ | S06_bumpy_wide_loop | ![S06 top](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_top.png) | ![S06 side](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_side.png) | ![S06 oblique](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_oblique.png) |
46
+
47
+ ### S06 preset at a glance
48
+
49
+ ```json
50
+ {
51
+ "path_xy": [[0, 0], [4, -1], [8, 0], [8, 5], [2, 5], [-1, 2]],
52
+ "width": 2.6,
53
+ "depth": 1.4,
54
+ "wall_slope": 0.12,
55
+ "ground": {"z0": 0.2, "slope": [0.015, 0.03], "size_margin": 7.0},
56
+ "pipes": [
57
+ {"radius": 0.18, "length": 6.0, "angle_deg": 35, "s_center": 0.3, "z": -0.9, "offset_u": 0.35},
58
+ {"radius": 0.14, "length": 4.8, "angle_deg": -40, "s_center": 0.6, "z": -0.95, "offset_u": -0.45}
59
+ ],
60
+ "spheres": [{"radius": 0.35, "s": 0.82, "offset_u": 0.3, "z": -0.65}],
61
+ "noise": {
62
+ "enable": true,
63
+ "amplitude": 0.035,
64
+ "corr_length": 0.5,
65
+ "octaves": 4,
66
+ "gain": 0.55,
67
+ "apply_to": ["trench_walls", "trench_bottom", "pipe*_pipe_side"]
68
+ }
69
+ }
70
+ ```
71
+
72
+ ## CLI quick start
73
+
74
+ ```bash
75
+ trenchfoot-generate --help
76
+ trenchfoot-generate --preview --skip-volumetric --gallery docs/scenario_gallery.md
77
+ trenchfoot-plot packages/trenchfoot/scenarios/S05_wide_slope_pair/trench_scene.obj --open
78
+ ```
79
+
80
+ Set `TRENCHFOOT_SCENARIO_OUT_ROOT=/tmp/trench-previews` (or another writable path) to keep generated assets out of your checkout.
81
+
82
+ ## Python API
83
+
84
+ ```python
85
+ from trenchfoot import scene_spec_from_dict, generate_surface_mesh, generate_trench_volume, gmsh_available
86
+
87
+ spec_dict = {
88
+ "path_xy": [[0.0, 0.0], [5.0, 0.0]],
89
+ "width": 1.0,
90
+ "depth": 1.2,
91
+ "pipes": [{"radius": 0.1, "length": 1.8, "angle_deg": 0.0, "s_center": 0.5}],
92
+ "boxes": [],
93
+ "spheres": [],
94
+ "noise": {"enable": False},
95
+ }
96
+
97
+ scene = scene_spec_from_dict(spec_dict)
98
+ surface = generate_surface_mesh(scene, make_preview=True)
99
+ surface.persist("./surface")
100
+
101
+ if gmsh_available():
102
+ volume = generate_trench_volume(spec_dict, lc=0.4, persist_path="./volume/trench_volume.msh")
103
+ ```
104
+
105
+ `SurfaceMeshResult` keeps per-group faces, metrics, and optional preview PNG bytes; call `.persist(...)` when you need files. `VolumeMeshResult` exposes node coordinates, elements, and physical groups while still letting you stay in memory.
106
+
107
+ ## Testing
108
+
109
+ ```bash
110
+ pytest -rs
111
+ ```
112
+
113
+ The suite exercises each preset (surface + volumetric), the gallery helpers, and the SDK smoke paths.
@@ -0,0 +1,95 @@
1
+ # Trenchfoot
2
+
3
+ Surface and volumetric trench mesh generator with shipped presets, Plotly previews, and a lightweight Python SDK.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install trenchfoot
9
+ ```
10
+
11
+ Want volumetrics or visualisations? Install extras as needed:
12
+ - `pip install "trenchfoot[mesher]"` for gmsh-powered volume meshes.
13
+ - `pip install "trenchfoot[preview]"` for matplotlib snapshot renders.
14
+ - `pip install "trenchfoot[viz]"` for Plotly HTML viewers.
15
+
16
+ ## Scenario Gallery
17
+
18
+ Color key: trench surfaces use warm soil tones; embedded geometry is colour-coded per group.
19
+
20
+ | Scenario | Top | Side | Oblique |
21
+ | --- | --- | --- | --- |
22
+ | S01_straight_vwalls | ![S01 top](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_top.png) | ![S01 side](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_side.png) | ![S01 oblique](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_oblique.png) |
23
+ | S02_straight_slope_pipe | ![S02 top](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_top.png) | ![S02 side](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_side.png) | ![S02 oblique](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_oblique.png) |
24
+ | S03_L_slope_two_pipes_box | ![S03 top](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_top.png) | ![S03 side](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_side.png) | ![S03 oblique](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_oblique.png) |
25
+ | S04_U_slope_multi_noise | ![S04 top](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_top.png) | ![S04 side](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_side.png) | ![S04 oblique](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_oblique.png) |
26
+ | S05_wide_slope_pair | ![S05 top](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_top.png) | ![S05 side](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_side.png) | ![S05 oblique](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_oblique.png) |
27
+ | S06_bumpy_wide_loop | ![S06 top](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_top.png) | ![S06 side](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_side.png) | ![S06 oblique](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_oblique.png) |
28
+
29
+ ### S06 preset at a glance
30
+
31
+ ```json
32
+ {
33
+ "path_xy": [[0, 0], [4, -1], [8, 0], [8, 5], [2, 5], [-1, 2]],
34
+ "width": 2.6,
35
+ "depth": 1.4,
36
+ "wall_slope": 0.12,
37
+ "ground": {"z0": 0.2, "slope": [0.015, 0.03], "size_margin": 7.0},
38
+ "pipes": [
39
+ {"radius": 0.18, "length": 6.0, "angle_deg": 35, "s_center": 0.3, "z": -0.9, "offset_u": 0.35},
40
+ {"radius": 0.14, "length": 4.8, "angle_deg": -40, "s_center": 0.6, "z": -0.95, "offset_u": -0.45}
41
+ ],
42
+ "spheres": [{"radius": 0.35, "s": 0.82, "offset_u": 0.3, "z": -0.65}],
43
+ "noise": {
44
+ "enable": true,
45
+ "amplitude": 0.035,
46
+ "corr_length": 0.5,
47
+ "octaves": 4,
48
+ "gain": 0.55,
49
+ "apply_to": ["trench_walls", "trench_bottom", "pipe*_pipe_side"]
50
+ }
51
+ }
52
+ ```
53
+
54
+ ## CLI quick start
55
+
56
+ ```bash
57
+ trenchfoot-generate --help
58
+ trenchfoot-generate --preview --skip-volumetric --gallery docs/scenario_gallery.md
59
+ trenchfoot-plot packages/trenchfoot/scenarios/S05_wide_slope_pair/trench_scene.obj --open
60
+ ```
61
+
62
+ Set `TRENCHFOOT_SCENARIO_OUT_ROOT=/tmp/trench-previews` (or another writable path) to keep generated assets out of your checkout.
63
+
64
+ ## Python API
65
+
66
+ ```python
67
+ from trenchfoot import scene_spec_from_dict, generate_surface_mesh, generate_trench_volume, gmsh_available
68
+
69
+ spec_dict = {
70
+ "path_xy": [[0.0, 0.0], [5.0, 0.0]],
71
+ "width": 1.0,
72
+ "depth": 1.2,
73
+ "pipes": [{"radius": 0.1, "length": 1.8, "angle_deg": 0.0, "s_center": 0.5}],
74
+ "boxes": [],
75
+ "spheres": [],
76
+ "noise": {"enable": False},
77
+ }
78
+
79
+ scene = scene_spec_from_dict(spec_dict)
80
+ surface = generate_surface_mesh(scene, make_preview=True)
81
+ surface.persist("./surface")
82
+
83
+ if gmsh_available():
84
+ volume = generate_trench_volume(spec_dict, lc=0.4, persist_path="./volume/trench_volume.msh")
85
+ ```
86
+
87
+ `SurfaceMeshResult` keeps per-group faces, metrics, and optional preview PNG bytes; call `.persist(...)` when you need files. `VolumeMeshResult` exposes node coordinates, elements, and physical groups while still letting you stay in memory.
88
+
89
+ ## Testing
90
+
91
+ ```bash
92
+ pytest -rs
93
+ ```
94
+
95
+ The suite exercises each preset (surface + volumetric), the gallery helpers, and the SDK smoke paths.
@@ -442,10 +442,15 @@ def generate_trench_volume(
442
442
  for dim, tag in gmsh.model.getPhysicalGroups():
443
443
  name = gmsh.model.getPhysicalName(dim, tag) or f"dim{dim}_tag{tag}"
444
444
  entities = tuple(gmsh.model.getEntitiesForPhysicalGroup(dim, tag))
445
- pg_types, pg_elem_tags = gmsh.model.mesh.getElementsForPhysicalGroup(dim, tag)
445
+ elem_accum: Dict[int, List[int]] = {}
446
+ for entity_tag in entities:
447
+ et_types, et_elem_tags, _ = gmsh.model.mesh.getElements(dim, entity_tag)
448
+ for etype, tags in zip(et_types, et_elem_tags):
449
+ bucket = elem_accum.setdefault(int(etype), [])
450
+ bucket.extend(int(t) for t in tags)
446
451
  elements_map: Dict[int, np.ndarray] = {
447
- int(t): np.array(tags, dtype=int)
448
- for t, tags in zip(pg_types, pg_elem_tags)
452
+ etype: np.array(values, dtype=int)
453
+ for etype, values in elem_accum.items()
449
454
  }
450
455
  physical_groups.append(
451
456
  PhysicalGroupInfo(
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "trenchfoot"
7
- version = "0.1.0"
7
+ version = "0.1.1"
8
8
  description = "Synthetic trench scenario generator bundle (surfaces + volumetrics)."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  import sys
3
3
  from pathlib import Path
4
+ from typing import Optional
4
5
 
5
6
  import pytest
6
7
 
@@ -32,6 +33,38 @@ from trenchfoot.trench_scene_generator_v3 import (
32
33
  )
33
34
  import trenchfoot as tf
34
35
 
36
+ _GMSH_RUNTIME_READY: Optional[bool] = None
37
+
38
+
39
+ def _gmsh_runtime_ready() -> bool:
40
+ global _GMSH_RUNTIME_READY
41
+ if _GMSH_RUNTIME_READY is not None:
42
+ return _GMSH_RUNTIME_READY
43
+ try:
44
+ import gmsh # noqa: F401
45
+ except Exception:
46
+ _GMSH_RUNTIME_READY = False
47
+ return False
48
+ try:
49
+ gmsh.initialize()
50
+ except Exception:
51
+ _GMSH_RUNTIME_READY = False
52
+ else:
53
+ _GMSH_RUNTIME_READY = True
54
+ finally:
55
+ try:
56
+ gmsh.finalize()
57
+ except Exception:
58
+ pass
59
+ return _GMSH_RUNTIME_READY
60
+
61
+
62
+ def _require_gmsh_runtime():
63
+ gmsh = pytest.importorskip("gmsh")
64
+ if not _gmsh_runtime_ready():
65
+ pytest.skip("gmsh runtime prerequisites (e.g. libGLU) not available in this environment")
66
+ return gmsh
67
+
35
68
 
36
69
  def _minimal_spec_dict() -> dict:
37
70
  return {
@@ -128,7 +161,7 @@ def test_generate_scenarios_single(tmp_path):
128
161
 
129
162
 
130
163
  def test_volumetric_generation(tmp_path):
131
- gmsh = pytest.importorskip("gmsh")
164
+ gmsh = _require_gmsh_runtime()
132
165
 
133
166
  spec = _minimal_spec_dict()
134
167
  scenario = ScenarioDefinition(name="volume_case", spec=spec)
@@ -172,7 +205,7 @@ def test_volumetric_generation(tmp_path):
172
205
 
173
206
 
174
207
  def test_generate_trench_volume_in_memory(tmp_path):
175
- gmsh = pytest.importorskip("gmsh")
208
+ gmsh = _require_gmsh_runtime()
176
209
 
177
210
  spec = _minimal_spec_dict()
178
211
  result = tf.generate_trench_volume(spec, lc=0.4, persist_path=tmp_path / "volume.msh")
@@ -189,7 +222,7 @@ def test_generate_trench_volume_in_memory(tmp_path):
189
222
 
190
223
 
191
224
  def test_default_scenarios_volumetric(tmp_path):
192
- gmsh = pytest.importorskip("gmsh")
225
+ gmsh = _require_gmsh_runtime()
193
226
 
194
227
  scenarios = default_scenarios()
195
228
  report = generate_scenarios(
@@ -501,7 +501,7 @@ wheels = [
501
501
 
502
502
  [[package]]
503
503
  name = "trenchfoot"
504
- version = "0.1.0"
504
+ version = "0.1.1"
505
505
  source = { editable = "." }
506
506
  dependencies = [
507
507
  { name = "numpy" },
trenchfoot-0.1.0/.env DELETED
@@ -1 +0,0 @@
1
- PYPI_API_TOKEN=pypi-AgEIcHlwaS5vcmcCJGM5YWI2NWY2LTkyNWYtNDJhYS04MmJlLTgyMTI4ZmYxNDEzNgACKlszLCJiYTQ1Nzc2Ni01MDg0LTQ4ZmYtOGU5Yi05MjY4NjM3MTNiY2EiXQAABiD0c_I94VDqESwcYib8Gk61QcbLXW_GSVoUTohbfzHrQw
trenchfoot-0.1.0/PKG-INFO DELETED
@@ -1,104 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: trenchfoot
3
- Version: 0.1.0
4
- Summary: Synthetic trench scenario generator bundle (surfaces + volumetrics).
5
- Author: Liam Moore
6
- License-File: LICENSE
7
- Requires-Python: >=3.12
8
- Requires-Dist: numpy>=1.26
9
- Provides-Extra: dev
10
- Requires-Dist: pytest>=8.3; extra == 'dev'
11
- Provides-Extra: mesher
12
- Requires-Dist: gmsh>=4.11; extra == 'mesher'
13
- Provides-Extra: preview
14
- Requires-Dist: matplotlib>=3.8; extra == 'preview'
15
- Provides-Extra: viz
16
- Requires-Dist: plotly>=5.24; extra == 'viz'
17
- Description-Content-Type: text/markdown
18
-
19
- # Trenchfoot
20
-
21
- Synthetic trench scenario generator extracted from the Survi monorepo. This repository bundles
22
- surface + volumetric scene generation tooling and prebuilt scenarios.
23
-
24
- ## Layout
25
- - `packages/trenchfoot/`: the generator bundle (surface CLI, Gmsh mesher, scenario specs, Dockerfile).
26
- - `packages/trenchfoot/scenarios/`: prebuilt scenes (OBJ meshes, previews, metrics).
27
-
28
- ## Getting Started
29
- ```bash
30
- uv sync
31
- uv run python -m trenchfoot.generate_scenarios --help
32
- ```
33
-
34
- Optional extras:
35
- - Install `gmsh` and `meshio` to emit volumetric meshes.
36
- - Install `matplotlib` to refresh preview renders.
37
- - Set `TRENCHFOOT_SCENARIO_OUT_ROOT=/tmp/trench-previews` (or another writable path) to keep generated assets out of the repo checkout; the CLI uses this location unless `--out` is specified.
38
- - Install `plotly` via `pip install "trenchfoot[viz]"` to enable Plotly HTML meshes.
39
- - Use `uv run python -m trenchfoot.generate_scenarios --preview --gallery docs/scenario_gallery.md` to regenerate previews and emit a Markdown gallery (the README table below was generated this way).
40
-
41
- See `packages/trenchfoot/README.md` for the original usage notes and the CLI examples.
42
-
43
- ### CLI Shortcuts
44
- - `uv run python -m trenchfoot.generate_scenarios --scratch --skip-volumetric` runs the generator in a temporary directory (no repo churn) and prints the scratch path.
45
- - Add `--include-prebuilt` if you want the shipped assets copied into the scratch directory before regeneration.
46
- - Combine `--preview` with `--gallery docs/scenario_gallery.md` to refresh previews and the Markdown gallery in one go.
47
- - `trenchfoot-plot packages/trenchfoot/scenarios/S05_wide_slope_pair/trench_scene.obj --open` writes an interactive Plotly HTML (requires the `[viz]` extra) and opens it in your browser.
48
-
49
- ## Python API
50
-
51
- Trenchfoot now exposes a light-weight SDK so you can work entirely in memory:
52
-
53
- ```python
54
- from trenchfoot import (
55
- SceneSpec,
56
- scene_spec_from_dict,
57
- generate_surface_mesh,
58
- generate_trench_volume,
59
- gmsh_available,
60
- )
61
-
62
- spec_dict = {
63
- "path_xy": [[0.0, 0.0], [5.0, 0.0]],
64
- "width": 1.0,
65
- "depth": 1.2,
66
- "wall_slope": 0.1,
67
- "ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin": 2.0},
68
- "pipes": [{"radius": 0.1, "length": 1.8, "angle_deg": 0.0, "s_center": 0.5}],
69
- "boxes": [],
70
- "spheres": [],
71
- "noise": {"enable": False},
72
- }
73
-
74
- scene = scene_spec_from_dict(spec_dict)
75
- surface = generate_surface_mesh(scene)
76
- print(surface.metrics["surface_area_by_group"]["trench_walls"])
77
- surface.persist("./tmp/surface", include_previews=False)
78
-
79
- if gmsh_available():
80
- volume = generate_trench_volume(spec_dict, lc=0.4, persist_path="./tmp/volume/trench_volume.msh")
81
- print(len(volume.element_blocks), "element blocks", "across", volume.nodes.shape[0], "nodes")
82
- ```
83
-
84
- `SurfaceMeshResult` keeps the per-group vertex/face arrays, metrics, and optional preview PNGs (as bytes). Call `.persist(path)` when you want OBJ + metrics written to disk. `VolumeMeshResult` exposes the raw node coordinates, element connectivity, and the discovered physical groups while still letting you emit `.msh` files on demand.
85
-
86
- ## Mesh Clearance Guard Rails
87
- The volumetric mesher enforces a minimum 50 mm gap between the trench walls and any embedded geometry, scaling the threshold with each pipe’s radius and the current wall slope. When clearance gets tight, the generator shortens the pipe run and records per-pipe margins in `SUMMARY.json` under `pipe_clearances` so you can spot scenarios that are at risk before Gmsh complains.
88
-
89
- ## Scenario Gallery
90
- Color key: trench surfaces use warm soil tones, embedded geometry is color-coded per object (pipes in rotating palette, boxes teal/olive, spheres magenta/gray).
91
- | Scenario | Top | Side | Oblique |
92
- | --- | --- | --- | --- |
93
- | S01_straight_vwalls | ![S01 top](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_top.png) | ![S01 side](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_side.png) | ![S01 oblique](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_oblique.png) |
94
- | S02_straight_slope_pipe | ![S02 top](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_top.png) | ![S02 side](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_side.png) | ![S02 oblique](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_oblique.png) |
95
- | S03_L_slope_two_pipes_box | ![S03 top](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_top.png) | ![S03 side](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_side.png) | ![S03 oblique](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_oblique.png) |
96
- | S04_U_slope_multi_noise | ![S04 top](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_top.png) | ![S04 side](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_side.png) | ![S04 oblique](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_oblique.png) |
97
- | S05_wide_slope_pair | ![S05 top](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_top.png) | ![S05 side](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_side.png) | ![S05 oblique](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_oblique.png) |
98
- | S06_bumpy_wide_loop | ![S06 top](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_top.png) | ![S06 side](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_side.png) | ![S06 oblique](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_oblique.png) |
99
-
100
- ## Testing
101
- ```bash
102
- uv run pytest -rs
103
- ```
104
- The test suite exercises the single-scenario code path, runs all bundled presets (surface + volumetric) into a scratch directory, and checks that the CLI honours `TRENCHFOOT_SCENARIO_OUT_ROOT`.
@@ -1,86 +0,0 @@
1
- # Trenchfoot
2
-
3
- Synthetic trench scenario generator extracted from the Survi monorepo. This repository bundles
4
- surface + volumetric scene generation tooling and prebuilt scenarios.
5
-
6
- ## Layout
7
- - `packages/trenchfoot/`: the generator bundle (surface CLI, Gmsh mesher, scenario specs, Dockerfile).
8
- - `packages/trenchfoot/scenarios/`: prebuilt scenes (OBJ meshes, previews, metrics).
9
-
10
- ## Getting Started
11
- ```bash
12
- uv sync
13
- uv run python -m trenchfoot.generate_scenarios --help
14
- ```
15
-
16
- Optional extras:
17
- - Install `gmsh` and `meshio` to emit volumetric meshes.
18
- - Install `matplotlib` to refresh preview renders.
19
- - Set `TRENCHFOOT_SCENARIO_OUT_ROOT=/tmp/trench-previews` (or another writable path) to keep generated assets out of the repo checkout; the CLI uses this location unless `--out` is specified.
20
- - Install `plotly` via `pip install "trenchfoot[viz]"` to enable Plotly HTML meshes.
21
- - Use `uv run python -m trenchfoot.generate_scenarios --preview --gallery docs/scenario_gallery.md` to regenerate previews and emit a Markdown gallery (the README table below was generated this way).
22
-
23
- See `packages/trenchfoot/README.md` for the original usage notes and the CLI examples.
24
-
25
- ### CLI Shortcuts
26
- - `uv run python -m trenchfoot.generate_scenarios --scratch --skip-volumetric` runs the generator in a temporary directory (no repo churn) and prints the scratch path.
27
- - Add `--include-prebuilt` if you want the shipped assets copied into the scratch directory before regeneration.
28
- - Combine `--preview` with `--gallery docs/scenario_gallery.md` to refresh previews and the Markdown gallery in one go.
29
- - `trenchfoot-plot packages/trenchfoot/scenarios/S05_wide_slope_pair/trench_scene.obj --open` writes an interactive Plotly HTML (requires the `[viz]` extra) and opens it in your browser.
30
-
31
- ## Python API
32
-
33
- Trenchfoot now exposes a light-weight SDK so you can work entirely in memory:
34
-
35
- ```python
36
- from trenchfoot import (
37
- SceneSpec,
38
- scene_spec_from_dict,
39
- generate_surface_mesh,
40
- generate_trench_volume,
41
- gmsh_available,
42
- )
43
-
44
- spec_dict = {
45
- "path_xy": [[0.0, 0.0], [5.0, 0.0]],
46
- "width": 1.0,
47
- "depth": 1.2,
48
- "wall_slope": 0.1,
49
- "ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin": 2.0},
50
- "pipes": [{"radius": 0.1, "length": 1.8, "angle_deg": 0.0, "s_center": 0.5}],
51
- "boxes": [],
52
- "spheres": [],
53
- "noise": {"enable": False},
54
- }
55
-
56
- scene = scene_spec_from_dict(spec_dict)
57
- surface = generate_surface_mesh(scene)
58
- print(surface.metrics["surface_area_by_group"]["trench_walls"])
59
- surface.persist("./tmp/surface", include_previews=False)
60
-
61
- if gmsh_available():
62
- volume = generate_trench_volume(spec_dict, lc=0.4, persist_path="./tmp/volume/trench_volume.msh")
63
- print(len(volume.element_blocks), "element blocks", "across", volume.nodes.shape[0], "nodes")
64
- ```
65
-
66
- `SurfaceMeshResult` keeps the per-group vertex/face arrays, metrics, and optional preview PNGs (as bytes). Call `.persist(path)` when you want OBJ + metrics written to disk. `VolumeMeshResult` exposes the raw node coordinates, element connectivity, and the discovered physical groups while still letting you emit `.msh` files on demand.
67
-
68
- ## Mesh Clearance Guard Rails
69
- The volumetric mesher enforces a minimum 50 mm gap between the trench walls and any embedded geometry, scaling the threshold with each pipe’s radius and the current wall slope. When clearance gets tight, the generator shortens the pipe run and records per-pipe margins in `SUMMARY.json` under `pipe_clearances` so you can spot scenarios that are at risk before Gmsh complains.
70
-
71
- ## Scenario Gallery
72
- Color key: trench surfaces use warm soil tones, embedded geometry is color-coded per object (pipes in rotating palette, boxes teal/olive, spheres magenta/gray).
73
- | Scenario | Top | Side | Oblique |
74
- | --- | --- | --- | --- |
75
- | S01_straight_vwalls | ![S01 top](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_top.png) | ![S01 side](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_side.png) | ![S01 oblique](packages/trenchfoot/scenarios/S01_straight_vwalls/preview_oblique.png) |
76
- | S02_straight_slope_pipe | ![S02 top](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_top.png) | ![S02 side](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_side.png) | ![S02 oblique](packages/trenchfoot/scenarios/S02_straight_slope_pipe/preview_oblique.png) |
77
- | S03_L_slope_two_pipes_box | ![S03 top](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_top.png) | ![S03 side](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_side.png) | ![S03 oblique](packages/trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_oblique.png) |
78
- | S04_U_slope_multi_noise | ![S04 top](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_top.png) | ![S04 side](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_side.png) | ![S04 oblique](packages/trenchfoot/scenarios/S04_U_slope_multi_noise/preview_oblique.png) |
79
- | S05_wide_slope_pair | ![S05 top](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_top.png) | ![S05 side](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_side.png) | ![S05 oblique](packages/trenchfoot/scenarios/S05_wide_slope_pair/preview_oblique.png) |
80
- | S06_bumpy_wide_loop | ![S06 top](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_top.png) | ![S06 side](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_side.png) | ![S06 oblique](packages/trenchfoot/scenarios/S06_bumpy_wide_loop/preview_oblique.png) |
81
-
82
- ## Testing
83
- ```bash
84
- uv run pytest -rs
85
- ```
86
- The test suite exercises the single-scenario code path, runs all bundled presets (surface + volumetric) into a scratch directory, and checks that the CLI honours `TRENCHFOOT_SCENARIO_OUT_ROOT`.
File without changes
File without changes
File without changes