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

# OpenElement

> OpenElement is a custom element that you define as data.

Use it for furniture, equipment and other objects that are not walls, slabs or roofs. One definition gives a 2D plan symbol and a 3D model.

## Import

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

## Example

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

async function example(wasmURL: string): Promise<void> {
  await new Floorkit().setupOpenGeometry(wasmURL);
  const asset = new OpenElement({
    version: 1,
    id: 'equipment',
    labelName: 'Equipment',
    type: ElementType.FURNITURE,
    dimensions: { width: 1, depth: 0.6, height: 0.9 },
    profileView: {
      elements: [
        {
          id: 'footprint',
          kind: 'polygon',
          vertices: [
            [-0.5, -0.3],
            [0.5, -0.3],
            [0.5, 0.3],
            [-0.5, 0.3],
          ],
        },
      ],
    },
    modelView: {
      elements: [
        { id: 'body', kind: 'cuboid', center: [0, 0.45, 0], width: 1, depth: 0.6, height: 0.9 },
      ],
    },
  });
  try {
    asset.updateNodeProperty('body', 'modelView', 'height', 1.1);
    console.log(asset.getControlSchema(), asset.getOPBuffer());
  } finally {
    asset.dispose();
  }
}
```

## Notes

* The definition uses metres.
* The input can be text, a definition object, or options with a `source`.
* Use `updateNodeProperty` or `setOPConfig` to change the element. An unknown node id throws an error.
* `getOPBuffer` returns the definition as text.
* Start the geometry kernel before you create this object. See [`Floorkit`](/floorkit/api/runtime/floorkit).

**Inheritance:** `extends Polyline implements IShape, PlanVectorExportable, PortOwner`

## Constructor

```typescript theme={null}
constructor(config?: OpenElementInput);
```

## Properties

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

<ResponseField name="subElements2D" type="Map<string, THREE.Object3D>" />

<ResponseField name="subElements3D" type="Map<string, THREE.Object3D>" />

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

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

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

<ResponseField name="propertySet" type="OpenElementConfig" />

<ResponseField name="assetId" type="string">
  Read-only.
</ResponseField>

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

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

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

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

## Methods

### parseBuffer

```typescript theme={null}
static parseBuffer(buffer: string): OpenElementDefinition;
```

### normalizeDefinition

```typescript theme={null}
static normalizeDefinition(definition: unknown): OpenElementDefinition;
```

### getOPBuffer

```typescript theme={null}
getOPBuffer(): string;
```

### getAnchorDefinition

```typescript theme={null}
getAnchorDefinition(anchorId: string): AnchorDefinition | undefined;
```

### getAnchorMatrix

```typescript theme={null}
getAnchorMatrix(anchorId: string): THREE.Matrix4;
```

### getExportRoots

```typescript theme={null}
getExportRoots(view: PlanExportView): THREE.Object3D[];
```

### toDrawing

```typescript theme={null}
toDrawing(view: PlanExportView): DrawingPrimitive[];
```

Standardized plan primitives from the asset's authored 2D profile view.

### setOPConfig

```typescript theme={null}
setOPConfig(config: OpenElementInput): void;
```

### beginEdit

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

Start one live edit; a second `beginEdit` before `endEdit` keeps the first start.

### endEdit

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

End the live edit; its exact undo and redo, or undefined when no option changed.

### getOPConfig

```typescript theme={null}
getOPConfig(): OpenElementConfig;
```

### getControlSchema

```typescript theme={null}
getControlSchema(): ControlSchema;
```

### updateNodeProperty

```typescript theme={null}
updateNodeProperty(nodeId: string, section: "profileView" | "modelView" | "definitions", property: string, value: number | string): void;
```

### getEditAnchors

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

### applyEditAnchor

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

Apply a previewed handle drag.

### dispose

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

### setConfig

```typescript theme={null}
setConfig(options: Parameters<Polyline['setConfig']>[0]): void;
```

### setOPGeometry

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

### setOPMaterial

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

## Types

### PortOwner

```typescript theme={null}
interface PortOwner {
  ogid: string;
  getPorts(): DistributionPort[];
}
```

### OpenElementConfig

```typescript theme={null}
interface OpenElementConfig extends OpenElementDefinition, HasPropertySets {
  ogid?: string;
}
```

### OpenElementInput

```typescript theme={null}
type OpenElementInput = string | OpenElementDefinition | OpenElementOptions;
```

### OpenElementDefinition

```typescript theme={null}
interface OpenElementDefinition {
  version: 1;
  id: string;
  labelName: string;
  type: ElementType;
  dimensions: OpenElementDimensions;
  placement?: Placement;
  metadata?: Record<string, string>;
  anchors?: OpenElementAnchors;
  ports?: PortDefinition[];
  definitions?: OpenElementDefinitions;
  profileView?: OpenElementProfileView;
  modelView?: OpenElementModelView;
}
```

### AnchorDefinition

```typescript theme={null}
interface AnchorDefinition {
  placement: Placement;
  metadata?: Record<string, string>;
}
```

### ControlSchema

```typescript theme={null}
interface ControlSchema {
  nodes: NodeControlDescriptor[];
}
```

### DistributionPort

```typescript theme={null}
interface DistributionPort {
  id: string;
  domain: PortDomain;
  systemType: string;
  flowDirection: PortFlowDirection;
  placement: Placement;
  profile: PortProfile;
  internal?: boolean;
  metadata?: Record<string, string>;
}
```

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

<ResponseField name="domain" type="PortDomain" required />

<ResponseField name="systemType" type="string" required>
  Free-form but conventional: "supplyAir", "chilledWaterSupply", "power".
</ResponseField>

<ResponseField name="flowDirection" type="PortFlowDirection" required />

<ResponseField name="placement" type="Placement" required>
  Local placement on the owning element.
</ResponseField>

<ResponseField name="profile" type="PortProfile" required>
  Cross-section the connecting run must match.
</ResponseField>

<ResponseField name="internal" type="boolean">
  Chain-internal port of a generated run piece. Regenerated wholesale on every path edit, so
  external connections must never target it — the graph rejects such connects with `INTERNAL_PORT`.
</ResponseField>

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

### OpenElementOptions

```typescript theme={null}
interface OpenElementOptions
  extends Partial<Omit<OpenElementConfig, 'version' | 'dimensions'>>, HasPropertySets {
  version?: 1;
  dimensions?: Partial<OpenElementDimensions>;
  source?: string | OpenElementDefinition;
}
```

### OpenElementDimensions

```typescript theme={null}
interface OpenElementDimensions {
  width: number;
  depth: number;
  height: number;
}
```

### OpenElementAnchors

```typescript theme={null}
type OpenElementAnchors = Record<string, AnchorDefinition>;
```

### PortDefinition

A distribution port authored on a `.op` asset.

```typescript theme={null}
type PortDefinition = Omit<DistributionPort, 'internal'>;
```

### OpenElementDefinitions

```typescript theme={null}
type OpenElementDefinitions = Record<string, DefinitionNode>;
```

### OpenElementProfileView

```typescript theme={null}
interface OpenElementProfileView {
  elements: ProfileViewElement[];
}
```

### OpenElementModelView

```typescript theme={null}
interface OpenElementModelView {
  elements: ModelViewElement[];
}
```

### NodeControlDescriptor

```typescript theme={null}
interface NodeControlDescriptor {
  nodeId: string;
  nodeKind: string;
  section: 'profileView' | 'modelView' | 'definitions';
  properties: PropertyDescriptor[];
}
```

### PortDomain

```typescript theme={null}
type PortDomain = 'hvac' | 'piping' | 'electrical' | 'cableCarrier' | 'conduit';
```

### PortFlowDirection

```typescript theme={null}
type PortFlowDirection = 'source' | 'sink' | 'bidirectional';
```

### PortProfile

Cross-section a connecting run must match (or bridge with a transition).

```typescript theme={null}
type PortProfile =
  | {
      shape: 'round';
      diameter: number;
    }
  | {
      shape: 'rectangular';
      width: number;
      height: number;
    }
  | {
      shape: 'tray';
      width: number;
      height: number;
    }
  | {
      shape: 'electrical';
      poles: number;
      voltage?: number;
      amperage?: number;
    };
