Repository navigation
Plugin API Reference
Versions: this page covers plugin API 3, available since OxyBrush 3.0.7-beta (download the latest release). Releases before it run API 1 and 2; rows and sections marked (3) or "API 3" need 3.0.7-beta or later. This page is mirrored from
docs/pluginsin the repository.
An in-app plugin imports these functions from the module oxybrush.
This is API version 3, which adds the rows marked (3), along with (2)
from API 2. Older plugins keep working unchanged.
-
Types: every argument and result is
i32orf32. -
Pointers and lengths are byte offsets and counts in the plugin's
exported
memory. The host reads and writes only inside it, and checks the bounds. -
Layouts:
- positions, normals and colors are three little-endian
f32per vertex (x, y, zorr, g, b); - triangles are three
u32vertex indices, counter-clockwise seen from outside; - masks are one
f32per vertex; - face groups are one
u32per triangle; - hidden flags are one
u8per triangle.
- positions, normals and colors are three little-endian
-
Results: a negative result is an error code.
- Reads return how many items they wrote, at most
max. - Writes return 0.
- Reads return how many items they wrote, at most
-
Piece indices run from 0 to
piece_count() - 1, in the order of the Pieces panel.active_piece()is the one selected. - The scene is a copy, taken when the command starts. Writes don't change what later reads return. All of a command's writes are applied together when it returns.
| Export | |
|---|---|
memory |
required: the plugin's linear memory |
run(command: i32) |
required: called with the index of the command clicked |
overlay() |
optional: called each frame while the plugin's panel is open, to draw lines (needs overlay) |
| Function | |
|---|---|
log(ptr, len) |
UTF-8 text (up to 4096 bytes) for the status bar and the log file; the last line logged by a command is shown |
param(index) -> f32 |
the current value of param index (see the manifest); 0 for an unknown index |
param_color(index, ptr) -> i32 (3)
|
a color param's value as three f32 (sRGB 0..=1) at ptr
|
progress(fraction: f32) -> i32 (3)
|
report progress, 0..=1, shown as a bar; returns 1 once the user has clicked Stop, else 0 |
piece_count() -> i32 |
pieces in the scene |
active_piece() -> i32 |
index of the active piece |
| Function | |
|---|---|
vertex_count(piece) -> i32 |
|
triangle_count(piece) -> i32 |
|
read_positions(piece, ptr, max) -> i32 |
up to max positions |
read_triangles(piece, ptr, max) -> i32 |
up to max triangles |
read_mask(piece, ptr, max) -> i32 |
up to max mask values; 1 = fully protected |
read_normals(piece, ptr, max) -> i32 (2)
|
up to max unit vertex normals |
read_colors(piece, ptr, max) -> i32 (2)
|
up to max vertex colors, sRGB 0..=1, white where unpainted |
read_groups(piece, ptr, max) -> i32 (3)
|
up to max face groups |
read_hidden(piece, ptr, max) -> i32 (3)
|
up to max hidden flags, 1 = hidden |
Each write replaces that attribute for the whole piece. count must
be the piece's vertex count, or its triangle count for face groups and
hidden flags. If a command writes the same attribute twice, the last write
wins.
| Function | |
|---|---|
write_positions(piece, ptr, count) -> i32 |
new positions for every vertex; non-finite values are refused |
write_mask(piece, ptr, count) -> i32 (2)
|
a mask value for every vertex, clamped to 0..=1 |
write_colors(piece, ptr, count) -> i32 (2)
|
a color for every vertex, clamped to 0..=1 |
write_groups(piece, ptr, count) -> i32 (3)
|
a face group for every triangle |
write_hidden(piece, ptr, count) -> i32 (3)
|
a hidden flag for every triangle; nonzero = hidden |
| Function | |
|---|---|
write_mesh(piece, pos_ptr, vcount, tri_ptr, tcount) -> i32 |
replace the piece's vertices and triangles |
-
Limits: 3 to 4,000,000 vertices, 1 to 4,000,000 triangles, finite
positions, and indices below
vcount. -
Later writes use the new mesh. After
write_mesh, this command'swrite_maskandwrite_colorstakevcount, andwrite_groupsandwrite_hiddentaketcount.write_positionsreturnsERR_CONTEXT, since you just gave the positions. -
Earlier writes are dropped. Anything written to the piece before
write_meshwas for the old mesh, so it's discarded. - What isn't written starts fresh: unmasked, white, face group 0, all visible. To keep attributes, read them first and write them back after; the bundled Flip Faces plugin does this.
- Subdivision levels of the piece are removed. Undo restores them, and the old mesh.
| Function | |
|---|---|
add_piece(name_ptr, name_len, pos_ptr, vcount, tri_ptr, tcount) -> i32 |
a new piece, with the same limits as write_mesh; returns its index among this command's new pieces |
All of a command's new pieces become one undo step, and the last one becomes active.
| Function | |
|---|---|
scene_state(ptr, cap) -> i32 |
the scene as JSON: pieces, their versions, the camera; writes up to cap bytes and returns the full length (call with cap 0 to size a buffer) |
| Function | |
|---|---|
draw_line(x1, y1, z1, x2, y2, z2, rgba) -> i32 |
during overlay() only: a line in world space, color 0xRRGGBBAA; up to 20,000 lines a frame |
Mesh functions return ERR_CONTEXT during overlay(), and draw_line
returns it outside.
| Code | Name | Means |
|---|---|---|
| -1 | ERR_DENIED |
the manifest doesn't declare the capability |
| -2 | ERR_PIECE |
no piece with that index |
| -3 | ERR_MEMORY |
a pointer or length outside the plugin's memory |
| -4 | ERR_COUNT |
a count that doesn't match the piece, or values that aren't allowed (non-finite, indices out of range, over the limits) |
| -5 | ERR_CONTEXT |
not allowed here: mesh functions in overlay(), draw_line outside it, write_positions after write_mesh
|
When run returns, OxyBrush applies the command's writes:
- each piece's edits as one undo step, labelled
Plugin: <name> — <command>; - its new pieces as one more step.
If the piece changed while the command ran, its edits are skipped and the status bar says so. If the user clicked Stop, nothing is applied, even if the plugin finished anyway.
| Fuel per command | about 1,000,000,000 instructions, then the command is stopped |
| Fuel per overlay frame | about 20,000,000 instructions |
| Memory | 512 MB |
| Imports | only the functions above; a module importing anything else doesn't load |
OxyBrush is an open-source multiresolution digital sculpting tool written in pure Rust with wgpu. Visit the GitHub repository or download the latest version from Releases.
Getting Started
Sculpting & Workflow
- Sculpting & Brushes
- Subdivision Levels
- Topology & Remeshing
- Masking & Face Groups
- Posing & Transform Gizmo
- Vertex Color & Materials
Scripting & Extensibility
Pipeline & Production