Appearance
Scientific geometry
Isosurfaces
const samples = plot.uploadField(field(96, 10, gyroid));
const [lo, hi] = plot.fieldRange(samples);
const draw = (isovalue) => {
plot.clearScene();
plot.showIsosurface(samples, isovalue, [0.45, 0.78, 0.62]);
};
draw((lo + hi) / 2);
plot.frameScene();
return {
// Back and forth through the middle of the range. No upload: the
// triangles are made on the GPU for whatever value this names.
stream: (at) => draw((lo + hi) / 2 + (hi - lo) * 0.3 * Math.sin(at)),
};Calls
5 in the code above, in the order it makes them
plot.uploadField(field: Field): FieldHandleUpload a scalar field for isosurface extraction.
A separate upload from
uploadVolumeeven 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
handlenames.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.clearScene(): voidStop drawing everything in the scene.
What was uploaded stays uploaded, so rebuilding a scene from the same geometry costs nothing for the geometry.
plot.showIsosurface(handle: FieldHandle, isovalue: number, colour: Colour | Hex): voidDraw the surface through
isovaluein the fieldhandlenames.The triangulation runs on the GPU every frame, so a caller can
clearSceneand 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(): voidPoint 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.