```

### DefinitionNode

```typescript theme={null}
type DefinitionNode = ProfileNode | Curve3DNode | ModelNode | OperationNode;
```

### ProfileViewElement

```typescript theme={null}
type ProfileViewElement = ProfileNode | RefNode;
```

### ModelViewElement

```typescript theme={null}
type ModelViewElement = ModelNode | RefNode;
```

### PropertyDescriptor

```typescript theme={null}
interface PropertyDescriptor {
  key: string;
  type: ControlPropertyType;
  value: number | string;
  label?: string;
}
```

### ProfileNode

```typescript theme={null}
type ProfileNode = ProfilePolygonNode | ProfilePolylineNode | ProfileArcNode;
```

### Curve3DNode

```typescript theme={null}
type Curve3DNode = Curve3DPolylineNode;
```

### ModelNode

```typescript theme={null}
type ModelNode = ModelCuboidNode | ModelCylinderNode | ModelSweepNode;
```

### OperationNode

```typescript theme={null}
type OperationNode = Offset2DOpNode | Boolean3DOpNode;
```

### RefNode

```typescript theme={null}
interface RefNode extends BaseElementNode {
  ref: string;
}
```

### ControlPropertyType

```typescript theme={null}
type ControlPropertyType = 'number' | 'color';
```

### ProfilePolygonNode

```typescript theme={null}
interface ProfilePolygonNode extends BaseElementNode {
  kind: 'polygon';
  vertices: Point2[];
}
```

### ProfilePolylineNode

```typescript theme={null}
interface ProfilePolylineNode extends BaseElementNode {
  kind: 'polyline';
  points: Point2[];
}
```

### ProfileArcNode

```typescript theme={null}
interface ProfileArcNode extends BaseElementNode {
  kind: 'arc';
  center: Point2;
  radius: number;
  startAngle: number;
  sweepAngle: number;
  deflection?: number;
}
```

### Curve3DPolylineNode

```typescript theme={null}
interface Curve3DPolylineNode extends BaseElementNode {
  kind: 'polyline3d';
  points: Point3[];
}
```

### ModelCuboidNode

```typescript theme={null}
interface ModelCuboidNode extends BaseElementNode {
  kind: 'cuboid';
  center: Point3;
  width: number;
  height: number;
  depth: number;
}
```

### ModelCylinderNode

```typescript theme={null}
interface ModelCylinderNode extends BaseElementNode {
  kind: 'cylinder';
  center: Point3;
  radius: number;
  height: number;
  angle?: number;
}
```

### ModelSweepNode

```typescript theme={null}
type ModelSweepNode = ModelSweepDirectNode | ModelSweepRefNode;
```

### Offset2DOpNode

```typescript theme={null}
interface Offset2DOpNode extends BaseElementNode {
  kind: 'offset2d';
  sourceRef: string;
  distance: number;
  acuteThresholdDegrees?: number;
  bevel?: boolean;
  output: 'polyline' | 'polygon';
}
```

### Boolean3DOpNode

```typescript theme={null}
interface Boolean3DOpNode extends BaseElementNode {
  kind: 'boolean3d';
  operation: 'subtract' | 'union' | 'intersect';
  baseRef: string;
  operandRefs: string[];
}
```

### BaseElementNode

The package does not export this type by name.

```typescript theme={null}
interface BaseElementNode {
  id?: string;
  color?: ColorValue;
  placement?: Placement;
}
```

### Point2

The package does not export this type by name.

```typescript theme={null}
type Point2 = [number, number];
```

### Point3

The package does not export this type by name.

```typescript theme={null}
type Point3 = [number, number, number];
```

### ModelSweepDirectNode

```typescript theme={null}
interface ModelSweepDirectNode extends BaseElementNode {
  kind: 'sweep';
  path: Point3[];
  profile: Point3[];
  capStart?: boolean;
  capEnd?: boolean;
}
```

### ModelSweepRefNode

```typescript theme={null}
interface ModelSweepRefNode extends BaseElementNode {
  kind: 'sweep';
  pathRef: string;
  profileRef: string;
  capStart?: boolean;
  capEnd?: boolean;
}
```

### ColorValue

The package does not export this type by name.

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

## Related

* [`DrawingPrimitive`](/floorkit/api/drawings/draw-project-view#drawingprimitive)
* [`EditAnchor`](/floorkit/api/architecture/op-element#editanchor)
* [`ElementType`](/floorkit/api/architecture/op-element#elementtype)
* [`HasPropertySets`](/floorkit/api/architecture/op-element#haspropertysets)
* [`IShape`](/floorkit/api/shapes/cuboid-shape#ishape)
* [`Placement`](/floorkit/api/shapes/cuboid-shape#placement)
* [`PlanExportView`](/floorkit/api/shapes/cylinder-shape#planexportview)
* [`PlanVectorExportable`](/floorkit/api/shapes/cylinder-shape#planvectorexportable)


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