bits

bit_and

bit_and ( a : Numeric , b : Numeric ) : Int
Bitwise AND operation of two integers (`a & b`)
Arguments:
  • a : Numeric
  • b : Numeric
bit_and ( a : Mesh , b : Mesh ) : Mesh
Returns the boolean intersection of two meshes (`a & b`)
Arguments:
  • a : Mesh
  • b : Mesh

bit_or

bit_or ( a : Numeric , b : Numeric ) : Int
Bitwise OR operation of two integers (`a | b`)
Arguments:
  • a : Numeric
  • b : Numeric
bit_or ( a : Mesh , b : Mesh ) : Mesh
Returns the boolean union of two meshes (`a | b`)
Arguments:
  • a : Mesh
  • b : Mesh

core

assert

assert ( condition : Bool , message : String String(Assertion failed) ) : Nil
Raises an error if `condition` is false, optionally including `message` in the error
Arguments:
  • condition : Bool
  • message : String String(Assertion failed) - Optional message to include in the error if the assertion fails

float

float ( value : String | Numeric ) : Float
Converts a value to a float
Arguments:
  • value : String | Numeric

gizmo

alias: giz
gizmo ( name : String Nil , origin : Vec3 Vec3(0, 0, 0) , absolute : Bool Bool(false) , default : Vec3 Nil , ghost : Bool Nil ) : Vec3
A viewport-draggable `vec3` handle. Interactive only inside the Geotoy editor; everywhere else (level loader, tests) it returns the stored baked value, or the `default`/zero when unset.
Arguments:
  • name : String Nil - Stable handle id, scoped to the node. Omit for a positional `@N` id.
  • origin : Vec3 Vec3(0, 0, 0) - Node-local anchor where the handle is drawn in the viewport.
  • absolute : Bool Bool(false) - If true the returned value is the handle position itself; otherwise it's the drag offset from `origin` (zero until dragged).
  • default : Vec3 Nil - Value to return when no value has been stored for this handle.
  • ghost : Bool Nil - Override ghost rendering for this handle: `nil` follows the global Geotoy setting; `true`/`false` force it on/off.

gizmo_transform

aliases: giz_tfn, transform_gizmo
gizmo_transform ( name : String Nil , default : Mat4 Nil , ghost : Bool Nil ) : Mat4
A viewport-draggable `mat4` transform handle (absolute). Consume it with `apply_mat4`. Returns the stored baked transform, or the `default`/identity when unset.
Arguments:
  • name : String Nil - Stable handle id, scoped to the node. Omit for a positional `@N` id.
  • default : Mat4 Nil - Transform to return when no value has been stored for this handle.
  • ghost : Bool Nil - Override ghost rendering for this handle: `nil` follows the global Geotoy setting; `true`/`false` force it on/off.

gizmo1d

alias: giz1d
gizmo1d ( name : String Nil , origin : Vec3 Vec3(0, 0, 0) , absolute : Bool Bool(false) , default : Numeric Nil , axis : String Nil , ghost : Bool Nil ) : Float
A viewport-draggable `num` handle restricted to a single axis (default Y). Like `gizmo` but the live gizmo only exposes one axis.
Arguments:
  • name : String Nil - Stable handle id, scoped to the node. Omit for a positional `@N` id.
  • origin : Vec3 Vec3(0, 0, 0) - Node-local anchor where the handle is drawn in the viewport.
  • absolute : Bool Bool(false) - If true the returned value is the handle position itself; otherwise it's the drag offset from `origin` (zero until dragged).
  • default : Numeric Nil - Value to return when no value has been stored for this handle.
  • axis : String Nil - Which axis is draggable: "x", "y" (default), or "z".
  • ghost : Bool Nil - Override ghost rendering for this handle: `nil` follows the global Geotoy setting; `true`/`false` force it on/off.

gizmo2d

alias: giz2d
gizmo2d ( name : String Nil , origin : Vec3 Vec3(0, 0, 0) , absolute : Bool Bool(false) , default : Vec2 Nil , axes : String Nil , ghost : Bool Nil ) : Vec2
A viewport-draggable `vec2` handle restricted to two axes (default XZ, the ground plane). Like `gizmo` but the live gizmo only exposes the two chosen axes.
Arguments:
  • name : String Nil - Stable handle id, scoped to the node. Omit for a positional `@N` id.
  • origin : Vec3 Vec3(0, 0, 0) - Node-local anchor where the handle is drawn in the viewport.
  • absolute : Bool Bool(false) - If true the returned value is the handle position itself; otherwise it's the drag offset from `origin` (zero until dragged).
  • default : Vec2 Nil - Value to return when no value has been stored for this handle.
  • axes : String Nil - Which two axes are draggable, e.g. "xz" (default), "xy", "yz". The returned `vec2` maps to these axes in order.
  • ghost : Bool Nil - Override ghost rendering for this handle: `nil` follows the global Geotoy setting; `true`/`false` force it on/off.

input_bool

input_bool ( name : String , default : Bool Nil , label : String Nil ) : Bool
A panel-driven checkbox `bool` control. Returns the stored value, or `default`/false when unset.
Arguments:
  • name : String - Stable control id, scoped to the node. Also the default panel label.
  • default : Bool Nil - Value returned when the control is unset.
  • label : String Nil - Display label override; defaults to `name`.

input_color

input_color ( name : String , default : Vec3 Nil , label : String Nil ) : Vec3
A panel-driven color picker; returns the chosen color as an RGB `vec3`. Returns the stored value, or `default`/black when unset.
Arguments:
  • name : String - Stable control id, scoped to the node. Also the default panel label.
  • default : Vec3 Nil - RGB color returned when the control is unset.
  • label : String Nil - Display label override; defaults to `name`.

input_color_ramp

input_color_ramp ( name : String , default : Callable | Sequence , label : String Nil ) : Callable
An interactively-editable color gradient; returns the same callable `|x: float|: vec3` that `color_ramp` builds. Edited via a gradient bar with draggable stops in the controls panel.
Arguments:
  • name : String - Stable control id, scoped to the node. Also the default panel label.
  • default : Callable | Sequence - A `color_ramp` stop list (vec3 linear-RGB values; any of its forms) or a built `color_ramp(...)` value. Stop-list defaults get `color_ramp`'s defaults (oklab, clamp). Named easings only.
  • label : String Nil - Display label override; defaults to `name`.

input_float

input_float ( name : String , min : Numeric Nil , max : Numeric Nil , step : Numeric Nil , default : Numeric Nil , label : String Nil , style : String Nil ) : Float
A panel-driven `num` control (slider by default). Interactive in the Geotoy editor and injectable from level defs; elsewhere returns the stored value, or `default`/zero when unset.
Arguments:
  • name : String - Stable control id, scoped to the node. Also the default panel label.
  • min : Numeric Nil - Slider minimum.
  • max : Numeric Nil - Slider maximum.
  • step : Numeric Nil - Slider step; omit for continuous.
  • default : Numeric Nil - Value returned when the control is unset.
  • label : String Nil - Display label override; defaults to `name`.
  • style : String Nil - Widget style: "slider" (default), "entry", or "knob".

input_int

input_int ( name : String , min : Numeric Nil , max : Numeric Nil , step : Numeric Nil , default : Numeric Nil , label : String Nil , style : String Nil ) : Int
A panel-driven integer control (rounded slider). Injectable from level defs; returns the stored value, or `default`/zero when unset.
Arguments:
  • name : String - Stable control id, scoped to the node. Also the default panel label.
  • min : Numeric Nil - Slider minimum.
  • max : Numeric Nil - Slider maximum.
  • step : Numeric Nil - Slider step; defaults to 1 in the panel.
  • default : Numeric Nil - Value returned when the control is unset.
  • label : String Nil - Display label override; defaults to `name`.
  • style : String Nil - Widget style: "slider" (default), "entry", or "knob".

input_ramp

input_ramp ( name : String , default : Callable | Sequence , label : String Nil ) : Callable
An interactively-editable scalar transfer function; returns the same callable `|x: float|: float` that `ramp` builds. Edited as a curve/stop list in the controls panel.
Arguments:
  • name : String - Stable control id, scoped to the node. Also the default panel label.
  • default : Callable | Sequence - A `ramp` stop list (any of its forms) or a built `ramp(...)` value. Named easings only — closures can't be edited in the panel.
  • label : String Nil - Display label override; defaults to `name`.

input_select

input_select ( name : String , options : Sequence , default : String Nil , label : String Nil ) : String
A panel-driven dropdown; returns the chosen option as a `string`. An injected/stored value not in `options` falls back to `default` or the first option.
Arguments:
  • name : String - Stable control id, scoped to the node. Also the default panel label.
  • options : Sequence - The selectable string options.
  • default : String Nil - Option returned when unset; defaults to the first option.
  • label : String Nil - Display label override; defaults to `name`.

input_spline

input_spline ( name : String , default : Sequence Nil , label : String Nil ) : Sequence
An interactively-editable sequence of vec3 control points (a polyline/spline). Edited in the viewport in Geotoy and the level editor; injectable from level defs. Returns the stored points, or `default`/empty when unset. Feed into `extrude_pipe`, `fillet_path_3d`, `catmull_rom_3d`, etc.
Arguments:
  • name : String - Stable control id, scoped to the node. Also the default panel label.
  • default : Sequence Nil - Sequence of vec3 control points returned when the control is unset.
  • label : String Nil - Display label override; defaults to `name`.

int

int ( value : String | Numeric ) : Int
Converts a value to an int
Arguments:
  • value : String | Numeric

len

aliases: length, mag, magnitude
len ( v : Vec3 ) : Float
Returns the length/magnitude of a Vec3
Arguments:
  • v : Vec3
len ( v : Vec2 ) : Float
Returns the length/magnitude of a Vec2
Arguments:
  • v : Vec2
len ( v : String ) : Int
Returns the number of unicode characters in a string
Arguments:
  • v : String
len ( v : Sequence ) : Int
Returns the number of elements in a sequence. This will fully evaluate the sequence. Calling this with an infinite sequence will result in the program hanging or crashing.
Arguments:
  • v : Sequence
len ( m : Mesh ) : Int
Returns the number of vertices in a mesh
Arguments:
  • m : Mesh
len ( v : Texture ) : Texture
Per-texel length/magnitude of a texture's channel vector, producing a 1-channel texture
Arguments:
  • v : Texture
len ( v : Vec4 ) : Float
Returns the length/magnitude of a Vec4
Arguments:
  • v : Vec4
len ( m : Map ) : Int
Returns the number of entries in a map
Arguments:
  • m : Map
len ( path : Path ) : Float
Total arc length of a path over all its subpaths. Lazy paths are measured by sampling.
Arguments:
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

print

print ( ... Any ) : Nil
Prints all provided args and kwargs to the console
Arguments:
  • ...

render

render ( mesh : Mesh , attrs : Sequence | Nil Nil ) : Nil
Renders a mesh to the scene
Arguments:
  • mesh : Mesh
  • attrs : Sequence | Nil Nil - Names of custom per-vertex attributes (see `set_attr`) to export as GPU vertex attributes, in addition to the well-known `uv`, `tangent`, and `color` which always export. Each named attribute must exist on the mesh. Exported attributes are available to custom shaders as `attribute`s of the same name.
render ( light : Light ) : Nil
Renders a light to the scene
Arguments:
  • light : Light
render ( meshes : Sequence , attrs : Sequence | Nil Nil ) : Nil
Renders a sequence of entities to the scene. The sequence can contain a heterogeneous mix of meshes, lights, and paths (`Seq<Vec3>` or `Seq<Vec2>`). `Vec2` paths are rendered in the XZ plane. Each entity will be rendered separately.
Arguments:
  • meshes : Sequence - Either: - `Seq<Mesh | Light | Seq<Vec3 | Vec2>>` of objects to render to the scene, or - `Seq<Vec3>` of points representing a path to render, or - `Seq<Vec2>` of 2D points representing a path to render in the XZ plane
  • attrs : Sequence | Nil Nil - Names of custom per-vertex attributes (see `set_attr`) to export as GPU vertex attributes, in addition to the well-known `uv`, `tangent`, and `color` which always export. Each named attribute must exist on the mesh. Exported attributes are available to custom shaders as `attribute`s of the same name.
render ( path : Path ) : Nil
Renders a path in the XZ plane, one polyline per subpath, flattened at the ambient curve tolerance. The resulting 2D positions are projected onto the XZ plane (y=0).
Arguments:
  • path : Path - A path to render as a closed path in the XZ plane

render_path

alias: path_render
render_path ( path : Path , resolution : Numeric Int(1000) ) : Nil
Renders a path in the XZ plane, one polyline per subpath. Both concrete and lazy paths use the ambient curve-angle tolerance; `resolution` controls initial probe density for lazy paths.
Arguments:
  • path : Path - The path to render.
  • resolution : Numeric Int(1000) - Initial uniform probe count for lazy paths; known boundaries and adaptive refinement add samples as needed.

str

alias: string
str ( value : Any ) : String
Converts a value to a string. For simple types like numbers and booleans, this performs the basic conversion as you'd expect. For more complicated or internal types like meshes, lights, sequences, etc., the format is not defined and may change at a later time.
Arguments:
  • value : Any

vec2

alias: v2
vec2 ( x : Numeric , y : Numeric ) : Vec2
Creates a Vec2 given x, y
Arguments:
  • x : Numeric
  • y : Numeric
vec2 ( value : Numeric ) : Vec2
Creates a Vec2 with both components set to `value`
Arguments:
  • value : Numeric
vec2 ( x : Texture | Numeric , y : Texture | Numeric ) : Texture
Builds a 2-channel texture from 1-channel textures and/or constants
Arguments:
  • x : Texture | Numeric
  • y : Texture | Numeric
vec2 ( x : Texture ) : Texture
Splats a 1-channel texture into a 2-channel texture (zero-copy)
Arguments:
  • x : Texture

vec3

alias: v3
vec3 ( x : Numeric , y : Numeric , z : Numeric ) : Vec3
Creates a Vec3 given x, y, z
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
vec3 ( xy : Vec2 , z : Numeric ) : Vec3
Creates a Vec3 from a Vec2 and a z component
Arguments:
  • xy : Vec2
  • z : Numeric
vec3 ( x : Numeric , yz : Vec2 ) : Vec3
Creates a Vec3 from an x component and a Vec2
Arguments:
  • x : Numeric
  • yz : Vec2
vec3 ( value : Numeric ) : Vec3
Creates a Vec3 with all components set to `value`
Arguments:
  • value : Numeric
vec3 ( x : Texture | Numeric , y : Texture | Numeric , z : Texture | Numeric ) : Texture
Builds a 3-channel texture from 1-channel textures and/or constants
Arguments:
  • x : Texture | Numeric
  • y : Texture | Numeric
  • z : Texture | Numeric
vec3 ( x : Texture ) : Texture
Splats a 1-channel texture into a 3-channel texture (zero-copy)
Arguments:
  • x : Texture

vec4

alias: v4
vec4 ( x : Numeric , y : Numeric , z : Numeric , w : Numeric ) : Vec4
Creates a Vec4 given x, y, z, w
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • w : Numeric
vec4 ( xyz : Vec3 , w : Numeric ) : Vec4
Creates a Vec4 from a Vec3 and a w component
Arguments:
  • xyz : Vec3
  • w : Numeric
vec4 ( xy : Vec2 , zw : Vec2 ) : Vec4
Creates a Vec4 from two Vec2s
Arguments:
  • xy : Vec2
  • zw : Vec2
vec4 ( value : Numeric ) : Vec4
Creates a Vec4 with all components set to `value`
Arguments:
  • value : Numeric
vec4 ( x : Texture | Numeric , y : Texture | Numeric , z : Texture | Numeric , w : Texture | Numeric ) : Texture
Builds a 4-channel texture from 1-channel textures and/or constants
Arguments:
  • x : Texture | Numeric
  • y : Texture | Numeric
  • z : Texture | Numeric
  • w : Texture | Numeric
vec4 ( x : Texture ) : Texture
Splats a 1-channel texture into a 4-channel texture (zero-copy)
Arguments:
  • x : Texture

fn

call

call ( fn : Callable ) : Any
Calls `fn` with no arguments, returning its return value
Arguments:
  • fn : Callable
call ( fn : Callable , args : Sequence ) : Any
Calls `fn` with the provided arguments, returning its return value
Arguments:
  • fn : Callable
  • args : Sequence

compose

Example
move_and_scale = compose( translate(3, 3, 0), scale(0.5), ) cube = box(2) cube | set_material('blue') | render cube | move_and_scale | set_material('red') | render
compose ( ... Sequence ) : Callable
Composes all arguments, returning a callable like `|x| arg1(arg2(arg3(x)))`
Arguments:
  • ...
compose ( callables : Sequence ) : Callable
Composes a sequence of callables, returning a callable like `|x| callables[0](callables[1](...callables[n](x)))`
Arguments:
  • callables : Sequence - Sequence of callables to compose

deriv

deriv ( f : Callable , dir : Vec2 | Vec3 | Numeric ) : Callable
Forward-mode automatic differentiation. Returns a new closure computing the directional derivative (JVP) of `f` seeded by `dir` — e.g. for an embedding `phi = |p: vec2|: vec3`, `deriv(phi, vec2(1, 0))` computes the partial `d phi / d u`.
Arguments:
  • f : Callable - Closure to differentiate with respect to its FIRST parameter, which must carry an explicit type annotation (numeric, vec2, or vec3). Further parameters pass through unchanged (constant w.r.t. the derivative); the returned closure takes the same parameter list.
  • dir : Vec2 | Vec3 | Numeric - Tangent direction seeding the forward-mode derivative; must match the closure's parameter type.

grad

grad ( f : Callable ) : Callable
Returns a closure computing the gradient of a scalar-output function `f`. For a vec2/vec3 input the result returns the vector of partial derivatives; for a scalar input it is just `f'`.
Arguments:
  • f : Callable - Scalar-output closure to differentiate with respect to its FIRST parameter, which must carry an explicit type annotation (numeric, vec2, or vec3). Any further parameters pass through unchanged and are treated as constants, so values that change between calls can be arguments instead of captures; the returned closure takes the same parameter list. Prefer that over calling `grad` inside a loop: every `grad` call re-derives and re-optimizes the closure body, while a hoisted gradient is derived once.

light

ambient_light

ambient_light ( color : Vec3 | Numeric Int(16777215) , intensity : Numeric Float(1.8) ) : Light
Creates an ambient light. Note: This will not do anything until it is added to the scene via `render`
Arguments:
  • color : Vec3 | Numeric Int(16777215) - Color of the light in hex format (like 0xffffff) or webgl format (like `vec3(1., 1., 1.)`)
  • intensity : Numeric Float(1.8)

dir_light

Example
box(8) | render; (sphere(radius=5, resolution=4) + v3(8, 8, -4)) | render light_pos = v3(10, 13, -10) sphere(radius=0.5, resolution=4) | trans(light_pos * 1.1) | set_material('light_marker') | render dir_light(intensity=25, color=0xff00ff) | trans(light_pos) | render
dir_light ( target : Vec3 Vec3(0, 0, 0) , color : Vec3 | Numeric Int(16777215) , intensity : Numeric Float(5) , cast_shadow : Bool Bool(true) , shadow_map_size : Map | Numeric Small([("width", Int(4096)), ("height", Int(4096))]) , shadow_map_radius : Numeric Float(4) , shadow_map_blur_samples : Numeric Int(16) , shadow_map_type : String String(vsm) , shadow_map_bias : Numeric Float(-0.0001) , shadow_camera : Map | String | Nil Nil ) : Light
Creates a directional light. Note: This will not do anything until it is added to the scene via `render`
Arguments:
  • target : Vec3 Vec3(0, 0, 0) - Target point that the light is pointing at. If the light as at the same position as the target, it will point down towards negative Y
  • color : Vec3 | Numeric Int(16777215) - Color of the light in hex format (like 0xffffff) or webgl format (like `vec3(1., 1., 1.)`)
  • intensity : Numeric Float(5)
  • cast_shadow : Bool Bool(true)
  • shadow_map_size : Map | Numeric Small([("width", Int(4096)), ("height", Int(4096))]) - Size of the shadow map. Allowed keys: `width`, `height`. OR, a single integer value that will be used for both width and height.
  • shadow_map_radius : Numeric Float(4) - Radius for shadow map filtering
  • shadow_map_blur_samples : Numeric Int(16) - Number of samples for shadow map blur
  • shadow_map_type : String String(vsm) - Allowed values: `vsm`
  • shadow_map_bias : Numeric Float(-0.0001)
  • shadow_camera : Map | String | Nil Nil - Orthographic shadow frustum. `"auto"` or `nil` (the default) fits the frustum and light distance to the scene's bounding box automatically. Pass a map to set it explicitly. Allowed keys: `near`, `far`, `left`, `right`, `top`, `bottom`

hemisphere_light

hemisphere_light ( sky_color : Vec3 | Numeric Int(16777215) , ground_color : Vec3 | Numeric Int(4473924) , intensity : Numeric Float(1) ) : Light
Creates a hemisphere light: a cheap directional ambient that blends `sky_color` (from above) and `ground_color` (from below) by surface normal. Note: This will not do anything until it is added to the scene via `render`
Arguments:
  • sky_color : Vec3 | Numeric Int(16777215) - Color of the light coming from above (the sky), in hex format (like 0xffffff) or webgl format (like `vec3(1., 1., 1.)`)
  • ground_color : Vec3 | Numeric Int(4473924) - Color of the light coming from below (the ground), in hex format (like 0x444444) or webgl format (like `vec3(0.2, 0.2, 0.2)`)
  • intensity : Numeric Float(1)

rect_area_light

rect_area_light ( color : Vec3 | Numeric Int(16777215) , intensity : Numeric Float(1) , width : Numeric Float(10) , height : Numeric Float(10) ) : Light
Creates a rectangular area light (e.g. a softbox or window). The rectangle emits from its local -Z face; position and orientation come from transforms applied via `translate`/`rotate`/etc. Does not cast shadows. Note: This will not do anything until it is added to the scene via `render`
Arguments:
  • color : Vec3 | Numeric Int(16777215) - Color of the light in hex format (like 0xffffff) or webgl format (like `vec3(1., 1., 1.)`)
  • intensity : Numeric Float(1)
  • width : Numeric Float(10) - Width of the emitting rectangle
  • height : Numeric Float(10) - Height of the emitting rectangle

logic

and

and ( a : Bool , b : Bool ) : Bool
Logical AND operation of two booleans
Arguments:
  • a : Bool
  • b : Bool

not

not ( value : Bool ) : Bool
Inverts the boolean value (logical NOT)
Arguments:
  • value : Bool

or

or ( a : Bool , b : Bool ) : Bool
Logical OR operation of two booleans
Arguments:
  • a : Bool
  • b : Bool

xor

xor ( a : Bool , b : Bool ) : Bool
Logical XOR operation of two booleans
Arguments:
  • a : Bool
  • b : Bool

map

entries

entries ( map : Map ) : Sequence
Returns a lazy sequence of `[key, value]` pairs for the given map. Iteration order is arbitrary but stable for a given map, and matches the order of `keys` and `values`.
Arguments:
  • map : Map

from_entries

from_entries ( entries : Sequence ) : Map
Builds a map from a sequence of `[key, value]` pairs; the inverse of `entries`. Later entries overwrite earlier ones with the same key.
Arguments:
  • entries : Sequence - Sequence of `[key, value]` pairs. Keys must be strings or ints; ints are converted to string keys.

get_in

get_in ( path : Sequence , map : Map , default : Any Nil ) : Any
Reads the value at a path of keys through nested maps, returning `default` if the path can't be fully resolved.
Arguments:
  • path : Sequence - Sequence of string or int keys to follow through nested maps.
  • map : Map
  • default : Any Nil - Returned when the path is missing, hits a non-map value, or resolves to `nil`.

group_by

group_by ( cb : Callable , seq : Sequence ) : Map
Groups the elements of a sequence into a map of `key -> [elements]`, keyed by the value returned by `cb` for each element.
Arguments:
  • cb : Callable - Called with `(elem, index)` for each element; must return a string or int key for the element's group.
  • seq : Sequence

has

has ( key : String | Numeric , map : Map ) : Bool
Returns `true` if the map contains the given key. Unlike indexing (which yields `nil` for missing keys), this distinguishes a stored `nil` from an absent key.
Arguments:
  • key : String | Numeric
  • map : Map

keys

keys ( map : Map ) : Sequence
Returns a lazy sequence of the keys of the given map. Iteration order is arbitrary but stable for a given map.
Arguments:
  • map : Map

set_in

set_in ( path : Sequence , val : Any , map : Map ) : Map
Returns a copy of the map with `val` stored at the given path of keys. Missing or `nil` intermediate entries are created as empty maps; a non-map intermediate value is an error.
Arguments:
  • path : Sequence - Sequence of string or int keys to follow through nested maps.
  • val : Any
  • map : Map

update_in

update_in ( path : Sequence , cb : Callable , map : Map , default : Any Nil ) : Map
Returns a copy of the map with the value at the given path of keys replaced by `cb(current)`. Missing or `nil` intermediate entries are created as empty maps; a non-map intermediate value is an error.
Arguments:
  • path : Sequence - Sequence of string or int keys to follow through nested maps.
  • cb : Callable - Called with the current value at the path (or `default` if missing/`nil`); its return value is stored.
  • map : Map
  • default : Any Nil - Passed to `cb` in place of a missing or `nil` value at the path.

values

values ( map : Map ) : Sequence
Returns a lazy sequence of the values of the given map. Iteration order is arbitrary but stable for a given map, and matches the order of `keys` and `entries`.
Arguments:
  • map : Map

math

abs

abs ( value : Numeric ) : Int
Absolute Value
Arguments:
  • value : Numeric
abs ( value : Numeric ) : Float
Absolute Value
Arguments:
  • value : Numeric
abs ( value : Vec3 ) : Vec3
Component-wise absolute value of a Vec3
Arguments:
  • value : Vec3
abs ( value : Vec2 ) : Vec2
Component-wise absolute value of a Vec2
Arguments:
  • value : Vec2
abs ( value : Texture ) : Texture
Absolute value of every channel of a texture
Arguments:
  • value : Texture
abs ( value : Vec4 ) : Vec4
Component-wise absolute value of a Vec4
Arguments:
  • value : Vec4

acos

acos ( value : Numeric ) : Float
Returns the arccosine of a numeric value
Arguments:
  • value : Numeric
acos ( value : Vec3 ) : Vec3
Returns a Vec3 with the arccosine of each component
Arguments:
  • value : Vec3
acos ( value : Vec2 ) : Vec2
Returns a Vec2 with the arccosine of each component
Arguments:
  • value : Vec2
acos ( value : Texture ) : Texture
Applies arccosine to every channel of a texture
Arguments:
  • value : Texture
acos ( value : Vec4 ) : Vec4
Returns a Vec4 with the arccosine of each component
Arguments:
  • value : Vec4

add

add ( a : Vec3 , b : Vec3 ) : Vec3
Adds two Vec3s component-wise
Arguments:
  • a : Vec3
  • b : Vec3
add ( a : Numeric , b : Numeric ) : Float
a + b
Arguments:
  • a : Numeric
  • b : Numeric
add ( a : Numeric , b : Numeric ) : Float
a + b
Arguments:
  • a : Numeric
  • b : Numeric
add ( a : Numeric , b : Numeric ) : Int
a + b
Arguments:
  • a : Numeric
  • b : Numeric
add ( a : Mesh , b : Mesh ) : Mesh
Combines two meshes into one mesh containing all geometry from both inputs. This does NOT perform a boolean union; for that, use the `union` function or the `|` operator.
Arguments:
  • a : Mesh
  • b : Mesh
add ( mesh : Mesh , offset : Vec3 ) : Mesh
Translates the given mesh by a Vec3 offset
Arguments:
  • mesh : Mesh
  • offset : Vec3
add ( vec : Vec3 , num : Numeric ) : Vec3
Adds a numeric value to each component of a Vec3
Arguments:
  • vec : Vec3
  • num : Numeric
add ( a : Vec2 , b : Vec2 ) : Vec2
Adds two Vec2s component-wise
Arguments:
  • a : Vec2
  • b : Vec2
add ( a : Vec2 , b : Numeric ) : Vec2
Adds a numeric value to each component of a Vec2
Arguments:
  • a : Vec2
  • b : Numeric
add ( a : String , b : String ) : String
Concatenates two strings
Arguments:
  • a : String
  • b : String
add ( a : Vec4 , b : Vec4 ) : Vec4
Adds two Vec4s component-wise
Arguments:
  • a : Vec4
  • b : Vec4
add ( a : Vec4 , b : Numeric ) : Vec4
Adds a numeric value to each component of a Vec4
Arguments:
  • a : Vec4
  • b : Numeric
add ( a : Texture , b : Texture ) : Texture
Adds two textures elementwise; dims and channel counts must match
Arguments:
  • a : Texture
  • b : Texture
add ( a : Texture , b : Numeric ) : Texture
Adds a scalar to every channel of a texture
Arguments:
  • a : Texture
  • b : Numeric
add ( a : Numeric , b : Texture ) : Texture
Adds a scalar to every channel of a texture
Arguments:
  • a : Numeric
  • b : Texture
add ( a : Texture , b : Vec2 ) : Texture
Per-channel `texture + vec2` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec2
add ( a : Vec2 , b : Texture ) : Texture
Per-channel `vec2 + texture` (vec length must match the channel count)
Arguments:
  • a : Vec2
  • b : Texture
add ( a : Texture , b : Vec3 ) : Texture
Per-channel `texture + vec3` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec3
add ( a : Vec3 , b : Texture ) : Texture
Per-channel `vec3 + texture` (vec length must match the channel count)
Arguments:
  • a : Vec3
  • b : Texture
add ( a : Texture , b : Vec4 ) : Texture
Per-channel `texture + vec4` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec4
add ( a : Vec4 , b : Texture ) : Texture
Per-channel `vec4 + texture` (vec length must match the channel count)
Arguments:
  • a : Vec4
  • b : Texture

asin

asin ( value : Numeric ) : Float
Returns the arcsine of a numeric value
Arguments:
  • value : Numeric
asin ( value : Vec3 ) : Vec3
Returns a Vec3 with the arcsine of each component
Arguments:
  • value : Vec3
asin ( value : Vec2 ) : Vec2
Returns a Vec2 with the arcsine of each component
Arguments:
  • value : Vec2
asin ( value : Texture ) : Texture
Applies arcsine to every channel of a texture
Arguments:
  • value : Texture
asin ( value : Vec4 ) : Vec4
Returns a Vec4 with the arcsine of each component
Arguments:
  • value : Vec4

atan

atan ( value : Numeric ) : Float
Returns the arctangent of a numeric value
Arguments:
  • value : Numeric
atan ( value : Vec3 ) : Vec3
Returns a Vec3 with the arctangent of each component
Arguments:
  • value : Vec3
atan ( value : Vec2 ) : Vec2
Returns a Vec2 with the arctangent of each component
Arguments:
  • value : Vec2
atan ( value : Texture ) : Texture
Applies arctangent to every channel of a texture
Arguments:
  • value : Texture
atan ( value : Vec4 ) : Vec4
Returns a Vec4 with the arctangent of each component
Arguments:
  • value : Vec4

atan2

atan2 ( y : Numeric , x : Numeric ) : Float
Returns the arctangent of `y / x`, using the signs of both arguments to determine the correct quadrant.
Arguments:
  • y : Numeric
  • x : Numeric
atan2 ( xy : Vec2 ) : Float
Returns the arctangent of `y / x` for a Vec2, using the signs of both components to determine the correct quadrant.
Arguments:
  • xy : Vec2
atan2 ( y : Texture , x : Texture ) : Texture
Per-channel atan2 of two textures (1-channel broadcasts against either side)
Arguments:
  • y : Texture
  • x : Texture
atan2 ( y : Texture , x : Numeric ) : Texture
Per-channel atan2 of a texture `y` against a constant `x`
Arguments:
  • y : Texture
  • x : Numeric
atan2 ( y : Numeric , x : Texture ) : Texture
Per-channel atan2 of a constant `y` against a texture `x`
Arguments:
  • y : Numeric
  • x : Texture

ceil

ceil ( value : Numeric ) : Float
Rounds a numeric value up to the nearest integer
Arguments:
  • value : Numeric
ceil ( value : Vec3 ) : Vec3
Rounds each component of a Vec3 up to the nearest integer
Arguments:
  • value : Vec3
ceil ( value : Vec2 ) : Vec2
Rounds each component of a Vec2 up to the nearest integer
Arguments:
  • value : Vec2
ceil ( value : Texture ) : Texture
Applies ceil to every channel of a texture
Arguments:
  • value : Texture
ceil ( value : Vec4 ) : Vec4
Rounds each component of a Vec4 up to the nearest integer
Arguments:
  • value : Vec4

clamp

clamp ( min : Numeric , max : Numeric , value : Numeric ) : Int
Clamps a value between min and max
Arguments:
  • min : Numeric
  • max : Numeric
  • value : Numeric
clamp ( min : Numeric , max : Numeric , value : Numeric ) : Float
Clamps a value between min and max
Arguments:
  • min : Numeric
  • max : Numeric
  • value : Numeric
clamp ( min : Numeric , max : Numeric , value : Vec3 ) : Vec3
Clamps each component of a Vec3 between min and max
Arguments:
  • min : Numeric
  • max : Numeric
  • value : Vec3
clamp ( min : Numeric , max : Numeric , value : Vec2 ) : Vec2
Clamps each component of a Vec2 between min and max
Arguments:
  • min : Numeric
  • max : Numeric
  • value : Vec2
clamp ( min : Numeric , max : Numeric , value : Texture ) : Texture
Clamps every channel of a texture
Arguments:
  • min : Numeric
  • max : Numeric
  • value : Texture
clamp ( min : Numeric , max : Numeric , value : Vec4 ) : Vec4
Clamps each component of a Vec4 between min and max
Arguments:
  • min : Numeric
  • max : Numeric
  • value : Vec4

color_ramp

color_ramp ( stops : Sequence , domain : Vec2 | Sequence Vec2(0, 1) , extend : String String(clamp) , ease : Callable | String String(linear) , space : String String(oklab) ) : Callable
Color-specialized `ramp`: builds a gradient over vec3 stops (linear RGB in and out) and returns a callable `|x: float|: vec3`. Non-linear-space mixing bakes into a 256-entry LUT at construct time.
Arguments:
  • stops : Sequence - Stop list as in `ramp`; values must be vec3 colors in linear RGB (use `srgb(0xRRGGBB)` to bring in design-tool hex values).
  • domain : Vec2 | Sequence Vec2(0, 1) - `[lo, hi]` placement range used only by the bare-values stop form.
  • extend : String String(clamp) - Out-of-range behavior: "clamp" | "repeat" | "mirror" (period = stop extent).
  • ease : Callable | String String(linear) - Default segment easing: "linear" | "smooth" | "smoother" | "step", or a `|t|: float` callable evaluated at construct time.
  • space : String String(oklab) - Interpolation space: "oklab" (perceptually even; default) | "oklch" (hue as shorter-arc angle, stays saturated) | "linear" (raw RGB / light mixing) | "srgb" (legacy gamma-space, for matching design-tool gradients).

compose_transforms

compose_transforms ( transforms : Sequence ) : Mat4
Multiplies a sequence of transform matrices together: `compose_transforms([a, b, c])` is `a * b * c`. Matrix multiplication is not commutative — the LAST transform in the sequence is applied to a point FIRST. An empty sequence returns the identity.
Arguments:
  • transforms : Sequence - Sequence of `mat4`s to multiply together, left to right.

cos

cos ( value : Numeric ) : Float
Cosine
Arguments:
  • value : Numeric
cos ( value : Vec3 ) : Vec3
Returns a Vec3 with the cosine of each component
Arguments:
  • value : Vec3
cos ( value : Vec2 ) : Vec2
Returns a Vec2 with the cosine of each component
Arguments:
  • value : Vec2
