Packages

Composable, native Elixir CAD with sketches, assemblies, and verified printable exports

Current section

Files

Jump to
smith examples profiles.livemd
Raw

examples/profiles.livemd

# Sketches, revolve, and loft

```elixir
Mix.install([{:smith, "~> 0.2.0"}, {:kino, "~> 0.19.0"}])
```

## Before you start

After [the plate](plate.livemd), compare three ways to make solids: push a ring-shaped sketch into depth, rotate a wall section into a sleeve, and connect two outlines with a loft.

Run cells in order. Lengths are millimeters and modeling angles are degrees.
Each 3D preview supports orbit, zoom, and fullscreen.


## Draw a ring

Sketches describe one connected planar region, optionally with holes. They can be
previewed as faces before extrusion.

```elixir
alias Smith.{Plane, Sketch}
outline = Sketch.circle(25) |> Sketch.cut(Sketch.circle(15))
Smith.Kino.render(outline, label: "1 · Ring sketch")
```

## Extrude along the normal

The normal is perpendicular to the sketch. On the default XY plane, positive
extrusion goes along +Z. The flat ring becomes a 4 mm thick washer.

```elixir
ring = outline |> Smith.extrude(4)
Smith.Kino.render(ring, label: "2 · Extruded ring")
```

## Revolve a cross-section

The XZ plane's local Y points along world Z. Keep the section to one side of the
rotation axis to produce a hollow sleeve.

```elixir
sleeve =
  Sketch.rectangle(4, 20, align: {:min, :min}, at: {12, 0}, on: Plane.xz())
  |> Smith.revolve({0, 0, 1})
Smith.Kino.render(sleeve, label: "Revolved sleeve")
```

## Connect sections with a ruled loft

A ruled loft joins each pair of outlines directly. Here two rectangles at
different heights make a tapered transition. A smooth multi-section version
appears in [paths and shells](paths-and-shells.livemd).

```elixir
transition = Smith.loft([
  Sketch.rectangle(30, 20),
  Sketch.rectangle(20, 10, on: Plane.xy(z: 30))
])
Smith.Kino.render(transition, label: "Ruled transition")
```

## Export the ring

```elixir
{:ok, result} = Smith.evaluate(ring)
{:ok, volume} = OCEx.volume(result.shape)
true = abs(volume - :math.pi() * (25 * 25 - 15 * 15) * 4) < 1.0e-6
{:ok, files} = Smith.export(result, "output/livebook", name: "ring", on_bed: true)
files
```