Extending meshio++
Registering a custom format at runtime
Use meshioplusplus.register_format to add a format from outside the meshio++ package — for example, in application code or a third-party plugin.
import meshioplusplus
def my_read(filename):
# parse the file and return a meshioplusplus.Mesh
...
def my_write(filename, mesh, **kwargs):
# serialize mesh to the file
...
meshioplusplus.register_format(
"myformat", # format name used in file_format=
[".myfmt"], # file extensions (lowercase, with leading dot)
my_read, # reader function, or None if write-only
{"myformat": my_write}, # dict mapping format name(s) to writer function(s)
)After calling register_format, the format is immediately available through meshioplusplus.read, meshioplusplus.write, and the CLI.
A format can expose multiple writer variants under different names:
meshioplusplus.register_format(
"myformat",
[".myfmt"],
my_read,
{
"myformat": my_write_v2, # default
"myformat-v1": my_write_v1, # legacy variant
},
)Deregistering a format
meshioplusplus.deregister_format("myformat")This removes the format from all internal maps. Useful for overriding a built-in format or in tests.
Adding a new built-in format
Follow the existing module layout under src/meshioplusplus/:
Create the module directory
src/meshioplusplus/<format>/with an__init__.pythat exportsreadandwrite.Implement
read(filename)— return ameshioplusplus.Mesh.Implement
write(filename, mesh, **kwargs)— serialize the mesh.Add cell type mappings if the format uses its own element names. Convention: name them
_<format>_to_meshio_typeand_meshio_to_<format>_typein acommon.pyinside the module.Call
register_formatat module level (bottom of the main implementation file):pythonfrom .._helpers import register_format register_format("myformat", [".myfmt"], read, {"myformat": write})Import the module in
src/meshioplusplus/__init__.py— add it to both the import list and__all__.Add
tests/test_<format>.pyusinghelpers.write_read:pythonimport pytest import meshioplusplus from . import helpers @pytest.mark.parametrize("mesh", [helpers.tri_mesh, helpers.tet_mesh]) def test_myformat(mesh, tmp_path): helpers.write_read(tmp_path, meshioplusplus.myformat.write, meshioplusplus.myformat.read, mesh, atol=1e-15)
Reader and writer function signatures
def read(filename: str) -> meshioplusplus.Mesh:
...
def write(filename: str, mesh: meshioplusplus.Mesh, **kwargs) -> None:
...Readers should return writeable numpy arrays (set flags["WRITEABLE"] = True if needed). Writers should not mutate the mesh object.
Buffers
If your format can operate on open file buffers (not just paths), both read and write can accept buffer objects. Use meshioplusplus._files.is_buffer(obj, mode) to detect them:
from meshioplusplus._files import is_buffer
def read(filename):
if is_buffer(filename, "r"):
return _read_buffer(filename)
with open(filename, "rb") as f:
return _read_buffer(f)Note: formats that span multiple files (like TetGen) cannot support buffers.