Skip to content
View as Markdown llms.txt

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

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

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:

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.