> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ploterr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# validateBuildingModel

> validateBuildingModel checks a building model and returns all problems.

It does not need the geometry kernel, so it also runs on a server. Use it for a model that comes from a file, an API or an AI agent.

## Import

```typescript theme={null}
import {
  validateBuildingModel,
  assertValidBuildingModel,
  BmValidationError,
} from '@opengeometry/floorkit';
```

## Example

```typescript theme={null}
import { validateBuildingModel } from '@opengeometry/floorkit';

export function reportProblems(input: unknown): boolean {
  const result = validateBuildingModel(input);
  for (const issue of result.errors) console.error(issue.path, issue.code, issue.message);
  for (const issue of result.warnings) console.warn(issue.path, issue.code, issue.message);
  return result.ok;
}
```

## Notes

* Each problem has a `path`, a `code` and a `message`.
* `assertValidBuildingModel` returns the typed model, or throws `BmValidationError`.
* An opening that overlaps another opening, or whose offset is not on its wall, is an error. Floorkit does not move it.
* Whether an opening fits between the joints of its wall is a fact of the build, not of this check: the build reports `opening-does-not-fit` in `warnings`.
* A valid model can fail in the build step, because the build also checks the geometry.

## Signature

```typescript theme={null}
function validateBuildingModel(document: unknown): BmValidationResult;
```

## Parameters

<ParamField path="document" type="unknown" required />

## Returns

```typescript theme={null}
BmValidationResult;
```

## assertValidBuildingModel

Validate and return the document, throwing `BmValidationError` listing every problem.

```typescript theme={null}
function assertValidBuildingModel(document: unknown): BuildingModel;
```

## BmValidationError

```typescript theme={null}
class BmValidationError extends Error {
  readonly issues: BmIssue[];
  constructor(issues: BmIssue[]);
}
```

## Types

### BuildingModel

```typescript theme={null}
interface BuildingModel {
  schema: 'floorkit.building' | 'floorkit.building-model';
  version: 1 | 2 | 3 | 4;
  units: 'meters';
  upAxis: 'y';
  id: string;
  name?: string;
  metadata?: Record<string, string>;
  propertySets?: BmPsets;
  psets?: BmPsets;
  site?: BmSite;
  buildings: BmBuilding[];
  assets?: Record<string, BmAssetRef>;
  conditioning?: BmConditioning;
}
```

<ResponseField name="schema" type="'floorkit.building' | 'floorkit.building-model'" required>
  Discriminator. Identifiers written by earlier versions are accepted on input and replaced by
  these; anything else is rejected rather than guessed at.
</ResponseField>

<ResponseField name="version" type="1 | 2 | 3 | 4" required />

<ResponseField name="units" type="'meters'" required>
  An assertion, not a conversion knob. Spelled to match `OPBaseDocument.units`.
</ResponseField>

<ResponseField name="upAxis" type="'y'" required>
  Y-up, matching the Three.js scene and every element's own convention.
</ResponseField>

<ResponseField name="id" type="string" required />

<ResponseField name="name" type="string" />

<ResponseField name="metadata" type="Record<string, string>" />

<ResponseField name="propertySets" type="BmPsets">
  v2 interoperable name. `psets` remains readable for v1 documents.
</ResponseField>

<ResponseField name="psets" type="BmPsets" />

<ResponseField name="site" type="BmSite">
  Optional site framing. Present so a multi-building document has somewhere to say where it is.
</ResponseField>

<ResponseField name="buildings" type="BmBuilding[]" required />

<ResponseField name="assets" type="Record<string, BmAssetRef>">
  Catalog assets, referenced by instances. `.op` / `.opbase` remain the asset format.
</ResponseField>

<ResponseField name="conditioning" type="BmConditioning">
  Conditioning-export metadata; absent means sensible defaults.
</ResponseField>

### BmArcObject

A circular arc authored in a building working plane; angles are radians.

```typescript theme={null}
interface BmArcObject {
  kind: 'arc';
  id: string;
  workingPlaneId: string;
  center: [number, number];
  radius: number;
  startAngle: number;
  sweepAngle: number;
  color?: BmColor;
}
```

<ResponseField name="kind" type="'arc'" required />

<ResponseField name="id" type="string" required />

<ResponseField name="workingPlaneId" type="string" required />

<ResponseField
  name="center"
  type="[
number,
number
]"
  required
/>

<ResponseField name="radius" type="number" required />

<ResponseField name="startAngle" type="number" required />

