INTERACTIVE · WEBGL + COMPUTATIONAL GEOMETRY · REAL-TIME
Section Studio.
One plane equation, computed two ways — a GPU visual cut and a CPU-measured contour — forced to agree.
Drag a cutting plane through a procedurally-generated solid and two things happen in the same frame. The GPU clips the mesh so you see it cut open. On the CPU, every triangle is intersected with that same plane to recover the exact section contour — which is measured for area, perimeter, and bounds, drawn as a crisp 2D line, and exported as SVG. Same plane, two pipelines, one truth.
THE PROBLEM
To reason about a solid you slice it — a floor plate in a massing, wall thickness in a machined part, strut density in a lattice. But a rendered cut only looks right: it gives you a picture, not a number. And a bare list of numbers with no visible cut is impossible to trust or explain.
THE IDEA
Drive one cutting plane into two independent pipelines: a GPU clip that renders the cut, and a CPU solver that measures it. Because both consume the identical plane equation, the picture and the numbers must describe the same locus — each is a live check on the other.
WHY IT'S USEFUL
The read-outs and the SVG export are what turn a demo into an instrument. The section updates continuously as the plane moves, and the exported contour is a resolution-independent drawing suitable for drafting or documentation.
↑ PICK A SOLID · SET THE PLANE AXIS · DRAG OFFSET · ORBIT THE VIEW · EXPORT THE SECTION
The interesting engineering here is not that a solid can be cut open
on screen, nor that a polygon's area can be computed. It is that
one movable plane is asked to do both jobs through
two pipelines that never talk to each other — and
the results have to line up exactly. The GPU path is fast and
approximate-feeling; the CPU path is exact and slower. Running them
off the same n·x = d turns each into a sanity check on
the other. That duality is the idea; everything else is
plumbing.
The GPU cut — what you see
The solid is rendered with three and
@react-three/fiber. A single world-space clipping plane is
handed to the material (renderer.localClippingEnabled +
material.clippingPlanes), so the GPU discards
every fragment on the far side of the cut, every frame, while
you orbit — no geometry is modified, the clip is purely a per-pixel
test. The cut face is then filled with a translucent cap so the model
reads as a genuine solid rather than a hollow shell.
The CPU section — what you can trust
The showcase is the section itself. For each triangle I compute the signed distance of its three vertices to the plane, find the edges that straddle it, and interpolate the crossing points into a line segment. Thousands of these segments are then welded at shared endpoints and stitched into closed contour loops — the same marching-triangles idea that underpins contouring and slicing. From the loops I derive section area (hole-aware, via an even-odd nesting rule), perimeter, and the bounding box. This path is exact: it is the answer I would stake a measurement on.
An instrument, not an animation
The whole plane–mesh intersection reruns over the full triangle soup on every frame the plane moves — comfortably real-time in plain JavaScript. The claim I'll actually stand behind is the narrow one: the inner per-triangle crossing math is allocation-free, reusing three scratch slots and touching no heap. The surrounding pass is not — the segment buffers and the weld-and-stitch bookkeeping are rebuilt each frame — but keeping the hottest loop tight is what buys the real-time feel. The continuously-updating read-outs and the clean SVG export are what make this a tool you could actually reason with, rather than a canned clip.
Each solid is chosen to exercise the sectioning in a different way — all generated procedurally at load, with no model files:
- Stepped massing — stacked, set-back floor slabs. A vertical cut traces the stepped silhouette across every floor plate at once; a horizontal cut isolates the plate at whatever level the plane sits.
- Machined bracket — an extruded plate with a central bore, mounting holes, and lightening reliefs. Scanning the plane across it opens and closes holes, so the section count and area jump as features come and go.
- Gyroid lattice — a solid slice of the gyroid triply-periodic minimal surface, meshed with a self-contained marching-tetrahedra iso-surfacer. Its section is a field of interlocking loops — the visual signature of a TPMS lattice, and a deliberate stress test for the contour stitcher.
The honest edges of the build — a senior tool states them plainly:
- Not eyeballed frame-by-frame. The 3D viewport needs live WebGL, which the static build environment can't exercise. The scene has been reasoned about and instrumented, but not visually QA'd against a running GPU. What I would stake correctness on is the CPU side — the measurements, the 2D contour, and the SVG export are pure, deterministic functions of the triangle soup and the plane.
- The measurement is exact; one visual is a heuristic. Section area, perimeter, bounds, and the 2D drawing come straight from the plane–triangle math and are correct for any watertight input. The translucent 3D cap that fills the cut face is a secondary convenience, triangulated from the same loops via an even-odd shape build; for the gyroid's many interlocking loops the hole/nesting assignment is best-effort, so the cap can occasionally mis-fill even while the 2D section and the numbers stay right.
- Non-watertight input degrades gracefully, not silently. Open meshes yield open polylines instead of closed loops; area is only meaningful for closed contours, so it is reported as the even-odd sum and can be misleading on genuinely non-solid input.
What's next: a robust loop-nesting pass for the cap (an explicit winding/containment tree rather than even-odd depth parity), so the gyroid cap matches the always-correct 2D section; a Web Worker to offload the intersection so very large soups keep a steady frame rate; and a proper visual QA pass once a live GPU is in the loop. A first ergonomic fix already shipped — the orbit camera auto-reframes when you switch solids, since the three differ in scale and the view previously stayed put.
Astro island rendered client:only (WebGL can't
server-render), three +
@react-three/fiber + @react-three/drei for
the scene and orbit controls. The section solver, contour stitcher,
measurement code, marching-tetrahedra mesher, and SVG serializer are
hand-written TypeScript with no geometry libraries.
Every surrounding control and panel is painted with the site's design
tokens, so the whole instrument flips correctly between light and dark;
only the WebGL stage stays dark in both, on purpose, to hold geometry
contrast steady.
MORE INTERACTIVE WORK