Install
$ agentstack add mcp-loumalouomega-meshioplusplus ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- âś“ Prompt-injection patterns
- âś“ Secret / credential exfiltration
- âś“ Dangerous shell & filesystem operations
- âś“ Untrusted network calls
- âś“ Known-malicious package signatures
What it can access
- âś“ Network access No
- âś“ Filesystem access No
- âś“ Shell / process execution No
- âś“ Environment & secrets No
- âś“ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
I/O for mesh files.
[](https://pypi.org/project/meshioplusplus/) [](https://www.npmjs.com/package/@meshioplusplus/wasm) [](https://pypi.org/project/meshioplusplus/) [](https://doi.org/10.5281/zenodo.21629061)
[![C++][c++-image]][c++standard] [](https://pypi.org/project/meshioplusplus/) [](doc/c_api.md) [](doc/fortran.md) [](doc/julia.md) [](doc/r.md) [](https://www.npmjs.com/package/@meshioplusplus/wasm) [](src/viewer/)
[](https://github.com/loumalouomega/meshioplusplus) [](https://pypistats.org/packages/meshioplusplus) [](https://github.com/loumalouomega/meshioplusplus/releases/latest) [](https://github.com/loumalouomega/meshioplusplus/compare/v8.7.0...master) [](https://github.com/loumalouomega/meshioplusplus/commit/master)
[](https://github.com/loumalouomega/meshioplusplus/actions?query=workflow%3Aci) [](https://app.codecov.io/gh/loumalouomega/meshioplusplus) [](https://github.com/psf/black)
[c++-image]: https://img.shields.io/badge/C++-20-blue.svg?style=flat&logo=c%2B%2B [c++standard]: https://isocpp.org/std/the-standard
There are various mesh formats available for representing unstructured meshes. meshio++ can read and write all of the following and smoothly converts between them:
> Abaqus (.inp), > ANSYS msh (.msh), > Ansys/APDL coded database (.cdb, .inp), > AVS-UCD (.avs), > CGNS (.cgns), > DOLFIN XML (.xml), > COMSOL (.mphtxt), > Exodus (.e, .exo), > EnSight Gold (geometry, .case/.geo), > FLAC3D (.f3grid), > FLUX (mesh .pf3, field .dex), > FreeFem++ (.msh), > H5M (.h5m), > HMF (.hmf, experimental, meshio++-specific), > I-deas Universal / UNV (.unv), > ANSYS Fluent interpolation (.ip), > Kratos/MDPA (.mdpa), > Medit (.mesh, .meshb), > MED/Salome (.med), > Modulef (mesh .mfm, field .mff), > Nastran (bulk data, .bdf, .fem, .nas), > Netgen (.vol, .vol.gz), > Neuroglancer precomputed format, > Gmsh (format versions 2.2, 4.0, and 4.1, .msh), > OBJ (.obj), > OFF (.off), > OpenFOAM polyMesh (.foam, read-only), > PERMAS (.post, .post.gz, .dato, .dato.gz), > [PLY]() (.ply), > [STL]() (.stl), > Tecplot .dat, > TetGen .node/.ele, > Triangle .node/.ele/.poly, > SVG (output only; 2D direct, 3D via skin projection) (.svg), > TikZ (LaTeX output only; 2D direct, 3D via skin projection) (.tikz), > SU2 (.su2), > UGRID (.ugrid), > VTK (.vtk), > VTP (.vtp), > VTU (.vtu), > WKT (TIN) (.wkt), > XDMF (.xdmf, .xmf).
meshio++ ships a C++20 core (built with pybind11 + scikit-build-core) that reads and writes most formats with zero-copy numpy at the I/O boundary, plus optional HDF5/netCDF acceleration and a selectable parallel backend (AUTO by default — prefers OpenMP, then STL+TBB, then sequential; override with -DMESHIOPLUSPLUS_PARALLEL_BACKEND=..., including a bring-your-own Kokkos host backend). Every format has a pure-Python fallback, so behaviour and file compatibility are identical whether or not the native libraries are present. For a standalone C++ build use build/configure.sh (Linux/macOS) or build/configure.bat (Windows). Full docs (install, data model, per-format options, CLI) live at the documentation site (sources under doc/).
Install with
pip install meshioplusplus[all]
([all] pulls in all optional dependencies. By default, meshio++ only uses numpy.) You can then use the command-line tool
meshioplusplus convert input.msh output.vtk # convert between two formats
meshioplusplus info input.xdmf # show some info about the mesh
meshioplusplus compress input.vtu # compress the mesh file
meshioplusplus decompress input.vtu # decompress the mesh file
meshioplusplus binary input.msh # convert to binary format
meshioplusplus ascii input.msh # convert to ASCII format
meshioplusplus merge a.vtu b.vtu out.vtu # merge meshes (optional --weld)
meshioplusplus transform in.vtu out.vtu --translate 1,2,3 # affine transform
meshioplusplus clean in.vtu out.vtu --weld # weld / prune / de-dup
meshioplusplus crop in.vtu out.vtu --bbox 0,0,0,1,1,1 # subset by region
meshioplusplus split in.vtu 'out_{key}.vtu' --by type # split by criterion
meshioplusplus stats mesh.vtu # geometric statistics
meshioplusplus convert-cells in.msh out.vtu --mode simplexify # hexes -> tetra
meshioplusplus refine in.vtu out.vtu --levels 2 # uniform subdivision
meshioplusplus partition in.vtu 'out_{part}.vtu' --nparts 4 # N balanced parts
meshioplusplus smooth in.vtu out.vtu --iterations 20 # relax node positions
meshioplusplus interpolate src.vtu tgt.vtu out.vtu # transfer fields across meshes
meshioplusplus slice in.vtu out.vtu --normal 0,0,1 # planar cross-section
meshioplusplus isosurface in.vtu out.vtu --array T --values 350 # level set of a field
meshioplusplus data info mesh.vtu # summarize data arrays
meshioplusplus data calc in.vtu out.vtu --point "s = norm(v)" # derive a field
meshioplusplus data to-cell in.vtu out.vtu --keys T # point -> cell average
meshioplusplus data normalize in.vtu out.vtu --cell damage --to 0,1
with any of the supported formats.
The same verbs are available as a standalone C++ binary that needs no Python: grab a ready-to-run, statically-linked build for Linux/macOS/Windows from the GitHub Releases page, or build it yourself with build/configure.sh --cli --build (or -DMESHIOPLUSPLUS_BUILD_CLI=ON). It links only the C++ core. Named regions — and so point/cell sets — are carried there since v8.1.0, so info lists them and diff compares them; convert -s/-d is still Python-only.
In Python, simply do
import meshioplusplus
mesh = meshioplusplus.read(
filename, # string, os.PathLike, or a buffer/open file
# file_format="stl", # optional if filename is a path; inferred from extension
# see meshioplusplus convert --help for all possible formats
)
# mesh.points, mesh.cells, mesh.cells_dict, ...
# mesh.vtk.read() is also possible
to read a mesh. To write, do
import meshioplusplus
# two triangles and one quad
points = [
[0.0, 0.0],
[1.0, 0.0],
[0.0, 1.0],
[1.0, 1.0],
[2.0, 0.0],
[2.0, 1.0],
]
cells = [
("triangle", [[0, 1, 2], [1, 3, 2]]),
("quad", [[1, 4, 5, 3]]),
]
mesh = meshioplusplus.Mesh(
points,
cells,
# Optionally provide extra data on points, cells, etc.
point_data={"T": [0.3, -1.2, 0.5, 0.7, 0.0, -3.0]},
# Each item in cell data must match the cells array
cell_data={"a": [[0.1, 0.2], [0.4]]},
)
mesh.write(
"foo.vtk", # str, os.PathLike, or buffer/open file
# file_format="vtk", # optional if first argument is a path; inferred from extension
)
# Alternative with the same options
meshioplusplus.write_points_cells("foo.vtk", points, cells)
For both input and output, you can optionally specify the exact file_format (in case you would like to enforce ASCII over binary VTK, for example).
Skin extraction
meshioplusplus.extract_skin derives the boundary surface of a 3D volume mesh (the Kratos SkinDetectionProcess face-hashing algorithm — faces occurring exactly once are boundary; points are compacted, point_data follows):
vol = meshioplusplus.read("part.msh") # tetra/hexa/wedge/pyramid mesh
skin = meshioplusplus.extract_skin(vol) # triangle/quad/... surface mesh
The STL and PLY writers do this automatically for volume meshes (pass skin=False for the legacy drop-volume-cells behavior), and the SVG/TikZ writers render 3D meshes by projecting the skin through an orthographic camera (azimuth/elevation/roll in degrees, default the classic CAD isometric view) with painter's-algorithm depth ordering — that is exactly how the Stanford-bunny logo above is drawn.
Publication-quality vector figures
The SVG and TikZ writers can colour each face by a data array, turning them into figures you can drop straight into a paper — resolution-independent, and with no extra dependency: the colormaps are built into the core.
annotated = meshioplusplus.attach_quality(mesh)
meshioplusplus.write(
"quality.svg", annotated,
color_by="quality:scaled_jacobian", # or any point_data / cell_data name
cmap="viridis", # viridis / coolwarm / turbo
colorbar=True,
)
The bundled bracket coloured by element quality — the same figure tools/gen_doc_images.py regenerates.
Point data colours a face by the mean of its corner values, cell data by its owning cell's value — for a volume mesh, tracked through the extracted skin's parent-cell provenance, so a per-cell material or metric lands on the right facet. Multi-component arrays reduce to a component or to their magnitude; vmin/vmax set the range (default: the drawn faces' finite range), and non-finite values take nan_color. From the command line:
meshioplusplus convert mesh.vtu figure.svg --color-by temperature --colorbar
Colouring is available from Python, from C++ directly, and from both CLIs; the flat C/Fortran/WebAssembly bindings reach these writers through the shared registry and always emit the default styling.
Surface extraction
meshioplusplus.extract_surface is the general form of skin extraction: it picks the dimension automatically (a volume mesh → boundary faces, a 2D surface mesh → boundary edges) and can record each facet's parent cell id (record_parent_ids=True). See the surface extraction docs (doc/extract_surface.md).
surf = meshioplusplus.extract_surface(vol) # faces (or edges for a 2D mesh)
edges = meshioplusplus.extract_surface(sheet, record_parent_ids=True)
Mesh quality
meshioplusplus.compute_quality scores every cell on a set of geometric quality metrics (area/volume, scaled Jacobian, aspect ratio, skewness, interior/dihedral angles, warpage) and flags inverted/degenerate cells; attach_quality writes them back as cell_data. See doc/mesh_quality.md.
report = meshioplusplus.compute_quality(mesh)
print(report["num_inverted"], "inverted cells")
annotated = meshioplusplus.attach_quality(mesh) # metrics as cell_data
Reordering / renumbering
meshioplusplus.reorder renumbers nodes and elements to reduce sparse-matrix bandwidth (Reverse Cuthill–McKee) or improve cache locality (Morton / Hilbert space-filling curves). It is a pure permutation — geometry and all data preserved — and returns the applied node/cell permutations so external arrays can be remapped. compute_bandwidth measures the before/after connectivity bandwidth. See doc/reorder.md.
out = meshioplusplus.reorder(mesh, method="rcm") # "morton" / "hilbert" too
out, node_perm, cell_perms = meshioplusplus.reorder(mesh, return_permutation=True)
print(meshioplusplus.compute_bandwidth(mesh), "->", meshioplusplus.compute_bandwidth(out))
Comparison (diff)
meshioplusplus.diff compares two meshes and reports whether they are equivalent within a tolerance (`abserr tetra quadratic = meshioplusplus.convertcells(mesh, mode="elevate")
Each mode is idempotent on cells it does not apply to, so it is safe on a mixed-order mesh, and output is byte-identical across mesh backends and thread counts.
#### Refinement
**`meshioplusplus.refine`** subdivides every cell into congruent children of the *same* cell type, increasing a mesh's resolution: `line` → 2, `triangle` → 4, `quad` → 4, `tetra` → 8, `wedge` → 8, `hexahedron` → 8, with `levels=n` applying the templates `n` times. See `doc/refine.md`.
New nodes sit at the midpoints of the parent's edges, quad faces and (hexahedron only) body, and carry the mean of that entity's corner values for every `point_data` array — so a linear field is interpolated exactly. Mid-edge and quad-face-centre nodes are **shared** between every cell touching the entity, so the refined mesh has no hanging nodes; each parent's `cell_data` row is replicated to its children.
```python
fine = meshioplusplus.refine(mesh) # one level
finer = meshioplusplus.refine(mesh, levels=2) # 64x the cells in 3D
tagged = meshioplusplus.refine(mesh, record_parent_ids=True)
Children inherit the parent's orientation (zero newly-inverted cells for a well-oriented input), and volume is conserved — exactly for tetra always, and for wedge/hexahedron when the parent is affine. Higher-order cells, pyramid, and ragged blocks have no same-type subdivision and raise by name.
Decimation
meshioplusplus.decimate is refine's inverse: it reduces a surface mesh's face count by greedy quadric-error-metric (Garland–Heckbert) edge collapse, preserving shape, boundaries and features. Exactly one stopping criterion is given — ratio (fraction of faces to keep), target_faces, or max_error — and the output is all-triangle (quad/polygon blocks are triangulated first, block structure kept 1:1). See doc/decimate.md.
coarse = meshioplusplus.decimate(mesh, ratio=0.25) # keep 25% of the faces
coarse = meshioplusplus.decimate(mesh, target_faces=5000) # absolute face budget
coarse, report = meshioplusplus.decimate(mesh, max_error=1e-6, return_report=True)
Boundary vertices (once-used-edge test)
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: loumalouomega
- Source: loumalouomega/meshioplusplus
- License: MIT
- Homepage: https://loumalouomega.github.io/meshioplusplus/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.