Skip to content

Scientific geometry

Marching cubes ​

scenes/marching-cubes
const samples = plot.uploadField(field(96, 10, pair));
const [lo, hi] = plot.fieldRange(samples);
plot.showIsosurface(samples, lo + (hi - lo) * level, [0.85, 0.55, 0.3]);
plot.frameScene();

Calls

4 in the code above, in the order it makes them

plot.uploadField(field: Field): FieldHandle

Upload a scalar field for isosurface extraction.

A separate upload from uploadVolume even for the same numbers, because the two are held differently on the GPU. A caller who wants to see a field both ways uploads it twice.

plot.fieldRange(handle: FieldHandle): [min: number, max: number]

The value range of the field handle names.

What a caller needs before it can pick an isovalue worth looking at. Measured from the data at upload, so it is the range of the field rather than one somebody declared.

plot.showIsosurface(handle: FieldHandle, isovalue: number, colour: Colour | Hex): void

Draw the surface through isovalue in the field handle names.

The triangulation runs on the GPU every frame, so a caller can clearScene and call this again with a new isovalue each frame and pay a frame rather than an upload. That is what makes a dragged slider feel direct.

plot.frameScene(): void

Point the camera at the middle of everything uploaded, far enough back to see it.

Call after uploading. A scene measured in grid cells or in millimetres is nowhere near where a camera starts, and without this the first thing a caller sees is an empty canvas.