<ResponseField name="sweepAngle" type="number" required>
  Signed sweep, with `0 &lt; abs(sweepAngle) &lt;= 2π`.
</ResponseField>

<ResponseField name="color" type="BmColor" />

### BmCuboidObject

```typescript theme={null}
type BmCuboidObject = BmCuboidSizeObject | BmCuboidFreeformObject;
```

### BmCylinderObject

An analytic upright cylinder centered in a horizontal building working plane.

```typescript theme={null}
interface BmCylinderObject {
  kind: 'cylinder';
  id: string;
  workingPlaneId: string;
  center: [number, number];
  radius: number;
  height: number;
  color?: BmColor;
}
```

### BmCuboidSizeObject

An upright solid dimensioned around a horizontal working-plane center.

```typescript theme={null}
interface BmCuboidSizeObject extends BmCuboidBase {
  mode: 'size';
  center: [number, number];
  width: number;
  breadth: number;
}
```

### BmCuboidFreeformObject

An upright extrusion with an authored footprint and optional through holes.

```typescript theme={null}
interface BmCuboidFreeformObject extends BmCuboidBase {
  mode: 'freeform';
  outerRing: [number, number][];
  holes?: [number, number][][];
}
```

### BmLineObject

A straight segment authored in the local coordinates of a building working plane.

```typescript theme={null}
interface BmLineObject {
  kind: 'line';
  id: string;
  workingPlaneId: string;
  start: [number, number];
  end: [number, number];
  color?: BmColor;
}
```

### BmPolylineObject

An open path authored as vertices in a building working plane.

```typescript theme={null}
interface BmPolylineObject {
  kind: 'polyline';
  id: string;
  workingPlaneId: string;
  vertices: [number, number][];
  color?: BmColor;
}
```

### BmPolygonObject

A filled profile authored in a building working plane.

```typescript theme={null}
interface BmPolygonObject {
  kind: 'polygon';
  id: string;
  workingPlaneId: string;
  outerRing: [number, number][];
  holes?: [number, number][][];
  color?: BmColor;
}
```

### BmRectangleObject

```typescript theme={null}
type BmRectangleObject = BmRectangleSizeObject | BmRectangleFreeformObject;
```

### BmRectangleSizeObject

A rectangle dimensioned around a center in plane-local coordinates.

```typescript theme={null}
interface BmRectangleSizeObject extends BmRectangleBase {
  mode: 'size';
  center: [number, number];
  width: number;
  breadth: number;
}
```

### BmRectangleFreeformObject

An edited rectangle saved as an arbitrary filled plane-local profile.

```typescript theme={null}
interface BmRectangleFreeformObject extends BmRectangleBase {
  mode: 'freeform';
  outerRing: [number, number][];
  holes?: [number, number][][];
}
```

### BmModelObject

Extend this discriminated union as additional model primitives are supported.

```typescript theme={null}
type BmModelObject =
  | BmLineObject
  | BmArcObject
  | BmPolylineObject
  | BmPolygonObject
  | BmRectangleObject
  | BmCuboidObject
  | BmCylinderObject;
```

### BmWorkingPlane

A named local 2D frame in world XYZ coordinates.

```typescript theme={null}
interface BmWorkingPlane {
  id: string;
  name?: string;
  origin: Vec3;
  xAxis: Vec3;
  yAxis: Vec3;
}
```

### BmColor

A colour as `#rrggbb`.

```typescript theme={null}
type BmColor = string;
```

### BmSceneCategory

```typescript theme={null}
type BmSceneCategory = 'interior' | 'exterior' | 'aerial';
```

### BmPsetValue

```typescript theme={null}
type BmPsetValue = boolean | number | string;
```

### BmPsets

```typescript theme={null}
type BmPsets = PropertySets;
```

### BmCameraPose

A camera pose.

```typescript theme={null}
interface BmCameraPose {
  position: [number, number, number];
  target: [number, number, number];
  ogid?: string;
  t?: number;
  category?: BmSceneCategory;
}
```

### BmSite

The parcel.