cos ( value : Texture ) : Texture
Applies cosine to every channel of a texture
Arguments:
  • value : Texture
cos ( value : Vec4 ) : Vec4
Returns a Vec4 with the cosine of each component
Arguments:
  • value : Vec4

cosh

cosh ( value : Numeric ) : Float
Returns the hyperbolic cosine of a numeric value
Arguments:
  • value : Numeric
cosh ( value : Vec3 ) : Vec3
Returns a Vec3 with the hyperbolic cosine of each component
Arguments:
  • value : Vec3
cosh ( value : Vec2 ) : Vec2
Returns a Vec2 with the hyperbolic cosine of each component
Arguments:
  • value : Vec2

cross

cross ( a : Vec3 , b : Vec3 ) : Vec3
Cross product of two Vec3s, returning the Vec3 perpendicular to both (right-handed)
Arguments:
  • a : Vec3
  • b : Vec3

deg2rad

deg2rad ( value : Numeric ) : Float
Converts degrees to radians
Arguments:
  • value : Numeric

distance

alias: dist
distance ( a : Vec3 , b : Vec3 ) : Float
`sqrt((a.x - b.x)^2 + (a.y - b.y)^2 + (a.z - b.z)^2)`
Arguments:
  • a : Vec3
  • b : Vec3
distance ( a : Vec2 , b : Vec2 ) : Float
`sqrt((a.x - b.x)^2 + (a.y - b.y)^2`
Arguments:
  • a : Vec2
  • b : Vec2
distance ( a : Texture , b : Texture ) : Texture
Per-texel euclidean distance between two textures' channel vectors, producing a 1-channel texture
Arguments:
  • a : Texture
  • b : Texture
distance ( a : Vec4 , b : Vec4 ) : Float
`sqrt((a.x - b.x)^2 + (a.y - b.y)^2 + (a.z - b.z)^2 + (a.w - b.w)^2)`
Arguments:
  • a : Vec4
  • b : Vec4

div

div ( a : Vec3 , b : Vec3 ) : Vec3
Returns the component-wise division of two Vec3 values
Arguments:
  • a : Vec3
  • b : Vec3
div ( a : Vec3 , b : Numeric ) : Vec3
Divides each element of a Vec3 by a scalar
Arguments:
  • a : Vec3
  • b : Numeric
div ( a : Numeric , b : Numeric ) : Float
a / b
Arguments:
  • a : Numeric
  • b : Numeric
div ( a : Numeric , b : Numeric ) : Float
a / b
Arguments:
  • a : Numeric
  • b : Numeric
div ( a : Numeric , b : Numeric ) : Float
Divides two integers a / b and returns a float. The integers are converted to floats before division. If you need true integer division, use the `mod` function or `%` operator instead.
Arguments:
  • a : Numeric
  • b : Numeric
div ( a : Vec2 , b : Vec2 ) : Vec2
Returns the component-wise division of two `Vec2`s
Arguments:
  • a : Vec2
  • b : Vec2
div ( a : Vec2 , b : Numeric ) : Vec2
Divides each component of a Vec2 by a scalar
Arguments:
  • a : Vec2
  • b : Numeric
div ( a : Vec4 , b : Vec4 ) : Vec4
Returns the component-wise division of two Vec4 values
Arguments:
  • a : Vec4
  • b : Vec4
div ( a : Vec4 , b : Numeric ) : Vec4
Divides each element of a Vec4 by a scalar
Arguments:
  • a : Vec4
  • b : Numeric
div ( a : Texture , b : Texture ) : Texture
Divides two same-shape textures element-wise
Arguments:
  • a : Texture
  • b : Texture
div ( a : Texture , b : Numeric ) : Texture
Divides every channel of a texture by a scalar
Arguments:
  • a : Texture
  • b : Numeric
div ( a : Numeric , b : Texture ) : Texture
Scalar divided by every channel of a texture
Arguments:
  • a : Numeric
  • b : Texture
div ( a : Texture , b : Vec2 ) : Texture
Per-channel `texture / vec2` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec2
div ( a : Vec2 , b : Texture ) : Texture
Per-channel `vec2 / texture` (vec length must match the channel count)
Arguments:
  • a : Vec2
  • b : Texture
div ( a : Texture , b : Vec3 ) : Texture
Per-channel `texture / vec3` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec3
div ( a : Vec3 , b : Texture ) : Texture
Per-channel `vec3 / texture` (vec length must match the channel count)
Arguments:
  • a : Vec3
  • b : Texture
div ( a : Texture , b : Vec4 ) : Texture
Per-channel `texture / vec4` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec4
div ( a : Vec4 , b : Texture ) : Texture
Per-channel `vec4 / texture` (vec length must match the channel count)
Arguments:
  • a : Vec4
  • b : Texture

dot

dot ( a : Vec3 , b : Vec3 ) : Float
Dot product of two Vec3s: `a.x*b.x + a.y*b.y + a.z*b.z`
Arguments:
  • a : Vec3
  • b : Vec3
dot ( a : Vec2 , b : Vec2 ) : Float
Dot product of two Vec2s: `a.x*b.x + a.y*b.y`
Arguments:
  • a : Vec2
  • b : Vec2
dot ( a : Texture , b : Texture ) : Texture
Per-texel dot product of two textures' channel vectors, producing a 1-channel texture
Arguments:
  • a : Texture
  • b : Texture
dot ( a : Vec4 , b : Vec4 ) : Float
Dot product of two Vec4s: `a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w`
Arguments:
  • a : Vec4
  • b : Vec4

eq

eq ( a : Numeric , b : Numeric ) : Bool
`a == b`
Arguments:
  • a : Numeric
  • b : Numeric
eq ( a : Numeric , b : Numeric ) : Bool
`a == b`
Arguments:
  • a : Numeric
  • b : Numeric
eq ( a : Nil , b : Any ) : Bool
`a == b`
Arguments:
  • a : Nil
  • b : Any
eq ( a : Any , b : Nil ) : Bool
`a == b`
Arguments:
  • a : Any
  • b : Nil
eq ( a : Bool , b : Bool ) : Bool
`a == b`
Arguments:
  • a : Bool
  • b : Bool
eq ( a : String , b : String ) : Bool
`a == b`
Arguments:
  • a : String
  • b : String

exp

exp ( value : Numeric ) : Float
Returns the exponential of a numeric value
Arguments:
  • value : Numeric
exp ( value : Vec3 ) : Vec3
Returns a Vec3 with the exponential of each component
Arguments:
  • value : Vec3
exp ( value : Vec2 ) : Vec2
Returns a Vec2 with the exponential of each component
Arguments:
  • value : Vec2
exp ( value : Texture ) : Texture
Applies e^x to every channel of a texture
Arguments:
  • value : Texture
exp ( value : Vec4 ) : Vec4
Returns a Vec4 with the exponential of each component
Arguments:
  • value : Vec4

fix_float

fix_float ( value : Numeric ) : Float
If the provided float is NaN, non-infinite, or subnormal, returns 0.0. Otherwise, returns the float unchanged.
Arguments:
  • value : Numeric
fix_float ( value : Vec3 ) : Vec3
For each component of the Vec3, if it is NaN, non-infinite, or subnormal, returns 0.0. Otherwise, returns the component unchanged.
Arguments:
  • value : Vec3 - Vec3 value to fix
fix_float ( value : Vec2 ) : Vec2
For each component of the Vec2, if it is NaN, non-infinite, or subnormal, returns 0.0. Otherwise, returns the component unchanged.
Arguments:
  • value : Vec2 - Vec2 value to fix

floor

floor ( value : Numeric ) : Float
Rounds a numeric value down to the nearest integer
Arguments:
  • value : Numeric
floor ( value : Vec3 ) : Vec3
Rounds each component of a Vec3 down to the nearest integer
Arguments:
  • value : Vec3
floor ( value : Vec2 ) : Vec2
Rounds each component of a Vec2 down to the nearest integer
Arguments:
  • value : Vec2
floor ( value : Texture ) : Texture
Applies floor to every channel of a texture
Arguments:
  • value : Texture
floor ( value : Vec4 ) : Vec4
Rounds each component of a Vec4 down to the nearest integer
Arguments:
  • value : Vec4

fract

fract ( value : Numeric ) : Float
Returns the fractional part of a numeric value
Arguments:
  • value : Numeric
fract ( value : Vec3 ) : Vec3
Returns a Vec3 with the fractional part of each component
Arguments:
  • value : Vec3
fract ( value : Vec2 ) : Vec2
Returns a Vec2 with the fractional part of each component
Arguments:
  • value : Vec2
fract ( value : Texture ) : Texture
Applies fract to every channel of a texture
Arguments:
  • value : Texture
fract ( value : Vec4 ) : Vec4
Returns a Vec4 with the fractional part of each component
Arguments:
  • value : Vec4

gt

gt ( a : Numeric , b : Numeric ) : Bool
`a > b`
Arguments:
  • a : Numeric
  • b : Numeric
gt ( a : Numeric , b : Numeric ) : Bool
`a > b`
Arguments:
  • a : Numeric
  • b : Numeric

gte

gte ( a : Numeric , b : Numeric ) : Bool
`a >= b`
Arguments:
  • a : Numeric
  • b : Numeric
gte ( a : Numeric , b : Numeric ) : Bool
`a >= b`
Arguments:
  • a : Numeric
  • b : Numeric

inverse

inverse ( transform : Mat4 ) : Mat4
Returns the inverse of a transform matrix, which undoes it. Errors if the matrix is singular (e.g. it has a zero scale on some axis).
Arguments:
  • transform : Mat4

lerp

alias: mix
lerp ( t : Numeric , a : Vec3 , b : Vec3 ) : Vec3
Linearly interpolates between two Vec3 values `a` and `b` by a factor `t`
Arguments:
  • t : Numeric
  • a : Vec3
  • b : Vec3
lerp ( t : Numeric , a : Numeric , b : Numeric ) : Float
Linearly interpolates between two numeric values `a` and `b` by a factor `t`
Arguments:
  • t : Numeric
  • a : Numeric
  • b : Numeric
lerp ( t : Numeric , a : Vec2 , b : Vec2 ) : Vec2
Linearly interpolates between two Vec2 values `a` and `b` by a factor `t`
Arguments:
  • t : Numeric
  • a : Vec2
  • b : Vec2
lerp ( t : Numeric , a : Vec4 , b : Vec4 ) : Vec4
Linearly interpolates between two Vec4 values `a` and `b` by a factor `t`
Arguments:
  • t : Numeric
  • a : Vec4
  • b : Vec4
lerp ( t : Numeric , a : Texture , b : Texture ) : Texture
Linearly interpolates between two textures by a constant factor `t` (1-channel broadcasts against either side)
Arguments:
  • t : Numeric
  • a : Texture
  • b : Texture
lerp ( t : Texture , a : Texture , b : Texture ) : Texture
Linearly interpolates between two textures with a per-texel factor from texture `t` (1-channel broadcasts on any operand)
Arguments:
  • t : Texture
  • a : Texture
  • b : Texture

linearstep

linearstep ( edge0 : Numeric , edge1 : Numeric , x : Numeric ) : Float
Same as `smoothstep` but with simple linear interpolation instead of Hermite interpolation. It returns 0 if `x < edge0`, 1 if `x > edge1`, and a linear interpolation between 0 and 1 for values of `x` between `edge0` and `edge1`.
Arguments:
  • edge0 : Numeric
  • edge1 : Numeric
  • x : Numeric

ln

ln ( value : Numeric ) : Float
Returns the natural logarithm of a numeric value
Arguments:
  • value : Numeric
ln ( value : Vec3 ) : Vec3
Returns a Vec3 with the natural logarithm of each component
Arguments:
  • value : Vec3
ln ( value : Vec2 ) : Vec2
Returns a Vec2 with the natural logarithm of each component
Arguments:
  • value : Vec2

log10

log10 ( value : Numeric ) : Float
Returns the base-10 logarithm of a numeric value
Arguments:
  • value : Numeric
log10 ( value : Vec3 ) : Vec3
Returns a Vec3 with the base-10 logarithm of each component
Arguments:
  • value : Vec3
log10 ( value : Vec2 ) : Vec2
Returns a Vec2 with the base-10 logarithm of each component
Arguments:
  • value : Vec2

log2

log2 ( value : Numeric ) : Float
Returns the base-2 logarithm of a numeric value
Arguments:
  • value : Numeric
log2 ( value : Vec3 ) : Vec3
Returns a Vec3 with the base-2 logarithm of each component
Arguments:
  • value : Vec3
log2 ( value : Vec2 ) : Vec2
Returns a Vec2 with the base-2 logarithm of each component
Arguments:
  • value : Vec2
log2 ( value : Texture ) : Texture
Applies log base 2 to every channel of a texture
Arguments:
  • value : Texture
log2 ( value : Vec4 ) : Vec4
Returns a Vec4 with the base-2 logarithm of each component
Arguments:
  • value : Vec4

look_at

look_at ( pos : Vec3 , target : Vec3 , up : Vec3 Vec3(0, 1, 0) ) : Vec3
Euler angles (radians, XYZ) for an orientation whose local -Z points from `pos` toward `target`, with local +Y aligned to `up`. Feed the result to `rot`.
Arguments:
  • pos : Vec3 - Source position (the eye)
  • target : Vec3 - Target position to look at
  • up : Vec3 Vec3(0, 1, 0) - Up hint used to control roll
look_at ( mesh : Mesh , target : Vec3 , up : Vec3 Vec3(0, 1, 0) ) : Mesh
Orients a mesh so its local -Z points at `target`, with `up` controlling roll. Replaces the current rotation while preserving position and scale.
Arguments:
  • mesh : Mesh
  • target : Vec3 - Target position to look at
  • up : Vec3 Vec3(0, 1, 0) - Up hint used to control roll
look_at ( light : Light , target : Vec3 , up : Vec3 Vec3(0, 1, 0) ) : Light
Orients a light so its local -Z (emission direction) points at `target`, with `up` controlling roll. Replaces the current rotation while preserving position.
Arguments:
  • light : Light
  • target : Vec3 - Target position to look at
  • up : Vec3 Vec3(0, 1, 0) - Up hint used to control roll
look_at ( transform : Mat4 , target : Vec3 , up : Vec3 Vec3(0, 1, 0) ) : Mat4
Orients a transform matrix so its local -Z points at `target`, with `up` controlling roll. Replaces the current rotation while preserving position and scale.
Arguments:
  • transform : Mat4
  • target : Vec3 - Target position to look at
  • up : Vec3 Vec3(0, 1, 0) - Up hint used to control roll

lt

lt ( a : Numeric , b : Numeric ) : Bool
`a < b`
Arguments:
  • a : Numeric
  • b : Numeric
lt ( a : Numeric , b : Numeric ) : Bool
`a < b`
Arguments:
  • a : Numeric
  • b : Numeric

lte

lte ( a : Numeric , b : Numeric ) : Bool
`a <= b`
Arguments:
  • a : Numeric
  • b : Numeric
lte ( a : Numeric , b : Numeric ) : Bool
`a <= b`
Arguments:
  • a : Numeric
  • b : Numeric

mat4

mat4 ( m00 : Numeric , m01 : Numeric , m02 : Numeric , m03 : Numeric , m10 : Numeric , m11 : Numeric , m12 : Numeric , m13 : Numeric , m20 : Numeric , m21 : Numeric , m22 : Numeric , m23 : Numeric , m30 : Numeric , m31 : Numeric , m32 : Numeric , m33 : Numeric ) : Mat4
Builds a transform matrix from 16 explicit elements in row-major order. Transforms are treated as affine throughout: applying one to a point does not divide by `w`, so projective/perspective matrices are not supported.
Arguments:
  • m00 : Numeric
  • m01 : Numeric
  • m02 : Numeric
  • m03 : Numeric
  • m10 : Numeric
  • m11 : Numeric
  • m12 : Numeric
  • m13 : Numeric
  • m20 : Numeric
  • m21 : Numeric
  • m22 : Numeric
  • m23 : Numeric
  • m30 : Numeric
  • m31 : Numeric
  • m32 : Numeric
  • m33 : Numeric
mat4 ( ) : Mat4
Returns the identity transform matrix. Use it as the seed for a transform chain: `mat4() | trans(v3(2, 0, 0)) | rot(v3(0, pi/2, 0))`.

max

max ( a : Numeric , b : Numeric ) : Int
Returns the minimum of the provided arguments
Arguments:
  • a : Numeric
  • b : Numeric
max ( a : Numeric , b : Numeric ) : Float
Returns maximum of the provided arguments
Arguments:
  • a : Numeric
  • b : Numeric
max ( a : Vec3 , b : Vec3 ) : Vec3
Component-wise maximum of two Vec3s
Arguments:
  • a : Vec3
  • b : Vec3
max ( a : Vec2 , b : Vec2 ) : Vec2
Component-wise maximum of two Vec2s
Arguments:
  • a : Vec2
  • b : Vec2
max ( a : Texture , b : Texture ) : Texture
Element-wise maximum of two same-shape textures
Arguments:
  • a : Texture
  • b : Texture
max ( a : Texture , b : Numeric ) : Texture
Per-channel maximum of a texture and a scalar
Arguments:
  • a : Texture
  • b : Numeric
max ( a : Numeric , b : Texture ) : Texture
Per-channel maximum of a texture and a scalar
Arguments:
  • a : Numeric
  • b : Texture
max ( a : Vec4 , b : Vec4 ) : Vec4
Component-wise maximum of two Vec4s
Arguments:
  • a : Vec4
  • b : Vec4
max ( sequence : Sequence , by : Callable | Nil Nil ) : Any
Returns the element of the sequence with the largest key, or `nil` if the sequence is empty. The first of several equal-key elements wins.
Arguments:
  • sequence : Sequence
  • by : Callable | Nil Nil - Key function with signature `|x: T, ix: int|: K`, where `K` is an int, float, string, bool, or a list of those (compared element-wise, so `[primary, secondary]` sorts on multiple keys). Elements are used as their own keys if omitted.

min

min ( a : Numeric , b : Numeric ) : Int
Returns the minimum of the provided arguments
Arguments:
  • a : Numeric
  • b : Numeric
min ( a : Numeric , b : Numeric ) : Float
Returns minimum of the provided arguments
Arguments:
  • a : Numeric
  • b : Numeric
min ( a : Vec3 , b : Vec3 ) : Vec3
Component-wise minimum of two Vec3s
Arguments:
  • a : Vec3
  • b : Vec3
min ( a : Vec2 , b : Vec2 ) : Vec2
Component-wise minimum of two Vec2s
Arguments:
  • a : Vec2
  • b : Vec2
min ( a : Texture , b : Texture ) : Texture
Element-wise minimum of two same-shape textures
Arguments:
  • a : Texture
  • b : Texture
min ( a : Texture , b : Numeric ) : Texture
Per-channel minimum of a texture and a scalar
Arguments:
  • a : Texture
  • b : Numeric
min ( a : Numeric , b : Texture ) : Texture
Per-channel minimum of a texture and a scalar
Arguments:
  • a : Numeric
  • b : Texture
min ( a : Vec4 , b : Vec4 ) : Vec4
Component-wise minimum of two Vec4s
Arguments:
  • a : Vec4
  • b : Vec4
min ( sequence : Sequence , by : Callable | Nil Nil ) : Any
Returns the element of the sequence with the smallest key, or `nil` if the sequence is empty. The first of several equal-key elements wins.
Arguments:
  • sequence : Sequence
  • by : Callable | Nil Nil - Key function with signature `|x: T, ix: int|: K`, where `K` is an int, float, string, bool, or a list of those (compared element-wise, so `[primary, secondary]` sorts on multiple keys). Elements are used as their own keys if omitted.

mod

mod ( a : Numeric , b : Numeric ) : Int
a % b
Arguments:
  • a : Numeric
  • b : Numeric
mod ( a : Numeric , b : Numeric ) : Float
Floating point modulus (`a % b`)
Arguments:
  • a : Numeric
  • b : Numeric
mod ( a : Texture , b : Texture ) : Texture
Per-channel `a % b` of two textures (1-channel broadcasts against either side)
Arguments:
  • a : Texture
  • b : Texture
mod ( a : Texture , b : Numeric ) : Texture
Per-channel `a % b` of a texture against a constant
Arguments:
  • a : Texture
  • b : Numeric
mod ( a : Numeric , b : Texture ) : Texture
Per-channel `a % b` of a constant against a texture
Arguments:
  • a : Numeric
  • b : Texture

mul

mul ( a : Vec3 , b : Vec3 ) : Vec3
Returns the component-wise product of two Vec3 values
Arguments:
  • a : Vec3
  • b : Vec3
mul ( a : Vec3 , b : Numeric ) : Vec3
Multiplied each element of a Vec3 by a scalar
Arguments:
  • a : Vec3
  • b : Numeric
mul ( a : Numeric , b : Numeric ) : Float
a * b
Arguments:
  • a : Numeric
  • b : Numeric
mul ( a : Numeric , b : Numeric ) : Float
a * b
Arguments:
  • a : Numeric
  • b : Numeric
mul ( a : Numeric , b : Numeric ) : Int
a * b
Arguments:
  • a : Numeric
  • b : Numeric
mul ( mesh : Mesh , factor : Numeric ) : Mesh
Uniformly scales a mesh by a scalar factor
Arguments:
  • mesh : Mesh - Mesh to scale
  • factor : Numeric - Uniform scale to apply to the mesh
mul ( mesh : Mesh , factor : Vec3 ) : Mesh
Scales `mesh` by `factor` along each axis
Arguments:
  • mesh : Mesh
  • factor : Vec3
mul ( a : Vec2 , b : Vec2 ) : Vec2
Returns the component-wise product of two Vec2 values
Arguments:
  • a : Vec2
  • b : Vec2
mul ( a : Vec2 , b : Numeric ) : Vec2
Multiplied each element of a Vec2 by a scalar
Arguments:
  • a : Vec2
  • b : Numeric
mul ( a : Numeric , b : Vec2 ) : Vec2
Multiplied each element of a Vec2 by a scalar
Arguments:
  • a : Numeric
  • b : Vec2
mul ( a : Numeric , b : Vec3 ) : Vec3
Multiplied each element of a Vec3 by a scalar
Arguments:
  • a : Numeric
  • b : Vec3
mul ( a : Mat4 , b : Mat4 ) : Mat4
Composes two transform matrices. Matrix multiplication is not commutative: in `a * b`, `b` is applied to a point first and `a` second. See `compose_transforms` for the named equivalent.
Arguments:
  • a : Mat4
  • b : Mat4
mul ( a : Mat4 , b : Vec3 ) : Vec3
Transforms a 3D point by a transform matrix, treating it as a position (`w = 1`), so translation applies. Same as `transform_point`. Use `transform_dir` for directions, which ignores translation. Assumes an affine matrix; there is no perspective divide.
Arguments:
  • a : Mat4
  • b : Vec3
mul ( a : Vec4 , b : Vec4 ) : Vec4
Returns the component-wise product of two Vec4 values
Arguments:
  • a : Vec4
  • b : Vec4
mul ( a : Vec4 , b : Numeric ) : Vec4
Multiplies each element of a Vec4 by a scalar
Arguments:
  • a : Vec4
  • b : Numeric
mul ( a : Numeric , b : Vec4 ) : Vec4
Multiplies each element of a Vec4 by a scalar
Arguments:
  • a : Numeric
  • b : Vec4
mul ( a : Texture , b : Numeric ) : Texture
Multiplies every texel of a texture by a scalar
Arguments:
  • a : Texture
  • b : Numeric
mul ( a : Numeric , b : Texture ) : Texture
Multiplies every texel of a texture by a scalar
Arguments:
  • a : Numeric
  • b : Texture
mul ( a : Texture , b : Texture ) : Texture
Multiplies two textures elementwise (masking); dims and channel counts must match
Arguments:
  • a : Texture
  • b : Texture
mul ( a : Texture , b : Vec2 ) : Texture
Per-channel `texture * vec2` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec2
mul ( a : Vec2 , b : Texture ) : Texture
Per-channel `vec2 * texture` (vec length must match the channel count)
Arguments:
  • a : Vec2
  • b : Texture
mul ( a : Texture , b : Vec3 ) : Texture
Per-channel `texture * vec3` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec3
mul ( a : Vec3 , b : Texture ) : Texture
Per-channel `vec3 * texture` (vec length must match the channel count)
Arguments:
  • a : Vec3
  • b : Texture
mul ( a : Texture , b : Vec4 ) : Texture
Per-channel `texture * vec4` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec4
mul ( a : Vec4 , b : Texture ) : Texture
Per-channel `vec4 * texture` (vec length must match the channel count)
Arguments:
  • a : Vec4
  • b : Texture

neg

neg ( value : Numeric ) : Int
Negates an integer
Arguments:
  • value : Numeric
neg ( value : Numeric ) : Float
Negates a float
Arguments:
  • value : Numeric
neg ( value : Vec3 ) : Vec3
Negates each component of a Vec3
Arguments:
  • value : Vec3
neg ( value : Bool ) : Bool
Inverts a boolean (logical NOT)
Arguments:
  • value : Bool
neg ( value : Vec2 ) : Vec2
Negates each component of a Vec2
Arguments:
  • value : Vec2
neg ( value : Vec4 ) : Vec4
Negates each component of a Vec4
Arguments:
  • value : Vec4
neg ( value : Texture ) : Texture
Negates every channel of a texture
Arguments:
  • value : Texture

neq

neq ( a : Numeric , b : Numeric ) : Bool
`a != b`
Arguments:
  • a : Numeric
  • b : Numeric
neq ( a : Numeric , b : Numeric ) : Bool
`a != b`
Arguments:
  • a : Numeric
  • b : Numeric
neq ( a : Nil , b : Any ) : Bool
`a != b`
Arguments:
  • a : Nil
  • b : Any
neq ( a : Any , b : Nil ) : Bool
`a != b`
Arguments:
  • a : Any
  • b : Nil
neq ( a : Bool , b : Bool ) : Bool
`a != b`
Arguments:
  • a : Bool
  • b : Bool
neq ( a : String , b : String ) : Bool
`a != b`
Arguments:
  • a : String
  • b : String

normalize

normalize ( v : Vec3 ) : Vec3
Returns a normalized Vec3 (length 1) in the same direction as the input vector
Arguments:
  • v : Vec3
normalize ( v : Vec2 ) : Vec2
Returns a normalized Vec2 (length 1) in the same direction as the input vector
Arguments:
  • v : Vec2
normalize ( v : Texture ) : Texture
Per-texel normalization of a texture's channel vector to length 1
Arguments:
  • v : Texture
normalize ( v : Vec4 ) : Vec4
Returns a normalized Vec4 (length 1) in the same direction as the input vector
Arguments:
  • v : Vec4

poisson_points_2d

poisson_points_2d ( radius : Numeric , seed : Numeric Int(0) ) : Sequence
Generates a blue-noise (Poisson-disk) point set over [0,1)² via Bridson's algorithm, packed as densely as the radius allows. Distances are TOROIDAL, so the set tiles seamlessly with repeat-wrapped textures. Deterministic for a given seed.
Arguments:
  • radius : Numeric - Minimum distance between points, in UV units
  • seed : Numeric Int(0)
poisson_points_2d ( count : Numeric , seed : Numeric Int(0) ) : Sequence
Generates exactly `count` blue-noise (Poisson-disk) points over [0,1)² with toroidal distances (tiles seamlessly). The point order is shuffled, so any prefix is itself a well-spaced subset. Deterministic for a given seed.
Arguments:
  • count : Numeric - Exact number of points to return
  • seed : Numeric Int(0)

pos

pos ( value : Numeric ) : Numeric
Passes through the input unchanged (implementation detail of the unary `+` operator)
Arguments:
  • value : Numeric - h
pos ( value : Vec3 ) : Vec3
Passes through the input unchanged (implementation detail of the unary `+` operator)
Arguments:
  • value : Vec3
pos ( value : Vec2 ) : Vec2
Passes through the input unchanged (implementation detail of the unary `+` operator)
Arguments:
  • value : Vec2
pos ( value : Vec4 ) : Vec4
Passes through the input unchanged (implementation detail of the unary `+` operator)
Arguments:
  • value : Vec4

pow

pow ( base : Numeric , exponent : Numeric ) : Numeric
`Returns `base` raised to the power of `exponent``
Arguments:
  • base : Numeric
  • exponent : Numeric
pow ( base : Vec3 , exponent : Numeric ) : Vec3
Returns a Vec3 with each component raised to the power of `exponent`
Arguments:
  • base : Vec3
  • exponent : Numeric
pow ( base : Vec2 , exponent : Numeric ) : Vec2
Returns a Vec2 with each component raised to the power of `exponent`
Arguments:
  • base : Vec2
  • exponent : Numeric
pow ( base : Texture , exponent : Numeric ) : Texture
Raises every channel of a texture to a power
Arguments:
  • base : Texture
  • exponent : Numeric
pow ( base : Vec4 , exponent : Numeric ) : Vec4
Returns a Vec4 with each component raised to the power of `exponent`
Arguments:
  • base : Vec4
  • exponent : Numeric

rad2deg

rad2deg ( value : Numeric ) : Float
Converts radians to degrees
Arguments:
  • value : Numeric

ramp

ramp ( stops : Sequence , domain : Vec2 | Sequence Vec2(0, 1) , extend : String String(clamp) , ease : Callable | String String(linear) ) : Callable
Builds a multi-stop transfer function and returns it as a callable `|x: float|: float|vec3`. Native easings evaluate segments exactly; closure easings bake into a 256-entry LUT at construct time (documented quantization). Common use: mapping noise into other ranges, e.g. `fbm(pos=p) | ramp([[-1., 0.], [1., 1.]])`.
Arguments:
  • stops : Sequence - Stop list. Positioned form: `[[pos, value], …]` / `[[pos, value, ease], …]` / `[{pos, value, ease?}, …]` with positions in raw input units. Bare form: `[value, …]` spaced evenly over `domain`. Values must be all numbers or all vec3s (interpolated componentwise). Duplicate positions make a hard edge.
  • domain : Vec2 | Sequence Vec2(0, 1) - `[lo, hi]` placement range used only by the bare-values stop form.
  • extend : String String(clamp) - Out-of-range behavior: "clamp" | "repeat" | "mirror" (period = stop extent).
  • ease : Callable | String String(linear) - Default segment easing: "linear" | "smooth" | "smoother" | "step", or a `|t|: float` callable evaluated at construct time. A stop's own `ease` overrides it for the segment leaving that stop.

remap

remap ( in_lo : Numeric , in_hi : Numeric , out_lo : Numeric , out_hi : Numeric , x : Vec3 | Texture | Numeric , clamp : Bool Bool(false) ) : Float |Vec3 |Texture
Linearly maps `x` from `[in_lo, in_hi]` to `[out_lo, out_hi]`, extrapolating unless `clamp=true`.
Arguments:
  • in_lo : Numeric - Input range start.
  • in_hi : Numeric - Input range end.
  • out_lo : Numeric - Output range start.
  • out_hi : Numeric - Output range end.
  • x : Vec3 | Texture | Numeric - Value to remap (componentwise for vec3; every channel for a texture). Last so pipelines partially apply: `v | remap(-1., 1., 0., 1.)`.
  • clamp : Bool Bool(false) - Clamp the normalized position to [0, 1] before mapping (no extrapolation).

round

round ( value : Numeric ) : Float
Rounds a numeric value to the nearest integer
Arguments:
  • value : Numeric
round ( value : Vec3 ) : Vec3
Rounds each component of a Vec3 to the nearest integer
Arguments:
  • value : Vec3
round ( value : Vec2 ) : Vec2
Rounds each component of a Vec2 to the nearest integer
Arguments:
  • value : Vec2
round ( value : Texture ) : Texture
Applies round to every channel of a texture
Arguments:
  • value : Texture
round ( value : Vec4 ) : Vec4
Rounds each component of a Vec4 to the nearest integer
Arguments:
  • value : Vec4

sigmoid

sigmoid ( value : Numeric ) : Float
Sigmoid function
Arguments:
  • value : Numeric
sigmoid ( value : Vec3 ) : Vec3
Component-wise sigmoid of a Vec3
Arguments:
  • value : Vec3
sigmoid ( value : Vec2 ) : Vec2
Component-wise sigmoid of a Vec2
Arguments:
  • value : Vec2
sigmoid ( value : Texture ) : Texture
Applies sigmoid to every channel of a texture
Arguments:
  • value : Texture
sigmoid ( value : Vec4 ) : Vec4
Component-wise sigmoid of a Vec4
Arguments:
  • value : Vec4

signum

alias: sign
signum ( x : Numeric ) : Float
Returns -1, 0, or 1 depending on the sign of the input. For infinity, NaN, etc, the behavior is undefined.
Arguments:
  • x : Numeric
signum ( x : Numeric ) : Int
Returns -1, 0, or 1 depending on the sign of the input
Arguments:
  • x : Numeric
signum ( x : Vec2 ) : Vec2
Returns -1, 0, or 1 depending on the sign of the input element-wise
Arguments:
  • x : Vec2
signum ( x : Vec3 ) : Vec3
Returns -1, 0, or 1 depending on the sign of the input element-wise
Arguments:
  • x : Vec3

sin

sin ( value : Numeric ) : Float
Returns the sine of a numeric value
Arguments:
  • value : Numeric
sin ( value : Vec3 ) : Vec3
Returns the sine of each component of a Vec3
Arguments:
  • value : Vec3
sin ( value : Vec2 ) : Vec2
Returns a Vec2 with the sine of each component
Arguments:
  • value : Vec2
sin ( value : Texture ) : Texture
Applies sine to every channel of a texture
Arguments:
  • value : Texture
sin ( value : Vec4 ) : Vec4
Returns the sine of each component of a Vec4
Arguments:
  • value : Vec4

sinh

sinh ( value : Numeric ) : Float
Returns the hyperbolic sine of a numeric value
Arguments:
  • value : Numeric
sinh ( value : Vec3 ) : Vec3
Returns a Vec3 with the hyperbolic sine of each component
Arguments:
  • value : Vec3
sinh ( value : Vec2 ) : Vec2
Returns a Vec2 with the hyperbolic sine of each component
Arguments:
  • value : Vec2

smoothstep

smoothstep ( edge0 : Numeric , edge1 : Numeric , x : Numeric ) : Float
Works the same as `smoothstep` in GLSL. It returns 0 if `x < edge0`, 1 if `x > edge1`, and a smooth Hermite interpolation between 0 and 1 for values of `x` between `edge0` and `edge1`.
Arguments:
  • edge0 : Numeric
  • edge1 : Numeric
  • x : Numeric
smoothstep ( edge0 : Numeric , edge1 : Numeric , x : Texture ) : Texture
Applies smoothstep to every channel of a texture
Arguments:
  • edge0 : Numeric
  • edge1 : Numeric
  • x : Texture

sqrt

sqrt ( value : Numeric ) : Float
Square Root
Arguments:
  • value : Numeric
sqrt ( value : Vec3 ) : Vec3
Component-wise square root of a Vec3
Arguments:
  • value : Vec3
sqrt ( value : Vec2 ) : Vec2
Component-wise square root of a Vec2
Arguments:
  • value : Vec2
sqrt ( value : Texture ) : Texture
Applies the square root to every channel of a texture
Arguments:
  • value : Texture
sqrt ( value : Vec4 ) : Vec4
Component-wise square root of a Vec4
Arguments:
  • value : Vec4

srgb

srgb ( hex : Numeric ) : Vec3
Decodes an sRGB-encoded hex color to a linear-RGB vec3 — the correct way to bring design-tool colors into geoscript's linear color world.
Arguments:
  • hex : Numeric - sRGB-encoded hex color like `0xC97B4A`.
