/ concept-collection / mesh-converter
Sign in
concept-collection / mesh-converter
mesh-converter / README.md
90 lines · 4.4 KBPreviewCodeBlameHistoryRaw
1# mesh-converter
3A static web app for converting meshes between formats: upload a mesh file,
4inspect it in an interactive 3D view (shaded, wireframe, shaded + wireframe,
5or points), and download it in a format of your choice. Formats differ in what they can store, and the UI shows exactly which
6attributes (normals, colors) would be dropped by a lossy conversion.
8Conversion is powered by [meshio](https://github.com/nschloe/meshio) running
9in the browser via [Pyodide](https://pyodide.org) — no server, all mesh I/O
10happens client-side. The first visit downloads the Python runtime (~15 MB from
11the jsDelivr CDN, cached afterwards).
13| Format | Extension | positions/faces | normals | colors | notes |
14| --- | --- | --- | --- | --- | --- |
15| PLY (Polygon File Format) | `.ply` | ✓ | ✓ | ✓ | |
16| Wavefront OBJ | `.obj` | ✓ | ✓ | — | |
17| STL | `.stl` | ✓ | — | — | binary |
18| OFF (Object File Format) | `.off` | ✓ | — | — | |
19| VTK legacy | `.vtk` | ✓ | ✓ | ✓ | |
20| VTU (VTK XML) | `.vtu` | ✓ | ✓ | ✓ | |
21| Gmsh MSH | `.msh` | ✓ | — | — | |
22| XDMF | `.xdmf` | ✓ | ✓ | ✓ | h5py† |
23| MED (Salome) | `.med` | ✓ | ✓ | ✓ | h5py† |
24| H5M (MOAB) | `.h5m` | ✓ | ✓ | ✓ | h5py† |
25| AVS-UCD | `.avs` | ✓ | ✓ | ✓ | |
26| Abaqus | `.inp` | ✓ | — | — | |
27| Nastran | `.bdf` | ✓ | — | — | |
28| Medit | `.mesh` | ✓ | — | — | |
29| Netgen | `.vol` | ✓ | — | — | |
30| MDPA (Kratos) | `.mdpa` | ✓ | — | — | |
31| Tecplot | `.dat` | ✓ | — | — | |
32| DOLFIN XML | `.xml` | ✓ | — | — | |
33| PERMAS | `.post` | ✓ | — | — | |
35† HDF5-based formats need the h5py Pyodide package (~4 MB); it is loaded
36lazily the first time such a format is used, so the default footprint stays
37small.
39✓ marks what this app preserves when writing the format: vertex normals map to
40each format's native representation (`nx/ny/nz` properties in PLY, `vn` lines
41in OBJ, a `Normals` point-data array elsewhere) and vertex colors likewise
42(`red/green/blue` in PLY, an `RGB` point-data array elsewhere). On import,
43quads and polygons are fan-triangulated; volume cells are skipped.
45Some meshio formats are deliberately absent: ansys, cgns, su2, and ugrid
46cannot roundtrip their own output in meshio 5.3.5; exodus fails writing under
47wasm; flac3d holds volume cells only; wkt's reader hangs on non-toy meshes;
48tetgen spans two files; svg is write-only.
50A built-in sample mesh (a rainbow torus with normals and vertex colors) is
51available from the UI for trying things out without a file, and `examples/`
52holds it pre-exported in a few formats. An on-demand "estimate export sizes"
53action serializes the loaded mesh to every format in memory and shows the
54resulting file sizes in the format table and export dropdown.
56A loaded mesh can be shared as a self-contained link: "Copy share link" packs
57the original uploaded file (byte-identical, in its original format) together
58with the chosen export format and view mode into the URL fragment —
59deflate-compressed and base64url-encoded after `#share=`. Nothing is uploaded;
60the data lives in the URL itself, so whoever opens the link sees the mesh and
61can download it in any format. Links are capped at 65,000 characters (roughly
62a 100–300 KB mesh file, depending on how well it compresses); beyond that the
63app says the mesh is too large to share by URL.
65## Development
67```bash
68npm install
69npm run dev # local dev server
70npm run build # static build in dist/
71```
73Built with Vite, React, TypeScript, and three.js (react-three-fiber).
75## How it works
77- `src/mesh/bridge.py` runs inside Pyodide: it reads/writes mesh files with
78 meshio and exchanges arrays with JS as raw little-endian buffers through
79 Pyodide's in-memory filesystem.
80- `src/mesh/meshio.ts` loads Pyodide (script tag in `index.html`), installs
81 meshio via micropip, and wraps the bridge in typed async
82 `parseMeshFile`/`serializeMesh` functions built on the internal `MeshData`
83 representation (typed arrays of positions, triangle indices, optional
84 normals/colors).
85- `src/mesh/formats.ts` declares the supported formats and which attributes
86 each preserves; the upload, capability table, and loss-warning UI derive
87 from it. To add a meshio-supported format, add a descriptor there (with
88 `pyodidePackages` if it needs extra prebuilt packages such as h5py) and, if
89 it stores normals/colors in a format-specific way, teach
90 `bridge.py` how to map them.
moveopenescclose