# Custom part (peça própria)

> Component kind `custom-part` (category `static`, DSL name `customPart`, API v1)

A part you drew in the sketch/body editor (the parts library) placed into a bench. It carries a reference to the saved body plus a denormalized snapshot of its bounding box, weight and material, so the bench renders the real evaluated mesh while its graph, layout and BOM stay self-contained.

## Parameters

- **`partBodyId`** — The saved body _id (origin reference). Used to re-fetch and re-evaluate the body only when no embedded features are present (older benches).
- **`weightKg`** — Snapshot mass (kg) computed at save time from volume × density.
- **`material`** — Snapshot material id (e.g. "steel") the body was saved with.
- **`label`** — Optional display name; defaults to the body name at authoring.
- **`hasAxis`** — Legacy opt-in (id-only benches with no embedded features): set true to expose the rotational axis port for a turned part whose feature history is not embedded. Ignored when `features` are present — those are inspected directly for a revolve base op.

## Parameters schema

| Parameter | Type | Default | Constraints |
| --- | --- | --- | --- |
| `partBodyId` | String |  |  |
| `label` | String | — |  |
| `weightKg` | Number | — |  |
| `material` | String | — |  |
| `hasAxis` | Boolean | false |  |

## Ports

| Port | Type | Description |
| --- | --- | --- |
| `body` | `rigid` | Rigid structural port, always present. Weld or rest other parts against it; carries no motion. It is what makes the part counted by the static connectivity / envelope / interference / BOM passes. |
| `axis` | `rotational` | Rotational port along the revolve axis (local Z through the centred origin). Present ONLY on a revolved (lathe-turned) body. Couple it to a shaft or gear with `mech.couple` and the part spins 1:1 with it. |

## Kinematics

A revolved part is a rigid rotational FOLLOWER: coupled through its axis port it takes ω unchanged from the driver (ω_out = ω_in, no gear ratio) and accumulates θ, exactly like a gear mounted on a shaft. A prismatic part has no axis port and never spins. The rigid body port never propagates.

## Example

```
// A turned flange mounted on a driven shaft: it spins with the shaft.
const s = mech.shaft({ id: "S1", diameter: 20, length: 120 });
const flange = statics.customPart({
  id: 'flange1', partBodyId: 'aZ9…', label: 'Flange',
  features: [ /* … a body whose base op is { kind: "revolve" } */ ],
  bbox: [40, 40, 10], weightKg: 0.098, material: "steel",
  transform: { position: [0, 0, 0], rotation: [0, 0, 0] },
});
mech.couple(s.ports.axis, flange.ports.axis, { offsetMm: 60 });
mech.drive(s, { rpm: 60 });
```
