# Steel beam

Structural beam of any EN / AISC section or welded plate girder (PG <depth>) along X from −length/2 to +length/2 with bolted extended end plates or fin plates, bearing stiffeners at the ends and a stiffener pair at mid-span. The top flange (top of steel) is at y = topOfSteel; the default sits the beam on the ground.

**Standards:** EN 10365, AISC 360, EN 1993-1-8

## Installation

```bash
npx -y https://decktwin.com/cli/deck-twin-0.2.2.tgz add steel-beam
```

Copies `structure/steel-beam.tsx`, any helper files it imports and the shared `lib/` into `src/components/deck-twin/`. Needs `three`, `@react-three/fiber` and `@react-three/drei`.

## Usage

```tsx
import { Canvas } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei'
import { Stage } from './components/deck-twin/lib/stage'
import { SteelBeam } from './components/deck-twin/structure/steel-beam'

export default function Scene() {
  return (
    <Canvas shadows camera={{ position: [8, 5, 9], fov: 35 }}>
      <Stage>
        <SteelBeam />
      </Stage>
      <OrbitControls makeDefault />
    </Canvas>
  )
}
```

## Props

| Prop | Type | Default | Range |
| --- | --- | --- | --- |
| `section` | `"IPE 200" \| "IPE 300" \| "IPE 400" \| "IPE 600" \| "HEA 300" \| "HEB 300" \| "HEB 600" \| "W16x67" \| "W24x146" \| "UPN 300" \| "PG 1200"` | `"IPE 300"` |  |
| `length` | `number (m)` | `6` | 0.5 – 30 |
| `topOfSteel` | `number (m)` | `0.3` | 0 – 30 |
| `connection` | `"end-plate" \| "fin-plate" \| "none"` | `"end-plate"` |  |
| `stiffeners` | `boolean` | `true` |  |
| `finish` | `"painted" \| "galvanised"` | `"painted"` |  |
| `...group` | position, rotation, scale… |  |  |

## P&ID

Elevation: two parallel flange lines with end plates (or fin plates) at each end; on framing plans a single thick line between columns with the section (e.g. IPE 300, TOS EL +28.000) written along it.

Layout plan convention (structural / plot plan drawings) (structural elevation / framing plan)

Not on P&IDs. A beam drawn thicker on a plan is usually a primary girder.

Structural member schedule (EN 10365 / AISC 360) fields and the props they set:

| Field | Prop |
| --- | --- |
| Section | `section` |
| Length | `length` |
| Top of steel | `topOfSteel` |
| Connection | `connection` |
| Stiffeners | `stiffeners` |
| Finish | `finish` |

## Typical suppliers

Fabricated to project specification. The geometry is generic and sized from public standards. It is not vendor CAD.

## Source

`structure/steel-beam.tsx`. This is the component file only: it imports shared code, so install it with the command above rather than pasting it alone. https://decktwin.com/r/steel-beam.json has every file.

```tsx
// Structural steel beam (EN / AISC section or welded plate girder) with bolted end plates or fin plates, bearing stiffeners, at a top-of-steel elevation.
import type { Kit, MatKey } from '../lib/kit'
import { KitMesh, useKit, type GroupProps } from '../lib/mesh'
import { beamTOS, endPlate, finPlate, sec, webStiffeners } from './_steel'

export interface SteelBeamProps {
  section?: string
  /** along X, m */
  length?: number
  /** top-of-steel elevation, m */
  topOfSteel?: number
  connection?: 'end-plate' | 'fin-plate' | 'none'
  /** bearing stiffeners at the ends and a load-point stiffener pair at mid-span */
  stiffeners?: boolean
  finish?: 'painted' | 'galvanised'
}

export const defaults = {
  section: 'IPE 300',
  length: 6,
  topOfSteel: 0.3,
  connection: 'end-plate' as 'end-plate' | 'fin-plate' | 'none',
  stiffeners: true,
  finish: 'painted' as 'painted' | 'galvanised',
}

type P = typeof defaults

export function SteelBeam(props: SteelBeamProps & GroupProps) {
  const { section, length, topOfSteel, connection, stiffeners, finish, ...group } = { ...defaults, ...props }
  const data = useKit((k) => build(k, { section, length, topOfSteel, connection, stiffeners, finish }), [section, length, topOfSteel, connection, stiffeners, finish])
  return (
    <group {...group}>
      <KitMesh data={data} />
    </group>
  )
}

export default SteelBeam

function build(k: Kit, p: P) {
  const mat: MatKey = p.finish === 'galvanised' ? 'galvanised' : 'structSteel'
  const s = sec(p.section)
  const L = Math.max(0.5, p.length)
  const yc = p.topOfSteel - s.d / 2
  const open = s.kind === 'I' || s.kind === 'H' || s.kind === 'U'
  const tp = s.d > 0.5 ? 0.025 : 0.02
  const inset = p.connection === 'end-plate' ? tp : 0
  beamTOS(k, -L / 2 + inset, 0, L / 2 - inset, 0, p.topOfSteel, p.section, mat)
  if (p.connection === 'end-plate') {
    endPlate(k, [-L / 2 + tp, yc, 0], 'x', -1, s, mat)
    endPlate(k, [L / 2 - tp, yc, 0], 'x', 1, s, mat)
  } else if (p.connection === 'fin-plate' && open) {
    // supporting fin plates sit just beyond the beam ends (welded to the supporting member)
    finPlate(k, [-L / 2 - 0.012, yc, 0], 'x', 1, s.d, 0.14, mat)
    finPlate(k, [L / 2 + 0.012, yc, 0], 'x', -1, s.d, 0.14, mat)
  }
  if (p.stiffeners && open && s.kind !== 'U') for (const x of [-L / 2 + 0.12 + inset, 0, L / 2 - 0.12 - inset]) webStiffeners(k, [x, yc, 0], 'x', s, mat)
}
```
