-
Notifications
You must be signed in to change notification settings - Fork 0
Expressions
← Home · Solarxy Web · Node Reference
Any numeric parameter in Solarxy Web can hold a formula instead of a value. An expression can do arithmetic, call maths functions, read a parameter on another node, and ask questions about the geometry flowing into its own node. The result is recomputed whenever anything it depends on changes.
This turns a graph of independent settings into a graph of relationships: one control drives many, and the ones downstream follow.
Hover a numeric parameter row in the Properties panel. A small =
appears beside the label. Click it and the field becomes a monospace
expression box, seeded with the value that was already there, with the
value it currently resolves to shown underneath.
- Enter or clicking away commits the expression.
- Escape abandons the edit and puts back what was there.
- The
×at the end of the row, or the=toggle again, drops the expression and leaves the parameter holding the value it last resolved to, so turning a formula off does not snap the object back to a default.
If an expression cannot be parsed or evaluated, the field turns red and names the problem, and the node badges with the same message the moment it tries to cook.
Expressions are accepted on Float, Int, Bool, Vec2, Vec3, Vec4 and
Colour parameters. Text, attribute names, menus, file references and node
references stay literal and show no = at all, because there is nothing an
expression could produce for them.
Numbers and arithmetic. + - * / %, unary minus, parentheses,
comparisons (< <= > >= == !=), logic (&& || !), and a ternary
condition ? a : b. Vector values expose .x .y .z .w.
Constants. $PI, $E.
Time. $T (seconds), $F (frame), $FPS, from the scene clock. $T
is exactly $F / $FPS, so there is really one number and seconds is a view
of it. While playback is stopped both read the frame you are parked on, and
a freshly loaded scene always sits at the start of its frame range, so a
saved file reloads to the same picture every time. See
Runtime and playback.
Functions. abs sign floor ceil round min max clamp fit lerp sqrt pow exp log sin cos tan asin acos atan atan2 radians degrees fmod rand noise length distance dot cross normalize set.
set(...) builds a vector: set(1, 2, 3) is a Vec3. rand(seed) and
noise(...) are the same deterministic generators the scatter nodes use,
so a scatter and an expression drawing on the same seed agree, and neither
changes between runs or machines.
ch("path/parameter") reads a parameter somewhere else in the document.
| Form | Reads |
|---|---|
ch("radius") |
another parameter on this same node |
ch("sphere1/radius") |
a node beside this one in the same network |
ch("../scale") |
a parameter on this network's own container |
ch("../geo2/translate") |
a sibling of the container, up in the root |
ch("/geo1/sphere1/radius") |
an absolute path from the root |
The value you get is the one the target shows you: an angle read from a parameter measured in degrees arrives in degrees, and a value that its own parameter would clamp arrives clamped.
Renaming is safe. Rename a node and every expression pointing at it is rewritten to match, in the same undo step as the rename itself. One undo puts both back.
Cycles are refused when you write them, not when they cook. If an expression would make a parameter depend on itself, directly or through a chain, the edit is rejected and the document is left alone.
Inside a node that has geometry plugged into it, an expression can measure that geometry:
| Function | Returns |
|---|---|
npoints() |
point count |
nprims() |
primitive count (triangles, segments or points) |
nmeshes() |
number of meshes |
centroid() |
centre of the bounding box, as a vector |
bbox("size") |
bounding-box size, as a vector |
bbox("center") |
bounding-box centre, as a vector |
bbox("xmin") and friends |
one bound: xmin ymin zmin xmax ymax zmax
|
These read the default geometry input only. A node with several inputs
would otherwise make npoints() ambiguous, and quietly picking the first
one is the kind of rule nobody remembers.
A node with nothing connected does not answer 0. It says the input is not
connected, and the node badges, because 0 is a plausible wrong number and
a wrong number is worse than a stopped cook.
Expressions address nodes by name, so every node now gets a unique,
auto-numbered name when you create it: sphere1, sphere2, transform1.
Renaming to a name already taken in that network appends a number rather
than refusing the edit, so typing is never blocked mid-word.
Uniqueness is per network, not per document. Two different geometry
networks may each hold a sphere1, exactly as two folders may each hold a
readme. Paths resolve relative to where the expression lives.
Scenes saved before this release keep whatever names they had, duplicates included. Nothing is silently rewritten. If an expression cannot tell two same-named nodes apart, the node badges and names the collision, and you rename one.
Drive one box from another, so the second is always twice the first plus a margin:
- Add two boxes. They are named
box1andbox2. - Select
box2, open Geometry, hover Width, click=. - Type
ch("box1/width") * 2 + 1and press Enter.
The readout under the field shows the resolved width. Change box1's
width and box2 follows immediately. Rename box1 to driver and the
expression rewrites itself to ch("driver/width") * 2 + 1.
Expressions are sandboxed by three fixed limits: a maximum source length, a maximum nesting depth, and a maximum number of function calls per evaluation. There are no loops and no user-defined functions, which is what lets those three numbers be the whole safety story rather than a runtime budget.
Expressions are a Solarxy Web feature. The desktop viewer is not wired to the node engine, so it has no parameters to drive.
Solarxy - A cross-platform 3D model viewer, validator and browser-based node modeler built with Rust and wgpu.
GitHub Repository · Releases & Downloads
© 2026 Marko Koljancic · MIT License
Getting Started
Solarxy Web
- Solarxy Web
- Your first scene
- Expressions
- Attribute Wrangle
- Runtime and playback
- Publishing a scene
- Node Reference
Tutorials
Using Solarxy
Reference
Help
Project