# Extrude and revolve

[Start here](https://pegmatite.dev/guide/start.md). Fetch this topic when you raise or turn a 2D shape into a solid: walls, tapers, twists, a top of another shape, rings and turned parts.

## Profile first

Write the [2D shape](https://pegmatite.dev/guide/shapes.md), its shape modifiers, the sweep word, then solid modifiers:

```pegm
rect 40 30 | round 5 | extrude 10 | fillet 1 at #top
```

Everything before the sweep word treats the flat shape, everything after it the solid. After the word, positional dimensions come first and named options follow in any order; a repeated option keeps its last value. A second shape argument, such as the top of `extrude … to`, takes no modifiers of its own. Write one that needs them in a [group](https://pegmatite.dev/guide/shape-operations.md), whose braces mark where it ends:

```pegm
rect 30 30 | extrude 30 to { circle 20 | offset 2 }
```

`helix`, `sweep along` and varying profiles, shapes redrawn along the sweep, are in [sweeps](https://pegmatite.dev/guide/sweeps.md).

## Extrude

**Syntax:** _2d-shape_ **`| extrude`** _height_ [**`wall`** _thickness_] [**`inside`** | **`outside`**] [**`twist`** _degrees_] [**`size`** _factor_] [**`apex [`**_x_ _y_ [_z_]**`]`**] [**`to`** _top_]

| Argument or option   | Default        | Rule                                                                    |
| -------------------- | -------------- | ----------------------------------------------------------------------- |
| _height_             | required       | zero or greater                                                         |
| `wall` _thickness_   | filled profile | zero or greater; the outlines must stay valid                           |
| `inside` / `outside` | centered wall  | only with `wall` on a closed outline                                    |
| `twist` _degrees_    | no turn        | a number or a list `[`_a_ _b_ …`]` of two or more; not with `apex`/`to` |
| `size` _factor_      | drawn size     | as `twist`; zero or greater, zero only at the base or the top           |
| `apex [`_x y z_`]`   | straight sides | _z_ defaults to _height_; not between 0 and _height_                    |
| `to` _top_           | the profile    | one outline without holes, as is the profile; not with `apex`           |

The result is an ordinary solid, one closed, printable surface.

### Wall

`wall` draws the outline with a thickness instead of filling it, open at both ends. The wall is centered on the outline: `circle 20 | extrude 10 wall 2` is `tube 22 18 10`. `inside` and `outside` put it wholly on one side, keeping the drawn outline as its outer or inner face; below, the first is 40 across, the second 44, a centered wall 42. A hole in the shape is an outline of its own and gets its own wall.

```pegm
rect 40 40 | extrude 10 wall 2 inside
rect 40 40 | extrude 10 wall 2 outside
path "M0,0 H40 V40 H0 Z M10,10 H30 V30 H10 Z" | extrude 10 wall 2
```

A wall thick enough to close the opening is rejected, as an over-thick `shell` is. An open path encloses no area, so filling closes it first, while `wall` keeps it open; it has no inside or outside, so its wall is always centered. Below, a filled triangle and an L-shaped wall:

```pegm
path "M0,0 H30 V20" | extrude 10
path "M0,0 H30 V20" | extrude 10 wall 2
```

[`shell`](https://pegmatite.dev/guide/modifiers.md) hollows a finished solid inwards and keeps its bottom, a vessel. `wall` never fills the shape: open at both ends, corners as sharp as the outline's, and it can follow a line that encloses nothing.

### Apex

`apex` aims the sides at a point; _height_ is where they stop. Without _z_ the apex is at _height_, a pyramid. The point is in the shape's own frame, as a [mesh](https://pegmatite.dev/guide/solids.md) corner is: `circle`, `rect`, `ellipse` and regular polygons are centered on their origin, a `path` or a written `polygon` lies where its coordinates put it. An apex off the middle leans the point; the second below stands over the path's first corner. The solid is then placed by its box, so a lean moves the box, not the base.

```pegm
rect 20 10 | extrude 30 apex [5 -3]
path "M 0 0 L 20 0 L 15 12 L 2 10 Z" | extrude 30 apex [0 0]
circle 20 | extrude 30 apex [0 0 60]
```

An apex above _height_ makes a frustum: the third stops halfway, its top half the base. A negative _z_ spreads the sides instead: `apex [0 0 -60]` makes the top of a 30 tall extrude 1.5 times the base. An apex between 0 and _height_ is refused, since the sides would cross.

With `wall`, every level is the outline at that level drawn with the same thickness. Where the outline gets smaller than the wall, near a point or on a curve tighter than the wall, the wall closes over into solid, so a wall run to a point ends in a solid tip. Text or another long outline closing over all along is refused rather than built slowly; a higher apex keeps the top open.

```pegm
rect 30 30 | extrude 30 wall 2 inside apex [0 0 60]
rect 30 30 | extrude 30 wall 2 inside apex [0 0]
```

### To another shape

`to` joins the profile to a different top outline with straight lines. Outlines with the same number of corners pair corner to corner, each face between them a smooth twisted face. Different counts pair the points at the same fraction of each perimeter and keep every corner of both, each one becoming a point of the other outline; give both the same corner count to pair them directly. The top starts where the side twists least, its lines shortest, so a square's corners meet a circle at 45°. When both ways are as short, as with a square turned exactly 45°, the side turns counterclockwise.

```pegm
rect 30 30 | extrude 30 to circle 20
rect 30 30 | extrude 50 to { rect 30 30 | rotate 45 }
```

The top uses the profile's coordinates: centered shapes align by their origins, written coordinates shift the top. Below, the rectangle lies 20 right of the circle's middle and the side runs over to it; the solid, placed by its box, is 40 wide:

```pegm
circle 20 | extrude 30 to polygon points [10 -5] [30 -5] [30 5] [10 5]
```

With `wall`, both outlines are thickened and joined by straight sides, open at both ends. A wall too thick for either outline, closing the opening or pinching it in two, is refused, as is a wall on an open path. Both shapes must be single outlines without holes: text, tilings and paths with holes or several subpaths are rejected.

```pegm
rect 40 40 | extrude 40 wall 2 inside to circle 12
```

### Twist and size

`twist` turns the outline as it rises and `size` resizes it, both about the profile's own origin, the point `| rotate` and `| scale` use. A number is the top's value, reached evenly from the base: `twist 60` turns the top 60° counterclockwise seen from above, `size 0.5` makes it half the profile. `twist 720` turns twice. Size is a share of the drawn profile, above 1 it grows. An even size without twist rises in straight sides: on a 40 tall extrude `size 0.5` is the frustum of `apex [0 0 80]`, `size 0` the pyramid of `apex [0 0]`.

```pegm
!@right 10
star 6 40 28 | extrude 40 twist 60
star 6 40 28 | extrude 40 size 0.5
star 6 40 28 | extrude 40 twist 60 size 0.5
```

A list gives values at evenly spaced levels, base and top included, joined by a smooth curve that never overshoots: between two values it stays between them, and where they turn back it levels out. The first value is the base's own, so `size [0.5 1]` starts at half size and `twist [30 30 90]` starts turned. A list needs two values. A size cannot be negative and can be zero only at the base or the top, where the solid closes to a point. This vase swells, narrows and turns faster near its top:

```pegm
star 9 80 64 | round 4 | extrude 160 twist [0 30 120] size [1 1.3 0.85 1] wall 2 inside
```

A `wall` keeps its thickness at every level, turned and resized, but cannot follow a size down to zero. `apex` and `to` already set the top, so neither takes `twist` or `size`. A path drawn away from its origin swings round that origin as it turns.

## Revolve

**Syntax:** _2d-shape_ **`| revolve`** [_diameter_] [**`angle`** _degrees_] [**`start`** _degrees_] [**`shrink`**] [**`about`** _axis_]

| Argument or option | Default | Rule                                                       |
| ------------------ | ------- | ---------------------------------------------------------- |
| _diameter_         | `0`     | zero or greater; circle the profile's origin travels on    |
| `angle` _degrees_  | `360`   | greater than 0, at most 360                                |
| `start` _degrees_  | `0`     | where the turn begins round the axis                       |
| `shrink`           | off     | the material's own box instead of one mirrored on the axis |
| `about` _axis_     | `z`     | `x`, `y` or `z`                                            |

`revolve` turns the profile about the upright axis. A point's distance from the axis becomes its radius, its position along the axis its height. A `path` keeps the way it was drawn, its top the top of the solid, its Y growing downwards: below, a 10 square held 5 off the axis becomes a tube 10 tall, outer radius 15, bore 5. The axis and turn are those of a [circular pattern](https://pegmatite.dev/guide/patterns.md), starting at +X, so a `revolve` and a `circular` written against the same face agree.

```pegm
path "M5,0 H15 V10 H5 Z" | revolve
```

_diameter_ rings a shape drawn about its own origin: `circle 20 | revolve 40` is `torus 60 20`. At `0` the profile is swept at its own coordinates. A profile on the negative side of the axis is mirrored, one crossing it is clipped to the swept half, so a centered profile gives a primitive: `circle 20 | revolve` is a sphere, `rect 10 20 | revolve` a cylinder 10 across and 20 tall, `ellipse 10 20 | revolve` the spheroid between. Only the outline is swept; holes are ignored.

`angle` runs from +X toward +Y and caps both ends; facets follow the sweep. A partial turn keeps the box mirrored about its axis, so arcs of one ring share an axis and `start` moves material within a stable slot; `shrink` uses the material's own box. `start` shows only on a partial turn.

```pegm
circle 20 | revolve 40 angle 90 shrink
path "M4,0 C 4,6 14,6 14,14 L 18,14 C 18,4 8,4 8,0 Z" | revolve angle 270
circle 20 | revolve 40 angle 90 start 45
```

`about` names the axis. The radius lies on the axis that follows it in the cycle `x` → `y` → `z` → `x` and the turn runs toward the next: `about z` starts at +X toward +Y, `about x` starts at +Y, `about y` at +Z. `about` turns the solid itself, unlike [`on`](https://pegmatite.dev/guide/placement.md), which turns the frame the solid is built in and carries placement with it. A build plane lays it down.

```pegm
circle 20 | revolve 40 about y angle 120 start 30
on #front
path "M5,0 H15 V10 H5 Z" | revolve
```
