trenchfoot 0.1.1__py3-none-any.whl → 0.2.2__py3-none-any.whl
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.
- trenchfoot/generate_scenarios.py +104 -27
- trenchfoot/gmsh_sloped_trench_mesher.py +125 -25
- trenchfoot/scenarios/S01_straight_vwalls/metrics.json +4 -4
- trenchfoot/scenarios/S01_straight_vwalls/preview_oblique.png +0 -0
- trenchfoot/scenarios/S01_straight_vwalls/preview_side.png +0 -0
- trenchfoot/scenarios/S01_straight_vwalls/preview_top.png +0 -0
- trenchfoot/scenarios/S01_straight_vwalls/scene.json +2 -2
- trenchfoot/scenarios/S01_straight_vwalls/trench_scene.obj +30 -27
- trenchfoot/scenarios/S01_straight_vwalls/volumetric/trench_volume.msh +540 -802
- trenchfoot/scenarios/S02_straight_slope_pipe/metrics.json +10 -10
- trenchfoot/scenarios/S02_straight_slope_pipe/preview_oblique.png +0 -0
- trenchfoot/scenarios/S02_straight_slope_pipe/preview_side.png +0 -0
- trenchfoot/scenarios/S02_straight_slope_pipe/preview_top.png +0 -0
- trenchfoot/scenarios/S02_straight_slope_pipe/scene.json +3 -3
- trenchfoot/scenarios/S02_straight_slope_pipe/trench_scene.obj +4977 -4974
- trenchfoot/scenarios/S02_straight_slope_pipe/volumetric/trench_volume.msh +1694 -1969
- trenchfoot/scenarios/S03_L_slope_two_pipes_box/metrics.json +14 -14
- trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_oblique.png +0 -0
- trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_side.png +0 -0
- trenchfoot/scenarios/S03_L_slope_two_pipes_box/preview_top.png +0 -0
- trenchfoot/scenarios/S03_L_slope_two_pipes_box/scene.json +4 -4
- trenchfoot/scenarios/S03_L_slope_two_pipes_box/trench_scene.obj +10547 -10540
- trenchfoot/scenarios/S03_L_slope_two_pipes_box/volumetric/trench_volume.msh +3101 -3767
- trenchfoot/scenarios/S04_U_slope_multi_noise/metrics.json +17 -17
- trenchfoot/scenarios/S04_U_slope_multi_noise/preview_oblique.png +0 -0
- trenchfoot/scenarios/S04_U_slope_multi_noise/preview_side.png +0 -0
- trenchfoot/scenarios/S04_U_slope_multi_noise/preview_top.png +0 -0
- trenchfoot/scenarios/S04_U_slope_multi_noise/scene.json +8 -7
- trenchfoot/scenarios/S04_U_slope_multi_noise/trench_scene.obj +17999 -17988
- trenchfoot/scenarios/S04_U_slope_multi_noise/volumetric/trench_volume.msh +4991 -6506
- trenchfoot/scenarios/S05_wide_slope_pair/metrics.json +14 -14
- trenchfoot/scenarios/S05_wide_slope_pair/preview_oblique.png +0 -0
- trenchfoot/scenarios/S05_wide_slope_pair/preview_side.png +0 -0
- trenchfoot/scenarios/S05_wide_slope_pair/preview_top.png +0 -0
- trenchfoot/scenarios/S05_wide_slope_pair/scene.json +6 -6
- trenchfoot/scenarios/S05_wide_slope_pair/trench_scene.obj +10547 -10540
- trenchfoot/scenarios/S05_wide_slope_pair/volumetric/trench_volume.msh +5081 -0
- trenchfoot/scenarios/S06_bumpy_wide_loop/metrics.json +16 -16
- trenchfoot/scenarios/S06_bumpy_wide_loop/preview_oblique.png +0 -0
- trenchfoot/scenarios/S06_bumpy_wide_loop/preview_side.png +0 -0
- trenchfoot/scenarios/S06_bumpy_wide_loop/preview_top.png +0 -0
- trenchfoot/scenarios/S06_bumpy_wide_loop/scene.json +6 -6
- trenchfoot/scenarios/S06_bumpy_wide_loop/trench_scene.obj +12812 -12793
- trenchfoot/scenarios/S06_bumpy_wide_loop/volumetric/trench_volume.msh +10402 -0
- trenchfoot/scenarios/S07_circular_well/metrics.json +48 -0
- trenchfoot/scenarios/S07_circular_well/preview_oblique.png +0 -0
- trenchfoot/scenarios/S07_circular_well/preview_side.png +0 -0
- trenchfoot/scenarios/S07_circular_well/preview_top.png +0 -0
- trenchfoot/scenarios/S07_circular_well/scene.json +203 -0
- trenchfoot/scenarios/S07_circular_well/trench_scene.obj +64401 -0
- trenchfoot/scenarios/S07_circular_well/volumetric/trench_volume.msh +22370 -0
- trenchfoot/scenarios/SUMMARY.json +343 -32
- trenchfoot/trench_scene_generator_v3.py +323 -46
- {trenchfoot-0.1.1.dist-info → trenchfoot-0.2.2.dist-info}/METADATA +16 -18
- {trenchfoot-0.1.1.dist-info → trenchfoot-0.2.2.dist-info}/RECORD +58 -49
- {trenchfoot-0.1.1.dist-info → trenchfoot-0.2.2.dist-info}/WHEEL +1 -1
- {trenchfoot-0.1.1.dist-info → trenchfoot-0.2.2.dist-info}/entry_points.txt +0 -0
- {trenchfoot-0.1.1.dist-info → trenchfoot-0.2.2.dist-info}/licenses/LICENSE +0 -0
trenchfoot/generate_scenarios.py
CHANGED
|
@@ -135,18 +135,35 @@ def gmsh_available() -> bool:
|
|
|
135
135
|
return _gmsh_mesher is not None
|
|
136
136
|
|
|
137
137
|
|
|
138
|
+
def _generate_circular_path(
|
|
139
|
+
center: tuple[float, float], radius: float, n_vertices: int = 32
|
|
140
|
+
) -> List[List[float]]:
|
|
141
|
+
"""Generate vertices for a closed circular polyline.
|
|
142
|
+
|
|
143
|
+
The path is explicitly closed by repeating the first point at the end.
|
|
144
|
+
This ensures proper handling as a closed loop in mesh generation.
|
|
145
|
+
"""
|
|
146
|
+
import math
|
|
147
|
+
cx, cy = center
|
|
148
|
+
angles = [2 * math.pi * i / n_vertices for i in range(n_vertices)]
|
|
149
|
+
points = [[cx + radius * math.cos(a), cy + radius * math.sin(a)] for a in angles]
|
|
150
|
+
# Close the path by repeating the first point
|
|
151
|
+
points.append(points[0].copy())
|
|
152
|
+
return points
|
|
153
|
+
|
|
154
|
+
|
|
138
155
|
def default_scenarios() -> List[ScenarioDefinition]:
|
|
139
|
-
"""Built-in scenario presets."""
|
|
156
|
+
"""Built-in scenario presets with shallower depths and offset polygon ground."""
|
|
140
157
|
return [
|
|
141
158
|
ScenarioDefinition(
|
|
142
159
|
"S01_straight_vwalls",
|
|
143
160
|
{
|
|
144
161
|
"path_xy": [[0, 0], [5, 0]],
|
|
145
162
|
"width": 1.0,
|
|
146
|
-
"depth":
|
|
163
|
+
"depth": 0.6,
|
|
147
164
|
"wall_slope": 0.0,
|
|
148
165
|
"ground_margin": 0.5,
|
|
149
|
-
"ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin":
|
|
166
|
+
"ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin": 1.0},
|
|
150
167
|
"pipes": [],
|
|
151
168
|
"boxes": [],
|
|
152
169
|
"spheres": [],
|
|
@@ -158,17 +175,17 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
158
175
|
{
|
|
159
176
|
"path_xy": [[0, 0], [6, 0]],
|
|
160
177
|
"width": 1.2,
|
|
161
|
-
"depth":
|
|
178
|
+
"depth": 0.9,
|
|
162
179
|
"wall_slope": 0.2,
|
|
163
180
|
"ground_margin": 0.5,
|
|
164
|
-
"ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin":
|
|
181
|
+
"ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin": 1.0},
|
|
165
182
|
"pipes": [
|
|
166
183
|
{
|
|
167
184
|
"radius": 0.15,
|
|
168
185
|
"length": 7.0,
|
|
169
186
|
"angle_deg": 0,
|
|
170
187
|
"s_center": 0.5,
|
|
171
|
-
"z": -0.
|
|
188
|
+
"z": -0.45,
|
|
172
189
|
"offset_u": 0.0,
|
|
173
190
|
}
|
|
174
191
|
],
|
|
@@ -182,17 +199,17 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
182
199
|
{
|
|
183
200
|
"path_xy": [[0, 0], [6, 0], [6, 4]],
|
|
184
201
|
"width": 1.2,
|
|
185
|
-
"depth": 1.
|
|
202
|
+
"depth": 1.1,
|
|
186
203
|
"wall_slope": 0.15,
|
|
187
204
|
"ground_margin": 1.0,
|
|
188
|
-
"ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin":
|
|
205
|
+
"ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin": 1.2},
|
|
189
206
|
"pipes": [
|
|
190
207
|
{
|
|
191
208
|
"radius": 0.15,
|
|
192
209
|
"length": 8.0,
|
|
193
210
|
"angle_deg": 0,
|
|
194
211
|
"s_center": 0.35,
|
|
195
|
-
"z": -
|
|
212
|
+
"z": -0.6,
|
|
196
213
|
"offset_u": 0.0,
|
|
197
214
|
},
|
|
198
215
|
{
|
|
@@ -200,7 +217,7 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
200
217
|
"length": 5.0,
|
|
201
218
|
"angle_deg": 90,
|
|
202
219
|
"s_center": 0.75,
|
|
203
|
-
"z": -0.
|
|
220
|
+
"z": -0.55,
|
|
204
221
|
"offset_u": 0.2,
|
|
205
222
|
},
|
|
206
223
|
],
|
|
@@ -230,17 +247,17 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
230
247
|
{
|
|
231
248
|
"path_xy": [[0, 0], [6, 0], [6, 4], [0, 4]],
|
|
232
249
|
"width": 1.4,
|
|
233
|
-
"depth": 2
|
|
250
|
+
"depth": 1.2,
|
|
234
251
|
"wall_slope": 0.25,
|
|
235
252
|
"ground_margin": 1.2,
|
|
236
|
-
"ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin": 5
|
|
253
|
+
"ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin": 1.5},
|
|
237
254
|
"pipes": [
|
|
238
255
|
{
|
|
239
256
|
"radius": 0.18,
|
|
240
257
|
"length": 9.0,
|
|
241
258
|
"angle_deg": 0,
|
|
242
259
|
"s_center": 0.25,
|
|
243
|
-
"z": -
|
|
260
|
+
"z": -0.6,
|
|
244
261
|
"offset_u": 0.0,
|
|
245
262
|
},
|
|
246
263
|
{
|
|
@@ -248,7 +265,7 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
248
265
|
"length": 5.0,
|
|
249
266
|
"angle_deg": 45,
|
|
250
267
|
"s_center": 0.55,
|
|
251
|
-
"z": -
|
|
268
|
+
"z": -0.65,
|
|
252
269
|
"offset_u": -0.2,
|
|
253
270
|
},
|
|
254
271
|
{
|
|
@@ -256,12 +273,12 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
256
273
|
"length": 3.5,
|
|
257
274
|
"angle_deg": -60,
|
|
258
275
|
"s_center": 0.75,
|
|
259
|
-
"z": -
|
|
276
|
+
"z": -0.8,
|
|
260
277
|
"offset_u": 0.25,
|
|
261
278
|
},
|
|
262
279
|
],
|
|
263
280
|
"boxes": [],
|
|
264
|
-
"spheres": [{"radius": 0.
|
|
281
|
+
"spheres": [{"radius": 0.25, "s": 0.85, "offset_u": -0.2, "z": -0.7}],
|
|
265
282
|
"noise": {
|
|
266
283
|
"enable": True,
|
|
267
284
|
"amplitude": 0.02,
|
|
@@ -278,17 +295,17 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
278
295
|
{
|
|
279
296
|
"path_xy": [[0, 0], [9, 0], [9, 3]],
|
|
280
297
|
"width": 2.4,
|
|
281
|
-
"depth":
|
|
298
|
+
"depth": 0.7,
|
|
282
299
|
"wall_slope": 0.08,
|
|
283
300
|
"ground_margin": 1.5,
|
|
284
|
-
"ground": {"z0": 0.0, "slope": [0.02, -0.015], "size_margin":
|
|
301
|
+
"ground": {"z0": 0.0, "slope": [0.02, -0.015], "size_margin": 1.5},
|
|
285
302
|
"pipes": [
|
|
286
303
|
{
|
|
287
304
|
"radius": 0.2,
|
|
288
305
|
"length": 5.5,
|
|
289
306
|
"angle_deg": 10,
|
|
290
307
|
"s_center": 0.35,
|
|
291
|
-
"z": -0.
|
|
308
|
+
"z": -0.4,
|
|
292
309
|
"offset_u": 0.3,
|
|
293
310
|
"clearance_scale": 0.9,
|
|
294
311
|
},
|
|
@@ -297,7 +314,7 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
297
314
|
"length": 4.2,
|
|
298
315
|
"angle_deg": -15,
|
|
299
316
|
"s_center": 0.7,
|
|
300
|
-
"z": -0.
|
|
317
|
+
"z": -0.45,
|
|
301
318
|
"offset_u": -0.4,
|
|
302
319
|
"clearance_scale": 1.1,
|
|
303
320
|
},
|
|
@@ -306,10 +323,10 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
306
323
|
{
|
|
307
324
|
"along": 1.2,
|
|
308
325
|
"across": 0.9,
|
|
309
|
-
"height": 0.
|
|
326
|
+
"height": 0.35,
|
|
310
327
|
"s": 0.55,
|
|
311
328
|
"offset_u": -0.25,
|
|
312
|
-
"z": -0.
|
|
329
|
+
"z": -0.35,
|
|
313
330
|
}
|
|
314
331
|
],
|
|
315
332
|
"spheres": [],
|
|
@@ -329,17 +346,17 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
329
346
|
{
|
|
330
347
|
"path_xy": [[0, 0], [4, -1], [8, 0], [8, 5], [2, 5], [-1, 2]],
|
|
331
348
|
"width": 2.6,
|
|
332
|
-
"depth":
|
|
349
|
+
"depth": 0.85,
|
|
333
350
|
"wall_slope": 0.12,
|
|
334
351
|
"ground_margin": 2.0,
|
|
335
|
-
"ground": {"z0": 0.2, "slope": [0.015, 0.03], "size_margin":
|
|
352
|
+
"ground": {"z0": 0.2, "slope": [0.015, 0.03], "size_margin": 1.8},
|
|
336
353
|
"pipes": [
|
|
337
354
|
{
|
|
338
355
|
"radius": 0.18,
|
|
339
356
|
"length": 6.0,
|
|
340
357
|
"angle_deg": 35,
|
|
341
358
|
"s_center": 0.3,
|
|
342
|
-
"z": -0.
|
|
359
|
+
"z": -0.55,
|
|
343
360
|
"offset_u": 0.35,
|
|
344
361
|
"clearance_scale": 1.0,
|
|
345
362
|
},
|
|
@@ -348,14 +365,14 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
348
365
|
"length": 4.8,
|
|
349
366
|
"angle_deg": -40,
|
|
350
367
|
"s_center": 0.6,
|
|
351
|
-
"z": -0.
|
|
368
|
+
"z": -0.6,
|
|
352
369
|
"offset_u": -0.45,
|
|
353
370
|
"clearance_scale": 0.85,
|
|
354
371
|
},
|
|
355
372
|
],
|
|
356
373
|
"boxes": [],
|
|
357
374
|
"spheres": [
|
|
358
|
-
{"radius": 0.
|
|
375
|
+
{"radius": 0.3, "s": 0.82, "offset_u": 0.3, "z": -0.4}
|
|
359
376
|
],
|
|
360
377
|
"noise": {
|
|
361
378
|
"enable": True,
|
|
@@ -368,6 +385,66 @@ def default_scenarios() -> List[ScenarioDefinition]:
|
|
|
368
385
|
},
|
|
369
386
|
},
|
|
370
387
|
),
|
|
388
|
+
ScenarioDefinition(
|
|
389
|
+
"S07_circular_well",
|
|
390
|
+
{
|
|
391
|
+
"path_xy": _generate_circular_path((0.0, 0.0), radius=1.5, n_vertices=32),
|
|
392
|
+
"width": 2.0,
|
|
393
|
+
"depth": 2.5,
|
|
394
|
+
"wall_slope": 0.05,
|
|
395
|
+
"ground_margin": 1.0,
|
|
396
|
+
"ground": {"z0": 0.0, "slope": [0.0, 0.0], "size_margin": 2.0},
|
|
397
|
+
"pipes": [
|
|
398
|
+
# Upper pipe - large diameter, horizontal
|
|
399
|
+
{
|
|
400
|
+
"radius": 0.20,
|
|
401
|
+
"length": 4.0,
|
|
402
|
+
"angle_deg": 0,
|
|
403
|
+
"s_center": 0.25,
|
|
404
|
+
"z": -0.5,
|
|
405
|
+
"offset_u": 0.0,
|
|
406
|
+
},
|
|
407
|
+
# Middle pipe - medium, angled
|
|
408
|
+
{
|
|
409
|
+
"radius": 0.15,
|
|
410
|
+
"length": 3.5,
|
|
411
|
+
"angle_deg": 45,
|
|
412
|
+
"s_center": 0.5,
|
|
413
|
+
"z": -1.2,
|
|
414
|
+
"offset_u": 0.1,
|
|
415
|
+
},
|
|
416
|
+
# Lower pipe - small, opposite angle
|
|
417
|
+
{
|
|
418
|
+
"radius": 0.10,
|
|
419
|
+
"length": 3.0,
|
|
420
|
+
"angle_deg": -60,
|
|
421
|
+
"s_center": 0.75,
|
|
422
|
+
"z": -1.8,
|
|
423
|
+
"offset_u": -0.15,
|
|
424
|
+
},
|
|
425
|
+
# Deep pipe - crossing at bottom
|
|
426
|
+
{
|
|
427
|
+
"radius": 0.12,
|
|
428
|
+
"length": 3.2,
|
|
429
|
+
"angle_deg": 90,
|
|
430
|
+
"s_center": 0.0,
|
|
431
|
+
"z": -2.2,
|
|
432
|
+
"offset_u": 0.0,
|
|
433
|
+
},
|
|
434
|
+
],
|
|
435
|
+
"boxes": [],
|
|
436
|
+
"spheres": [{"radius": 0.25, "s": 0.4, "offset_u": 0.0, "z": -1.5}],
|
|
437
|
+
"noise": {
|
|
438
|
+
"enable": True,
|
|
439
|
+
"amplitude": 0.02,
|
|
440
|
+
"corr_length": 0.4,
|
|
441
|
+
"octaves": 2,
|
|
442
|
+
"gain": 0.5,
|
|
443
|
+
"seed": 37,
|
|
444
|
+
"apply_to": ["trench_walls", "trench_bottom"],
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
),
|
|
371
448
|
]
|
|
372
449
|
|
|
373
450
|
|
|
@@ -48,6 +48,42 @@ def _normalize(v):
|
|
|
48
48
|
|
|
49
49
|
def _rotate_ccw(v): return np.array([-v[1], v[0]], float)
|
|
50
50
|
|
|
51
|
+
def _is_path_closed(path, threshold=0.01):
|
|
52
|
+
"""Detect if path is explicitly closed (first and last points nearly identical)."""
|
|
53
|
+
if len(path) < 3:
|
|
54
|
+
return False
|
|
55
|
+
P = np.array(path, float)
|
|
56
|
+
first_last_dist = np.linalg.norm(P[0] - P[-1])
|
|
57
|
+
return first_last_dist < threshold
|
|
58
|
+
|
|
59
|
+
def _offset_closed_polyline(path, offset):
|
|
60
|
+
"""Offset a closed polyline, returning a single closed ring."""
|
|
61
|
+
P = np.array(path, float)
|
|
62
|
+
n = len(P)
|
|
63
|
+
if n < 3:
|
|
64
|
+
raise ValueError("Closed polyline needs at least 3 points")
|
|
65
|
+
tangents = []
|
|
66
|
+
normals = []
|
|
67
|
+
for i in range(n):
|
|
68
|
+
t = _normalize(P[(i+1) % n] - P[i])
|
|
69
|
+
if np.linalg.norm(t) < 1e-12:
|
|
70
|
+
t = np.array([1.0, 0.0])
|
|
71
|
+
tangents.append(t)
|
|
72
|
+
normals.append(np.array([-t[1], t[0]], float))
|
|
73
|
+
offset_pts = []
|
|
74
|
+
for k in range(n):
|
|
75
|
+
t_prev, n_prev = tangents[(k-1) % n], normals[(k-1) % n]
|
|
76
|
+
t_next, n_next = tangents[k], normals[k]
|
|
77
|
+
L1_p = P[k] + offset * n_prev
|
|
78
|
+
L1_d = t_prev
|
|
79
|
+
L2_p = P[k] + offset * n_next
|
|
80
|
+
L2_d = t_next
|
|
81
|
+
pt = _line_intersection_2d(L1_p, L1_d, L2_p, L2_d)
|
|
82
|
+
if pt is None:
|
|
83
|
+
pt = 0.5 * (L1_p + L2_p)
|
|
84
|
+
offset_pts.append(pt)
|
|
85
|
+
return offset_pts
|
|
86
|
+
|
|
51
87
|
def _line_intersection_2d(p, d, q, e):
|
|
52
88
|
M = np.array([d, -e], float).T; det = np.linalg.det(M)
|
|
53
89
|
if abs(det) < 1e-12: return None
|
|
@@ -173,35 +209,99 @@ def generate_trench_volume(
|
|
|
173
209
|
half_top = width_top / 2.0
|
|
174
210
|
half_bot = max(1e-3, half_top - slope * depth)
|
|
175
211
|
|
|
176
|
-
|
|
177
|
-
Lbot, Rbot = _offset_polyline(path_xy, half_bot)
|
|
178
|
-
ring_top = _ring_from_LR(Ltop, Rtop)
|
|
179
|
-
ring_bot = _ring_from_LR(Lbot, Rbot)
|
|
212
|
+
is_closed = _is_path_closed(path_xy)
|
|
180
213
|
|
|
181
|
-
|
|
182
|
-
|
|
214
|
+
if is_closed:
|
|
215
|
+
# For closed paths, create annular (ring-shaped) trench with outer and inner walls
|
|
216
|
+
outer_top = np.array(_offset_closed_polyline(path_xy, half_top), float)
|
|
217
|
+
inner_top = np.array(_offset_closed_polyline(path_xy, -half_top), float)
|
|
218
|
+
outer_bot = np.array(_offset_closed_polyline(path_xy, half_bot), float)
|
|
219
|
+
inner_bot = np.array(_offset_closed_polyline(path_xy, -half_bot), float)
|
|
183
220
|
|
|
184
|
-
|
|
185
|
-
|
|
221
|
+
outer_top_xyz = [(x, y, g(x, y)) for (x, y) in outer_top]
|
|
222
|
+
inner_top_xyz = [(x, y, g(x, y)) for (x, y) in inner_top]
|
|
223
|
+
outer_bot_xyz = [(x, y, g(x, y) - depth) for (x, y) in outer_bot]
|
|
224
|
+
inner_bot_xyz = [(x, y, g(x, y) - depth) for (x, y) in inner_bot]
|
|
186
225
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
226
|
+
# Create outer and inner wire loops at top and bottom
|
|
227
|
+
outer_top_loop = _add_closed_wire_xyz(outer_top_xyz)
|
|
228
|
+
inner_top_loop = _add_closed_wire_xyz(inner_top_xyz)
|
|
229
|
+
outer_bot_loop = _add_closed_wire_xyz(outer_bot_xyz)
|
|
230
|
+
inner_bot_loop = _add_closed_wire_xyz(inner_bot_xyz)
|
|
231
|
+
|
|
232
|
+
# Outer wall: loft from outer_top to outer_bot
|
|
233
|
+
outDimTags_outer = []
|
|
234
|
+
try:
|
|
235
|
+
gmsh.model.occ.addThruSections(
|
|
236
|
+
[outer_top_loop, outer_bot_loop], makeSolid=False, makeRuled=True, outDimTags=outDimTags_outer
|
|
237
|
+
)
|
|
238
|
+
except TypeError:
|
|
239
|
+
outDimTags_outer = gmsh.model.occ.addThruSections(
|
|
240
|
+
[outer_top_loop, outer_bot_loop], makeSolid=False, makeRuled=True
|
|
241
|
+
) or []
|
|
242
|
+
|
|
243
|
+
# Inner wall: loft from inner_top to inner_bot
|
|
244
|
+
outDimTags_inner = []
|
|
245
|
+
try:
|
|
246
|
+
gmsh.model.occ.addThruSections(
|
|
247
|
+
[inner_top_loop, inner_bot_loop], makeSolid=False, makeRuled=True, outDimTags=outDimTags_inner
|
|
248
|
+
)
|
|
249
|
+
except TypeError:
|
|
250
|
+
outDimTags_inner = gmsh.model.occ.addThruSections(
|
|
251
|
+
[inner_top_loop, inner_bot_loop], makeSolid=False, makeRuled=True
|
|
252
|
+
) or []
|
|
253
|
+
|
|
254
|
+
# Create top and bottom surfaces (annular)
|
|
255
|
+
top_surf = gmsh.model.occ.addPlaneSurface([outer_top_loop, inner_top_loop])
|
|
256
|
+
bot_surf = gmsh.model.occ.addPlaneSurface([outer_bot_loop, inner_bot_loop])
|
|
257
|
+
|
|
258
|
+
# Collect all surfaces to form a shell
|
|
259
|
+
all_surfs = [top_surf, bot_surf]
|
|
260
|
+
all_surfs.extend([tag for (dim, tag) in outDimTags_outer if dim == 2])
|
|
261
|
+
all_surfs.extend([tag for (dim, tag) in outDimTags_inner if dim == 2])
|
|
262
|
+
|
|
263
|
+
# Create surface loop and volume
|
|
264
|
+
gmsh.model.occ.synchronize()
|
|
265
|
+
surf_loop = gmsh.model.occ.addSurfaceLoop(all_surfs)
|
|
266
|
+
trench_vol = gmsh.model.occ.addVolume([surf_loop])
|
|
267
|
+
|
|
268
|
+
gmsh.model.occ.healShapes()
|
|
269
|
+
gmsh.model.occ.removeAllDuplicates()
|
|
270
|
+
gmsh.model.occ.synchronize()
|
|
271
|
+
|
|
272
|
+
# Use outer_top for ring_top in clearance calculations
|
|
273
|
+
ring_top = outer_top
|
|
274
|
+
else:
|
|
275
|
+
# Original logic for open paths
|
|
276
|
+
Ltop, Rtop = _offset_polyline(path_xy, half_top)
|
|
277
|
+
Lbot, Rbot = _offset_polyline(path_xy, half_bot)
|
|
278
|
+
ring_top = _ring_from_LR(Ltop, Rtop)
|
|
279
|
+
ring_bot = _ring_from_LR(Lbot, Rbot)
|
|
280
|
+
|
|
281
|
+
ring_top_xyz = [(x, y, g(x, y)) for (x, y) in ring_top]
|
|
282
|
+
ring_bot_xyz = [(x, y, g(x, y) - depth) for (x, y) in ring_bot]
|
|
283
|
+
|
|
284
|
+
top_loop = _add_closed_wire_xyz(ring_top_xyz)
|
|
285
|
+
bot_loop = _add_closed_wire_xyz(ring_bot_xyz)
|
|
286
|
+
|
|
287
|
+
outDimTags = []
|
|
288
|
+
try:
|
|
289
|
+
gmsh.model.occ.addThruSections(
|
|
290
|
+
[top_loop, bot_loop], makeSolid=True, makeRuled=True, outDimTags=outDimTags
|
|
291
|
+
)
|
|
292
|
+
except TypeError: # gmsh >= 4.14 removed outDimTags kwarg
|
|
293
|
+
outDimTags = gmsh.model.occ.addThruSections(
|
|
294
|
+
[top_loop, bot_loop], makeSolid=True, makeRuled=True
|
|
295
|
+
)
|
|
296
|
+
if outDimTags is None:
|
|
297
|
+
outDimTags = []
|
|
298
|
+
gmsh.model.occ.healShapes()
|
|
299
|
+
gmsh.model.occ.removeAllDuplicates()
|
|
300
|
+
gmsh.model.occ.synchronize()
|
|
201
301
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
302
|
+
vols = [tag for (dim, tag) in outDimTags if dim == 3]
|
|
303
|
+
assert len(vols) >= 1, "Loft did not create a volume"
|
|
304
|
+
trench_vol = vols[0]
|
|
205
305
|
|
|
206
306
|
pipe_cfgs = cfg.get("pipes", [])
|
|
207
307
|
cum_lengths, total_length = _polyline_lengths(path_xy)
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"surface_area_by_group": {
|
|
3
3
|
"trench_bottom": 5.0,
|
|
4
4
|
"trench_cap_for_volume": 5.0,
|
|
5
|
-
"trench_walls":
|
|
6
|
-
"ground_surface":
|
|
5
|
+
"trench_walls": 7.2,
|
|
6
|
+
"ground_surface": 10.0
|
|
7
7
|
},
|
|
8
8
|
"closed_surface_sets": {
|
|
9
9
|
"trench_closed_groups": [
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
]
|
|
14
14
|
},
|
|
15
15
|
"volumes": {
|
|
16
|
-
"trench_from_surface": -1.
|
|
17
|
-
"trench_flux_integral_div1": -1.
|
|
16
|
+
"trench_from_surface": -1.0,
|
|
17
|
+
"trench_flux_integral_div1": -1.0
|
|
18
18
|
},
|
|
19
19
|
"footprint_area_top": 5.0,
|
|
20
20
|
"footprint_area_bottom": 5.0,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
]
|
|
11
11
|
],
|
|
12
12
|
"width": 1.0,
|
|
13
|
-
"depth":
|
|
13
|
+
"depth": 0.6,
|
|
14
14
|
"wall_slope": 0.0,
|
|
15
15
|
"ground_margin": 0.5,
|
|
16
16
|
"ground": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
0.0,
|
|
20
20
|
0.0
|
|
21
21
|
],
|
|
22
|
-
"size_margin":
|
|
22
|
+
"size_margin": 1.0
|
|
23
23
|
},
|
|
24
24
|
"pipes": [],
|
|
25
25
|
"boxes": [],
|
|
@@ -1,46 +1,49 @@
|
|
|
1
1
|
g trench_bottom
|
|
2
|
-
v 0 -0.5 -
|
|
3
|
-
v 5 -0.5 -
|
|
4
|
-
v 5 0.5 -
|
|
5
|
-
v 0 0.5 -
|
|
2
|
+
v 0 -0.5 -0.6
|
|
3
|
+
v 5 -0.5 -0.6
|
|
4
|
+
v 5 0.5 -0.6
|
|
5
|
+
v 0 0.5 -0.6
|
|
6
6
|
f 2 1 4
|
|
7
7
|
f 4 3 2
|
|
8
|
-
g trench_cap_for_volume
|
|
9
|
-
v 0 -0.5 0
|
|
10
|
-
v 5 -0.5 0
|
|
11
|
-
v 5 0.5 0
|
|
12
|
-
v 0 0.5 0
|
|
13
|
-
f 8 5 6
|
|
14
|
-
f 6 7 8
|
|
15
8
|
g trench_walls
|
|
16
9
|
v 0 -0.5 0
|
|
17
10
|
v 5 -0.5 0
|
|
18
|
-
v 5 -0.5 -
|
|
19
|
-
v 0 -0.5 -
|
|
11
|
+
v 5 -0.5 -0.6
|
|
12
|
+
v 0 -0.5 -0.6
|
|
20
13
|
v 5 -0.5 0
|
|
21
14
|
v 5 0.5 0
|
|
22
|
-
v 5 0.5 -
|
|
23
|
-
v 5 -0.5 -
|
|
15
|
+
v 5 0.5 -0.6
|
|
16
|
+
v 5 -0.5 -0.6
|
|
24
17
|
v 5 0.5 0
|
|
25
18
|
v 0 0.5 0
|
|
26
|
-
v 0 0.5 -
|
|
27
|
-
v 5 0.5 -
|
|
19
|
+
v 0 0.5 -0.6
|
|
20
|
+
v 5 0.5 -0.6
|
|
28
21
|
v 0 0.5 0
|
|
29
22
|
v 0 -0.5 0
|
|
30
|
-
v 0 -0.5 -
|
|
31
|
-
v 0 0.5 -
|
|
23
|
+
v 0 -0.5 -0.6
|
|
24
|
+
v 0 0.5 -0.6
|
|
25
|
+
f 5 6 7
|
|
26
|
+
f 5 7 8
|
|
32
27
|
f 9 10 11
|
|
33
28
|
f 9 11 12
|
|
34
29
|
f 13 14 15
|
|
35
30
|
f 13 15 16
|
|
36
31
|
f 17 18 19
|
|
37
32
|
f 17 19 20
|
|
38
|
-
f 21 22 23
|
|
39
|
-
f 21 23 24
|
|
40
33
|
g ground_surface
|
|
41
|
-
v
|
|
42
|
-
v
|
|
43
|
-
v
|
|
44
|
-
v
|
|
45
|
-
|
|
46
|
-
|
|
34
|
+
v 0 -1.5 0
|
|
35
|
+
v 5 -1.5 0
|
|
36
|
+
v 5 1.5 0
|
|
37
|
+
v 0 1.5 0
|
|
38
|
+
v 0 -0.5 0
|
|
39
|
+
v 5 -0.5 0
|
|
40
|
+
v 5 0.5 0
|
|
41
|
+
v 0 0.5 0
|
|
42
|
+
f 21 22 25
|
|
43
|
+
f 22 26 25
|
|
44
|
+
f 22 23 26
|
|
45
|
+
f 23 27 26
|
|
46
|
+
f 23 24 27
|
|
47
|
+
f 24 28 27
|
|
48
|
+
f 24 21 28
|
|
49
|
+
f 21 25 28
|