Writes PLY files.
Rows are accumulated as iodata and handed to the file in batches. Building
output by appending binaries (acc <> row) copies the whole accumulator on
every row, turning a linear write into a quadratic one; iodata avoids that.
Element data is written in the header's declared order, and each row is serialised in property order — that order is the on-disk layout.
Values are validated before they are encoded
Binary encoding silently truncates: 300 written as uchar becomes 44,
a float too large for float32 becomes infinity, and a 256-item list with a
uchar count writes a length of zero — which then reads back as an empty
list through this library's own reader, losing the data without ever
reporting an error. Every value is therefore range-checked first, and a
violation returns {:error, %Ply.Error{}} naming the row and property.
Writing is atomic
Output goes to a temporary file in the destination directory and is renamed into place only after every row has been written and the declared counts verified. A validation failure part-way through would otherwise leave a truncated file with a header that lies about its contents — and would destroy an existing valid file at that path.
Summary
Functions
Writes a header and its element data to path.
Functions
@spec write( Path.t(), Ply.Header.t(), %{required(String.t()) => Enumerable.t()}, keyword() ) :: :ok | {:error, Ply.Error.t() | File.posix()}
Writes a header and its element data to path.
data maps element names to Enumerables of rows, so a caller can stream
millions of rows without materialising them.