I/O¶
This page documents how to load and save meshes with mmgpy.
mmgpy registers a Medit reader/writer plugin with PyVista on import, so pv.read("foo.mesh") and dataset.save("foo.mesh") both go through MMG's native I/O. Other formats are handled by PyVista directly; formats not natively supported by VTK require pip install pyvista[io] (which pulls in meshio).
Reading Meshes¶
Use pyvista.read for everything. With mmgpy imported, the same call also reads MMG's native Medit format:
import pyvista as pv
import mmgpy # noqa: F401 -- registers reader/writer + accessor
mesh = pv.read("input.mesh") # MMG native (via mmgpy's plugin)
mesh = pv.read("input.meshb") # MMG binary
mesh = pv.read("input.vtu") # VTK XML
mesh = pv.read("input.stl") # STL surface
The reader plugin auto-detects volumetric vs surface vs 2D meshes from the file's Dimension keyword and element population. A sibling .sol file (same stem, same directory) is auto-loaded into point_data / cell_data.
Deprecated: mmgpy.read
mmgpy.read(...) is kept as a compatibility shim that returns the old
internal Mesh wrapper. It emits a DeprecationWarning and will be
removed in 0.14. New code should call pv.read(...) and use the .mmg
accessor.
Supported Formats¶
| Format | Extensions | Notes |
|---|---|---|
| MMG native | .mesh, .meshb |
Recommended for MMG |
| VTK Legacy | .vtk |
Universal, ParaView compatible |
| VTK XML | .vtu, .vtp |
Modern VTK format |
| STL | .stl |
Surface meshes only |
| OBJ | .obj |
Surface meshes only |
| PLY | .ply |
Point cloud / mesh |
| GMSH | .msh |
Popular for FEM |
| Abaqus | .inp |
FEM format |
| CGNS | .cgns |
CFD format |
| Exodus II | .e, .exo |
Sandia format |
| ANSYS | .ansys |
FEM format |
| MED | .med |
Salome format |
| And many more... | Install pyvista[io] for meshio-backed formats |
Usage¶
import pyvista as pv
import mmgpy # noqa: F401 -- registers reader/writer + accessor
# Auto-detect format from extension
mesh = pv.read("input.mesh")
mesh = pv.read("input.vtk")
mesh = pv.read("input.stl")
print(f"Kind: {mesh.mmg.kind}") # MeshKind.TETRAHEDRAL, etc.
From PyVista Primitives¶
The accessor works on any pv.UnstructuredGrid or pv.PolyData, so you don't need an explicit conversion:
import pyvista as pv
import mmgpy # noqa: F401
# Surface
sphere = pv.Sphere(radius=1.0)
remeshed_surface = sphere.mmg.remesh(hsiz=0.1)
# Volume (needs tetrahedral cells)
volume = pv.Box().triangulate().delaunay_3d()
remeshed_volume = volume.mmg.remesh(hsiz=0.2)
# 2D plane
plane = pv.Plane()
remeshed_plane = plane.mmg.remesh(hsiz=0.1)
Saving Meshes¶
Use PyVista's save():
# MMG native (registered reader/writer)
remeshed_volume.save("output.mesh")
# VTK formats (handled by PyVista)
remeshed_volume.save("output.vtk")
remeshed_volume.save("output.vtu")
# Surface meshes also support .stl
remeshed_surface.save("output.stl")
Format is inferred from the file extension.
Complete Example¶
import pyvista as pv
import mmgpy # noqa: F401
mesh = pv.read("input.mesh")
print(f"Loaded {mesh.mmg.kind} mesh")
remeshed = mesh.mmg.remesh(hmax=0.1)
# Save to different formats
remeshed.save("output.mesh") # MMG native (fast)
remeshed.save("output.vtk") # For ParaView
remeshed.save("output.vtu") # VTK XML format
# Or build from a PyVista primitive
torus = pv.ParametricTorus()
remeshed_torus = torus.mmg.remesh(hmax=0.1)
remeshed_torus.save("torus.mesh")
Generating a 2D Mesh from Boundary Edges¶
mmgpy.mmg2d.generate triangulates a 2D domain described by a vertex+edge outline. Internally it drives the same MMG2D_mmg2dmesh entry point that the standalone executable uses when fed a .mesh file with no triangles.
import numpy as np
import pyvista as pv
import mmgpy # noqa: F401 -- registers the accessor
from mmgpy import mmg2d
verts = np.array(
[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]],
dtype=np.float64,
)
edges = np.array([[0, 1], [1, 2], [2, 3], [3, 0]], dtype=np.int32)
mesh = mmg2d.generate(verts, edges, hmax=0.1)
# Equivalent via the .mmg accessor: a line-only PolyData is auto-routed
# through the same generation path.
verts_3d = np.column_stack([verts, np.zeros(len(verts))])
lines = np.column_stack([np.full(len(edges), 2), edges]).ravel()
outline = pv.PolyData(verts_3d, lines=lines)
mesh = outline.mmg.remesh(hmax=0.1)
Tips¶
- MMG native format: Use
.meshfor fastest I/O with MMG (mmgpy's reader plugin handles ridges and reference markers natively). - VTK for visualization: Use
.vtkor.vtufor ParaView. - Surface formats: STL and OBJ are surface-only.
- Binary formats: Some formats support binary (faster, smaller).
- Field data: Most formats preserve scalar/vector fields via
point_data/cell_data.