# Breaking Changes — @twinfinity/core

# 5.x -> 6.x

Breaking changes going from @twinfinity/core 5.x to 6.x

### BimIfcClass

`BimIfcClass` is now a type alias for `ModelProductClass` (from `@twinfinity/t8-client-model`).

#### Static convenience properties removed

The static class references have been removed, use predefined instead.

```typescript
// Before
BimIfcClass.ifcSpace;
BimIfcClass.ifcBuildingStorey;
BimIfcClass.ifcProject;
BimIfcClass.ifcSite;
BimIfcClass.ifcBuilding;
BimIfcClass.ifcCovering;

// After
ModelProductClass.predefined.space;
ModelProductClass.predefined.buildingStorey;
ModelProductClass.predefined.project;
ModelProductClass.predefined.site;
ModelProductClass.predefined.building;
ModelProductClass.predefined.covering;
```

#### `id` no longer includes the `Ifc` prefix

`ModelProductClass.id` now returns the class name without the `Ifc` prefix. This is so that a class of object can be identical independent of source. Code that compared or stored `.id` strings directly must be updated.

```typescript
// Before
o.class.id; // "IfcWall"
classToType.get('IfcWall');

// After
o.class.id; // "Wall"
classToType.get('Wall');
```

The `is()` method still accepts `PredefinedIfcClassId` strings with the prefix (e.g., `o.class.is('IfcWall')`), so behavioral checks using `is()` are unaffected. Use `is()` instead of comparing `.id` directly when possible.

The `type` property (e.g., `"walls"`, `"space"`, `"doors"`) is unchanged and remains the recommended way to group classes by category.

The `ModelProduct.className` does still contain the full name (e.g. `IfcWall`).

#### Counter properties renamed

```typescript
// Before
productClass.ifcObjectCount;
productClass.ifcObjectsWithGeometryCount;

// After
productClass.objectCount;
productClass.objectsWithGeometryCount;
```

### BimIfcObject

`BimIfcObject` now implements `ModelProduct` (from `@twinfinity/t8-client-model`).

#### `properties` and `quantities` replaced

The `BimPropertySets` and `BimQuantitySets` wrapper classes have been removed. Properties and quantities are now accessed directly as `Record<string, T8PropertySet<T8Unit>>` and `Record<string, T8QuantitySet<T8Unit>>`.

#### Accessing property sets

```typescript
// Before
obj.properties.sets['Pset_WallCommon'];
obj.properties.computed['Pset_Twinfinity'];
obj.quantities.sets['Qto_WallBaseQuantities'];

// After
obj.propertySets['Pset_WallCommon'];
obj.computedPropertySets['Pset_Twinfinity'];
obj.quantitySets['Qto_WallBaseQuantities'];
```

#### Accessing individual property values

The old `BimPropertySet` allowed direct indexing with `pset['PropertyName']` returning `unknown`. The new `T8PropertySet` uses a typed `properties` record where each entry is a `T8Property` with explicit `value`, `type`, and `unit` fields.

```typescript
// Before — untyped, direct key access
const pset = obj.properties.sets['Pset_WallCommon'];
const isExternal = pset['IsExternal']; // unknown

// After — typed T8Property with value/type/unit
const pset = obj.propertySets['Pset_WallCommon'];
const isExternal = pset.properties['IsExternal'];
isExternal.value; // boolean | number | string | undefined
isExternal.type; // e.g. 'IfcBoolean'
isExternal.unit; // T8Unit | undefined
```

Properties with conflicting values from multiple sources are represented as arrays:

```typescript
const prop = pset.properties['StoreyName'];
if (Array.isArray(prop)) {
  prop.forEach((p) => console.log(p.value));
} else {
  console.log(prop.value);
}
```

#### Accessing individual quantity values

Same pattern — old `BimQuantitySets` used untyped access, new `T8QuantitySet` uses a typed `quantities` record.

```typescript
// Before
const qset = obj.quantities.sets['Qto_WallBaseQuantities'];
const area = qset['NetSideArea']; // unknown

// After
const qset = obj.quantitySets['Qto_WallBaseQuantities'];
const area = qset.quantities['NetSideArea'];
area.value; // boolean | number | string (required, not optional)
area.type; // e.g. 'IfcAreaMeasure'
area.unit; // T8Unit | undefined (e.g. { name: 'SQUARE_METRE', type: 'AREAUNIT' })
```

### New properties

- `globalId` — getter for the entity's GUID
- `localId` — getter for the numerical local ID
- `className` — getter for the IFC class name (e.g. `'IfcWall'`)
- `data` — getter for product data values (e.g. `elevation`, `longname`, `spacetype`)
- `meshes` — getter returning the product meshes
- `aggregates` — products aggregated by this product
- `contains` — products spatially contained by this product

### `children` semantics

`children` still returns aggregates + contains combined, but `aggregates` and `contains` are now available separately.

### BimIfcBuildingStorey

#### Counter property renamed

```typescript
// Before
storey.ifcObjectsWithGeometryCount;

// After
storey.objectsWithGeometryCount;
```

### BimTypeObject

`BimTypeObject` now implements `ModelEntityType`.

#### `properties` and `quantities` replaced

Same change as `BimIfcObject` — wrapper classes removed, direct record access with typed `T8PropertySet` / `T8QuantitySet`. See the `BimIfcObject` section above for full details on the new property/quantity value access patterns.

```typescript
// Before
type.properties.sets['Pset_WallCommon']['IsExternal']; // unknown
type.quantities.sets['Qto_WallBaseQuantities']['NetSideArea']; // unknown

// After
type.propertySets['Pset_WallCommon'].properties['IsExternal'].value; // boolean | number | string | undefined
type.quantitySets['Qto_WallBaseQuantities'].quantities['NetSideArea'].value; // boolean | number | string
```

#### New properties

- `className` — getter alias for `ifcClass`

### BimIfcStyle

#### New property

- `surfaceColor` — getter returning `readonly [r, g, b, a]` tuple

### Discipline

`Discipline` is now re-exported from `@twinfinity/t8-client-model`. The class API is identical, but counter properties have been renamed:

```typescript
// Before
discipline.ifcObjectCount;
discipline.ifcObjectsWithGeometryCount;

// After
discipline.objectCount;
discipline.objectsWithGeometryCount;
```

### Removed exports

| Export                       | Replacement                                                                    |
| ---------------------------- | ------------------------------------------------------------------------------ |
| `BimPropertySets`            | Use `Record<string, T8PropertySet<T8Unit>>` directly                           |
| `BimQuantitySets`            | Use `Record<string, T8QuantitySet<T8Unit>>` directly                           |
| `BimPropertySet` (interface) | Use `T8PropertySet` from `@twinfinity/t8-client-model`                         |
| `getModelProduct`            | Removed — `BimIfcObject` now implements `ModelProduct` directly                |
| `createModelProject`         | Removed — use `T8Project` or `ModelProject` from `@twinfinity/t8-client-model` |
| `BimT8gdFileReader`          | Moved to `@twinfinity/geometry` as `T8gdReader`                                |
| `BimVertexDataReaderV2`      | Moved to `@twinfinity/geometry` as `VertexDataReaderV2`                        |
| `BimVertexData` (type)       | Use `VertexData` from `@twinfinity/geometry`                                   |
| `NormalType` (enum)          | Use `NormalType` from `@twinfinity/geometry`                                   |
