Supported Formats
Format table
Each format name links to a detailed reference page (structure, options, data mapping, and the C++ vs Python behaviour).
| Format name | Extensions | Read | Write | Extra dependencies |
|---|---|---|---|---|
abaqus | .inp | ✓ | ✓ | — |
ansys | .msh | ✓ | ✓ | — |
ansysInp | .cdb, .inp | ✓ | ✓ | — |
avsucd | .avs | ✓ | ✓ | — |
cgns | .cgns | ✓ | ✓ | h5py |
dex | .dex | ✓ | ✓ | — |
dolfin-xml | .xml | ✓ | ✓ | — |
exodus | .e, .exo, .ex2 | ✓ | ✓ | netCDF4 |
flac3d | .f3grid | ✓ | ✓ | — |
flux | .pf3 | ✓ | ✓ | — |
freefem | .msh | ✓ | ✓ | — |
gmsh / gmsh22 | .msh | ✓ | ✓ | — |
h5m | .h5m | ✓ | ✓ | h5py |
hmf | .hmf | ✓ | ✓ | h5py |
ip | .ip | ✓ | ✓ | — |
mdpa | .mdpa | ✓ | ✓ | — |
med | .med | ✓ | ✓ | h5py |
medit | .mesh, .meshb | ✓ | ✓ | — |
mff | .mff | ✓ | ✓ | — |
mfm | .mfm | ✓ | ✓ | — |
mphtxt | .mphtxt | ✓ | ✓ | — |
nastran | .bdf, .fem, .nas | ✓ | ✓ | — |
netgen | .vol, .vol.gz | ✓ | ✓ | — |
neuroglancer | (no extension) | ✓ | ✓ | — |
obj | .obj | ✓ | ✓ | — |
off | .off | ✓ | ✓ | — |
openfoam | .foam | ✓ | — | — |
permas | .post, .post.gz, .dato, .dato.gz | ✓ | ✓ | — |
ply | .ply | ✓ | ✓ | — |
stl | .stl | ✓ | ✓ | — |
su2 | .su2 | ✓ | ✓ | — |
svg | .svg | — | ✓ | — |
tecplot | .dat, .tec | ✓ | ✓ | — |
tetgen | .ele / .node | ✓ | ✓ | — |
tikz | .tikz | — | ✓ | — |
ugrid | .ugrid | ✓ | ✓ | — |
unv | .unv | ✓ | ✓ | — |
vtk / vtk42 / vtk51 | .vtk | ✓ | ✓ | — |
vtu | .vtu | ✓ | ✓ | — |
wkt | .wkt | ✓ | ✓ | — |
xdmf | .xdmf, .xmf | ✓ | ✓ | h5py (for HDF data) |
Note on .msh: ansys, freefem, and gmsh all use .msh. When writing without an explicit file_format, meshio++ picks gmsh if the mesh carries gmsh-native tags (gmsh:physical/gmsh:geometrical/gmsh:dim_tags) or MED-derived tags (cell_tags/point_tags/med:*), else falls back to the first registered candidate (ansys). When reading, meshio++ tries the registered formats in order and uses the first that parses the file. Specify file_format explicitly (e.g. file_format="freefem") to avoid ambiguity either way.
Note on .inp: abaqus and ansysInp both use .inp. abaqus is registered first, so plain extension-based dispatch resolves to Abaqus by default; pass file_format="ansysInp" (or call meshioplusplus.ansysInp.read/write directly) to select the Ansys/APDL reader for a .inp file.
Note on tetgen: The format spans two files (.node + .ele). It cannot be read from or written to a buffer.
Note on svg: Write-only, 2D meshes only. C++ core with a Python fallback.
Note on tikz: Write-only, 2D meshes only; emits a standalone (directly pdflatex-compilable) LaTeX/TikZ document by default (standalone=False for a bare tikzpicture snippet). C++ core (byte-identical to the Python reference) with a Python fallback.
Note on openfoam: Read-only; a directory-based format (points/faces/owner/neighbour/boundary under constant/polyMesh), not a single file.
Note on mfm: Single element type per file (non-hybrid), linear elements only.
Note on FEconv-derived formats (unv, mfm, freefem, mphtxt, flux, mff, dex, ip): These readers/writers were implemented against the FEconv format documentation and public format specs (FEconv is GPL; no FEconv code or data is used — MIT-clean, with fixtures generated by round-trip). unv handles the parabolic mid-node "sandwich" ordering, maps permanent groups (datasets 2467/2477/2452/2435/2432/2430) to point_sets/cell_sets, and reads/writes field datasets (2414, and legacy 55/57 in Code-Aster mode) as point_data/cell_data; mphtxt and flux round-trip per-element region references as cell_data (mphtxt:geom, pf3:ref). Node orderings for higher-order elements round-trip losslessly but may differ from the originating tool's internal ordering for some element types.
Note on the field-only formats (mff, dex, ip): These carry result data, not geometry. They read into a geometry-less Mesh (no cells) with the field(s) in point_data; dex/ip also populate points from the coordinates in the file, while mff carries no coordinates (its points has zero columns and only the field values round-trip). To attach a field to a mesh, read the field file and the mesh file separately and copy the field Mesh's point_data onto the geometry Mesh — there is no fixed naming convention pairing a field file with its mesh (unlike TetGen's .node/.ele).
Native acceleration and fallbacks
meshio++ ships a C++ core (meshioplusplus._core, built with pybind11 + scikit-build-core). Most formats read and write through the C++ core with zero-copy numpy at the I/O boundary; each has a pure-Python fallback that is used automatically when the C++ path can't handle a file or when the extension was built without an optional dependency:
- HDF5 (
cgns,h5m,hmf,med, and XDMFdata_format="HDF") — C++ when built withMESHIOPLUSPLUS_WITH_HDF5, otherwiseh5py. Formed, the C++ core covers the mesh-representation part (points, tags, families, metadata, node orientation,POGragged polygons) and defers the field/bitmask/gmsh-bridging/multi-mesh constructs to the Python reference; seemed.md. - netCDF (
exodus) — C++ when built withMESHIOPLUSPLUS_WITH_NETCDF, otherwisenetCDF4. - zlib (VTU zlib compression) — C++ when built with
MESHIOPLUSPLUS_WITH_ZLIB, otherwise the Python stdlib.
Behaviour and file compatibility are identical either way; the native paths are only faster. Install the optional runtime deps with pip install meshioplusplus[all].
Format-specific write options
All writers are called as meshioplusplus.write(filename, mesh, file_format=..., **kwargs) or mesh.write(filename, **kwargs). The **kwargs depend on the format.
Gmsh (.msh)
meshioplusplus.gmsh.write(filename, mesh,
fmt_version="4.1", # "2.2", "4.0", or "4.1"
binary=True,
float_fmt=".16e",
)Use file_format="gmsh22" to write version 2.2 via the generic meshioplusplus.write.
VTU (.vtu)
meshioplusplus.vtu.write(filename, mesh,
binary=True,
compression="zlib", # "zlib", "lzma", or None
header_type=None, # "UInt32" or "UInt64"
)VTK (.vtk)
meshioplusplus.vtk.write(filename, mesh,
binary=True,
# For version selection use file_format="vtk42" or "vtk51"
)file_format="vtk" writes VTK 5.1. file_format="vtk42" or "vtk51" select specific versions.
XDMF (.xdmf, .xmf)
meshioplusplus.xdmf.write(filename, mesh,
data_format="HDF", # "HDF", "XML", or "Binary"
compression="gzip", # h5py compression filter (HDF only)
compression_opts=4, # compression level
)With data_format="HDF", meshio++ writes a companion .h5 file alongside the .xdmf. With "XML", all data is embedded in the XML. With "Binary", data is written to separate .bin files.
Medit (.mesh)
meshioplusplus.medit.write(filename, mesh,
float_fmt=".16e",
)PLY (.ply)
meshioplusplus.ply.write(filename, mesh,
binary=True,
)STL (.stl)
meshioplusplus.stl.write(filename, mesh,
binary=False,
)MED (.med)
meshioplusplus.med.write(filename, mesh,
med_version="4.1.0", # MAJ.MIN.REL written to INFOS_GENERALES
)MED does not support compression. meshioplusplus.med.read_med_multi/ write_med_multi read/write files containing several meshes — see med.md.
AnsysInp (.cdb, .inp)
meshioplusplus.ansysInp.read(filename) / meshioplusplus.ansysInp.write(filename, mesh) — no extra options. See the .inp note above for the Abaqus extension collision.
OpenFOAM (.foam, read-only)
meshioplusplus.openfoam.read(filename) — no extra options, no writer.
CGNS (.cgns)
meshioplusplus.cgns.write(filename, mesh,
compression="gzip",
compression_opts=4,
)Nastran (.bdf)
meshioplusplus.nastran.write(filename, mesh,
point_format="fixed-large", # or "fixed-small", "free"
cell_format="fixed-small",
)FLAC3D (.f3grid)
meshioplusplus.flac3d.write(filename, mesh,
float_fmt=".16e",
binary=False,
)SU2 (.su2)
meshioplusplus.su2.write(filename, mesh) — no extra options.
AVS-UCD (.avs)
meshioplusplus.avsucd.write(filename, mesh) — no extra options.
Abaqus (.inp)
meshioplusplus.abaqus.write(filename, mesh) — no extra options.
DOLFIN-XML (.xml)
meshioplusplus.dolfin.write(filename, mesh) — no extra options.
CLI format names
When using meshioplusplus convert -o <format>, use one of the format names from the first column of the table above (e.g. gmsh, gmsh22, vtk, vtk42, vtu, xdmf, …).