```typescript theme={null}
interface BmSite {
  id: string;
  name?: string;
  boundary?: PolygonProfile;
  lotLines?: LotLineClass[];
  elevation?: number;
  geoAnchor?: GeoAnchor;
  trueNorthDeg?: number;
  zoning?: ZoningRuleSet;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="name" type="string" />

<ResponseField name="boundary" type="PolygonProfile">
  Parcel in the world XZ plane; holes are excluded islands.
</ResponseField>

<ResponseField name="lotLines" type="LotLineClass[]">
  One class per outer-ring edge of `boundary` (edge i = `outerRing[i] → [i+1]`).
</ResponseField>

<ResponseField name="elevation" type="number">
  World Y of grade. Default 0.
</ResponseField>

<ResponseField name="geoAnchor" type="GeoAnchor">
  WGS84 anchor for the local origin, if the project is georeferenced.
</ResponseField>

<ResponseField name="trueNorthDeg" type="number">
  Degrees from project north (−Z) to true north, positive clockwise from above.
</ResponseField>

<ResponseField name="zoning" type="ZoningRuleSet">
  The zoning rules this document was evaluated against — values are the consumer's; the schema and
  evaluator are `zoning/`.
</ResponseField>

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

### BmConditioning

```typescript theme={null}
interface BmConditioning {
  sceneId?: string;
  category?: BmSceneCategory;
  axisTags?: Record<string, string>;
  poses?: BmCameraPose[];
}
```

<ResponseField name="sceneId" type="string" />

<ResponseField name="category" type="BmSceneCategory" />

<ResponseField name="axisTags" type="Record<string, string>" />

<ResponseField name="poses" type="BmCameraPose[]">
  Default poses. `--cameras` and `--sample-cameras` both override these.
</ResponseField>

### BmBuilding

```typescript theme={null}
interface BmBuilding {
  id: string;
  name?: string;
  buildingType?: string;
  propertySets?: BmPsets;
  psets?: BmPsets;
  workingPlanes?: BmWorkingPlane[];
  mass?: BmMass;
  storeys: BmStorey[];
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="name" type="string" />

<ResponseField name="buildingType" type="string">
  Free-form programme tag — `residential`, `office`, … Kept open; consumers disagree on the set.
</ResponseField>

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

<ResponseField name="workingPlanes" type="BmWorkingPlane[]">
  Named world-space frames for model objects owned by this building.
</ResponseField>

<ResponseField name="mass" type="BmMass">
  The massing volume, when the building is (also) a mass. Its segments REFERENCE storeys in
  `storeys` by id — the storey list stays the single source of elevations and heights, and a storey
  may carry zero elements while the mass gives it a body.
</ResponseField>

<ResponseField name="storeys" type="BmStorey[]" required />

### BmMassSegment

One extruded segment of a mass (podium, tower, setback), bottom-up.

```typescript theme={null}
interface BmMassSegment {
  id: string;
  name?: string;
  footprint: PolygonProfile;
  height: number;
  use?: string;
  color?: BmColor;
  storeyIds: string[];
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="name" type="string" />

<ResponseField name="footprint" type="PolygonProfile" required>
  Footprint in the world XZ plane; holes are courtyards.
</ResponseField>

<ResponseField name="height" type="number" required>
  Extrusion height. Must equal the sum of the referenced storeys' heights.
</ResponseField>

<ResponseField name="use" type="string">
  `BuildingUse` value, or any string (`custom:` is implied).
</ResponseField>

<ResponseField name="color" type="BmColor">
  Colour of this part, `#rrggbb`. A part without one takes the `color` of the mass, else the colour
  of its use in the palette of the build (`MASS_COLORS_BY_USE`, or `BuildOptions.massColors`), else
  `#a0b8c8`.
</ResponseField>

<ResponseField name="storeyIds" type="string[]" required>
  Ids of the storeys that tile this segment, bottom-up and contiguous.
</ResponseField>

### BmMass

```typescript theme={null}
interface BmMass {
  id: string;
  elevation: number;
  use?: string;
  color?: BmColor;
  propertySets?: BmPsets;
  segments: BmMassSegment[];
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="elevation" type="number" required>
  World Y of the bottom face of `segments[0]`.
</ResponseField>

<ResponseField name="use" type="string" />

<ResponseField name="color" type="BmColor">
  Colour of every part of the mass that has no `color` of its own, `#rrggbb`.
</ResponseField>

<ResponseField name="propertySets" type="BmPsets">
  Data on the physical mass element; building-scope data stays on `BmBuilding`.
</ResponseField>

<ResponseField name="segments" type="BmMassSegment[]" required />

### BmWallSegmentRef

Authored identity of one segment, including a closed run's final wrap segment.

```typescript theme={null}
interface BmWallSegmentRef {
  wallId: string;
  segmentIndex: number;
}
```

### BmDetachedFaceTrim

Auxiliary face trim; axes and host/opening ownership stay in authored walls.

```typescript theme={null}
interface BmDetachedFaceTrim {
  wall: BmWallSegmentRef;
  end: import('../../elements/walls/wall-model').WallEnd;
  host: BmWallSegmentRef;
  source?: 'T' | 'X';
}
```

### BmWallNetworkState

V4 reconstruction state; saved nonautomatic joining is not supported yet.

```typescript theme={null}
interface BmWallNetworkState {
  options: import('../../elements/walls/wall-model').WallNetworkOptions & {
    autoJoin: true;
  };
  detachedFaceTrims: BmDetachedFaceTrim[];
}
```

### BmStorey

One storey.

```typescript theme={null}
interface BmStorey {
  id: string;
  name?: string;
  elevation: number;
  height: number;
  usage?: string;
  areaKind?: AreaKind;
  propertySets?: BmPsets;
  psets?: BmPsets;
  walls?: BmWall[];
  modelObjects?: BmModelObject[];
  unhostedOpenings?: BmUnhostedOpening[];
  wallJoins?: import('../../elements/walls/wall-model').WallJoinOverride[];
  wallNetworkState?: BmWallNetworkState;
  slabs?: BmSlab[];
  roofs?: BmRoof[];
  columns?: BmColumn[];
  beams?: BmBeam[];
  spaces?: BmSpace[];
  stairs?: BmStair[];
  railings?: BmRailing[];
  instances?: BmAssetInstance[];
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="name" type="string" />

<ResponseField name="elevation" type="number" required>
  World Y of this storey's structural floor datum.
</ResponseField>

<ResponseField name="height" type="number" required>
  Floor-to-floor height. Also the default wall height for walls that omit one.
</ResponseField>

<ResponseField name="usage" type="string">
  Programme for this storey — `retail`, `residential`, …
</ResponseField>

<ResponseField name="areaKind" type="AreaKind">
  What the plate of this storey counts as (basement, core, parking, ...). Derived when absent: a
  `parking` use gives `parking`, a storey whose top is at or below the site grade gives `basement`,
  otherwise `gross`. Zoning counts toward the floor area ratio only the kinds in `countsTowardFAR`.
</ResponseField>

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

<ResponseField name="walls" type="BmWall[]" />

<ResponseField name="modelObjects" type="BmModelObject[]">
  Basic geometry saved in this storey, placed by a building working plane.
</ResponseField>

<ResponseField name="unhostedOpenings" type="BmUnhostedOpening[]">
  v3 openings placed in the world XZ plane without a host wall.
</ResponseField>

<ResponseField name="wallJoins" type="import('../../elements/walls/wall-model').WallJoinOverride[]" />

<ResponseField name="wallNetworkState" type="BmWallNetworkState">
  V4 only. Restored before the first network resolution; never a second wall model.
</ResponseField>

<ResponseField name="slabs" type="BmSlab[]" />

<ResponseField name="roofs" type="BmRoof[]" />

<ResponseField name="columns" type="BmColumn[]" />

<ResponseField name="beams" type="BmBeam[]" />

<ResponseField name="spaces" type="BmSpace[]" />

<ResponseField name="stairs" type="BmStair[]" />

<ResponseField name="railings" type="BmRailing[]" />

<ResponseField name="instances" type="BmAssetInstance[]" />

### BmWall

```typescript theme={null}
interface BmWall {
  id: string;
  labelName?: string;
  points: PointXZ[];
  closed?: boolean;
  locationLine?: import('../../elements/walls/wall-model').LocationLine;
  locationOffset?: number;
  priority?: number;
  joins?: {
    start: import('../../elements/walls/wall-model').WallEndJoin;
    end: import('../../elements/walls/wall-model').WallEndJoin;
  };
  thickness: number;
  height?: number;
  material?: WallMaterial | string;
  color?: BmColor;
  propertySets?: BmPsets;
  psets?: BmPsets;
  openings?: BmOpening[];
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="labelName" type="string" />

<ResponseField name="points" type="PointXZ[]" required>
  Centreline in the world XZ plane. Network walls require horizontal paths, so there is no Y here to
  get wrong; the compiler places it at the storey's elevation.
</ResponseField>

<ResponseField name="closed" type="boolean" />

<ResponseField name="locationLine" type="import('../../elements/walls/wall-model').LocationLine" />

<ResponseField name="locationOffset" type="number" />

<ResponseField name="priority" type="number" />

<ResponseField
  name="joins"
  type="{
start: import('../../elements/walls/wall-model').WallEndJoin;
end: import('../../elements/walls/wall-model').WallEndJoin;
}"
/>

<ResponseField name="thickness" type="number" required />

<ResponseField name="height" type="number">
  Defaults to the owning storey's `height`.
</ResponseField>

<ResponseField name="material" type="WallMaterial | string" />

<ResponseField name="color" type="BmColor" />

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

<ResponseField name="openings" type="BmOpening[]">
  Hosted by this wall. The nesting IS the host relationship.
</ResponseField>

### BmStationAlong

Distance along the wall centreline from `points[0]`, accumulated across segments and including the closing segment when `closed`.

```typescript theme={null}
type BmStationAlong = number;
```

### BmOpening

```typescript theme={null}
type BmOpening = BmDoor | BmWindow | BmVoid;
```

### BmUnhostedOpening

An opening placed in the world XZ plane, with no wall cutter or host relationship.

```typescript theme={null}
type BmUnhostedOpening = BmUnhostedDoor | BmUnhostedWindow;
```

### BmUnhostedDoor

```typescript theme={null}
type BmUnhostedDoor = Omit<BmDoor, 'offset'> & BmUnhostedOpeningPose;
```

### BmUnhostedWindow

```typescript theme={null}
type BmUnhostedWindow = Omit<BmWindow, 'offset'> & BmUnhostedOpeningPose;
```

### BmUnhostedOpeningPose

```typescript theme={null}
interface BmUnhostedOpeningPose {
  position: PointXZ;
  yawDeg: number;
  frameDepth?: number;
  offset?: never;
  hostWallId?: never;
  hostId?: never;
  wallId?: never;
}
```

<ResponseField name="position" type="PointXZ" required>
  World \[X, Z] position in metres.
</ResponseField>

<ResponseField name="yawDeg" type="number" required>
  Degrees in the world XZ plane: +X is 0, turning toward +Z is positive.
</ResponseField>

<ResponseField name="frameDepth" type="number">
  Former host wall depth, or an authored frame depth. Defaults to 0.15 m.
</ResponseField>

<ResponseField name="offset" type="never" />

<ResponseField name="hostWallId" type="never" />

<ResponseField name="hostId" type="never" />

<ResponseField name="wallId" type="never" />

### BmOpeningBase

```typescript theme={null}
interface BmOpeningBase {
  id: string;
  labelName?: string;
  offset: BmStationAlong;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

### BmDoor

```typescript theme={null}
interface BmDoor extends BmOpeningBase {
  kind: 'door';
  width: number;
  height: number;
  baseHeight?: number;
  frameWidth?: number;
  panelThickness?: number;
  doorType?: DoorType;
  doorQuadrant?: 1 | 2 | 3 | 4;
  swingAngleDegrees?: number;
  color?: BmColor;
  frameColor?: BmColor;
}
```

<ResponseField name="kind" type="'door'" required />

<ResponseField name="width" type="number" required />

<ResponseField name="height" type="number" required />

<ResponseField name="baseHeight" type="number">
  Threshold height above the wall base. A real 3D position for a door. Default 0.
</ResponseField>

<ResponseField name="frameWidth" type="number" />

<ResponseField name="panelThickness" type="number" />

<ResponseField name="doorType" type="DoorType" />

<ResponseField name="doorQuadrant" type="1 | 2 | 3 | 4">
  Which way the door swings, as a 2x2 of hinge side x swing face.
</ResponseField>

<ResponseField name="swingAngleDegrees" type="number" />

<ResponseField name="color" type="BmColor" />

<ResponseField name="frameColor" type="BmColor" />

### BmWindow

```typescript theme={null}
interface BmWindow extends BmOpeningBase {
  kind: 'window';
  width: number;
  height: number;
  sillHeight: number;
  frameWidth?: number;
  paneThickness?: number;
  windowType?: WindowType;
  frameColor?: BmColor;
  glassColor?: BmColor;
}
```

<ResponseField name="kind" type="'window'" required />

<ResponseField name="width" type="number" required />

<ResponseField name="height" type="number" required />

<ResponseField name="sillHeight" type="number" required>
  Bottom of the glass above the wall base — the only vertical control for a window.
</ResponseField>

<ResponseField name="frameWidth" type="number" />

<ResponseField name="paneThickness" type="number" />

<ResponseField name="windowType" type="WindowType" />

<ResponseField name="frameColor" type="BmColor" />

<ResponseField name="glassColor" type="BmColor" />

### BmVoid

A plain unfilled hole — `WallOpening`.

```typescript theme={null}
interface BmVoid extends BmOpeningBase {
  kind: 'void';
  width: number;
  height: number;
  sillHeight?: number;
}
```

<ResponseField name="kind" type="'void'" required />

<ResponseField name="width" type="number" required />

<ResponseField name="height" type="number" required />

<ResponseField name="sillHeight" type="number">
  Sill height above the wall base. Default 0.
</ResponseField>

### BmSlabRole

Which class to build.

```typescript theme={null}
type BmSlabRole = 'slab' | 'floor' | 'ceiling';
```

### BmSlab

```typescript theme={null}
interface BmSlab {
  id: string;
  labelName?: string;
  role?: BmSlabRole;
  profile: PolygonProfile;
  thickness: number;
  baseOffset: number;
  material?: SlabMaterial | FloorMaterial | CeilingMaterial;
  color?: BmColor;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="labelName" type="string" />

<ResponseField name="role" type="BmSlabRole" />

<ResponseField name="profile" type="PolygonProfile" required />

<ResponseField name="thickness" type="number" required />

<ResponseField name="baseOffset" type="number" required>
  Metres above the storey's `elevation` to the plate's BOTTOM face (its underside, for a ceiling).
</ResponseField>

<ResponseField name="material" type="SlabMaterial | FloorMaterial | CeilingMaterial" />

<ResponseField name="color" type="BmColor" />

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

### BmRoof

```typescript theme={null}
interface BmRoof {
  id: string;
  labelName?: string;
  profile: PolygonProfile;
  roofType?: RoofType;
  pitch?: number;
  overhang?: number;
  thickness: number;
  baseOffset: number;
  ridgeDirection?: number;
  massStyle?: boolean;
  material?: RoofMaterial;
  color?: BmColor;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="labelName" type="string" />

<ResponseField name="profile" type="PolygonProfile" required />

<ResponseField name="roofType" type="RoofType" />

<ResponseField name="pitch" type="number" />

<ResponseField name="overhang" type="number" />

<ResponseField name="thickness" type="number" required />

<ResponseField name="baseOffset" type="number" required>
  Metres above the storey's `elevation` to the EAVE (the wall-plate top).
</ResponseField>

<ResponseField name="ridgeDirection" type="number" />

<ResponseField name="massStyle" type="boolean" />

<ResponseField name="material" type="RoofMaterial" />

<ResponseField name="color" type="BmColor" />

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

### BmStair

A stair on a storey.

```typescript theme={null}
interface BmStair {
  id: string;
  labelName?: string;
  layout?: StairLayout;
  origin: PointXZ;
  rotation?: number;
  baseOffset: number;
  width?: number;
  totalRise?: number;
  treadDepth?: number;
  riserHeight?: number;
  maxRiserHeight?: number;
  landingDepth?: number;
  turnDirection?: StairTurnDirection;
  showBreakLine?: boolean;
  color?: BmColor;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="labelName" type="string" />

<ResponseField name="layout" type="StairLayout">
  Defaults to `STRAIGHT`.
</ResponseField>

<ResponseField name="origin" type="PointXZ" required>
  Plan position of the first flight's walkline start.
</ResponseField>

<ResponseField name="rotation" type="number">
  Plan rotation in degrees about `origin`, CCW from above. Defaults to 0.
</ResponseField>

<ResponseField name="baseOffset" type="number" required>
  Metres above the storey's `elevation` to the stair base.
</ResponseField>

<ResponseField name="width" type="number">
  Flight width. Defaults to 1 m.
</ResponseField>

<ResponseField name="totalRise" type="number">
  Level-to-level rise. Defaults to the storey's `height`, which is what a stair inside a storey
  almost always climbs.
</ResponseField>

<ResponseField name="treadDepth" type="number">
  Tread depth / going. Defaults to 0.28 m.
</ResponseField>

<ResponseField name="riserHeight" type="number">
  Target riser height; the solver fits equal risers at or below this and `maxRiserHeight`.
</ResponseField>

<ResponseField name="maxRiserHeight" type="number">
  Hard riser cap. Defaults to 0.19 m.
</ResponseField>

<ResponseField name="landingDepth" type="number">
  Landing depth for L and U layouts, clamped to at least `width`. Defaults to 1 m.
</ResponseField>

<ResponseField name="turnDirection" type="StairTurnDirection">
  Which way an L or U turns walking up. Defaults to `left`.
</ResponseField>

<ResponseField name="showBreakLine" type="boolean">
  Draw the conventional break line across the first flight in plan. Defaults to true.
</ResponseField>

<ResponseField name="color" type="BmColor" />

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

### BmRailing

A railing, as a path in WORLD coordinates rather than relative to the storey — a stair-hosted rail follows the flight nosings and therefore climbs through the storey, so a single `baseOffset` could not describe it.

```typescript theme={null}
interface BmRailing {
  id: string;
  labelName?: string;
  path: [number, number, number][];
  height?: number;
  color?: BmColor;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="labelName" type="string" />

<ResponseField
  name="path"
  type="[
number,
number,
number
][]"
  required
>
  Rail base path, world coordinates, `[x, y, z]` per point. Segments may slope.
</ResponseField>

<ResponseField name="height" type="number">
  Rail height above the base path. Defaults to 1 m; guard code typically wants at least that.
</ResponseField>

<ResponseField name="color" type="BmColor" />

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

### BmColumn

```typescript theme={null}
interface BmColumn {
  id: string;
  labelName?: string;
  shape?: ColumnShape;
  center: PointXZ;
  rotation?: number;
  baseOffset: number;
  height?: number;
  width?: number;
  depth?: number;
  radius?: number;
  customProfile?: PolygonProfile;
  material?: ColumnMaterial;
  color?: BmColor;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="labelName" type="string" />

<ResponseField name="shape" type="ColumnShape" />

<ResponseField name="center" type="PointXZ" required />

<ResponseField name="rotation" type="number" />

<ResponseField name="baseOffset" type="number" required>
  Metres above the storey's `elevation` to the column base.
</ResponseField>

<ResponseField name="height" type="number">
  Defaults to the storey's `height`.
</ResponseField>

<ResponseField name="width" type="number" />

<ResponseField name="depth" type="number" />

<ResponseField name="radius" type="number" />

<ResponseField name="customProfile" type="PolygonProfile" />

<ResponseField name="material" type="ColumnMaterial" />

<ResponseField name="color" type="BmColor" />

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

### BmBeam

```typescript theme={null}
interface BmBeam {
  id: string;
  labelName?: string;
  shape?: BeamShape;
  start: [number, number, number];
  end: [number, number, number];
  width?: number;
  depth?: number;
  radius?: number;
  customProfile?: PolygonProfile;
  material?: ColumnMaterial;
  color?: BmColor;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="labelName" type="string" />

<ResponseField name="shape" type="BeamShape" />

<ResponseField
  name="start"
  type="[
number,
number,
number
]"
  required
>
  `[x, yOffset, z]` — y is STOREY-RELATIVE, unlike `BeamOptions.start` which is world.
</ResponseField>

<ResponseField
  name="end"
  type="[
number,
number,
number
]"
  required
/>

<ResponseField name="width" type="number" />

<ResponseField name="depth" type="number" />

<ResponseField name="radius" type="number" />

<ResponseField name="customProfile" type="PolygonProfile" />

<ResponseField name="material" type="ColumnMaterial" />

<ResponseField name="color" type="BmColor" />

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

### BmSpace

```typescript theme={null}
interface BmSpace {
  id: string;
  name: string;
  number?: string;
  profile: PolygonProfile;
  baseOffset?: number;
  height?: number;
  show3D?: boolean;
  color?: BmColor;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

### BmAssetRef

```typescript theme={null}
type BmAssetRef =
  | {
      kind: 'external-op';
      uri: string;
    }
  | {
      kind: 'embedded-op';
      definition: unknown;
    };
```

### BmAssetInstance

```typescript theme={null}
interface BmAssetInstance {
  id: string;
  assetRef: string;
  position: [number, number, number];
  rotationYDeg?: number;
  scale?: [number, number, number];
  labelName?: string;
  propertySets?: BmPsets;
  psets?: BmPsets;
}
```

<ResponseField name="id" type="string" required />

<ResponseField name="assetRef" type="string" required />

<ResponseField
  name="position"
  type="[
number,
number,
number
]"
  required
>
  `position.y` is STOREY-RELATIVE; the compiler adds the storey elevation.
</ResponseField>

<ResponseField name="rotationYDeg" type="number" />

<ResponseField
  name="scale"
  type="[
number,
number,
number
]"
/>

<ResponseField name="labelName" type="string" />

<ResponseField name="propertySets" type="BmPsets" />

<ResponseField name="psets" type="BmPsets" />

### BmIssue

```typescript theme={null}
interface BmIssue {
  path: string;
  code: string;
  message: string;
  openingFit?: BmOpeningFit;
}
```

<ResponseField name="path" type="string" required>
  JSON path into the document, e.g. `buildings[0].storeys[0].walls[1].openings[2].offset`.
</ResponseField>

<ResponseField name="code" type="string" required>
  Stable machine code, so a caller can branch without parsing prose.
</ResponseField>

<ResponseField name="message" type="string" required>
  One sentence, with the numbers in it.
</ResponseField>

<ResponseField name="openingFit" type="BmOpeningFit">
  The numbers of an `opening-does-not-fit` issue.
</ResponseField>

### BmOpeningFit

Where a hosted opening fits on its wall, in offsets along the saved centreline of that wall.

```typescript theme={null}
interface BmOpeningFit {
  wallId: string;
  openingId: string;
  offset: number;
  fitRange: {
    start: number;
    end: number;
  } | null;
  nearestOffset: number | null;
  reasons: WallOpeningFitReason[];
}
```

<ResponseField name="wallId" type="string" required />

<ResponseField name="openingId" type="string" required />

<ResponseField name="offset" type="number" required>
  The offset that was asked or saved.
</ResponseField>

<ResponseField
  name="fitRange"
  type="{
start: number;
end: number;
} | null"
  required
>
  The range of fitting offsets on its wall segment that holds `nearestOffset`; null when none.
</ResponseField>

<ResponseField name="nearestOffset" type="number | null" required>
  The fitting offset nearest to `offset`, or null when the opening fits nowhere there.
</ResponseField>

<ResponseField name="reasons" type="WallOpeningFitReason[]" required>
  Why it does not fit; `t-junction` alone means it is over the seam of a T stem.
</ResponseField>

### BmValidationResult

```typescript theme={null}
interface BmValidationResult {
  ok: boolean;
  errors: BmIssue[];
  warnings: BmIssue[];
}
```

### BmCuboidBase

The package does not export this type by name.

```typescript theme={null}
interface BmCuboidBase {
  kind: 'cuboid';
  id: string;
  workingPlaneId: string;
  height: number;
  color?: BmColor;
}
```

### BmRectangleBase

The package does not export this type by name.

```typescript theme={null}
interface BmRectangleBase {
  kind: 'rectangle';
  id: string;
  workingPlaneId: string;
  color?: BmColor;
}
```

## Related

* [`AreaKind`](/floorkit/api/architecture/massing-helpers#areakind)
* [`BeamShape`](/floorkit/api/architecture/beam#beamshape)
* [`CeilingMaterial`](/floorkit/api/architecture/ceiling#ceilingmaterial)
* [`ColumnMaterial`](/floorkit/api/architecture/column#columnmaterial)
* [`ColumnShape`](/floorkit/api/architecture/column#columnshape)
* [`DoorType`](/floorkit/api/architecture/door#doortype)
* [`FloorMaterial`](/floorkit/api/architecture/floor#floormaterial)
* [`GeoAnchor`](/floorkit/api/world/site#geoanchor)
* [`LocationLine`](/floorkit/api/architecture/wall#locationline)
* [`LotLineClass`](/floorkit/api/world/site#lotlineclass)
* [`PointXZ`](/floorkit/api/primitives/polygon-maths#pointxz)
* [`PolygonProfile`](/floorkit/api/primitives/polygon-maths#polygonprofile)
* [`PropertySets`](/floorkit/api/architecture/op-element#propertysets)
* [`RoofMaterial`](/floorkit/api/architecture/roof#roofmaterial)
* [`RoofType`](/floorkit/api/architecture/roof#rooftype)
* [`SlabMaterial`](/floorkit/api/architecture/slab#slabmaterial)
* [`StairLayout`](/floorkit/api/architecture/stair#stairlayout)
* [`StairTurnDirection`](/floorkit/api/architecture/stair#stairturndirection)
* [`Vec3`](/floorkit/api/architecture/wall#vec3)
* [`WallEnd`](/floorkit/api/architecture/wall-network#wallend)
* [`WallEndJoin`](/floorkit/api/architecture/wall#wallendjoin)
* [`WallJoinOverride`](/floorkit/api/architecture/wall-network#walljoinoverride)
* [`WallMaterial`](/floorkit/api/architecture/wall#wallmaterial)
* [`WallNetworkOptions`](/floorkit/api/architecture/wall-network#wallnetworkoptions)
* [`WallOpeningFitReason`](/floorkit/api/architecture/wall#wallopeningfitreason)
* [`WindowType`](/floorkit/api/architecture/window#windowtype)
* [`ZoningRuleSet`](/floorkit/api/world/zoning-rules#zoningruleset)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.