More Interchange Formats: glTF, 3MF, XDMF, NRRD, IGES
println("Julia ", VERSION)Julia 1.12.6
Overview
The dedicated tutorials cover the classic CAD/simulation formats (STL, OBJ, PLY, VTK, MSH, INP, STEP, DICOM, NIfTI). Rasmah also reads and writes a handful of modern and HPC interchange formats, each with a single job to do:
- glTF / GLB — the runtime 3D format for web viewers and game engines.
- 3MF — the additive-manufacturing format (a ZIP of OPC parts, in mm).
- XDMF — the HPC field-data format for time-series simulation output.
- NRRD / MHD — the two “ASCII header + raw voxels” scalar-volume formats.
- IGES — the legacy analytic BRep exchange format (export).
Every one of them round-trips: write it, read it back, and check you got the same geometry.
using Rasmah
dir = mktempdir() # a scratch directory for the files below"/tmp/jl_fW0wrq"
glTF and GLB (triangle meshes)
A TriangleMesh writes directly to glTF 2.0 (JSON + .bin) or the single-file binary .glb, and read_gltf reads both back:
m = icosphere(2)
write_gltf(m, joinpath(dir, "sphere.gltf"))
write_glb(m, joinpath(dir, "sphere.glb"))
m_gltf = read_gltf(joinpath(dir, "sphere.gltf"))
m_glb = read_gltf(joinpath(dir, "sphere.glb"))
println("glTF round-trip: ", size(m_gltf.vertices) == size(m.vertices))
println("GLB round-trip: ", length(m_glb.vertices) == length(m.vertices))glTF round-trip: true
GLB round-trip: true
3MF (additive manufacturing)
3MF stores the mesh in millimetres; write_3mf / read_3mf handle the OPC container for you:
write_3mf(m, joinpath(dir, "sphere.3mf"))
m_3mf = read_3mf(joinpath(dir, "sphere.3mf"))
println("3MF round-trip: ", length(m_3mf.vertices) == length(m.vertices))3MF round-trip: true
XDMF (tetrahedral fields and time series)
XDMF stores an unstructured mesh plus point/cell attributes. read_xdmf returns the mesh and its named attribute dictionary:
tm = tetrahedralize_box(1.0, 1.0, 1.0, 3, 3, 3)
write_xdmf(tm, joinpath(dir, "box.xmf"); point_data = Dict(:density => range(0, 1, length=size(tm.nodes, 2))))
result = read_xdmf(joinpath(dir, "box.xmf"))
println("XDMF mesh round-trip: ", size(result.mesh.nodes) == size(tm.nodes))
println("XDMF attributes: ", keys(result.attributes))XDMF mesh round-trip: true
XDMF attributes: [:density]
NRRD (scalar volumes)
NRRD wraps a DicomVolume (the same values + spacing + origin representation DICOM and NIfTI use):
vol = DicomVolume(zeros(4, 5, 6), [1.0, 1.0, 1.0], [0.0, 0.0, 0.0])
write_nrrd(vol, joinpath(dir, "vol.nrrd"))
vol2 = read_nrrd(joinpath(dir, "vol.nrrd"))
println("NRRD round-trip: ", size(vol2.values) == size(vol.values))NRRD round-trip: true
IGES (legacy BRep export)
IGES exports the exact BRep as its analytic surface/curve entities (planes, surfaces of revolution, and NURBS). It’s export-only — the format is a one-way bridge to legacy CAD systems:
b = brep(box(1.0, 1.0, 1.0))
write_iges(b, joinpath(dir, "box.igs"))
println("IGES written: ", filesize(joinpath(dir, "box.igs")) > 0)IGES written: true
Next steps
- Converting representations — which conversions are lossless and which are not.
- VTK: legacy and XML — the field-data format XDMF complements.
