RasmahRasmah

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