Skip to content

VTU — VTK XML UnstructuredGrid (.vtu)

The serial VTK XML UnstructuredGrid format: an XML container whose DataArray payloads can be inline ASCII, inline base64 binary, or appended raw/base64 binary, optionally block-compressed.

Format namevtu
Extensions.vtu
Read / Write✓ / ✓
Extra dependencies

Reading & writing

python
import meshioplusplus

mesh = meshioplusplus.read("mesh.vtu")
meshioplusplus.vtu.write("out.vtu", mesh,
    binary=True,
    compression="zlib",  # "zlib", "lzma", or None
    header_type=None,    # "UInt32" or "UInt64"
)
  • binary — base64-encoded binary DataArrays (True) or ASCII.
  • compression — block compression filter for binary data (vtkZLibDataCompressor/vtkLZMADataCompressor, or none).
  • header_type — integer type used for the binary block header/sizes (default UInt32).

File structure

xml
<VTKFile type="UnstructuredGrid" byte_order="..." [compressor="..."] [header_type="..."]>
  <UnstructuredGrid>
    <Piece NumberOfPoints=".." NumberOfCells="..">
      <Points><DataArray .../></Points>
      <Cells>
        <DataArray Name="connectivity" .../>
        <DataArray Name="offsets" .../>
        <DataArray Name="types" .../>
        <!-- polyhedron only: -->
        <DataArray Name="faces" .../><DataArray Name="faceoffsets" .../>
      </Cells>
      <PointData><DataArray Name=".." .../></PointData>
      <CellData><DataArray Name=".." .../></CellData>
    </Piece>
    <FieldData><DataArray Name=".." .../></FieldData>
  </UnstructuredGrid>
  <AppendedData encoding="base64">_<blob></AppendedData>
</VTKFile>

Binary encoding scheme (matching VTK's own convention exactly, so files round-trip byte-for-byte with other VTK tools):

  • Uncompressed: base64(header[header_type: total_nbytes] + raw_bytes).
  • Compressed: base64(header[nblocks, blocksize=32768, last_block_size, csize_0..csize_{n-1}]), followed by a separate base64 blob of concat(compressed_block_0..n-1). Header fields use the file's declared header_type dtype throughout.

Cell types

The full VTK cell set, including VTK Lagrange high-order cells (VTK_LAGRANGE_*). See VTK for the shared numeric type-code table.

Data mapping

<PointData>/<CellData> map generically to point_data/cell_data; cell_sets round-trip as extra data arrays with an info-level message (VTU has no native set concept). <FieldData>mesh.field_data.

Quirks & limitations

  • Raw/appended binary without valid XML: when appended binary data contains raw bytes that break XML parsing, the Python reader falls back to a regex-based manual split of the file into header/data/footer before continuing — the C++ reader does not implement this path at all and raises on any <AppendedData> section, forcing the Python fallback.
  • lzma compression is Python-only — the C++ reader/writer explicitly reject it.
  • Polyhedron cells are entirely unsupported by C++ (both reading and writing) — always routed to Python. Polyhedron cells also cannot be mixed with other cell types in the same file (a ValueError in the Python writer if attempted).
  • Multi-<Piece> files: the Python reader merges all pieces (concatenating points/cells/point_data across them); the C++ reader only supports a single <Piece> and throws otherwise.
  • A header_type other than the default (None, meaning UInt32) always forces the Python path.
  • 2D points are auto-padded to 3D on write (warning in Python; silent in C++).
  • Byte order: the Python writer records the system's native byte order in the byte_order attribute; the C++ writer always declares LittleEndian.

Notes

  • tests/meshes/vtu/00_raw_binary.vtu, 01_raw_binary_int64.vtu (uses an Int64 header type), 02_raw_compressed.vtu (zlib-compressed appended data) — each a 162-point, 64-cell tetra mesh, all exercised via the raw-binary fallback path described above.
  • The C++ core handles ASCII, uncompressed binary, and zlib binary (when built with MESHIO_WITH_ZLIB; otherwise the Python stdlib handles zlib too) — see native acceleration.

Released under the MIT License.