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

# Opening

> Opening is the base class of Door, Window and WallOpening.

Use it only when you need a free cutter shape. For a hole in a wall, use one of the three subclasses.

## Import

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

## Example

```typescript theme={null}
import { Opening, Floorkit } from '@opengeometry/floorkit';

async function example(wasmURL: string): Promise<void> {
  await new Floorkit().setupOpenGeometry(wasmURL);
  const opening = new Opening({
    points: [
      [0, 0],
      [1.2, 0],
    ],
    thickness: 0.3,
    height: 2.1,
    baseHeight: 0,
  });
  try {
    opening.setOPConfig({ ...opening.getOPConfig(), height: 2.2 });
    console.log(opening.holeLoop2D, opening.getAnalyticCutBounds());
  } finally {
    opening.dispose();
  }
}
```

## Notes

* Points are `[alongWall, acrossWall]` in metres. `baseHeight` gives the vertical position.
* An opening does not cut the objects near it. The host does the cut.
* `Wall.attachOpening` accepts a `Door`, a `Window` or a `WallOpening`.
* Start the geometry kernel before you create this object. See [`Floorkit`](/floorkit/api/runtime/floorkit).
* This object is live geometry. To save a building, write it in a [building model](/floorkit/concepts/building-model).

**Inheritance:** `extends OPElement implements IShape, IPlaceable`

## Constructor

```typescript theme={null}
constructor(openingConfig?: Partial<OpeningOptions<T>>);
```

<ParamField path="openingConfig.ogid" type="string" />

<ParamField path="openingConfig.labelName" type="string" />

<ParamField path="openingConfig.type" type="T" />

<ParamField path="openingConfig.hostWallId" type="string" />

<ParamField path="openingConfig.thickness" type="number" />

<ParamField path="openingConfig.height" type="number" />

