Stream helpers for spatial formats.
Important: despite the name, most paths materialize the full source (or full enumerable) then yield items. True incremental I/O for multi-GB files is not implemented yet.
Prefer source: :file when the argument is a filesystem path, or
source: :binary when it is an encoded payload. With :auto (default), a
binary is treated as a path only when it looks path-like (under 4 KiB, no
ply/EXCP/GSPL magic prefix, and contains / or \ or ends with
.ply/.excp/.gspl/.bin) and File.regular?/1 is true. A real
file without separators/extensions is not auto-opened; a short slash-containing
binary that happens to be a regular path may be misread as a file.
Summary
Functions
Returns an enumerable over points or Gaussians decoded from a path or binary.
Encodes an enumerable of points or Gaussians after collecting it in memory.
Encodes spatial data and writes the binary to path.
Functions
@spec decode( Path.t() | binary(), keyword() ) :: Enumerable.t()
Returns an enumerable over points or Gaussians decoded from a path or binary.
The complete source and decoded cloud are currently materialized before elements are emitted.
Arguments
source(Path.t() | binary()) — a path or complete encoded payload. Paths and payloads are both binaries, so:sourcecontrols resolution.opts(keyword()) — requires:format::ply,:spatial_binary, or:gsplat.:sourcemay be:auto(default),:file, or:binary; PLY also accepts:as.
Returns
An Enumerable.t() yielding %Point{} for PLY/EXCP point clouds or
%Gaussian{} for PLY/GSPL Gaussian clouds. A failure is delayed until
enumeration and represented by exactly one
{:error, %ExCodecs.Error{}} element:
reason: :invalid_options—:formatis absent.reason: :unsupported_codec—:formatis unknown.reason: :io_error— a selected file cannot be read.reason: :invalid_data— the payload is malformed, unsupported, or truncated.
Raises / exceptions
A missing format does not raise. Keyword.fetch/2 and decoder option access
raise FunctionClauseError when opts is not a proper keyword list. PLY
source dispatch raises FunctionClauseError for a non-binary source.
EXCP/GSPL source resolution has no clause for non-binaries and may return an
invalid value that causes CaseClauseError; an unsupported :source value
also raises CaseClauseError. Decoder exceptions may occur during
enumeration.
Examples
iex> alias ExCodecs.Spatial.{Point, PointCloud}
iex> {:ok, bin} = ExCodecs.Spatial.encode(PointCloud.new([Point.new(0.0, 0.0, 0.0)]), format: :ply)
iex> [%Point{}] = ExCodecs.Spatial.Stream.decode(bin, format: :ply) |> Enum.to_list()
iex> true
true
@spec encode( Enumerable.t(), keyword() ) :: {:ok, binary()} | {:error, ExCodecs.Error.t()}
Encodes an enumerable of points or Gaussians after collecting it in memory.
A non-empty enumerable is classified by its first element. Empty input is
encoded as an empty %PointCloud{} for PLY/EXCP and as an empty
%GaussianCloud{} for GSPL.
Arguments
enumerable(Enumerable.t()) —%Point{}or%Gaussian{}elements. The list should be homogeneous and contain valid struct shapes.opts(keyword()) — requires:format::ply,:spatial_binary, or:gsplat. Remaining keys are forwarded toExCodecs.Spatial.encode/2.
Returns
{:ok, payload}wherepayloadis abinary().{:error, %ExCodecs.Error{reason: :invalid_options}}if:formatis absent.{:error, %ExCodecs.Error{reason: :unsupported_codec}}for an unknown format (including empty input).{:error, %ExCodecs.Error{reason: :invalid_data}}when the first item is an error tuple or is not a%Point{}/%Gaussian{}, when cloud and format are incompatible, or when codec validation fails.
Raises / exceptions
Enum.to_list/1 raises Protocol.UndefinedError for a non-enumerable and
propagates exceptions raised by enumeration. Keyword access raises
FunctionClauseError for a non-keyword opts. Manually malformed point or
Gaussian structs can raise codec shape/numeric exceptions; PLY converts its
encoding exceptions to :invalid_data.
Examples
iex> alias ExCodecs.Spatial.Point
iex> {:ok, bin} = ExCodecs.Spatial.Stream.encode([Point.new(1.0, 0.0, 0.0)], format: :ply)
iex> is_binary(bin)
true
@spec encode_to_file( Enumerable.t() | ExCodecs.Spatial.PointCloud.t() | ExCodecs.Spatial.GaussianCloud.t(), Path.t(), keyword() ) :: :ok | {:error, ExCodecs.Error.t()}
Encodes spatial data and writes the binary to path.
Arguments
data(PointCloud.t() | GaussianCloud.t() | Enumerable.t()) — a cloud, or an enumerable of%Point{}/%Gaussian{}values.path(Path.t()) — destination accepted byFile.write/2; parent directories must already exist.opts(keyword()) — the options forExCodecs.Spatial.encode/2, with:formatrequired for enumerable input and defaulting to:plyfor an already-built cloud.
Returns
:okafter the complete payload is written.- any
:invalid_options,:unsupported_codec, or:invalid_dataerror returned by encoding. {:error, %ExCodecs.Error{reason: :io_error, details: reason}}whenFile.write/2returns a file/POSIX error such as:enoent,:eacces, or:enospc.
Raises / exceptions
Normal File.write/2 path/POSIX failures are returned. Invalid path terms or
non-path binaries can raise FunctionClauseError or ArgumentError in the
path/file APIs. Encoding also has the enumerable, keyword, and
malformed-struct exceptions documented by encode/2.
Examples
iex> alias ExCodecs.Spatial.{Point, PointCloud}
iex> path = Path.join(System.tmp_dir!(), "ex_codecs_doc_65540.ply")
iex> :ok = ExCodecs.Spatial.Stream.encode_to_file(PointCloud.new([Point.new(0, 0, 0)]), path, format: :ply)
iex> {:ok, "ply" <> _} = File.read(path)
iex> File.rm!(path)
:ok