Low-level indexed triangle utilities used by the exporter.
A mesh has :vertices (world {x, y, z} tuples) and :triangles
(zero-based {a, b, c} indices into that vertex list). Native meshes
from OCEx.mesh/3 need welding to share indices across face boundaries.
These functions return maps or binaries directly, not tagged results.
They assume trusted, well-formed mesh data and may raise on malformed
input. For normal print output, use Smith.export/3, which handles
meshing, checks, serialization, and files together.
Summary
Functions
Parses a binary STL and welds the resulting vertices.
Reports edge connectivity, winding, counts, and signed mesh volume.
Serializes a mesh as a geometry-only 3MF ZIP archive.
Serializes a mesh as binary STL, returning bytes without writing a file.
Merges vertices assigned to the same grid cell and remaps triangles.
Functions
Parses a binary STL and welds the resulting vertices.
Requires an 80-byte header, a 32-bit little-endian triangle count, and
exactly 50 bytes per triangle. Facet normals and attribute words are
ignored. Vertices are welded with the default tolerance of weld/2;
the result is a mesh map, not a tagged result.
This utility is for trusted binary data. ASCII STL, truncated records, trailing bytes, and unsupported float encodings are not handled as tagged errors and may raise Elixir exceptions.
iex> {:ok, box} = OCEx.box(2, 3, 4)
iex> {:ok, raw} = OCEx.mesh(box)
iex> mesh = raw |> Smith.Mesh.to_stl() |> Smith.Mesh.from_stl()
iex> {length(mesh.vertices), length(mesh.triangles)}
{8, 12}
Reports edge connectivity, winding, counts, and signed mesh volume.
Returns a map directly:
:watertight— at least one edge exists and every edge belongs to exactly two triangles.:winding_consistent— each shared edge is traversed in opposite directions by its two triangles. For an empty mesh this istrue.:components— number of triangle groups connected by shared edges.:volume— signed volume in cubic model units.:vertices,:triangles— input list lengths.
It does not weld vertices first. Call weld/2 on native face meshes
before inspecting connectivity. Consistent winding does not necessarily
mean outward winding; an entirely reversed shell has negative volume.
The checks do not detect arbitrary triangle self-intersections or prove
manifold vertex neighborhoods.
iex> {:ok, box} = OCEx.box(2, 3, 4)
iex> {:ok, raw} = OCEx.mesh(box)
iex> report = raw |> Smith.Mesh.weld() |> Smith.Mesh.inspect()
iex> {report.watertight, report.winding_consistent, report.components,
...> report.volume}
{true, true, 1, 24.0}
Serializes a mesh as a geometry-only 3MF ZIP archive.
Returns archive bytes without writing a file. The archive contains one mesh object and one build item, with millimeter units. Disconnected components remain within that one object. There are no materials, printer profiles, support settings, or slicer configuration.
This function does not validate the mesh. Use Smith.export/3 to run
print mesh checks before producing files.
Serializes a mesh as binary STL, returning bytes without writing a file.
Writes 32-bit float coordinates and calculated facet normals. STL does
not store units. Vertex precision can change during serialization, so
Smith.Export.mesh/3 checks the parsed STL rather than just this input.
No topology or volume validation is performed here.
Merges vertices assigned to the same grid cell and remaps triangles.
tolerance is the grid spacing in model units, default 1.0e-6. Each
coordinate is divided by that spacing and rounded to form a key. The
first vertex in each cell is retained at its original coordinates;
vertices are not snapped to the grid or averaged.
Triangles with repeated indices after welding are removed. Duplicate
triangles are removed regardless of winding. Collinear triangles with
three distinct indices are not removed. Only :vertices and
:triangles are retained in the returned map.
This function assumes valid indices and a positive tolerance. It returns a mesh directly and may raise on malformed data.