capytaine 2.3__cp39-cp39-macosx_14_0_arm64.whl → 3.0.0a1__cp39-cp39-macosx_14_0_arm64.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.
Files changed (86) hide show
  1. capytaine/.dylibs/libgcc_s.1.1.dylib +0 -0
  2. capytaine/.dylibs/libgfortran.5.dylib +0 -0
  3. capytaine/.dylibs/libquadmath.0.dylib +0 -0
  4. capytaine/__about__.py +7 -2
  5. capytaine/__init__.py +8 -12
  6. capytaine/bem/engines.py +234 -354
  7. capytaine/bem/problems_and_results.py +30 -21
  8. capytaine/bem/solver.py +205 -81
  9. capytaine/bodies/bodies.py +279 -862
  10. capytaine/bodies/dofs.py +136 -9
  11. capytaine/bodies/hydrostatics.py +540 -0
  12. capytaine/bodies/multibodies.py +216 -0
  13. capytaine/green_functions/{libs/Delhommeau_float32.cpython-39-darwin.so → Delhommeau_float32.cpython-39-darwin.so} +0 -0
  14. capytaine/green_functions/{libs/Delhommeau_float64.cpython-39-darwin.so → Delhommeau_float64.cpython-39-darwin.so} +0 -0
  15. capytaine/green_functions/abstract_green_function.py +2 -2
  16. capytaine/green_functions/delhommeau.py +50 -31
  17. capytaine/green_functions/hams.py +19 -13
  18. capytaine/io/legacy.py +3 -103
  19. capytaine/io/xarray.py +15 -10
  20. capytaine/meshes/__init__.py +2 -6
  21. capytaine/meshes/abstract_meshes.py +375 -0
  22. capytaine/meshes/clean.py +302 -0
  23. capytaine/meshes/clip.py +347 -0
  24. capytaine/meshes/export.py +89 -0
  25. capytaine/meshes/geometry.py +244 -394
  26. capytaine/meshes/io.py +433 -0
  27. capytaine/meshes/meshes.py +621 -676
  28. capytaine/meshes/predefined/cylinders.py +22 -56
  29. capytaine/meshes/predefined/rectangles.py +26 -85
  30. capytaine/meshes/predefined/spheres.py +4 -11
  31. capytaine/meshes/quality.py +118 -407
  32. capytaine/meshes/surface_integrals.py +48 -29
  33. capytaine/meshes/symmetric_meshes.py +641 -0
  34. capytaine/meshes/visualization.py +353 -0
  35. capytaine/post_pro/free_surfaces.py +1 -4
  36. capytaine/post_pro/kochin.py +10 -10
  37. capytaine/tools/block_circulant_matrices.py +275 -0
  38. capytaine/tools/lists_of_points.py +2 -2
  39. capytaine/tools/memory_monitor.py +45 -0
  40. capytaine/tools/symbolic_multiplication.py +31 -5
  41. capytaine/tools/timer.py +68 -42
  42. {capytaine-2.3.dist-info → capytaine-3.0.0a1.dist-info}/METADATA +8 -14
  43. capytaine-3.0.0a1.dist-info/RECORD +65 -0
  44. capytaine-3.0.0a1.dist-info/WHEEL +6 -0
  45. capytaine/bodies/predefined/__init__.py +0 -6
  46. capytaine/bodies/predefined/cylinders.py +0 -151
  47. capytaine/bodies/predefined/rectangles.py +0 -111
  48. capytaine/bodies/predefined/spheres.py +0 -70
  49. capytaine/green_functions/FinGreen3D/.gitignore +0 -1
  50. capytaine/green_functions/FinGreen3D/FinGreen3D.f90 +0 -3589
  51. capytaine/green_functions/FinGreen3D/LICENSE +0 -165
  52. capytaine/green_functions/FinGreen3D/Makefile +0 -16
  53. capytaine/green_functions/FinGreen3D/README.md +0 -24
  54. capytaine/green_functions/FinGreen3D/test_program.f90 +0 -39
  55. capytaine/green_functions/LiangWuNoblesse/.gitignore +0 -1
  56. capytaine/green_functions/LiangWuNoblesse/LICENSE +0 -504
  57. capytaine/green_functions/LiangWuNoblesse/LiangWuNoblesseWaveTerm.f90 +0 -751
  58. capytaine/green_functions/LiangWuNoblesse/Makefile +0 -18
  59. capytaine/green_functions/LiangWuNoblesse/README.md +0 -2
  60. capytaine/green_functions/LiangWuNoblesse/test_program.f90 +0 -28
  61. capytaine/green_functions/libs/__init__.py +0 -0
  62. capytaine/io/mesh_loaders.py +0 -1086
  63. capytaine/io/mesh_writers.py +0 -692
  64. capytaine/io/meshio.py +0 -38
  65. capytaine/matrices/__init__.py +0 -16
  66. capytaine/matrices/block.py +0 -592
  67. capytaine/matrices/block_toeplitz.py +0 -325
  68. capytaine/matrices/builders.py +0 -89
  69. capytaine/matrices/linear_solvers.py +0 -232
  70. capytaine/matrices/low_rank.py +0 -395
  71. capytaine/meshes/clipper.py +0 -465
  72. capytaine/meshes/collections.py +0 -334
  73. capytaine/meshes/mesh_like_protocol.py +0 -37
  74. capytaine/meshes/properties.py +0 -276
  75. capytaine/meshes/quadratures.py +0 -80
  76. capytaine/meshes/symmetric.py +0 -392
  77. capytaine/tools/lru_cache.py +0 -49
  78. capytaine/ui/vtk/__init__.py +0 -3
  79. capytaine/ui/vtk/animation.py +0 -329
  80. capytaine/ui/vtk/body_viewer.py +0 -28
  81. capytaine/ui/vtk/helpers.py +0 -82
  82. capytaine/ui/vtk/mesh_viewer.py +0 -461
  83. capytaine-2.3.dist-info/RECORD +0 -92
  84. capytaine-2.3.dist-info/WHEEL +0 -4
  85. {capytaine-2.3.dist-info → capytaine-3.0.0a1.dist-info}/LICENSE +0 -0
  86. {capytaine-2.3.dist-info → capytaine-3.0.0a1.dist-info}/entry_points.txt +0 -0
