---
title: Interior
source: https://infrared.city/docs/sdk/1.0/python/interior/
---

# Interior

Helpers for the interior models.

The one thing every interior user needs and does not have: a way to turn the FLAT mesh shape the rest of this SDK produces into the NESTED entity shape the interior models require.

`client.buildings.get_area()` returns `AreaBuildings` whose `.buildings` is a `Dict[str, DotBimMesh]` — the flat `{coordinates, indices}` shape used by the six outdoor grid models. Interior models need `{"geometry": {"payload": {"coordinates": …, "indices": …}}}`. Passing the flat form is not an error server-side: the entity is read as having no geometry, skipped, and the analysis runs against an empty occluder, returning a confident non-physical result.

So the natural thing to do — fetch neighbouring buildings and drop them into `context_geometry` — is exactly the thing that silently produces a wrong answer. These helpers exist so that path is one obvious call instead of a trap.

## to_interior_entity

```python
to_interior_entity(
mesh: Any,
*,
category: Optional[str] = None,
opening_factor: Optional[float] = None,
position: Optional[Mapping[str, float]] = None,
rotation: Optional[Mapping[str, float]] = None,
) -> Dict[str, Any]
```

Wrap a flat mesh in the nested interior entity shape.

Accepts a `DotBimMesh`, a plain `{"coordinates": …, "indices": …}` dict, or an already-nested entity (returned with its extras applied), so it is safe to call on anything.

Parameters mirror the wire contract rather than tidying it up:

`category` Tags what an entity IS. **Required by two of daylight-factor's four tiers:** the `floors` and `buildings` tiers cluster storeys from barriers carrying `category="floor"` and then read their `geometry.position`/`rotation` strictly — plain barriers give a billed rejection, and categorised-but-untransformed slabs give a billed 500. The `sensor_points` and `sensor_surfaces` tiers ignore it. `opening_factor` daylight-factor only; emitted as `openingFactor` (camelCase, the only spelling the worker reads). Visible-light transmittance in [0, 1]. `position` / `rotation` Read strictly wherever an entity is categorised, and their absence is a 500 rather than a validation error. Defaulted to identity when a `category` is given.

## interior_entities

```python
interior_entities(
meshes: Any,
*,
category: Optional[str] = None,
opening_factor: Optional[float] = None,
) -> Dict[str, Dict[str, Any]]
```

Convert a whole map of flat meshes into interior entities.

Takes the `AreaBuildings` returned by `client.buildings.get_area()`, its `.buildings` mapping, or any `{id: mesh}` dict, and returns a map ready to pass as `context_geometry` / `barriers` / `spatial_volumes`.

The intended use, and the reason this exists:

```python
area = client.buildings.get_area(site_polygon)
request = DaylightFactorModelRequest(
analysis_type=AnalysesName.daylight_factor,
barriers=my_room_barriers,
sensor_points=my_points,
context_geometry=interior_entities(area),   # neighbours as occluders
)
```

Without the conversion those neighbours are silently dropped and the room reads far brighter than it is.
