# Solids reference

[Start here](https://pegmatite.dev/guide/start.md). Fetch this topic when a model needs a cone, pyramid, star, platonic solid or hand-written mesh, the rules of a primitive's sizes, or a solid's numbered faces `#f1`, `#f2`, ….

Every dimension is zero or greater; a dimension of zero makes a [zero-sized volume](https://pegmatite.dev/guide/booleans.md). Width runs along X, depth along Y and height along Z in the solid's own frame.

## Basic solids

**Syntax:** **`cube`** _size_

**Syntax:** **`block`** _width_ _depth_ _height_

**Syntax:** **`cylinder`** _diameter_ _height_

**Syntax:** **`sphere`** _diameter_

**Syntax:** **`cone`** _diameter_ _height_

A right circular cone standing on its base; the diameter is the base's.

```pegm
cylinder 20 10
cone 20 30
```

### Tube and torus

**Syntax:** **`tube`** _outer-diameter_ _inner-diameter_ _height_

An upright cylinder of the outer diameter with a bore of the inner one. The inner diameter must be greater than zero and no larger than the outer; equal diameters leave a wall of no thickness, a zero-sized volume. Both walls use the flats of a cylinder's wall, so a tube and a cylinder of one diameter meet facet to facet, without slivers:

```pegm
tube 30 18 10
@top cylinder 30 5
```

**Syntax:** **`torus`** _outer-diameter_ _inner-diameter_

A ring lying in the XY plane, measured by its overall diameter and its hole. The hole must be greater than zero and no larger than the outside; equal diameters leave no material.

```pegm
torus 30 18
```

## Prisms and pyramids

**Syntax:** **`prism`** _sides_ [**`diameter`** | **`edge`** | **`across`**] _size_ _height_

**Syntax:** **`pyramid`** _sides_ [**`diameter`** | **`edge`** | **`across`**] _size_ _height_

A regular prism with _sides_ upright faces, or a regular pyramid with _sides_ faces meeting at the apex, standing on its base. _sides_ is a whole number of 3 or more.

- The size measures the base. By default it is the diameter of the base's circumcircle, the circle through its corners, so the solid fits inside the cylinder or cone of that diameter. A square base of diameter _d_ has a side of _d_ / √2. The word before the size changes the measure: see [measuring a solid's size](https://pegmatite.dev/guide/expressions.md).
- The base is turned so that a **face**, not a corner, points front. A square prism or pyramid stands square with the axes like `block`, and its box faces run parallel to real faces.
- Every upright face of a prism has a [numbered name](https://pegmatite.dev/guide/solids.md#numbered-faces), so a prism builds round something on flats.

```pegm
block 20 20 6
@top pyramid 4 edge 20 20
```

The pyramid's base covers the block it caps.

```pegm
prism 6 40 20
on #f2 cube 6
```

### Star prism

**Syntax:** **`starprism`** _spikes_ _outer-diameter_ _inner-diameter_ _height_

A star raised into a solid on its base. All four numbers are required. The spikes reach the outer circle and the notches between them the inner one; the inner diameter must be smaller than the outer, and _spikes_ is a whole number of 3 or more. As the diameters approach each other the star flattens towards a prism of _spikes_ × 2 sides.

The first spike points along **+X**, where a [circular pattern](https://pegmatite.dev/guide/patterns.md) puts its first iteration and a [revolve](https://pegmatite.dev/guide/extrude.md) begins its turn, so a ring written in the same frame lands one solid on each spike:

```pegm
starprism 8 60 30 6
on #top circular 60 8 @top cylinder 6 6
```

## Platonic solids

**Syntax:** **`tetrahedron`** [**`diameter`** | **`edge`**] _size_

**Syntax:** **`octahedron`** [**`diameter`** | **`edge`** | **`across`**] _size_

**Syntax:** **`dodecahedron`** [**`diameter`** | **`edge`** | **`across`**] _size_

**Syntax:** **`icosahedron`** [**`diameter`** | **`edge`** | **`across`**] _size_

- The size is the edge length by default, the measure `cube`, the fifth platonic solid, takes. The same edge makes very different sizes: a dodecahedron of edge 10 is far bigger than a tetrahedron of edge 10.
- `diameter` measures the sphere through the vertices, as `sphere` does. Only the vertices touch it, so the solid is a little smaller than the sphere, the closer the more faces it has.
- `across` measures between opposite faces, which is the height the solid stands. The tetrahedron has no face opposite a face and does not take `across`. See [measuring a solid's size](https://pegmatite.dev/guide/expressions.md).
- Each stands on one of its faces, so it rests flat on the ground and on any face it is placed on. Every face except the tetrahedron's has a parallel one on top, so the others stack directly.

```pegm
!@right 4
sphere 20
icosahedron diameter 20
dodecahedron diameter 20
```

```pegm
icosahedron 12
on #top icosahedron 12
```

## Mesh

**Syntax:** **`mesh vertices [`**_x_ _y_ _z_**`]`**… **`faces [`**_i_ _j_ _k_ …**`]`**…

A solid written out by hand: its corners after `vertices`, then its faces after `faces`, each the list of corners it runs through. A corner is named by its place in the list, **counted from 0**. This is a tetrahedron with three corners on the axes:

```pegm
mesh vertices [0 0 0] [10 0 0] [0 10 0] [0 0 10] faces [0 1 2] [0 1 3] [0 2 3] [1 2 3]
```

- A face may have more than three corners if it is **flat** and they are listed in order around it, so a box needs six faces, not twelve triangles.
- The faces must close the solid: **every edge is shared by exactly two faces**. Which way round a face is listed does not matter; the faces are turned to agree and to face out.
- A face that is not flat, an edge not shared by exactly two faces, or a corner that does not exist is an error pointing at the face.
- Placement normalizes the mesh's box to the X/Y centre and Z 0, so translating every vertex does not move the placed solid.
- Coordinates and indices accept variables and [expressions](https://pegmatite.dev/guide/expressions.md).

```pegm
mesh vertices [0 0 0] [20 0 0] [20 10 0] [0 10 0] [0 0 10] [20 0 10] [20 10 10] [0 10 10]
     faces [4 5 6 7] [0 1 5 4] [1 2 6 5] [2 3 7 6] [3 0 4 7] [0 1 2 3]
```

A mesh numbers its faces `#f1`, `#f2`, … **in the order they are written**, not in the order of other solids' [numbered faces](https://pegmatite.dev/guide/solids.md#numbered-faces). The six direction names cover its box as usual. Below, `#f1` is the front slope and the square base `#f5` is also `#bottom`:

```pegm
set $h 30
mesh vertices [-10 -10 0] [10 -10 0] [10 10 0] [-10 10 0] [0 0 $h]
     faces [0 1 4] [1 2 4] [2 3 4] [3 0 4] [0 1 2 3]
on #f1 cylinder 4 6
```

## Numbered faces

Besides the six directions, a solid names every planar side it really has `#f1`, `#f2`, …, including sides no direction can name, such as a pyramid's slope or one pentagon of a dodecahedron. A solid built on a slanted face leans out with it:

```pegm
pyramid 4 20 30
on #f1 cylinder 4 10
```

The numbering runs from the side that faces most steeply up to the one that faces most steeply down; sides facing equally far up are counted around from the front, clockwise. On a cube:

| Name  | Same face as |
| ----- | ------------ |
| `#f1` | `#top`       |
| `#f2` | `#front`     |
| `#f3` | `#left`      |
| `#f4` | `#back`      |
| `#f5` | `#right`     |
| `#f6` | `#bottom`    |

On a four-sided pyramid `#f1` to `#f4` are the slopes, front first, and `#f5` is `#bottom`. A numbered face that covers a whole side of the box _is_ that box face, so both names place a solid identically.

- Only planar sides are numbered, never facets on curves: a cylinder has two (its caps), a cone one (its base), a sphere none.
- Outside `on`, the six directions name a side only where one of these lies in that face of the box: a dodecahedron has `#top` and `#bottom` but no `#front`. `on #front` still builds against the box's plane.
- The names belong to the shape the solid was built as. Like the six directions they follow it through a transform and are never renamed.
- An oblique face cannot be given to `shell`, `chamfer` or `fillet`, which work in axis-aligned coordinates.
- A `cut` makes a new shape, which is numbered afresh.

```pegm
cylinder 20 30
on #f1 cube 6
```
