# `Quiddity.Part`
[🔗](https://github.com/d-led/ex.quiddity/blob/main/lib/quiddity/part.ex#L1)

A STEP part, read once and asked about as often as you like.

The struct holds the engine's handle — the parsed B-rep lives in Rust, and the
handle is a reference to it — plus the summary that came with it. Nothing here
is a copy of the geometry: a `Part` is a *capability* to answer questions about
one file.

A B-rep is immutable once read, so one handle serves every process on the node
at once; that is the sharing the BEAM is built for, and the reason a handle
rather than a term is what `Quiddity.open/1` answers.

# `t`

```elixir
@type t() :: %Quiddity.Part{path: Path.t(), ref: reference(), summary: map()}
```

# `bounds`

```elixir
@spec bounds(t()) :: {[float()], [float()]}
```

The part's bounding box, as `{min, max}` in millimetres.

# `centre`

```elixir
@spec centre(t()) :: [float()]
```

The centre of the bounding box, in millimetres.

# `diagonal`

```elixir
@spec diagonal(t()) :: float()
```

The part's diagonal, in millimetres: the scale a tolerant question uses.

# `extent`

```elixir
@spec extent(t()) :: [float()]
```

The extent of the part along each axis, in millimetres.

# `face_count`

```elixir
@spec face_count(t()) :: non_neg_integer()
```

How many faces the B-rep has — the numbers `Quiddity.face/2` takes.

# `shell?`

```elixir
@spec shell?(t()) :: boolean()
```

Whether the part is a shell with no solid behind it.

Geometry questions still answer, but "inside" and "outside" do not: a shell
has no authority to say which side is material, so a ray's first hit is the
only hit that means anything.

# `unresolved_faces`

```elixir
@spec unresolved_faces(t()) :: [non_neg_integer()]
```

Faces the kernel could not resolve; a ray may pass through one.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
