> ## 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.

# Pure edits

> Apply one edit command to a model without a session.

A pure edit applies one edit command to a building model and returns a new model. It needs no session, and it does not change the model that you give. Use it on a server, in a test, or when you do not need geometry.

## Import

```typescript theme={null}
import {
  applyBuildingEdit,
  applyBuildingEditResolved,
  massSegmentHeightCommand,
  BmEditError,
} from '@opengeometry/floorkit';
```

## Example

```typescript theme={null}
import {
  applyBuildingEdit,
  BmEditError,
  type BmColumn,
  type BuildingModel,
} from '@opengeometry/floorkit';

export function withColumn(model: BuildingModel, column: BmColumn): BuildingModel | undefined {
  try {
    return applyBuildingEdit(model, {
      kind: 'add-element',
      buildingId: 'building',
      storeyId: 'ground',
      list: 'columns',
      element: column,
    });
  } catch (error) {
    if (error instanceof BmEditError) {
      console.error(error.code, error.message);
      return undefined;
    }
    throw error;
  }
}
```

## Notes

* Both functions take a [`BuildingEditCommand`](/floorkit/api/editor/building-session#buildingeditcommand). `applyBuildingEditResolved` takes each `kind`. `applyBuildingEdit` rejects some wall and opening commands, such as `create-wall` and `add-hosted-opening`, with the code `resolved-edit-required`.
* `add-element`, `replace-element` and `remove-element` change one entry of a list of a storey: `slabs`, `roofs`, `spaces`, `stairs`, `columns`, `beams`, `railings` or `instances`. `add-element` rejects an id that the list has. `replace-element` and `remove-element` reject an id that the list does not have. The new element of `replace-element` must have the same id.
* `add-asset`, `replace-asset` and `remove-asset` change one asset of the model. `add-asset` rejects an id that exists. `replace-asset` and `remove-asset` reject an id that does not exist. `remove-asset` rejects an asset that an instance uses.
* `add-storey`, `remove-storey` and `replace-storey-settings` change the storeys of one building. `add-storey` rejects a storey id that the building has. `remove-storey` rejects the last storey of a building. `replace-storey-settings` replaces the `name`, the `elevation`, the `height`, the `usage` and the `areaKind` together. The `areaKind` is what the plate of the storey counts as (`gross`, `balcony`, `core`, `basement`, `parking` or `mechanical`); a value that is not one of these is refused as `invalid-command`.
* `replace-mass` sets the mass of one building and the settings of all its storeys. A storey id that stays keeps its elements, a new id adds an empty storey, and a storey that is left out is removed. It rejects the removal of a storey that holds an element. `massSegmentHeightCommand(model, buildingId, segmentId, height)` gives this command for a new height of one segment.
* `add-building` adds a whole building, last in the list: its storeys, their elements and its optional `mass`. Each id in it must be new in the whole model. The smallest valid building has one storey, and for a massing study a `mass` with one segment whose `storeyIds` names that storey and whose `height` is the height of the storey. `remove-building` removes a building and all it holds; it rejects the last building of the model.
* `replace-site` replaces the site whole: `boundary`, `lotLines`, `elevation`, `geoAnchor`, `trueNorthDeg` and the `zoning` rules. Without `site`, the model has no site any more. The model check refuses a self-intersecting boundary and a `lotLines` list that does not have one class per boundary edge. Run `evaluateZoning` again after the step; the command does not run it.
* A `batch` applies its `commands` in order and returns one model. If one command fails, the error has the code of that command, and its message starts with the place of the command, such as `command 2 of 3:`. A batch cannot be empty and cannot hold a batch.
* A rejected command throws `BmEditError`. The model that you gave is not changed.
* The functions check the full result. For an edit in an app, use a [`BuildingSession`](/floorkit/api/editor/building-session). It also builds the geometry and keeps undo and redo.

## applyBuildingEdit

Apply one saved edit of a building model, or one batch of edits, and return a validated new model.

```typescript theme={null}
function applyBuildingEdit(model: BuildingModel, command: BuildingEditCommand): BuildingModel;
```

**Throws:** \{BmEditError} If the command, target, or resulting geometry is invalid.

## applyBuildingEditResolved

Apply an immutable edit with exact junction-aware hosted-opening decisions.

```typescript theme={null}
function applyBuildingEditResolved(
  model: BuildingModel,
  command: BuildingEditCommand,
): BuildingModel;
```

## massSegmentHeightCommand

The `replace-mass` command that gives one segment of a saved mass the height `height`, snapped to whole storeys at the pitch of its top storey; `undefined` when the snapped height is the saved one.

```typescript theme={null}
function massSegmentHeightCommand(
  model: Readonly<BuildingModel>,
  buildingId: string,
  segmentId: string,
  height: number,
): ReplaceMassCommand | undefined;
```

## BmEditError

A rejected edit; `issues` carries model-validation details when available.

```typescript theme={null}
class BmEditError extends Error {
  readonly code: BmEditErrorCode;
  readonly issues?: BmIssue[];
  constructor(code: BmEditErrorCode, message: string, issues?: BmIssue[]);
}
```

## Types

### BmEditErrorCode

Stable category for a rejected building edit.

```typescript theme={null}
type BmEditErrorCode =
  | 'invalid-command'
  | 'invalid-target'
  | 'hosted-openings-unsupported'
  | 'join-overrides-unsupported'
  | 'resolved-edit-required'
  | 'kernel-unavailable'
  | 'invalid-geometry';
```

### ReplaceMassCommand

Replace the mass of a building and the settings of its whole storey list in one step.

```typescript theme={null}
interface ReplaceMassCommand {
  kind: 'replace-mass';
  buildingId: string;
  mass?: BmMass;
  storeys: MassStoreySettings[];
}
```

### MassStoreySettings

The settings of one storey in a `replace-mass` command; its elements are not part of it.

```typescript theme={null}
interface MassStoreySettings {
  id: string;
  name?: string;
  elevation: number;
  height: number;
  usage?: string;
  areaKind?: AreaKind;
}
```

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

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

<ResponseField name="elevation" type="number" required>
  World Y of the floor of the storey, in metres.
</ResponseField>

<ResponseField name="height" type="number" required>
  Floor-to-floor height in metres.
</ResponseField>

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

<ResponseField name="areaKind" type="AreaKind">
  What the plate of the storey counts as; see `BmStorey.areaKind`.
</ResponseField>

### BuildingCommand

Add or remove a whole building of a model.

```typescript theme={null}
type BuildingCommand =
  | {
      kind: 'add-building';
      building: BmBuilding;
    }
  | {
      kind: 'remove-building';
      buildingId: string;
    };
```

### ReplaceSiteCommand

Replace the site of a model whole: boundary, lot lines, grade, geo anchor, true north and zoning rules.

```typescript theme={null}
interface ReplaceSiteCommand {
  kind: 'replace-site';
  site?: BmSite;
}
```

## Related

* [`AreaKind`](/floorkit/api/architecture/massing-helpers#areakind)
* [`BmBuilding`](/floorkit/api/architecture/validate-building-model#bmbuilding)
* [`BmIssue`](/floorkit/api/architecture/validate-building-model#bmissue)
* [`BmMass`](/floorkit/api/architecture/validate-building-model#bmmass)
* [`BmSite`](/floorkit/api/architecture/validate-building-model#bmsite)
* [`BuildingEditCommand`](/floorkit/api/editor/building-session#buildingeditcommand)
* [`BuildingModel`](/floorkit/api/architecture/validate-building-model#buildingmodel)


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