srgb ( r : Numeric , g : Numeric , b : Numeric ) : Vec3
Decodes sRGB-encoded channel values (0–1) to a linear-RGB vec3.
Arguments:
  • r : Numeric - sRGB-encoded red in [0, 1].
  • g : Numeric - sRGB-encoded green in [0, 1].
  • b : Numeric - sRGB-encoded blue in [0, 1].

sub

sub ( a : Vec3 , b : Vec3 ) : Vec3
Component-wise subtraction of two Vec3s
Arguments:
  • a : Vec3
  • b : Vec3
sub ( a : Numeric , b : Numeric ) : Float
a -b
Arguments:
  • a : Numeric
  • b : Numeric
sub ( a : Numeric , b : Numeric ) : Float
a - b
Arguments:
  • a : Numeric
  • b : Numeric
sub ( a : Numeric , b : Numeric ) : Int
a - b
Arguments:
  • a : Numeric
  • b : Numeric
sub ( a : Mesh , b : Mesh ) : Mesh
Returns the boolean difference of two meshes (`a - b`). This is equivalent to the `difference` function.
Arguments:
  • a : Mesh - Base mesh
  • b : Mesh - Mesh to subtract
sub ( mesh : Mesh , offset : Vec3 ) : Mesh
Translates the mesh by (`-offset`)
Arguments:
  • mesh : Mesh
  • offset : Vec3
sub ( vec : Vec3 , num : Numeric ) : Vec3
Subtracts a numeric value from each component of a Vec3
Arguments:
  • vec : Vec3
  • num : Numeric
sub ( a : Vec2 , b : Vec2 ) : Vec2
Subtracts two Vec2s component-wise
Arguments:
  • a : Vec2
  • b : Vec2
sub ( a : Vec2 , b : Numeric ) : Vec2
Subtracts a numeric value from each component of a Vec2
Arguments:
  • a : Vec2
  • b : Numeric
sub ( a : Vec4 , b : Vec4 ) : Vec4
Component-wise subtraction of two Vec4s
Arguments:
  • a : Vec4
  • b : Vec4
sub ( a : Vec4 , b : Numeric ) : Vec4
Subtracts a numeric value from each component of a Vec4
Arguments:
  • a : Vec4
  • b : Numeric
sub ( a : Texture , b : Texture ) : Texture
Subtracts two same-shape textures element-wise
Arguments:
  • a : Texture
  • b : Texture
sub ( a : Texture , b : Numeric ) : Texture
Subtracts a scalar from every channel of a texture
Arguments:
  • a : Texture
  • b : Numeric
sub ( a : Numeric , b : Texture ) : Texture
Scalar minus every channel of a texture
Arguments:
  • a : Numeric
  • b : Texture
sub ( a : Texture , b : Vec2 ) : Texture
Per-channel `texture - vec2` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec2
sub ( a : Vec2 , b : Texture ) : Texture
Per-channel `vec2 - texture` (vec length must match the channel count)
Arguments:
  • a : Vec2
  • b : Texture
sub ( a : Texture , b : Vec3 ) : Texture
Per-channel `texture - vec3` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec3
sub ( a : Vec3 , b : Texture ) : Texture
Per-channel `vec3 - texture` (vec length must match the channel count)
Arguments:
  • a : Vec3
  • b : Texture
sub ( a : Texture , b : Vec4 ) : Texture
Per-channel `texture - vec4` (vec length must match the channel count)
Arguments:
  • a : Texture
  • b : Vec4
sub ( a : Vec4 , b : Texture ) : Texture
Per-channel `vec4 - texture` (vec length must match the channel count)
Arguments:
  • a : Vec4
  • b : Texture

tan

tan ( value : Numeric ) : Float
Tangent
Arguments:
  • value : Numeric
tan ( value : Vec3 ) : Vec3
Returns the tangent of each component of a Vec3
Arguments:
  • value : Vec3
tan ( value : Vec2 ) : Vec2
Returns a Vec2 with the tangent of each component
Arguments:
  • value : Vec2
tan ( value : Texture ) : Texture
Applies tangent to every channel of a texture
Arguments:
  • value : Texture
tan ( value : Vec4 ) : Vec4
Returns the tangent of each component of a Vec4
Arguments:
  • value : Vec4

tanh

tanh ( value : Numeric ) : Float
Returns the hyperbolic tangent of a numeric value
Arguments:
  • value : Numeric
tanh ( value : Vec3 ) : Vec3
Returns a Vec3 with the hyperbolic tangent of each component
Arguments:
  • value : Vec3
tanh ( value : Vec2 ) : Vec2
Returns a Vec2 with the hyperbolic tangent of each component
Arguments:
  • value : Vec2

transform_dir

transform_dir ( transform : Mat4 , dir : Vec3 ) : Vec3
Transforms a 3D direction by a transform matrix, treating it as a vector (`w = 0`) so translation is ignored. Rotation and scale still apply, so the result is not normalized. For normals under non-uniform scale use `transform_normal`.
Arguments:
  • transform : Mat4
  • dir : Vec3

transform_normal

transform_normal ( transform : Mat4 , normal : Vec3 ) : Vec3
Transforms a surface normal by a transform matrix using the inverse transpose, so normals stay perpendicular to the surface under non-uniform scale. The result is normalized. Errors if the matrix is singular or the normal is degenerate.
Arguments:
  • transform : Mat4
  • normal : Vec3

transform_point

transform_point ( transform : Mat4 , point : Vec3 ) : Vec3
Transforms a 3D point by a transform matrix, treating it as a position (`w = 1`) so translation applies. Equivalent to `transform * point`. Assumes an affine matrix; there is no perspective divide.
Arguments:
  • transform : Mat4
  • point : Vec3

transpose

transpose ( transform : Mat4 ) : Mat4
Returns the transpose of a transform matrix (rows and columns swapped).
Arguments:
  • transform : Mat4
transpose ( texture : Texture ) : Texture
Swaps a texture's axes (`out[x, y] = in[y, x]`, so a WxH input yields HxW). O(1): returns a view of the same pixel data. Same as `texture_transpose`.
Arguments:
  • texture : Texture

trunc

trunc ( value : Numeric ) : Float
Truncates a numeric value to its integer part
Arguments:
  • value : Numeric
trunc ( value : Vec3 ) : Vec3
Truncates each component of a Vec3 to its integer part
Arguments:
  • value : Vec3
trunc ( value : Vec2 ) : Vec2
Truncates each component of a Vec2 to its integer part
Arguments:
  • value : Vec2
trunc ( value : Texture ) : Texture
Applies trunc to every channel of a texture
Arguments:
  • value : Texture
trunc ( value : Vec4 ) : Vec4
Truncates each component of a Vec4 to its integer part
Arguments:
  • value : Vec4

mesh

aabb

