# 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`](./formats/abaqus.md) | `.inp` | ✓ | ✓ | — |
| [`ansys`](./formats/ansys.md) | `.msh` | ✓ | ✓ | — |
| [`ansysInp`](./formats/ansysinp.md) | `.cdb`, `.inp` | ✓ | ✓ | — |
| [`avsucd`](./formats/avsucd.md) | `.avs` | ✓ | ✓ | — |
| [`cgns`](./formats/cgns.md) | `.cgns` | ✓ | ✓ | `h5py` |
| [`dex`](./formats/dex.md) | `.dex` | ✓ | ✓ | — |
| [`dolfin-xml`](./formats/dolfin.md) | `.xml` | ✓ | ✓ | — |
| [`exodus`](./formats/exodus.md) | `.e`, `.exo`, `.ex2` | ✓ | ✓ | `netCDF4` |
| [`flac3d`](./formats/flac3d.md) | `.f3grid` | ✓ | ✓ | — |
| [`flux`](./formats/flux.md) | `.pf3` | ✓ | ✓ | — |
| [`freefem`](./formats/freefem.md) | `.msh` | ✓ | ✓ | — |
| [`gmsh` / `gmsh22`](./formats/gmsh.md) | `.msh` | ✓ | ✓ | — |
| [`h5m`](./formats/h5m.md) | `.h5m` | ✓ | ✓ | `h5py` |
| [`hmf`](./formats/hmf.md) | `.hmf` | ✓ | ✓ | `h5py` |
| [`ip`](./formats/ip.md) | `.ip` | ✓ | ✓ | — |
| [`mdpa`](./formats/mdpa.md) | `.mdpa` | ✓ | ✓ | — |
| [`med`](./formats/med.md) | `.med` | ✓ | ✓ | `h5py` |
| [`medit`](./formats/medit.md) | `.mesh`, `.meshb` | ✓ | ✓ | — |
| [`mff`](./formats/mff.md) | `.mff` | ✓ | ✓ | — |
| [`mfm`](./formats/mfm.md) | `.mfm` | ✓ | ✓ | — |
| [`mphtxt`](./formats/mphtxt.md) | `.mphtxt` | ✓ | ✓ | — |
| [`nastran`](./formats/nastran.md) | `.bdf`, `.fem`, `.nas` | ✓ | ✓ | — |
| [`netgen`](./formats/netgen.md) | `.vol`, `.vol.gz` | ✓ | ✓ | — |
| [`neuroglancer`](./formats/neuroglancer.md) | (no extension) | ✓ | ✓ | — |
| [`obj`](./formats/obj.md) | `.obj` | ✓ | ✓ | — |
| [`off`](./formats/off.md) | `.off` | ✓ | ✓ | — |
| [`openfoam`](./formats/openfoam.md) | `.foam` | ✓ | — | — |
| [`permas`](./formats/permas.md) | `.post`, `.post.gz`, `.dato`, `.dato.gz` | ✓ | ✓ | — |
| [`ply`](./formats/ply.md) | `.ply` | ✓ | ✓ | — |
| [`stl`](./formats/stl.md) | `.stl` | ✓ | ✓ | — |
| [`su2`](./formats/su2.md) | `.su2` | ✓ | ✓ | — |
| [`svg`](./formats/svg.md) | `.svg` | — | ✓ | — |
| [`tecplot`](./formats/tecplot.md) | `.dat`, `.tec` | ✓ | ✓ | — |
| [`tetgen`](./formats/tetgen.md) | `.ele` / `.node` | ✓ | ✓ | — |
| [`ugrid`](./formats/ugrid.md) | `.ugrid` | ✓ | ✓ | — |
| [`unv`](./formats/unv.md) | `.unv` | ✓ | ✓ | — |
| [`vtk` / `vtk42` / `vtk51`](./formats/vtk.md) | `.vtk` | ✓ | ✓ | — |
| [`vtu`](./formats/vtu.md) | `.vtu` | ✓ | ✓ | — |
| [`wkt`](./formats/wkt.md) | `.wkt` | ✓ | ✓ | — |
| [`xdmf`](./formats/xdmf.md) | `.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.

**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](https://github.com/victorsndvg/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 XDMF `data_format="HDF"`) — C++ when built with `MESHIOPLUSPLUS_WITH_HDF5`, otherwise `h5py`. For `med`, the C++ core covers the mesh-representation part (points, tags, families, metadata, node orientation, `POG` ragged polygons) and defers the field/bitmask/gmsh-bridging/multi-mesh constructs to the Python reference; see [`med.md`](./formats/med.md#quirks-limitations).
- **netCDF** (`exodus`) — C++ when built with `MESHIOPLUSPLUS_WITH_NETCDF`, otherwise `netCDF4`.
- **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`)

```python
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`)

```python
meshioplusplus.vtu.write(filename, mesh,
    binary=True,
    compression="zlib",   # "zlib", "lzma", or None
    header_type=None,     # "UInt32" or "UInt64"
)
```

### VTK (`.vtk`)

```python
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`)

```python
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`)

```python
meshioplusplus.medit.write(filename, mesh,
    float_fmt=".16e",
)
```

### PLY (`.ply`)

```python
meshioplusplus.ply.write(filename, mesh,
    binary=True,
)
```

### STL (`.stl`)

```python
meshioplusplus.stl.write(filename, mesh,
    binary=False,
)
```

### MED (`.med`)

```python
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`](./formats/med.md).

### AnsysInp (`.cdb`, `.inp`)

`meshioplusplus.ansysInp.read(filename)` / `meshioplusplus.ansysInp.write(filename, mesh)` —
no extra options. See the [`.inp` note](#format-table) above for the
Abaqus extension collision.

### OpenFOAM (`.foam`, read-only)

`meshioplusplus.openfoam.read(filename)` — no extra options, no writer.

### CGNS (`.cgns`)

```python
meshioplusplus.cgns.write(filename, mesh,
    compression="gzip",
    compression_opts=4,
)
```

### Nastran (`.bdf`)

```python
meshioplusplus.nastran.write(filename, mesh,
    point_format="fixed-large",   # or "fixed-small", "free"
    cell_format="fixed-small",
)
```

### FLAC3D (`.f3grid`)

```python
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`, …).
