Shapes
The first example to read. It constructs every built-in analytic shape (see
Analytic shapes), evaluates each one, and runs one of them through GPU::transform.
The source is at Examples/Shapes/main.cpp.
Fig. 17 The bounded shapes, as the viewer first shows them.
The code that runs on either side
The file opens with the query that the last section hands to GPU::transform: a small struct
holding a shape by value, whose EBGEOMETRY_HOST_DEVICE call operator returns the shape’s signed
distance at a point. A shape is a trivially copyable value, so this is all a kernel needs.
Construct the shapes
Each shape is one constructor call, with the shape’s position before its sizes:
SphereSDF<T>(center, radius), BoxSDF<T>(lo, hi), TorusSDF<T>(center, majorRadius,
minorRadius), and so on. A shape with a built-in axis (the torus, both cones, the rounded cylinder)
has it along \(y\), and a size is that of the finished shape, so a rounded box of outer size 1.2
fits a box of side 1.2 exactly. The parameters of every shape are documented in
EBGeometry_AnalyticDistanceFunctions.hpp.
The example also constructs PerlinSDF, a fractal
noise field: not the distance to any surface, but a common building block for perturbing one.
Use them on the host
The program prints one row per shape, using the three calls every shape has:
signedDistance(point): negative inside, positive outside, zero on the surface.computeBoundingVolume(): the shape’s axis-aligned bounding box, infinite along any direction in which the shape is unbounded (the plane, the infinite cylinder and cone, the noise).distanceQuality: whether the value is the exact Euclidean distance, a lower bound on it, or only a sign (DistanceQuality). Every built-in shape is exact except the noise. Composition and BVH pruning depend on it; see Basic CSG.
shape (0,0,0) (.5,.5,.5) (2,0,0) box along x quality
plane 0.0000 0.8660 1.1547 [-inf, +inf] exact
sphere -1.0000 -0.1340 1.0000 [-1.00, 1.00] exact
...
Perlin noise 0.9990 1.0615 0.9990 [-inf, +inf] not a distance
The same query on a GPU
The last section evaluates the torus at points along the \(x\) axis with
GPU::transform(Distance{torus}, points, distances), which writes into a vector the caller has
sized. Compiled as CUDA or HIP, that runs a kernel; compiled as
plain C++, a host loop, so the section runs in both builds. A shape owns no memory, so nothing but
the points has to reach the device. See Running queries on a GPU.
Looking at it
The example ends with a window on the bounded shapes side by side, compiled into one tape (see
Basic CSG) with each moved to its place by Translate.
The window needs SDL2 and is built with make VIEWER=SDL2 or cmake -DEBGEOMETRY_VIEWER=SDL2 (see
The viewer window (EBGEOMETRY_VIEWER)); otherwise, and with --no-view or without a display, view() prints why
and returns. Drag to orbit and scroll to zoom; the window lists its other keys (see
The viewer’s keys).
Building and running
See Building for how to compile it with CMake, GNU Make, or a direct compiler invocation, and Running on a GPU for a GPU build.
cd Examples/Shapes
./Shapes.ex