NURLNURL registrynurl-lang.org →

← ply

ply 0.2.3 API

viewer_html_data.nu

GENERATED by tools/embed_viewer.py from views/viewer.html — do not edit. The viewer page, embedded so an installed binary needs no views/ directory on disk (--page FILE overrides). Chunked because released nurlc stack-overflows on string literals past ~48 KB.

API

@ viewer_html_chunks → i

@ viewer_html_chunk i k → s


view.nu

packages/ply/src/view.nu — look at the cloud.

Serves two things on localhost: the viewer page, and the bytes of a PLY file.

GET / the viewer, one self-contained WebGL document GET /cloud the PLY, verbatim

The page is compiled into the binary (viewer_html_data.nu, generated by tools/embed_viewer.py) because nurlpkg install ships a binary and nothing else — a views/ path next to the executable can never resolve for an installed tool. A page_override file path replaces it while editing the page.

The cloud is read into memory once and handed out on every request. A large scene is ~100+ MB, which is a lot to hold but exactly what the browser is about to hold anyway, and it means the file can be replaced underneath a running viewer without the server noticing a half-written one.

( vw_serve path host port page_override quiet tls ) → i exit code

host is the BIND address: 127.0.0.1 stays private to the machine, 0.0.0.0 serves every interface, a specific address (192.168.1.30) serves exactly that adapter. tls != 0 generates a fresh self-signed P-256 certificate at startup (std/x509_gen) and serves HTTPS — the browser warns once, but the bytes cross the LAN encrypted.

API

: VwState

: VwState {
    String page
    String name
    ( Vec u ) cloud
}

: ~ i g_vw 0

@ vw_page s override → String

The page as compiled in. --page FILE reads from disk instead, which is the only way to iterate on the viewer without rebuilding.

@ h_vw_index HttpRequest req Params p → HttpResponse

@ h_vw_cloud HttpRequest req Params p → HttpResponse

@ vw_serve s path s host i port s page_override i quiet i tls → i

Serve path until interrupted. Returns a process exit code.


ply.nu

packages/ply/src/ply.nu — a streaming PLY point-cloud writer.

The property layout is the one every viewer reads and the bundled viewer parses: x, y, z as float32 and red, green, blue as uchar — 15 bytes a vertex in binary_little_endian, one line a vertex in ascii.

The vertex count is usually not known until the last point is pushed, so the header is written with a fixed-width zero-padded placeholder and patched in place at the end, rather than holding the whole cloud in memory:

( ply_create path ascii comment ) → !*PlyW String ( ply_vertex w x y z r g b ) → v buffered; flushes itself ( ply_count w ) → i vertices pushed so far ( ply_finish w ) → b flush, patch the count, close

ply_finish frees the handle either way; its F means the file could not be finished and should not be trusted.

Writes are buffered ~4 KB at a time — a vertex is 15 bytes, and a write per vertex would make the file the slowest part of a pipeline that computes millions of them.

API

: i PLY_COUNT_WIDTH 12

The count field is fixed-width so the header keeps its byte length when the real number is patched in. 12 digits holds any cloud a filesystem holds.

: i PLY_FLUSH_AT 4096

: PlyW

: PlyW {
    File f
    i n
    i ascii
    i cnt_off  // where the count field starts, for the patch at the end
    String abuf
    ( Vec u ) bbuf
}

@ ply_create s path i ascii s comment → !*PlyW String

Open path and write the header. comment goes in as one comment line ("" for none) — a place for provenance, not for structure.

@ ply_count * PlyW w → i

@ ply_flush * PlyW w → b

Write out whatever is buffered. Idempotent; ply_vertex calls it on its own past PLY_FLUSH_AT bytes.

@ ply_vertex * PlyW w f x f y f z i r i g i b → v

Push one vertex. Colour components are clamped to 0..255.

@ ply_finish * PlyW w → b

Flush, rewind to the count field, overwrite it in place, close, free.


main.nu

packages/ply/src/main.nu — the ply CLI.

ply view <cloud.ply> [--port n] [--host a] [--tls] [--page f] ply info <cloud.ply> print the header ply <cloud.ply> shorthand for view

The viewer serves one self-contained WebGL page on localhost and the cloud next to it; nothing is installed, nothing leaves the machine.

API

@ main → i