<ParamField path="openingConfig.baseHeight" type="number">
  THE vertical authority: the bottom of the rough opening, measured above the host wall's base.
  Never a world Y — the host frame's origin supplies the storey elevation, so `world.y =
      frame.origin.y + baseHeight`. Without a host or free placement, the identity frame makes
  `baseHeight` world Y.
</ParamField>

<ParamField path="openingConfig.length" type="number" />

<ParamField path="openingConfig.points" type="[number, number][]" />

<ParamField path="openingConfig.propertySets" type="PropertySets" />

## Properties

<ResponseField name="ogType" type="T" />

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

<ResponseField name="subElements2D" type="Map<string, OPGeometry>" />

<ResponseField name="subElements3D" type="Map<string, OPGeometry>" />

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

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

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

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

<ResponseField name="onOpeningUpdated" type="Event<null>" />

<ResponseField name="propertySet" type="OpeningOptions<T>" />

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

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

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

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

<ResponseField name="alongWall" type="number">
  Read-only. Where this opening currently sits along its host wall — the counterpart of `baseHeight`
  for the horizontal axis. Read by the walls so that attaching without an explicit `offset`
  preserves an authored position instead of snapping the opening back to the wall's start.
</ResponseField>

<ResponseField name="baseHeight" type="number">
  Bottom of the rough opening above the host wall's base. See OpeningOptions.
</ResponseField>

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

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

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

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

<ResponseField name="holeLoop2D" type="Vector3[]">
  Read-only. Plan-view hole loop (Vector3\[] in the XZ plane at Y=0). The wall uses this as a Polygon
  hole. The 1 µm across-wall inset keeps hole edges strictly inside the outer polygon so the WASM
  triangulator does not produce degenerate output when edges coincide with the boundary.
</ResponseField>

<ResponseField name="opening3D" type="AnalyticSolid">
  Read-only.
</ResponseField>

## Methods

### bindHostEdit

```typescript theme={null}
bindHostEdit(callbacks: {
    begin: () => void;
    preview?: (position: Vec3, snapRadius: number) => void;
    commit: () => {
        undo: () => void;
        redo: () => void;
    } | void;
} | null): void;
```

### beginEdit

```typescript theme={null}
beginEdit(): void;
```

### endEdit

```typescript theme={null}
endEdit(): {
    undo: () => void;
    redo: () => void;
} | undefined;
```

### bindHostCurve

```typescript theme={null}
bindHostCurve(curve: OpeningHostCurve | null): void;
```

### move

```typescript theme={null}
move(delta: Vec3): void;
```

Translate this opening by a WORLD-space `delta`, hosted or not — the delta is projected onto the active frame's axes (identity when no frame is bound), so there is one interpretation rather than one per hosting state.

### rotate

```typescript theme={null}
rotate(angleDeg: number, axis?: Vec3, anchor?: Vec3): void;
```

Rotate this element by `angleDeg` around `axis` (default Y-up), pivoted at `anchor` (default the element's own centroid).

### setOPConfig

```typescript theme={null}
setOPConfig(config: OpeningOptions<T>): void;
```

### getOPConfig

```typescript theme={null}
getOPConfig(): OpeningOptions<T>;
```

### anchorSpace

```typescript theme={null}
anchorSpace(): "local" | "world";
```

Two draggable endpoints.

### getEditAnchors

```typescript theme={null}
getEditAnchors(): EditAnchor[];
```

### applyEditAnchor

```typescript theme={null}
applyEditAnchor(id: string, position: [
    number,
    number,
    number
]): void;
```

### bindHostFrame

```typescript theme={null}
bindHostFrame(frame: WallFrame | null): void;
```

Bind this opening to its host wall's frame.

### bindFreePlacement

```typescript theme={null}
bindFreePlacement(placement: FreeOpeningPlacement): void;
```

Place an unhosted opening at a storey datum without creating a wall host.

### toWorldPoints

```typescript theme={null}
toWorldPoints(): Vector3[];
```

Stored centreline points as world-space Vector3s, at `baseHeight`.

### getAnalyticCutBounds

```typescript theme={null}
getAnalyticCutBounds(): AnalyticOpeningCutBounds | null;
```

Exact station/elevation rectangle used by analytic wall subtraction.

### getWorldCutElevationRange

```typescript theme={null}
getWorldCutElevationRange(): {
    bottom: number;
    top: number;
} | null;
```

World Y range of the analytic rough opening, including ancestor placement once.

### dispose

```typescript theme={null}
dispose(): void;
```

### setOPGeometry

```typescript theme={null}
setOPGeometry(): void;
```

### setOPMaterial

```typescript theme={null}
setOPMaterial(): void;
```

## Types

### OPGeometry

Visual primitive stored in an element's subElements2D / subElements3D maps.

```typescript theme={null}
interface OPGeometry extends THREE.Object3D {
  outline?: boolean;
}
```

### OpeningHostCurve

```typescript theme={null}
interface OpeningHostCurve {
  center: [number, number, number];
  radius: number;
  startAngle: number;
  sweepAngle: number;
  centreOffset: number;
}
```

### OpeningOptions

```typescript theme={null}
interface OpeningOptions<T extends ElementType = ElementType.OPENING> extends HasPropertySets {
  ogid?: string;
  labelName: string;
  type: T;
  hostWallId?: string;
  thickness?: number;
  height?: number;
  baseHeight?: number;
  length?: number;
  points?: [number, number][];
}
```

### WallFrame

Wall-local coordinate frame.

The package does not export this type by name.

```typescript theme={null}
interface WallFrame {
  origin: Vector3;
  alongWallAxis: Vector3;
  acrossWallAxis: Vector3;
  verticalAxis: Vector3;
  length: number;
  thickness?: number;
}
```

<ResponseField name="origin" type="Vector3" required />

<ResponseField name="alongWallAxis" type="Vector3" required />

<ResponseField name="acrossWallAxis" type="Vector3" required />

<ResponseField name="verticalAxis" type="Vector3" required />

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

<ResponseField name="thickness" type="number">
  Host wall thickness. Populated when the frame comes from a wall; undefined for unhosted use.
</ResponseField>

### FreeOpeningPlacement

```typescript theme={null}
interface FreeOpeningPlacement {
  position: [x: number, z: number];
  yawDeg: number;
  elevation: number;
}
```

<ResponseField
  name="position"
  type="[
x: number,
z: number
]"
  required
>
  Centre of the opening in the world XZ plane.
</ResponseField>

<ResponseField name="yawDeg" type="number" required>
  Degrees from +X toward +Z.
</ResponseField>

<ResponseField name="elevation" type="number" required>
  World Y of the owning storey's datum.
</ResponseField>

## Related

* [`OPElement`](/floorkit/api/architecture/op-element)
* [`AnalyticOpeningCutBounds`](/floorkit/api/architecture/door#analyticopeningcutbounds)
* [`EditAnchor`](/floorkit/api/architecture/op-element#editanchor)
* [`ElementType`](/floorkit/api/architecture/op-element#elementtype)
* [`Event`](/floorkit/api/architecture/wall-network#event)
* [`HasPropertySets`](/floorkit/api/architecture/op-element#haspropertysets)
* [`IPlaceable`](/floorkit/api/architecture/op-element#iplaceable)
* [`IShape`](/floorkit/api/shapes/cuboid-shape#ishape)
* [`Vec3`](/floorkit/api/architecture/wall#vec3)


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