mmgpy 0.3.0__cp312-cp312-win_amd64.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 (132) hide show
  1. bin/Release/mmg2d_O3.exe +0 -0
  2. bin/Release/mmg3d_O3.exe +0 -0
  3. bin/Release/mmgs_O3.exe +0 -0
  4. bin/__init__.py +10 -0
  5. bin/concrt140.dll +0 -0
  6. bin/mmg.dll +0 -0
  7. bin/mmg2d.dll +0 -0
  8. bin/mmg2d_O3.exe +0 -0
  9. bin/mmg3d.dll +0 -0
  10. bin/mmg3d_O3.exe +0 -0
  11. bin/mmgs.dll +0 -0
  12. bin/mmgs_O3.exe +0 -0
  13. bin/msvcp140.dll +0 -0
  14. bin/msvcp140_1.dll +0 -0
  15. bin/msvcp140_2.dll +0 -0
  16. bin/msvcp140_atomic_wait.dll +0 -0
  17. bin/msvcp140_codecvt_ids.dll +0 -0
  18. bin/vcruntime140.dll +0 -0
  19. bin/vcruntime140_1.dll +0 -0
  20. include/__init__.py +10 -0
  21. include/mmg/common/libmmgtypes.h +687 -0
  22. include/mmg/common/libmmgtypesf.h +762 -0
  23. include/mmg/common/mmg_export.h +47 -0
  24. include/mmg/common/mmgcmakedefines.h +46 -0
  25. include/mmg/common/mmgcmakedefinesf.h +29 -0
  26. include/mmg/common/mmgversion.h +54 -0
  27. include/mmg/libmmg.h +67 -0
  28. include/mmg/libmmgf.h +42 -0
  29. include/mmg/mmg2d/libmmg2d.h +2761 -0
  30. include/mmg/mmg2d/libmmg2df.h +3263 -0
  31. include/mmg/mmg2d/mmg2d_export.h +34 -0
  32. include/mmg/mmg3d/libmmg3d.h +3444 -0
  33. include/mmg/mmg3d/libmmg3df.h +4041 -0
  34. include/mmg/mmg3d/mmg3d_export.h +34 -0
  35. include/mmg/mmgs/libmmgs.h +2560 -0
  36. include/mmg/mmgs/libmmgsf.h +3028 -0
  37. include/mmg/mmgs/mmgs_export.h +34 -0
  38. lib/__init__.py +10 -0
  39. lib/cmake/mmg/FindElas.cmake +57 -0
  40. lib/cmake/mmg/FindSCOTCH.cmake +373 -0
  41. lib/cmake/mmg/MmgTargets-release.cmake +53 -0
  42. lib/cmake/mmg/MmgTargets.cmake +127 -0
  43. lib/cmake/mmg/mmgConfig.cmake +43 -0
  44. lib/mmg.lib +0 -0
  45. lib/mmg2d.lib +0 -0
  46. lib/mmg3d.lib +0 -0
  47. lib/mmgs.lib +0 -0
  48. mmgpy/__init__.py +888 -0
  49. mmgpy/_logging.py +86 -0
  50. mmgpy/_mmgpy.cp312-win_amd64.pyd +0 -0
  51. mmgpy/_mmgpy.pyi +650 -0
  52. mmgpy/_options.py +304 -0
  53. mmgpy/_progress.py +539 -0
  54. mmgpy/_pyvista.py +423 -0
  55. mmgpy/_version.py +3 -0
  56. mmgpy/_version.py.in +3 -0
  57. mmgpy/lagrangian.py +394 -0
  58. mmgpy/metrics.py +595 -0
  59. mmgpy/mmg2d.dll +0 -0
  60. mmgpy/mmg2d.lib +0 -0
  61. mmgpy/mmg3d.dll +0 -0
  62. mmgpy/mmg3d.lib +0 -0
  63. mmgpy/mmgs.dll +0 -0
  64. mmgpy/mmgs.lib +0 -0
  65. mmgpy/progress.py +57 -0
  66. mmgpy/py.typed +0 -0
  67. mmgpy/sizing.py +370 -0
  68. mmgpy-0.3.0.dist-info/DELVEWHEEL +2 -0
  69. mmgpy-0.3.0.dist-info/METADATA +75 -0
  70. mmgpy-0.3.0.dist-info/RECORD +132 -0
  71. mmgpy-0.3.0.dist-info/WHEEL +5 -0
  72. mmgpy-0.3.0.dist-info/entry_points.txt +6 -0
  73. mmgpy-0.3.0.dist-info/licenses/LICENSE +38 -0
  74. mmgpy.libs/vtkCommonColor-9.5-07cd19e9d77559cb8be83e8ac8833cd4.dll +0 -0
  75. mmgpy.libs/vtkCommonComputationalGeometry-9.5-4aaf997b087c330e171c14a4ba6be7b2.dll +0 -0
  76. mmgpy.libs/vtkCommonCore-9.5.dll +0 -0
  77. mmgpy.libs/vtkCommonDataModel-9.5.dll +0 -0
  78. mmgpy.libs/vtkCommonExecutionModel-9.5-2f7a1bae0a1d4d0e205eea43596a659c.dll +0 -0
  79. mmgpy.libs/vtkCommonMath-9.5-609b01246386fe29df2677fa5c7ca793.dll +0 -0
  80. mmgpy.libs/vtkCommonMisc-9.5-4173df33811eddea1529a40bf93266c8.dll +0 -0
  81. mmgpy.libs/vtkCommonSystem-9.5-e5b15bd84934b99e3b2bbe5d3e064c97.dll +0 -0
  82. mmgpy.libs/vtkCommonTransforms-9.5-9b76a61640718d893271cc0b5db50d1d.dll +0 -0
  83. mmgpy.libs/vtkDICOMParser-9.5-203c95a77d21799a8049a576e1b28f2e.dll +0 -0
  84. mmgpy.libs/vtkFiltersCellGrid-9.5-fa6bda61d2d528369d8b2f3a66d2d6b4.dll +0 -0
  85. mmgpy.libs/vtkFiltersCore-9.5-935a5f5225a975e99626296b2f3ded70.dll +0 -0
  86. mmgpy.libs/vtkFiltersExtraction-9.5-dc0a7543ba584f7e8ce9f9184485a228.dll +0 -0
  87. mmgpy.libs/vtkFiltersGeneral-9.5-709f69dbcca8aba1750582106a97c605.dll +0 -0
  88. mmgpy.libs/vtkFiltersGeometry-9.5-7abfb655763a62f56d63b45038d6e811.dll +0 -0
  89. mmgpy.libs/vtkFiltersHybrid-9.5-0721ec98d8a8b7442d900747e1ec59fb.dll +0 -0
  90. mmgpy.libs/vtkFiltersHyperTree-9.5-f9ee6a4761fdad8956c08a51dae77636.dll +0 -0
  91. mmgpy.libs/vtkFiltersModeling-9.5-458d9d2c544bb3c37de28c26c05c07bc.dll +0 -0
  92. mmgpy.libs/vtkFiltersParallel-9.5-1f243ffe308277c3970d8be4172d856f.dll +0 -0
  93. mmgpy.libs/vtkFiltersReduction-9.5-bf8c4a248bd84fbd6bb1a2ab5f646e56.dll +0 -0
  94. mmgpy.libs/vtkFiltersSources-9.5-492fa5b1b8562f4b141a347a38ae1ce5.dll +0 -0
  95. mmgpy.libs/vtkFiltersStatistics-9.5-6e99ef76387303ec5ff8c0fe6101d446.dll +0 -0
  96. mmgpy.libs/vtkFiltersTexture-9.5-15c23120b41b9a1c4acb01f790aad01f.dll +0 -0
  97. mmgpy.libs/vtkFiltersVerdict-9.5-332c0402a58129ec5b6af7b7f56cbb62.dll +0 -0
  98. mmgpy.libs/vtkIOCellGrid-9.5-88e1ec9c5a3554a82aedc0027fe84c6b.dll +0 -0
  99. mmgpy.libs/vtkIOCore-9.5.dll +0 -0
  100. mmgpy.libs/vtkIOGeometry-9.5-47c69db15c63c5773efa6851b59ae0a7.dll +0 -0
  101. mmgpy.libs/vtkIOImage-9.5-74bb92e688da5595ff9ff7645f9a0a13.dll +0 -0
  102. mmgpy.libs/vtkIOLegacy-9.5.dll +0 -0
  103. mmgpy.libs/vtkIOParallel-9.5.dll +0 -0
  104. mmgpy.libs/vtkIOParallelXML-9.5.dll +0 -0
  105. mmgpy.libs/vtkIOXML-9.5.dll +0 -0
  106. mmgpy.libs/vtkIOXMLParser-9.5-1893156c41fd4cf7165904675cb5d15d.dll +0 -0
  107. mmgpy.libs/vtkImagingCore-9.5-145fc0249cffbd27c610d10812e1cbfc.dll +0 -0
  108. mmgpy.libs/vtkImagingSources-9.5-f0c087a4669caa045584ed61f52502b7.dll +0 -0
  109. mmgpy.libs/vtkParallelCore-9.5-e91757b6dbd2a5369ab2bd05ff95d79d.dll +0 -0
  110. mmgpy.libs/vtkParallelDIY-9.5-04dd6b6b5dd8a5eacd43d270999cf09a.dll +0 -0
  111. mmgpy.libs/vtkRenderingCore-9.5-24a9802d77a083def26449fa681b1af7.dll +0 -0
  112. mmgpy.libs/vtkdoubleconversion-9.5-5e39712b9f4e44ea8a26e9119e53a7d4.dll +0 -0
  113. mmgpy.libs/vtkexpat-9.5-3b1dd25e09a2cccbbac723de448cb894.dll +0 -0
  114. mmgpy.libs/vtkfmt-9.5-50239b66bf315d100ecd306114139e9b.dll +0 -0
  115. mmgpy.libs/vtkjpeg-9.5-9412ee79f685a9196398b988a59666cd.dll +0 -0
  116. mmgpy.libs/vtkjsoncpp-9.5-abfad956527e3a4885dbb39f99f9e4d4.dll +0 -0
  117. mmgpy.libs/vtkkissfft-9.5-464db9175ce63de19addc69be524c4b7.dll +0 -0
  118. mmgpy.libs/vtkloguru-9.5-ec016ed005b4a79062e329ad8f1c382d.dll +0 -0
  119. mmgpy.libs/vtklz4-9.5-798b58f4518733b0eee8027eeba022fb.dll +0 -0
  120. mmgpy.libs/vtklzma-9.5-8f489b5430eb47d578de52c769a4dd5c.dll +0 -0
  121. mmgpy.libs/vtkmetaio-9.5-8f0a559399d53e4c7fc06272620b2167.dll +0 -0
  122. mmgpy.libs/vtkpng-9.5-1dbed3116ba7e31f56512a93b942cdf5.dll +0 -0
  123. mmgpy.libs/vtkpugixml-9.5-23ef37d65494ab52babc6d45b24764b7.dll +0 -0
  124. mmgpy.libs/vtksys-9.5.dll +0 -0
  125. mmgpy.libs/vtktiff-9.5-767fd93c8402517d5b2d1befab98c41e.dll +0 -0
  126. mmgpy.libs/vtktoken-9.5-f4ff567202eeb9a613c0b242aa05dbc9.dll +0 -0
  127. mmgpy.libs/vtkverdict-9.5-6bb84649d1b0ca1cc5454307fd35083b.dll +0 -0
  128. mmgpy.libs/vtkzlib-9.5-779937c44671e188e9f96125eb5afb12.dll +0 -0
  129. share/__init__.py +10 -0
  130. share/man/man1/mmg2d.1.gz +0 -0
  131. share/man/man1/mmg3d.1.gz +0 -0
  132. share/man/man1/mmgs.1.gz +0 -0
