File I/O
Overview
A design is only useful if it can leave Rasmah and come back. The file-I/O side of Rasmah reads and writes the geometry-exchange formats of the CAD, CAE, and 3D-printing worlds natively — no external library — so a mesh, a boundary representation, or a volume can be shared with any other tool.
Every format is a write_* / read_* pair, and each pair accepts either an IO stream or a file path. What a format stores decides the Rasmah type it maps to:
- a triangle mesh (
TriangleMesh) — the common surface format (STL, OBJ, PLY, glTF, …); - a volume mesh (
TetMesh) — for solver decks (MSH, INP, VTU); - an exact boundary representation (
BRep) — for the CAD exchange formats (STEP, IGES); - a scalar volume (
DicomVolume) — for medical imaging (DICOM, NIfTI); - a point cloud (
PointCloud) — for scan data (XYZ, PCD, PTX, LAS).
The guiding rule is round-trip fidelity: write a model out and read it back, and you get the same geometry. Every format's round trip is locked in by CI.
The read/write pattern
Writers and readers are polymorphic over IO and paths, so you can write to a file, an in-memory buffer, or a stream. A mesh round trip is the canonical shape of every format:
m = surface_mesh(sphere(1.0))
io = IOBuffer()
write_stl(m, io)
seekstart(io)
m2 = read_stl(io)
size(m.faces) == size(m2.faces)trueMesh formats
The surface- and volume-mesh formats:
Rasmah.write_stl — Function
write_stl(m, path::AbstractString; binary=true, unit=nothing)
write_stl(m, io::IO; binary=true, unit=nothing)Write a TriangleMesh m as an STL file, binary (default) or ASCII. The optional unit rescales the coordinates on write.
Rasmah.read_stl — Function
read_stl(path::AbstractString; unit=nothing)
read_stl(io::IO; unit=nothing)Read a binary or ASCII STL file into a TriangleMesh (vertices are welded so shared corners are merged). The optional unit rescales the coordinates on read.
Rasmah.write_obj — Function
write_obj(m::TriangleMesh, path::AbstractString; unit = nothing)
write_obj(m::TriangleMesh, io::IO; unit = nothing)Write m as an ASCII Wavefront OBJ file (optional unit rescales the coordinates on write).
Rasmah.read_obj — Function
read_obj(path::AbstractString; unit = nothing) -> TriangleMesh
read_obj(io::IO; unit = nothing) -> TriangleMeshRead an ASCII Wavefront OBJ file into a TriangleMesh (polygonal faces are fan-triangulated; optional unit rescales the coordinates).
Rasmah.write_ply — Function
write_ply(m::TriangleMesh, io; binary = false, unit = nothing)
write_ply(m::TriangleMesh, path; binary = false, unit = nothing)Write a TriangleMesh as a PLY file (ASCII by default, or binary little-endian with binary = true). unit optionally rescales from SI to the given length unit.
Rasmah.read_ply — Function
read_ply(path; unit = nothing) -> TriangleMesh
read_ply(io; unit = nothing) -> TriangleMeshRead a PLY file (ASCII, binary little-endian, or binary big-endian) into a TriangleMesh. Polygonal faces are fan-triangulated and extra vertex properties are discarded. unit optionally rescales from the given length unit to SI.
Rasmah.write_vtk — Function
write_vtk(mesh, io; binary = false, unit = nothing)
write_vtk(mesh, path; binary = false, unit = nothing)Write a TriangleMesh, TetMesh, or HexMesh as a legacy VTK (.vtk) file (ASCII by default, or big-endian binary with binary = true). A .vtp/.vtu extension writes the XML format instead. unit optionally rescales from SI.
Rasmah.read_vtk — Function
read_vtk(path; skip_unsupported = false, unit = nothing)
read_vtk(io; skip_unsupported = false, unit = nothing)Read a VTK file (legacy ASCII/binary or XML) into a TriangleMesh or TetMesh. skip_unsupported skips unsupported cell types instead of erroring. unit optionally rescales from the given length unit to SI.
Rasmah.write_vtu — Function
write_vtu(m, io; format=:ascii, point_data=nothing, cell_data=nothing, compact=false, unit=nothing)Write a TetMesh as a VTK XML UnstructuredGrid (.vtu) stream, with optional point_data/cell_data fields.
Rasmah.write_vtp — Function
write_vtp(m, io; format=:ascii, point_data=nothing, cell_data=nothing, compact=false, unit=nothing)Write a TriangleMesh as a VTK XML PolyData (.vtp) stream, with optional point_data/cell_data fields.
Rasmah.write_msh — Function
write_msh(m, path::AbstractString; binary=false, unit=nothing)
write_msh(m, io::IO; binary=false, unit=nothing)Write a TriangleMesh (type-2 triangles) or TetMesh (type-4 tetrahedra) as a gmsh MSH 2.2 file, ASCII or binary. The optional unit rescales the coordinates on write.
Rasmah.read_msh — Function
read_msh(path::AbstractString; unit=nothing)
read_msh(io::IO; unit=nothing)Read a gmsh MSH 2.2 or 4.1 file (ASCII or binary) into a TriangleMesh (from type-2 triangles) or TetMesh (from type-4 tetrahedra). The optional unit rescales the coordinates on read.
Rasmah.write_inp — Function
write_inp(m, path; kwargs...)
write_inp(m, io::IO; kwargs...)Write the mesh (and optionally a full Abaqus model deck) as an .inp input deck.
Rasmah.read_inp — Function
read_inp(path; kwargs...)
read_inp(io::IO; recover = false, unit = nothing)Read an Abaqus .inp input deck, auto-detecting the element type and returning the matching mesh (plus sets/material when recover = true).
STL, OBJ, and PLY store a bare triangle soup; VTK, MSH, and INP also carry the volume tetrahedra (and, for MSH/INP, physical groups or solver cards). A write_* followed by its read_* returns the same mesh.
glTF: the web format
glTF 2.0 is the runtime format of the web — the "JPEG of 3D" — used by viewers, augmented reality, and 3D-printing previews. Rasmah writes both the .gltf + .bin pair and the self-contained .glb container:
Rasmah.write_gltf — Function
write_gltf(m, path; color=nothing, metallic=1.0, roughness=1.0) -> pathWrite a TriangleMesh as a glTF 2.0 .gltf file (a JSON manifest plus a companion .bin buffer), or to an IO stream as a self-contained JSON document with the buffer inlined as a base64 data URI.
Theory
glTF — the "JPEG of 3D" — is the standard runtime format for web viewers, augmented reality, and 3D-printing preview. A .gltf scene is a JSON description of nodes, meshes, and materials referencing binary geometry in a sidecar .bin buffer; write_glb packs both into one container instead. color, metallic, and roughness set the physically-based material the viewer renders.
Arguments
m: theTriangleMeshto write.path/io: the destination (a path, or anIOstream).
Keyword options
color = nothing: optional RGB triple for the material.metallic = 1.0,roughness = 1.0: PBR material factors.
Returns
The path (or the io stream).
Example
julia> using Rasmah
julia> m = surface_mesh(sphere(1.0));
julia> io = IOBuffer();
julia> write_gltf(m, io);
julia> seekstart(io);
julia> size(read_gltf(io).faces) == size(m.faces)
trueRasmah.write_glb — Function
write_glb(m, path; color=nothing, metallic=1.0, roughness=1.0) -> pathWrite a TriangleMesh as a binary glTF 2.0 (.glb) file, packing the JSON and BIN chunks into a single container (the self-contained counterpart of write_gltf, which writes a .gltf + .bin pair).
Example
julia> using Rasmah
julia> m = surface_mesh(sphere(1.0));
julia> io = IOBuffer();
julia> write_glb(m, io);
julia> seekstart(io);
julia> size(read_gltf(io).faces) == size(m.faces)
trueSee also: write_gltf, read_gltf.
Rasmah.read_gltf — Function
read_gltf(path) -> TriangleMeshRead a glTF 2.0 file (.gltf or binary .glb) into a TriangleMesh, decoding the scene graph, applying node transforms, and welding the primitives into one surface. path may be a file path or an IO stream.
Example
julia> using Rasmah
julia> m = surface_mesh(sphere(1.0));
julia> io = IOBuffer();
julia> write_glb(m, io);
julia> seekstart(io);
julia> size(read_gltf(io).faces) == size(m.faces)
trueSee also: write_gltf, write_glb.
Exact CAD exchange
The formats that preserve exact topology — faces, edges, and vertices rather than a triangle approximation — are covered in Exact CAD exchange (STEP and IGES).
Volumes and points
The scalar-volume and point-cloud formats — medical imaging and scan data — are covered in Volumes and point clouds (DICOM, NIfTI, XYZ/PCD, and the PVD animation collection).
The native format
Rasmah's own .rasmah format serializes the feature graph itself (not the frozen geometry), so a model reopens as the editable parametric program it was built from:
Rasmah.write_rasmah — Function
write_rasmah(m, io::IO)
write_rasmah(m, path::AbstractString)Serialize a feature graph m to native .rasmah JSON, writing to an IO stream or a file path.
Rasmah.read_rasmah — Function
read_rasmah(io::IO)
read_rasmah(path::AbstractString)Read a native .rasmah JSON file back into a feature graph.
io = IOBuffer()
write_rasmah(sphere(1.0), io)
position(io)98A sphere(1.0) serializes to a compact 98-byte JSON document — the whole parameterized model, not a tessellation.
Next steps
To read and write the exact boundary representation, continue to Exact CAD exchange; for medical and scan data, Volumes and point clouds.