aabb ( mesh : Mesh ) : Sequence
Returns the axis-aligned bounding box of `mesh` as a 2-element sequence `[mins, maxs]` of Vec3 corners, in world space (after the mesh's transform is applied). Errors if the mesh is empty.
Arguments:
  • mesh : Mesh - The mesh to compute the axis-aligned bounding box of.

align

align ( to : Vec3 , mesh : Mesh , from : Vec3 Vec3(0, 0, -1) , up_from : Vec3 | Nil Nil , up_to : Vec3 | Nil Nil ) : Mesh
Rotates a mesh so its local `from` axis points along world-space direction `to`. Without `up_from`/`up_to` this is the minimal rotation (no roll control); supplying them additionally rolls about `to` so `up_from` points toward `up_to`. Replaces the current rotation while preserving position and scale.
Arguments:
  • to : Vec3 - World-space direction to point the `from` axis along (auto-normalized)
  • mesh : Mesh
  • from : Vec3 Vec3(0, 0, -1) - Local-space axis to align (auto-normalized); defaults to -Z
  • up_from : Vec3 | Nil Nil - Optional secondary local axis for roll control, rolled toward `up_to` (best-effort, projected perpendicular to `from`). Must be paired with `up_to`.
  • up_to : Vec3 | Nil Nil - World-space target for `up_from`. Must be paired with `up_from`.
align ( to : Vec3 , light : Light , from : Vec3 Vec3(0, 0, -1) , up_from : Vec3 | Nil Nil , up_to : Vec3 | Nil Nil ) : Light
Rotates a light so its local `from` axis points along world-space direction `to`. Without `up_from`/`up_to` this is the minimal rotation (no roll control); supplying them additionally rolls about `to` so `up_from` points toward `up_to`. Replaces the current rotation while preserving position.
Arguments:
  • to : Vec3 - World-space direction to point the `from` axis along (auto-normalized)
  • light : Light
  • from : Vec3 Vec3(0, 0, -1) - Local-space axis to align (auto-normalized); defaults to -Z
  • up_from : Vec3 | Nil Nil - Optional secondary local axis for roll control, rolled toward `up_to` (best-effort, projected perpendicular to `from`). Must be paired with `up_to`.
  • up_to : Vec3 | Nil Nil - World-space target for `up_from`. Must be paired with `up_from`.
align ( to : Vec3 , transform : Mat4 , from : Vec3 Vec3(0, 0, -1) , up_from : Vec3 | Nil Nil , up_to : Vec3 | Nil Nil ) : Mat4
Rotates a transform matrix so its local `from` axis points along world-space direction `to`. Without `up_from`/`up_to` this is the minimal rotation (no roll control); supplying them additionally rolls about `to` so `up_from` points toward `up_to`. Replaces the current rotation while preserving position and scale.
Arguments:
  • to : Vec3 - World-space direction to point the `from` axis along (auto-normalized)
  • transform : Mat4
  • from : Vec3 Vec3(0, 0, -1) - Local-space axis to align (auto-normalized); defaults to -Z
  • up_from : Vec3 | Nil Nil - Optional secondary local axis for roll control, rolled toward `up_to` (best-effort, projected perpendicular to `from`). Must be paired with `up_to`.
  • up_to : Vec3 | Nil Nil - World-space target for `up_from`. Must be paired with `up_from`.

alpha_wrap_3d

alias: alpha_wrap
Example
distance_to_circle = |p: vec3, radius: num| sqrt(p.y*p.y + pow(sqrt(p.x*p.x + p.z*p.z) - radius, 2)); radius = 8 0.. -> || { randv(-radius*1.1, radius*1.1) } | filter(|p| distance_to_circle(p, radius) < 2) | take(1550) | alpha_wrap(alpha=1/100, offset=1/100) | smooth(iterations=2) | simplify(tolerance=0.01) | render
alpha_wrap_3d ( mesh : Mesh , alpha : Numeric Float(0.033333335) , offset : Numeric Float(0.03) , manifold : Bool Bool(true) , seeds : Sequence | Nil Nil ) : Mesh
Computes an alpha-wrap of a mesh. This is kind of like a concave version of a convex hull. This function is guaranteed to produce watertight/2-manifold outputs. `alpha_wrap` is an alias. For more details, see here: https://doc.cgal.org/latest/Alpha_wrap_3/index.html
Arguments:
  • mesh : Mesh
  • alpha : Numeric Float(0.033333335) - Controls the feature size of the computed wrapping. Smaller values will capture more detail and produce more faces. This value is relative to the bounding box of the input mesh. Values should be in the range (0, 1).
  • offset : Numeric Float(0.03) - Controls the offset distance between the the input and the wrapped output mesh surfaces. Larger values will result in simpler outputs with better triangle quality, potentially at the cost of sharp edges and fine details. This value is relative to the bounding box of the input mesh. Values should be in the range (0, 1).
  • manifold : Bool Bool(true) - Post-processes the wrap so it is geometrically 2-manifold as well as combinatorially (no separate sheets touching at a vertex or edge). Disable for a slightly faster wrap that may contain such pinches.
  • seeds : Sequence | Nil Nil - Optional sequence of Vec3 points from which the wrap starts instead of from the outside. Each seed must sit inside a cavity of the input with room for a sphere of radius `alpha` around it; the result is then the wrap of that enclosed space (e.g. the inside of a room) rather than of the outside.
alpha_wrap_3d ( points : Sequence , alpha : Numeric Float(0.033333335) , offset : Numeric Float(0.03) , manifold : Bool Bool(true) , seeds : Sequence | Nil Nil ) : Mesh
Computes an alpha-wrap of a sequence of points. This is kind of like a concave version of a convex hull. This function is guaranteed to produce watertight/2-manifold outputs. For more details, see here: https://doc.cgal.org/latest/Alpha_wrap_3/index.html
Arguments:
  • points : Sequence
  • alpha : Numeric Float(0.033333335) - Controls the feature size of the computed wrapping. Smaller values will capture more detail and produce more faces. This value is relative to the bounding box of the input points. Values should be in the range (0, 1).
  • offset : Numeric Float(0.03) - Controls the offset distance between the the input and the wrapped output mesh surfaces. Larger values will result in simpler outputs with better triangle quality, potentially at the cost of sharp edges and fine details. This value is relative to the bounding box of the input points. Values should be in the range (0, 1).
  • manifold : Bool Bool(true) - Post-processes the wrap so it is geometrically 2-manifold as well as combinatorially (no separate sheets touching at a vertex or edge). Disable for a slightly faster wrap that may contain such pinches.
  • seeds : Sequence | Nil Nil - Optional sequence of Vec3 points from which the wrap starts instead of from the outside. Each seed must sit inside a cavity of the input with room for a sphere of radius `alpha` around it; the result is then the wrap of that enclosed space (e.g. the inside of a room) rather than of the outside.

apply_mat4

apply_mat4 ( m00 : Numeric , m01 : Numeric , m02 : Numeric , m03 : Numeric , m10 : Numeric , m11 : Numeric , m12 : Numeric , m13 : Numeric , m20 : Numeric , m21 : Numeric , m22 : Numeric , m23 : Numeric , m30 : Numeric , m31 : Numeric , m32 : Numeric , m33 : Numeric , mesh : Mesh ) : Mesh
Sets the transform of a mesh to an explicit 4x4 matrix (row-major order)
Arguments:
  • m00 : Numeric
  • m01 : Numeric
  • m02 : Numeric
  • m03 : Numeric
  • m10 : Numeric
  • m11 : Numeric
  • m12 : Numeric
  • m13 : Numeric
  • m20 : Numeric
  • m21 : Numeric
  • m22 : Numeric
  • m23 : Numeric
  • m30 : Numeric
  • m31 : Numeric
  • m32 : Numeric
  • m33 : Numeric
  • mesh : Mesh
apply_mat4 ( matrix : Mat4 , mesh : Mesh ) : Mesh
Sets the transform of a mesh to the given `mat4`
Arguments:
  • matrix : Mat4
  • mesh : Mesh

apply_transforms

apply_transforms ( mesh : Mesh ) : Mesh
Applies rotation, translation, and scale transforms to the vertices of a mesh, resetting the transforms to identity
Arguments:
  • mesh : Mesh
apply_transforms ( path : Path ) : Path
Bakes the 2D affine transform into the path's segment control points, resetting the transform to identity. Only works with trace_path/trace_svg_path paths.
Arguments:
  • path : Path - Path whose transform will be baked into its geometry.
apply_transforms ( meshes : Sequence ) : Sequence
Applies transforms to each mesh in a sequence, resetting each transform to identity.
Arguments:
  • meshes : Sequence - Sequence of meshes whose transforms will be baked into their vertices.

attr

attr ( name : String , mesh : Mesh ) : Sequence
Returns the values of per-vertex attribute `name` as a sequence in `verts` order (`nil` for vertices lacking a value). Errors if the mesh has no such attribute.
Arguments:
  • name : String
  • mesh : Mesh

attrs

attrs ( mesh : Mesh ) : Sequence
Returns the names of the mesh's per-vertex attributes, sorted.
Arguments:
  • mesh : Mesh

bake_ao

bake_ao ( mesh : Mesh , samples : Nil | Numeric Nil , max_dist : Nil | Numeric Nil , occluders : Mesh | Sequence | Nil Nil , bias : Nil | Numeric Nil , into : String String(ao) , refine : Nil | Numeric Nil , min_edge : Nil | Numeric Nil , split_seams : Bool Bool(true) ) : Mesh
Bakes ambient occlusion per vertex into a scalar attribute: the fraction of cosine-weighted hemisphere rays from each vertex (around its smooth normal) that escape `mesh` and `occluders`; 1 = open, 0 = buried. Sampling is deterministic, so re-evaluation is stable. Resolution is the mesh's own: a large triangle gets a linear ramp between its corners, so either `tessellate` first where occlusion detail matters or pass `refine` to split edges only where the ramp is wrong, and `smooth_attr` the result to soften noise (typically `smooth_attr("ao", iterations=2, weights="cotan")`). Read it in shaders via the material's `vertexAttrs`, or write it into `color`, which every material multiplies in by default.
Arguments:
  • mesh : Mesh
  • samples : Nil | Numeric Nil - Rays per vertex; `nil` = 32, or 256 with `refine`. Cost is vertices x samples; 16 is fine while iterating, 64+ for a final bake. Estimator noise falls as ~0.34/samples^0.75 (RMS 0.025 at 32, 0.005 at 256), which is also what bounds how finely `refine` can resolve.
  • max_dist : Nil | Numeric Nil - Ignore hits farther than this (world units) for local occlusion; `nil` = unlimited.
  • occluders : Mesh | Sequence | Nil Nil - Other meshes that block rays in addition to `mesh` itself (world space).
  • bias : Nil | Numeric Nil - Ray-origin offset along the normal to avoid self-hits; defaults to 1e-4 of the mesh's bounding diagonal.
  • into : String String(ao) - Name of the scalar attribute written.
  • refine : Nil | Numeric Nil - AO tolerance for adaptive tessellation. Each face's edge midpoints and centroid are sampled (quarter points too on edges whose ends differ by more than this); where a sample differs from the linear interpolation of the corners by more than this, the face is bisected (longest edge first, Rivara-style, so triangles stay well-shaped; seam twins split together) and the new faces tested in turn, so vertices land only where a linear ramp would be wrong. Costs roughly one extra sample per edge and per face of the output. Clamped to the sampling noise floor, ~1.3/samples^0.75 (0.095 at 32 samples, 0.02 at 256, 0.012 at 512), with a printed notice; below it noise would refine every penumbra down to `min_edge`. So `samples` sets the finest resolvable feature and `refine` the accepted interpolation error. `nil` leaves the mesh as is.
  • min_edge : Nil | Numeric Nil - With `refine`, edges shorter than this (world units) are never split; defaults to 1% of the mesh's bounding diagonal.
  • split_seams : Bool Bool(true) - Split the mesh along sharp edges and recompute shading normals first, exactly like `compute_normals` with the runtime sharp-angle threshold, so each side of a crease bakes with its own normal and holds its own AO (and `smooth_attr` can't bleed across it). Off, a crease vertex gets one value blended over both sides. Leaves the mesh open along creases like the exported mesh already is, so bake last; already-split meshes are unaffected.

bipyramid

bipyramid ( n : Numeric , radius : Numeric Float(1) , height : Numeric Float(1) ) : Mesh
N-gonal bipyramid: a regular `n`-gon equator (radius) in the XZ plane with apexes at ±`height` on Y. `bipyramid(4)` is the axis-aligned octahedron; larger `n` gives gem-like diamonds.
Arguments:
  • n : Numeric - Number of sides of the equatorial polygon (>= 3)
  • radius : Numeric Float(1) - Circumradius of the equatorial polygon
  • height : Numeric Float(1) - Distance from the center to each apex along Y

box

alias: cube
box ( width : Numeric , height : Numeric , depth : Numeric ) : Mesh
Creates a rectangular prism mesh with the specified width, height, and depth
Arguments:
  • width : Numeric - Width along the X axis
  • height : Numeric - Height along the Y axis
  • depth : Numeric - Depth along the Z axis
box ( size : Vec3 | Numeric Vec3(1, 1, 1) ) : Mesh
Creates a box using a uniform or vector size
Arguments:
  • size : Vec3 | Numeric Vec3(1, 1, 1) - Size of the box as a Vec3, or a single numeric value for a cube

capsule

capsule ( radius : Numeric Float(1) , height : Numeric Float(1) , cap_segments : Numeric Int(4) , radial_segments : Numeric Int(8) , height_segments : Numeric Int(1) ) : Mesh
Generates a capsule mesh (cylinder with hemispherical caps)
Arguments:
  • radius : Numeric Float(1) - Radius of the capsule
  • height : Numeric Float(1) - Height of the cylindrical middle section. The total height of the capsule is `height + 2 * radius`.
  • cap_segments : Numeric Int(4) - Number of curve segments used to build each hemispherical cap
  • radial_segments : Numeric Int(8) - Number of segmented faces around the circumference
  • height_segments : Numeric Int(1) - Number of rows of faces along the height of the middle section

compute_normals

compute_normals ( mesh : Mesh , smooth_angle : Nil | Numeric Nil ) : Mesh
Recomputes a mesh's shading normals using dihedral-angle auto-smoothing (like Blender's shade-auto-smooth), replacing any existing normals so hard edges get crisp creasing while smooth regions stay smooth. Existing `uv`/`tangent` attributes are preserved, and authored attribute seams (e.g. a `rail_sweep` `split_seams` UV seam, or a `compute_uvs` cut) that run through a smooth region are re-smoothed so they don't read as a lighting crease. Useful after `rail_sweep` with `split_seams` (which bakes fully-smooth normals) to restore crisp creasing without losing the procedural UVs.
Arguments:
  • mesh : Mesh
  • smooth_angle : Nil | Numeric Nil - Dihedral crease threshold in degrees: an edge whose two faces differ in orientation by more than this becomes a sharp (hard) shading edge, while smoother edges are shaded smooth. Larger values smooth more. Defaults to the runtime sharp-angle threshold (see `set_sharp_angle_threshold`).

compute_uvs

compute_uvs ( mesh : Mesh , type : String String(auto) , scale : Numeric Float(1) , n_cones : Numeric Int(0) , island_rotation : Bool Bool(false) , options : Map | Nil Nil , name : String | Nil Nil , label : String | Nil Nil ) : Mesh
Procedurally generates UV coordinates and tangents for a mesh, returning a new mesh with `uv` and `tangent` vertex attributes populated. Conformal types (auto/unwrap/disk/sphere) are backed by the BFF unwrap module; "planar" is a native planar projection.
Arguments:
  • mesh : Mesh
  • type : String String(auto) - UV generation method. "auto", "unwrap", "disk", and "sphere" produce a minimal-distortion conformal unwrap via the BFF module. "planar" projects onto the mesh's dominant plane natively. "cylindrical" wraps U around the auto-detected axis exactly once (seamless 0/1, meridian seam split); V is scaled by the tube circumference so texels stay square (isotropic), and cap faces get a planar disk projection at the tube's density. It works best on tube-dominant meshes (length > diameter) where the axis is unambiguous and mostly straight. "tube" generalizes it to bent/deformed closed tube-like meshes (elbows, arches, trim, pipes) via harmonic fields: U wraps the cross-section once, V runs along the tube arc-length-uniformly, and crease-bounded end caps become planar islands (see `options`). Requires closed genus-0. "strip" is a solver-free topological trim-strip unwrap: the mesh is split into smooth patches at sharp edges, and each patch that is a quad/tri strip (dual graph a path or ring) is mapped STRAIGHT in UV space — U = arc length along the strip's rails, V constant per rail — so a horizontally-patterned texture flows smoothly along a curved strip. Ring strips are cut and rounded to an integer repeat count; non-strip patches fall back to planar islands (see `options`). Best for hard-edged extrusions/profiles (square/polygonal pipes, frames, trim). "toroidal" (closed genus-1) is reserved and not yet implemented.
  • scale : Numeric Float(1) - Multiplier applied to the generated UV coordinates. Larger values tile a texture more densely. For "cylindrical" and "tube", integer values preserve the seamless wrap. Closed "strip" rings stay seamless at any scale (their repeat count is rounded to an integer after scaling).
  • n_cones : Numeric Int(0) - Number of cone singularities for the conformal unwrap. 0 lets BFF pick automatically for closed surfaces. Ignored by non-BFF types.
  • island_rotation : Bool Bool(false) - Ignored; kept so older programs still parse. Island orientation for BFF types is controlled via `options` (`up`, `fallback`, `axis`).
  • options : Map | Nil Nil - Map of options specific to the chosen `type`. For "auto"/"unwrap"/"disk"/"sphere": `{ up: '+y', fallback: '-z', axis: '+v', pre_split: true }` — when `up` is given, each UV island is rotated so texture axis `axis` ('+v' = texture up, or '+u'/'-v'/'-u') follows that local-space direction on every face, with faces whose normal is within 15° of `up` using `fallback` instead; omit `up` to let islands rotate freely for tighter packing. `pre_split` (default true) splits sharp edges topologically (per the sharp-angle threshold) before the conformal solve, so creases become boundaries the unwrap can cut islands along — usually what you want for hard-surface meshes; set false to unwrap the welded smooth surface instead (note "sphere" mapping needs closed topology, so on a creased mesh it only engages with `pre_split: false`). For "cylindrical": `{ normalize_v: bool }` — when true, V is stretched to span 0..1 across the mesh's axial extent instead of being circumference-scaled for square texels. For "tube": `{ caps: 'auto'|'none', cap_angle: degrees, cap_max_span: float, cap_alignment: float, normalize_v: bool, seam_straightness: float, detwist: bool }` — `caps` toggles end-cap island detection; `cap_angle` is the crease angle bounding a cap patch (defaults to the mesh sharp-edge threshold); `cap_max_span` is the max fraction of tube length a cap may span (default 0.15); `cap_alignment` is the min alignment between cap normal and local tube direction, 0..1 (default 0.6); `normalize_v` makes V span 0..1 over the tube length instead of isotropic scaling; `seam_straightness` (default 8) penalizes the internal seam cut for traveling around the tube instead of along it, preventing the texture from twisting along the spine (0 = plain shortest-path seam); `detwist` (default true) cancels any residual rotational drift of U along the spine by referencing a rotation-minimizing frame. For "strip": `{ strip_angle: degrees, layout: 'stack'|'overlap'|'fill', u_mode: 'uniform'|'rail', fallback: 'planar'|'error' }` — `strip_angle` is the crease angle that splits the mesh into patches (defaults to the mesh sharp-edge threshold); `layout` places islands in V: 'stack' (default) stacks them at integer V offsets, 'overlap' gives every island the same V band starting at 0, 'fill' stretches each island's V to span 0..1 with U scaled to keep texels square; `u_mode` 'uniform' (default) gives both rails a shared U so quads map to true rectangles (a ring band's inner rail stretches instead of shearing), 'rail' keeps each rail's own arc length (exact per-rail texel density, shears when rail lengths differ); `fallback` controls non-strip patches: 'planar' (default) maps them as planar islands, 'error' fails so unexpected topology is surfaced.
  • name : String | Nil Nil - When given, registers an editor control for this call's UV params (like the `input_*` builtins): the UI's stored value overrides `type`/`scale`/`n_cones`/`options`, which act as defaults. Unique per node; always pass as a kwarg (`name='...'`).
  • label : String | Nil Nil - Display label for the control; falls back to `name`.
compute_uvs ( type : String , mesh : Mesh , scale : Numeric Float(1) , n_cones : Numeric Int(0) , options : Map | Nil Nil , name : String | Nil Nil , label : String | Nil Nil ) : Mesh
Pipe-friendly form with `type` first: `mesh | compute_uvs('planar', scale=2)` partially applies and the piped mesh fills the `mesh` slot. Args past `type` should be passed as kwargs when piping.
Arguments:
  • type : String - UV generation method; see the first signature for the full list.
  • mesh : Mesh
  • scale : Numeric Float(1) - Multiplier applied to the generated UV coordinates.
  • n_cones : Numeric Int(0) - Number of cone singularities for the conformal unwrap; ignored by non-BFF types.
  • options : Map | Nil Nil - Map of options specific to the chosen `type`; see the first signature.
  • name : String | Nil Nil - When given, registers an editor control for this call's UV params; see the first signature.
  • label : String | Nil Nil - Display label for the control; falls back to `name`.

cone

cone ( radius : Numeric , height : Numeric , radial_segments : Numeric , height_segments : Numeric Int(1) ) : Mesh
Generates a cone mesh. The base of the cone is centered at the origin, and the cone extends upwards along the positive Y axis.
Arguments:
  • radius : Numeric
  • height : Numeric
  • radial_segments : Numeric
  • height_segments : Numeric Int(1)

connected_components

Example
0..10 -> || { sphere(radius=1.15, resolution=2) | trans(randv(-3, 3)) } | union | connected_components -> |component: mesh, i: int| { component | set_material(str(i)) } | render
connected_components ( mesh : Mesh ) : Sequence
Splits a mesh into its connected components, returning a sequence of meshes where each mesh is a connected component of the input mesh. The sequence of connected components is sorted by vertex count from highest to lowest. This is NOT lazy; the connected components are computed at the time this function is called.
Arguments:
  • mesh : Mesh

convex_hull

Example
// pick 50,000 random points within 1 unit of the origin points = 0..100000000 -> || { randv(0, 1) } | filter(|v| len(v) < 1) | take(50000) // Create a mesh bounded by the convex hull of all those // points. This is the smallest convex shape that contains // all of the points. points | convex_hull | render
convex_hull ( points : Sequence ) : Mesh
Computes the convex hull of a sequence of points, returning a mesh representing the convex hull
Arguments:
  • points : Sequence
convex_hull ( mesh : Mesh ) : Mesh
Computes the convex hull of a mesh, returning a mesh representing the convex hull. This will apply all transforms on the mesh, and the returned mesh will have an identity transform.
Arguments:
  • mesh : Mesh

cylinder

alias: cyl
cylinder ( radius : Numeric , height : Numeric , radial_segments : Numeric , height_segments : Numeric Int(1) ) : Mesh
Generates a cylinder mesh
Arguments:
  • radius : Numeric
  • height : Numeric
  • radial_segments : Numeric
  • height_segments : Numeric Int(1)

delaunay_remesh

delaunay_remesh ( mesh : Mesh , facet_distance : Numeric Float(0.14) , target_edge_length : Numeric Float(0.2) , protect_sharp_edges : Bool Bool(true) , sharp_angle_threshold_degrees : Numeric Float(30) ) : Mesh
Remeshes a mesh using a Delaunay refinement of a restricted Delaunay triangulation. TODO improve docs once we understand the behavior of this function better. See the docs for the underlying CGAL function for more details: https://doc.cgal.org/latest/Polygon_mesh_processing/index.html - Section 2.1.2 Remeshing
Arguments:
  • mesh : Mesh
  • facet_distance : Numeric Float(0.14) - This controls the precision of the output mesh. Smaller values will produce meshes that more closely approximate the input, but will also produce more faces. This value represents units in the local space of the mesh, so it must be chosen relative to the size of the input mesh.
  • target_edge_length : Numeric Float(0.2) - This serves as an upper bound for the lengths of curve edges in the underlying Delaunay triangulation. Smaller values will produce more faces. This value represents units in the local space of the mesh, so it must be chosen relative to the size of the input mesh.
  • protect_sharp_edges : Bool Bool(true) - If true, edges with angles >= the `sharp_angle_threshold_degrees` will not be modified.
  • sharp_angle_threshold_degrees : Numeric Float(30) - Angle threshold in degrees for edges to be considered sharp. Only used if `protect_sharp_edges` is true.

difference

Example
a = box(size=8) b = icosphere(radius=5, resolution=5) // subtract the space inside the sphere from the cube core = sub(a, b) // You can also just use `-` instead. The following is // equivalent to the previous: core = a - b core | render
difference ( a : Mesh , b : Mesh , split_seams : Bool Bool(false) ) : Mesh
Returns the boolean difference of two meshes (`a - b`)
Arguments:
  • a : Mesh - Base mesh
  • b : Mesh - Mesh to subtract
  • split_seams : Bool Bool(false) - When the operands carry per-vertex attributes, the cut curve is an attribute seam. By default its vertices are welded, blending both sides' values, so the output stays 2-manifold. `true` keeps each side's values on duplicate vertices instead (like `rail_sweep`'s `split_seams`), leaving the mesh open along the cut. Authored seams such as UV cuts survive either way.
difference ( meshes : Sequence , split_seams : Bool Bool(false) ) : Mesh
Returns the boolean difference of a sequence of meshes (`meshes[0] - meshes[1] - ...`)
Arguments:
  • meshes : Sequence - Sequence of meshes to subtract in order
  • split_seams : Bool Bool(false) - When the operands carry per-vertex attributes, the cut curve is an attribute seam. By default its vertices are welded, blending both sides' values, so the output stays 2-manifold. `true` keeps each side's values on duplicate vertices instead (like `rail_sweep`'s `split_seams`), leaving the mesh open along the cut. Authored seams such as UV cuts survive either way.

dodecahedron

dodecahedron ( radius : Numeric Float(1) ) : Mesh
Regular dodecahedron with circumradius `radius` (sits edge-up).
Arguments:
  • radius : Numeric Float(1) - Circumradius (center-to-vertex distance)

drop_attr

drop_attr ( name : String , mesh : Mesh ) : Mesh
Returns a copy of `mesh` without per-vertex attribute `name`. Errors if the mesh has no such attribute.
Arguments:
  • name : String
  • mesh : Mesh

embed_path

embed_path ( path : Sequence | Path , embed : Callable , thickness : Callable | Numeric , flipped : Bool Bool(false) , tolerance : Nil | Numeric Nil , curve_angle_degrees : Numeric Nil , normal_mode : String | Nil Nil , split_seams : Bool Bool(false) ) : Mesh
Embeds a filled 2D path into 3D through an arbitrary map φ: ℝ²→ℝ³ and thickens it into a closed 2-manifold solid. Generalizes `tessellate_path` from an affine coordinate-plane embedding to any nonlinear map, and fuses in `extrude_along_normals`-style thickening in a single pass. The region is constrained-Delaunay-triangulated (holes via subpath nesting), each vertex is mapped through `embed`, and the resulting surface is offset along its per-vertex normals and stitched into a watertight solid. A hole in the path becomes a hole drilled through the thickness of the plate. By default the cap is a single coarse triangulation, so strongly-curved embeddings facet; set `tolerance` for distortion-aware refinement that resolves the true warped shape (densifies boundary curves under `embed` and refines the interior to tolerance). The thickening direction comes from `normal_mode` (default: exact autodiff of `embed` when possible, else finite differences; "mesh" for topological normals). By default the output is a welded watertight 2-manifold, CSG-ready; pass `split_seams=true` for a render-oriented seam-split mesh with authored analytic shading normals, procedural UVs, and tangents.
Arguments:
  • path : Sequence | Path - A filled 2D region to embed and thicken. A sequence of Vec2 points, a sequence of Vec2 sequences (outer + holes via subpath nesting), or a path. Holes drilled through the plate come straight from subpath nesting, exactly like `tessellate_path`.
  • embed : Callable - The map φ used to embed the region into 3D: `|uv: vec2|: vec3`. Receives the path's native 2D coordinates (not normalized), so `|p| v3(p.x, 0, p.y)` reproduces a flat plate in the XZ plane with thickness growing +Y, matching `tessellate_path`. In general the default cap faces −(∂φ/∂u × ∂φ/∂v); `flipped` picks the other side. Make φ follow a curve, spline, helix, or analytic surface to bend the plate.
  • thickness : Callable | Numeric - How far to thicken the embedded surface into a closed solid, offset along the per-vertex embedded normal. A number for uniform thickness, or a callable for per-vertex thickness (like `extrude_along_normals`): `|pos: vec3|: num` or `|pos: vec3, uv: vec2|: num` — the 2-arg form also receives the pre-embed 2D domain coordinate, so thickness can be authored in path space without inverting `embed`.
  • flipped : Bool Bool(false) - If true, flips the cap winding, reversing which side the thickness grows toward.
  • tolerance : Nil | Numeric Nil - Distortion-aware cap refinement tolerance, in world units: the maximum allowed deviation between the faceted cap and the true embedded surface. When nil (default), the cap is a single coarse triangulation of the input path (fast, but a straight domain edge that bends under `embed` will facet into long slivers). When set to a positive number, each boundary loop is densified under `embed` so straight edges resolve into their true 3D curves, and the interior is Delaunay-refined until every triangle is within tolerance. Smaller values give a finer, more faithful surface at the cost of more triangles. When `thickness` is a callable (and `normal_mode` isn't "mesh"), refinement also tracks the offset cap `embed(uv) ∓ thickness·normal`, so a spatially-varying thickness that curves the bottom cap or walls is resolved even where `embed` itself is flat. Distinct from `curve_angle_degrees`: that controls how finely the input path's own 2D curves are sampled *before* embedding; `tolerance` controls how finely the embedded 3D surface is resolved *after*. They compose.
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing the input path's 2D curves (beziers/arcs/circles) into the boundary polyline that gets embedded. Falls back to the runtime default (settable via `set_curve_angle_threshold`, seeded by the prelude) when nil. Only affects callable/path inputs with actual curve features; a raw `Seq<Vec2>` is used as-is.
  • normal_mode : String | Nil Nil - The surface-normal *source*: always drives the thickening offset direction, and additionally the cap's authored (smooth) shading normals when `split_seams` is true. Nil (default) picks the best available: exact symbolic autodiff of `embed` when it is differentiable, otherwise finite differences. "autodiff" forces exact derivatives (errors if `embed` isn't differentiable), "finite_diff" forces central differences, and "mesh" reverts to topological face-weighted normals. The explicit modes are handy for validation and debugging. Orthogonal to `split_seams`, which controls output topology.
  • split_seams : Bool Bool(false) - When true, splits the cap/wall seam and each wall's UV wrap seam, then authors exact analytic cap shading normals, procedural UVs (caps: domain coords; walls: arc-length × thickness), and glTF tangents. Because this duplicates coincident vertices, the result is NO LONGER watertight 2-manifold (NO_WELD); intended for final render meshes, not as input to CSG/boolean ops. Default false: a welded watertight 2-manifold with no authored attributes (shading is left to the render path's auto-smooth) — the thickening direction still comes from `normal_mode`'s analytic normal.

extrude

extrude ( up : Vec3 | Callable , mesh : Mesh ) : Mesh
Extrudes a mesh in the direction of `up` by displacing each vertex along that direction. This is designed to be used with 2D meshes; using it on meshes with volume or thickness will probably not work.
Arguments:
  • up : Vec3 | Callable - Direction to extrude the mesh. Each vertex will be displaced by this amount. If a callable is provided, it should have signature `|vertex_pos: vec3|: vec3` and return the displacement for each vertex. An optional second parameter must be a destructured attribute bag, e.g. `|pos, {uv, ix}|`; see `warp`.
  • mesh : Mesh

extrude_along_normals

extrude_along_normals ( distance : Callable | Numeric , mesh : Mesh ) : Mesh
Extrudes a 2D mesh into a shell along its per-vertex normals. Normals are computed per connected component as the area-weighted average of adjacent face normals. Useful for adding thickness to a surface that follows a curve through space, e.g. a mesh draped over a curved surface via `warp`, where a single global `up` direction won't follow the surface curvature. Like `extrude`, designed for 2D (single-layer) meshes: the input is duplicated, displaced, the original is flipped to face the other way, and boundary edges are stitched into side walls to produce a closed 2-manifold shell. Fails to produce a clean shell when the offset distance exceeds the local radius of curvature on concave regions; adjacent normals converge past their starting positions and the duplicated layer self-intersects. For mild undulation this is a non-issue.
Arguments:
  • distance : Callable | Numeric - Distance to extrude each vertex along its computed normal. If a callable is provided, it should have signature `|vertex_pos: vec3|: num` and return the per-vertex distance. An optional second parameter must be a destructured attribute bag, e.g. `|pos, {uv, ix}|`; see `warp`.
  • mesh : Mesh

extrude_path

extrude_path ( path : Sequence | Path , up : Vec3 , flipped : Bool Bool(false) , curve_angle_degrees : Numeric Nil , sample_count : Nil | Numeric Nil ) : Mesh
Sweeps a path along an `up` vector to produce a triangle-strip surface mesh. Each point along the path is duplicated at `+up` to form the top edge of the strip. Multiple subpaths (from path inputs) are extruded independently; closed paths are not supported and trigger an error.
Arguments:
  • path : Sequence | Path - Either: - A path, sampled adaptively per `curve_angle_degrees` and optionally capped by `sample_count` (including lazy paths). Returned 2D points are embedded in the XZ plane (`vec2(x, y)` → `vec3(x, 0, y)`). - A `Seq<Vec2 | Vec3>` of pre-discretized points used as-is (no resampling). `Vec2` points are embedded in the XZ plane; `Vec3` points are used directly, which lets you extrude a polyline that already lives in 3D space. Errors if the sequence has fewer than 2 points or contains any other element type.
  • up : Vec3 - Direction to sweep the path along. Each point in the path is duplicated at `+up` to form the top of the strip.
  • flipped : Bool Bool(false) - If true, reverses the winding order of the generated triangles, flipping the strip's facing direction.
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves in a path input, including lazy paths.
  • sample_count : Nil | Numeric Nil - Optional cap on total points across all subpaths after adaptive materialization, including lazy paths. A cap may sacrifice the curve-angle tolerance.

extrude_pipe

Example
spiral = |count, height_factor, radius, resolution| { 0..count -> |i| { t = i * (1. / resolution) vec3( sin(t) * radius, i * height_factor, cos(t) * radius ) } } spiral(count=400, height_factor=0.1, radius=5.5, resolution=4) | extrude_pipe(radius=0.5, resolution=8, close_ends=true) | render
Example
// demo of `extrude_pipe` with a dynamic radius for each // vertex of the pipe's rings resolution = 12 get_radius = |segment_ix: int, center: vec3| { 0..resolution -> |i| { if segment_ix % 12 < 6 { if i % 2 == 0 { 2 } else { 1 } } else { 0.5 } } } 0..78 -> |i| { vec3(i * 0.15, 0, 0) } | extrude_pipe(resolution=resolution, radius=get_radius) | simplify(tolerance=0.1) | compute_uvs('unwrap', n_cones=8, name='uv') | render
extrude_pipe ( radius : Callable | Numeric , resolution : Numeric Int(8) , path : Sequence , close_ends : Bool Bool(true) , connect_ends : Bool Bool(false) , twist : Callable | Numeric Float(0) , adaptive_path_sampling : Bool Bool(false) ) : Mesh
Extrudes a pipe along a sequence of points. The radius can be constant or vary along the path using a callable.
Arguments:
  • radius : Callable | Numeric - Radius of the pipe or a callable with signature `|point_ix: int, path_point: vec3|: float | seq` that returns the radius at each point along the path. If a sequence is returned by the callback, its length must match the resolution and it should contain the distance of each point along the ring from the pipe's center.
  • resolution : Numeric Int(8) - Number of segments to use for the pipe's circular cross-section
  • path : Sequence - Sequence of Vec3 points defining the path of the pipe. Often the output of a function like `bezier3d`.
  • close_ends : Bool Bool(true) - Whether to close the ends of the pipe with triangle fans
  • connect_ends : Bool Bool(false) - Whether the pipe should be a closed loop, connecting the last point back to the first. If true, the first and last points of the path will be connected with triangles.
  • twist : Callable | Numeric Float(0) - Twist angle in radians to apply along the path, or a callable with signature `|point_ix: int, path_point: vec3|: float` that returns the twist angle at each point along the path. A value of 0 means no twist.
  • adaptive_path_sampling : Bool Bool(false) - When true (default), uses curvature-aware adaptive sampling to distribute path points. Concentrates vertices in high-curvature regions of the path, improving mesh quality at bends while using fewer vertices on straight sections. Set to false to use the input points directly without resampling. Note: automatically disabled when a dynamic twist callable is provided, as twist complicates the geometry in ways the adaptive sampler cannot account for.

faces

faces ( mesh : Mesh ) : Sequence
Returns the mesh's triangles as `[i, j, k]` sequences of vertex indices into `verts` order, CCW winding. Together with `verts` this is the raw indexed mesh; `mesh(verts, indices)` rebuilds one.
Arguments:
  • mesh : Mesh

fan_fill

Example
// create a path defining the outline of a circle circle_path = 0..100 -> |i| { t = i / 100 vec3(cos(t * pi * 2), 0, sin(t * pi * 2)) } // fill the outline into a flat mesh circle = fan_fill( circle_path, // flip the direction the triangles are facing so that // it is visible when looking from the top down flipped=true ) circle | render
fan_fill ( path : Sequence , closed : Bool Bool(true) , flipped : Bool Bool(false) , center : Vec3 | Nil Nil ) : Mesh
Builds a fan of triangles from a sequence of points, filling the area inside them. One triangle will be built for each pair of adjacent points in the path, connecting them to the center point.
Arguments:
  • path : Sequence - A sequence of Vec3 points representing the path to fill
  • closed : Bool Bool(true) - If true, the path will be treated as closed - connecting the last point to the first.
  • flipped : Bool Bool(false) - If true, the winding order of the triangles generated will be flipped - inverting the inside/outside of the generated mesh.
  • center : Vec3 | Nil Nil - If provided, the center point for the fan will be placed at this position. Otherwise, the center will be computed as the average of the points in the path.
fan_fill ( path : Path , closed : Bool | Nil Nil , flipped : Bool Bool(false) , center : Vec2 | Vec3 | Nil Nil , curve_angle_degrees : Numeric Nil , sample_count : Nil | Numeric Nil ) : Mesh
Builds a fan of triangles by discretizing a path and filling the area inside each subpath. One triangle will be built per pair of adjacent points in each subpath, connecting to that subpath's center. Output lives in the XZ plane.
Arguments:
  • path : Path - A path. Sampled in the XZ plane (`vec2(x, y)` -> `vec3(x, 0, y)`). Multi-subpath inputs are fanned independently and combined into one mesh.
  • closed : Bool | Nil Nil - Optional override for treating each subpath as closed. When nil (default), closedness is inherited from the path's topology (or inferred from `p(0) ~= p(1)` for black-box callables).
  • flipped : Bool Bool(false) - If true, the winding order of the triangles generated will be flipped - inverting the inside/outside of the generated mesh.
  • center : Vec2 | Vec3 | Nil Nil - If provided, the center point for each fan will be placed at this position. A `Vec2` is embedded in the XZ plane. Otherwise, the center is computed as the average of each subpath's discretized points.
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when adaptively discretizing curves, including lazy paths (`lerp_paths`, `catmull_rom`, `path(fn)`).
  • sample_count : Nil | Numeric Nil - Optional cap on total points across all subpaths after adaptive materialization, including lazy paths. When nil, use the curve-angle tolerance without a point cap.

flip_normals

flip_normals ( mesh : Mesh ) : Mesh
Flips the normals of a mesh, returning a new mesh with inverted normals. This actually flips the winding order of the mesh's triangles under the hood and re-computes normals based off that.
Arguments:
  • mesh : Mesh

grid

grid ( size : Vec2 | Numeric , divisions : Vec2 | Numeric Vec2(1, 1) , flipped : Bool Bool(false) ) : Mesh
Generates a flat grid mesh in the XZ plane centered at the origin with the specified size and number of subdivisions.
Arguments:
  • size : Vec2 | Numeric - Size of the grid along the X and Z axes (providing a number will set the same size for both axes). The grid is centered at the origin, so a size of `vec2(1, 1)` will produce a grid that extends from -0.5 to +0.5 along both axes.
  • divisions : Vec2 | Numeric Vec2(1, 1) - Number of subdivisions along each axis. If an integer is provided, it will be used for both axes.
  • flipped : Bool Bool(false) - If true, the winding order of the triangles will be flipped - making the front side face downwards (negative Y).

icosahedron

icosahedron ( radius : Numeric Float(1) ) : Mesh
Regular icosahedron with circumradius `radius` (sits edge-up; same as `icosphere(radius, 0)`).
Arguments:
  • radius : Numeric Float(1) - Circumradius (center-to-vertex distance)

icosphere

alias: sphere
icosphere ( radius : Numeric , resolution : Numeric ) : Mesh
Generates an icosphere mesh
Arguments:
  • radius : Numeric
  • resolution : Numeric - Number of subdivisions to apply when generating the icosphere. 0 -> 20 faces, 1 -> 80 faces, 2 -> 320 faces, ...

intersect

Example
a = cylinder(radius=6, height=20, radial_segments=20) b = icosphere(radius=10, resolution=5) // only keep the area that exists inside both the sphere // and the cylinder, kind of like cutting out the core // of an apple core = intersect(a, b) // `intersect` also has a dedicated operator. The // following is equivalent to the previous: core = a & b core | render
intersect ( a : Mesh , b : Mesh , split_seams : Bool Bool(false) ) : Mesh
Returns the boolean intersection of two meshes (`a & b`)
Arguments:
  • a : Mesh
  • b : Mesh
  • split_seams : Bool Bool(false) - When the operands carry per-vertex attributes, the cut curve is an attribute seam. By default its vertices are welded, blending both sides' values, so the output stays 2-manifold. `true` keeps each side's values on duplicate vertices instead (like `rail_sweep`'s `split_seams`), leaving the mesh open along the cut. Authored seams such as UV cuts survive either way.
intersect ( meshes : Sequence , split_seams : Bool Bool(false) ) : Mesh
Returns the boolean intersection of a sequence of meshes (`meshes[0] & meshes[1] & ...`)
Arguments:
  • meshes : Sequence - Sequence of meshes to intersect
  • split_seams : Bool Bool(false) - When the operands carry per-vertex attributes, the cut curve is an attribute seam. By default its vertices are welded, blending both sides' values, so the output stays 2-manifold. `true` keeps each side's values on duplicate vertices instead (like `rail_sweep`'s `split_seams`), leaving the mesh open along the cut. Authored seams such as UV cuts survive either way.

intersects

intersects ( a : Mesh , b : Mesh ) : Bool
Returns true if any triangle of `a` intersects one of `b`. Surfaces only: a mesh fully inside another doesn't count, and neither does contact at a single point.
Arguments:
  • a : Mesh
  • b : Mesh

intersects_ray

Example
// generate a 3D matrix of cubes filling all the space 0..10 -> |y_ix| { y = y_ix - 5 0..10 -> |x_ix| { x = x_ix - 5 0..10 -> |z_ix| { z = z_ix - 5 box(0.9) | trans(x, y, z) } } } | flatten | flatten -> |cube| { has_hit = cube | intersects_ray( ray_origin=v3(-10, -10, -5), ray_direction=vec3(1, 1, 0.5) ) if has_hit { return cube } cube | scale(0.2) | set_material('red') } | render
intersects_ray ( ray_origin : Vec3 , ray_direction : Vec3 , mesh : Mesh , max_distance : Nil | Numeric Nil ) : Bool
Casts a ray from `ray_origin` in `ray_direction` and checks if it intersects `mesh` within `max_distance` (or any distance if `max_distance` is `nil`)
Arguments:
  • ray_origin : Vec3
  • ray_direction : Vec3
  • mesh : Mesh
  • max_distance : Nil | Numeric Nil - Max distance to check for intersection (`nil` considers intersections at any distance), measured in multiples of `ray_direction` (world distance for a unit vector). If the intersection occurs at a distance greater than this, `false` will be returned.

is_manifold

is_manifold ( mesh : Mesh , two_manifold : Bool Bool(true) ) : Bool
Returns true if the mesh satisfies the manifold condition. Assumes the mesh is a single connected component; disconnected islands or parts may produce incorrect results. By default checks for 2-manifold (watertight): every edge shared by exactly two faces. Set `two_manifold=false` to check only for 1-manifold (no edge shared by more than two faces). This check is purely topological; vertex positions, normals, and winding order are not considered.
Arguments:
  • mesh : Mesh - The mesh to check
  • two_manifold : Bool Bool(true) - If true (default), checks that every edge is shared by exactly two faces (watertight/2-manifold). If false, checks only that no edge is shared by more than two faces (1-manifold).

is_self_intersecting

is_self_intersecting ( mesh : Mesh ) : Nil |Map
Checks if a mesh has any self-intersecting triangles. Returns `nil` if no self-intersections are found. If a self-intersection is found, returns a map with keys: `tri0` and `tri1` (sequences of 3 Vec3 vertices for each intersecting triangle), `point` (a Vec3 on the intersection), and `type` ("segment" or "coplanar").
Arguments:
  • mesh : Mesh - The mesh to check for self-intersections

isotropic_remesh

isotropic_remesh ( target_edge_length : Numeric , mesh : Mesh , iterations : Numeric Int(1) , protect_borders : Bool Bool(true) , protect_sharp_edges : Bool Bool(true) , sharp_angle_threshold_degrees : Numeric Float(30) ) : Mesh
Remeshes a mesh to have more uniform edge lengths, targeting the specified edge length. See the docs for the underlying CGAL function for more details: https://doc.cgal.org/latest/Polygon_mesh_processing/index.html - Section 2.1.2 Remeshing
Arguments:
  • target_edge_length : Numeric - Target edge length for the remeshed output. Edges will be split or collapsed to try to achieve this length.
  • mesh : Mesh
  • iterations : Numeric Int(1) - Number of remeshing iterations to perform. Typical values are between 1 and 5.
  • protect_borders : Bool Bool(true) - If true, edges on the border of the mesh will not be modified.
  • protect_sharp_edges : Bool Bool(true) - If true, edges with angles >= the `sharp_angle_threshold_degrees` will not be modified.
  • sharp_angle_threshold_degrees : Numeric Float(30) - Angle threshold in degrees for edges to be considered sharp. Only used if `protect_sharp_edges` is true.

join

Example
cubes: mesh = 0..10 -> |i| { box(1) | trans(0, i * 1.5, 0) | rot(0, i * 0.2, 0) } | join cubes | render
join ( meshes : Sequence ) : Mesh
Combines a sequence of meshes into one mesh containing all geometry from the inputs. This does NOT perform a boolean union; for that, use the `union` function or the `|` operator to create a union over a sequence of meshes.
Arguments:
  • meshes : Sequence
join ( separator : String , strings : Sequence ) : String
Joins a sequence of strings into a single string, inserting the `separator` between each element
Arguments:
  • separator : String - String to insert between each mesh
  • strings : Sequence - Sequence of strings to join

mesh

Example
// builds a cube mesh from scratch verts = [ v3(-1, -1, -1), v3(1, -1, -1), v3(1, 1, -1), v3(-1, 1, -1), v3(-1, -1, 1), v3(1, -1, 1), v3(1, 1, 1), v3(-1, 1, 1) ] indices = [ 0, 2, 1, 0, 3, 2, 4, 5, 6, 4, 6, 7, 0, 1, 5, 0, 5, 4, 2, 3, 7, 2, 7, 6, 0, 7, 3, 0, 4, 7, 1, 2, 6, 1, 6, 5, ] mesh(verts, indices) | render
mesh ( verts : Sequence , indices : Sequence ) : Mesh
Creates a mesh from a sequence of vertices and indices
Arguments:
  • verts : Sequence - Sequence of Vec3 vertices, pointed into by `faces`
  • indices : Sequence - A flag sequence of integer indices corresponding to triangles. Must have `length % 3 == 0`
mesh ( ) : Mesh
Creates an empty mesh with no vertices or indices. This can be useful as the initial value for `fold` or and other situations like that.

octahedron

alias: diamond
octahedron ( radius : Numeric Float(1) ) : Mesh
Regular octahedron with vertices on the ±X/±Y/±Z axes (a vertex points straight up). Alias: `diamond`.
Arguments:
  • radius : Numeric Float(1) - Circumradius (center-to-vertex distance)

origin_to_geometry

origin_to_geometry ( mesh : Mesh ) : Mesh
Moves the mesh so that its origin is at the center of its geometry (averge of all its vertices), returning a new mesh. This will actually modify the vertex positions and preserve any existing transforms.
Arguments:
  • mesh : Mesh
origin_to_geometry ( path : Path ) : Path
Moves a 2D path so that its origin is at its centroid (signed-area centroid of the filled region when any subpath is closed, arc-length centroid otherwise), returning a new path. Preserves any existing transforms.
Arguments:
  • path : Path - Path to center.

parametric_surface

Example
major_r = 2 minor_r = 0.5 parametric_surface( u_res=150, v_res=50, u_closed=true, v_closed=true, generator=|u, v| { theta = u * 2 * pi phi = v * 2 * pi r = major_r + minor_r * (1 + sin(u*pi*12) * 0.8) * cos(phi) v3(r * cos(theta), minor_r * (0.5 + sin(v*pi*4) * 0.4) * sin(phi), r * sin(theta)) }, fku_stitching=false, flip_normals=true ) | render
parametric_surface ( u_res : Numeric , v_res : Numeric , u_closed : Bool Bool(false) , v_closed : Bool Bool(false) , flip_normals : Bool Bool(false) , generator : Callable , fku_stitching : Bool Bool(true) , adaptive_u_sampling : Bool Bool(false) , adaptive_v_sampling : Bool Bool(false) , capped : Bool Bool(false) ) : Mesh
Generates a mesh from a parametric function over a 2D domain. Handles topological wrapping via the closed flags and automatically welds coincident vertices at boundary poles to maintain manifold topology. By default, normals point outward when V increases counter-clockwise (looking down +Y); use flip_normals=true to reverse.
Arguments:
  • u_res : Numeric - Number of segments along the U axis
  • v_res : Numeric - Number of segments along the V axis
  • u_closed : Bool Bool(false) - If true, connects the U-end back to U-start (creates cylindrical topology along U)
  • v_closed : Bool Bool(false) - If true, connects the V-end back to V-start (creates cylindrical topology along V)
  • flip_normals : Bool Bool(false) - If true, reverses triangle winding to flip normal direction. By default, normals follow the cross product of U and V tangents.
  • generator : Callable - A function `|u: num, v: num| -> vec3` that returns the 3D position for each (u, v) coordinate in [0, 1]
  • fku_stitching : Bool Bool(true) - When true (default), uses the Fuchs/Kedem/Uselton (FKU) dynamic programming algorithm to find optimal triangulation between adjacent rows. FKU minimizes total edge length, avoiding sharp angles and long edges when vertex positions drift between rows. When false, uses simple quad-based stitching for predictable topology and uniform wireframe appearance.
  • adaptive_u_sampling : Bool Bool(false) - When true, uses curvature-aware adaptive sampling along the U axis. Concentrates rows in high-curvature U regions of the surface. Disabled by default since parametric_surface is very general-purpose and adaptive sampling may not always be appropriate.
  • adaptive_v_sampling : Bool Bool(false) - When true, uses curvature-aware adaptive sampling along the V axis within each row. Concentrates vertices in high-curvature V regions. Works well with FKU stitching which can handle rows with non-uniform vertex distributions. Disabled by default since parametric_surface is very general-purpose and adaptive sampling may not always be appropriate.
  • capped : Bool Bool(false) - When true, triangulates the open ends of a tube-like surface (exactly one of `u_closed`/`v_closed` is true). Each end-ring is projected to its best-fit plane (via Newell's normal oriented along the axis) and triangulated with CGAL's constrained Delaunay triangulation (the same machinery rail_sweep uses), and it handles concave/non-convex ring shapes correctly. Rings that aren't co-planar are projected as a best effort. Cap winding follows `flip_normals` so the caps match the surface's facing direction. No-op when both axes are closed (torus) or neither is (sheet).

partition_faces

alias: partition_mesh
partition_faces ( predicate : Callable , mesh : Mesh , transformed : Bool Bool(false) ) : Sequence
Partitions a mesh's faces into separate sub-meshes using `predicate`, returning a sequence of meshes. Always returns at least two meshes (trailing partitions may be empty). Shared-vertex connectivity and per-vertex attributes (normals, uv, tangent) are preserved within each partition. This is NOT lazy; the partition is computed at the time this function is called.
Arguments:
  • predicate : Callable - Called once per triangle with its three vertex positions `|v0: vec3, v1: vec3, v2: vec3|` in CCW winding order and the mesh's local space. Return a bool to sort the face into output mesh 0 (false) or 1 (true), or an int to route it into the output mesh at that index (clamped to `0..=100000`).
  • mesh : Mesh
  • transformed : Bool Bool(false) - When true, the mesh's transform is applied to the vertex positions passed to `predicate` (world space). When false (default), positions are in the mesh's local space. Either way, the mesh's transform is copied to every output mesh.

point_distribute

Example
base = torus_knot_path( radius=12, tube_radius=7, p=3, q=4, point_count=400 ) | extrude_pipe( radius=2, resolution=12, connect_ends=true ) | set_material('base') base | render surface_points = base | point_distribute(count=500) -> |pos: vec3| { icosphere(radius=0.6, resolution=1) | trans(pos) } surface_points | render
point_distribute ( count : Nil | Numeric , mesh : Mesh , seed : Numeric Int(0) , cb : Callable | Nil Nil , world_space : Bool Bool(true) ) : Sequence
Distributes a specified number of points uniformly across the surface of a mesh returned as a sequence. If `cb` is Nil or not provided, a sequence of vec3 positions will be returned. If `cb` is provided, the sequence will consist of the return values from calling `cb(pos, normal)` for each sampled point. This is lazy; the points will not be generated until the sequence is consumed.
Arguments:
  • count : Nil | Numeric - The number of points to distribute across the mesh. If `nil`, returns an infinite sequence.
  • mesh : Mesh
  • seed : Numeric Int(0)
  • cb : Callable | Nil Nil - Optional callable with signature `|point: vec3, normal: vec3|: any`. If provided, this function will be called for each generated point and normal and whatever it returns will be included in the output sequence instead of the point.
  • world_space : Bool Bool(true) - If true, points and normals will be returned in world space. If false, they will be returned in the local space of the mesh.

rail_sweep

rail_sweep ( spine_resolution : Numeric , ring_resolution : Sequence | Numeric , spine : Callable | Sequence , profile : Callable | Path | Nil Nil , frame_mode : Vec3 | String String(rmf) , twist : Callable | Numeric Float(0) , closed : Bool Bool(false) , capped : Bool Bool(true) , profile_samplers : Callable | Sequence | Path | Nil Nil , dynamic_profile : Callable | Nil Nil , fku_stitching : Bool Bool(true) , spine_sampling_scheme : Callable | Sequence | Map | String | Nil Nil , adaptive_profile_sampling : Bool Bool(true) , split_seams : Bool Bool(false) , cap_uv_scale : Vec2 Vec2(1, 1) , crease_angle_threshold_deg : Nil | Numeric Nil ) : Mesh
Sweeps a profile along a spine to produce a mesh. Profile points are connected in increasing `v` order; for outward-facing normals, the profile winding should be counter-clockwise when viewed along the local tangent.
Arguments:
  • spine_resolution : Numeric - Number of samples to take along the spine
  • ring_resolution : Sequence | Numeric - Number of samples to take around each profile ring. For a multi-subpath profile (holed/disjoint), each subpath gets this full count (they are not split). Pass a sequence of ints to set a per-subpath count instead (in sampler subpath order); its length must match the number of subpaths.
  • spine : Callable | Sequence - Spine definition as a callable with signature `|u: float|: vec3` or a sequence of Vec3 points. When a sequence is provided, the default behavior is to use the points as-is (requiring `spine_resolution` to match the sequence length); pass an explicit `spine_sampling_scheme` such as "uniform" or "chebyshev" to resample the polyline.
  • profile : Callable | Path | Nil Nil - Callable with signature `|u: float, v: float, u_ix: int, v_ix: int, spine_center: vec3|: vec2` that returns the local (x, y) offset for each point in the ring. Optional when `dynamic_profile` is provided.
  • frame_mode : Vec3 | String String(rmf) - Frame mode for the sweep. Use "rmf" (default) for rotation-minimizing frames, or provide a Vec3 up direction for fixed-up framing.
  • twist : Callable | Numeric Float(0) - Twist angle in radians to apply per ring, or a callable with signature `|point_ix: int, spine_center: vec3|: float`.
  • closed : Bool Bool(false) - Whether to connect the last ring back to the first.
  • capped : Bool Bool(true) - Whether to cap the start and end rings with triangulated faces. Ignored when `closed` is true. For an open (non-closed) profile there is no closed boundary ring to cap: an explicit `capped=true` errors, while the default is silently treated as uncapped. For holed/disjoint (multi-subpath) profiles, caps are triangulated per nesting group (outer + its holes) and are only available in wasm builds.
  • profile_samplers : Callable | Sequence | Path | Nil Nil - Optional path or sequence of paths whose critical points align the profile's `v` sampling.
  • dynamic_profile : Callable | Nil Nil - Alternative to `profile` (mutually exclusive). Callable with signature `|u: float, u_ix: int|: path | { sampler: |v|: vec2, path_samplers: path | Seq<path>, sharp: bool, adaptive: bool, closed: bool }`. Returns either a path directly (critical points and subpath topology extracted automatically if it's a PathTracerCallable) or a map with a sampler plus optional keys: `path_samplers` (trace_paths for critical points), `sharp` (mark ring edges as sharp), `adaptive` (override global adaptive_profile_sampling for this ring), `closed` (for a black-box sampler, whether the profile ring wraps closed — default true; an open profile sweeps into a sheet with boundary; not valid for multi-subpaths, whose per-subpath openness comes from their own topology). Multi-subpath profiles (disjoint loops, or nested opposite-winding loops for a hollow tube) require a real path and a topology (count/closedness/winding/nesting) that stays constant along the spine. More efficient than `profile` for dynamic profiles as it's called once per ring instead of per vertex. Cannot be used together with `profile_samplers`.
  • fku_stitching : Bool Bool(true) - When true (default), uses the Fuchs/Kedem/Uselton (FKU) dynamic programming algorithm to find optimal triangulation between adjacent rings. FKU minimizes total edge length, producing better triangle quality when ring vertex counts differ or when vertices drift between rings. When false, uses simple quad-based stitching for predictable topology and uniform wireframe appearance.
  • spine_sampling_scheme : Callable | Sequence | Map | String | Nil Nil - Controls how sample points are distributed along the spine. When unset (the default), sequence spines are used as-is (requires `spine_resolution` to match the sequence length) and callable spines fall back to "uniform". String options: "passthrough"/"as_is"/"raw" - use sequence points as-is (sequence input only); "uniform" - evenly spaced samples; "chebyshev"/"cos"/"cosine" - Chebyshev node spacing (denser near endpoints); "superellipse"/"bevel" - superellipse-adapted spacing with default exponent 5; "adaptive" - curvature-aware sampling that concentrates vertices in high-curvature regions of the spine. Map options: { type: "uniform" }, { type: "chebyshev" }, { type: "superellipse", exponent: N } - superellipse-adapted spacing where higher exponent concentrates samples more at endpoints (exponent=2 is similar to chebyshev, exponent>2 is progressively sharper), { type: "adaptive" } - adaptive curvature-based sampling. Also accepts: a sequence of floats - explicit t values in [0, 1] (length must match spine_resolution); a callable `|i: int|: float` - returns t value for each sample index. The t values are used both for sampling the spine/rail and as the `u` parameter passed to the profile function.
  • adaptive_profile_sampling : Bool Bool(true) - When true (default), uses curvature-aware adaptive sampling for profile rings. Concentrates vertices in high-curvature regions of the profile curve, often achieving equivalent visual quality with significantly fewer vertices. Only applies when using `dynamic_profile`. Can be overridden per-ring by returning `{ sampler: ..., adaptive: true/false }` from the dynamic_profile callable. Set to false to use uniform sampling.
  • split_seams : Bool Bool(false) - When true, splits vertices at the profile UV seam (so textures wrap seamlessly, V: 0→1) and duplicates cap rings (so caps get planar UVs + an in-plane tangent + a sharp cap edge). Because this duplicates coincident vertices, the result is NO LONGER watertight 2-manifold; intended for final render meshes, not as input to CSG/boolean ops. Default false: shared vertices and watertight topology, at the cost of one smeared seam column and caps that inherit the body's swept UV/tangent.
  • cap_uv_scale : Vec2 Vec2(1, 1) - Extra per-axis multiplier on the planar cap UVs when `split_seams` is set. Caps are baked to match the swept walls' texel density automatically: U in world units (like the body's arc-length U) and V normalized by the cap's mean loop perimeter (like the body's per-loop [0,1] V), so the same material `uvScale` reads consistently across the seam and holed caps land between the outer/inner wall density. This multiplier layers on top for manual tweaks; default (1, 1) keeps the matched density. No effect without `split_seams` (unsplit caps inherit the body's swept UV).
  • crease_angle_threshold_deg : Nil | Numeric Nil - Experimental strength-aware profile sampling and FKU stitching. nil (default) preserves legacy critical-point handling. A number from 0 to 180 enables automatic turning-angle measurements at the existing profile guides after interpolation/transforms. Guides below this angle in degrees no longer reserve samples; endpoints and unmeasurable guides are retained. FKU's critical-pair attraction fades smoothly from zero at a flat guide to its existing full strength at 15 degrees, limited by the weaker endpoint. Use 0 to test weighting without dropping guides, or try 1 to ignore almost-flat guides. This measures profile turns, not 3D dihedrals, and does not guarantee crease connections.

reflect

reflect ( normal : Vec3 , mesh : Mesh ) : Mesh
Mirrors a mesh across the plane through the origin with the given `normal`, returning a new mesh. Vertex positions and normals are reflected and triangle winding is reversed so the result stays consistently oriented (rather than turning inside-out). Operates in the mesh's local space.
Arguments:
  • normal : Vec3 - Normal of the mirror plane (need not be normalized).
  • mesh : Mesh
reflect ( normal : Vec3 , offset : Numeric , mesh : Mesh ) : Mesh
Mirrors a mesh across the plane with the given `normal`, shifted from the origin by `offset` along that normal, returning a new mesh. Vertex positions and normals are reflected and triangle winding is reversed so the result stays consistently oriented. Operates in the mesh's local space.
Arguments:
  • normal : Vec3 - Normal of the mirror plane (need not be normalized).
  • offset : Numeric - Signed distance of the mirror plane from the origin, measured along the unit `normal`.
  • mesh : Mesh
reflect ( axis : Vec2 , path : Path ) : Path
Reflects a path across the line through the origin running along `axis`.
Arguments:
  • axis : Vec2 - Direction of the mirror line, which passes through the origin.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
reflect ( axis : Vec2 , offset : Numeric , path : Path ) : Path
Reflects a path across the line running along `axis`, shifted by `offset` along the line's normal.
Arguments:
  • axis : Vec2 - Direction of the mirror line.
  • offset : Numeric - Distance of the mirror line from the origin along the line's normal.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

reflect_x

reflect_x ( mesh : Mesh ) : Mesh
Mirrors a mesh across the `x = 0` plane (negating x), returning a new mesh with winding reversed to stay consistently oriented.
Arguments:
  • mesh : Mesh
reflect_x ( offset : Numeric , mesh : Mesh ) : Mesh
Mirrors a mesh across the plane `x = offset`, returning a new mesh with winding reversed to stay consistently oriented.
Arguments:
  • offset : Numeric - X position of the mirror plane.
  • mesh : Mesh
reflect_x ( path : Path ) : Path
Reflects a path across the x axis (negates y).
Arguments:
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
reflect_x ( offset : Numeric , path : Path ) : Path
Reflects a path across the line `y = offset`.
Arguments:
  • offset : Numeric - Mirror over the line `y = offset` instead.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

reflect_y

reflect_y ( mesh : Mesh ) : Mesh
Mirrors a mesh across the `y = 0` plane (negating y), returning a new mesh with winding reversed to stay consistently oriented.
Arguments:
  • mesh : Mesh
reflect_y ( offset : Numeric , mesh : Mesh ) : Mesh
Mirrors a mesh across the plane `y = offset`, returning a new mesh with winding reversed to stay consistently oriented.
Arguments:
  • offset : Numeric - Y position of the mirror plane.
  • mesh : Mesh
reflect_y ( path : Path ) : Path
Reflects a path across the y axis (negates x).
Arguments:
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
reflect_y ( offset : Numeric , path : Path ) : Path
Reflects a path across the line `x = offset`.
Arguments:
  • offset : Numeric - Mirror over the line `x = offset` instead.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

reflect_z

reflect_z ( mesh : Mesh ) : Mesh
Mirrors a mesh across the `z = 0` plane (negating z), returning a new mesh with winding reversed to stay consistently oriented.
Arguments:
  • mesh : Mesh
reflect_z ( offset : Numeric , mesh : Mesh ) : Mesh
Mirrors a mesh across the plane `z = offset`, returning a new mesh with winding reversed to stay consistently oriented.
Arguments:
  • offset : Numeric - Z position of the mirror plane.
  • mesh : Mesh

remesh_planar_patches

remesh_planar_patches ( mesh : Mesh , max_angle_deg : Numeric Float(5) , max_offset : Nil | Numeric Nil , least_squares : Bool Bool(false) ) : Mesh
Remeshes a mesh by identifying planar regions and simplifying them into a simpler set of triangles. This is useful for optimizing meshes produced by a variety of other built-in methods that tend to produce a lot of small triangles in flat areas. See the docs for the underlying CGAL function for more details: https://doc.cgal.org/latest/Polygon_mesh_processing/index.html - Section 2.1.2 Remeshing
Arguments:
  • mesh : Mesh
  • max_angle_deg : Numeric Float(5) - Maximum angle in degrees between face normals for faces to be considered coplanar
  • max_offset : Nil | Numeric Nil - Maximum distance from the plane for faces to be considered coplanar. This is an absolute distance in the mesh's local space. If not provided or set to `nil`, it will default to 1% of the diagonal length of the mesh's bounding box.
  • least_squares : Bool Bool(false) - When false (default), each planar region is measured against the plane of its seed face (largest faces first), so every face in a region is within `max_angle_deg`/`max_offset` of one real input face. When true, the region's plane is refit by least squares as it grows, which merges gently curved areas into fewer, larger facets that cut through the surface rather than lying on it.

rot

rot ( rotation : Vec3 , mesh : Mesh ) : Mesh
Rotates a mesh in local space using a Vec3 of Euler angles in radians (right-multiply: M = M * R). The rotation is relative to the object's current orientation.
Arguments:
  • rotation : Vec3 - Rotation defined by Euler angles in radians
  • mesh : Mesh - Mesh to rotate
rot ( x : Numeric , y : Numeric , z : Numeric , mesh : Mesh ) : Mesh
Rotates a mesh in local space using individual Euler angle components in radians (right-multiply: M = M * R).
Arguments:
  • x : Numeric - Rotation about X axis (radians)
  • y : Numeric - Rotation about Y axis (radians)
  • z : Numeric - Rotation about Z axis (radians)
  • mesh : Mesh - Mesh to rotate
rot ( rotation : Vec3 , light : Light ) : Light
Rotates a light in local space using a Vec3 of Euler angles in radians (right-multiply: M = M * R).
Arguments:
  • rotation : Vec3 - Rotation defined by Euler angles in radians
  • light : Light - Light to rotate
rot ( x : Numeric , y : Numeric , z : Numeric , light : Light ) : Light
Rotates a light in local space using individual Euler angle components in radians (right-multiply: M = M * R).
Arguments:
  • x : Numeric - Rotation about X axis (radians)
  • y : Numeric - Rotation about Y axis (radians)
  • z : Numeric - Rotation about Z axis (radians)
  • light : Light - Light to rotate
rot ( rotation : Vec3 , transform : Mat4 ) : Mat4
Composes a rotation onto a transform matrix in local space using a Vec3 of Euler angles in radians (right-multiply: M = M * R).
Arguments:
  • rotation : Vec3
  • transform : Mat4
rot ( x : Numeric , y : Numeric , z : Numeric , transform : Mat4 ) : Mat4
Composes a rotation onto a transform matrix in local space using individual Euler angle components in radians (right-multiply: M = M * R).
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • transform : Mat4
rot ( rotation : Vec3 , point : Vec3 ) : Vec3
Rotates a 3D point around the origin by a Vec3 of Euler angles in radians.
Arguments:
  • rotation : Vec3 - Euler angles in radians.
  • point : Vec3
rot ( x : Numeric , y : Numeric , z : Numeric , point : Vec3 ) : Vec3
Rotates a 3D point around the origin by individual Euler angle components in radians.
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • point : Vec3
rot ( angle : Numeric , point : Vec2 ) : Vec2
Rotates a 2D point counter-clockwise around the origin. There is only one rotation axis in 2D, so this takes a single angle in radians.
Arguments:
  • angle : Numeric - Rotation angle in radians.
  • point : Vec2
rot ( angle : Numeric , texture : Texture ) : Texture
Rotates a texture's placement transform in the UV plane (right-multiply: M = M * R; local ops act about the texture's centered origin). Counter-clockwise, matching the 2D point `rot` convention.
Arguments:
  • angle : Numeric - Rotation angle in radians.
  • texture : Texture
rot ( angle : Numeric , path : Path ) : Path
Rotates a path counter-clockwise about the origin.
Arguments:
  • angle : Numeric - Angle in radians.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

rot_around_center

alias: rot_local
rot_around_center ( rotation : Vec3 , mesh : Mesh ) : Mesh
Rotates a mesh around its current position (the translation component of its transform matrix). The object spins in place without changing its world-space position. Equivalent to: translate to origin, rotate, translate back.
Arguments:
  • rotation : Vec3 - Rotation defined by Euler angles in radians
  • mesh : Mesh - Mesh to rotate
rot_around_center ( x : Numeric , y : Numeric , z : Numeric , mesh : Mesh ) : Mesh
Rotates a mesh around its current position using individual Euler angle components in radians.
Arguments:
  • x : Numeric - Rotation about X axis (radians)
  • y : Numeric - Rotation about Y axis (radians)
  • z : Numeric - Rotation about Z axis (radians)
  • mesh : Mesh - Mesh to rotate
rot_around_center ( rotation : Vec3 , light : Light ) : Light
Rotates a light around its current position using a Vec3 of Euler angles in radians.
Arguments:
  • rotation : Vec3 - Rotation defined by Euler angles in radians
  • light : Light - Light to rotate
rot_around_center ( x : Numeric , y : Numeric , z : Numeric , light : Light ) : Light
Rotates a light around its current position using individual Euler angle components in radians.
Arguments:
  • x : Numeric - Rotation about X axis (radians)
  • y : Numeric - Rotation about Y axis (radians)
  • z : Numeric - Rotation about Z axis (radians)
  • light : Light - Light to rotate
rot_around_center ( rotation : Vec3 , transform : Mat4 ) : Mat4
Rotates a transform matrix around the position it encodes (the translation component), using a Vec3 of Euler angles in radians.
Arguments:
  • rotation : Vec3
  • transform : Mat4
rot_around_center ( x : Numeric , y : Numeric , z : Numeric , transform : Mat4 ) : Mat4
Rotates a transform matrix around the position it encodes (the translation component), using individual Euler angle components in radians.
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • transform : Mat4

rot_axis

rot_axis ( axis : Vec3 , angle : Numeric , mesh : Mesh ) : Mesh
Rotates a mesh around an arbitrary local axis by `angle` radians (right-multiply: M = M * R).
Arguments:
  • axis : Vec3 - Axis to rotate around (auto-normalized; must be non-zero).
  • angle : Numeric - Rotation angle in radians.
  • mesh : Mesh
rot_axis ( axis : Vec3 , angle : Numeric , light : Light ) : Light
Rotates a light around an arbitrary local axis by `angle` radians (right-multiply: M = M * R).
Arguments:
  • axis : Vec3 - Axis to rotate around (auto-normalized; must be non-zero).
  • angle : Numeric - Rotation angle in radians.
  • light : Light
rot_axis ( axis : Vec3 , angle : Numeric , transform : Mat4 ) : Mat4
Rotates a transform matrix around an arbitrary local axis by `angle` radians (right-multiply: M = M * R).
Arguments:
  • axis : Vec3 - Axis to rotate around (auto-normalized; must be non-zero).
  • angle : Numeric - Rotation angle in radians.
  • transform : Mat4
rot_axis ( axis : Vec3 , angle : Numeric , point : Vec3 ) : Vec3
Rotates a 3D point around an arbitrary axis through the origin by `angle` radians.
Arguments:
  • axis : Vec3 - Axis to rotate around (auto-normalized; must be non-zero).
  • angle : Numeric - Rotation angle in radians.
  • point : Vec3

rot_global

rot_global ( rotation : Vec3 , mesh : Mesh ) : Mesh
Rotates a mesh in world space around the world origin using a Vec3 of Euler angles in radians (left-multiply: M = R * M). This rotates both the object's orientation and its position around the origin.
Arguments:
  • rotation : Vec3 - Rotation defined by Euler angles in radians
  • mesh : Mesh - Mesh to rotate
rot_global ( x : Numeric , y : Numeric , z : Numeric , mesh : Mesh ) : Mesh
Rotates a mesh in world space around the world origin using individual Euler angle components in radians (left-multiply: M = R * M).
Arguments:
  • x : Numeric - Rotation about X axis (radians)
  • y : Numeric - Rotation about Y axis (radians)
  • z : Numeric - Rotation about Z axis (radians)
  • mesh : Mesh - Mesh to rotate
rot_global ( rotation : Vec3 , light : Light ) : Light
Rotates a light in world space around the world origin using a Vec3 of Euler angles in radians (left-multiply: M = R * M).
Arguments:
  • rotation : Vec3 - Rotation defined by Euler angles in radians
  • light : Light - Light to rotate
rot_global ( x : Numeric , y : Numeric , z : Numeric , light : Light ) : Light
Rotates a light in world space around the world origin using individual Euler angle components in radians (left-multiply: M = R * M).
Arguments:
  • x : Numeric - Rotation about X axis (radians)
  • y : Numeric - Rotation about Y axis (radians)
  • z : Numeric - Rotation about Z axis (radians)
  • light : Light - Light to rotate
rot_global ( rotation : Vec3 , transform : Mat4 ) : Mat4
Composes a rotation onto a transform matrix in world space around the world origin using a Vec3 of Euler angles in radians (left-multiply: M = R * M).
Arguments:
  • rotation : Vec3
  • transform : Mat4
rot_global ( x : Numeric , y : Numeric , z : Numeric , transform : Mat4 ) : Mat4
Composes a rotation onto a transform matrix in world space around the world origin using individual Euler angle components in radians (left-multiply: M = R * M).
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • transform : Mat4
rot_global ( rotation : Vec3 , point : Vec3 ) : Vec3
Rotates a 3D point around the origin by a Vec3 of Euler angles in radians. A bare point has no frame of its own, so this matches `rot`.
Arguments:
  • rotation : Vec3 - Euler angles in radians.
  • point : Vec3
rot_global ( x : Numeric , y : Numeric , z : Numeric , point : Vec3 ) : Vec3
Rotates a 3D point around the origin by individual Euler angle components in radians. A bare point has no frame of its own, so this matches `rot`.
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • point : Vec3
rot_global ( angle : Numeric , point : Vec2 ) : Vec2
Rotates a 2D point counter-clockwise around the origin. There is only one rotation axis in 2D, so this takes a single angle in radians. A bare point has no frame of its own, so this matches `rot`.
Arguments:
  • angle : Numeric - Rotation angle in radians.
  • point : Vec2
rot_global ( angle : Numeric , texture : Texture ) : Texture
Rotates a texture's placement in the UV plane about the base-UV origin (left-multiply: M = R * M). Counter-clockwise, matching the 2D point `rot` convention.
Arguments:
  • angle : Numeric - Rotation angle in radians.
  • texture : Texture

sample_voxels

Example
dim = 50 dims = v3(dim) lo = 0 hi = 50 sample_voxels( dims, |x: int, y: int, z: int| { // floor if y == lo && z % 2 == (round(x * 0.3) % 2) { return 1 } // X structure with hole in middle m = x + round(sin(y * 0.48)*3) in_center = x >= 16 && x <= 34 && z >= 16 && z <= 34 cond = !in_center && ( z - y == 1 || (hi-z) - y == 1 || z - y == 2 || (hi-z) - y == 2 || z - y == 3 || (hi-z) - y == 3 ) && !(y > 40) && x > 10 && x < 40 if cond { if m % 4 == 3 { return 2 } else { return 1 } } // central spire x = x-25 z = z-25 v = v2(x,z) r = 6 + 4 * smoothstep(30, 50, y) + sin(3.5 + y * 0.25) * 3 if abs(len(v) - r) < 0.5 { return 3 } return 0 }, ["default", "accent", "copper"], // false, // false // false ) | render
sample_voxels ( dims : Vec3 , cb : Callable , materials : Sequence | Nil Nil , cgal_remesh : Bool | Nil Nil , fill_internal_voids : Bool Bool(false) ) : Mesh |Sequence
Generates a mesh or sequence of meshes by sampling a 3D grid defined by `dims`. For each voxel in the grid, the provided callback will be called with the voxel's coordinate. If the callback returns 0, false, or nil, the voxel will be left empty. If it returns true or any non-zero integer, the voxel will be filled. Values > 1 will use material `n - 1` from the `materials` argument. A separate mesh will be generated for each unique material used. The generated meshes are guaranteed to be 2-manifold/watertight, meaning that they can be further processed by other builtins like `smooth`, `simplify`, CSG (`union`/`intersect`/etc.).
Arguments:
  • dims : Vec3 - The bounds of the voxel grid to sample
  • cb : Callable - A callable with signature `|x_ix: int, y_ix: int, z_ix: int|: bool | int | nil` that will be called for each voxel in the grid. Returning 0, false, or nil will leave the voxel empty. Returning true or any non-zero integer will fill the voxel. Values > 1 will use material `n - 1` from the `materials` argument. The maximum material index is 254.
  • materials : Sequence | Nil Nil - An optional sequence of materials to assign to filled voxels. The first material in the sequence will be used for voxels where the callback returns true or 1, the second material for voxels where the callback returns 2, and so on. If not provided or set to `nil`, all filled voxels will use the default material. The maximum number of materials is 254.
  • cgal_remesh : Bool | Nil Nil - Determines whether the generated mesh(es) will be remeshed using CGAL's `remesh_planar_patches` function. This produces better outputs with fewer faces and vertices, but takes more time to compute. If not provided or set to `nil`, this will be dynamically enabled/disabled for each output mesh depending on its vertex count.
  • fill_internal_voids : Bool Bool(false) - If true, internal voids in the generated meshes will be filled. This can help reduce face/vertex counts, but requires extra computation.

scale

scale ( x : Numeric , y : Numeric , z : Numeric , mesh : Mesh ) : Mesh
Scales a mesh in local space by separate factors along each axis (right-multiply: M = M * S).
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • mesh : Mesh
scale ( scale : Vec3 | Numeric , mesh : Mesh ) : Mesh
Scales a mesh in local space (right-multiply: M = M * S). Accepts a Vec3 for non-uniform scaling or a number for uniform scaling.
Arguments:
  • scale : Vec3 | Numeric
  • mesh : Mesh
scale ( x : Numeric , y : Numeric , z : Numeric , transform : Mat4 ) : Mat4
Composes a non-uniform scale onto a transform matrix in local space (right-multiply: M = M * S).
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • transform : Mat4
scale ( scale : Vec3 | Numeric , transform : Mat4 ) : Mat4
Composes a scale onto a transform matrix in local space (right-multiply: M = M * S). Accepts a Vec3 for non-uniform scaling or a number for uniform scaling.
Arguments:
  • scale : Vec3 | Numeric
  • transform : Mat4
scale ( scale : Vec2 | Numeric , texture : Texture ) : Texture
Scales a texture's placement transform (right-multiply: M = M * S; local ops act about the texture's centered origin). Accepts a Vec2 for non-uniform scaling or a number for uniform scaling.
Arguments:
  • scale : Vec2 | Numeric
  • texture : Texture
scale ( scale : Vec2 | Numeric , path : Path ) : Path
Scales a path about the origin. A non-uniform scale converts arcs to cubic Béziers.
Arguments:
  • scale : Vec2 | Numeric - Uniform factor, or per-axis factors as a `vec2`.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
scale ( x : Numeric , y : Numeric , path : Path ) : Path
Scales a path about the origin. A non-uniform scale converts arcs to cubic Béziers.
Arguments:
  • x : Numeric - X factor.
  • y : Numeric - Y factor.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

set_attr

set_attr ( name : String , value : Callable | Sequence , mesh : Mesh , spatial : String | Nil Nil ) : Mesh
Returns a copy of `mesh` with per-vertex attribute `name` set, replacing any existing attribute of that name. Attributes ride along through warps, transforms, seam splits, `extrude`, `join`/`+`, CSG booleans (interpolated at the cut, operand attribute sets unioned), `simplify`, and `split_by_plane`; are resampled by nearest point through re-tessellating ops (see `transfer_attrs`); are interpolated when vertices are split; can be read inside per-vertex callbacks via the attribute bag; and are exported to the GPU as vertex attributes (well-known names always, custom names via `render(attrs=)`).
Arguments:
  • name : String - Attribute name (letters, digits, underscores). Well-known names carry fixed types and export rules: `uv` (vec2), `tangent` (vec4), `color` (vec3 or vec4, linear RGB). Any other name defines a custom attribute. `pos`, `normal`, and `ix` are reserved.
  • value : Callable | Sequence - Either a callable `|pos: vec3, normal: vec3, {...attrs}|: num | vec2 | vec3 | vec4` invoked once per vertex (see `warp` for the attribute bag), or a sequence with one value per vertex in `verts` order. The value type sets the attribute's arity and must be the same for every vertex.
  • mesh : Mesh
  • spatial : String | Nil Nil - How the attribute responds to transforms baked into the mesh: `"none"` (default; colors, weights, uvs) or `"direction"` (a unit direction lying in the surface: rotated with the mesh, negated when it is mirrored, and renormalized wherever vertices are blended).

set_default_material

set_default_material ( material : String | Material ) : Nil
Sets the default material for all meshes that do not have a specific material set
Arguments:
  • material : String | Material - Can be either a `Material` value or a string specifying the name of an externally defined material

set_material

Example
box(5) | trans(5, 0, 0) // This requires a material called "red" to have been // defined in the material editor for the scene. // // This can be found in the hamburger menu next to the // home button. | set_material('red') | render icosphere(radius=3, resolution=4) | trans(-5, 0, 0) // same for this one | set_material('blue') | render
set_material ( material : String | Material , mesh : Mesh ) : Mesh
Sets the material for a mesh
Arguments:
  • material : String | Material - Can be either a `Material` value or a string specifying the name of an externally defined material
  • mesh : Mesh

set_sharp_angle_threshold

set_sharp_angle_threshold ( angle_degrees : Numeric ) : Nil
Sets the sharp angle threshold for computing auto-smooth-shaded normals (specified in degrees). If the angle between two adjacent faces is greater than this angle, the edge will be considered sharp. Must be called as a top-level statement (not inside closures or conditionals); use per-call kwargs like `compute_normals(mesh, angle)` for finer-grained control.
Arguments:
  • angle_degrees : Numeric - The angle at which edges are considered sharp, in degrees

simplify

simplify ( tolerance : Numeric Float(0.01) , mesh : Mesh , engine : String String(meshopt) ) : Mesh
Reduces mesh complexity within an error budget. Meshopt is the default; engine="manifold" selects the original implementation. Both preserve materials and vertex attributes. Output is checked for manifold topology; self-intersection freedom is not guaranteed by this check.
Arguments:
  • tolerance : Numeric Float(0.01) - Positive finite simplification tolerance in mesh-local distance units. 0.01 is a good starting point. The engines use different error estimates, so equal tolerances need not produce equal triangle counts; this is not a certified maximum surface-distance bound.
  • mesh : Mesh
  • engine : String String(meshopt) - Simplification engine: "meshopt" (default) or "manifold". Meshopt keeps original vertex positions and attributes, preserves authored and smooth source normals, and favors regular triangles. It validates manifold output and may reduce less to preserve topology. Manifold uses the existing solid-library simplifier. Use `compute_normals` afterward to deliberately recompute shading from the reduced mesh.
simplify ( mesh : Mesh , tolerance : Numeric Float(0.01) , engine : String String(meshopt) ) : Mesh
Reduces mesh complexity within an error budget. Meshopt is the default; engine="manifold" selects the original implementation. Both preserve materials and vertex attributes. Output is checked for manifold topology; self-intersection freedom is not guaranteed by this check.
Arguments:
  • mesh : Mesh
  • tolerance : Numeric Float(0.01) - Positive finite simplification tolerance in mesh-local distance units. 0.01 is a good starting point. The engines use different error estimates, so equal tolerances need not produce equal triangle counts; this is not a certified maximum surface-distance bound.
  • engine : String String(meshopt) - Simplification engine: "meshopt" (default) or "manifold". Meshopt keeps original vertex positions and attributes, preserves authored and smooth source normals, and favors regular triangles. It validates manifold output and may reduce less to preserve topology. Manifold uses the existing solid-library simplifier. Use `compute_normals` afterward to deliberately recompute shading from the reduced mesh.

smooth

smooth ( mesh : Mesh , type : String String(catmullclark) , iterations : Numeric Int(1) ) : Mesh
Smooths a mesh using the specified algorithm (defaults to catmullclark). More iterations result in a smoother mesh.
Arguments:
  • mesh : Mesh
  • type : String String(catmullclark) - Type of smoothing to perform. Supported values are "catmullclark", "loop", "doosabin", and "sqrt".
  • iterations : Numeric Int(1) - Number of smoothing iterations to perform

smooth_attr

smooth_attr ( name : String , mesh : Mesh , iterations : Numeric Int(1) , lambda : Numeric Float(0.5) , weights : String String(uniform) , pin : String | Nil Nil ) : Mesh
Returns a copy of `mesh` with attribute `name` blurred over the mesh's own connectivity: each vertex relaxes toward the weighted mean of its one-ring, repeated `iterations` times. Direction attributes stay unit length. Use it to denoise `bake_ao` output, feather weights, or spread any painted attribute across the surface.
Arguments:
  • name : String - Attribute to smooth.
  • mesh : Mesh
  • iterations : Numeric Int(1) - Relaxation passes.
  • lambda : Numeric Float(0.5) - How far each vertex moves toward its neighbours' mean per pass, 0..1.
  • weights : String String(uniform) - `"uniform"` weights every neighbour equally; `"cotan"` uses cotangent (geometry-aware) weights that don't bias toward densely tessellated regions.
  • pin : String | Nil Nil - Name of a scalar attribute; vertices where it is nonzero keep their value (feathering toward painted regions).

split_by_plane

Example
shape = box(10, 5, 10) | union(cyl(radius=4, height=8, radial_segments=40)) pieces: seq = shape | split_by_plane( plane_normal=vec3(1, -1, 1), plane_offset=0 ) pieces = pieces -> |piece: mesh, i: int| { if i == 0 { piece | set_material('red') } else { piece | set_material('blue') | trans(0, 1, 0) } } render(pieces)
split_by_plane ( plane_normal : Vec3 , plane_offset : Numeric , mesh : Mesh ) : Sequence
Splits a mesh by a plane, returning a sequence containing two meshes: the part in front of the plane and the part behind the plane. This will apply all transforms on the mesh, and the returned meshes will have an identity transform.
Arguments:
  • plane_normal : Vec3 - Normal vector of the plane to cut the mesh with
  • plane_offset : Numeric - Offset of the plane from the origin along the plane normal
  • mesh : Mesh

stanford_bunny

alias: bunny
Example
stanford_bunny() | render
stanford_bunny ( ) : Mesh
Generates a Stanford bunny mesh, a well-known 3D model often used in computer graphics as a test object. This mesh IS manifold, so it can be used with functions that require a manifold mesh such as mesh boolean ops, `trace_geodesic_path`, and others.

stitch_contours

Example
example for the `stitch_contours` function
height_segments = 40 resolution = 100 radius = 5 // creates a sequence of contours which encode the profile // of the shape we're building from bottom to top contours = 0..height_segments -> |y_ix| { 0..resolution -> |i| { t = i / resolution // bulge the radius out, but at a different spot // depending on how far up the shape we are radius = radius + sin(y_ix * 0.5 + t * pi * 4) * 4 // construct a path tracing the radius of the shape // at this height, basing it off the parametric // equation for a circle vec3( cos(t * pi * 2) * radius, y_ix * 2.25, sin(t * pi * 2) * radius ) } } // join the contours into a closed 3D mesh by connecting // them with a strip of triangles between each one. contours // default options shown | stitch_contours(closed=true, cap_ends=true) | render
stitch_contours ( contours : Sequence , flipped : Bool Bool(false) , closed : Bool Bool(true) , cap_start : Bool Bool(false) , cap_end : Bool Bool(false) , cap_ends : Bool Bool(false) ) : Mesh
Stitches together a sequence of contours into a single mesh. The contours should be closed loops.
Arguments:
  • contours : Sequence - A `Seq<Seq<Vec3>>`, where each inner sequence contains points representing a contour that will be stitched together into a mesh
  • flipped : Bool Bool(false) - If true, the winding order of the triangles generated will be flipped - inverting the inside/outside of the generated mesh.
  • closed : Bool Bool(true) - If true, the contours will be stitched together as closed loops - connecting the last point to the first for each one.
  • cap_start : Bool Bool(false) - If true, a triangle fan will be created to cap the first contour
  • cap_end : Bool Bool(false) - If true, a triangle fan will be created to cap the last contour
  • cap_ends : Bool Bool(false) - shorthand for `cap_start=true, cap_end=true`

subdivide_by_line

alias: skewer
subdivide_by_line ( line_origin : Vec3 , line_dir : Vec3 , mesh : Mesh , eps : Numeric Float(0.0001) ) : Mesh
Skewers a mesh with an infinite line. Triangles whose interiors are intersected by the line are split into three fan triangles around the hit point. Hits coincident with an edge split the edge (and both adjacent triangles). Hits coincident with a vertex are no-ops. Aliased as `skewer`.
Arguments:
  • line_origin : Vec3 - A point on the line that skewers the mesh
  • line_dir : Vec3 - Direction of the line. Need not be unit-length; it will be normalized internally.
  • mesh : Mesh
  • eps : Numeric Float(0.0001) - World-space tolerance for snapping the hit point to a nearby vertex or edge. Larger values make the skewer more forgiving of near-coincident geometry; smaller values snap less aggressively.

subdivide_by_plane

subdivide_by_plane ( plane_normal : Vec3 , plane_offset : Numeric , mesh : Mesh ) : Mesh
Subdivides a mesh by a plane, splitting all edges and faces that intersect the plane.
Arguments:
  • plane_normal : Vec3 - Normal vector of the plane to cut the mesh with
  • plane_offset : Numeric - Offset of the plane from the origin along the plane normal
  • mesh : Mesh
subdivide_by_plane ( plane_normals : Sequence , plane_offsets : Sequence , mesh : Mesh ) : Mesh
Subdivides a mesh by a sequence of planes, splitting all edges and faces that intersect any of the planes. This is more efficient than repeatedly subdividing by a single plane multiple times.
Arguments:
  • plane_normals : Sequence - Sequence of normal vectors of the planes to cut the mesh with
  • plane_offsets : Sequence - Sequence of offsets of the planes from the origin along the plane normals
  • mesh : Mesh

tessellate

aliases: subdivide, tess
tessellate ( target_edge_length : Numeric , mesh : Mesh ) : Mesh
Tessellates a mesh, splitting edges to achieve a target edge length.
Arguments:
  • target_edge_length : Numeric
  • mesh : Mesh

tessellate_path

tessellate_path ( path : Sequence | Path , flipped : Bool Bool(false) , curve_angle_degrees : Numeric Nil , sample_count : Nil | Numeric Nil , fill_rule : String | Nil Nil , engine : String | Nil Nil , max_edge_len : Nil | Numeric Nil , min_angle_degrees : Nil | Numeric Nil , plane : String | Nil Nil ) : Mesh
Tessellates a 2D path into a triangle mesh, by default in the XZ plane (override with `plane`). Path topology (subpaths and the holes they imply via nesting) is preserved by both backends. Build paths-with-holes by either using a multi-subpath path (e.g. `path([rect(...), rect(...) | reverse])`) or applying a Clipper2 boolean op upstream. CGAL refinement runs when either `max_edge_len` or `min_angle_degrees` is supplied; otherwise the raw constrained Delaunay triangulation is returned. Each constraint independently triggers splitting of triangles that violate it; a triangle is split if it has either an edge longer than `max_edge_len` OR an angle smaller than `min_angle_degrees`.
Arguments:
  • path : Sequence | Path - A sequence of Vec2 points, a sequence of Vec2 sequences, or a path.
  • flipped : Bool Bool(false) - If true, the winding order of the generated triangles will be flipped.
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing trace_path curves.
  • sample_count : Nil | Numeric Nil - Maximum total number of output points across all subpaths. When provided, adaptively resamples the path to this count using curvature+arc-length weighting while preserving critical corners. When nil (default), uses the path's natural tessellation resolution.
  • fill_rule : String | Nil Nil - Fill rule used to identify the interior of the shape: "nonzero", "evenodd", "positive", or "negative". If nil, inherited from the path (e.g. set via `trace_path`) and otherwise defaulting to "nonzero". The CGAL engine always uses nesting-based fill (equivalent to "evenodd"); requesting any winding-dependent rule ("nonzero"/"positive"/"negative") with multiple subpaths under CGAL is a runtime error. The lyon engine honors all four rules per its tessellator semantics.
  • engine : String | Nil Nil - Tessellation engine: "cgal" or "lyon". If nil (default), the engine is chosen automatically. - CGAL is preferred: cleaner topology (no T-junctions), supports holes via nesting (any number of subpaths), supports mesh refinement via `max_edge_len`. - lyon is chosen when a winding-dependent fill rule ("nonzero"/"positive"/"negative") is requested with multiple subpaths, since CGAL only implements nesting-based fill. Forcing engine="cgal" in a case lyon would be auto-selected is a runtime error.
  • max_edge_len : Nil | Numeric Nil - Upper bound on the length of any triangle edge after refinement. Triangles with a longer edge are split. When set together with `min_angle_degrees` or used with the default angle bound, drives the density of the refined mesh. CGAL-only; setting this with engine="lyon" is a runtime error.
  • min_angle_degrees : Nil | Numeric Nil - Lower bound (in degrees) on the smallest angle in any triangle after refinement. Triangles with a smaller angle are split. Range: [0, ~20.7]; 0 disables the shape criterion entirely (refinement then driven purely by `max_edge_len`). The upper limit comes from CGAL: Delaunay refinement only provably terminates for aspect bounds up to 0.125 (squared sine), i.e. min angle ≲ 20.7°. When this kwarg is omitted but `max_edge_len` is set, CGAL's default ~20.6° applies. Narrow regions (e.g. slivers between holes) can then split well below `max_edge_len`. Pass 0 if you want only the edge-length constraint.
  • plane : String | Nil Nil - Coordinate plane the mesh is triangulated into, as a two-axis swizzle mapping the 2D (u, v) point to two of x/y/z (the remaining axis is 0). Order matters: "xz" (default) maps u→x, v→z; "zx" maps u→z, v→x (a mirror embedding). Any two distinct axes are accepted ("xy", "yx", "xz", "zx", "yz", "zy"). The default front face points along the +remaining axis (+Y for "xz"); use `flipped` to reverse it.

tetrahedron

tetrahedron ( radius : Numeric Float(1) ) : Mesh
Regular tetrahedron with circumradius `radius`, inscribed in the cube (sits edge-up).
Arguments:
  • radius : Numeric Float(1) - Circumradius (center-to-vertex distance)

text_to_mesh

Example
text = text_to_mesh( "Vanadium", font_weight=700, depth=200, font_family="IBM Plex Sans", height=7.5 ) | rot(pi/2, 0, 0) | trans(-21, 1.5, -100); (bunny() | scale(4)) - text | render
text_to_mesh ( text : String , font_family : String String(IBM Plex Sans) , font_size : Numeric Float(24) , font_weight : String | Nil | Numeric Nil , font_style : String | Nil Nil , letter_spacing : Nil | Numeric Nil , width : Nil | Numeric Nil , height : Nil | Numeric Nil , depth : Nil | Numeric Float(0.2) ) : Mesh
Generates a 2D path representing the given text string, triangulates it into a mesh, and optionally extrudes it into 3D. The generated mesh lies in the XZ plane, with Y being the up direction.
Arguments:
  • text : String
  • font_family : String String(IBM Plex Sans) - Font family to use for the text. Must exist on Google Fonts.
  • font_size : Numeric Float(24)
  • font_weight : String | Nil | Numeric Nil
  • font_style : String | Nil Nil - Must be one of "normal", "italic", or "oblique". If nil, defaults to "normal".
  • letter_spacing : Nil | Numeric Nil
  • width : Nil | Numeric Nil - Width of the generated mesh in world units along the X axis. If only one of `width` or `height` is provided, the other dimension will be scaled to maintain the aspect ratio of the text.
  • height : Nil | Numeric Nil - Height of the generated mesh in world units along the Z axis. If only one of `width` or `height` is provided, the other dimension will be scaled to maintain the aspect ratio of the text.
  • depth : Nil | Numeric Float(0.2) - Depth to extrude the text into a 3D mesh. If 0 or nil, will produce a flat 2D mesh in the XZ plane.

trace_geodesic_path

Example
c = cyl(radius=6, height=20, radial_segments=40) // sequence of steps deltas to talk along the surface of // the mesh path = 0..20 -> || v2(3, 1); surface_points: seq = trace_geodesic_path( path, c, full_path=false, start_pos_local_space=v3(10, -8, 0) ) // cut out a cube from the surface of the mesh at each // step of the walk fold( c, |c: mesh, pt: vec3| c - (box(2) + pt), surface_points ) | compute_uvs('unwrap', n_cones=10, name='uv') | render // adds a red directional light to better show off the // carved out sections dir_light(intensity=12, color=v3(1,0.3,0.1)) | trans(40, 20, -10) | render
trace_geodesic_path ( path : Sequence , mesh : Mesh , world_space : Bool Bool(true) , full_path : Bool Bool(true) , start_pos_local_space : Vec3 | Nil Nil , up_dir_world_space : Vec3 Vec3(0, 1, 0) ) : Sequence
Traces a geodesic path across the surface of a mesh, following a sequence of 2D points. The mesh must be manifold. Returns a `Seq<Vec3>` of points on the surface of the mesh that were visited during the walk.
Arguments:
  • path : Sequence - A sequence of `Vec2` points representing movements to take across the surface of the mesh relative to the current position. For example, a sequence of `[vec2(0, 1), vec2(1, 0)]` would move 1 unit up and then 1 unit right.
  • mesh : Mesh
  • world_space : Bool Bool(true) - If true, points will be returned in world space. If false, they will be returned in the local space of the mesh.
  • full_path : Bool Bool(true) - This controls behavior when the path crosses between faces in the mesh. If true, intermediate points will be included in the output for whenever the path hits an edge. This can result in the output sequence having more elements than the input sequence, and it will ensure that all generated edges in the output path lie on the surface of the mesh.
  • start_pos_local_space : Vec3 | Nil Nil - If provided, the starting position for the path will be snapped to the surface of the mesh at this position. If `nil`, the walk will start at an arbitrary point on the mesh surface.
  • up_dir_world_space : Vec3 Vec3(0, 1, 0) - When the walk starts, it will be oriented such that the positive Y axis of the local tangent space is aligned as closely as possible with this up direction at the starting position. Another way of saying this is that it lets you set what direction is north when first starting the walk on the mesh's surface.

transfer_attrs

transfer_attrs ( src : Mesh , mesh : Mesh ) : Mesh
Returns a copy of `mesh` carrying every per-vertex attribute of `src`, sampled by nearest point: each vertex takes the barycentric blend of the closest `src` triangle (in world space). Exact wherever `mesh` lies on `src`'s surface, e.g. after remeshing; also the way to paint attributes on a low-poly proxy and carry them onto detailed geometry. Attribute seams (UV cuts) can't survive re-tessellation, so recompute UVs rather than transferring them. `smooth`, `isotropic_remesh`, `delaunay_remesh`, `remesh_planar_patches`, `alpha_wrap`, and `convex_hull` apply this automatically.
Arguments:
  • src : Mesh - Mesh whose per-vertex attributes are sampled.
  • mesh : Mesh

translate

alias: trans
Example
box(1) | render box(1) | translate(0, 2, 0) | render // you can also use a shorthand for translating meshes box(1) + vec3(2, 0, 0) | render
translate ( translation : Vec3 , mesh : Mesh ) : Mesh
Translates a mesh in local space (right-multiply: M = M * T). The translation is relative to the object's current orientation. Alias: `trans`.
Arguments:
  • translation : Vec3
  • mesh : Mesh
translate ( x : Numeric , y : Numeric , z : Numeric , mesh : Mesh ) : Mesh
Translates a mesh in local space (right-multiply: M = M * T). Alias: `trans`.
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • mesh : Mesh
translate ( translation : Vec3 , light : Light ) : Light
Translates a light in local space (right-multiply: M = M * T). The translation is relative to the light's current orientation. Alias: `trans`.
Arguments:
  • translation : Vec3
  • light : Light
translate ( x : Numeric , y : Numeric , z : Numeric , light : Light ) : Light
Translates a light in local space (right-multiply: M = M * T). Alias: `trans`.
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • light : Light
translate ( translation : Vec3 , transform : Mat4 ) : Mat4
Composes a translation onto a transform matrix in local space (right-multiply: M = M * T). Alias: `trans`.
Arguments:
  • translation : Vec3
  • transform : Mat4
translate ( x : Numeric , y : Numeric , z : Numeric , transform : Mat4 ) : Mat4
Composes a translation onto a transform matrix in local space (right-multiply: M = M * T). Alias: `trans`.
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • transform : Mat4
translate ( offset : Vec2 , texture : Texture ) : Texture
Translates a texture's placement transform in base-UV units (right-multiply: M = M * T). Alias: `trans`.
Arguments:
  • offset : Vec2
  • texture : Texture
translate ( x : Numeric , y : Numeric , texture : Texture ) : Texture
Translates a texture's placement transform in base-UV units (right-multiply: M = M * T). Alias: `trans`.
Arguments:
  • x : Numeric
  • y : Numeric
  • texture : Texture
translate ( offset : Vec2 , path : Path ) : Path
Translates a path.
Arguments:
  • offset : Vec2 - Translation.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
translate ( x : Numeric , y : Numeric , path : Path ) : Path
Translates a path.
Arguments:
  • x : Numeric - X translation.
  • y : Numeric - Y translation.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

translate_global

alias: trans_global
translate_global ( translation : Vec3 , mesh : Mesh ) : Mesh
Translates a mesh in world space (left-multiply: M = T * M). The translation is always along world axes regardless of the object's current orientation. Alias: `trans_global`.
Arguments:
  • translation : Vec3
  • mesh : Mesh
translate_global ( x : Numeric , y : Numeric , z : Numeric , mesh : Mesh ) : Mesh
Translates a mesh in world space (left-multiply: M = T * M). Alias: `trans_global`.
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • mesh : Mesh
translate_global ( translation : Vec3 , light : Light ) : Light
Translates a light in world space (left-multiply: M = T * M). The translation is always along world axes regardless of the light's current orientation. Alias: `trans_global`.
Arguments:
  • translation : Vec3
  • light : Light
translate_global ( x : Numeric , y : Numeric , z : Numeric , light : Light ) : Light
Translates a light in world space (left-multiply: M = T * M). Alias: `trans_global`.
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • light : Light
translate_global ( translation : Vec3 , transform : Mat4 ) : Mat4
Composes a translation onto a transform matrix in world space (left-multiply: M = T * M). Alias: `trans_global`.
Arguments:
  • translation : Vec3
  • transform : Mat4
translate_global ( x : Numeric , y : Numeric , z : Numeric , transform : Mat4 ) : Mat4
Composes a translation onto a transform matrix in world space (left-multiply: M = T * M). Alias: `trans_global`.
Arguments:
  • x : Numeric
  • y : Numeric
  • z : Numeric
  • transform : Mat4
translate_global ( offset : Vec2 , texture : Texture ) : Texture
Translates a texture's placement in base-UV units, unaffected by its current rotation/scale (left-multiply: M = T * M). The idiomatic final placement op: `stamp | scale(s) | rot(a) | trans_global(pos)`. Alias: `trans_global`.
Arguments:
  • offset : Vec2
  • texture : Texture
translate_global ( x : Numeric , y : Numeric , texture : Texture ) : Texture
Translates a texture's placement in base-UV units, unaffected by its current rotation/scale (left-multiply: M = T * M). Alias: `trans_global`.
Arguments:
  • x : Numeric
  • y : Numeric
  • texture : Texture

union

union ( a : Mesh , b : Mesh , split_seams : Bool Bool(false) ) : Mesh
Returns the boolean union of two meshes (`a | b`)
Arguments:
  • a : Mesh
  • b : Mesh
  • split_seams : Bool Bool(false) - When the operands carry per-vertex attributes, the cut curve is an attribute seam. By default its vertices are welded, blending both sides' values, so the output stays 2-manifold. `true` keeps each side's values on duplicate vertices instead (like `rail_sweep`'s `split_seams`), leaving the mesh open along the cut. Authored seams such as UV cuts survive either way.
union ( meshes : Sequence , split_seams : Bool Bool(false) ) : Mesh
Returns the boolean union of a sequence of meshes (`meshes[0] | meshes[1] | ...`)
Arguments:
  • meshes : Sequence - Sequence of meshes to union
  • split_seams : Bool Bool(false) - When the operands carry per-vertex attributes, the cut curve is an attribute seam. By default its vertices are welded, blending both sides' values, so the output stays 2-manifold. `true` keeps each side's values on duplicate vertices instead (like `rail_sweep`'s `split_seams`), leaving the mesh open along the cut. Authored seams such as UV cuts survive either way.

utah_teapot

alias: teapot
Example
utah_teapot() | render
utah_teapot ( ) : Mesh
Generates a Utah teapot mesh, a well-known 3D model often used in computer graphics as a test object. Note that the teapot is NOT manifold, so it cannot be used with functions that require a manifold mesh such as mesh boolean ops, `trace_geodesic_path`, and others.

verts

verts ( mesh : Mesh , world_space : Bool Bool(false) ) : Sequence
Returns a sequence of all vertices in a mesh in an arbitrary order
Arguments:
  • mesh : Mesh
  • world_space : Bool Bool(false) - If true, the vertices will be returned in world space coordinates. If false, they will be returned in the local space of the mesh.

warp

Example
icosphere(radius=8, resolution=4) // the position of each vertex in the mesh is set to // whatever this function returns. | warp(|pos: vec3, normal: vec3| { if pos.y >= 0 { return pos } // elongate and distort the bottom half of the sphere vec3( pos.x + sin(pos.y) * 1.5, pos.y * 2, pos.z + sin(pos.y) * 1.5 ) }) | render // warp also has a dedicated shorthand operator. The // following two statements are equivalent: box(4) | warp(|pos| pos * 2) box(4) -> |pos| pos * 2
warp ( fn : Callable , mesh : Mesh ) : Mesh
Applies a warp function to each vertex of the mesh, returning a new mesh with each vertex transformed by `fn`.
Arguments:
  • fn : Callable - Callable with signature `|pos: vec3, normal: vec3|: vec3`. Given the position and normal of each vertex in the mesh, returns a new position for that vertex in the output mesh. An optional trailing parameter must be a destructured attribute bag naming the per-vertex data to read, e.g. `|pos, normal, {uv, color, ix}|`: any attribute on the mesh (see `set_attr`), plus `ix` (vertex index in `verts` order), `pos`, and `normal`. Only the named keys are read, so omitting the bag costs nothing.
  • mesh : Mesh

path

alpha_wrap_2d

alpha_wrap_2d ( path : Path , alpha : Numeric Float(0.033333335) , offset : Numeric Float(0.03) , manifold : Bool Bool(true) , seeds : Sequence | Nil Nil , curve_angle_degrees : Numeric Nil , sample_count : Numeric Int(128) ) : Path
Computes a 2D alpha-wrap of a path: a simple, hole-aware outline that strictly encloses every segment of the input, roughly `offset` away from it, with concavities narrower than `alpha` filled in. Think of it as a concave hull of the strokes and filled regions of the path. Overlapping or self-intersecting subpaths and open strokes are all fine as input. The output is a polyline path (no continuous curve detail) with holes represented as nested subpaths under even-odd filling. For more details, see here: https://doc.cgal.org/latest/Alpha_wrap_2/index.html
Arguments:
  • path : Path - A path. Every subpath is discretized into line segments; closed subpaths are sealed, open ones are treated as strokes.
  • alpha : Numeric Float(0.033333335) - Controls the feature size of the computed wrapping: the wrap can only enter gaps and concavities wider than about `alpha`. Smaller values follow the input more closely and produce more vertices. This value is relative to the bounding box of the input. Values should be in the range (0, 1).
  • offset : Numeric Float(0.03) - Distance between the input and the output boundary. Larger values give simpler, rounder outlines at the cost of sharp corners and fine detail. This value is relative to the bounding box of the input. Values should be in the range (0, 1).
  • manifold : Bool Bool(true) - Post-processes the wrap so its boundary is geometrically 1-manifold as well as combinatorially (no separate loops touching at a vertex). Disable for a slightly faster wrap that may contain such pinches.
  • seeds : Sequence | Nil Nil - Optional sequence of Vec2 points from which the wrap starts instead of from the outside. Each seed must sit inside an enclosed region of the input with room for a disk of radius `alpha` around it; the result is then the wrap of that enclosed space (an inset of the region's boundary) rather than of the outside.
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves.
  • sample_count : Numeric Int(128) - Initial uniform probe count for lazy paths. Critical points and structural boundaries are also sampled, then refined adaptively per curve_angle_degrees; this is not an output cap.
alpha_wrap_2d ( points : Sequence , alpha : Numeric Float(0.033333335) , offset : Numeric Float(0.03) , manifold : Bool Bool(true) , seeds : Sequence | Nil Nil ) : Path
Computes a 2D alpha-wrap of a set of points: a simple, hole-aware outline enclosing all of them, roughly `offset` away from the outermost points, with gaps narrower than `alpha` closed over. Useful for blob-like silhouettes around scattered points. The output is a polyline path with holes represented as nested subpaths under even-odd filling. For more details, see here: https://doc.cgal.org/latest/Alpha_wrap_2/index.html
Arguments:
  • points : Sequence - A sequence of Vec2 points
  • alpha : Numeric Float(0.033333335) - Controls the feature size of the computed wrapping: the wrap can only enter gaps between points wider than about `alpha`, so larger values merge nearby points into one blob. Smaller values produce tighter outlines around each cluster. This value is relative to the bounding box of the input points. Values should be in the range (0, 1).
  • offset : Numeric Float(0.03) - Distance between the input points and the output boundary. Larger values give simpler, rounder outlines. This value is relative to the bounding box of the input points. Values should be in the range (0, 1).
  • manifold : Bool Bool(true) - Post-processes the wrap so its boundary is geometrically 1-manifold as well as combinatorially (no separate loops touching at a vertex). Disable for a slightly faster wrap that may contain such pinches.
  • seeds : Sequence | Nil Nil - Optional sequence of Vec2 points from which the wrap starts instead of from the outside. Each seed must sit inside an enclosed region of the input with room for a disk of radius `alpha` around it; the result is then the wrap of that enclosed space rather than of the outside.

arc

arc ( rx : Numeric , ry : Numeric , x_axis_rotation : Numeric , large_arc : Bool , sweep : Bool , to : Vec2 , path : Path ) : Path
Pen op: elliptical arc from the current point to the end point with radii `rx`, `ry` and x-axis rotation `x_axis_rotation` (degrees), following SVG's arc parameterization. `large_arc` picks the longer of the two candidate arcs; `sweep` picks the counter-clockwise one. The short forms use `large_arc=false, sweep=true`.
Arguments:
  • rx : Numeric - X radius.
  • ry : Numeric - Y radius.
  • x_axis_rotation : Numeric - Rotation of the ellipse's x axis in degrees.
  • large_arc : Bool - Take the larger of the two arcs.
  • sweep : Bool - Sweep counter-clockwise.
  • to : Vec2 - End point.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
arc ( rx : Numeric , ry : Numeric , x_axis_rotation : Numeric , large_arc : Bool , sweep : Bool , x : Numeric , y : Numeric , path : Path ) : Path
Pen op: elliptical arc from the current point to the end point with radii `rx`, `ry` and x-axis rotation `x_axis_rotation` (degrees), following SVG's arc parameterization. `large_arc` picks the longer of the two candidate arcs; `sweep` picks the counter-clockwise one. The short forms use `large_arc=false, sweep=true`.
Arguments:
  • rx : Numeric - X radius.
  • ry : Numeric - Y radius.
  • x_axis_rotation : Numeric - Rotation of the ellipse's x axis in degrees.
  • large_arc : Bool - Take the larger of the two arcs.
  • sweep : Bool - Sweep counter-clockwise.
  • x : Numeric - End x.
  • y : Numeric - End y.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
arc ( rx : Numeric , ry : Numeric , x_axis_rotation : Numeric , to : Vec2 , path : Path ) : Path
Pen op: elliptical arc from the current point to the end point with radii `rx`, `ry` and x-axis rotation `x_axis_rotation` (degrees), following SVG's arc parameterization. `large_arc` picks the longer of the two candidate arcs; `sweep` picks the counter-clockwise one. The short forms use `large_arc=false, sweep=true`.
Arguments:
  • rx : Numeric - X radius.
  • ry : Numeric - Y radius.
  • x_axis_rotation : Numeric - Rotation of the ellipse's x axis in degrees.
  • to : Vec2 - End point.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
arc ( rx : Numeric , ry : Numeric , x_axis_rotation : Numeric , x : Numeric , y : Numeric , path : Path ) : Path
Pen op: elliptical arc from the current point to the end point with radii `rx`, `ry` and x-axis rotation `x_axis_rotation` (degrees), following SVG's arc parameterization. `large_arc` picks the longer of the two candidate arcs; `sweep` picks the counter-clockwise one. The short forms use `large_arc=false, sweep=true`.
Arguments:
  • rx : Numeric - X radius.
  • ry : Numeric - Y radius.
  • x_axis_rotation : Numeric - Rotation of the ellipse's x axis in degrees.
  • x : Numeric - End x.
  • y : Numeric - End y.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

bezier3d

alias: bezier
bezier3d ( p0 : Vec3 , p1 : Vec3 , p2 : Vec3 , p3 : Vec3 , count : Numeric ) : Sequence
Generates a sequence of `count` evenly-spaced points along a cubic Bezier curve defined by four control points
Arguments:
  • p0 : Vec3
  • p1 : Vec3
  • p2 : Vec3
  • p3 : Vec3
  • count : Numeric

catmull_rom

catmull_rom ( points : Sequence , tension : Numeric Float(0.5) , closed : Bool Bool(false) ) : Path
Returns a path `|t: float|: vec2` that evaluates a Catmull-Rom spline through the given 2D control points. The spline passes through every control point. All interior joints are C1 smooth; only the endpoints of an open spline are non-smooth. `tension` generalises to the full cardinal spline family (`0.5` = standard Catmull-Rom).
Arguments:
  • points : Sequence - Sequence of `vec2` control points the spline passes through.
  • tension : Numeric Float(0.5) - Tangent scale factor. `0.5` (default) gives standard Catmull-Rom. Higher values produce more pronounced curves; `0.0` produces a linear interpolation between points.
  • closed : Bool Bool(false) - If true, the spline wraps from the last control point back to the first, forming a closed loop.

catmull_rom_3d

catmull_rom_3d ( points : Sequence , tension : Numeric Float(0.5) , closed : Bool Bool(false) ) : Callable
Returns a callable `|t: float|: vec3` that evaluates a Catmull-Rom spline through the given 3D control points. The spline passes through every control point. All interior joints are C1 smooth; only the endpoints of an open spline are non-smooth. `tension` generalises to the full cardinal spline family (`0.5` = standard Catmull-Rom).
Arguments:
  • points : Sequence - Sequence of `vec3` control points the spline passes through.
  • tension : Numeric Float(0.5) - Tangent scale factor. `0.5` (default) gives standard Catmull-Rom. Higher values produce more pronounced curves; `0.0` produces a linear interpolation between points.
  • closed : Bool Bool(false) - If true, the spline wraps from the last control point back to the first, forming a closed loop.

circle

circle ( center : Vec2 , radius : Numeric ) : Path
Closed circular path built from two arcs, starting at the rightmost point and running counter-clockwise.
Arguments:
  • center : Vec2 - Center of the circle.
  • radius : Numeric - Radius of the circle.
circle ( cx : Numeric , cy : Numeric , radius : Numeric ) : Path
Closed circular path built from two arcs, starting at the rightmost point and running counter-clockwise.
Arguments:
  • cx : Numeric - Center x.
  • cy : Numeric - Center y.
  • radius : Numeric - Radius of the circle.

close

close ( path : Path ) : Path
Pen op: closes the open last subpath with a straight segment back to its start. No-op when the last subpath is already closed or empty.
Arguments:
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

close_all

close_all ( path : Path ) : Path
Closes every open subpath of the path.
Arguments:
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

critical_points

critical_points ( path : Path ) : Sequence
Returns the critical t values of a path as a sequence of floats. Critical points are parameter values where sharp features (corners, segment boundaries) occur. Only works with paths that have topology information.
Arguments:
  • path : Path - A path (e.g. from trace_path, offset_path, lerp_paths).

cubic_bezier

alias: cubic
cubic_bezier ( ctrl1 : Vec2 , ctrl2 : Vec2 , to : Vec2 , path : Path ) : Path
Pen op: cubic Bézier from the current point with control points `ctrl1` and `ctrl2` to `to`.
Arguments:
  • ctrl1 : Vec2 - First control point.
  • ctrl2 : Vec2 - Second control point.
  • to : Vec2 - End point.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
cubic_bezier ( c1x : Numeric , c1y : Numeric , c2x : Numeric , c2y : Numeric , x : Numeric , y : Numeric , path : Path ) : Path
Pen op: cubic Bézier from the current point with control points `(c1x, c1y)` and `(c2x, c2y)` to `(x, y)`.
Arguments:
  • c1x : Numeric - First control point x.
  • c1y : Numeric - First control point y.
  • c2x : Numeric - Second control point x.
  • c2y : Numeric - Second control point y.
  • x : Numeric - End x.
  • y : Numeric - End y.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

discretize_path

discretize_path ( path : Path , curve_angle_degrees : Numeric Nil , sample_count : Numeric Int(128) ) : Path
Replaces every continuous curve in the input path with a polyline of straight line segments, returning a new path. This is the same discretization step that `path_union` / `offset_path` apply internally before handing geometry to Clipper2; running it explicitly is useful for inspecting the polyline that those operations would see, or for paths where polyline-only consumers need a guaranteed-segment-only input. Uses adaptive sampling driven by the global or explicit `curve_angle_degrees`, including lazy paths. Lazy sampling starts from `sample_count` uniform probes plus known critical points and segment boundaries, then refines between them. Existing anchors are retained; additional refinement vertices are not marked as creases. Finite probes can miss arbitrary black-box oscillations; increase `sample_count` if needed.
Arguments:
  • path : Path - A path. Concrete and lazy paths both use adaptive sampling and preserve existing critical points.
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves.
  • sample_count : Numeric Int(128) - Initial uniform probe count for lazy paths, augmented by critical points and adaptive refinement; not an output cap.

fill_rule

fill_rule ( rule : String | Numeric , path : Path ) : Path
Returns the path with the given fill rule, which tessellation, rasterization and boolean ops read from the path when they are not given one explicitly.
Arguments:
  • rule : String | Numeric - One of `"nonzero"`, `"evenodd"`, `"positive"`, `"negative"` (or the Clipper2 numeric code).
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

fillet_path

fillet_path ( path : Sequence , radius : Callable | Numeric , resolution : Numeric Int(8) , clamp_radius : Bool Bool(true) , closed : Bool Bool(false) ) : Sequence
Smooths the interior corners of a 2D polyline by replacing each corner with a circular-arc fillet of the requested radius. Collinear vertices, U-turns, and zero-length segments pass through unmodified. Returns a new sequence of `vec2` points (the original endpoints are preserved when `closed=false`).
Arguments:
  • path : Sequence - Sequence of `vec2` points defining a polyline whose interior corners will be smoothed.
  • radius : Callable | Numeric - Target radius of the inscribed circle at each corner. Either a number (constant for every corner) or a callable `|corner_ix: int, vertex: vec2|: float` that returns a per-corner radius.
  • resolution : Numeric Int(8) - Number of arc segments generated per filleted corner. Higher values produce smoother bends. Each corner replaces 1 input vertex with `resolution + 1` output vertices.
  • clamp_radius : Bool Bool(true) - When true, automatically reduces the per-corner radius so that the fillet's tangent points never cross the midpoint of an adjacent segment. When false, an error is raised if the requested radius is too large for a given corner.
  • closed : Bool Bool(false) - If true, the path is treated as a closed loop and the wrap-around corner between the last and first points is also filleted.

fillet_path_3d

fillet_path_3d ( path : Sequence , radius : Callable | Numeric , resolution : Numeric Int(8) , clamp_radius : Bool Bool(true) , closed : Bool Bool(false) ) : Sequence
Smooths the interior corners of a 3D polyline by replacing each corner with a true circular-arc fillet of the requested radius (lying in the plane of the bend). Collinear vertices, U-turns, and zero-length segments pass through unmodified. Returns a new sequence of `vec3` points (the original endpoints are preserved when `closed=false`). Designed to be piped directly into `extrude_pipe` or other path-consuming builtins.
Arguments:
  • path : Sequence - Sequence of `vec3` points defining a polyline whose interior corners will be smoothed. Often piped directly into `extrude_pipe`.
  • radius : Callable | Numeric - Target radius of the inscribed circle at each corner. Either a number (constant for every corner) or a callable `|corner_ix: int, vertex: vec3|: float` that returns a per-corner radius.
  • resolution : Numeric Int(8) - Number of arc segments generated per filleted corner. Higher values produce smoother bends. Each corner replaces 1 input vertex with `resolution + 1` output vertices.
  • clamp_radius : Bool Bool(true) - When true, automatically reduces the per-corner radius so that the fillet's tangent points never cross the midpoint of an adjacent segment. When false, an error is raised if the requested radius is too large for a given corner.
  • closed : Bool Bool(false) - If true, the path is treated as a closed loop and the wrap-around corner between the last and first points is also filleted.

fit_path

fit_path ( path : Path , pad : Numeric Float(0) ) : Path
Uniformly scales and translates a 2D path so its bounding box fits inside `[pad, 1-pad]²`, filling the longer axis and centering the shorter one. Aspect ratio is preserved. The usual first step before `rasterize_path` / `path_sdf` / `path_uv` for glyphs, traced SVGs, or anything authored in arbitrary units. Uses the exact analytic bounding box when available (see `path_aabb`), falling back to the discretized outline for black-box samplers or arcs under non-uniform transforms.
Arguments:
  • path : Path - A 2D path.
  • pad : Numeric Float(0) - Padding on every side as a fraction of the unit square, in [0, 0.5).

lerp_paths

lerp_paths ( path_a : Path , path_b : Path , mix : Numeric , sample_count : Numeric Int(64) ) : Path
Interpolates between two paths, returning a new path. At each `t`, the output point is `lerp(path_a(t), path_b(t), mix)`. Critical points from both input paths are merged to preserve sharp features during interpolation.
Arguments:
  • path_a : Path - First path.
  • path_b : Path - Second path.
  • mix : Numeric - Interpolation factor [0, 1]. 0 returns path_a, 1 returns path_b.
  • sample_count : Numeric Int(64) - Fallback critical point resolution when inputs lack topology data.

line

line ( x : Numeric , y : Numeric , path : Path ) : Path
Pen op: straight segment from the current point. Pen ops append to the open last subpath; on a closed or empty path they start a new subpath from the current point (the last subpath's end, its start if it is closed, or the origin when the path is empty). Chain them with `|`: `path() | move(0, 0) | line(1, 0) | close`.
Arguments:
  • x : Numeric - X of the segment end.
  • y : Numeric - Y of the segment end.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
line ( to : Vec2 , path : Path ) : Path
Pen op: straight segment from the current point. Pen ops append to the open last subpath; on a closed or empty path they start a new subpath from the current point (the last subpath's end, its start if it is closed, or the origin when the path is empty). Chain them with `|`: `path() | move(0, 0) | line(1, 0) | close`.
Arguments:
  • to : Vec2 - End of the segment.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

lissajous_knot_path

Example
lissajous_knot_path( amp=vec3(18), freq=vec3(3, 5, 7), phase=vec3(0,pi/2,pi/5), count=500 ) | extrude_pipe(radius=1,connect_ends=true, resolution=8) | render
lissajous_knot_path ( amp : Vec3 Vec3(1, 1, 1) , freq : Vec3 Vec3(3, 5, 7) , phase : Vec3 Vec3(0, 1.5707964, 0.62831855) , count : Numeric ) : Sequence
Generates a sequence of points defining a Lissajous knot path
Arguments:
  • amp : Vec3 Vec3(1, 1, 1) - Amplitude of the Lissajous curve in each axis
  • freq : Vec3 Vec3(3, 5, 7) - Frequency of the Lissajous curve in each axis. These should be "pairwise-coprime" integers, meaning that the ratio of any two frequencies should not be reducible to a simpler fraction.
  • phase : Vec3 Vec3(0, 1.5707964, 0.62831855) - Phase offset of the Lissajous curve in each axis
  • count : Numeric - Number of points to sample along the path

move

move ( x : Numeric , y : Numeric , path : Path ) : Path
Pen op: starts a new subpath at the given point. Pen ops append to the open last subpath; on a closed or empty path they start a new subpath from the current point (the last subpath's end, its start if it is closed, or the origin when the path is empty). Chain them with `|`: `path() | move(0, 0) | line(1, 0) | close`.
Arguments:
  • x : Numeric - X of the new subpath start.
  • y : Numeric - Y of the new subpath start.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
move ( to : Vec2 , path : Path ) : Path
Pen op: starts a new subpath at the given point. Pen ops append to the open last subpath; on a closed or empty path they start a new subpath from the current point (the last subpath's end, its start if it is closed, or the origin when the path is empty). Chain them with `|`: `path() | move(0, 0) | line(1, 0) | close`.
Arguments:
  • to : Vec2 - Start of the new subpath.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

offset_path

offset_path ( path : Path , delta : Numeric , join_type : String | Numeric String(round) , end_type : String | Numeric String(round) , miter_limit : Numeric Float(2) , arc_tolerance : Numeric Float(0) , preserve_collinear : Bool Bool(false) , reverse_solution : Bool Bool(false) , step_count : Numeric Int(0) , superellipse_exponent : Numeric Float(2.5) , end_extension_scale : Numeric Float(1) , arrow_back_sweep : Numeric Float(0) , teardrop_pinch : Numeric Float(0.5) , join_angle_threshold : Numeric Float(0) , chebyshev_spacing : Bool Bool(false) , simplify_epsilon : Numeric Float(0.0001) , curve_angle_degrees : Numeric Nil , sample_count : Numeric Int(128) ) : Path
Offsets a 2D path using Clipper2 and returns a new path. Note: continuous curve detail is lost; the output is a polyline representation.
Arguments:
  • path : Path - A path.
  • delta : Numeric - Offset distance (positive inflates, negative deflates).
  • join_type : String | Numeric String(round) - Join type at corners: square, bevel, round, miter, superellipse, knob, step, spike (or numeric enum).
  • end_type : String | Numeric String(round) - End cap type for open paths: polygon, joined, butt, square, round, superellipse, triangle, arrow, teardrop (or numeric enum).
  • miter_limit : Numeric Float(2) - Miter limit for sharp corners.
  • arc_tolerance : Numeric Float(0) - Arc tolerance for round joins.
  • preserve_collinear : Bool Bool(false) - If true, preserve collinear vertices during offset.
  • reverse_solution : Bool Bool(false) - If true, reverse output path orientation.
  • step_count : Numeric Int(0) - Number of steps for stepped joins/caps.
  • superellipse_exponent : Numeric Float(2.5) - Superellipse exponent for superellipse joins/caps.
  • end_extension_scale : Numeric Float(1) - Scale for open end caps.
  • arrow_back_sweep : Numeric Float(0) - Arrow back sweep for arrow end caps.
  • teardrop_pinch : Numeric Float(0.5) - Teardrop pinch amount for teardrop end caps.
  • join_angle_threshold : Numeric Float(0) - Angle threshold used by some join types.
  • chebyshev_spacing : Bool Bool(false) - If true, use Chebyshev spacing for round joins.
  • simplify_epsilon : Numeric Float(0.0001) - Epsilon for pre-offset simplification (0 disables).
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves.
  • sample_count : Numeric Int(128) - Initial uniform probe count for lazy paths. Critical points and structural boundaries are also sampled, then refined adaptively per curve_angle_degrees; this is not an output cap.

path

path ( items : Sequence | Path | Nil Nil , fill_rule : String | Nil | Numeric Nil ) : Path
Groups paths into one path whose subpaths run in order. Concrete inputs are merged into a single flat list of subpaths; lazy inputs (`lerp_paths`, `catmull_rom`, `path(fn)`) are kept as they are. `path()` is the empty path, the usual start of a pen-op chain: `path() | move(0, 0) | line(1, 1) | close`.
Arguments:
  • items : Sequence | Path | Nil Nil - A path, a sequence of paths, or nested sequences of them; `nil` entries are skipped.
  • fill_rule : String | Nil | Numeric Nil - Fill rule for the grouped path (`"nonzero"`, `"evenodd"`, `"positive"`, `"negative"`). When omitted it is inherited if every item agrees; conflicting rules are an error.
path ( f : Callable , closed : Bool | Nil Nil ) : Path
Wraps a `|t: num|: vec2` callable as a lazy path. It has no draw commands, so pen ops and `path_segments` need `discretize_path` first; everything else samples it.
Arguments:
  • f : Callable - A `|t: num|: vec2` callable sampled over `t` in [0, 1].
  • closed : Bool | Nil Nil - Whether the sampled curve is a closed loop. When nil it is inferred from whether `f(0)` and `f(1)` coincide.

path_aabb

path_aabb ( path : Path ) : Sequence
Returns the exact axis-aligned bounding box of a 2D path as a 2-element sequence `[mins, maxs]` of Vec2 corners. The bound is computed analytically from the path's line segments, beziers, and arcs (exact modulo floating-point rounding), not from a polyline discretization. Any transforms applied to the path are baked in. Errors if the path is empty, or if it contains arc segments under a non-uniform transform (skew or non-uniform scale), since transformed arcs are conics with no closed-form axis-aligned bound; bake the transform with `apply_transforms` first in that case.
Arguments:
  • path : Path - A path with analytic segment topology (e.g. from `circle`, `rect`, `path()` pen ops, `trace_svg_path`, `text_to_path`).

path_difference

alias: path_sub
path_difference ( subject : Path , clip : Path , fill_rule : String | Nil | Numeric Nil , curve_angle_degrees : Numeric Nil , sample_count : Numeric Int(64) , engine : String | Nil Nil ) : Path
Computes the difference of two 2D paths (subject minus clip). The result contains areas inside subject but not inside clip. See `path_union` for the full fill-rule and engine reference; the same conventions apply here.
Arguments:
  • subject : Path - The first path.
  • clip : Path - The second path.
  • fill_rule : String | Nil | Numeric Nil - Fill rule for determining path interiors: evenodd, nonzero, positive, negative (or numeric enum 0-3). Defaults to `nonzero` for the `clipper` engine and `evenodd` for `cgal` (the only rule `cgal` accepts).
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves.
  • sample_count : Numeric Int(64) - Initial uniform probe count for lazy paths. Critical points and structural boundaries are also sampled, then refined adaptively per curve_angle_degrees; this is not an output cap.
  • engine : String | Nil Nil - Backend: `clipper` (default; fast, fixed-point) or `cgal` (slower, exact-arithmetic).

path_frame

path_frame ( t : Numeric , path : Path , inward_normal : Bool Bool(true) ) : Map
Samples a path at parameter `t` and returns a frame dict `{pos: vec2, tangent: vec2, normal: vec2}`. - `pos`: the path point `p(t)`. - `tangent`: a unit vector along the path direction, computed via central finite difference (with one-sided fallback at t=0 and t=1). - `normal`: a unit vector perpendicular to the tangent. By default it's the left-perpendicular (counter-clockwise rotation by 90°). For closed subpaths whose orientation can be determined, it is flipped to consistently point inward when `inward_normal` is true. Useful for sweeps, ribbons, offset constructions, or any procedural geometry that needs to follow a path with a consistent local frame.
Arguments:
  • t : Numeric - Arc-length parameter in [0, 1]; clamped if out of range.
  • path : Path - path.
  • inward_normal : Bool Bool(true) - When true and `t` lies inside a closed subpath whose orientation can be determined, the normal is flipped to point inward (toward the interior of the closed shape) regardless of CW/CCW winding. For open subpaths or paths without topology, has no effect; the normal is the left-perpendicular of the tangent.

path_intersect

path_intersect ( subject : Path , clip : Path , fill_rule : String | Nil | Numeric Nil , curve_angle_degrees : Numeric Nil , sample_count : Numeric Int(64) , engine : String | Nil Nil ) : Path
Computes the intersection of two 2D paths. The intersection contains only areas inside both paths. See `path_union` for the full fill-rule and engine reference; the same conventions apply here.
Arguments:
  • subject : Path - The first path.
  • clip : Path - The second path.
  • fill_rule : String | Nil | Numeric Nil - Fill rule for determining path interiors: evenodd, nonzero, positive, negative (or numeric enum 0-3). Defaults to `nonzero` for the `clipper` engine and `evenodd` for `cgal` (the only rule `cgal` accepts).
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves.
  • sample_count : Numeric Int(64) - Initial uniform probe count for lazy paths. Critical points and structural boundaries are also sampled, then refined adaptively per curve_angle_degrees; this is not an output cap.
  • engine : String | Nil Nil - Backend: `clipper` (default; fast, fixed-point) or `cgal` (slower, exact-arithmetic).

path_intersects

path_intersects ( a : Path , b : Path , fill_rule : String | Numeric String(nonzero) , curve_angle_degrees : Numeric Nil , sample_count : Numeric Int(64) ) : Bool
Returns `true` if the two 2D path regions overlap under the given fill rule, `false` otherwise. Detects both cases where path segments cross and cases where one path is fully contained inside the other. Uses Clipper2's region intersection internally, so winding order and the chosen fill rule determine what counts as interior. Only supported for paths with known topology (e.g. from `trace_svg_path`, `text_to_path`, `lerp_path`, `catmull_rom`); generic black-box `|t|: vec2` callables raise an error.
Arguments:
  • a : Path - The first path.
  • b : Path - The second path. Same restriction as `a`.
  • fill_rule : String | Numeric String(nonzero) - Fill rule used to determine the interior of each path when checking for overlap: evenodd, nonzero, positive, negative (or numeric enum 0-3).
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves.
  • sample_count : Numeric Int(64) - Initial uniform probe count for lazy paths, augmented by critical points and adaptive refinement; not an output cap.

path_segments

path_segments ( path : Path ) : Sequence
Returns a sequence of tagged dicts, one per segment of the path, in subpath traversal order with the path's transform applied. Every segment dict has these common fields: - `type`: `"line"` | `"quad"` | `"cubic"` | `"arc"` - `start`, `end`: vec2 endpoints - `length`: arc length of the segment - `subpath`: int - index of the parent subpath - `closed`: bool - whether the parent subpath is closed - `t_start`, `t_end`: floats in [0, 1] - arc-length parameters within the parent subpath - `t_start_global`, `t_end_global`: floats in [0, 1] - arc-length parameters across the full path Per-type extras: - `quad`: `ctrl: vec2` - `cubic`: `ctrl1: vec2`, `ctrl2: vec2` - `arc`: `center: vec2`, `rx: num`, `ry: num`, `x_axis_rotation: num` (radians), `large_arc: bool`, `sweep: bool`, `theta_start: num`, `theta_delta: num` The path's `reverse` flag is a sampling-order concern and is intentionally not honoured here; segments are always emitted in their as-built order. Only works with paths that expose segment topology (i.e. those backed by a path tracer); paths from `catmull_rom` / `lerp_paths` are not supported.
Arguments:
  • path : Path - path from any path constructor or op / boolean ops.

path_union

path_union ( subject : Path , clip : Path , fill_rule : String | Nil | Numeric Nil , curve_angle_degrees : Numeric Nil , sample_count : Numeric Int(64) , engine : String | Nil Nil ) : Path
Computes the union of two 2D paths. The union contains all areas inside either path. Which regions count as "inside" depends on `fill_rule` (default `nonzero`): - `nonzero`: a point is inside if the signed-crossing count of a ray from it to infinity is non-zero. Inner subpaths must wind opposite to outer subpaths to register as holes. - `evenodd`: a point is inside if the unsigned crossing count is odd. Winding direction is ignored; holes arise purely from nesting. - `positive` / `negative`: like `nonzero` but keep only regions with positive or negative winding number respectively. **Engine selection** (`engine` kwarg, default `clipper`): - `clipper`: Clipper2, fast but operates in fixed-point internally so float coordinates are quantized and exact-coincident points may shift slightly. This can cause T-junctions and tiny gaps in the output topology that break downstream operations like 2-manifold extrusion. - `cgal`: CGAL `Polygon_set_2` over `Exact_predicates_exact_constructions_kernel`; exact arithmetic preserves coincident edges precisely. Slower (often 10–100×) but produces clean topology suitable for `extrude` / `tessellate_path`. Only `evenodd` fill rule is supported; within each input, subpaths combine under XOR (matching the nesting-based fill model). For paths built procedurally as non-overlapping subpaths (e.g. an outer shape plus enclosed holes), skip the boolean op entirely and pass the multi-subpath path directly to downstream consumers; they will treat nested subpaths as holes under their own fill rule.
Arguments:
  • subject : Path - The first path.
  • clip : Path - The second path.
  • fill_rule : String | Nil | Numeric Nil - Fill rule for determining path interiors: evenodd, nonzero, positive, negative (or numeric enum 0-3). Defaults to `nonzero` for the `clipper` engine and `evenodd` for `cgal` (the only rule `cgal` accepts).
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves.
  • sample_count : Numeric Int(64) - Initial uniform probe count for lazy paths. Critical points and structural boundaries are also sampled, then refined adaptively per curve_angle_degrees; this is not an output cap.
  • engine : String | Nil Nil - Backend: `clipper` (default; fast, fixed-point) or `cgal` (slower, exact-arithmetic via `Polygon_set_2` over EPECK).
path_union ( paths : Sequence , fill_rule : String | Nil | Numeric Nil , curve_angle_degrees : Numeric Nil , sample_count : Numeric Int(64) , engine : String | Nil Nil ) : Path
Computes the union of every path in a sequence in a single boolean pass. Much faster than chaining pairwise unions (`reduce(path_union)` and `fold(init, path_union)` route here automatically), since each pairwise step would re-sample and re-analyze the growing result. Options and engines behave as for the two-path form; with `engine="cgal"` the inputs are combined pairwise internally.
Arguments:
  • paths : Sequence - Sequence of paths to union together.
  • fill_rule : String | Nil | Numeric Nil - Fill rule for determining path interiors: evenodd, nonzero, positive, negative (or numeric enum 0-3). Defaults to `nonzero` for the `clipper` engine and `evenodd` for `cgal` (the only rule `cgal` accepts).
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves.
  • sample_count : Numeric Int(64) - Initial uniform probe count for lazy paths. Critical points and structural boundaries are also sampled, then refined adaptively per curve_angle_degrees; this is not an output cap.
  • engine : String | Nil Nil - Backend: `clipper` (default; fast, fixed-point) or `cgal` (slower, exact-arithmetic via `Polygon_set_2` over EPECK).

path_xor

path_xor ( subject : Path , clip : Path , fill_rule : String | Nil | Numeric Nil , curve_angle_degrees : Numeric Nil , sample_count : Numeric Int(64) , engine : String | Nil Nil ) : Path
Computes the exclusive-or (XOR) of two 2D paths. The result contains areas inside either path but not both. See `path_union` for the full fill-rule and engine reference; the same conventions apply here.
Arguments:
  • subject : Path - The first path.
  • clip : Path - The second path.
  • fill_rule : String | Nil | Numeric Nil - Fill rule for determining path interiors: evenodd, nonzero, positive, negative (or numeric enum 0-3). Defaults to `nonzero` for the `clipper` engine and `evenodd` for `cgal` (the only rule `cgal` accepts).
  • curve_angle_degrees : Numeric Nil - Max turning angle (degrees) per segment when discretizing curves.
  • sample_count : Numeric Int(64) - Initial uniform probe count for lazy paths. Critical points and structural boundaries are also sampled, then refined adaptively per curve_angle_degrees; this is not an output cap.
  • engine : String | Nil Nil - Backend: `clipper` (default; fast, fixed-point) or `cgal` (slower, exact-arithmetic).

polygon

polygon ( points : Sequence ) : Path
Closed path through `points`, joined by straight segments and closed back to the first point.
Arguments:
  • points : Sequence - Sequence of `vec2` vertices (at least 3 distinct).

polyline

polyline ( points : Sequence ) : Path
Open path through `points`, joined by straight segments.
Arguments:
  • points : Sequence - Sequence of `vec2` vertices (at least 2).

polyline_frames

polyline_frames ( points : Sequence , n : Numeric , closed : Bool Bool(false) , smooth : Numeric Float(0) , up : Vec3 | Nil Nil , inward_normal : Bool Bool(true) ) : Sequence
Samples a polyline (a `Seq<Vec2>` or `Seq<Vec3>` of points) at a set of positions and returns a `Seq` of frame dicts. vec2 polylines yield `{t, pos, tangent, normal}`; vec3 polylines additionally yield `binormal`. `t` is normalized arc length in [0, 1], so evenly-spaced `t` gives evenly-spaced points no matter how the input vertices are distributed. Values outside [0, 1] are clamped. Frames are piecewise constant per segment: a sample lands on a segment and takes that segment's direction, with `pos` interpolated along it. Pass `smooth` to blend orientation across corners instead of snapping. This is the polyline counterpart to `path_frame`, which works on continuous 2D paths. Every call walks the whole point sequence to build its arc-length table, so it's built for short static point lists (tens of points) sampled in one shot — not for repeated random access into long paths. Consecutive duplicate points are dropped.
Arguments:
  • points : Sequence - Sequence of `vec2` or `vec3` points defining the polyline. All points must be the same type. At least 2 distinct points are required (3 when `closed=true`).
  • n : Numeric - Number of evenly-spaced (in arc length) samples. Open polylines sample inclusively, `t = i / (n - 1)`, so the first and last samples land exactly on the endpoints. Closed polylines sample half-open, `t = i / n`, so the wrap-around sample doesn't duplicate the first.
  • closed : Bool Bool(false) - When true the polyline is treated as a loop: a closing segment from the last point back to the first is added, and frames stay coherent across the seam.
  • smooth : Numeric Float(0) - Turn-smoothing band half-width, in world units of arc length. `0` (the default) gives the exact per-segment frame, so orientation snaps at each vertex. Otherwise the frame blends from the incoming to the outgoing segment's frame over `smooth` units either side of the corner. Automatically clamped per-corner to half the shorter adjacent segment, so bands never overlap and no value is ever "too large".
  • up : Vec3 | Nil Nil - vec3 polylines only. When set, `normal` is `tangent × up`, giving a fixed-reference frame that never rolls — usually what you want when placing upright objects like pillars along a ground path. When nil (the default), normals are parallel-transported segment to segment (rotation-minimizing), which stays coherent on spines that turn out of any single plane. Errors if passed for a vec2 polyline.
  • inward_normal : Bool Bool(true) - vec2 polylines only. When true and the polyline is closed, the normal is flipped to point into the interior regardless of CW/CCW winding, matching `path_frame`. No effect on open or vec3 polylines.
polyline_frames ( points : Sequence , t : Sequence , closed : Bool Bool(false) , smooth : Numeric Float(0) , up : Vec3 | Nil Nil , inward_normal : Bool Bool(true) ) : Sequence
Samples a polyline (a `Seq<Vec2>` or `Seq<Vec3>` of points) at a set of positions and returns a `Seq` of frame dicts. vec2 polylines yield `{t, pos, tangent, normal}`; vec3 polylines additionally yield `binormal`. `t` is normalized arc length in [0, 1], so evenly-spaced `t` gives evenly-spaced points no matter how the input vertices are distributed. Values outside [0, 1] are clamped. Frames are piecewise constant per segment: a sample lands on a segment and takes that segment's direction, with `pos` interpolated along it. Pass `smooth` to blend orientation across corners instead of snapping. This is the polyline counterpart to `path_frame`, which works on continuous 2D paths. Every call walks the whole point sequence to build its arc-length table, so it's built for short static point lists (tens of points) sampled in one shot — not for repeated random access into long paths. Consecutive duplicate points are dropped.
Arguments:
  • points : Sequence - Sequence of `vec2` or `vec3` points defining the polyline. All points must be the same type. At least 2 distinct points are required (3 when `closed=true`).
  • t : Sequence - Explicit sample positions as a sequence of numbers, each a normalized arc-length parameter in [0, 1] (clamped if out of range). Order is arbitrary; output frames are returned in the order given.
  • closed : Bool Bool(false) - When true the polyline is treated as a loop: a closing segment from the last point back to the first is added, and frames stay coherent across the seam.
  • smooth : Numeric Float(0) - Turn-smoothing band half-width, in world units of arc length. `0` (the default) gives the exact per-segment frame, so orientation snaps at each vertex. Otherwise the frame blends from the incoming to the outgoing segment's frame over `smooth` units either side of the corner. Automatically clamped per-corner to half the shorter adjacent segment, so bands never overlap and no value is ever "too large".
  • up : Vec3 | Nil Nil - vec3 polylines only. When set, `normal` is `tangent × up`, giving a fixed-reference frame that never rolls — usually what you want when placing upright objects like pillars along a ground path. When nil (the default), normals are parallel-transported segment to segment (rotation-minimizing), which stays coherent on spines that turn out of any single plane. Errors if passed for a vec2 polyline.
  • inward_normal : Bool Bool(true) - vec2 polylines only. When true and the polyline is closed, the normal is flipped to point into the interior regardless of CW/CCW winding, matching `path_frame`. No effect on open or vec3 polylines.

quadratic_bezier

aliases: quad, quad_bezier
quadratic_bezier ( ctrl : Vec2 , to : Vec2 , path : Path ) : Path
Pen op: quadratic Bézier from the current point through `ctrl` to `to`.
Arguments:
  • ctrl : Vec2 - Control point.
  • to : Vec2 - End point.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
quadratic_bezier ( cx : Numeric , cy : Numeric , x : Numeric , y : Numeric , path : Path ) : Path
Pen op: quadratic Bézier from the current point through `(cx, cy)` to `(x, y)`.
Arguments:
  • cx : Numeric - Control point x.
  • cy : Numeric - Control point y.
  • x : Numeric - End x.
  • y : Numeric - End y.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

rect

rect ( center : Vec2 , size : Vec2 | Numeric ) : Path
Closed rectangular path traced counter-clockwise from the top-right corner.
Arguments:
  • center : Vec2 - Center of the rectangle.
  • size : Vec2 | Numeric - Width and height as a `vec2`, or one number for a square.
rect ( cx : Numeric , cy : Numeric , width : Numeric , height : Numeric ) : Path
Closed rectangular path traced counter-clockwise from the top-right corner.
Arguments:
  • cx : Numeric - Center x.
  • cy : Numeric - Center y.
  • width : Numeric - Width.
  • height : Numeric - Height.

set_curve_angle_threshold

set_curve_angle_threshold ( angle_degrees : Numeric ) : Nil
Sets the default `curve_angle_degrees` used when discretizing continuous path features (Clipper2/CGAL boundaries, `tessellate_path`, `extrude_path`, etc.) and the kwarg is omitted. Builtins that take an explicit `curve_angle_degrees` override this per-call. Must be called as a top-level statement (not inside closures or conditionals).
Arguments:
  • angle_degrees : Numeric - Maximum angular deviation per segment, in degrees; smaller is finer.

simplify_path

simplify_path ( path : Path , tolerance : Numeric Float(0.01) ) : Path
Removes vertices from the straight runs of a path (Ramer–Douglas–Peucker) while keeping every remaining point of the original within `tolerance` of the result. Curve segments are kept verbatim, and critical points marked by producers (`path_union`, `offset_path`, `alpha_wrap_2d`, `discretize_path`, …) are never removed, so `critical_points` survive; authored joints from pen ops / `polygon` are all candidates. Use it to thin dense polylines (boolean/wrap output, traced text, SVG) before sweeping, lerping, or further booleans.
Arguments:
  • path : Path - A path. Lazy paths (e.g. `lerp_paths`) are discretized first at the ambient curve angle.
  • tolerance : Numeric Float(0.01) - Max distance (in path units) any removed vertex may lie from the simplified outline. 0 only removes collinear vertices.
simplify_path ( tolerance : Numeric , path : Path ) : Path
Tolerance-first form for pipelines: `path | simplify_path(0.02)`.
Arguments:
  • tolerance : Numeric - Max distance (in path units) any removed vertex may lie from the simplified outline.
  • path : Path - A path.

smooth_cubic_bezier

aliases: smooth_bezier, smooth_cubic
smooth_cubic_bezier ( ctrl2 : Vec2 , to : Vec2 , path : Path ) : Path
Pen op: cubic Bézier whose first control point mirrors the previous cubic's second across the current point (the current point itself when there is none), like SVG `S`.
Arguments:
  • ctrl2 : Vec2 - Second control point.
  • to : Vec2 - End point.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
smooth_cubic_bezier ( c2x : Numeric , c2y : Numeric , x : Numeric , y : Numeric , path : Path ) : Path
Pen op: cubic Bézier whose first control point mirrors the previous cubic's second across the current point (the current point itself when there is none), like SVG `S`.
Arguments:
  • c2x : Numeric - Second control point x.
  • c2y : Numeric - Second control point y.
  • x : Numeric - End x.
  • y : Numeric - End y.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

smooth_quadratic_bezier

aliases: smooth_quad_bezier, smooth_quad
smooth_quadratic_bezier ( to : Vec2 , path : Path ) : Path
Pen op: quadratic Bézier whose control point mirrors the previous quadratic's across the current point (the current point itself when there is none), like SVG `T`.
Arguments:
  • to : Vec2 - End point.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.
smooth_quadratic_bezier ( x : Numeric , y : Numeric , path : Path ) : Path
Pen op: quadratic Bézier whose control point mirrors the previous quadratic's across the current point (the current point itself when there is none), like SVG `T`.
Arguments:
  • x : Numeric - End x.
  • y : Numeric - End y.
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

subpaths

subpaths ( path : Path ) : Sequence
Returns a lazy sequence of paths, one for each disconnected subpath in the input path. For example, if a path is created with multiple `move` commands, each segment between moves becomes a separate subpath. Each returned sampler works like the original, with `t` in [0,1] sampling along that particular subpath.
Arguments:
  • path : Path - A path to split

superellipse

superellipse ( t : Numeric , n : Numeric , width : Numeric Float(1) , height : Numeric Float(1) ) : Vec2
Returns the `Vec2` position at parameter `t` along the perimeter of a superellipse
Arguments:
  • t : Numeric - Parameter in [0, 1] specifying the position along the superellipse perimeter
  • n : Numeric - Exponent that controls the shape of the superellipse. A value of 2 produces an ellipse, higher values produce more rectangular shapes, and lower values produce diamond and star-like shapes.
  • width : Numeric Float(1)
  • height : Numeric Float(1)

superellipse_path

aliases: rounded_rect, rounded_rectangle
superellipse_path ( n : Numeric , point_count : Numeric , width : Numeric Float(1) , height : Numeric Float(1) ) : Sequence
Generates a sequence of points defining a superellipse, or rounded rectangle. Returns a sequence of `point_count` `Vec2` points
Arguments:
  • n : Numeric - Exponent that controls the shape of the superellipse. A value of 2 produces an ellipse, higher values produce more rectangular shapes, and lower values produce diamond and star-like shapes.
  • point_count : Numeric - Number of points to generate along the path
  • width : Numeric Float(1)
  • height : Numeric Float(1)

text_to_path

text_to_path ( text : String , font_family : String String(IBM Plex Sans) , font_size : Numeric Float(24) , font_weight : String | Nil | Numeric Nil , font_style : String | Nil Nil , letter_spacing : Nil | Numeric Nil ) : Path
Fetches SVG path data for the given text and returns a path. Suitable for use with `tessellate_path`, `render_path`, `subpaths`, etc.
Arguments:
  • text : String
  • font_family : String String(IBM Plex Sans) - Font family to use for the text. Must exist on Google Fonts.
  • font_size : Numeric Float(24)
  • font_weight : String | Nil | Numeric Nil
  • font_style : String | Nil Nil - Must be one of "normal", "italic", or "oblique". If nil, defaults to "normal".
  • letter_spacing : Nil | Numeric Nil

text_to_svg

text_to_svg ( text : String , font_family : String String(IBM Plex Sans) , font_size : Numeric Float(24) , font_weight : String | Nil | Numeric Nil , font_style : String | Nil Nil , letter_spacing : Nil | Numeric Nil ) : String
Fetches the SVG path data string for the given text in the specified font. Requires an internet connection to fetch from the font server.
Arguments:
  • text : String
  • font_family : String String(IBM Plex Sans) - Font family to use for the text. Must exist on Google Fonts.
  • font_size : Numeric Float(24)
  • font_weight : String | Nil | Numeric Nil
  • font_style : String | Nil Nil - Must be one of "normal", "italic", or "oblique". If nil, defaults to "normal".
  • letter_spacing : Nil | Numeric Nil

torus_knot_path

Example
ambient_light(color=0xffffff, intensity=1.8) | render dir_light( color=0xffffff, intensity=5, cast_shadow=true, shadow_map_size={width: 2048*2, height: 2048*2}, shadow_map_radius=4, shadow_map_blur_samples=16, shadow_map_type="vsm", shadow_map_bias=-0.0001, shadow_camera={near: 1, far: 25, left: -20, right: 20, top: 20, bottom: -20}, ) | trans(-10, 10, 0) | render; //-- end prelude path = torus_knot_path( radius=5, tube_radius=2, p=3, q=4, point_count=400 ) path | extrude_pipe(radius=1, resolution=12, connect_ends=true) | simplify(tolerance=0.05) | render
torus_knot_path ( radius : Numeric , tube_radius : Numeric , p : Numeric , q : Numeric , point_count : Numeric ) : Sequence
Generates a sequence of points defining a torus knot path
Arguments:
  • radius : Numeric
  • tube_radius : Numeric
  • p : Numeric - Number of times the knot wraps around the torus in the longitudinal direction
  • q : Numeric - Number of times the knot wraps around the torus in the meridional direction
  • point_count : Numeric - Number of points to generate along the path

trace_svg_path

trace_svg_path ( svg_path : String ) : Path
Parses SVG path data (`M`, `L`, `H`, `V`, `C`, `S`, `Q`, `T`, `A`, `Z`, absolute or relative) into a path.
Arguments:
  • svg_path : String - An SVG path data string using move, line, cubic/quadratic, smooth, and arc commands.

trim_path

alias: path_trim
trim_path ( path : Path , start : Nil | Numeric Nil , end : Nil | Numeric Nil , unit : String String(t) ) : Path
Returns a new path covering the portion of `path` between `start` and `end`. Trimming is done in the global arc-length parameterization that spans all subpaths, so `start`/`end` cut across the concatenated subpaths; iterate `path_subpaths` first to trim an individual subpath. Negative bounds count back from the end (e.g. `trim_path(p, start=4, end=-4, unit='distance')` drops 4 units from each end). For tracer-backed paths the result is a real sliced path: lines, beziers and arcs keep their exact geometry and every sharp corner inside the range is preserved. Black-box callables are wrapped and resampled, with `distance` bounds resolved against a sampling-based length estimate.
Arguments:
  • path : Path - A path. Concrete paths are sliced geometrically (curves and sharp corners preserved exactly); lazy paths are wrapped and resampled over the trimmed range.
  • start : Nil | Numeric Nil - Start of the kept range. Negative values count back from the end. `nil` keeps from the path start.
  • end : Nil | Numeric Nil - End of the kept range. Negative values count back from the end. `nil` keeps to the path end.
  • unit : String String(t) - `"t"` (default) treats `start`/`end` as normalized arc-length parameters in [0, 1]; `"distance"` treats them as arc-length distances.

rand

curl_noise

Example
noise_scale = 0.001 noise_gain = 0.175 origin_bias = 0.0002 step_size = 0.1 seed_offset = v3(-4) build_path = |count: int| { scan({ dir: normalize(randv(-1, 1)) * 50., pos: v3(0) }, |{ dir, pos }, i| { field_p = seed_offset + pos * noise_scale noise = curl_noise(field_p) dir = dir * 0.9 dir = dir + noise * noise_gain dir = dir + -pos * pow((distance(pos, vec3(0)) * origin_bias), 3) pos = pos + dir * step_size { dir: dir, pos: pos } }, 0..count) -> |{ pos }| pos } paths = 0..800 -> || { build_path(2500) | filter(|_, i| i % 4 == 0) | extrude_pipe(radius=1, resolution=8) } paths | for_each(render) // paths // | flatten // | alpha_wrap(alpha=1/500, offset=1/700) // | simplify(tolerance=0.0125) // | smooth(iterations=1) // | simplify(tolerance=0.0125) // | render
curl_noise ( pos : Vec3 ) : Vec3
Samples 3D curl noise at a given position using default parameters
Arguments:
  • pos : Vec3
curl_noise ( seed : Numeric Int(0) , octaves : Numeric Int(4) , frequency : Numeric Float(1) , lacunarity : Numeric Float(2) , persistence : Numeric Float(0.5) , pos : Vec3 ) : Vec3
Samples 3D curl noise at a given position using the specified parameters
Arguments:
  • seed : Numeric Int(0)
  • octaves : Numeric Int(4)
  • frequency : Numeric Float(1)
  • lacunarity : Numeric Float(2)
  • persistence : Numeric Float(0.5)
  • pos : Vec3
curl_noise ( pos : Vec2 ) : Vec2
Samples 2D curl noise at a given position using default parameters
Arguments:
  • pos : Vec2
curl_noise ( seed : Numeric Int(0) , octaves : Numeric Int(4) , frequency : Numeric Float(1) , lacunarity : Numeric Float(2) , persistence : Numeric Float(0.5) , pos : Vec2 ) : Vec2
Samples 2D curl noise at a given position using the specified parameters
Arguments:
  • seed : Numeric Int(0)
  • octaves : Numeric Int(4)
  • frequency : Numeric Float(1)
  • lacunarity : Numeric Float(2)
  • persistence : Numeric Float(0.5)
  • pos : Vec2

fbm

Example
grid(size=300, divisions=300) -> |v| { noise = fbm(octaves=8, pos=v*0.01, lacunarity=1.8) vec3(v.x, noise * 36, v.z) } | render
fbm ( pos : Vec3 ) : Float
Samples 3D fractal Brownian motion (FBM) at a given position using default parameters
Arguments:
  • pos : Vec3
fbm ( seed : Numeric Int(0) , octaves : Numeric Int(4) , frequency : Numeric Float(1) , lacunarity : Numeric Float(2) , persistence : Numeric Float(0.5) , pos : Vec3 ) : Float
Samples 3D fractal Brownian motion (FBM) at a given position using the specified parameters
Arguments:
  • seed : Numeric Int(0)
  • octaves : Numeric Int(4)
  • frequency : Numeric Float(1)
  • lacunarity : Numeric Float(2)
  • persistence : Numeric Float(0.5)
  • pos : Vec3
fbm ( pos : Vec2 , tileable : Bool | Numeric Bool(false) ) : Float
Samples 2D fractal Brownian motion (FBM) at a given position using default parameters
Arguments:
  • pos : Vec2
  • tileable : Bool | Numeric Bool(false) - `true` tiles seamlessly with period 1 in `pos` units; a number tiles with that period. Each octave's frequency is snapped so a whole number of noise cells fits the period.
fbm ( seed : Numeric Int(0) , octaves : Numeric Int(4) , frequency : Numeric Float(1) , lacunarity : Numeric Float(2) , persistence : Numeric Float(0.5) , pos : Vec2 , tileable : Bool | Numeric Bool(false) ) : Float
Samples 2D fractal Brownian motion (FBM) at a given position using the specified parameters
Arguments:
  • seed : Numeric Int(0)
  • octaves : Numeric Int(4)
  • frequency : Numeric Float(1)
  • lacunarity : Numeric Float(2)
  • persistence : Numeric Float(0.5)
  • pos : Vec2
  • tileable : Bool | Numeric Bool(false) - `true` tiles seamlessly with period 1 in `pos` units; a number tiles with that period. Each octave's frequency is snapped so a whole number of noise cells fits the period.
fbm ( pos : Numeric ) : Float
Samples 1D fractal Brownian motion (FBM) at a given position using default parameters
Arguments:
  • pos : Numeric
fbm ( seed : Numeric Int(0) , octaves : Numeric Int(4) , frequency : Numeric Float(1) , lacunarity : Numeric Float(2) , persistence : Numeric Float(0.5) , pos : Numeric ) : Float
Samples 1D fractal Brownian motion (FBM) at a given position using the specified parameters
Arguments:
  • seed : Numeric Int(0)
  • octaves : Numeric Int(4)
  • frequency : Numeric Float(1)
  • lacunarity : Numeric Float(2)
  • persistence : Numeric Float(0.5)
  • pos : Numeric

randf

randf ( min : Numeric , max : Numeric ) : Float
Returns a random float between `min` and `max`
Arguments:
  • min : Numeric
  • max : Numeric
randf ( ) : Float
Returns a random float between 0. and 1.

randi

randi ( min : Numeric , max : Numeric ) : Int
Returns a random integer in `[min, max)`. If `min == max`, returns `min`.
Arguments:
  • min : Numeric
  • max : Numeric
randi ( ) : Int
Returns a random integer. Any 64-bit integer is equally possible, positive or negative.

randv

alias: randv3
randv ( min : Vec3 , max : Vec3 ) : Vec3
Returns a random Vec3 where each component is between the corresponding components of `min` and `max`
Arguments:
  • min : Vec3
  • max : Vec3
randv ( min : Numeric , max : Numeric ) : Vec3
Returns a random Vec3 where each component is between `min` and `max`
Arguments:
  • min : Numeric
  • max : Numeric
randv ( ) : Vec3
Returns a random Vec3 where each component is between 0. and 1.

ridged_multifractal

ridged_multifractal ( pos : Vec3 ) : Float
Samples 3D ridged multifractal noise at a given position using default parameters
Arguments:
  • pos : Vec3
ridged_multifractal ( seed : Numeric Int(0) , octaves : Numeric Int(4) , frequency : Numeric Float(1) , lacunarity : Numeric Float(2) , persistence : Numeric Float(0.5) , gain : Numeric Float(2) , pos : Vec3 ) : Float
Samples 3D ridged multifractal noise at a given position using the specified parameters
Arguments:
  • seed : Numeric Int(0)
  • octaves : Numeric Int(4)
  • frequency : Numeric Float(1)
  • lacunarity : Numeric Float(2)
  • persistence : Numeric Float(0.5)
  • gain : Numeric Float(2)
  • pos : Vec3
ridged_multifractal ( pos : Vec2 ) : Float
Samples 2D ridged multifractal noise at a given position using default parameters
Arguments:
  • pos : Vec2
ridged_multifractal ( seed : Numeric Int(0) , octaves : Numeric Int(4) , frequency : Numeric Float(1) , lacunarity : Numeric Float(2) , persistence : Numeric Float(0.5) , gain : Numeric Float(2) , pos : Vec2 ) : Float
Samples 2D ridged multifractal noise at a given position using the specified parameters
Arguments:
  • seed : Numeric Int(0)
  • octaves : Numeric Int(4)
  • frequency : Numeric Float(1)
  • lacunarity : Numeric Float(2)
  • persistence : Numeric Float(0.5)
  • gain : Numeric Float(2)
  • pos : Vec2

set_rng_seed

set_rng_seed ( seed : Numeric ) : Nil
Sets the seed for the shared PRNG used by functions like `randi`, `randf`, etc. This will reset the state of the RNG, so it will always return the same value the next time it's used after this is called.
Arguments:
  • seed : Numeric

srandf

srandf ( seed : Numeric , min : Numeric , max : Numeric ) : Float
Returns a deterministic random float between `min` and `max` for `seed`.
Arguments:
  • seed : Numeric
  • min : Numeric
  • max : Numeric
srandf ( seed : Numeric ) : Float
Returns a deterministic random float between 0. and 1. for `seed`.
Arguments:
  • seed : Numeric

srandi

srandi ( seed : Numeric , min : Numeric , max : Numeric ) : Int
Returns a deterministic random integer in `[min, max)` for `seed`. If `min == max`, returns `min`.
Arguments:
  • seed : Numeric
  • min : Numeric
  • max : Numeric
srandi ( seed : Numeric ) : Int
Returns a deterministic random integer for `seed`. Any 64-bit integer is equally possible, positive or negative.
Arguments:
  • seed : Numeric

srandv

srandv ( seed : Numeric , min : Vec3 , max : Vec3 ) : Vec3
Returns a deterministic Vec3 for `seed` where each component is between the corresponding components of `min` and `max`.
Arguments:
  • seed : Numeric
  • min : Vec3
  • max : Vec3
srandv ( seed : Numeric , min : Numeric , max : Numeric ) : Vec3
Returns a deterministic Vec3 for `seed` where each component is between `min` and `max`.
Arguments:
  • seed : Numeric
  • min : Numeric
  • max : Numeric
srandv ( seed : Numeric ) : Vec3
Returns a deterministic Vec3 for `seed` where each component is between 0. and 1.
Arguments:
  • seed : Numeric

worley_noise

alias: worley
worley_noise ( pos : Vec3 , seed : Numeric Int(0) , range_fn : String String(euclidean) , return_type : String String(distance) ) : Float
Samples 3D Worley noise at a given position using default parameters
Arguments:
  • pos : Vec3
  • seed : Numeric Int(0)
  • range_fn : String String(euclidean) - Distance function used to sample the noise. Must be one of the following: "euclidean" (default), "euclidean_squared", "manhattan", "chebyshev", or "quadratic".
  • return_type : String String(distance) - Flag to control whether distances or values are returned. Must be either "distance" (default) or "value".
worley_noise ( pos : Vec2 , seed : Numeric Int(0) , range_fn : String String(euclidean) , return_type : String String(distance) ) : Float
Samples 2D Worley noise at a given position using the specified parameters
Arguments:
  • pos : Vec2
  • seed : Numeric Int(0)
  • range_fn : String String(euclidean) - Distance function used to sample the noise. Must be one of the following: "euclidean" (default), "euclidean_squared", "manhattan", "chebyshev", or "quadratic".
  • return_type : String String(distance) - Flag to control whether distances or values are returned. Must be either "distance" (default) or "value".

seq

all

all ( cb : Callable , sequence : Sequence ) : Bool
Returns true if all elements of the sequence make the callback return true
Arguments:
  • cb : Callable - Callable with signature `|x|: bool`
  • sequence : Sequence

any

any ( cb : Callable , sequence : Sequence ) : Bool
Returns true if any element of the sequence makes the callback return true
Arguments:
  • cb : Callable - Callable with signature `|x|: bool`
  • sequence : Sequence

append

alias: push
append ( val : Any , seq : Sequence ) : Sequence
Appends a value to the end of a sequence, returning a new sequence. The old sequence is left unchanged. If the sequence is not eager (as produced by the `collect` function, an array literal, or similar), it will be collected into memory before this happens. Note that this isn't very efficient and requires collecting and/or cloning the underlying sequence. It's better to keep things lazy and use sequences and sequence combinators where possible.
Arguments:
  • val : Any - The value to add to the end of the sequence
  • seq : Sequence - The sequence to which the value should be added

chain

chain ( sequences : Sequence ) : Sequence
Returns a new sequence that concatenates all input sequences. This is lazy and will not evaluate the sequences until the output sequence is consumed.
Arguments:
  • sequences : Sequence - Sequence of sequences to chain together

collect

collect ( sequence : Sequence ) : Sequence
Makes the sequence eager, collecting all elements into memory. This will allow the sequence to indexed with `[]`.
Arguments:
  • sequence : Sequence

filter

filter ( fn : Callable , sequence : Sequence ) : Sequence
Filters a sequence using a predicate function. This is lazy and will not evaluate the function until the output sequence is consumed.
Arguments:
  • fn : Callable - Callable with signature `|x: T, ix: int|: bool`
  • sequence : Sequence - Sequence to filter

first

first ( sequence : Sequence ) : Any
Returns the first element of a sequence, or `Nil` if the sequence is empty.
Arguments:
  • sequence : Sequence

flatten

flatten ( sequence : Sequence ) : Sequence
Flattens a sequence of sequences into a single sequence. Any non-sequence elements are passed through unchanged. Note that only a single level of flattening is performed.
Arguments:
  • sequence : Sequence

fold

fold ( initial_val : Any , fn : Callable , sequence : Sequence ) : Any
Same as `reduce` but with an explicit initial value
Arguments:
  • initial_val : Any
  • fn : Callable - Callable with signature `|acc, x, i|: acc`
  • sequence : Sequence

fold_while

fold_while ( initial_val : Any , fn : Callable , sequence : Sequence ) : Any
Same as `fold` but with the option early-exiting. If the provided callback returns `nil`, the final state of the accumulator passed into that iteration will be returned.
Arguments:
  • initial_val : Any
  • fn : Callable - Callable with signature `|acc, x, i|: acc | nil`. If this callback returns `nil`, the final state of the accumulator passed into that iteration will be returned.
  • sequence : Sequence

for_each

for_each ( cb : Callable , sequence : Sequence ) : Nil
Applies the callback to each element of the sequence, returning `nil`. This is useful for running side effects.
Arguments:
  • cb : Callable - Callable with signature `|x|`
  • sequence : Sequence

last

last ( sequence : Sequence ) : Any
Returns the last element of a sequence, or `Nil` if the sequence is empty.
Arguments:
  • sequence : Sequence

map

map ( fn : Callable , sequence : Sequence ) : Sequence
Applies a function to each element of a sequence and returns a new sequence. This is lazy and will not evaluate the function until the output sequence is consumed.
Arguments:
  • fn : Callable - Callable with signature `|x: T, ix: int|: y`
  • sequence : Sequence - Sequence to map over
map ( fn : Callable , mesh : Mesh ) : Mesh
Applies a function to each vertex in a mesh and returns a new mesh with the transformed vertices.
Arguments:
  • fn : Callable - Callable with signature `|vtx: Vec3, normal: Vec3|: Vec3` that will be invoked for each vertex in the new mesh, returning a new position for that vertex An optional trailing parameter must be a destructured attribute bag naming the per-vertex data to read, e.g. `|pos, normal, {uv, color, ix}|`: any attribute on the mesh (see `set_attr`), plus `ix` (vertex index in `verts` order), `pos`, and `normal`. Only the named keys are read, so omitting the bag costs nothing.
  • mesh : Mesh
map ( fn : Callable , texture : Texture ) : Texture
Applies a function to each pixel of a texture and returns a new texture with the same dimensions and wrap mode.
Arguments:
  • fn : Callable - Callable with signature `|val: float|vec2|vec3|vec4, uv: vec2, x_ix: int, y_ix: int|: float | vec2 | vec3 | vec4`, invoked once per pixel. `val`'s type matches the input's channel count; the return type sets the output's channel count.
  • texture : Texture

reduce

reduce ( fn : Callable , sequence : Sequence ) : Any
Same as `fold` but with the first element of the sequence as the initial value
Arguments:
  • fn : Callable - Callable with signature `|acc, x, i|: acc`
  • sequence : Sequence - Sequence to reduce

reverse

reverse ( sequence : Sequence ) : Sequence
Returns a new sequence with the elements in reverse order. This is NOT lazy and will evaluate the entire sequence immediately and collect all of its elements into memory.
Arguments:
  • sequence : Sequence
reverse ( path : Path ) : Path
Reverses a path's direction: `t` runs the other way, subpath order and every segment flip.
Arguments:
  • path : Path - The path to operate on; pen ops take it last so they can be chained with `|`.

scan

Example
build_smooth_path = |smoothing: num| { // this is essentially applying a low-pass filter dirs = scan( initial=normalize(randv(-1, 1)), fn=|acc, _| { new_dir = mix(1 - smoothing, acc, randv(-1, 1)) normalize(new_dir) }, sequence=0..100 ) scan( initial=vec3(0), fn=|pos, dir| pos + dir, sequence=dirs ) } smooth_path = build_smooth_path(0.75) random_path = build_smooth_path(0) smooth_path | extrude_pipe(radius=0.2, resolution=8) | set_material('red') | render random_path | extrude_pipe(radius=0.2, resolution=8) | set_material('blue') | render
scan ( initial : Any , fn : Callable , sequence : Sequence ) : Sequence
Applies a function cumulatively to the elements of a sequence, returning a new sequence of intermediate results. Similar to the `Iterator::scan` function from Rust, but with a little less freedom in the way it can be used. This is lazy and will not evaluate the function until the output sequence is consumed. NOTE: This function may be subject to change in the future. It would be much better for it to return a tuple to allow de-coupling output sequence values from the retained state.
Arguments:
  • initial : Any - Initial value to seed the state with. This value will NOT be included in the output sequence.
  • fn : Callable - Callable with signature `|acc, x, ix|: acc`
  • sequence : Sequence - Sequence to scan

skip

skip ( count : Numeric , sequence : Sequence ) : Sequence
Returns a new sequence with the first `n` elements skipped. If `n` is greater than the length of the sequence, an empty sequence is returned. This is lazy and will not evaluate the sequence until the output sequence is consumed.
Arguments:
  • count : Numeric - Number of elements to skip from the start of the sequence
  • sequence : Sequence - Sequence to skip elements from

skip_while

skip_while ( fn : Callable , sequence : Sequence ) : Sequence
Returns a new sequence with elements skipped from the start of the input sequence until the predicate function returns false. This is lazy and will not evaluate the function until the output sequence is consumed.
Arguments:
  • fn : Callable - Callable with signature `|x|: bool`
  • sequence : Sequence

sort

sort ( sequence : Sequence , by : Callable | Nil Nil , stable : Bool Bool(false) , desc : Bool Bool(false) ) : Sequence
Sorts a sequence by key in ascending order. Ints and floats compare with each other numerically; mixing any other key kinds is an error. The key function is called once per element. This is NOT lazy and will evaluate the entire sequence immediately and collect all of its elements into memory.
Arguments:
  • sequence : Sequence
  • by : Callable | Nil Nil - Key function with signature `|x: T, ix: int|: K`, where `K` is an int, float, string, bool, or a list of those (compared element-wise, so `[primary, secondary]` sorts on multiple keys). Elements are used as their own keys if omitted.
  • stable : Bool Bool(false) - If true, elements with equal keys keep their original relative order
  • desc : Bool Bool(false) - Sort in descending order

take

take ( count : Numeric , sequence : Sequence ) : Sequence
Returns a new sequence containing the first `n` elements of the input sequence. If `n` is greater than the length of the sequence, the entire sequence is returned. This is lazy and will not evaluate the sequence until the output sequence is consumed.
Arguments:
  • count : Numeric - Number of elements to take from the start of the sequence
  • sequence : Sequence - Sequence to take elements from

take_while

take_while ( fn : Callable , sequence : Sequence ) : Sequence
Returns a new sequence containing elements from the start of the input sequence until the predicate function returns false. This is lazy and will not evaluate the function until the output sequence is consumed.
Arguments:
  • fn : Callable - Callable with signature `|x|: bool`
  • sequence : Sequence - Sequence to take elements from

str

chars

chars ( s : String ) : Sequence
Returns a sequence of the unicode characters in a string
Arguments:
  • s : String

texture

blit

blit ( stamp : Texture , base : Texture , blend : String String(over) , filter : String String(bilinear) ) : Texture
Draws `stamp` into `base` at the placement carried by the stamp's transform (see `trans`/`rot`/`scale` on textures), returning a new texture. The base's own transform and wrap mode are preserved on the result.
Arguments:
  • stamp : Texture - Texture to draw; its transform places its centered [-0.5, 0.5]² local frame in the base's UV space. Sampled with decal semantics — its own wrap mode is ignored and outside its bounds contributes nothing.
  • base : Texture - Texture to draw into. Writes follow ITS wrap mode: "repeat" wraps the stamp's footprint around edges (preserving seamless tiling); "clamp"/"mirror" clip.
  • blend : String String(over) - One of "over", "add", "sub", "mul", "max", "min". A stamp alpha channel (4-channel always; 2-channel onto a 1-channel base) modulates any mode — "over" then alpha-composites like a sprite. Without an alpha channel "over" replaces the full stamp quad, so give heightfield stamps a `v2(height, alpha)` shape rather than bare floats.
  • filter : String String(bilinear) - "bilinear" (default; trilinear mip prefiltering kicks in when minified) or "nearest" (raw texels, no prefiltering)

blur

blur ( radius : Numeric , texture : Texture ) : Texture
Gaussian-blurs a texture (all channels), respecting its wrap mode at the boundaries
Arguments:
  • radius : Numeric - Gaussian standard deviation in pixels. <= 0 returns the input unchanged.
  • texture : Texture

composite

composite ( top : Texture , bottom : Texture , blend : String String(over) ) : Texture
Per-pixel composite of two same-size textures: texel (x, y) of `top` over texel (x, y) of `bottom`, returning a new texture. This is the whole-image counterpart to `blit`, which places a stamp by its transform and resamples — `composite` has no placement, does no filtering, and needs no `trans_global(0.5, 0.5)` to cover.
Arguments:
  • top : Texture - Texture to composite on top. Must match `bottom`'s dimensions; its transform and wrap mode are ignored.
  • bottom : Texture - Texture to composite onto. Its transform, wrap mode, and GPU params are preserved on the result.
  • blend : String String(over) - One of "over", "add", "sub", "mul", "max", "min". A `top` alpha channel (4-channel always; 2-channel onto a 1-channel bottom) modulates any mode.

concat_channels

concat_channels ( a : Texture | Numeric , b : Texture | Numeric , c : Texture | Numeric , d : Texture | Numeric ) : Texture
Joins the channels of several same-sized textures into one texture, in argument order (numpy `concatenate(axis=-1)`). A numeric argument contributes one channel filled with that constant. At least one argument must be a texture; it fixes the output dims, wrap mode, and placement transform. Total channels must be <= 4. The idiom for compositing with a mask sourced from an unrelated texture: `concat_channels(rgb, mask)` builds an RGBA stamp for `blit`.
Arguments:
  • a : Texture | Numeric - Texture whose channels are appended in order, or a constant filling a single channel
  • b : Texture | Numeric - Texture whose channels are appended in order, or a constant filling a single channel
  • c : Texture | Numeric - Texture whose channels are appended in order, or a constant filling a single channel
  • d : Texture | Numeric - Texture whose channels are appended in order, or a constant filling a single channel
concat_channels ( a : Texture | Numeric , b : Texture | Numeric , c : Texture | Numeric ) : Texture
Joins the channels of several same-sized textures into one texture, in argument order (numpy `concatenate(axis=-1)`). A numeric argument contributes one channel filled with that constant. At least one argument must be a texture; it fixes the output dims, wrap mode, and placement transform. Total channels must be <= 4. The idiom for compositing with a mask sourced from an unrelated texture: `concat_channels(rgb, mask)` builds an RGBA stamp for `blit`.
Arguments:
  • a : Texture | Numeric - Texture whose channels are appended in order, or a constant filling a single channel
  • b : Texture | Numeric - Texture whose channels are appended in order, or a constant filling a single channel
  • c : Texture | Numeric - Texture whose channels are appended in order, or a constant filling a single channel
concat_channels ( a : Texture | Numeric , b : Texture | Numeric ) : Texture
Joins the channels of several same-sized textures into one texture, in argument order (numpy `concatenate(axis=-1)`). A numeric argument contributes one channel filled with that constant. At least one argument must be a texture; it fixes the output dims, wrap mode, and placement transform. Total channels must be <= 4. The idiom for compositing with a mask sourced from an unrelated texture: `concat_channels(rgb, mask)` builds an RGBA stamp for `blit`.
Arguments:
  • a : Texture | Numeric - Texture whose channels are appended in order, or a constant filling a single channel
  • b : Texture | Numeric - Texture whose channels are appended in order, or a constant filling a single channel

crop

crop ( x : Numeric , y : Numeric , w : Numeric , h : Numeric , texture : Texture ) : Texture
O(1) rectangular crop view; no pixels are copied. Equivalent to `t[y..y+h, x..x+w]`. `wrap` applies in view space, so a repeat-wrapped crop tiles the crop.
Arguments:
  • x : Numeric - Left edge of the crop, in pixels
  • y : Numeric - Top edge of the crop, in pixels
  • w : Numeric - Crop width in pixels; must be >= 1 and fit within the texture
  • h : Numeric - Crop height in pixels; must be >= 1 and fit within the texture
  • texture : Texture

dilate

dilate ( radius : Numeric , texture : Texture ) : Texture
Morphological dilation (per-channel running max over a box window), wrap-aware at boundaries. O(1) per pixel at any radius.
Arguments:
  • radius : Numeric - Box structuring-element radius in pixels; the window is (2r+1)x(2r+1). <= 0 returns the input unchanged.
  • texture : Texture

erode

erode ( radius : Numeric , texture : Texture ) : Texture
Morphological erosion (per-channel running min over a box window), wrap-aware at boundaries. O(1) per pixel at any radius.
Arguments:
  • radius : Numeric - Box structuring-element radius in pixels; the window is (2r+1)x(2r+1). <= 0 returns the input unchanged.
  • texture : Texture

flip_x

flip_x ( texture : Texture ) : Texture
Mirrors a texture horizontally. O(1): returns a view of the same pixel data.
Arguments:
  • texture : Texture

flip_y

flip_y ( texture : Texture ) : Texture
Mirrors a texture vertically. O(1): returns a view of the same pixel data.
Arguments:
  • texture : Texture

height_to_normal

height_to_normal ( texture : Texture ) : Texture
Generates a 3-channel tangent-space normal map (OpenGL convention, encoded 0-1) from a heightmap via wrap-aware central differences
Arguments:
  • texture : Texture - Heightmap; channel 0 is read as the height
height_to_normal ( strength : Numeric , texture : Texture ) : Texture
Generates a 3-channel tangent-space normal map (OpenGL convention, encoded 0-1) from a heightmap via wrap-aware central differences
Arguments:
  • strength : Numeric - Scale applied to the height gradient (height units per texel)
  • texture : Texture - Heightmap; channel 0 is read as the height

input_image_levels

input_image_levels ( name : String , texture : Texture , default : Map | Nil Nil , label : String Nil ) : Texture
An interactively-editable levels adjustment (`texture_levels` with UI-configured params over a histogram); returns the adjusted texture.
Arguments:
  • name : String - Stable control id, scoped to the node. Also the default panel label.
  • texture : Texture - Input texture; also sources the histogram shown behind the control. Put this downstream of expensive synthesis so scrubbing stays cheap.
  • default : Map | Nil Nil - Optional map with any of the keys in_lo/in_hi/out_lo/out_hi/gamma; missing keys use identity values.
  • label : String Nil - Display label override; defaults to `name`.

load_image

load_image ( uri : String , srgb : Bool Bool(true) , scale : Numeric Float(1) , offset : Numeric Float(0) , channels : Nil | Numeric Nil ) : Texture
Decodes an embedded base64 image into a float texture (wrap=repeat). The image-decode dependency loads lazily on first use.
Arguments:
  • uri : String - `data:image/...;base64,...` data URI. Decoded host-side in the browser; PNG is the canonical format.
  • srgb : Bool Bool(true) - Decode sRGB-encoded color channels to linear (the convention for color images). Pass false for data images (heightmaps, texton kernels, masks) whose bytes are raw values. Alpha is never sRGB-decoded.
  • scale : Numeric Float(1) - Multiplier applied to every non-alpha channel after decode (decode yields [0, 1])
  • offset : Numeric Float(0) - Added to every non-alpha channel after `scale`
  • channels : Nil | Numeric Nil - Force the output channel count (1, 3, or 4). Default auto-detects: 4 if any alpha < 1, 1 if fully gray, else 3.

materialize

materialize ( texture : Texture ) : Texture
Copies a strided texture view (crop/swizzle/flip) into dense storage; no-op on already-dense textures. A perf hint only — every op accepts views directly.
Arguments:
  • texture : Texture

morph_blackhat

morph_blackhat ( radius : Numeric , texture : Texture ) : Texture
Black top-hat (`morph_close(t) - t`): isolates dark features smaller than the structuring element.
Arguments:
  • radius : Numeric - Box structuring-element radius in pixels; the window is (2r+1)x(2r+1). <= 0 is a no-op for `morph_open`/`morph_close` and yields an all-zero result for the difference forms.
  • texture : Texture

morph_close

morph_close ( radius : Numeric , texture : Texture ) : Texture
Morphological closing (dilate then erode): fills dark pinholes and gaps smaller than the structuring element. Dual of `morph_open`.
Arguments:
  • radius : Numeric - Box structuring-element radius in pixels; the window is (2r+1)x(2r+1). <= 0 is a no-op for `morph_open`/`morph_close` and yields an all-zero result for the difference forms.
  • texture : Texture

morph_open

morph_open ( radius : Numeric , texture : Texture ) : Texture
Morphological opening (erode then dilate): removes bright specks smaller than the structuring element, leaving larger shapes at their original size.
Arguments:
  • radius : Numeric - Box structuring-element radius in pixels; the window is (2r+1)x(2r+1). <= 0 is a no-op for `morph_open`/`morph_close` and yields an all-zero result for the difference forms.
  • texture : Texture

morph_outline

morph_outline ( radius : Numeric , texture : Texture ) : Texture
Morphological gradient (`dilate - erode`): a band straddling every edge, 2r+1 px wide.
Arguments:
  • radius : Numeric - Box structuring-element radius in pixels; the window is (2r+1)x(2r+1). <= 0 is a no-op for `morph_open`/`morph_close` and yields an all-zero result for the difference forms.
  • texture : Texture

morph_tophat

morph_tophat ( radius : Numeric , texture : Texture ) : Texture
White top-hat (`t - morph_open(t)`): isolates bright features smaller than the structuring element.
Arguments:
  • radius : Numeric - Box structuring-element radius in pixels; the window is (2r+1)x(2r+1). <= 0 is a no-op for `morph_open`/`morph_close` and yields an all-zero result for the difference forms.
  • texture : Texture

path_sdf

path_sdf ( path : Path , width : Numeric Int(256) , height : Numeric Int(256) , fill_rule : String | Nil | Numeric Nil , tileable : Bool | Numeric Bool(false) , wrap : String String(repeat) , curve_angle_degrees : Nil | Numeric Nil ) : Texture
Signed distance field of a 2D path as a 1-channel texture sampled at texel centers. Distance is to the drawn curve in path units (the same units as `offset_path` deltas, so `path_sdf(p) < r` agrees with `rasterize_path(offset_path(r, p))`). Negative inside closed subpaths under `fill_rule`; open subpaths contribute unsigned distance only. Self-overlapping shapes keep interior seams in the field; run `path_union(p, p)` first for distance to the filled boundary. Distance fields compose exactly with `min`/`max` and `blit(..., blend="min")`; threshold once at the end (`smoothstep` with a texel-sized ramp for anti-aliasing).
Arguments:
  • path : Path - A path. Path space maps onto the texture's [0,1]² UV space; place it with `translate`/`scale`/`rot` on the path.
  • width : Numeric Int(256) - Output width in texels
  • height : Numeric Int(256) - Output height in texels
  • fill_rule : String | Nil | Numeric Nil - Fill rule for determining path interiors: evenodd, nonzero, positive, negative (or numeric enum 0-3). Defaults to the path's own fill rule, else `nonzero`.
  • tileable : Bool | Numeric Bool(false) - `true` tiles seamlessly with period 1 in path units (the texture's UV extent); a number tiles with that period. The path is replicated at every period offset before rasterizing, so shapes crossing the texture edge wrap around and distances/`t` are measured to the nearest copy.
  • wrap : String String(repeat) - Boundary behavior consulted by texture ops: "repeat" (seamless/toroidal, the default), "clamp", or "mirror"
  • curve_angle_degrees : Nil | Numeric Nil - Max turning angle (degrees) per segment when discretizing curves. When nil, curves are instead flattened to within 0.05 texels of the true curve (and at most 12° per segment), which is usually far fewer segments than the ambient 1° setting.

path_uv

path_uv ( path : Path , width : Numeric Int(256) , height : Numeric Int(256) , local_t : Bool Bool(false) , tileable : Bool | Numeric Bool(false) , wrap : String String(repeat) , curve_angle_degrees : Nil | Numeric Nil ) : Texture
Along/across parameterization of a 2D path as a 2-channel `(t, n)` texture. `t` is the arc-length parameter of the nearest point on the path, global across all subpaths (as used by `path_frame` / `trim_path`) or per-subpath with `local_t=true`; `n` is the signed distance along the `path_frame` normal there: left of travel for open subpaths, inward for closed ones (so `n > 0` inside a closed shape while `path_sdf` is negative). The 2D analog of `rail_sweep` UVs: stitches via `fract(t * count)` masked by `abs(n) < w`, gradients along a curve via a ramp on `t`. `t` jumps across the medial axis (texels equidistant from two parts of the path); that discontinuity is inherent to nearest-point parameterization.
Arguments:
  • path : Path - A path. Path space maps onto the texture's [0,1]² UV space; place it with `translate`/`scale`/`rot` on the path.
  • width : Numeric Int(256) - Output width in texels
  • height : Numeric Int(256) - Output height in texels
  • local_t : Bool Bool(false) - When true, `t` runs over `[0, 1]` separately along every subpath (each ring/stroke gets a full lap) instead of each subpath owning a slice of the global `[0, 1]` proportional to its share of the total length. Use it for effects that must wrap seamlessly around every loop, e.g. `cos(t * 2 * pi)` on concentric rings.
  • tileable : Bool | Numeric Bool(false) - `true` tiles seamlessly with period 1 in path units (the texture's UV extent); a number tiles with that period. The path is replicated at every period offset before rasterizing, so shapes crossing the texture edge wrap around and distances/`t` are measured to the nearest copy.
  • wrap : String String(repeat) - Boundary behavior consulted by texture ops: "repeat" (seamless/toroidal, the default), "clamp", or "mirror"
  • curve_angle_degrees : Nil | Numeric Nil - Max turning angle (degrees) per segment when discretizing curves. When nil, curves are instead flattened to within 0.05 texels of the true curve (and at most 12° per segment), which is usually far fewer segments than the ambient 1° setting.

rasterize_path

rasterize_path ( path : Path , width : Numeric Int(256) , height : Numeric Int(256) , fill_rule : String | Nil | Numeric Nil , tileable : Bool | Numeric Bool(false) , wrap : String String(repeat) , curve_angle_degrees : Nil | Numeric Nil ) : Texture
Rasterizes a 2D path into a 1-channel anti-aliased coverage texture: each texel holds the fraction of its area inside the fill under `fill_rule`, so edge texels get partial values. Follows SVG fill semantics: open subpaths are implicitly closed. For strokes, threshold `abs(path_sdf(p))` (round joins/caps) or fill `offset_path(w/2, p)` (exact joins/caps). The result is an ordinary texture: blit it, scatter it, use it as a mask.
Arguments:
  • path : Path - A path. Path space maps onto the texture's [0,1]² UV space; place it with `translate`/`scale`/`rot` on the path.
  • width : Numeric Int(256) - Output width in texels
  • height : Numeric Int(256) - Output height in texels
  • fill_rule : String | Nil | Numeric Nil - Fill rule for determining path interiors: evenodd, nonzero, positive, negative (or numeric enum 0-3). Defaults to the path's own fill rule, else `nonzero`.
  • tileable : Bool | Numeric Bool(false) - `true` tiles seamlessly with period 1 in path units (the texture's UV extent); a number tiles with that period. The path is replicated at every period offset before rasterizing, so shapes crossing the texture edge wrap around and distances/`t` are measured to the nearest copy.
  • wrap : String String(repeat) - Boundary behavior consulted by texture ops: "repeat" (seamless/toroidal, the default), "clamp", or "mirror"
  • curve_angle_degrees : Nil | Numeric Nil - Max turning angle (degrees) per segment when discretizing curves. When nil, curves are instead flattened to within 0.05 texels of the true curve (and at most 12° per segment), which is usually far fewer segments than the ambient 1° setting.

render_texture

render_texture ( texture : Texture , name : String String(default) , usage : String | Nil Nil ) : Nil
Registers a texture as a named output of the composition, symmetric to `render` for meshes
Arguments:
  • texture : Texture
  • name : String String(default) - Output channel name this texture is published under
  • usage : String | Nil Nil - Semantic role of this output: one of "albedo", "normal", "roughness", "height", "metalness", "ao", "mask". Drives colorspace handling and preview auto-binding in consumers.

render_texture_stack

render_texture_stack ( slices : Sequence , name : String String(default) , usage : String | Nil Nil ) : Nil
Registers an ordered set of texture slices as a named stack output of the composition. Consumers sample it as a texture array, interpolating adjacent slices by a per-fragment index t in [0,1].
Arguments:
  • slices : Sequence - Seq of 2-256 textures with matching dims/channels/wrap, interpolated by a normalized index t in [0,1] at render time (slice 0 at t=0, last at t=1)
  • name : String String(default) - Output channel name this stack is published under
  • usage : String | Nil Nil - Semantic role of this output: one of "albedo", "normal", "roughness", "height", "metalness", "ao", "mask". Drives colorspace handling and preview auto-binding in consumers.

resize

resize ( width : Numeric , height : Numeric , texture : Texture , filter : String String(mitchell) ) : Texture
Resamples a texture to new dimensions via a separable filter. Downsampling is area-correct (the kernel widens with the minification ratio); boundaries respect the texture's wrap mode.
Arguments:
  • width : Numeric - Output width in pixels
  • height : Numeric - Output height in pixels
  • texture : Texture
  • filter : String String(mitchell) - "nearest", "box", "triangle", "mitchell" (the default), or "lanczos3"

sample

sample ( texture : Texture , uv : Vec2 , filter : String String(bilinear) , wrap : String | Nil Nil ) : Float |Vec2 |Vec3 |Vec4
Reads one texel-space value from a texture at a continuous coordinate, like a GPU texture fetch: returns a float for 1-channel textures, vec2/vec3/vec4 otherwise. All channels are filtered independently (no alpha premultiplication). The main use is inside texel closures, where it is the gather primitive that expresses warps, stretches, offsets, displacement maps, polar remaps, and so on: `texture(w, h, |uv| sample(src, uv + v2(.05 * sin(uv.y * tau), 0.)))`. Such bodies auto-vectorize into a single gather pass over the coordinate field. The output stays tileable whenever the coordinate function is periodic up to whole-texture translations. Coordinates are floats, so exact pixel-index gathers are written as `sample(src, (v2(x, y) + .5) / dims, filter="nearest")`.
Arguments:
  • texture : Texture
  • uv : Vec2 - Continuous coordinate in the same space as texel-closure `uv` params: texel (x, y) is centered at `((x + 0.5) / w, (y + 0.5) / h)`. Any value; out-of-range coordinates resolve through the wrap mode.
  • filter : String String(bilinear) - "bilinear" (the default) or "nearest". Nearest is an exact texel pick (`floor(uv * dims)`), so integer-stepped coordinates gather pixels without any blending.
  • wrap : String | Nil Nil - "repeat", "clamp", or "mirror"; defaults to the texture's own wrap mode

scatter

scatter ( count : Numeric , stamps : Callable , base : Texture , blend : String String(over) , filter : String String(bilinear) ) : Texture
Blits `count` generated stamp instances into `base` (instance order = blend order), returning a new texture. Equivalent to folding `blit` over the generated stamps, but with a single pixel-buffer copy.
Arguments:
  • count : Numeric - Number of instances to generate and blit
  • stamps : Callable - Generator callable `|ix: int|: texture` returning a PLACED texture for each instance (position/rotation/scale via the texture transform ops). Invoked once per instance in order.
  • base : Texture - Texture the instances are blitted into
  • blend : String String(over) - One of "over", "add", "sub", "mul", "max", "min". A stamp alpha channel (4-channel always; 2-channel onto a 1-channel base) modulates any mode — "over" then alpha-composites like a sprite. Without an alpha channel "over" replaces the full stamp quad, so give heightfield stamps a `v2(height, alpha)` shape rather than bare floats.
  • filter : String String(bilinear) - "bilinear" or "nearest"
scatter ( stamps : Sequence , base : Texture , blend : String String(over) , filter : String String(bilinear) ) : Texture
Blits each placed texture in `stamps` into `base` in sequence order, returning a new texture.
Arguments:
  • stamps : Sequence - Sequence of placed textures to blit in order
  • base : Texture - Texture the instances are blitted into
  • blend : String String(over) - One of "over", "add", "sub", "mul", "max", "min". A stamp alpha channel (4-channel always; 2-channel onto a 1-channel base) modulates any mode — "over" then alpha-composites like a sprite. Without an alpha channel "over" replaces the full stamp quad, so give heightfield stamps a `v2(height, alpha)` shape rather than bare floats.
  • filter : String String(bilinear) - "bilinear" or "nearest"

sharpen

sharpen ( texture : Texture , amt : Numeric Float(0.5) , sigma : Numeric Float(2) ) : Texture
Unsharp mask: `t + (t - blur(sigma, t)) * amt`. The texture is the first arg so pipelines partially apply: `t | sharpen(amt=0.3)`.
Arguments:
  • texture : Texture
  • amt : Numeric Float(0.5) - Strength of the re-added high-frequency detail. 0 is a no-op; negative values soften.
  • sigma : Numeric Float(2) - Gaussian radius of the blur subtracted to isolate detail; larger picks up coarser features.

spectral_noise

spectral_noise ( bands : Sequence , kernels : Sequence | Nil Nil , width : Numeric Int(256) , height : Numeric Int(256) , seed : Numeric Int(0) , freq_scale : Numeric Float(1) , distribution : String String(gaussian) ) : Texture
Synthesizes a seamless 1-channel Gaussian noise texture from a compact spectral fingerprint (as produced by the texture-utils noise-signature extractor). Params are size-independent: any power-of-two output size yields the same texture statistics.
Arguments:
  • bands : Sequence - 8 rows of 4 floats: log-polar spectrum gains, radial bands (low->high frequency, log-spaced over cycles/pixel [1/256, 0.5]) x angular sectors. Each value is a log-power gain relative to the loudest cell, in [-14, 0] nats (0 = loudest, -14 = silent).
  • kernels : Sequence | Nil Nil - Optional spectral peaks; each is [f0y, f0x, sig1, sig2, angle, energy], all floats: f0 in cycles/pixel [-0.5, 0.5]; sig1/sig2 = log10 of the peak's spectral widths, in [-3, -0.5]; angle in radians [0, pi]; energy = log10 of the peak's energy relative to the band spectrum, in [-4, 2].
  • width : Numeric Int(256) - Output width in pixels; power of two (FFT synthesis)
  • height : Numeric Int(256) - Output height in pixels; power of two (FFT synthesis)
  • seed : Numeric Int(0) - Noise instance seed; same params + seed + size -> identical texture. Different seeds are independent instances of the same texture, suitable for equal-power crossfade morphing.
  • freq_scale : Numeric Float(1) - Scales all model frequencies (>1 = finer detail) without changing the fingerprint; [0.125, 8]
  • distribution : String String(gaussian) - "gaussian" (default): standardized field, mean 0 / std 1 — the form that composes linearly (equal-power seed crossfades stay exact); pair with z-score ramp stop positions. "uniform": values remapped to uniform [0, 1] via the Gaussian CDF, for direct use as a mask/height.

texture

texture ( width : Numeric , height : Numeric , generator : Callable , wrap : String String(repeat) ) : Texture
Synthesizes a new texture by evaluating `generator` at every pixel
Arguments:
  • width : Numeric - Width in pixels
  • height : Numeric - Height in pixels
  • generator : Callable - Callable of signature `|uv: vec2, x_ix: int, y_ix: int|: float | vec2 | vec3 | vec4`, invoked once per pixel at the pixel's center UV; `x_ix`/`y_ix` are absolute pixel indices and may be omitted from the closure's params. The return type sets the channel count (float -> 1, vec2 -> 2, vec3 -> 3, vec4 -> 4/RGBA).
  • wrap : String String(repeat) - Boundary behavior consulted by texture ops: "repeat" (seamless/toroidal, the default), "clamp", or "mirror"

texture_equalize

texture_equalize ( texture : Texture ) : Texture
Per-channel histogram equalization: maps each value to its empirical CDF, so the output is uniformly distributed on [0, 1] whatever the input's distribution (min -> 0, median -> 0.5, max -> 1). Thresholding the result at `p` covers exactly `1 - p` of the pixels.
Arguments:
  • texture : Texture

texture_invert

texture_invert ( texture : Texture ) : Texture
Inverts every channel (`1 - x`), alpha included.
Arguments:
  • texture : Texture

texture_levels

texture_levels ( in_lo : Numeric , in_hi : Numeric , out_lo : Numeric , out_hi : Numeric , gamma : Numeric , texture : Texture ) : Texture
Photoshop-style levels: `out_lo + (out_hi - out_lo) * clamp((x - in_lo) / (in_hi - in_lo), 0, 1)^(1/gamma)` on color channels; alpha is preserved on 4-channel textures.
Arguments:
  • in_lo : Numeric - Input black point
  • in_hi : Numeric - Input white point
  • out_lo : Numeric - Output level for the black point (swap with `out_hi` to invert)
  • out_hi : Numeric - Output level for the white point
  • gamma : Numeric - Midtone gamma; > 1 brightens midtones, < 1 darkens
  • texture : Texture

texture_max

texture_max ( texture : Texture ) : Float |Vec2 |Vec3 |Vec4
Per-channel maximum over all pixels; returns a float for 1-channel textures, vec2/vec3/vec4 otherwise
Arguments:
  • texture : Texture

texture_mean

texture_mean ( texture : Texture ) : Float |Vec2 |Vec3 |Vec4
Per-channel mean over all pixels; returns a float for 1-channel textures, vec2/vec3/vec4 otherwise
Arguments:
  • texture : Texture

texture_min

texture_min ( texture : Texture ) : Float |Vec2 |Vec3 |Vec4
Per-channel minimum over all pixels; returns a float for 1-channel textures, vec2/vec3/vec4 otherwise
Arguments:
  • texture : Texture

texture_normalize

texture_normalize ( texture : Texture , sigmas : Vec2 | Sequence | Nil | Numeric Nil ) : Texture
Per-channel linear stretch of a window onto [0, 1], clamped: by default the exact [min, max] (a constant channel maps to 0), or a mean/std-relative window via `sigmas`. Useful ahead of `texture_levels` / `input_image_levels` when a synthesis step's output range is unknown; see `texture_standardize` / `texture_equalize` for the other normal forms.
Arguments:
  • texture : Texture
  • sigmas : Vec2 | Sequence | Nil | Numeric Nil - Window to stretch instead of the exact [min, max]: a number `k` maps `mean ± k*std` to [0, 1] (2.5 covers ~99% of a Gaussian field; the tails clip instead of washing out the contrast), or a signed `[lo, hi]` pair of z-positions (`[0., 2.]` maps `mean..mean + 2*std`, everything below the mean to 0).

texture_quantile

texture_quantile ( texture : Texture , q : Numeric ) : Float |Vec2 |Vec3 |Vec4
Per-channel value at quantile `q` (e.g. `texture_quantile(t, 0.7)` is the threshold above which 30% of pixels lie); returns a float for 1-channel textures, vec2/vec3/vec4 otherwise. Exact for textures up to 64k pixels, estimated from a 64k stride-sample above that.
Arguments:
  • texture : Texture
  • q : Numeric - Quantile in [0, 1]: 0 = min, 0.5 = median, 1 = max

texture_roll

texture_roll ( dx : Numeric , dy : Numeric , texture : Texture ) : Texture
Circularly shifts a texture by whole pixels: `out[x, y] = in[(x - dx) mod w, (y - dy) mod h]`. Always toroidal regardless of the texture's wrap mode; exact (no resampling). For fractional or per-pixel offsets use `sample`.
Arguments:
  • dx : Numeric - Horizontal shift in pixels; positive moves content toward +x (right). Any int; taken modulo the width.
  • dy : Numeric - Vertical shift in pixels; positive moves content toward +y (down). Any int; taken modulo the height.
  • texture : Texture

texture_standardize

texture_standardize ( texture : Texture ) : Texture
Per-channel `(x - mean) / std`, so every channel has mean 0 and std 1 (the convention `spectral_noise` emits; makes any roughly-Gaussian field interchangeable with it and usable with z-score ramp stops). A constant channel maps to 0.
Arguments:
  • texture : Texture

texture_std

texture_std ( texture : Texture ) : Float |Vec2 |Vec3 |Vec4
Per-channel population standard deviation over all pixels; returns a float for 1-channel textures, vec2/vec3/vec4 otherwise
Arguments:
  • texture : Texture

texture_transpose

texture_transpose ( texture : Texture ) : Texture
Swaps a texture's axes (`out[x, y] = in[y, x]`, so a WxH input yields HxW). O(1): returns a view of the same pixel data. Column-wise versions of row-wise ops come from `transpose | op | transpose`.
Arguments:
  • texture : Texture

texture_zip

texture_zip ( fn : Callable , textures : Sequence ) : Texture
Combines two or more textures into a new one by invoking a callable once per pixel with the corresponding texel of each input. All inputs must have identical dimensions; channel counts are independent. The result inherits its dimensions, wrap mode, transform, filters, and format from the FIRST input; the others contribute pixels only. A single-element seq is allowed and behaves like `map` over that texture. Like `map` over a texture and `texture` generators, the body is auto-vectorized into whole-texture kernel passes when it stays inside the supported set; conditionals lower to an exact per-texel select, so masked/conditional blends are as fast as dedicated builtins would be. Watch the usual fallback triggers: conditional arms must have matching arity, an int arm (`if c { v } else { 0 }`) falls back (write `0.`), and an `if` without `else` or an early `return` falls back.
Arguments:
  • fn : Callable - Callable with signature `|in0, in1, ..., uv: vec2, x_ix: int, y_ix: int|: float | vec2 | vec3 | vec4`, invoked once per pixel. One leading param per input texture, each typed by that texture's channel count (1ch -> float, 2ch -> vec2, ...); channel counts may differ freely between inputs. Trailing params may be omitted. The return type sets the output's channel count.
  • textures : Sequence - Seq of one or more textures with matching dims (channel counts may differ), zipped per-texel and bound to the callable's leading params in order