mmgpy/_pyvista.py ADDED
@@ -0,0 +1,423 @@
1
+ """PyVista integration for mmgpy mesh classes.
2
+
3
+ This module provides conversion functions between PyVista mesh types
4
+ and mmgpy mesh classes.
5
+
6
+ Example:
7
+ >>> import pyvista as pv
8
+ >>> from mmgpy import MmgMesh3D, from_pyvista, to_pyvista
9
+ >>>
10
+ >>> # Load mesh and convert to mmgpy
11
+ >>> grid = pv.read("mesh.vtk")
12
+ >>> mesh = from_pyvista(grid)
13
+ >>>
14
+ >>> # Remesh and convert back
15
+ >>> mesh.remesh(hmax=0.1)
16
+ >>> result = to_pyvista(mesh)
17
+
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from typing import TYPE_CHECKING, overload
23
+
24
+ import numpy as np
25
+ import pyvista as pv
26
+
27
+ from mmgpy._mmgpy import MmgMesh2D, MmgMesh3D, MmgMeshS
28
+
29
+ if TYPE_CHECKING:
30
+ from numpy.typing import NDArray
31
+
32
+ _DIMS_2D = 2
33
+ _DIMS_3D = 3
34
+ _TRIANGLE_VERTS = 3
35
+ _2D_DETECTION_TOLERANCE = 1e-8
36
+
37
+
38
+ def _is_2d_mesh(points: NDArray[np.floating]) -> bool:
39
+ """Check if points are essentially 2D (z coordinates are zero or near-zero)."""
40
+ if points.shape[1] == _DIMS_2D:
41
+ return True
42
+ if points.shape[1] == _DIMS_3D:
43
+ z_coords = points[:, 2]
44
+ return bool(np.allclose(z_coords, 0, atol=_2D_DETECTION_TOLERANCE))
45
+ return False
46
+
47
+
48
+ def _extract_triangles_from_polydata(mesh: pv.PolyData) -> NDArray[np.int32]:
49
+ """Extract triangle connectivity from PolyData faces array."""
50
+ if hasattr(mesh, "cells_dict") and pv.CellType.TRIANGLE in mesh.cells_dict:
51
+ return mesh.cells_dict[pv.CellType.TRIANGLE].astype(np.int32)
52
+
53
+ faces = mesh.faces
54
+ if len(faces) == 0:
55
+ msg = "PolyData has no faces"
56
+ raise ValueError(msg)
57
+
58
+ triangles = []
59
+ i = 0
60
+ while i < len(faces):
61
+ n_verts = faces[i]
62
+ if n_verts != _TRIANGLE_VERTS:
63
+ msg = f"Expected triangles (3 vertices), got {n_verts}-vertex polygon"
64
+ raise ValueError(msg)
65
+ triangles.append(faces[i + 1 : i + 4])
66
+ i += n_verts + 1
67
+
68
+ return np.array(triangles, dtype=np.int32)
69
+
70
+
71
+ def _from_pyvista_to_mmg3d(mesh: pv.UnstructuredGrid) -> MmgMesh3D:
72
+ """Convert UnstructuredGrid with tetrahedra to MmgMesh3D."""
73
+ if pv.CellType.TETRA not in mesh.cells_dict:
74
+ msg = "UnstructuredGrid must contain tetrahedra (CellType.TETRA)"
75
+ raise ValueError(msg)
76
+
77
+ vertices = np.array(mesh.points, dtype=np.float64)
78
+ elements = mesh.cells_dict[pv.CellType.TETRA].astype(np.int32)
79
+
80
+ return MmgMesh3D(vertices, elements)
81
+
82
+
83
+ def _from_pyvista_to_mmg2d(mesh: pv.PolyData) -> MmgMesh2D:
84
+ """Convert PolyData with 2D triangles to MmgMesh2D."""
85
+ points = np.array(mesh.points, dtype=np.float64)
86
+ if points.shape[1] == _DIMS_3D:
87
+ vertices = np.ascontiguousarray(points[:, :2])
88
+ else:
89
+ vertices = points
90
+ triangles = _extract_triangles_from_polydata(mesh)
91
+
92
+ return MmgMesh2D(vertices, triangles)
93
+
94
+
95
+ def _from_pyvista_to_mmgs(mesh: pv.PolyData) -> MmgMeshS:
96
+ """Convert PolyData with 3D surface triangles to MmgMeshS."""
97
+ vertices = np.array(mesh.points, dtype=np.float64)
98
+ triangles = _extract_triangles_from_polydata(mesh)
99
+
100
+ return MmgMeshS(vertices, triangles)
101
+
102
+
103
+ def _from_pyvista_with_explicit_type(
104
+ mesh: pv.UnstructuredGrid | pv.PolyData,
105
+ mesh_type: type[MmgMesh3D | MmgMesh2D | MmgMeshS],
106
+ ) -> MmgMesh3D | MmgMesh2D | MmgMeshS:
107
+ """Convert PyVista mesh to mmgpy mesh with explicit type."""
108
+ if mesh_type is MmgMesh3D:
109
+ if not isinstance(mesh, pv.UnstructuredGrid):
110
+ msg = "MmgMesh3D requires UnstructuredGrid input"
111
+ raise ValueError(msg)
112
+ return _from_pyvista_to_mmg3d(mesh)
113
+
114
+ if mesh_type is MmgMesh2D:
115
+ if not isinstance(mesh, pv.PolyData):
116
+ msg = "MmgMesh2D requires PolyData input"
117
+ raise ValueError(msg)
118
+ return _from_pyvista_to_mmg2d(mesh)
119
+
120
+ if mesh_type is MmgMeshS:
121
+ if not isinstance(mesh, pv.PolyData):
122
+ msg = "MmgMeshS requires PolyData input"
123
+ raise ValueError(msg)
124
+ return _from_pyvista_to_mmgs(mesh)
125
+
126
+ msg = f"Unknown mesh type: {mesh_type}"
127
+ raise ValueError(msg)
128
+
129
+
130
+ def _from_pyvista_auto_detect(
131
+ mesh: pv.UnstructuredGrid | pv.PolyData,
132
+ ) -> MmgMesh3D | MmgMesh2D | MmgMeshS:
133
+ """Convert PyVista mesh to mmgpy mesh with auto-detection."""
134
+ if isinstance(mesh, pv.UnstructuredGrid):
135
+ if pv.CellType.TETRA in mesh.cells_dict:
136
+ return _from_pyvista_to_mmg3d(mesh)
137
+ msg = "UnstructuredGrid must contain tetrahedra for auto-detection"
138
+ raise ValueError(msg)
139
+
140
+ if isinstance(mesh, pv.PolyData):
141
+ if _is_2d_mesh(mesh.points):
142
+ return _from_pyvista_to_mmg2d(mesh)
143
+ return _from_pyvista_to_mmgs(mesh)
144
+
145
+ msg = f"Unsupported PyVista mesh type: {type(mesh)}"
146
+ raise TypeError(msg)
147
+
148
+
149
+ @overload
150
+ def from_pyvista(
151
+ mesh: pv.UnstructuredGrid | pv.PolyData,
152
+ mesh_type: type[MmgMesh3D],
153
+ ) -> MmgMesh3D: ...
154
+
155
+
156
+ @overload
157
+ def from_pyvista(
158
+ mesh: pv.UnstructuredGrid | pv.PolyData,
159
+ mesh_type: type[MmgMesh2D],
160
+ ) -> MmgMesh2D: ...
161
+
162
+
163
+ @overload
164
+ def from_pyvista(
165
+ mesh: pv.UnstructuredGrid | pv.PolyData,
166
+ mesh_type: type[MmgMeshS],
167
+ ) -> MmgMeshS: ...
168
+
169
+
170
+ @overload
171
+ def from_pyvista(
172
+ mesh: pv.UnstructuredGrid | pv.PolyData,
173
+ mesh_type: None = None,
174
+ ) -> MmgMesh3D | MmgMesh2D | MmgMeshS: ...
175
+
176
+
177
+ def from_pyvista(
178
+ mesh: pv.UnstructuredGrid | pv.PolyData,
179
+ mesh_type: type[MmgMesh3D | MmgMesh2D | MmgMeshS] | None = None,
180
+ ) -> MmgMesh3D | MmgMesh2D | MmgMeshS:
181
+ """Convert a PyVista mesh to an mmgpy mesh.
182
+
183
+ Args:
184
+ mesh: PyVista mesh (UnstructuredGrid or PolyData).
185
+ mesh_type: Target mesh class. If None, auto-detects based on:
186
+ - UnstructuredGrid with tetrahedra → MmgMesh3D
187
+ - PolyData with 2D points (z≈0) → MmgMesh2D
188
+ - PolyData with 3D points → MmgMeshS
189
+
190
+ Returns:
191
+ The appropriate mmgpy mesh instance.
192
+
193
+ Raises:
194
+ ValueError: If mesh type cannot be determined or is incompatible.
195
+
196
+ Note:
197
+ When auto-detecting mesh type for PolyData, a mesh is considered 2D
198
+ (and converted to MmgMesh2D) if all z-coordinates are within 1e-8 of zero.
199
+ For thin 3D meshes near z=0, explicitly specify ``mesh_type=MmgMeshS``.
200
+
201
+ Example:
202
+ >>> import pyvista as pv
203
+ >>> from mmgpy import from_pyvista, MmgMeshS
204
+ >>>
205
+ >>> # Auto-detect mesh type
206
+ >>> grid = pv.read("tetra_mesh.vtk")
207
+ >>> mesh3d = from_pyvista(grid)
208
+ >>>
209
+ >>> # Explicit mesh type for thin 3D surfaces
210
+ >>> surface = pv.read("surface.stl")
211
+ >>> mesh_s = from_pyvista(surface, MmgMeshS)
212
+
213
+ """
214
+ if mesh_type is not None:
215
+ return _from_pyvista_with_explicit_type(mesh, mesh_type)
216
+ return _from_pyvista_auto_detect(mesh)
217
+
218
+
219
+ @overload
220
+ def to_pyvista(
221
+ mesh: MmgMesh3D,
222
+ *,
223
+ include_refs: bool = True,
224
+ ) -> pv.UnstructuredGrid: ...
225
+
226
+
227
+ @overload
228
+ def to_pyvista(
229
+ mesh: MmgMesh2D,
230
+ *,
231
+ include_refs: bool = True,
232
+ ) -> pv.PolyData: ...
233
+
234
+
235
+ @overload
236
+ def to_pyvista(
237
+ mesh: MmgMeshS,
238
+ *,
239
+ include_refs: bool = True,
240
+ ) -> pv.PolyData: ...
241
+
242
+
243
+ def to_pyvista(
244
+ mesh: MmgMesh3D | MmgMesh2D | MmgMeshS,
245
+ *,
246
+ include_refs: bool = True,
247
+ ) -> pv.UnstructuredGrid | pv.PolyData:
248
+ """Convert an mmgpy mesh to a PyVista mesh.
249
+
250
+ Args:
251
+ mesh: mmgpy mesh instance (MmgMesh3D, MmgMesh2D, or MmgMeshS).
252
+ include_refs: If True, include element references as cell_data.
253
+
254
+ Returns:
255
+ PyVista mesh:
256
+ - MmgMesh3D → UnstructuredGrid with tetrahedra
257
+ - MmgMesh2D → PolyData with triangular faces (z=0)
258
+ - MmgMeshS → PolyData with triangular faces
259
+
260
+ Raises:
261
+ TypeError: If mesh is not an mmgpy mesh type.
262
+
263
+ Example:
264
+ >>> from mmgpy import MmgMesh3D, to_pyvista
265
+ >>>
266
+ >>> mesh = MmgMesh3D(vertices, elements)
267
+ >>> mesh.remesh(hmax=0.1)
268
+ >>> grid = to_pyvista(mesh)
269
+ >>> grid.plot()
270
+
271
+ """
272
+ if isinstance(mesh, MmgMesh3D):
273
+ return _mmg3d_to_pyvista(mesh, include_refs=include_refs)
274
+ if isinstance(mesh, MmgMesh2D):
275
+ return _mmg2d_to_pyvista(mesh, include_refs=include_refs)
276
+ if isinstance(mesh, MmgMeshS):
277
+ return _mmgs_to_pyvista(mesh, include_refs=include_refs)
278
+
279
+ msg = f"Unsupported mesh type: {type(mesh)}"
280
+ raise TypeError(msg)
281
+
282
+
283
+ def _mmg3d_to_pyvista(mesh: MmgMesh3D, *, include_refs: bool) -> pv.UnstructuredGrid:
284
+ """Convert MmgMesh3D to PyVista UnstructuredGrid."""
285
+ vertices = mesh.get_vertices()
286
+
287
+ if include_refs:
288
+ elements, refs = mesh.get_elements_with_refs()
289
+ else:
290
+ elements = mesh.get_elements()
291
+ refs = None
292
+
293
+ grid = pv.UnstructuredGrid({pv.CellType.TETRA: elements}, vertices)
294
+
295
+ if refs is not None:
296
+ grid.cell_data["refs"] = refs
297
+
298
+ return grid
299
+
300
+
301
+ def _mmg2d_to_pyvista(mesh: MmgMesh2D, *, include_refs: bool) -> pv.PolyData:
302
+ """Convert MmgMesh2D to PyVista PolyData."""
303
+ vertices_2d = mesh.get_vertices()
304
+ vertices_3d = np.column_stack([vertices_2d, np.zeros(len(vertices_2d))])
305
+
306
+ if include_refs:
307
+ triangles, refs = mesh.get_triangles_with_refs()
308
+ else:
309
+ triangles = mesh.get_triangles()
310
+ refs = None
311
+
312
+ faces = np.hstack(
313
+ [np.full((len(triangles), 1), _TRIANGLE_VERTS), triangles],
314
+ ).ravel()
315
+ polydata = pv.PolyData(vertices_3d, faces=faces)
316
+
317
+ if refs is not None:
318
+ polydata.cell_data["refs"] = refs
319
+
320
+ return polydata
321
+
322
+
323
+ def _mmgs_to_pyvista(mesh: MmgMeshS, *, include_refs: bool) -> pv.PolyData:
324
+ """Convert MmgMeshS to PyVista PolyData."""
325
+ vertices = mesh.get_vertices()
326
+
327
+ if include_refs:
328
+ triangles, refs = mesh.get_triangles_with_refs()
329
+ else:
330
+ triangles = mesh.get_triangles()
331
+ refs = None
332
+
333
+ faces = np.hstack(
334
+ [np.full((len(triangles), 1), _TRIANGLE_VERTS), triangles],
335
+ ).ravel()
336
+ polydata = pv.PolyData(vertices, faces=faces)
337
+
338
+ if refs is not None:
339
+ polydata.cell_data["refs"] = refs
340
+
341
+ return polydata
342
+
343
+
344
+ def _mmg3d_from_pyvista(
345
+ cls: type[MmgMesh3D], # noqa: ARG001
346
+ mesh: pv.UnstructuredGrid | pv.PolyData,
347
+ ) -> MmgMesh3D:
348
+ """Create MmgMesh3D from a PyVista mesh."""
349
+ if not isinstance(mesh, pv.UnstructuredGrid):
350
+ msg = "MmgMesh3D.from_pyvista requires UnstructuredGrid input"
351
+ raise TypeError(msg)
352
+ return _from_pyvista_to_mmg3d(mesh)
353
+
354
+
355
+ def _mmg2d_from_pyvista(
356
+ cls: type[MmgMesh2D], # noqa: ARG001
357
+ mesh: pv.UnstructuredGrid | pv.PolyData,
358
+ ) -> MmgMesh2D:
359
+ """Create MmgMesh2D from a PyVista mesh."""
360
+ if not isinstance(mesh, pv.PolyData):
361
+ msg = "MmgMesh2D.from_pyvista requires PolyData input"
362
+ raise TypeError(msg)
363
+ return _from_pyvista_to_mmg2d(mesh)
364
+
365
+
366
+ def _mmgs_from_pyvista(
367
+ cls: type[MmgMeshS], # noqa: ARG001
368
+ mesh: pv.UnstructuredGrid | pv.PolyData,
369
+ ) -> MmgMeshS:
370
+ """Create MmgMeshS from a PyVista mesh."""
371
+ if not isinstance(mesh, pv.PolyData):
372
+ msg = "MmgMeshS.from_pyvista requires PolyData input"
373
+ raise TypeError(msg)
374
+ return _from_pyvista_to_mmgs(mesh)
375
+
376
+
377
+ def _mmg3d_to_pyvista_method(
378
+ self: MmgMesh3D,
379
+ *,
380
+ include_refs: bool = True,
381
+ ) -> pv.UnstructuredGrid:
382
+ """Convert MmgMesh3D to a PyVista UnstructuredGrid."""
383
+ return _mmg3d_to_pyvista(self, include_refs=include_refs)
384
+
385
+
386
+ def _mmg2d_to_pyvista_method(
387
+ self: MmgMesh2D,
388
+ *,
389
+ include_refs: bool = True,
390
+ ) -> pv.PolyData:
391
+ """Convert MmgMesh2D to a PyVista PolyData."""
392
+ return _mmg2d_to_pyvista(self, include_refs=include_refs)
393
+
394
+
395
+ def _mmgs_to_pyvista_method(
396
+ self: MmgMeshS,
397
+ *,
398
+ include_refs: bool = True,
399
+ ) -> pv.PolyData:
400
+ """Convert MmgMeshS to a PyVista PolyData."""
401
+ return _mmgs_to_pyvista(self, include_refs=include_refs)
402
+
403
+
404
+ def add_pyvista_methods() -> None:
405
+ """Add PyVista methods to mesh classes.
406
+
407
+ Call this function to add `from_pyvista` classmethod and `to_pyvista`
408
+ instance method to MmgMesh3D, MmgMesh2D, and MmgMeshS classes.
409
+
410
+ These methods are automatically called at import time.
411
+ """
412
+ # Add classmethods - type ignores needed for monkey-patching pybind11 classes
413
+ MmgMesh3D.from_pyvista = classmethod(_mmg3d_from_pyvista) # type: ignore[attr-defined]
414
+ MmgMesh2D.from_pyvista = classmethod(_mmg2d_from_pyvista) # type: ignore[attr-defined]
415
+ MmgMeshS.from_pyvista = classmethod(_mmgs_from_pyvista) # type: ignore[attr-defined]
416
+
417
+ # Add instance methods
418
+ MmgMesh3D.to_pyvista = _mmg3d_to_pyvista_method # type: ignore[attr-defined]
419
+ MmgMesh2D.to_pyvista = _mmg2d_to_pyvista_method # type: ignore[attr-defined]
420
+ MmgMeshS.to_pyvista = _mmgs_to_pyvista_method # type: ignore[attr-defined]
421
+
422
+
423
+ __all__ = ["add_pyvista_methods", "from_pyvista", "to_pyvista"]
mmgpy/_version.py ADDED
@@ -0,0 +1,3 @@
1
+ """Version information."""
2
+
3
+ __version__ = "0.3.0"
mmgpy/_version.py.in ADDED
@@ -0,0 +1,3 @@
1
+ """Version information."""
2
+
3
+ __version__ = "@MMGPY_VERSION@"