@@ -1,465 +0,0 @@
1
- """This module implements a tools to clip meshes against a plane.
2
- Based on meshmagick <https://github.com/LHEEA/meshmagick> by François Rongère.
3
- """
4
- # Copyright (C) 2017-2019 Matthieu Ancellin, based on the work of François Rongère
5
- # See LICENSE file at <https://github.com/mancellin/capytaine>
6
-
7
- import logging
8
-
9
- import numpy as np
10
-
11
- from capytaine.meshes.geometry import Plane
12
- from capytaine.meshes.meshes import Mesh
13
-
14
- LOG = logging.getLogger(__name__)
15
-
16
-
17
- def clip(source_mesh: Mesh, plane: Plane, vicinity_tol=1e-12, name=None):
18
- """Return a new mesh containing the source mesh clipped by the plane.
19
-
20
- Parameters
21
- ----------
22
- source_mesh : Mesh
23
- The mesh to be clipped.
24
- plane : Plane, optional
25
- The clipping plane.
26
- vicinity_tol : float, optional
27
- The absolute tolerance to consider en vertex is on the plane. Default is 1e-12.
28
- name: string, optional
29
- A name for the new clipped mesh.
30
- """
31
- vertices_data = _vertices_positions_wrt_plane(source_mesh, plane, vicinity_tol)
32
-
33
- nb_vertices_strictly_above_plane = np.count_nonzero(
34
- vertices_data['vertices_above_mask']
35
- )
36
- nb_vertices_below_or_on_plane = np.count_nonzero(
37
- vertices_data['vertices_below_mask'] | vertices_data['vertices_on_mask']
38
- )
39
-
40
- if nb_vertices_strictly_above_plane == source_mesh.nb_vertices:
41
- LOG.warning(f"Clipping {source_mesh.name} by {plane}: all vertices are removed.")
42
- clipped_mesh = Mesh(None, None)
43
- clipped_mesh._clipping_data = dict(faces_ids=[])
44
-
45
- elif nb_vertices_below_or_on_plane == source_mesh.nb_vertices:
46
- LOG.info(f"Clipping {source_mesh.name} by {plane}: no action.")
47
- clipped_mesh = source_mesh.copy()
48
- clipped_mesh._clipping_data = dict(faces_ids=list(range(source_mesh.nb_faces)))
49
-
50
- else:
51
- upper_mesh, crown_mesh, lower_mesh = _partition_mesh(vertices_data, source_mesh)
52
-
53
- if crown_mesh.nb_faces > 0:
54
- clipped_crown_mesh = _clip_crown(crown_mesh, plane)
55
- clipped_mesh = lower_mesh + clipped_crown_mesh
56
- clipped_mesh._clipping_data = {
57
- 'faces_ids': np.concatenate((lower_mesh._clipping_data['faces_ids'],
58
- clipped_crown_mesh._clipping_data['faces_ids']))
59
- }
60
- else:
61
- clipped_mesh = lower_mesh
62
-
63
- if name is None:
64
- clipped_mesh.name = f'{source_mesh.name}_clipped'
65
- clipped_mesh.remove_unused_vertices()
66
- clipped_mesh.remove_degenerated_faces()
67
-
68
- return clipped_mesh
69
-
70
-
71
- def _vertices_positions_wrt_plane(source_mesh, plane, vicinity_tol):
72
- """Classifies vertices with respect to the clipping plane."""
73
- vertices_distances = plane.distance_to_point(source_mesh.vertices)
74
- vertices_data = {'vertices_distances': vertices_distances,
75
- 'vertices_above_mask': vertices_distances > vicinity_tol,
76
- 'vertices_on_mask': np.abs(vertices_distances) < vicinity_tol,
77
- 'vertices_below_mask': vertices_distances < -vicinity_tol
78
- }
79
- return vertices_data
80
-
81
-
82
- def _partition_mesh(vertices_data, source_mesh):
83
- """Partitions the mesh in 3 with respect to the plane:
84
- * upper_mesh: part entirely above the clipping plane
85
- * crown_mesh: part intersecting the clipping plane
86
- * lower_mesh: part entirely under the clipping plane
87
- """
88
- nb_vertices_above_per_face = vertices_data['vertices_above_mask'][source_mesh.faces].sum(axis=1)
89
- nb_vertices_below_per_face = vertices_data['vertices_below_mask'][source_mesh.faces].sum(axis=1)
90
-
91
- # Simple criteria ensuring that _faces are totally above or below the plane (4 _vertices at the same side)
92
- # Works for both triangles and quadrangles
93
- above_faces_mask = nb_vertices_above_per_face == 4
94
- below_faces_mask = nb_vertices_below_per_face == 4
95
- crown_faces_mask = np.logical_not(np.logical_or(above_faces_mask, below_faces_mask))
96
-
97
- faces_ids = {
98
- 'upper_mesh': np.where(above_faces_mask)[0],
99
- 'crown_mesh': np.where(crown_faces_mask)[0],
100
- 'lower_mesh': np.where(below_faces_mask)[0]
101
- }
102
-
103
- partition = []
104
- for name in ['upper_mesh', 'crown_mesh', 'lower_mesh']:
105
- new_mesh, vertices_ids = source_mesh.extract_faces(
106
- id_faces_to_extract=faces_ids[name], return_index=True, name=name)
107
- new_mesh._clipping_data = {
108
- 'faces_ids': faces_ids[name],
109
- 'vertices_ids': vertices_ids,
110
- 'vertices_distances': vertices_data['vertices_distances'][vertices_ids],
111
- 'above_vertices_mask': vertices_data['vertices_above_mask'][vertices_ids],
112
- 'on_vertices_mask': vertices_data['vertices_on_mask'][vertices_ids],
113
- 'below_vertices_mask': vertices_data['vertices_below_mask'][vertices_ids],
114
- }
115
- partition.append(new_mesh)
116
-
117
- return partition
118
-
119
-
120
- def _clip_crown(crown_mesh, plane):
121
- """Performs the clipping operation of the crown_mesh and determines the obtained boundaries.
122
- This is the heart method of the class.
123
- """
124
- vertices = crown_mesh.vertices
125
-
126
- above_vertices_mask = crown_mesh._clipping_data['above_vertices_mask']
127
- below_vertices_mask = crown_mesh._clipping_data['below_vertices_mask']
128
-
129
- on_vertices_mask = crown_mesh._clipping_data['on_vertices_mask']
130
- # TODO: Vertices pre-projection to be done here
131
-
132
- vertices_distances = crown_mesh._clipping_data['vertices_distances']
133
-
134
- # Init
135
- clipped_crown_mesh_faces = list()
136
- clipped_crown_mesh_relative_faces_ids = list()
137
-
138
- direct_boundary_edges = dict()
139
- inv_boundary_edges = dict()
140
- intersections_vertices = list()
141
-
142
- index_new_vertices = crown_mesh.nb_vertices
143
-
144
- for face_id in range(crown_mesh.nb_faces):
145
-
146
- face = crown_mesh.get_face(face_id)
147
-
148
- # # Determining the type of face clipping
149
- v_above_face = np.where(above_vertices_mask[face])[0]
150
- v_on_face = np.where(on_vertices_mask[face])[0]
151
- v_below_face = np.where(below_vertices_mask[face])[0]
152
-
153
- nb_above = len(v_above_face)
154
- nb_on = len(v_on_face)
155
- nb_below = len(v_below_face)
156
-
157
- face_type = str(nb_above) + str(nb_on) + str(nb_below)
158
-
159
- if face_type == '202':
160
- # 0*-----*3
161
- # | |
162
- # ----o-----o----
163
- # | |
164
- # 1*-----*2
165
- if v_above_face[1] == v_above_face[0] + 1:
166
- face = np.roll(face, -v_above_face[1])
167
- p0, p1, p2, p3 = vertices[face]
168
- ileft = plane.get_edge_intersection(p0, p1)
169
- iright = plane.get_edge_intersection(p2, p3)
170
- intersections_vertices += [ileft, iright]
171
- boundary_edge = [index_new_vertices, index_new_vertices + 1]
172
- clipped_crown_mesh_faces.append([index_new_vertices, face[1], face[2], index_new_vertices + 1])
173
- clipped_crown_mesh_relative_faces_ids.append(face_id)
174
- index_new_vertices += 2
175
-
176
- elif face_type == '301':
177
- # *2
178
- # / \
179
- # / \
180
- # / \
181
- # 3* *1
182
- # \ /
183
- # ---o---o---
184
- # \ /
185
- # *0
186
- face = np.roll(face, -v_below_face[0])
187
- p0, p1, p3 = vertices[face[[0, 1, 3]]]
188
- ileft = plane.get_edge_intersection(p0, p3)
189
- iright = plane.get_edge_intersection(p0, p1)
190
- intersections_vertices += [ileft, iright]
191
- boundary_edge = [index_new_vertices, index_new_vertices + 1]
192
- clipped_crown_mesh_faces.append([index_new_vertices, face[0], index_new_vertices + 1, index_new_vertices])
193
- clipped_crown_mesh_relative_faces_ids.append(face_id)
194
- index_new_vertices += 2
195
-
196
- elif face_type == '103':
197
- # *0
198
- # / \
199
- # ---o---o---
200
- # / \
201
- # 1* - - - *3
202
- # \ /
203
- # \ /
204
- # \ /
205
- # *2
206
- face = np.roll(face, -v_above_face[0])
207
- p0, p1, p3 = vertices[face[[0, 1, 3]]]
208
- ileft = plane.get_edge_intersection(p0, p1)
209
- iright = plane.get_edge_intersection(p0, p3)
210
- intersections_vertices += [ileft, iright]
211
- boundary_edge = [index_new_vertices, index_new_vertices + 1]
212
- clipped_crown_mesh_faces.append([index_new_vertices, face[1], face[3], index_new_vertices + 1])
213
- clipped_crown_mesh_relative_faces_ids.append(face_id)
214
- clipped_crown_mesh_faces.append([face[1], face[2], face[3], face[1]])
215
- clipped_crown_mesh_relative_faces_ids.append(face_id)
216
- index_new_vertices += 2
217
-
218
- elif face_type == '102':
219
- # *O
220
- # / \
221
- # ---o---o---
222
- # / \
223
- # 1*-------*2
224
- face = np.roll(face, -v_above_face[0])
225
- p0, p1, p2 = vertices[face]
226
- ileft = plane.get_edge_intersection(p0, p1)
227
- iright = plane.get_edge_intersection(p0, p2)
228
- intersections_vertices += [ileft, iright]
229
- boundary_edge = [index_new_vertices, index_new_vertices + 1]
230
- clipped_crown_mesh_faces.append([index_new_vertices, face[1], face[2], index_new_vertices + 1])
231
- clipped_crown_mesh_relative_faces_ids.append(face_id)
232
- index_new_vertices += 2
233
-
234
- elif face_type == '201': # done
235
- # 2*-------*1
236
- # \ /
237
- # ---o---o---
238
- # \ /
239
- # *0
240
- face = np.roll(face, -v_below_face[0])
241
- p0, p1, p2 = vertices[face]
242
- ileft = plane.get_edge_intersection(p0, p2)
243
- iright = plane.get_edge_intersection(p0, p1)
244
- intersections_vertices += [ileft, iright]
245
- boundary_edge = [index_new_vertices, index_new_vertices + 1]
246
- clipped_crown_mesh_faces.append([index_new_vertices, face[0], index_new_vertices + 1, index_new_vertices])
247
- clipped_crown_mesh_relative_faces_ids.append(face_id)
248
- index_new_vertices += 2
249
-
250
- elif face_type == '211':
251
- # *3 *1
252
- # / \ / \
253
- # / *2 or 2* \
254
- # 0/ / \ \0
255
- # ---*---o--- ---o---*---
256
- # \ / \ /
257
- # *1 *3
258
- #
259
-
260
- face = np.roll(face, -v_on_face[0])
261
- if vertices_distances[face[1]] < 0.:
262
- p1, p2 = vertices[face[[1, 2]]]
263
- iright = plane.get_edge_intersection(p1, p2)
264
- intersections_vertices.append(iright)
265
- boundary_edge = [face[0], index_new_vertices]
266
- clipped_crown_mesh_faces.append([face[0], face[1], index_new_vertices, face[0]])
267
- else:
268
- p2, p3 = vertices[face[[2, 3]]]
269
- ileft = plane.get_edge_intersection(p2, p3)
270
- intersections_vertices.append(ileft)
271
- boundary_edge = [index_new_vertices, face[0]]
272
- clipped_crown_mesh_faces.append([index_new_vertices, face[3], face[0], index_new_vertices])
273
- clipped_crown_mesh_relative_faces_ids.append(face_id)
274
- index_new_vertices += 1
275
-
276
- elif face_type == '112':
277
- # *3 *1
278
- # / \ / \
279
- # ---*---o--- or ---o---*---
280
- # 0\ \ / /0
281
- # \ *2 2* /
282
- # \ / \ /
283
- # *1 *3
284
- face = np.roll(face, -v_on_face[0])
285
- if vertices_distances[face[1]] < 0.:
286
- p2, p3 = vertices[face[[2, 3]]]
287
- iright = plane.get_edge_intersection(p2, p3)
288
- intersections_vertices.append(iright)
289
- boundary_edge = [face[0], index_new_vertices]
290
- clipped_crown_mesh_faces.append([face[0], face[1], face[2], index_new_vertices])
291
- else:
292
- p1, p2 = vertices[face[[1, 2]]]
293
- ileft = plane.get_edge_intersection(p1, p2)
294
- intersections_vertices.append(ileft)
295
- boundary_edge = [index_new_vertices, face[0]]
296
- clipped_crown_mesh_faces.append([index_new_vertices, face[2], face[3], face[0]])
297
- clipped_crown_mesh_relative_faces_ids.append(face_id)
298
- index_new_vertices += 1
299
-
300
- elif face_type == '013':
301
- # -----*-----
302
- # / \
303
- # / \
304
- # * *
305
- # \ /
306
- # \ /
307
- # *
308
- boundary_edge = None
309
- clipped_crown_mesh_faces.append(list(face))
310
- clipped_crown_mesh_relative_faces_ids.append(face_id)
311
-
312
- elif face_type == '210' or face_type == '310':
313
- # *-------* *
314
- # \ 210 / / \ 310
315
- # \ / * *
316
- # \ / \ /
317
- # ----*---- ----*----
318
- boundary_edge = None
319
-
320
- elif face_type == '111':
321
- # *2 *1
322
- # /| |\
323
- # / | | \
324
- # ---*--o--- or ---o--*---
325
- # 0\ | | /0
326
- # \| |/
327
- # *1 *2
328
- face = np.roll(face, -v_on_face[0])
329
- p1, p2 = vertices[face[[1, 2]]]
330
- if vertices_distances[face[1]] < 0.:
331
- iright = plane.get_edge_intersection(p1, p2)
332
- intersections_vertices.append(iright)
333
- boundary_edge = [face[0], index_new_vertices]
334
- clipped_crown_mesh_faces.append([face[0], face[1], index_new_vertices, face[0]])
335
- else:
336
- ileft = plane.get_edge_intersection(p1, p2)
337
- intersections_vertices.append(ileft)
338
- boundary_edge = [index_new_vertices, face[0]]
339
- clipped_crown_mesh_faces.append([index_new_vertices, face[2], face[0], index_new_vertices])
340
- clipped_crown_mesh_relative_faces_ids.append(face_id)
341
- index_new_vertices += 1
342
-
343
- elif face_type == '120':
344
- # *O
345
- # / \
346
- # / \
347
- # 1/ \2
348
- # ----*-------*----
349
- # face = np.roll(face, -v_above_face[0])
350
- # boundary_edge = [face[1], face[2]]
351
- # FIXME: quick fix here : robust ?
352
- boundary_edge = None
353
-
354
- elif face_type == '021':
355
- # ----*-------*----
356
- # 2\ /1
357
- # \ /
358
- # \ /
359
- # *0
360
- face = np.roll(face, -v_below_face[0])
361
- boundary_edge = [face[2], face[1]]
362
- face = list(face)
363
- face.append(face[0])
364
- clipped_crown_mesh_faces.append(face)
365
- clipped_crown_mesh_relative_faces_ids.append(face_id)
366
-
367
- elif face_type == '022':
368
- # ----*-----*----
369
- # 0| |3
370
- # | |
371
- # 1*-----*2
372
- if v_on_face[1] == v_on_face[0] + 1:
373
- face = np.roll(face, -v_on_face[1])
374
- boundary_edge = [face[0], face[3]]
375
- clipped_crown_mesh_faces.append(list(face))
376
- clipped_crown_mesh_relative_faces_ids.append(face_id)
377
-
378
- elif face_type == '012':
379
- # ------*------
380
- # / \
381
- # / \
382
- # / \
383
- # *-------*
384
- boundary_edge = None
385
- face = list(face)
386
- face.append(face[0])
387
- clipped_crown_mesh_faces.append(face)
388
- clipped_crown_mesh_relative_faces_ids.append(face_id)
389
-
390
- elif face_type == '220':
391
- # 0*-----*3
392
- # | |
393
- # 1| |2
394
- # ----*-----*----
395
-
396
- # if v_above_face[1] == v_above_face[0] + 1:
397
- # face = np.roll(face, -v_above_face[1])
398
- # boundary_edge = [face[1], face[2]]
399
- # FIXME: quick fix here : robust ?
400
- boundary_edge = None
401
-
402
- elif face_type == '121':
403
- # *0
404
- # / \
405
- # / \
406
- # ---*-----*---
407
- # 1\ /3
408
- # \ /
409
- # *2
410
- face = np.roll(face, -v_above_face[0])
411
- boundary_edge = [face[1], face[3]]
412
- clipped_crown_mesh_faces.append([face[1], face[2], face[3], face[1]])
413
- clipped_crown_mesh_relative_faces_ids.append(face_id)
414
-
415
- elif face_type == '300' or face_type == '400':
416
- # * *-----*
417
- # / \ | |
418
- # /300\ or | 400 |
419
- # *-----* *-----*
420
- # ____________ ______________
421
- boundary_edge = None
422
-
423
- elif face_type == '003':
424
- # -----------
425
- # *
426
- # / \
427
- # / \
428
- # *-----*
429
- boundary_edge = None
430
- face = list(face)
431
- face.append(face[0])
432
- clipped_crown_mesh_faces.append(face)
433
- clipped_crown_mesh_relative_faces_ids.append(face_id)
434
-
435
- elif face_type == '004':
436
- # ---------------
437
- # *-----*
438
- # | |
439
- # | |
440
- # *-----*
441
- boundary_edge = None
442
- clipped_crown_mesh_faces.append(list(face))
443
- clipped_crown_mesh_relative_faces_ids.append(face_id)
444
-
445
- elif face_type == '030' or face_type == '040':
446
- # Face is totally on the plane --> rare case...
447
- boundary_edge = None
448
-
449
- else:
450
- raise Exception("Face %u clipping case %s not known." % (face_id, face_type))
451
-
452
- # Building boundary connectivity
453
- if boundary_edge is not None:
454
- direct_boundary_edges[boundary_edge[0]] = boundary_edge[1]
455
- inv_boundary_edges[boundary_edge[1]] = boundary_edge[0]
456
-
457
- if len(intersections_vertices) > 0:
458
- vertices = np.concatenate((vertices, intersections_vertices))
459
-
460
- clipped_crown_mesh = Mesh(vertices, clipped_crown_mesh_faces)
461
- clipped_crown_mesh._clipping_data = {
462
- 'faces_ids': crown_mesh._clipping_data['faces_ids'][clipped_crown_mesh_relative_faces_ids]
463
- }
464
-
465
- return clipped_crown_mesh